main-site/components/themeselector.tsx

99 lines
3.6 KiB
TypeScript

import { useUpdateTheme } from "../pages/_app";
import { useContext, useState } from 'react';
import { ThemeContext, DefaultTheme } from "styled-components";
import { darkTheme, lightTheme } from './themes';
import { ThemeDropDown, ThemeDropDownButton, ThemeDropDownOption, ThemeDropDownOptions } from "./styles/themedropdown/desktop";
import { ThemeDropDownMobile, ThemeDropDownButtonMobile, ThemeDropDownOptionMobile, ThemeDropDownOptionsMobile } from "./styles/themedropdown/mobile";
import Themes from '../public/data/themes.json';
export const StyleSelector = ({ mobile }: { mobile: number }) => {
const themes: DefaultTheme[] = Themes.themes;
const updateTheme = useUpdateTheme();
const currentTheme = useContext(ThemeContext);
const [selectedTheme, setSelectedTheme] = useState(themes[currentTheme.themeId]);
if(currentTheme !== selectedTheme) {
setSelectedTheme(currentTheme);
}
const updateThemeWithStorage = (newTheme: DefaultTheme) => {
if (newTheme.themeId === lightTheme.themeId) {
updateLightTheme(newTheme);
}
else {
setSelectedTheme(newTheme);
localStorage.setItem("theme", newTheme.themeId.toString());
updateTheme(newTheme);
}
}
const updateLightTheme = (newTheme: DefaultTheme) => {
if (confirm("Really switch to Light Mode?")) {
setSelectedTheme(newTheme);
localStorage.setItem("theme", newTheme.themeId.toString());
updateTheme(newTheme)
}
}
const [visible, setVisible] = useState(false);
const [buttonFocus, setButtonFocus] = useState(visible);
function handleBlur(event:any) {
if (!event.currentTarget.contains(event.relatedTarget)) {
setButtonFocus(false);
setVisible(false);
}
}
let themeselector: JSX.Element;
if(mobile) {
themeselector = (
<ThemeDropDownMobile onBlur={(event) => handleBlur(event)}>
<ThemeDropDownButtonMobile focus={+buttonFocus} show={+visible} onFocus={() => setButtonFocus(true)} onClick={() => setVisible(visible => !visible)}>
{selectedTheme.themeName}
</ThemeDropDownButtonMobile>
<ThemeDropDownOptionsMobile focus={+buttonFocus} id="themesDropdown" show={+visible}>
{themes.map((theme) => (
<ThemeDropDownOptionMobile active={theme.themeId === selectedTheme.themeId ? 1 : 0} key={theme.themeId} onClick={() => updateThemeWithStorage(theme)}>
{theme.themeName}
</ThemeDropDownOptionMobile>
))}
</ThemeDropDownOptionsMobile>
</ThemeDropDownMobile>
);
}
else {
themeselector = (
<ThemeDropDown onBlur={(event) => handleBlur(event)}>
<ThemeDropDownButton focus={+buttonFocus} show={+visible} onFocus={() => setButtonFocus(true)} onClick={() => setVisible(visible => !visible)}>{selectedTheme.themeName}
</ThemeDropDownButton>
<ThemeDropDownOptions id="themesDropdown" show={+visible}>
{themes.map((theme) => (
<ThemeDropDownOption active={theme.themeId === selectedTheme.themeId ? 1 : 0} key={theme.themeId} onClick={() => updateThemeWithStorage(theme)}>
{theme.themeName}
</ThemeDropDownOption>
))}
</ThemeDropDownOptions>
</ThemeDropDown>
);
}
return themeselector;
}
export const StyleSelectorPlaceholder = () => {
return (
<ThemeDropDown></ThemeDropDown>
)
}
export function getTheme(themeId: number, themes: DefaultTheme[]): DefaultTheme {
let retTheme: DefaultTheme = darkTheme;
themes.forEach((theme) => {
if (theme.themeId === themeId) { retTheme = theme};
})
return retTheme;
}
export default StyleSelector;