@@ -4,21 +4,51 @@ import { Tabs } from './tabs';
4
4
import { TabList } from './tabs-list' ;
5
5
import { TabPanel } from './tabs-panel' ;
6
6
7
- const ThreeTabsComponent = component$ ( ( ) => {
8
- return (
9
- < Tabs data-testid = "tabs" >
10
- < TabList >
11
- < Tab > Tab 1</ Tab >
12
- < Tab > Tab 2</ Tab >
13
- < Tab > Tab 3</ Tab >
14
- </ TabList >
7
+ interface ThreeTabsCompProps {
8
+ isMiddleDisabled ?: boolean ;
9
+ showDisableButton ?: boolean ;
10
+ disabledIndex ?: number ;
11
+ }
15
12
16
- < TabPanel > Panel 1</ TabPanel >
17
- < TabPanel > Panel 2</ TabPanel >
18
- < TabPanel > Panel 3</ TabPanel >
19
- </ Tabs >
20
- ) ;
21
- } ) ;
13
+ const ThreeTabsComponent = component$ (
14
+ ( {
15
+ isMiddleDisabled = false ,
16
+ showDisableButton = false ,
17
+ disabledIndex,
18
+ } : ThreeTabsCompProps ) => {
19
+ const isMiddleDisabledSignal = useSignal ( isMiddleDisabled ) ;
20
+
21
+ return (
22
+ < >
23
+ < Tabs data-testid = "tabs" >
24
+ < TabList >
25
+ < Tab disabled = { disabledIndex === 0 } > Tab 1</ Tab >
26
+ < Tab disabled = { disabledIndex === 1 || isMiddleDisabledSignal . value } >
27
+ Tab 2
28
+ </ Tab >
29
+ < Tab disabled = { disabledIndex === 2 } > Tab 3</ Tab >
30
+ </ TabList >
31
+
32
+ < TabPanel > Panel 1</ TabPanel >
33
+ < TabPanel > Panel 2</ TabPanel >
34
+ < TabPanel > Panel 3</ TabPanel >
35
+ </ Tabs >
36
+
37
+ < br />
38
+
39
+ { showDisableButton && (
40
+ < button
41
+ onClick$ = { ( ) =>
42
+ ( isMiddleDisabledSignal . value = ! isMiddleDisabledSignal . value )
43
+ }
44
+ >
45
+ Toggle middle tab disabled
46
+ </ button >
47
+ ) }
48
+ </ >
49
+ ) ;
50
+ }
51
+ ) ;
22
52
23
53
interface DynamicTabsProps {
24
54
tabIndexToDelete ?: number ;
@@ -132,78 +162,208 @@ describe('Tabs', () => {
132
162
cy . findByRole ( 'tabpanel' ) . should ( 'contain' , 'Dynamic Tab 2 Panel' ) ;
133
163
} ) ;
134
164
135
- it ( `GIVEN 3 tabs,
136
- WHEN removing the last one dynamically
137
- THEN only 2 should remain` , ( ) => {
138
- cy . mount ( < DynamicTabsComponent tabsLength = { 3 } tabIndexToDelete = { 2 } /> ) ;
165
+ describe ( 'Dynamic Tabs' , ( ) => {
166
+ it ( `GIVEN 3 tabs,
167
+ WHEN removing the last one dynamically
168
+ THEN only 2 should remain` , ( ) => {
169
+ cy . mount ( < DynamicTabsComponent tabsLength = { 3 } tabIndexToDelete = { 2 } /> ) ;
139
170
140
- cy . findByRole ( 'button' , { name : / r e m o v e t a b / i } ) . click ( ) ;
171
+ cy . findByRole ( 'button' , { name : / r e m o v e t a b / i } ) . click ( ) ;
141
172
142
- cy . findAllByRole ( 'tab' ) . should ( 'have.length' , 2 ) ;
143
- } ) ;
173
+ cy . findAllByRole ( 'tab' ) . should ( 'have.length' , 2 ) ;
174
+ } ) ;
144
175
145
- it ( `GIVEN 3 tabs
146
- WHEN clicking on the last one and then removing it
147
- THEN tab 2 should be shown` , ( ) => {
148
- cy . mount ( < DynamicTabsComponent tabsLength = { 3 } tabIndexToDelete = { 2 } /> ) ;
176
+ it ( `GIVEN 3 tabs
177
+ WHEN clicking on the last one and then removing it
178
+ THEN tab 2 should be shown` , ( ) => {
179
+ cy . mount ( < DynamicTabsComponent tabsLength = { 3 } tabIndexToDelete = { 2 } /> ) ;
149
180
150
- cy . findByRole ( 'tab' , { name : / D y n a m i c T a b 3 / i } ) . click ( ) ;
151
- cy . findByRole ( 'tabpanel' ) . should ( 'contain' , 'Dynamic Tab 3 Panel' ) ;
181
+ cy . findByRole ( 'tab' , { name : / D y n a m i c T a b 3 / i } ) . click ( ) ;
182
+ cy . findByRole ( 'tabpanel' ) . should ( 'contain' , 'Dynamic Tab 3 Panel' ) ;
152
183
153
- cy . findByRole ( 'button' , { name : / r e m o v e t a b / i } ) . click ( ) ;
184
+ cy . findByRole ( 'button' , { name : / r e m o v e t a b / i } ) . click ( ) ;
154
185
155
- cy . findByRole ( 'tabpanel' ) . should ( 'contain' , 'Dynamic Tab 2 Panel' ) ;
156
- } ) ;
186
+ cy . findByRole ( 'tabpanel' ) . should ( 'contain' , 'Dynamic Tab 2 Panel' ) ;
187
+ } ) ;
157
188
158
- it ( `GIVEN 4 tabs
159
- WHEN clicking on the last one and then removing the 3rd
160
- THEN tab 4 should be shown` , ( ) => {
161
- cy . mount ( < DynamicTabsComponent tabsLength = { 4 } tabIndexToDelete = { 2 } /> ) ;
162
- cy . findByRole ( 'tab' , { name : / D y n a m i c T a b 4 / i } ) . click ( ) ;
163
- cy . findByRole ( 'button' , { name : / r e m o v e t a b / i } ) . click ( ) ;
189
+ it ( `GIVEN 4 tabs
190
+ WHEN clicking on the last one and then removing the 3rd
191
+ THEN tab 4 should be shown` , ( ) => {
192
+ cy . mount ( < DynamicTabsComponent tabsLength = { 4 } tabIndexToDelete = { 2 } /> ) ;
193
+ cy . findByRole ( 'tab' , { name : / D y n a m i c T a b 4 / i } ) . click ( ) ;
194
+ cy . findByRole ( 'button' , { name : / r e m o v e t a b / i } ) . click ( ) ;
164
195
165
- cy . findByRole ( 'tabpanel' ) . should ( 'contain' , 'Dynamic Tab 4 Panel' ) ;
166
- } ) ;
196
+ cy . findByRole ( 'tabpanel' ) . should ( 'contain' , 'Dynamic Tab 4 Panel' ) ;
197
+ } ) ;
198
+
199
+ it ( `GIVEN 4 tabs
200
+ WHEN selecting the 3rd one and adding a tab at the start
201
+ THEN the correct tab should be displayed` , ( ) => {
202
+ cy . mount ( < DynamicTabsComponent tabsLength = { 4 } tabIndexToAdd = { 1 } /> ) ;
203
+ cy . findByRole ( 'tab' , { name : / D y n a m i c T a b 3 / i } ) . click ( ) ;
204
+ cy . findByRole ( 'button' , { name : / a d d t a b / i } ) . click ( ) ;
205
+
206
+ cy . findByRole ( 'tabpanel' ) . should ( 'contain' , 'Dynamic Tab 3 Panel' ) ;
207
+ } ) ;
208
+
209
+ it ( `GIVEN tabs inside of tabs
210
+ WHEN clicking on the root second tab
211
+ THEN it should show only the selected root panel` , ( ) => {
212
+ cy . mount ( < TabsInsideOfTabs /> ) ;
213
+
214
+ cy . findAllByRole ( 'tab' , { name : / T a b 2 / i } ) . first ( ) . click ( ) ;
167
215
168
- it ( `GIVEN 4 tabs
169
- WHEN selecting the 3rd one and adding a tab at the start
170
- THEN the correct tab should be displayed` , ( ) => {
171
- cy . mount ( < DynamicTabsComponent tabsLength = { 4 } tabIndexToAdd = { 1 } /> ) ;
172
- cy . findByRole ( 'tab' , { name : / D y n a m i c T a b 3 / i } ) . click ( ) ;
173
- cy . findByRole ( 'button' , { name : / a d d t a b / i } ) . click ( ) ;
216
+ cy . findByRole ( 'tabpanel' )
217
+ . should ( 'be.visible' )
218
+ . should ( 'contain' , 'Root Panel 2' ) ;
219
+ } ) ;
174
220
175
- cy . findByRole ( 'tabpanel' ) . should ( 'contain' , 'Dynamic Tab 3 Panel' ) ;
221
+ it ( `GIVEN tabs inside of tabs
222
+ WHEN clicking on the child second tab
223
+ THEN it should show only the selected child panel` , ( ) => {
224
+ cy . mount ( < TabsInsideOfTabs /> ) ;
225
+
226
+ cy . findAllByRole ( 'tab' , { name : / T a b 2 / i } ) . eq ( 1 ) . click ( ) ;
227
+
228
+ cy . findAllByRole ( 'tabpanel' ) . eq ( 1 ) . should ( 'contain' , 'Child Panel 2' ) ;
229
+ } ) ;
176
230
} ) ;
177
231
178
- it ( `GIVEN tabs inside of tabs
179
- WHEN clicking on the root second tab
180
- THEN it should show only the selected root panel` , ( ) => {
181
- cy . mount ( < TabsInsideOfTabs /> ) ;
232
+ describe ( 'Right key handling' , ( ) => {
233
+ it ( `GIVEN 3 tabs and the focus is on the first,
234
+ WHEN triggering the right arrow key
235
+ THEN the focus should be on the next tab` , ( ) => {
236
+ cy . mount ( < ThreeTabsComponent /> ) ;
237
+
238
+ cy . findByRole ( 'tab' , { name : / T a b 1 / i } ) . type ( '{rightarrow}' ) ;
239
+
240
+ cy . findByRole ( 'tab' , { name : / T a b 2 / i } ) . should ( 'have.focus' ) ;
241
+ } ) ;
242
+
243
+ it ( `GIVEN 3 tabs and the focus is on the last,
244
+ WHEN triggering the right arrow key
245
+ THEN the focus should be on the first tab` , ( ) => {
246
+ cy . mount ( < ThreeTabsComponent /> ) ;
247
+
248
+ cy . findByRole ( 'tab' , { name : / T a b 3 / i } ) . type ( '{rightarrow}' ) ;
249
+
250
+ cy . findByRole ( 'tab' , { name : / T a b 1 / i } ) . should ( 'have.focus' ) ;
251
+ } ) ;
252
+
253
+ it ( `GIVEN 3 tabs and the second is disabled and the focus is on the first,
254
+ WHEN triggering the right arrow key
255
+ THEN the focus should be on the third tab` , ( ) => {
256
+ cy . mount ( < ThreeTabsComponent isMiddleDisabled = { true } /> ) ;
257
+
258
+ cy . findByRole ( 'tab' , { name : / T a b 1 / i } ) . type ( '{rightarrow}' ) ;
182
259
183
- cy . findAllByRole ( 'tab' , { name : / T a b 2 / i } ) . first ( ) . click ( ) ;
260
+ cy . findByRole ( 'tab' , { name : / T a b 3 / i } ) . should ( 'have.focus' ) ;
261
+ } ) ;
184
262
185
- cy . findByRole ( 'tabpanel' )
186
- . should ( 'be.visible' )
187
- . should ( 'contain' , 'Root Panel 2' ) ;
263
+ it ( `GIVEN 3 tabs and the focus is on the first,
264
+ WHEN disabling the middle dynamically and triggering the right arrow key
265
+ THEN the focus should be on the third tab` , ( ) => {
266
+ cy . mount ( < ThreeTabsComponent showDisableButton = { true } /> ) ;
267
+
268
+ cy . findByRole ( 'button' , { name : 'Toggle middle tab disabled' } ) . click ( ) ;
269
+
270
+ cy . findByRole ( 'tab' , { name : / T a b 1 / i } ) . type ( '{rightarrow}' ) ;
271
+
272
+ cy . findByRole ( 'tab' , { name : / T a b 3 / i } ) . should ( 'have.focus' ) ;
273
+ } ) ;
188
274
} ) ;
189
275
190
- it ( `GIVEN tabs inside of tabs
191
- WHEN clicking on the child second tab
192
- THEN it should show only the selected child panel` , ( ) => {
193
- cy . mount ( < TabsInsideOfTabs /> ) ;
276
+ describe ( 'Left key handling' , ( ) => {
277
+ it ( `GIVEN 3 tabs and the focus is on the second,
278
+ WHEN triggering the left arrow key
279
+ THEN the focus should be on the first tab` , ( ) => {
280
+ cy . mount ( < ThreeTabsComponent /> ) ;
281
+
282
+ cy . findByRole ( 'tab' , { name : / T a b 2 / i } ) . type ( '{leftarrow}' ) ;
283
+
284
+ cy . findByRole ( 'tab' , { name : / T a b 1 / i } ) . should ( 'have.focus' ) ;
285
+ } ) ;
286
+
287
+ it ( `GIVEN 3 tabs and the focus is on the first,
288
+ WHEN triggering the left arrow key
289
+ THEN the focus should be on the last tab` , ( ) => {
290
+ cy . mount ( < ThreeTabsComponent /> ) ;
291
+
292
+ cy . findByRole ( 'tab' , { name : / T a b 1 / i } ) . type ( '{leftarrow}' ) ;
293
+
294
+ cy . findByRole ( 'tab' , { name : / T a b 3 / i } ) . should ( 'have.focus' ) ;
295
+ } ) ;
194
296
195
- cy . findAllByRole ( 'tab' , { name : / T a b 2 / i } ) . eq ( 1 ) . click ( ) ;
297
+ it ( `GIVEN 3 tabs and the second is disabled and the focus is on the third,
298
+ WHEN triggering the left arrow key
299
+ THEN the focus should be on the first tab` , ( ) => {
300
+ cy . mount ( < ThreeTabsComponent isMiddleDisabled = { true } /> ) ;
196
301
197
- cy . findAllByRole ( 'tabpanel' ) . eq ( 1 ) . should ( 'contain' , 'Child Panel 2' ) ;
302
+ cy . findByRole ( 'tab' , { name : / T a b 3 / i } ) . type ( '{leftarrow}' ) ;
303
+
304
+ cy . findByRole ( 'tab' , { name : / T a b 1 / i } ) . should ( 'have.focus' ) ;
305
+ } ) ;
198
306
} ) ;
199
307
200
- it ( `GIVEN 3 tabs and the focus is on the first,
201
- WHEN triggering the right arrow key
202
- THEN the focus should be on the next tab` , ( ) => {
203
- cy . mount ( < ThreeTabsComponent /> ) ;
308
+ describe ( 'Home, End, PageUp and PageDown keys handling' , ( ) => {
309
+ it ( `GIVEN 3 tabs and the focus is on the third,
310
+ WHEN triggering the 'home' key
311
+ THEN the focus should be on the first tab` , ( ) => {
312
+ cy . mount ( < ThreeTabsComponent /> ) ;
313
+
314
+ cy . findByRole ( 'tab' , { name : / T a b 3 / i } ) . type ( '{home}' ) ;
315
+
316
+ cy . findByRole ( 'tab' , { name : / T a b 1 / i } ) . should ( 'have.focus' ) ;
317
+ } ) ;
318
+
319
+ it ( `GIVEN 3 tabs and the first is disabled and the focus is on the third,
320
+ WHEN triggering the 'home' key
321
+ THEN the focus should be on the second tab` , ( ) => {
322
+ cy . mount ( < ThreeTabsComponent disabledIndex = { 0 } /> ) ;
323
+
324
+ cy . findByRole ( 'tab' , { name : / T a b 3 / i } ) . type ( '{home}' ) ;
325
+
326
+ cy . findByRole ( 'tab' , { name : / T a b 2 / i } ) . should ( 'have.focus' ) ;
327
+ } ) ;
328
+
329
+ it ( `GIVEN 3 tabs and the focus is on the third,
330
+ WHEN triggering the 'home' key
331
+ THEN the focus should be on the first tab` , ( ) => {
332
+ cy . mount ( < ThreeTabsComponent /> ) ;
333
+
334
+ cy . findByRole ( 'tab' , { name : / T a b 3 / i } ) . type ( '{pageUp}' ) ;
335
+
336
+ cy . findByRole ( 'tab' , { name : / T a b 1 / i } ) . should ( 'have.focus' ) ;
337
+ } ) ;
338
+
339
+ it ( `GIVEN 3 tabs and the focus is on the third,
340
+ WHEN triggering the 'end' key
341
+ THEN the focus should be on the first tab` , ( ) => {
342
+ cy . mount ( < ThreeTabsComponent /> ) ;
343
+
344
+ cy . findByRole ( 'tab' , { name : / T a b 1 / i } ) . type ( '{end}' ) ;
345
+
346
+ cy . findByRole ( 'tab' , { name : / T a b 3 / i } ) . should ( 'have.focus' ) ;
347
+ } ) ;
348
+
349
+ it ( `GIVEN 3 tabs and the first is disabled and the focus is on the third,
350
+ WHEN triggering the 'end' key
351
+ THEN the focus should be on the second tab` , ( ) => {
352
+ cy . mount ( < ThreeTabsComponent disabledIndex = { 2 } /> ) ;
353
+
354
+ cy . findByRole ( 'tab' , { name : / T a b 1 / i } ) . type ( '{end}' ) ;
355
+
356
+ cy . findByRole ( 'tab' , { name : / T a b 2 / i } ) . should ( 'have.focus' ) ;
357
+ } ) ;
358
+
359
+ it ( `GIVEN 3 tabs and the focus is on the third,
360
+ WHEN triggering the 'end' key
361
+ THEN the focus should be on the first tab` , ( ) => {
362
+ cy . mount ( < ThreeTabsComponent /> ) ;
204
363
205
- cy . findByRole ( 'tab' , { name : / T a b 1 / i } ) . type ( '{rightarrow }' ) ;
364
+ cy . findByRole ( 'tab' , { name : / T a b 1 / i } ) . type ( '{pageDown }' ) ;
206
365
207
- cy . findByRole ( 'tab' , { name : / T a b 2 / i } ) . should ( 'have.focus' ) ;
366
+ cy . findByRole ( 'tab' , { name : / T a b 3 / i } ) . should ( 'have.focus' ) ;
367
+ } ) ;
208
368
} ) ;
209
369
} ) ;
0 commit comments