reshaped 3.7.0-canary.1 → 3.7.0-canary.3
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.
- package/CHANGELOG.md +2 -0
- package/dist/bundle.css +1 -1
- package/dist/bundle.js +9 -9
- package/dist/components/Tabs/Tabs.module.css +1 -1
- package/dist/components/Tabs/Tabs.types.d.ts +1 -0
- package/dist/components/Tabs/TabsItem.js +2 -2
- package/dist/components/Tabs/tests/Tabs.stories.d.ts +47 -10
- package/dist/components/Tabs/tests/Tabs.stories.js +481 -303
- package/dist/components/View/View.js +2 -2
- package/dist/components/View/tests/View.stories.d.ts +4 -0
- package/dist/components/View/tests/View.stories.js +24 -1
- package/package.json +1 -1
- package/dist/components/Tabs/tests/Tabs.test.stories.d.ts +0 -27
- package/dist/components/Tabs/tests/Tabs.test.stories.js +0 -128
@@ -1,4 +1,5 @@
|
|
1
1
|
import React from "react";
|
2
|
+
import { expect, fn, userEvent, waitFor, within } from "storybook/test";
|
2
3
|
import { Example } from "../../../utilities/storybook/index.js";
|
3
4
|
import Tabs from "../index.js";
|
4
5
|
import View from "../../View/index.js";
|
@@ -15,347 +16,524 @@ export default {
|
|
15
16
|
},
|
16
17
|
},
|
17
18
|
};
|
18
|
-
export const
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
</Tabs.List>
|
26
|
-
</Tabs>
|
27
|
-
</Example.Item>
|
28
|
-
|
29
|
-
<Example.Item title="variant: pills">
|
30
|
-
<Tabs variant="pills">
|
31
|
-
<Tabs.List>
|
32
|
-
<Tabs.Item value="0">Item 1</Tabs.Item>
|
33
|
-
<Tabs.Item value="1">Long item 2</Tabs.Item>
|
34
|
-
<Tabs.Item value="2">Very long item 3</Tabs.Item>
|
35
|
-
</Tabs.List>
|
36
|
-
</Tabs>
|
37
|
-
</Example.Item>
|
19
|
+
export const base = {
|
20
|
+
name: "base",
|
21
|
+
render: () => (<Tabs>
|
22
|
+
<Tabs.List>
|
23
|
+
<Tabs.Item value="1">Item 1</Tabs.Item>
|
24
|
+
<Tabs.Item value="2">Item 2</Tabs.Item>
|
25
|
+
</Tabs.List>
|
38
26
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
27
|
+
<Tabs.Panel value="1">
|
28
|
+
<View padding={4}>Content 1</View>
|
29
|
+
</Tabs.Panel>
|
30
|
+
<Tabs.Panel value="2">
|
31
|
+
<View padding={4}>Content 2</View>
|
32
|
+
</Tabs.Panel>
|
33
|
+
</Tabs>),
|
34
|
+
play: async ({ canvas }) => {
|
35
|
+
const list = canvas.getByRole("tablist");
|
36
|
+
const items = canvas.getAllByRole("tab");
|
37
|
+
const panels = canvas.getAllByRole("tabpanel", { hidden: true });
|
38
|
+
expect(list).toBeInTheDocument();
|
39
|
+
expect(items).toHaveLength(2);
|
40
|
+
expect(panels).toHaveLength(2);
|
41
|
+
expect(panels[0]).toBeVisible();
|
42
|
+
expect(panels[1]).not.toBeVisible();
|
43
|
+
const selectedItem = items[0];
|
44
|
+
const selectedPanel = panels[0];
|
45
|
+
expect(selectedItem).toHaveAttribute("aria-selected", "true");
|
46
|
+
expect(selectedItem.getAttribute("aria-controls")).toBe(selectedPanel.getAttribute("id"));
|
47
|
+
const unselectedItem = items[1];
|
48
|
+
const unselectedPanel = panels[1];
|
49
|
+
expect(unselectedItem).toHaveAttribute("aria-selected", "false");
|
50
|
+
expect(unselectedItem.getAttribute("aria-controls")).toBe(unselectedPanel.getAttribute("id"));
|
51
|
+
await userEvent.tab();
|
52
|
+
expect(document.activeElement).toBe(items[0]);
|
53
|
+
await userEvent.tab();
|
54
|
+
waitFor(() => {
|
55
|
+
expect(document.activeElement).toBe(panels[0]);
|
56
|
+
});
|
57
|
+
},
|
58
|
+
};
|
59
|
+
export const variant = {
|
60
|
+
name: "variant",
|
61
|
+
render: () => (<Example>
|
62
|
+
<Example.Item title="variant: default">
|
63
|
+
<Tabs>
|
64
|
+
<Tabs.List>
|
65
|
+
<Tabs.Item value="1">Long item 2</Tabs.Item>
|
66
|
+
<Tabs.Item value="0">Item 1</Tabs.Item>
|
67
|
+
<Tabs.Item value="2">Very long item 3</Tabs.Item>
|
68
|
+
</Tabs.List>
|
69
|
+
</Tabs>
|
70
|
+
</Example.Item>
|
48
71
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
</Example>);
|
59
|
-
export const size = () => (<Example>
|
60
|
-
<Example.Item title="variant: default, size: large">
|
61
|
-
<Tabs size="large">
|
62
|
-
<Tabs.List>
|
63
|
-
<Tabs.Item value="0">Item 1</Tabs.Item>
|
64
|
-
<Tabs.Item value="1">Long item 2</Tabs.Item>
|
65
|
-
<Tabs.Item value="2">Very long item 3</Tabs.Item>
|
66
|
-
</Tabs.List>
|
67
|
-
</Tabs>
|
68
|
-
</Example.Item>
|
72
|
+
<Example.Item title="variant: pills">
|
73
|
+
<Tabs variant="pills">
|
74
|
+
<Tabs.List>
|
75
|
+
<Tabs.Item value="0">Item 1</Tabs.Item>
|
76
|
+
<Tabs.Item value="1">Long item 2</Tabs.Item>
|
77
|
+
<Tabs.Item value="2">Very long item 3</Tabs.Item>
|
78
|
+
</Tabs.List>
|
79
|
+
</Tabs>
|
80
|
+
</Example.Item>
|
69
81
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
82
|
+
<Example.Item title="variant: pills-elevated">
|
83
|
+
<Tabs variant="pills-elevated">
|
84
|
+
<Tabs.List>
|
85
|
+
<Tabs.Item value="0">Item 1</Tabs.Item>
|
86
|
+
<Tabs.Item value="1">Long item 2</Tabs.Item>
|
87
|
+
<Tabs.Item value="2">Very long item 3</Tabs.Item>
|
88
|
+
</Tabs.List>
|
89
|
+
</Tabs>
|
90
|
+
</Example.Item>
|
79
91
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
92
|
+
<Example.Item title="variant: borderless">
|
93
|
+
<Tabs variant="borderless">
|
94
|
+
<Tabs.List>
|
95
|
+
<Tabs.Item value="0">Item 1</Tabs.Item>
|
96
|
+
<Tabs.Item value="1">Long item 2</Tabs.Item>
|
97
|
+
<Tabs.Item value="2">Very long item 3</Tabs.Item>
|
98
|
+
</Tabs.List>
|
99
|
+
</Tabs>
|
100
|
+
</Example.Item>
|
101
|
+
</Example>),
|
102
|
+
};
|
103
|
+
export const size = {
|
104
|
+
name: "size",
|
105
|
+
render: () => (<Example>
|
106
|
+
<Example.Item title="variant: default, size: large">
|
107
|
+
<Tabs size="large">
|
108
|
+
<Tabs.List>
|
109
|
+
<Tabs.Item value="0">Item 1</Tabs.Item>
|
110
|
+
<Tabs.Item value="1">Long item 2</Tabs.Item>
|
111
|
+
<Tabs.Item value="2">Very long item 3</Tabs.Item>
|
112
|
+
</Tabs.List>
|
113
|
+
</Tabs>
|
114
|
+
</Example.Item>
|
89
115
|
|
90
|
-
|
91
|
-
|
92
|
-
<Tabs.List>
|
93
|
-
<Tabs.Item value="0">Item 1</Tabs.Item>
|
94
|
-
<Tabs.Item value="1">Long item 2</Tabs.Item>
|
95
|
-
<Tabs.Item value="2">Very long item 3</Tabs.Item>
|
96
|
-
</Tabs.List>
|
97
|
-
</Tabs>
|
98
|
-
</Example.Item>
|
99
|
-
</Example>);
|
100
|
-
export const direction = () => (<Example>
|
101
|
-
<Example.Item title="direction: column, variant: underline">
|
102
|
-
<Tabs direction="column">
|
103
|
-
<Tabs.List>
|
104
|
-
<Tabs.Item value="0">Item 1</Tabs.Item>
|
105
|
-
<Tabs.Item value="1">Long item 2</Tabs.Item>
|
106
|
-
<Tabs.Item value="2">Very long item 3</Tabs.Item>
|
107
|
-
<Tabs.Item value="3">Very long item 3</Tabs.Item>
|
108
|
-
</Tabs.List>
|
109
|
-
</Tabs>
|
110
|
-
</Example.Item>
|
111
|
-
<Example.Item title="direction: column, variant: pills">
|
112
|
-
<Tabs direction="column" variant="pills">
|
113
|
-
<Tabs.List>
|
114
|
-
<Tabs.Item value="0">Item 1</Tabs.Item>
|
115
|
-
<Tabs.Item value="1">Long item 2</Tabs.Item>
|
116
|
-
<Tabs.Item value="2">Very long item 3</Tabs.Item>
|
117
|
-
</Tabs.List>
|
118
|
-
</Tabs>
|
119
|
-
</Example.Item>
|
120
|
-
<Example.Item title="direction: column, variant: pills-elevated">
|
121
|
-
<Tabs direction="column" variant="pills-elevated">
|
122
|
-
<Tabs.List>
|
123
|
-
<Tabs.Item value="0">Item 1</Tabs.Item>
|
124
|
-
<Tabs.Item value="1">Long item 2</Tabs.Item>
|
125
|
-
<Tabs.Item value="2">Very long item 3</Tabs.Item>
|
126
|
-
</Tabs.List>
|
127
|
-
</Tabs>
|
128
|
-
</Example.Item>
|
129
|
-
</Example>);
|
130
|
-
export const composition = () => (<Example>
|
131
|
-
<Example.Item title="panels without focusable content">
|
132
|
-
<Tabs>
|
133
|
-
<View gap={4}>
|
116
|
+
<Example.Item title="variant: pills, size: large">
|
117
|
+
<Tabs variant="pills" size="large">
|
134
118
|
<Tabs.List>
|
135
119
|
<Tabs.Item value="0">Item 1</Tabs.Item>
|
136
120
|
<Tabs.Item value="1">Long item 2</Tabs.Item>
|
137
121
|
<Tabs.Item value="2">Very long item 3</Tabs.Item>
|
138
122
|
</Tabs.List>
|
123
|
+
</Tabs>
|
124
|
+
</Example.Item>
|
139
125
|
|
140
|
-
|
141
|
-
|
142
|
-
<Tabs.
|
143
|
-
|
144
|
-
|
145
|
-
|
126
|
+
<Example.Item title="variant: pills-elevated, size: large">
|
127
|
+
<Tabs variant="pills-elevated" size="large">
|
128
|
+
<Tabs.List>
|
129
|
+
<Tabs.Item value="0">Item 1</Tabs.Item>
|
130
|
+
<Tabs.Item value="1">Long item 2</Tabs.Item>
|
131
|
+
<Tabs.Item value="2">Very long item 3</Tabs.Item>
|
132
|
+
</Tabs.List>
|
133
|
+
</Tabs>
|
134
|
+
</Example.Item>
|
146
135
|
|
147
|
-
|
148
|
-
|
149
|
-
|
136
|
+
<Example.Item title="variant: borderless, size: large">
|
137
|
+
<Tabs variant="borderless" size="large">
|
138
|
+
<Tabs.List>
|
139
|
+
<Tabs.Item value="0">Item 1</Tabs.Item>
|
140
|
+
<Tabs.Item value="1">Long item 2</Tabs.Item>
|
141
|
+
<Tabs.Item value="2">Very long item 3</Tabs.Item>
|
142
|
+
</Tabs.List>
|
143
|
+
</Tabs>
|
144
|
+
</Example.Item>
|
145
|
+
</Example>),
|
146
|
+
};
|
147
|
+
export const direction = {
|
148
|
+
name: "direction",
|
149
|
+
render: () => (<Example>
|
150
|
+
<Example.Item title="direction: column, variant: underline">
|
151
|
+
<Tabs direction="column">
|
152
|
+
<Tabs.List>
|
153
|
+
<Tabs.Item value="0">Item 1</Tabs.Item>
|
154
|
+
<Tabs.Item value="1">Long item 2</Tabs.Item>
|
155
|
+
<Tabs.Item value="2">Very long item 3</Tabs.Item>
|
156
|
+
</Tabs.List>
|
157
|
+
</Tabs>
|
158
|
+
</Example.Item>
|
159
|
+
<Example.Item title="direction: column, variant: pills">
|
160
|
+
<Tabs direction="column" variant="pills">
|
150
161
|
<Tabs.List>
|
151
162
|
<Tabs.Item value="0">Item 1</Tabs.Item>
|
152
163
|
<Tabs.Item value="1">Long item 2</Tabs.Item>
|
153
164
|
<Tabs.Item value="2">Very long item 3</Tabs.Item>
|
154
165
|
</Tabs.List>
|
166
|
+
</Tabs>
|
167
|
+
</Example.Item>
|
168
|
+
<Example.Item title="direction: column, variant: pills-elevated">
|
169
|
+
<Tabs direction="column" variant="pills-elevated">
|
170
|
+
<Tabs.List>
|
171
|
+
<Tabs.Item value="0">Item 1</Tabs.Item>
|
172
|
+
<Tabs.Item value="1">Long item 2</Tabs.Item>
|
173
|
+
<Tabs.Item value="2">Very long item 3</Tabs.Item>
|
174
|
+
</Tabs.List>
|
175
|
+
</Tabs>
|
176
|
+
</Example.Item>
|
177
|
+
<Example.Item title="direction: column, variant: borderless">
|
178
|
+
<Tabs direction="column" variant="borderless">
|
179
|
+
<Tabs.List>
|
180
|
+
<Tabs.Item value="0">Item 1</Tabs.Item>
|
181
|
+
<Tabs.Item value="1">Long item 2</Tabs.Item>
|
182
|
+
<Tabs.Item value="2">Very long item 3</Tabs.Item>
|
183
|
+
</Tabs.List>
|
184
|
+
</Tabs>
|
185
|
+
</Example.Item>
|
186
|
+
</Example>),
|
187
|
+
};
|
188
|
+
export const icon = {
|
189
|
+
name: "icon",
|
190
|
+
render: () => (<Example>
|
191
|
+
<Example.Item title="icon">
|
192
|
+
<Tabs>
|
193
|
+
<Tabs.List>
|
194
|
+
<Tabs.Item value="0" icon={IconZap}>
|
195
|
+
Item 1
|
196
|
+
</Tabs.Item>
|
197
|
+
<Tabs.Item value="1" icon={IconZap}>
|
198
|
+
Long item 2
|
199
|
+
</Tabs.Item>
|
200
|
+
</Tabs.List>
|
201
|
+
</Tabs>
|
202
|
+
</Example.Item>
|
203
|
+
<Example.Item title="icon only">
|
204
|
+
<Tabs variant="pills-elevated">
|
205
|
+
<Tabs.List>
|
206
|
+
<Tabs.Item value="0" icon={IconZap} attributes={{ "aria-label": "Tab 1" }}/>
|
207
|
+
<Tabs.Item value="1" icon={IconZap} attributes={{ "aria-label": "Tab 2" }}/>
|
208
|
+
</Tabs.List>
|
209
|
+
</Tabs>
|
210
|
+
</Example.Item>
|
211
|
+
</Example>),
|
212
|
+
};
|
213
|
+
export const equalWidth = {
|
214
|
+
name: "itemWidth",
|
215
|
+
render: () => (<Example>
|
216
|
+
<Example.Item title="equal width items">
|
217
|
+
<Tabs onChange={console.log} itemWidth="equal">
|
218
|
+
<Tabs.List>
|
219
|
+
<Tabs.Item value="0" icon={IconZap}>
|
220
|
+
Item 1
|
221
|
+
</Tabs.Item>
|
222
|
+
<Tabs.Item value="1" icon={IconZap}>
|
223
|
+
Long item 2
|
224
|
+
</Tabs.Item>
|
225
|
+
<Tabs.Item value="2" icon={IconZap}>
|
226
|
+
Very long item 3
|
227
|
+
</Tabs.Item>
|
228
|
+
</Tabs.List>
|
229
|
+
</Tabs>
|
230
|
+
</Example.Item>
|
231
|
+
</Example>),
|
232
|
+
};
|
233
|
+
export const href = {
|
234
|
+
name: "href",
|
235
|
+
render: () => (<Example>
|
236
|
+
<Example.Item title="href, no onChange">
|
237
|
+
<Tabs value="2">
|
238
|
+
<Tabs.List>
|
239
|
+
<Tabs.Item value="1" href="#item-1" icon={IconZap}>
|
240
|
+
Item 1
|
241
|
+
</Tabs.Item>
|
242
|
+
<Tabs.Item value="2" href="#item-2" icon={IconZap}>
|
243
|
+
Long item 2
|
244
|
+
</Tabs.Item>
|
245
|
+
<Tabs.Item value="3" href="#item-3" icon={IconZap}>
|
246
|
+
Very long item 3
|
247
|
+
</Tabs.Item>
|
248
|
+
</Tabs.List>
|
249
|
+
</Tabs>
|
250
|
+
</Example.Item>
|
251
|
+
</Example>),
|
252
|
+
};
|
253
|
+
export const disabled = {
|
254
|
+
name: "item, disabled",
|
255
|
+
render: () => {
|
256
|
+
return (<Example>
|
257
|
+
<Example.Item title="disabled">
|
258
|
+
<Tabs defaultValue="1">
|
259
|
+
<Tabs.List>
|
260
|
+
<Tabs.Item value="1">Item 1</Tabs.Item>
|
261
|
+
<Tabs.Item value="2" disabled>
|
262
|
+
Item 2
|
263
|
+
</Tabs.Item>
|
264
|
+
<Tabs.Item value="3">Item 3</Tabs.Item>
|
265
|
+
</Tabs.List>
|
155
266
|
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
267
|
+
<Tabs.Panel value="1">
|
268
|
+
<View padding={4}>Content 1</View>
|
269
|
+
</Tabs.Panel>
|
270
|
+
<Tabs.Panel value="2">
|
271
|
+
<View padding={4}>Content 2</View>
|
272
|
+
</Tabs.Panel>
|
273
|
+
<Tabs.Panel value="3">
|
274
|
+
<View padding={4}>Content 3</View>
|
275
|
+
</Tabs.Panel>
|
276
|
+
</Tabs>
|
277
|
+
</Example.Item>
|
278
|
+
|
279
|
+
<Example.Item title="disabled, href">
|
280
|
+
<Tabs defaultValue="1">
|
281
|
+
<Tabs.List>
|
282
|
+
<Tabs.Item href="#item1" value="1">
|
283
|
+
Item 1
|
284
|
+
</Tabs.Item>
|
285
|
+
<Tabs.Item href="#item2" value="2" disabled>
|
286
|
+
Item 2
|
287
|
+
</Tabs.Item>
|
288
|
+
<Tabs.Item href="#item3" value="3">
|
289
|
+
Item 3
|
290
|
+
</Tabs.Item>
|
291
|
+
</Tabs.List>
|
292
|
+
|
293
|
+
<Tabs.Panel value="1">
|
294
|
+
<View padding={4}>Content 1</View>
|
295
|
+
</Tabs.Panel>
|
296
|
+
<Tabs.Panel value="2">
|
297
|
+
<View padding={4}>Content 2</View>
|
298
|
+
</Tabs.Panel>
|
299
|
+
<Tabs.Panel value="3">
|
300
|
+
<View padding={4}>Content 3</View>
|
301
|
+
</Tabs.Panel>
|
302
|
+
</Tabs>
|
303
|
+
</Example.Item>
|
304
|
+
</Example>);
|
305
|
+
},
|
306
|
+
play: ({ canvas }) => {
|
307
|
+
const items = canvas.getAllByRole("tab");
|
308
|
+
expect(items[0]).not.toBeDisabled();
|
309
|
+
expect(items[1]).toBeDisabled();
|
310
|
+
expect(items[2]).not.toBeDisabled();
|
311
|
+
expect(items[3]).toHaveAttribute("href");
|
312
|
+
expect(items[4]).not.toHaveAttribute("href");
|
313
|
+
expect(items[5]).toHaveAttribute("href");
|
314
|
+
},
|
315
|
+
};
|
316
|
+
export const defaultValue = {
|
317
|
+
name: "defaultValue, uncontrolled",
|
318
|
+
args: {
|
319
|
+
handleChange: fn(),
|
320
|
+
},
|
321
|
+
render: (args) => (<Tabs defaultValue="2" onChange={args.handleChange}>
|
322
|
+
<Tabs.List>
|
323
|
+
<Tabs.Item value="1">Item 1</Tabs.Item>
|
324
|
+
<Tabs.Item value="2">Item 2</Tabs.Item>
|
325
|
+
</Tabs.List>
|
326
|
+
|
327
|
+
<Tabs.Panel value="1">Content 1</Tabs.Panel>
|
328
|
+
<Tabs.Panel value="2">Content 2</Tabs.Panel>
|
329
|
+
</Tabs>),
|
330
|
+
play: async ({ canvas, args }) => {
|
331
|
+
const items = canvas.getAllByRole("tab");
|
332
|
+
expect(items[1]).toHaveAttribute("aria-selected", "true");
|
333
|
+
expect(items[1]).toHaveAttribute("tabindex", "0");
|
334
|
+
expect(items[0]).toHaveAttribute("tabindex", "-1");
|
335
|
+
await userEvent.click(items[0]);
|
336
|
+
expect(args.handleChange).toHaveBeenCalledTimes(1);
|
337
|
+
expect(args.handleChange).toHaveBeenCalledWith({ value: "1" });
|
338
|
+
expect(document.activeElement).toBe(items[0]);
|
339
|
+
expect(items[0]).toHaveAttribute("aria-selected", "true");
|
340
|
+
expect(items[0]).toHaveAttribute("tabindex", "0");
|
341
|
+
expect(items[1]).toHaveAttribute("tabindex", "-1");
|
342
|
+
},
|
343
|
+
};
|
344
|
+
export const value = {
|
345
|
+
name: "value, controlled",
|
346
|
+
args: {
|
347
|
+
handleChange: fn(),
|
348
|
+
},
|
349
|
+
render: (args) => (<Tabs value="2" onChange={args.handleChange}>
|
350
|
+
<Tabs.List>
|
351
|
+
<Tabs.Item value="1">Item 1</Tabs.Item>
|
352
|
+
<Tabs.Item value="2">Item 2</Tabs.Item>
|
353
|
+
</Tabs.List>
|
354
|
+
|
355
|
+
<Tabs.Panel value="1">Content 1</Tabs.Panel>
|
356
|
+
<Tabs.Panel value="2">Content 2</Tabs.Panel>
|
357
|
+
</Tabs>),
|
358
|
+
play: async ({ canvas, args }) => {
|
359
|
+
const items = canvas.getAllByRole("tab");
|
360
|
+
expect(items[1]).toHaveAttribute("aria-selected", "true");
|
361
|
+
expect(items[1]).toHaveAttribute("tabindex", "0");
|
362
|
+
expect(items[0]).toHaveAttribute("tabindex", "-1");
|
363
|
+
await userEvent.click(items[0]);
|
364
|
+
expect(args.handleChange).toHaveBeenCalledTimes(1);
|
365
|
+
expect(args.handleChange).toHaveBeenCalledWith({ value: "1" });
|
366
|
+
expect(document.activeElement).toBe(items[0]);
|
367
|
+
expect(items[1]).toHaveAttribute("aria-selected", "true");
|
368
|
+
expect(items[1]).toHaveAttribute("tabindex", "0");
|
369
|
+
expect(items[0]).toHaveAttribute("tabindex", "-1");
|
370
|
+
},
|
371
|
+
};
|
372
|
+
export const className = {
|
373
|
+
name: "className, attributes",
|
374
|
+
render: () => (<div data-testid="root">
|
171
375
|
<Tabs>
|
172
|
-
<Tabs.List>
|
173
|
-
<Tabs.Item
|
174
|
-
Item
|
175
|
-
</Tabs.Item>
|
176
|
-
<Tabs.Item value="1" icon={IconZap}>
|
177
|
-
Long item 2
|
178
|
-
</Tabs.Item>
|
179
|
-
</Tabs.List>
|
180
|
-
</Tabs>
|
181
|
-
</Example.Item>
|
182
|
-
<Example.Item title="icon only">
|
183
|
-
<Tabs variant="pills-elevated">
|
184
|
-
<Tabs.List>
|
185
|
-
<Tabs.Item value="0" icon={IconZap} attributes={{ "aria-label": "Tab 1" }}/>
|
186
|
-
<Tabs.Item value="1" icon={IconZap} attributes={{ "aria-label": "Tab 2" }}/>
|
187
|
-
</Tabs.List>
|
188
|
-
</Tabs>
|
189
|
-
</Example.Item>
|
190
|
-
</Example>);
|
191
|
-
export const equalWidth = () => (<Example>
|
192
|
-
<Example.Item title="equal width items">
|
193
|
-
<Tabs onChange={console.log} itemWidth="equal">
|
194
|
-
<Tabs.List>
|
195
|
-
<Tabs.Item value="0" icon={IconZap}>
|
196
|
-
Item 1
|
197
|
-
</Tabs.Item>
|
198
|
-
<Tabs.Item value="1" icon={IconZap}>
|
199
|
-
Long item 2
|
200
|
-
</Tabs.Item>
|
201
|
-
<Tabs.Item value="2" icon={IconZap}>
|
202
|
-
Very long item 3
|
203
|
-
</Tabs.Item>
|
204
|
-
</Tabs.List>
|
205
|
-
</Tabs>
|
206
|
-
</Example.Item>
|
207
|
-
</Example>);
|
208
|
-
export const selection = () => (<Example>
|
209
|
-
<Example.Item title="value: 2, uncontrolled">
|
210
|
-
<Tabs defaultValue="2">
|
211
|
-
<Tabs.List>
|
212
|
-
<Tabs.Item value="1" icon={IconZap}>
|
213
|
-
Item 1
|
214
|
-
</Tabs.Item>
|
215
|
-
<Tabs.Item value="2" icon={IconZap}>
|
216
|
-
Long item 2
|
217
|
-
</Tabs.Item>
|
218
|
-
<Tabs.Item value="3" icon={IconZap}>
|
219
|
-
Very long item 3
|
376
|
+
<Tabs.List attributes={{ id: "test-list-id" }} className="test-list-classname">
|
377
|
+
<Tabs.Item attributes={{ id: "test-item-id" }} value="1">
|
378
|
+
Item
|
220
379
|
</Tabs.Item>
|
221
380
|
</Tabs.List>
|
222
381
|
|
223
|
-
<Tabs.Panel value="1"
|
224
|
-
<Tabs.Panel value="2">Tab 2</Tabs.Panel>
|
225
|
-
<Tabs.Panel value="3">Tab 3</Tabs.Panel>
|
382
|
+
<Tabs.Panel attributes={{ "data-testid": "test-panel-id" }} className="test-panel-classname" value="1"/>
|
226
383
|
</Tabs>
|
227
|
-
</
|
384
|
+
</div>),
|
385
|
+
play: async ({ canvas }) => {
|
386
|
+
const list = canvas.getByTestId("root").firstChild;
|
387
|
+
const item = within(list).getByRole("presentation");
|
388
|
+
const panel = canvas.getByRole("tabpanel");
|
389
|
+
expect(list).toHaveClass("test-list-classname");
|
390
|
+
expect(list).toHaveAttribute("id", "test-list-id");
|
391
|
+
expect(item).toHaveAttribute("id", "test-item-id");
|
392
|
+
expect(panel).toHaveClass("test-panel-classname");
|
393
|
+
expect(panel).toHaveAttribute("data-testid", "test-panel-id");
|
394
|
+
},
|
395
|
+
};
|
396
|
+
export const testFocusableContent = {
|
397
|
+
name: "test: focusable content",
|
398
|
+
render: () => (<Example>
|
399
|
+
<Example.Item title="panels without focusable content">
|
400
|
+
<Tabs>
|
401
|
+
<View gap={4}>
|
402
|
+
<Tabs.List>
|
403
|
+
<Tabs.Item value="0">Item 1</Tabs.Item>
|
404
|
+
<Tabs.Item value="1">Long item 2</Tabs.Item>
|
405
|
+
<Tabs.Item value="2">Very long item 3</Tabs.Item>
|
406
|
+
</Tabs.List>
|
228
407
|
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
<Tabs.Item value="2" icon={IconZap}>
|
236
|
-
Long item 2
|
237
|
-
</Tabs.Item>
|
238
|
-
<Tabs.Item value="3" icon={IconZap}>
|
239
|
-
Very long item 3
|
240
|
-
</Tabs.Item>
|
241
|
-
</Tabs.List>
|
408
|
+
<Tabs.Panel value="0">Tab 1</Tabs.Panel>
|
409
|
+
<Tabs.Panel value="1">Tab 2</Tabs.Panel>
|
410
|
+
<Tabs.Panel value="2">Tab 3</Tabs.Panel>
|
411
|
+
</View>
|
412
|
+
</Tabs>
|
413
|
+
</Example.Item>
|
242
414
|
|
243
|
-
|
244
|
-
<Tabs
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
<Tabs value="2">
|
252
|
-
<Tabs.List>
|
253
|
-
<Tabs.Item value="1" href="#item-1" icon={IconZap}>
|
254
|
-
Item 1
|
255
|
-
</Tabs.Item>
|
256
|
-
<Tabs.Item value="2" href="#item-2" icon={IconZap}>
|
257
|
-
Long item 2
|
258
|
-
</Tabs.Item>
|
259
|
-
<Tabs.Item value="3" href="#item-3" icon={IconZap}>
|
260
|
-
Very long item 3
|
261
|
-
</Tabs.Item>
|
262
|
-
</Tabs.List>
|
263
|
-
</Tabs>
|
264
|
-
</Example.Item>
|
265
|
-
</Example>);
|
266
|
-
export const edgeCases = () => (<Example>
|
267
|
-
<Example.Item title="Viewport overflow">
|
268
|
-
<Tabs>
|
269
|
-
<Tabs.List>
|
270
|
-
{[...Array(8)].map((_, i) => (<Tabs.Item value={`${i}`} key={i} icon={IconZap}>
|
271
|
-
Very long item {i}
|
272
|
-
</Tabs.Item>))}
|
273
|
-
</Tabs.List>
|
415
|
+
<Example.Item title="panels with focusable content">
|
416
|
+
<Tabs>
|
417
|
+
<View gap={4}>
|
418
|
+
<Tabs.List>
|
419
|
+
<Tabs.Item value="0">Item 1</Tabs.Item>
|
420
|
+
<Tabs.Item value="1">Long item 2</Tabs.Item>
|
421
|
+
<Tabs.Item value="2">Very long item 3</Tabs.Item>
|
422
|
+
</Tabs.List>
|
274
423
|
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
<Tabs.Item value="2">Very long item 3</Tabs.Item>
|
300
|
-
</Tabs.List>
|
301
|
-
</Tabs>
|
302
|
-
</Example.Item>
|
303
|
-
</Example>);
|
304
|
-
export const edgeCaseDom = () => {
|
305
|
-
const [activeItem, setActiveItem] = React.useState("1");
|
306
|
-
const sectionsRef = React.useRef(null);
|
307
|
-
return (<Example>
|
308
|
-
<Example.Item title="active item changes on scroll">
|
309
|
-
<View justify="center" align="center" padding={10}>
|
310
|
-
<View width={60} gap={2}>
|
311
|
-
<Tabs value={activeItem} onChange={(args) => setActiveItem(args.value)}>
|
312
|
-
<Tabs.List>
|
313
|
-
<Tabs.Item value="1">Item 1</Tabs.Item>
|
314
|
-
<Tabs.Item value="2">Item 2</Tabs.Item>
|
315
|
-
<Tabs.Item value="3">Item 3</Tabs.Item>
|
316
|
-
<Tabs.Item value="4">Item 4</Tabs.Item>
|
317
|
-
</Tabs.List>
|
318
|
-
</Tabs>
|
424
|
+
<Tabs.Panel value="0">
|
425
|
+
<Button onClick={() => { }}>Tab 1 action</Button>
|
426
|
+
</Tabs.Panel>
|
427
|
+
<Tabs.Panel value="1">
|
428
|
+
<Button onClick={() => { }}>Tab 2 action</Button>
|
429
|
+
</Tabs.Panel>
|
430
|
+
<Tabs.Panel value="2">
|
431
|
+
<Button onClick={() => { }}>Tab 3 action</Button>
|
432
|
+
</Tabs.Panel>
|
433
|
+
</View>
|
434
|
+
</Tabs>
|
435
|
+
</Example.Item>
|
436
|
+
</Example>),
|
437
|
+
};
|
438
|
+
export const testComposition = {
|
439
|
+
name: "test: composition",
|
440
|
+
render: () => (<Example>
|
441
|
+
<Example.Item title="Viewport overflow">
|
442
|
+
<Tabs>
|
443
|
+
<Tabs.List>
|
444
|
+
{[...Array(8)].map((_, i) => (<Tabs.Item value={`${i}`} key={i} icon={IconZap}>
|
445
|
+
Very long item {i}
|
446
|
+
</Tabs.Item>))}
|
447
|
+
</Tabs.List>
|
319
448
|
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
449
|
+
{[...Array(8)].map((_, i) => (<Tabs.Panel value={`${i}`} key={i}>
|
450
|
+
Tab {i}
|
451
|
+
</Tabs.Panel>))}
|
452
|
+
</Tabs>
|
453
|
+
</Example.Item>
|
454
|
+
<Example.Item>
|
455
|
+
<Tabs onChange={console.log} variant="pills-elevated" name="hey">
|
456
|
+
<Tabs.List>
|
457
|
+
<Tabs.Item value="0">Item 1</Tabs.Item>
|
458
|
+
<Tabs.Item value="1">Long item 2</Tabs.Item>
|
459
|
+
<Tabs.Item value="2">
|
460
|
+
<View borderColor="neutral-faded" padding={5}>
|
461
|
+
Item 3
|
462
|
+
</View>
|
463
|
+
</Tabs.Item>
|
464
|
+
</Tabs.List>
|
465
|
+
</Tabs>
|
466
|
+
</Example.Item>
|
467
|
+
<Example.Item title="Custom non-interactive list children">
|
468
|
+
<Tabs direction="column">
|
469
|
+
<Tabs.List>
|
470
|
+
<Tabs.Item value="0">Item 1</Tabs.Item>
|
471
|
+
<View height={6} backgroundColor="neutral-faded" borderRadius="small"/>
|
472
|
+
<Tabs.Item value="1">Long item 2</Tabs.Item>
|
473
|
+
<Tabs.Item value="2">Very long item 3</Tabs.Item>
|
474
|
+
</Tabs.List>
|
475
|
+
</Tabs>
|
476
|
+
</Example.Item>
|
477
|
+
</Example>),
|
478
|
+
};
|
479
|
+
export const testEdgeCaseDom = {
|
480
|
+
name: "test: scroll subscription",
|
481
|
+
render: () => {
|
482
|
+
const [activeItem, setActiveItem] = React.useState("1");
|
483
|
+
const sectionsRef = React.useRef(null);
|
484
|
+
return (<Example>
|
485
|
+
<Example.Item title="active item changes on scroll">
|
486
|
+
<View justify="center" align="center" padding={10}>
|
487
|
+
<View width={60} gap={2}>
|
488
|
+
<Tabs value={activeItem} onChange={(args) => setActiveItem(args.value)}>
|
489
|
+
<Tabs.List>
|
490
|
+
<Tabs.Item value="1">Item 1</Tabs.Item>
|
491
|
+
<Tabs.Item value="2">Item 2</Tabs.Item>
|
492
|
+
<Tabs.Item value="3">Item 3</Tabs.Item>
|
493
|
+
<Tabs.Item value="4">Item 4</Tabs.Item>
|
494
|
+
</Tabs.List>
|
495
|
+
</Tabs>
|
326
496
|
|
327
|
-
|
328
|
-
|
497
|
+
<ScrollArea attributes={{ ref: sectionsRef }} height={70} onScroll={(args) => {
|
498
|
+
setActiveItem(Math.min(4, Math.floor(args.y * 10) + 1).toString());
|
499
|
+
}}>
|
500
|
+
<View gap={4}>
|
501
|
+
<View gap={2}>
|
502
|
+
<Text>Section 1</Text>
|
503
|
+
|
504
|
+
<View gap={1} direction="row">
|
505
|
+
{[...Array(4)].map((_, i) => (<View grow height="100px" backgroundColor="neutral-faded" key={i}/>))}
|
506
|
+
</View>
|
329
507
|
</View>
|
330
|
-
</View>
|
331
508
|
|
332
|
-
|
333
|
-
|
509
|
+
<View gap={2}>
|
510
|
+
<Text>Section 2</Text>
|
334
511
|
|
335
|
-
|
336
|
-
|
512
|
+
<View gap={1} direction="row">
|
513
|
+
{[...Array(4)].map((_, i) => (<View key={i} grow height="100px" backgroundColor="neutral-faded"/>))}
|
514
|
+
</View>
|
337
515
|
</View>
|
338
|
-
</View>
|
339
516
|
|
340
|
-
|
341
|
-
|
517
|
+
<View gap={2}>
|
518
|
+
<Text>Section 3</Text>
|
342
519
|
|
343
|
-
|
344
|
-
|
520
|
+
<View gap={1} direction="row">
|
521
|
+
{[...Array(4)].map((_, i) => (<View key={i} grow height="100px" backgroundColor="neutral-faded"/>))}
|
522
|
+
</View>
|
345
523
|
</View>
|
346
|
-
</View>
|
347
524
|
|
348
|
-
|
349
|
-
|
525
|
+
<View gap={2}>
|
526
|
+
<Text>Section 4</Text>
|
350
527
|
|
351
|
-
|
352
|
-
|
528
|
+
<View gap={1} direction="row">
|
529
|
+
{[...Array(4)].map((_, i) => (<View key={i} grow height="100px" backgroundColor="neutral-faded"/>))}
|
530
|
+
</View>
|
353
531
|
</View>
|
354
532
|
</View>
|
355
|
-
</
|
356
|
-
</
|
533
|
+
</ScrollArea>
|
534
|
+
</View>
|
357
535
|
</View>
|
358
|
-
</
|
359
|
-
</Example
|
360
|
-
|
536
|
+
</Example.Item>
|
537
|
+
</Example>);
|
538
|
+
},
|
361
539
|
};
|