@transferwise/components 0.0.0-experimental-4af964d → 0.0.0-experimental-04f7ce3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,123 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-webpack5';
2
+ import { expect, userEvent, within } from 'storybook/test';
3
+ import { useState } from 'react';
4
+
5
+ import { withVariantConfig } from '../../.storybook/helpers';
6
+ import { Field } from '../field/Field';
7
+ import Switch from './Switch';
8
+
9
+ export default {
10
+ component: Switch,
11
+ title: 'Actions/Switch/Tests',
12
+ tags: ['!autodocs', '!manifest'],
13
+ } satisfies Meta<typeof Switch>;
14
+
15
+ type Story = StoryObj<typeof Switch>;
16
+
17
+ /** All switch states across all themes. */
18
+ export const Variants: Story = {
19
+ render: function Render() {
20
+ const [unchecked, setUnchecked] = useState(false);
21
+ const [checked, setChecked] = useState(true);
22
+
23
+ return (
24
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '16px', padding: '16px' }}>
25
+ <Field label="Unchecked">
26
+ <Switch checked={unchecked} onClick={() => setUnchecked((v) => !v)} />
27
+ </Field>
28
+ <Field label="Checked">
29
+ <Switch checked={checked} onClick={() => setChecked((v) => !v)} />
30
+ </Field>
31
+ <Field label="Disabled (off)">
32
+ <Switch checked={false} disabled onClick={() => {}} />
33
+ </Field>
34
+ <Field label="Disabled (on)">
35
+ <Switch checked disabled onClick={() => {}} />
36
+ </Field>
37
+ </div>
38
+ );
39
+ },
40
+ ...withVariantConfig(['default', 'dark', 'bright-green', 'forest-green']),
41
+ };
42
+
43
+ /**
44
+ * Tests keyboard navigation and interaction:
45
+ * - Tab focuses the switch
46
+ * - Space toggles the switch on and off
47
+ */
48
+ export const KeyboardInteraction: Story = {
49
+ render: function Render() {
50
+ const [checked, setChecked] = useState(false);
51
+ return (
52
+ <Field id="notif-field" label="Email notifications">
53
+ <Switch checked={checked} onClick={() => setChecked((v) => !v)} />
54
+ </Field>
55
+ );
56
+ },
57
+ play: async ({ canvasElement, step }) => {
58
+ const wait = async (ms: number) =>
59
+ new Promise<void>((resolve) => {
60
+ setTimeout(resolve, ms);
61
+ });
62
+ const canvas = within(canvasElement);
63
+ const switchEl = canvas.getByRole('switch');
64
+
65
+ await step('tab focuses the switch', async () => {
66
+ await userEvent.tab();
67
+ await expect(switchEl).toHaveFocus();
68
+ });
69
+
70
+ await wait(400);
71
+
72
+ await step('space toggles the switch on', async () => {
73
+ await userEvent.keyboard(' ');
74
+ await expect(switchEl).toHaveAttribute('aria-checked', 'true');
75
+ });
76
+
77
+ await wait(400);
78
+
79
+ await step('space toggles the switch off', async () => {
80
+ await userEvent.keyboard(' ');
81
+ await expect(switchEl).toHaveAttribute('aria-checked', 'false');
82
+ });
83
+ },
84
+ };
85
+
86
+ /** Switch rendered in RTL mode. */
87
+ export const RTL: Story = {
88
+ render: function Render() {
89
+ const [unchecked, setUnchecked] = useState(false);
90
+ const [checked, setChecked] = useState(true);
91
+
92
+ return (
93
+ <div style={{ display: 'flex', flexDirection: 'column', gap: '16px', padding: '16px' }}>
94
+ <Field label="Unchecked">
95
+ <Switch checked={unchecked} onClick={() => setUnchecked((v) => !v)} />
96
+ </Field>
97
+ <Field label="Checked">
98
+ <Switch checked={checked} onClick={() => setChecked((v) => !v)} />
99
+ </Field>
100
+ <Field label="Disabled (off)">
101
+ <Switch checked={false} disabled onClick={() => {}} />
102
+ </Field>
103
+ <Field label="Disabled (on)">
104
+ <Switch checked disabled onClick={() => {}} />
105
+ </Field>
106
+ </div>
107
+ );
108
+ },
109
+ ...withVariantConfig(['rtl']),
110
+ };
111
+
112
+ /** Switch at 400% zoom for accessibility testing. */
113
+ export const Zoom400: Story = {
114
+ render: function Render() {
115
+ const [checked, setChecked] = useState(false);
116
+ return (
117
+ <Field label="Email notifications">
118
+ <Switch checked={checked} onClick={() => setChecked((v) => !v)} />
119
+ </Field>
120
+ );
121
+ },
122
+ ...withVariantConfig(['400%']),
123
+ };