summaryrefslogtreecommitdiffstats
path: root/src/components/molecules/forms/motion-toggle.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/molecules/forms/motion-toggle.tsx')
-rw-r--r--src/components/molecules/forms/motion-toggle.tsx82
1 files changed, 63 insertions, 19 deletions
diff --git a/src/components/molecules/forms/motion-toggle.tsx b/src/components/molecules/forms/motion-toggle.tsx
index 55ff150..6925248 100644
--- a/src/components/molecules/forms/motion-toggle.tsx
+++ b/src/components/molecules/forms/motion-toggle.tsx
@@ -1,17 +1,25 @@
-import Toggle, {
- type ToggleChoices,
- type ToggleProps,
-} from '@components/molecules/forms/toggle';
import useAttributes from '@utils/hooks/use-attributes';
import useLocalStorage from '@utils/hooks/use-local-storage';
import { FC } from 'react';
import { useIntl } from 'react-intl';
+import RadioGroup, {
+ type RadioGroupCallback,
+ type RadioGroupCallbackProps,
+ type RadioGroupOption,
+ type RadioGroupProps,
+} from './radio-group';
+
+export type MotionToggleValue = 'on' | 'off';
export type MotionToggleProps = Pick<
- ToggleProps,
- 'className' | 'labelClassName' | 'value'
+ RadioGroupProps,
+ 'groupClassName' | 'legendClassName'
> & {
/**
+ * True if motion should be reduced by default.
+ */
+ defaultValue: 'on' | 'off';
+ /**
* The local storage key to save preference.
*/
storageKey: string;
@@ -23,14 +31,14 @@ export type MotionToggleProps = Pick<
* Render a Toggle component to set reduce motion.
*/
const MotionToggle: FC<MotionToggleProps> = ({
+ defaultValue,
storageKey,
- value,
...props
}) => {
const intl = useIntl();
const { value: isReduced, setValue: setIsReduced } = useLocalStorage<boolean>(
storageKey,
- value
+ defaultValue === 'on' ? false : true
);
useAttributes({
element: document.documentElement || undefined,
@@ -53,20 +61,56 @@ const MotionToggle: FC<MotionToggleProps> = ({
description: 'MotionToggle: deactivate reduce motion label',
id: 'pWKyyR',
});
- const reduceMotionChoices: ToggleChoices = {
- left: onLabel,
- right: offLabel,
+
+ const options: RadioGroupOption[] = [
+ {
+ id: 'reduced-motion-on',
+ label: onLabel,
+ name: 'reduced-motion',
+ value: 'on',
+ },
+ {
+ id: 'reduced-motion-off',
+ label: offLabel,
+ name: 'reduced-motion',
+ value: 'off',
+ },
+ ];
+
+ /**
+ * Update the current setting.
+ *
+ * @param {string} newValue - A boolean as string.
+ */
+ const updateSetting = (newValue: MotionToggleValue) => {
+ setIsReduced(newValue === 'on' ? false : true);
+ };
+
+ /**
+ * Handle change events.
+ *
+ * @param {RadioGroupCallbackProps} props - An object with choices.
+ */
+ const handleChange: RadioGroupCallback = ({
+ choices,
+ updateChoice,
+ }: RadioGroupCallbackProps) => {
+ if (choices.new === choices.prev) {
+ const newChoice = choices.new === 'on' ? 'off' : 'on';
+ updateChoice(newChoice);
+ updateSetting(newChoice);
+ } else {
+ updateSetting(choices.new as MotionToggleValue);
+ }
};
return (
- <Toggle
- id="reduce-motion-settings"
- name="reduce-motion-settings"
- label={reduceMotionLabel}
- labelSize="medium"
- choices={reduceMotionChoices}
- value={isReduced}
- setValue={setIsReduced}
+ <RadioGroup
+ initialChoice={defaultValue}
+ kind="toggle"
+ legend={reduceMotionLabel}
+ onChange={handleChange}
+ options={options}
{...props}
/>
);