diff options
Diffstat (limited to 'src/components/organisms/modals')
4 files changed, 150 insertions, 21 deletions
diff --git a/src/components/organisms/modals/settings-modal.module.scss b/src/components/organisms/modals/settings-modal.module.scss new file mode 100644 index 0000000..fef3492 --- /dev/null +++ b/src/components/organisms/modals/settings-modal.module.scss @@ -0,0 +1,46 @@ +@use "@styles/abstracts/functions" as fun; +@use "@styles/abstracts/variables" as var; + +.wrapper { + width: 100%; + + @media screen and (max-height: #{var.get-breakpoint("2xs")}) and (max-width: #{var.get-breakpoint("sm")}) { + --first-col-width: #{fun.convert-px(160)}; + --col-gap: var(--spacing-xl); + + display: grid; + grid-template-columns: var(--first-col-width) 1fr; + gap: var(--spacing-xl); + } +} + +.form { + display: flex; + flex-flow: row wrap; + column-gap: var(--spacing-lg); +} + +.items { + margin: 0 0 var(--spacing-2xs); + max-width: unset; +} + +.fieldset__body { + margin-left: auto; +} + +.tooltip { + font-size: var(--font-size-sm); + z-index: 2; + + @media screen and (max-height: #{var.get-breakpoint("2xs")}) { + width: calc(100vw - var(--spacing-md)); + padding: var(--spacing-md) var(--spacing-2xs) var(--spacing-2xs) + var(--spacing-2xs); + right: 0; + } + + @media screen and (min-width: #{var.get-breakpoint("sm")}) { + width: 100%; + } +} diff --git a/src/components/organisms/modals/settings-modal.stories.tsx b/src/components/organisms/modals/settings-modal.stories.tsx index d263e2b..649d68b 100644 --- a/src/components/organisms/modals/settings-modal.stories.tsx +++ b/src/components/organisms/modals/settings-modal.stories.tsx @@ -1,3 +1,5 @@ +import { storageKey as ackeeStorageKey } from '@components/molecules/forms/ackee-toggle.fixture'; +import { storageKey as motionStorageKey } from '@components/molecules/forms/motion-toggle.fixture'; import { ComponentMeta, ComponentStory } from '@storybook/react'; import SettingsModal from './settings-modal'; @@ -55,6 +57,9 @@ export default { }, }, }, + parameters: { + layout: 'fullscreen', + }, } as ComponentMeta<typeof SettingsModal>; const Template: ComponentStory<typeof SettingsModal> = (args) => ( @@ -65,3 +70,7 @@ const Template: ComponentStory<typeof SettingsModal> = (args) => ( * Modals Stories - Settings */ export const Settings = Template.bind({}); +Settings.args = { + ackeeStorageKey, + motionStorageKey, +}; diff --git a/src/components/organisms/modals/settings-modal.test.tsx b/src/components/organisms/modals/settings-modal.test.tsx index 91f77de..9277067 100644 --- a/src/components/organisms/modals/settings-modal.test.tsx +++ b/src/components/organisms/modals/settings-modal.test.tsx @@ -1,14 +1,40 @@ +import { storageKey as ackeeStorageKey } from '@components/molecules/forms/ackee-toggle.fixture'; +import { storageKey as motionStorageKey } from '@components/molecules/forms/motion-toggle.fixture'; import { render, screen } from '@tests/utils'; import SettingsModal from './settings-modal'; describe('SettingsModal', () => { - it('renders a fake heading', () => { + it('renders the modal heading', () => { render( <SettingsModal - ackeeStorageKey="ackee-tracking" - motionStorageKey="reduce-motion" + ackeeStorageKey={ackeeStorageKey} + motionStorageKey={motionStorageKey} /> ); expect(screen.getByText(/Settings/i)).toBeInTheDocument(); }); + + it('renders a settings form', () => { + render( + <SettingsModal + ackeeStorageKey={ackeeStorageKey} + motionStorageKey={motionStorageKey} + /> + ); + expect( + screen.getByRole('form', { name: /^Settings form/i }) + ).toBeInTheDocument(); + expect( + screen.getByRole('radiogroup', { name: /^Theme:/i }) + ).toBeInTheDocument(); + expect( + screen.getByRole('radiogroup', { name: /^Code blocks:/i }) + ).toBeInTheDocument(); + expect( + screen.getByRole('radiogroup', { name: /^Animations:/i }) + ).toBeInTheDocument(); + expect( + screen.getByRole('radiogroup', { name: /^Tracking:/i }) + ).toBeInTheDocument(); + }); }); diff --git a/src/components/organisms/modals/settings-modal.tsx b/src/components/organisms/modals/settings-modal.tsx index 0ab6b7a..d11dfe7 100644 --- a/src/components/organisms/modals/settings-modal.tsx +++ b/src/components/organisms/modals/settings-modal.tsx @@ -1,23 +1,28 @@ -import Spinner from '@components/atoms/loaders/spinner'; +import Form from '@components/atoms/forms/form'; +import AckeeToggle, { + AckeeToggleProps, +} from '@components/molecules/forms/ackee-toggle'; +import MotionToggle, { + MotionToggleProps, +} from '@components/molecules/forms/motion-toggle'; +import PrismThemeToggle from '@components/molecules/forms/prism-theme-toggle'; +import ThemeToggle from '@components/molecules/forms/theme-toggle'; import Modal, { type ModalProps } from '@components/molecules/modals/modal'; -import dynamic from 'next/dynamic'; import { FC } from 'react'; import { useIntl } from 'react-intl'; -import { type SettingsFormProps } from '../forms/settings-form'; - -const DynamicSettingsForm = dynamic( - () => import('@components/organisms/forms/settings-form'), - { - loading: () => <Spinner />, - ssr: false, - } -); +import styles from './settings-modal.module.scss'; export type SettingsModalProps = Pick<ModalProps, 'className'> & - Pick< - SettingsFormProps, - 'ackeeStorageKey' | 'motionStorageKey' | 'tooltipClassName' - >; + Pick<AckeeToggleProps, 'tooltipClassName'> & { + /** + * The local storage key for Ackee settings. + */ + ackeeStorageKey: AckeeToggleProps['storageKey']; + /** + * The local storage key for Reduce motion settings. + */ + motionStorageKey: MotionToggleProps['storageKey']; + }; /** * SettingsModal component @@ -26,7 +31,9 @@ export type SettingsModalProps = Pick<ModalProps, 'className'> & */ const SettingsModal: FC<SettingsModalProps> = ({ className = '', - ...props + ackeeStorageKey, + motionStorageKey, + tooltipClassName, }) => { const intl = useIntl(); const title = intl.formatMessage({ @@ -34,10 +41,51 @@ const SettingsModal: FC<SettingsModalProps> = ({ description: 'SettingsModal: title', id: 'gPfT/K', }); + const ariaLabel = intl.formatMessage({ + defaultMessage: 'Settings form', + id: 'xYNeKX', + description: 'SettingsModal: an accessible form name', + }); return ( - <Modal title={title} icon="cogs" className={className}> - <DynamicSettingsForm {...props} /> + <Modal + title={title} + icon="cogs" + className={`${styles.wrapper} ${className}`} + > + <Form + aria-label={ariaLabel} + className={styles.form} + itemsClassName={styles.items} + onSubmit={() => null} + > + <ThemeToggle + bodyClassName={styles.fieldset__body} + groupClassName={styles.group} + legendClassName={styles.label} + /> + <PrismThemeToggle + bodyClassName={styles.fieldset__body} + groupClassName={styles.group} + legendClassName={styles.label} + /> + <MotionToggle + defaultValue="on" + bodyClassName={styles.fieldset__body} + groupClassName={styles.group} + legendClassName={styles.label} + storageKey={motionStorageKey} + /> + <AckeeToggle + defaultValue="full" + bodyClassName={styles.fieldset__body} + buttonClassName={styles.btn} + groupClassName={`${styles.group} ${styles['group--ackee']}`} + legendClassName={`${styles.label} ${styles['label--ackee']}`} + storageKey={ackeeStorageKey} + tooltipClassName={`${styles.tooltip} ${tooltipClassName}`} + /> + </Form> </Modal> ); }; |
