diff --git a/src/ui/React/ThemeEditorModal.tsx b/src/ui/React/ThemeEditorModal.tsx index b1681588a..637054a3f 100644 --- a/src/ui/React/ThemeEditorModal.tsx +++ b/src/ui/React/ThemeEditorModal.tsx @@ -15,30 +15,15 @@ interface IProps { onClose: () => void; } -function ColorEditor({ name }: { name: string }): React.ReactElement { - const [color, setColor] = useState(Settings.theme[name]); - if (color === undefined) return <>; - const valid = color.match(/#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})/g); +interface IColorEditorProps { + name: string; + color: string | undefined; + onColorChange: (name: string, value: string) => void; + defaultColor: string; +} - function set(): void { - if (!valid) return; - Settings.theme[name] = color; - ThemeEvents.emit(); - } - - function revert(): void { - Settings.theme[name] = defaultSettings.theme[name]; - setColor(defaultSettings.theme[name]); - ThemeEvents.emit(); - } - - function onChange(event: React.ChangeEvent): void { - setColor(event.target.value); - } - - function onColorPickerChange(newValue: Color): void { - setColor("#" + newValue.hex.toLowerCase()); - } +function ColorEditor({ name, onColorChange, color, defaultColor }: IColorEditorProps): React.ReactElement { + if (color === undefined) throw new Error("should not happen"); return ( <> @@ -46,20 +31,20 @@ function ColorEditor({ name }: { name: string }): React.ReactElement { sx={{ mx: 1 }} label={name} value={color} - onChange={onChange} variant="standard" InputProps={{ startAdornment: ( <> - + onColorChange(name, "#" + newColor.hex)} + /> ), endAdornment: ( <> - - - - + onColorChange(name, defaultColor)}> @@ -71,6 +56,34 @@ function ColorEditor({ name }: { name: string }): React.ReactElement { } export function ThemeEditorModal(props: IProps): React.ReactElement { + const [customTheme, setCustomTheme] = useState<{ [key: string]: string | undefined }>({ + ...Settings.theme, + }); + + function onThemeChange(event: React.ChangeEvent): void { + try { + const importedTheme = JSON.parse(event.target.value); + if (typeof importedTheme !== "object") return; + setCustomTheme(importedTheme); + for (const key of Object.keys(importedTheme)) { + Settings.theme[key] = importedTheme[key]; + } + ThemeEvents.emit(); + } catch (err) { + // ignore + } + } + + function onColorChange(name: string, value: string): void { + setCustomTheme((old: any) => { + old[name] = value; + return old; + }); + + Settings.theme[name] = value; + ThemeEvents.emit(); + } + return ( @@ -84,44 +97,177 @@ export function ThemeEditorModal(props: IProps): React.ReactElement { info error
- - - + + +
- - - + + +
- - - + + +
- - - + + +
- - - + + +
- - - - + + + +
- - - - - - - + + + + + + + +
+
+
); }