import { ChangeEvent, FC } from 'react'; import { useIntl } from 'react-intl'; import { useAttributes, useLocalStorage } from '../../../../utils/hooks'; import { Legend } from '../../../atoms'; import { Switch, SwitchOption, SwitchProps } from '../../../molecules'; export type MotionToggleValue = 'on' | 'off'; export type MotionToggleProps = Omit< SwitchProps, 'isInline' | 'items' | 'name' | 'onSwitch' | 'value' > & { /** * True if motion should be reduced by default. */ defaultValue: 'on' | 'off'; /** * The local storage key to save preference. */ storageKey: string; }; /** * MotionToggle component * * Render a Toggle component to set reduce motion. */ export const MotionToggle: FC = ({ defaultValue, storageKey, ...props }) => { const intl = useIntl(); const { value: isReduced, setValue: setIsReduced } = useLocalStorage( storageKey, defaultValue !== 'on' ); useAttributes({ element: typeof window !== 'undefined' ? document.documentElement : undefined, attribute: 'reduced-motion', value: `${isReduced}`, }); const reduceMotionLabel = intl.formatMessage({ defaultMessage: 'Animations:', description: 'MotionToggle: reduce motion label', id: '/q5csZ', }); const onLabel = intl.formatMessage({ defaultMessage: 'On', description: 'MotionToggle: activate reduce motion label', id: 'va65iw', }); const offLabel = intl.formatMessage({ defaultMessage: 'Off', description: 'MotionToggle: deactivate reduce motion label', id: 'pWKyyR', }); const options: [SwitchOption, SwitchOption] = [ { id: 'reduced-motion-on', label: onLabel, value: 'on', }, { id: 'reduced-motion-off', label: offLabel, value: 'off', }, ]; const updateSetting = (e: ChangeEvent) => { setIsReduced((prev) => !prev); }; return ( {reduceMotionLabel}} name="reduced-motion" onSwitch={updateSetting} value={isReduced ? 'off' : 'on'} /> ); };