From 757201fdc5c04a3f15504f74bf8ab85bb6018c2b Mon Sep 17 00:00:00 2001 From: Armand Philippot Date: Fri, 27 Oct 2023 11:09:38 +0200 Subject: 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. --- .../forms/motion-toggle/motion-toggle.fixture.ts | 1 - .../forms/motion-toggle/motion-toggle.stories.tsx | 30 +-------------- .../forms/motion-toggle/motion-toggle.test.tsx | 3 +- .../forms/motion-toggle/motion-toggle.tsx | 44 +++------------------- .../organisms/modals/settings-modal.stories.tsx | 15 +------- .../organisms/modals/settings-modal.test.tsx | 5 +-- src/components/organisms/modals/settings-modal.tsx | 19 ++-------- .../organisms/toolbar/settings.stories.tsx | 13 ------- src/components/organisms/toolbar/settings.test.tsx | 16 +------- src/components/organisms/toolbar/settings.tsx | 10 +---- .../organisms/toolbar/toolbar.stories.tsx | 11 ------ src/components/organisms/toolbar/toolbar.test.tsx | 4 +- src/components/organisms/toolbar/toolbar.tsx | 25 ++++++------ 13 files changed, 31 insertions(+), 165 deletions(-) delete mode 100644 src/components/organisms/forms/motion-toggle/motion-toggle.fixture.ts (limited to 'src/components/organisms') 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; const Template: ComponentStory = (args) => ( @@ -41,7 +18,4 @@ const Template: ComponentStory = (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(); + render(); 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 = ({ - defaultValue, - storageKey, - ...props -}) => { +export const MotionToggle: FC = ({ ...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 = ({ }, ]; - const updateSetting = useCallback(() => { - setIsReduced((prev) => !prev); - }, [setIsReduced]); - return ( = ({ items={options} legend={{reduceMotionLabel}} 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 = (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(); + render(); expect(rtlScreen.getByText(/Settings/i)).toBeInTheDocument(); }); it('renders a settings form', () => { - render(); + render(); 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 & { - /** - * The local storage key for Reduce motion settings. - */ - motionStorageKey: MotionToggleProps['storageKey']; -}; +export type SettingsModalProps = Pick; /** * SettingsModal component * * Render a modal with settings options. */ -export const SettingsModal: FC = ({ - className = '', - motionStorageKey, -}) => { +export const SettingsModal: FC = ({ className = '' }) => { const intl = useIntl(); const title = intl.formatMessage({ defaultMessage: 'Settings', @@ -59,11 +50,7 @@ export const SettingsModal: FC = ({ > - + 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( - - ); + render(); expect( rtlScreen.getByRole('checkbox', { name: 'Open settings' }) ).toBeInTheDocument(); }); it('renders a button to close settings modal', () => { - render( - - ); + render(); 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} /> - + ); }; 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( - - ); + render(); 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 & - Pick & { - /** - * Set additional classnames to the toolbar wrapper. - */ - className?: string; - /** - * The main nav items. - */ - nav: MainNavItemProps['items']; - }; +export type ToolbarProps = Pick & { + /** + * 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 & */ export const Toolbar: FC = ({ className = '', - motionStorageKey, nav, searchPage, }) => { @@ -77,7 +75,6 @@ export const Toolbar: FC = ({ -- cgit v1.2.3