@@ -4,21 +4,51 @@ import { Tabs } from './tabs';
44import { TabList } from './tabs-list' ;
55import { TabPanel } from './tabs-panel' ;
66
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+ }
1512
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+ ) ;
2252
2353interface DynamicTabsProps {
2454 tabIndexToDelete ?: number ;
@@ -132,78 +162,208 @@ describe('Tabs', () => {
132162 cy . findByRole ( 'tabpanel' ) . should ( 'contain' , 'Dynamic Tab 2 Panel' ) ;
133163 } ) ;
134164
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 } /> ) ;
139170
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 ( ) ;
141172
142- cy . findAllByRole ( 'tab' ) . should ( 'have.length' , 2 ) ;
143- } ) ;
173+ cy . findAllByRole ( 'tab' ) . should ( 'have.length' , 2 ) ;
174+ } ) ;
144175
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 } /> ) ;
149180
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' ) ;
152183
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 ( ) ;
154185
155- cy . findByRole ( 'tabpanel' ) . should ( 'contain' , 'Dynamic Tab 2 Panel' ) ;
156- } ) ;
186+ cy . findByRole ( 'tabpanel' ) . should ( 'contain' , 'Dynamic Tab 2 Panel' ) ;
187+ } ) ;
157188
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 ( ) ;
164195
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 ( ) ;
167215
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+ } ) ;
174220
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+ } ) ;
176230 } ) ;
177231
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}' ) ;
182259
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+ } ) ;
184262
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+ } ) ;
188274 } ) ;
189275
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+ } ) ;
194296
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 } /> ) ;
196301
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+ } ) ;
198306 } ) ;
199307
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 /> ) ;
204363
205- cy . findByRole ( 'tab' , { name : / T a b 1 / i } ) . type ( '{rightarrow }' ) ;
364+ cy . findByRole ( 'tab' , { name : / T a b 1 / i } ) . type ( '{pageDown }' ) ;
206365
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+ } ) ;
208368 } ) ;
209369} ) ;
0 commit comments