diff options
| author | Armand Philippot <git@armandphilippot.com> | 2023-10-27 11:09:38 +0200 |
|---|---|---|
| committer | Armand Philippot <git@armandphilippot.com> | 2023-11-11 18:15:27 +0100 |
| commit | 757201fdc5c04a3f15504f74bf8ab85bb6018c2b (patch) | |
| tree | 1adda54704314b24ec81bfdbf0c13acbce2cda87 /src/components | |
| parent | 3ab9f0423e97af63da4bf6a13ffd786955bd5b3b (diff) | |
refactor(hooks,provider): move reduce motion setter
Since the local storage key is not meant to change between the
components, it should be set directly inside the app file. So
both the local storage and the data attribute should be handle
in a provider.
I also added a custom document because we need a script to
retrieve the stored value in local storage earlier to avoid
flashing on hydration.
Diffstat (limited to 'src/components')
15 files changed, 32 insertions, 170 deletions
diff --git a/src/components/molecules/forms/switch/switch.tsx b/src/components/molecules/forms/switch/switch.tsx index df2ba0c..ad3e514 100644 --- a/src/components/molecules/forms/switch/switch.tsx +++ b/src/components/molecules/forms/switch/switch.tsx @@ -55,9 +55,7 @@ const SwitchItem: FC<SwitchItemProps> = ({ value, ...props }) => { - const selectedItemClass = isSelected ? styles['item--selected'] : ''; - const disabledItemClass = isDisabled ? styles['item--disabled'] : ''; - const itemClass = `${styles.item} ${selectedItemClass} ${disabledItemClass} ${className}`; + const itemClass = `${styles.item} ${className}`; return ( <Label {...props} className={itemClass} htmlFor={id}> diff --git a/src/components/organisms/forms/motion-toggle/motion-toggle.fixture.ts b/src/components/organisms/forms/motion-toggle/motion-toggle.fixture.ts deleted file mode 100644 index f13658a..0000000 --- a/src/components/organisms/forms/motion-toggle/motion-toggle.fixture.ts +++ /dev/null @@ -1 +0,0 @@ -export const storageKey = 'reduced-motion'; diff --git a/src/components/organisms/forms/motion-toggle/motion-toggle.stories.tsx b/src/components/organisms/forms/motion-toggle/motion-toggle.stories.tsx index 811830b..7adef1b 100644 --- a/src/components/organisms/forms/motion-toggle/motion-toggle.stories.tsx +++ b/src/components/organisms/forms/motion-toggle/motion-toggle.stories.tsx @@ -1,6 +1,5 @@ import type { ComponentMeta, ComponentStory } from '@storybook/react'; import { MotionToggle } from './motion-toggle'; -import { storageKey } from './motion-toggle.fixture'; /** * MotionToggle - Storybook Meta @@ -8,29 +7,7 @@ import { storageKey } from './motion-toggle.fixture'; export default { title: 'Organisms/Forms/Toggle', component: MotionToggle, - argTypes: { - defaultValue: { - control: { - type: 'select', - }, - description: 'Set the default value.', - options: ['on', 'off'], - type: { - name: 'string', - required: true, - }, - }, - storageKey: { - control: { - type: 'text', - }, - description: 'Set local storage key.', - type: { - name: 'string', - required: true, - }, - }, - }, + argTypes: {}, } as ComponentMeta<typeof MotionToggle>; const Template: ComponentStory<typeof MotionToggle> = (args) => ( @@ -41,7 +18,4 @@ const Template: ComponentStory<typeof MotionToggle> = (args) => ( * Toggle Stories - Motion */ export const Motion = Template.bind({}); -Motion.args = { - defaultValue: 'on', - storageKey, -}; +Motion.args = {}; diff --git a/src/components/organisms/forms/motion-toggle/motion-toggle.test.tsx b/src/components/organisms/forms/motion-toggle/motion-toggle.test.tsx index 6952f46..d20057e 100644 --- a/src/components/organisms/forms/motion-toggle/motion-toggle.test.tsx +++ b/src/components/organisms/forms/motion-toggle/motion-toggle.test.tsx @@ -1,12 +1,11 @@ import { describe, expect, it } from '@jest/globals'; import { render, screen as rtlScreen } from '../../../../../tests/utils'; import { MotionToggle } from './motion-toggle'; -import { storageKey } from './motion-toggle.fixture'; describe('MotionToggle', () => { // toHaveValue received undefined. Maybe because of localStorage hook... it('renders a toggle component', () => { - render(<MotionToggle storageKey={storageKey} defaultValue="on" />); + render(<MotionToggle />); expect( rtlScreen.getByRole('radiogroup', { name: /Animations:/i, diff --git a/src/components/organisms/forms/motion-toggle/motion-toggle.tsx b/src/components/organisms/forms/motion-toggle/motion-toggle.tsx index 2545c20..33527c3 100644 --- a/src/components/organisms/forms/motion-toggle/motion-toggle.tsx +++ b/src/components/organisms/forms/motion-toggle/motion-toggle.tsx @@ -1,6 +1,6 @@ -import { useCallback, type FC } from 'react'; +import type { FC } from 'react'; import { useIntl } from 'react-intl'; -import { useAttributes, useLocalStorage } from '../../../../utils/hooks'; +import { useReducedMotion } from '../../../../utils/hooks'; import { Legend } from '../../../atoms'; import { Switch, @@ -8,47 +8,19 @@ import { type SwitchProps, } from '../../../molecules'; -export type MotionToggleValue = 'on' | 'off'; - -const validator = (value: unknown): value is boolean => - typeof value === 'boolean'; - export type MotionToggleProps = Omit< SwitchProps, 'isInline' | 'items' | 'name' | 'onSwitch' | 'value' -> & { - /** - * True if motion should be reduced by default. - */ - defaultValue: MotionToggleValue; - /** - * The local storage key to save preference. - */ - storageKey: string; -}; +>; /** * MotionToggle component * * Render a Toggle component to set reduce motion. */ -export const MotionToggle: FC<MotionToggleProps> = ({ - defaultValue, - storageKey, - ...props -}) => { +export const MotionToggle: FC<MotionToggleProps> = ({ ...props }) => { const intl = useIntl(); - const [isReduced, setIsReduced] = useLocalStorage( - storageKey, - defaultValue !== 'on', - validator - ); - useAttributes({ - element: - typeof window === 'undefined' ? undefined : document.documentElement, - attribute: 'reduced-motion', - value: `${isReduced}`, - }); + const { isReduced, toggleReducedMotion } = useReducedMotion(); const reduceMotionLabel = intl.formatMessage({ defaultMessage: 'Animations:', @@ -79,10 +51,6 @@ export const MotionToggle: FC<MotionToggleProps> = ({ }, ]; - const updateSetting = useCallback(() => { - setIsReduced((prev) => !prev); - }, [setIsReduced]); - return ( <Switch {...props} @@ -90,7 +58,7 @@ export const MotionToggle: FC<MotionToggleProps> = ({ items={options} legend={<Legend>{reduceMotionLabel}</Legend>} name="reduced-motion" - onSwitch={updateSetting} + onSwitch={toggleReducedMotion} value={isReduced ? 'off' : 'on'} /> ); diff --git a/src/components/organisms/modals/settings-modal.stories.tsx b/src/components/organisms/modals/settings-modal.stories.tsx index 57ce00f..7c56f27 100644 --- a/src/components/organisms/modals/settings-modal.stories.tsx +++ b/src/components/organisms/modals/settings-modal.stories.tsx @@ -1,5 +1,4 @@ import type { ComponentMeta, ComponentStory } from '@storybook/react'; -import { storageKey as motionStorageKey } from '../forms/motion-toggle/motion-toggle.fixture'; import { SettingsModal } from './settings-modal'; /** @@ -22,16 +21,6 @@ export default { required: false, }, }, - motionStorageKey: { - control: { - type: 'text', - }, - description: 'A local storage key for reduced motion setting..', - type: { - name: 'string', - required: true, - }, - }, tooltipClassName: { control: { type: 'text', @@ -59,6 +48,4 @@ const Template: ComponentStory<typeof SettingsModal> = (args) => ( * Modals Stories - Settings */ export const Settings = Template.bind({}); -Settings.args = { - motionStorageKey, -}; +Settings.args = {}; diff --git a/src/components/organisms/modals/settings-modal.test.tsx b/src/components/organisms/modals/settings-modal.test.tsx index 26d046a..af2b6e9 100644 --- a/src/components/organisms/modals/settings-modal.test.tsx +++ b/src/components/organisms/modals/settings-modal.test.tsx @@ -1,16 +1,15 @@ import { describe, expect, it } from '@jest/globals'; import { render, screen as rtlScreen } from '../../../../tests/utils'; -import { storageKey as motionStorageKey } from '../forms/motion-toggle/motion-toggle.fixture'; import { SettingsModal } from './settings-modal'; describe('SettingsModal', () => { it('renders the modal heading', () => { - render(<SettingsModal motionStorageKey={motionStorageKey} />); + render(<SettingsModal />); expect(rtlScreen.getByText(/Settings/i)).toBeInTheDocument(); }); it('renders a settings form', () => { - render(<SettingsModal motionStorageKey={motionStorageKey} />); + render(<SettingsModal />); expect( rtlScreen.getByRole('form', { name: /^Settings form/i }) ).toBeInTheDocument(); diff --git a/src/components/organisms/modals/settings-modal.tsx b/src/components/organisms/modals/settings-modal.tsx index f62312b..5fea491 100644 --- a/src/components/organisms/modals/settings-modal.tsx +++ b/src/components/organisms/modals/settings-modal.tsx @@ -4,28 +4,19 @@ import { Form, Heading, Icon, Modal, type ModalProps } from '../../atoms'; import { AckeeToggle, MotionToggle, - type MotionToggleProps, PrismThemeToggle, ThemeToggle, } from '../forms'; import styles from './settings-modal.module.scss'; -export type SettingsModalProps = Pick<ModalProps, 'className'> & { - /** - * The local storage key for Reduce motion settings. - */ - motionStorageKey: MotionToggleProps['storageKey']; -}; +export type SettingsModalProps = Pick<ModalProps, 'className'>; /** * SettingsModal component * * Render a modal with settings options. */ -export const SettingsModal: FC<SettingsModalProps> = ({ - className = '', - motionStorageKey, -}) => { +export const SettingsModal: FC<SettingsModalProps> = ({ className = '' }) => { const intl = useIntl(); const title = intl.formatMessage({ defaultMessage: 'Settings', @@ -59,11 +50,7 @@ export const SettingsModal: FC<SettingsModalProps> = ({ > <ThemeToggle className={styles.item} /> <PrismThemeToggle className={styles.item} /> - <MotionToggle - className={styles.item} - defaultValue="on" - storageKey={motionStorageKey} - /> + <MotionToggle className={styles.item} /> <AckeeToggle className={styles.item} direction="upwards" /> </Form> </Modal> diff --git a/src/components/organisms/toolbar/settings.stories.tsx b/src/components/organisms/toolbar/settings.stories.tsx index 66b4e0f..793c521 100644 --- a/src/components/organisms/toolbar/settings.stories.tsx +++ b/src/components/organisms/toolbar/settings.stories.tsx @@ -8,9 +8,6 @@ import { Settings } from './settings'; export default { title: 'Organisms/Toolbar/Settings', component: Settings, - args: { - motionStorageKey: 'reduced-motion', - }, argTypes: { className: { control: { @@ -38,16 +35,6 @@ export default { required: true, }, }, - motionStorageKey: { - control: { - type: 'text', - }, - description: 'Set Reduced motion settings local storage key.', - type: { - name: 'string', - required: true, - }, - }, setIsActive: { control: { type: null, diff --git a/src/components/organisms/toolbar/settings.test.tsx b/src/components/organisms/toolbar/settings.test.tsx index 66fa6a6..6dbed2b 100644 --- a/src/components/organisms/toolbar/settings.test.tsx +++ b/src/components/organisms/toolbar/settings.test.tsx @@ -8,26 +8,14 @@ const doNothing = () => { describe('Settings', () => { it('renders a button to open settings modal', () => { - render( - <Settings - motionStorageKey="reduced-motion" - isActive={false} - setIsActive={doNothing} - /> - ); + render(<Settings isActive={false} setIsActive={doNothing} />); expect( rtlScreen.getByRole('checkbox', { name: 'Open settings' }) ).toBeInTheDocument(); }); it('renders a button to close settings modal', () => { - render( - <Settings - motionStorageKey="reduced-motion" - isActive={true} - setIsActive={doNothing} - /> - ); + render(<Settings isActive={true} setIsActive={doNothing} />); expect( rtlScreen.getByRole('checkbox', { name: 'Close settings' }) ).toBeInTheDocument(); diff --git a/src/components/organisms/toolbar/settings.tsx b/src/components/organisms/toolbar/settings.tsx index 124dd42..1b68db8 100644 --- a/src/components/organisms/toolbar/settings.tsx +++ b/src/components/organisms/toolbar/settings.tsx @@ -19,10 +19,7 @@ export type SettingsProps = SettingsModalProps & { const SettingsWithRef: ForwardRefRenderFunction< HTMLDivElement, SettingsProps -> = ( - { className = '', isActive = false, motionStorageKey, setIsActive }, - ref -) => { +> = ({ className = '', isActive = false, setIsActive }, ref) => { const intl = useIntl(); const label = isActive ? intl.formatMessage({ @@ -54,10 +51,7 @@ const SettingsWithRef: ForwardRefRenderFunction< isActive={isActive} label={label} /> - <SettingsModal - className={`${styles.modal} ${className}`} - motionStorageKey={motionStorageKey} - /> + <SettingsModal className={`${styles.modal} ${className}`} /> </div> ); }; diff --git a/src/components/organisms/toolbar/toolbar.stories.tsx b/src/components/organisms/toolbar/toolbar.stories.tsx index 22bead9..19dc135 100644 --- a/src/components/organisms/toolbar/toolbar.stories.tsx +++ b/src/components/organisms/toolbar/toolbar.stories.tsx @@ -8,7 +8,6 @@ export default { title: 'Organisms/Toolbar', component: ToolbarComponent, args: { - motionStorageKey: 'reduced-motion', searchPage: '#', }, argTypes: { @@ -25,16 +24,6 @@ export default { required: false, }, }, - motionStorageKey: { - control: { - type: 'text', - }, - description: 'Set Reduced motion settings local storage key.', - type: { - name: 'string', - required: true, - }, - }, nav: { description: 'The main nav items.', type: { diff --git a/src/components/organisms/toolbar/toolbar.test.tsx b/src/components/organisms/toolbar/toolbar.test.tsx index e6b1022..23b13c1 100644 --- a/src/components/organisms/toolbar/toolbar.test.tsx +++ b/src/components/organisms/toolbar/toolbar.test.tsx @@ -11,9 +11,7 @@ const nav = [ describe('Toolbar', () => { it('renders a navigation menu', () => { - render( - <Toolbar motionStorageKey="reduced-motion" nav={nav} searchPage="#" /> - ); + render(<Toolbar nav={nav} searchPage="#" />); expect(rtlScreen.getByRole('navigation')).toBeInTheDocument(); }); }); diff --git a/src/components/organisms/toolbar/toolbar.tsx b/src/components/organisms/toolbar/toolbar.tsx index be46636..c400285 100644 --- a/src/components/organisms/toolbar/toolbar.tsx +++ b/src/components/organisms/toolbar/toolbar.tsx @@ -3,20 +3,19 @@ import { type FC, useState, useCallback } from 'react'; import { useOnClickOutside, useRouteChange } from '../../../utils/hooks'; import { MainNavItem, type MainNavItemProps } from './main-nav'; import { Search, type SearchProps } from './search'; -import { Settings, type SettingsProps } from './settings'; +import { Settings } from './settings'; import styles from './toolbar.module.scss'; -export type ToolbarProps = Pick<SearchProps, 'searchPage'> & - Pick<SettingsProps, 'motionStorageKey'> & { - /** - * Set additional classnames to the toolbar wrapper. - */ - className?: string; - /** - * The main nav items. - */ - nav: MainNavItemProps['items']; - }; +export type ToolbarProps = Pick<SearchProps, 'searchPage'> & { + /** + * Set additional classnames to the toolbar wrapper. + */ + className?: string; + /** + * The main nav items. + */ + nav: MainNavItemProps['items']; +}; /** * Toolbar component @@ -25,7 +24,6 @@ export type ToolbarProps = Pick<SearchProps, 'searchPage'> & */ export const Toolbar: FC<ToolbarProps> = ({ className = '', - motionStorageKey, nav, searchPage, }) => { @@ -77,7 +75,6 @@ export const Toolbar: FC<ToolbarProps> = ({ <Settings className={`${styles.modal} ${styles['modal--settings']}`} isActive={isSettingsOpened} - motionStorageKey={motionStorageKey} ref={settingsRef} setIsActive={toggleSettings} /> diff --git a/src/components/templates/layout/layout.tsx b/src/components/templates/layout/layout.tsx index fd3a928..9017d3c 100644 --- a/src/components/templates/layout/layout.tsx +++ b/src/components/templates/layout/layout.tsx @@ -313,8 +313,6 @@ export const Layout: FC<LayoutProps> = ({ /> <Toolbar className={styles.toolbar} - // eslint-disable-next-line react/jsx-no-literals -- Storage key allowed - motionStorageKey="reduced-motion" nav={mainNav} searchPage={ROUTES.SEARCH} /> |
