diff --git a/app/soapbox/features/soapbox_config/index.tsx b/app/soapbox/features/soapbox_config/index.tsx index fc1b79793..25e28ce5d 100644 --- a/app/soapbox/features/soapbox_config/index.tsx +++ b/app/soapbox/features/soapbox_config/index.tsx @@ -10,7 +10,7 @@ import HStack from 'soapbox/components/ui/hstack/hstack'; import Stack from 'soapbox/components/ui/stack/stack'; import Streamfield from 'soapbox/components/ui/streamfield/streamfield'; import { Checkbox } from 'soapbox/features/forms'; -import ThemeToggle from 'soapbox/features/ui/components/theme-toggle'; +import ThemeSelector from 'soapbox/features/ui/components/theme-selector'; import { useAppSelector, useAppDispatch } from 'soapbox/hooks'; import { normalizeSoapboxConfig } from 'soapbox/normalizers'; @@ -48,6 +48,7 @@ type ValueGetter = (e: React.ChangeEvent) => any; type ColorValueGetter = (color: ColorResult, event: React.ChangeEvent) => any; type Template = ImmutableMap; type ConfigPath = Array; +type ThemeChangeHandler = (theme: string) => void; const templates: Record = { promoPanelItem: ImmutableMap({ icon: '', text: '', url: '' }), @@ -109,6 +110,12 @@ const SoapboxConfig: React.FC = () => { }; }; + const handleThemeChange = (path: ConfigPath): ThemeChangeHandler => { + return theme => { + setConfig(path, theme); + }; + }; + const handleColorChange = (path: ConfigPath, getValue: ColorValueGetter): ColorChangeHandler => { return (color, event) => { setConfig(path, getValue(color, event)); @@ -196,12 +203,10 @@ const SoapboxConfig: React.FC = () => {
- - {/* value)} - themeMode={soapbox.defaultSettings.get('themeMode')} - intl={intl} - /> */} +
diff --git a/app/soapbox/features/ui/components/theme-selector.tsx b/app/soapbox/features/ui/components/theme-selector.tsx new file mode 100644 index 000000000..bc009ea7d --- /dev/null +++ b/app/soapbox/features/ui/components/theme-selector.tsx @@ -0,0 +1,63 @@ +import React, { useMemo } from 'react'; +import { defineMessages, useIntl } from 'react-intl'; + +import { Icon } from 'soapbox/components/ui'; + +const messages = defineMessages({ + light: { id: 'theme_toggle.light', defaultMessage: 'Light' }, + dark: { id: 'theme_toggle.dark', defaultMessage: 'Dark' }, + system: { id: 'theme_toggle.system', defaultMessage: 'System' }, +}); + +interface IThemeSelector { + value: string, + onChange: (value: string) => void, +} + +/** Pure theme selector. */ +const ThemeSelector: React.FC = ({ value, onChange }) => { + const intl = useIntl(); + + const themeIconSrc = useMemo(() => { + switch (value) { + case 'system': + return require('@tabler/icons/icons/device-desktop.svg'); + case 'light': + return require('@tabler/icons/icons/sun.svg'); + case 'dark': + return require('@tabler/icons/icons/moon.svg'); + default: + return null; + } + }, [value]); + + const handleChange: React.ChangeEventHandler = e => { + onChange(e.target.value); + }; + + return ( + + ); +}; + +export default ThemeSelector; diff --git a/app/soapbox/features/ui/components/theme-toggle.tsx b/app/soapbox/features/ui/components/theme-toggle.tsx index 3d69a4afa..3465190b9 100644 --- a/app/soapbox/features/ui/components/theme-toggle.tsx +++ b/app/soapbox/features/ui/components/theme-toggle.tsx @@ -1,65 +1,25 @@ -import React, { useMemo } from 'react'; -import { defineMessages, useIntl } from 'react-intl'; +import React from 'react'; import { useDispatch } from 'react-redux'; import { changeSetting } from 'soapbox/actions/settings'; -import { Icon } from 'soapbox/components/ui'; import { useSettings } from 'soapbox/hooks'; -const messages = defineMessages({ - light: { id: 'theme_toggle.light', defaultMessage: 'Light' }, - dark: { id: 'theme_toggle.dark', defaultMessage: 'Dark' }, - system: { id: 'theme_toggle.system', defaultMessage: 'System' }, -}); +import ThemeSelector from './theme-selector'; -interface IThemeToggle { - showLabel?: boolean, -} - -const ThemeToggle = ({ showLabel }: IThemeToggle) => { - const intl = useIntl(); +/** Stateful theme selector. */ +const ThemeToggle: React.FC = () => { const dispatch = useDispatch(); const themeMode = useSettings().get('themeMode'); - const onToggle = (event: React.ChangeEvent) => { - dispatch(changeSetting(['themeMode'], event.target.value)); + const handleChange = (themeMode: string) => { + dispatch(changeSetting(['themeMode'], themeMode)); }; - const themeIconSrc = useMemo(() => { - switch (themeMode) { - case 'system': - return require('@tabler/icons/icons/device-desktop.svg'); - case 'light': - return require('@tabler/icons/icons/sun.svg'); - case 'dark': - return require('@tabler/icons/icons/moon.svg'); - default: - return null; - } - }, [themeMode]); - return ( - + ); };