aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/organisms/forms/settings-form/prism-theme-toggle
diff options
context:
space:
mode:
authorArmand Philippot <git@armandphilippot.com>2023-10-30 12:44:11 +0100
committerArmand Philippot <git@armandphilippot.com>2023-11-11 18:15:27 +0100
commit0e52a59917406ad03c174e030c6c1c92ab23449d (patch)
tree693bbcc5edbe78ebd2f0050fddbc45c706e0ba61 /src/components/organisms/forms/settings-form/prism-theme-toggle
parent84a679b0e48ed76eee2fa44d3caac83591aa3c8c (diff)
refactor(components): extract SettingsForm component form SettingsModal
We could use an array of items and map over it instead of repeating the Switch component for each settings but with translations, it becomes quickly unreadable. So I prefer to keep separate components.
Diffstat (limited to 'src/components/organisms/forms/settings-form/prism-theme-toggle')
-rw-r--r--src/components/organisms/forms/settings-form/prism-theme-toggle/index.ts1
-rw-r--r--src/components/organisms/forms/settings-form/prism-theme-toggle/prism-theme-toggle.stories.tsx20
-rw-r--r--src/components/organisms/forms/settings-form/prism-theme-toggle/prism-theme-toggle.test.tsx27
-rw-r--r--src/components/organisms/forms/settings-form/prism-theme-toggle/prism-theme-toggle.tsx78
4 files changed, 126 insertions, 0 deletions
diff --git a/src/components/organisms/forms/settings-form/prism-theme-toggle/index.ts b/src/components/organisms/forms/settings-form/prism-theme-toggle/index.ts
new file mode 100644
index 0000000..f4e490f
--- /dev/null
+++ b/src/components/organisms/forms/settings-form/prism-theme-toggle/index.ts
@@ -0,0 +1 @@
+export * from './prism-theme-toggle';
diff --git a/src/components/organisms/forms/settings-form/prism-theme-toggle/prism-theme-toggle.stories.tsx b/src/components/organisms/forms/settings-form/prism-theme-toggle/prism-theme-toggle.stories.tsx
new file mode 100644
index 0000000..9313bf2
--- /dev/null
+++ b/src/components/organisms/forms/settings-form/prism-theme-toggle/prism-theme-toggle.stories.tsx
@@ -0,0 +1,20 @@
+import type { ComponentMeta, ComponentStory } from '@storybook/react';
+import { PrismThemeToggle } from './prism-theme-toggle';
+
+/**
+ * PrismThemeToggle - Storybook Meta
+ */
+export default {
+ title: 'Organisms/Forms/Settings/Items',
+ component: PrismThemeToggle,
+ argTypes: {},
+} as ComponentMeta<typeof PrismThemeToggle>;
+
+const Template: ComponentStory<typeof PrismThemeToggle> = (args) => (
+ <PrismThemeToggle {...args} />
+);
+
+/**
+ * Toggle Stories - Prism theme
+ */
+export const PrismTheme = Template.bind({});
diff --git a/src/components/organisms/forms/settings-form/prism-theme-toggle/prism-theme-toggle.test.tsx b/src/components/organisms/forms/settings-form/prism-theme-toggle/prism-theme-toggle.test.tsx
new file mode 100644
index 0000000..b9f05c4
--- /dev/null
+++ b/src/components/organisms/forms/settings-form/prism-theme-toggle/prism-theme-toggle.test.tsx
@@ -0,0 +1,27 @@
+import { describe, expect, it } from '@jest/globals';
+import { render, screen as rtlScreen } from '../../../../../../tests/utils';
+import { PrismThemeProvider } from '../../../../../utils/providers';
+import { PrismThemeToggle } from './prism-theme-toggle';
+
+describe('PrismThemeToggle', () => {
+ it('renders a radio group of two radio buttons', () => {
+ const defaultTheme = 'dark';
+
+ render(
+ <PrismThemeProvider
+ attribute="fuga"
+ storageKey="sed"
+ defaultTheme={defaultTheme}
+ >
+ <PrismThemeToggle />
+ </PrismThemeProvider>
+ );
+
+ expect(
+ rtlScreen.getByRole('radiogroup', {
+ name: /Code blocks:/i,
+ })
+ ).toBeInTheDocument();
+ expect(rtlScreen.getAllByRole('radio')).toHaveLength(2);
+ });
+});
diff --git a/src/components/organisms/forms/settings-form/prism-theme-toggle/prism-theme-toggle.tsx b/src/components/organisms/forms/settings-form/prism-theme-toggle/prism-theme-toggle.tsx
new file mode 100644
index 0000000..b427754
--- /dev/null
+++ b/src/components/organisms/forms/settings-form/prism-theme-toggle/prism-theme-toggle.tsx
@@ -0,0 +1,78 @@
+import { forwardRef, type ForwardRefRenderFunction } from 'react';
+import { useIntl } from 'react-intl';
+import { usePrismTheme } from '../../../../../utils/hooks';
+import { Icon, Legend } from '../../../../atoms';
+import {
+ Switch,
+ type SwitchOption,
+ type SwitchProps,
+} from '../../../../molecules';
+
+export type PrismThemeToggleProps = Omit<
+ SwitchProps,
+ 'isInline' | 'items' | 'legend' | 'name' | 'onSwitch' | 'value'
+>;
+
+const PrismThemeToggleWithRef: ForwardRefRenderFunction<
+ HTMLFieldSetElement,
+ PrismThemeToggleProps
+> = (props, ref) => {
+ const intl = useIntl();
+ const { currentTheme, toggleTheme } = usePrismTheme();
+
+ const messages = {
+ legend: intl.formatMessage({
+ defaultMessage: 'Code blocks:',
+ description: 'PrismThemeToggle: theme label',
+ id: 'ftXN+0',
+ }),
+ options: {
+ dark: intl.formatMessage({
+ defaultMessage: 'Dark theme',
+ description: 'PrismThemeToggle: dark theme label',
+ id: 'og/zWL',
+ }),
+ light: intl.formatMessage({
+ defaultMessage: 'Light theme',
+ description: 'PrismThemeToggle: light theme label',
+ id: 'tsWh8x',
+ }),
+ },
+ };
+
+ const options: [SwitchOption, SwitchOption] = [
+ {
+ id: 'code-blocks-light',
+ // eslint-disable-next-line react/jsx-no-literals
+ label: <Icon aria-label={messages.options.light} shape="sun" size="sm" />,
+ value: 'light',
+ },
+ {
+ id: 'code-blocks-dark',
+ // eslint-disable-next-line react/jsx-no-literals
+ label: <Icon aria-label={messages.options.dark} shape="moon" size="sm" />,
+ value: 'dark',
+ },
+ ];
+
+ return (
+ <Switch
+ {...props}
+ isInline
+ items={options}
+ legend={<Legend>{messages.legend}</Legend>}
+ // eslint-disable-next-line react/jsx-no-literals
+ name="code-blocks"
+ onSwitch={toggleTheme}
+ ref={ref}
+ value={currentTheme}
+ />
+ );
+};
+
+/**
+ * PrismThemeToggle component
+ *
+ * Render a Toggle component to set code blocks theme.
+ */
+export const PrismThemeToggle = forwardRef(PrismThemeToggleWithRef);