import type { Meta, StoryObj } from '@storybook/react-webpack5'; import { expect, userEvent, within } from 'storybook/test'; import { useState } from 'react'; import { withVariantConfig } from '../../.storybook/helpers'; import { Field } from '../field/Field'; import Switch from './Switch'; export default { component: Switch, title: 'Actions/Switch/Tests', tags: ['!autodocs', '!manifest'], } satisfies Meta; type Story = StoryObj; /** All switch states across all themes. */ export const Variants: Story = { render: function Render() { const [unchecked, setUnchecked] = useState(false); const [checked, setChecked] = useState(true); return (
setUnchecked((v) => !v)} /> setChecked((v) => !v)} /> {}} /> {}} />
); }, ...withVariantConfig(['default', 'dark', 'bright-green', 'forest-green']), }; /** * Tests keyboard navigation and interaction: * - Tab focuses the switch * - Space toggles the switch on and off */ export const KeyboardInteraction: Story = { render: function Render() { const [checked, setChecked] = useState(false); return ( setChecked((v) => !v)} /> ); }, play: async ({ canvasElement, step }) => { const wait = async (ms: number) => new Promise((resolve) => { setTimeout(resolve, ms); }); const canvas = within(canvasElement); const switchEl = canvas.getByRole('switch'); await step('tab focuses the switch', async () => { await userEvent.tab(); await expect(switchEl).toHaveFocus(); }); await wait(400); await step('space toggles the switch on', async () => { await userEvent.keyboard(' '); await expect(switchEl).toHaveAttribute('aria-checked', 'true'); }); await wait(400); await step('space toggles the switch off', async () => { await userEvent.keyboard(' '); await expect(switchEl).toHaveAttribute('aria-checked', 'false'); }); }, }; /** Switch rendered in RTL mode. */ export const RTL: Story = { render: function Render() { const [unchecked, setUnchecked] = useState(false); const [checked, setChecked] = useState(true); return (
setUnchecked((v) => !v)} /> setChecked((v) => !v)} /> {}} /> {}} />
); }, ...withVariantConfig(['rtl']), }; /** Switch at 400% zoom for accessibility testing. */ export const Zoom400: Story = { render: function Render() { const [checked, setChecked] = useState(false); return ( setChecked((v) => !v)} /> ); }, ...withVariantConfig(['400%']), };