summaryrefslogtreecommitdiffstats
path: root/src/components/organisms/modals
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/organisms/modals')
-rw-r--r--src/components/organisms/modals/settings-modal.module.scss46
-rw-r--r--src/components/organisms/modals/settings-modal.stories.tsx9
-rw-r--r--src/components/organisms/modals/settings-modal.test.tsx32
-rw-r--r--src/components/organisms/modals/settings-modal.tsx84
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>
);
};