summaryrefslogtreecommitdiffstats
path: root/src/components/molecules/forms/theme-toggle.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/molecules/forms/theme-toggle.tsx')
-rw-r--r--src/components/molecules/forms/theme-toggle.tsx73
1 files changed, 52 insertions, 21 deletions
diff --git a/src/components/molecules/forms/theme-toggle.tsx b/src/components/molecules/forms/theme-toggle.tsx
index e9dd5e4..30bc55c 100644
--- a/src/components/molecules/forms/theme-toggle.tsx
+++ b/src/components/molecules/forms/theme-toggle.tsx
@@ -1,16 +1,18 @@
import Moon from '@components/atoms/icons/moon';
import Sun from '@components/atoms/icons/sun';
-import Toggle, {
- type ToggleChoices,
- type ToggleProps,
-} from '@components/molecules/forms/toggle';
import { useTheme } from 'next-themes';
import { FC } from 'react';
import { useIntl } from 'react-intl';
+import RadioGroup, {
+ type RadioGroupCallback,
+ type RadioGroupCallbackProps,
+ type RadioGroupOption,
+ type RadioGroupProps,
+} from './radio-group';
export type ThemeToggleProps = Pick<
- ToggleProps,
- 'className' | 'labelClassName'
+ RadioGroupProps,
+ 'groupClassName' | 'legendClassName'
>;
/**
@@ -18,16 +20,36 @@ export type ThemeToggleProps = Pick<
*
* Render a Toggle component to set theme.
*/
-const ThemeToggle: FC<ThemeToggleProps> = ({ ...props }) => {
+const ThemeToggle: FC<ThemeToggleProps> = (props) => {
const intl = useIntl();
const { resolvedTheme, setTheme } = useTheme();
const isDarkTheme = resolvedTheme === 'dark';
/**
* Update the theme.
+ *
+ * @param {string} theme - A theme name.
*/
- const updateTheme = () => {
- setTheme(isDarkTheme ? 'light' : 'dark');
+ const updateTheme = (theme: string) => {
+ setTheme(theme === 'light' ? 'light' : 'dark');
+ };
+
+ /**
+ * Handle change events.
+ *
+ * @param {RadioGroupCallbackProps} props - An object with choices.
+ */
+ const handleChange: RadioGroupCallback = ({
+ choices,
+ updateChoice,
+ }: RadioGroupCallbackProps) => {
+ if (choices.new === choices.prev) {
+ const newTheme = choices.new === 'light' ? 'dark' : 'light';
+ updateChoice(newTheme);
+ updateTheme(newTheme);
+ } else {
+ updateTheme(choices.new);
+ }
};
const themeLabel = intl.formatMessage({
@@ -45,20 +67,29 @@ const ThemeToggle: FC<ThemeToggleProps> = ({ ...props }) => {
description: 'ThemeToggle: dark theme label',
id: '2QwvtS',
});
- const themeChoices: ToggleChoices = {
- left: <Sun title={lightThemeLabel} />,
- right: <Moon title={darkThemeLabel} />,
- };
+
+ const options: RadioGroupOption[] = [
+ {
+ id: 'theme-light',
+ label: <Sun title={lightThemeLabel} />,
+ name: 'theme',
+ value: 'light',
+ },
+ {
+ id: 'theme-dark',
+ label: <Moon title={darkThemeLabel} />,
+ name: 'theme',
+ value: 'dark',
+ },
+ ];
return (
- <Toggle
- id="theme-settings"
- name="theme-settings"
- label={themeLabel}
- labelSize="medium"
- choices={themeChoices}
- value={isDarkTheme}
- setValue={updateTheme}
+ <RadioGroup
+ initialChoice={isDarkTheme ? 'dark' : 'light'}
+ kind="toggle"
+ legend={themeLabel}
+ onChange={handleChange}
+ options={options}
{...props}
/>
);