1
- import { component$ , useStore } from '@builder.io/qwik' ;
1
+ import { component$ , useSignal , useStore , useTask$ } from '@builder.io/qwik' ;
2
2
import { Tab } from './tab' ;
3
3
import { Tabs } from './tabs' ;
4
4
import { TabList } from './tabs-list' ;
5
5
import { TabPanel } from './tabs-panel' ;
6
6
7
- interface DynamicTabsProps {
8
- tabIndexToDelete ?: number ;
9
- tabIndexToAdd ?: number ;
10
- tabsLength : number ;
11
- selectedIndex ?: number ;
12
- }
13
-
14
7
const ThreeTabsComponent = component$ ( ( ) => {
15
8
return (
16
9
< Tabs data-testid = "tabs" >
@@ -27,22 +20,32 @@ const ThreeTabsComponent = component$(() => {
27
20
) ;
28
21
} ) ;
29
22
23
+ interface DynamicTabsProps {
24
+ tabIndexToDelete ?: number ;
25
+ tabIndexToAdd ?: number ;
26
+ tabsLength : number ;
27
+ selectedIndex ?: number ;
28
+ changeIndexTo ?: number ;
29
+ }
30
+
30
31
const DynamicTabsComponent = component$ (
31
32
( {
32
33
tabIndexToDelete = 0 ,
33
34
tabIndexToAdd = 0 ,
34
35
tabsLength,
35
- selectedIndex = 0 ,
36
+ changeIndexTo = 0 ,
36
37
} : DynamicTabsProps ) => {
37
38
const tabNames = Array ( tabsLength )
38
39
. fill ( 1 )
39
40
. map ( ( _ , index ) => `Dynamic Tab ${ index + 1 } ` ) ;
40
41
41
42
const tabsState = useStore ( tabNames ) ;
42
43
44
+ const selectedIndex = useSignal ( 0 ) ;
45
+
43
46
return (
44
47
< >
45
- < Tabs selectedIndex = { selectedIndex } >
48
+ < Tabs selectedIndex = { selectedIndex . value } >
46
49
< TabList >
47
50
{ tabsState . map ( ( tab ) => (
48
51
< Tab key = { tab } > { tab } </ Tab >
@@ -60,56 +63,137 @@ const DynamicTabsComponent = component$(
60
63
>
61
64
Add Tab
62
65
</ button >
66
+ < button
67
+ onClick$ = { ( ) => {
68
+ selectedIndex . value = changeIndexTo ;
69
+ } }
70
+ >
71
+ Change index to { changeIndexTo }
72
+ </ button >
63
73
</ >
64
74
) ;
65
75
}
66
76
) ;
67
77
78
+ const TabsInsideOfTabs = component$ ( ( ) => {
79
+ return (
80
+ < Tabs >
81
+ < TabList >
82
+ < Tab > Tab 1</ Tab >
83
+ < Tab > Tab 2</ Tab >
84
+ < Tab > Tab 3</ Tab >
85
+ </ TabList >
86
+
87
+ < TabPanel >
88
+ < Tabs >
89
+ < TabList >
90
+ < Tab > Tab 1</ Tab >
91
+ < Tab > Tab 2</ Tab >
92
+ < Tab > Tab 3</ Tab >
93
+ </ TabList >
94
+
95
+ < TabPanel > Panel 1</ TabPanel >
96
+ < TabPanel > Child Panel 2</ TabPanel >
97
+ < TabPanel > Panel 3</ TabPanel >
98
+ </ Tabs >
99
+ </ TabPanel >
100
+ < TabPanel > Root Panel 2</ TabPanel >
101
+ < TabPanel > Panel 3</ TabPanel >
102
+ </ Tabs >
103
+ ) ;
104
+ } ) ;
105
+
68
106
describe ( 'Tabs' , ( ) => {
69
107
it ( 'INIT' , ( ) => {
70
108
cy . mount ( < ThreeTabsComponent /> ) ;
71
-
72
- // cy.findByTestId('tabs').should('be.visible').matchImage();
109
+ // cy.findByTestId('tabs').matchImage();
73
110
74
111
cy . checkA11yForComponent ( ) ;
75
112
} ) ;
76
- it ( 'should render the component' , ( ) => {
113
+ it ( `GIVEN 3 tabs
114
+ WHEN clicking the middle one
115
+ THEN render the middle panel` , ( ) => {
77
116
cy . mount ( < ThreeTabsComponent /> ) ;
78
117
79
118
cy . findByRole ( 'tab' , { name : / T a b 2 / i } ) . click ( ) ;
80
119
81
120
cy . findByRole ( 'tabpanel' ) . should ( 'contain' , 'Panel 2' ) ;
82
121
} ) ;
83
122
84
- it ( 'Given 3 tabs, when removing the last one dynamically, only 2 should remain' , ( ) => {
123
+ it ( `GIVEN 3 tabs
124
+ WHEN changing the selected index programmatically to the middle
125
+ THEN render the middle panel` , ( ) => {
126
+ cy . mount ( < DynamicTabsComponent tabsLength = { 3 } changeIndexTo = { 1 } /> ) ;
127
+
128
+ cy . findByRole ( 'tabpanel' ) . should ( 'contain' , 'Dynamic Tab 1 Panel' ) ;
129
+
130
+ cy . findByRole ( 'button' , { name : / C h a n g e i n d e x / i } ) . click ( ) ;
131
+
132
+ cy . findByRole ( 'tabpanel' ) . should ( 'contain' , 'Dynamic Tab 2 Panel' ) ;
133
+ } ) ;
134
+
135
+ it ( `GIVEN 3 tabs,
136
+ WHEN removing the last one dynamically
137
+ THEN only 2 should remain` , ( ) => {
85
138
cy . mount ( < DynamicTabsComponent tabsLength = { 3 } tabIndexToDelete = { 2 } /> ) ;
86
139
87
140
cy . findByRole ( 'button' , { name : / r e m o v e t a b / i } ) . click ( ) ;
88
141
89
142
cy . findAllByRole ( 'tab' ) . should ( 'have.length' , 2 ) ;
90
143
} ) ;
91
144
92
- it ( 'Given 3 tabs, when clicking on the last one and then removing it, tab 2 should be shown' , ( ) => {
145
+ it ( `GIVEN 3 tabs
146
+ WHEN clicking on the last one and then removing it
147
+ THEN tab 2 should be shown` , ( ) => {
93
148
cy . mount ( < DynamicTabsComponent tabsLength = { 3 } tabIndexToDelete = { 2 } /> ) ;
149
+
94
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' ) ;
152
+
95
153
cy . findByRole ( 'button' , { name : / r e m o v e t a b / i } ) . click ( ) ;
96
154
97
155
cy . findByRole ( 'tabpanel' ) . should ( 'contain' , 'Dynamic Tab 2 Panel' ) ;
98
156
} ) ;
99
157
100
- it ( 'Given 4 tabs, when clicking on the last one and then removing the 3rd, tab 4 should be shown' , ( ) => {
158
+ it ( `GIVEN 4 tabs
159
+ WHEN clicking on the last one and then removing the 3rd
160
+ THEN tab 4 should be shown` , ( ) => {
101
161
cy . mount ( < DynamicTabsComponent tabsLength = { 4 } tabIndexToDelete = { 2 } /> ) ;
102
162
cy . findByRole ( 'tab' , { name : / D y n a m i c T a b 4 / i } ) . click ( ) ;
103
163
cy . findByRole ( 'button' , { name : / r e m o v e t a b / i } ) . click ( ) ;
104
164
105
165
cy . findByRole ( 'tabpanel' ) . should ( 'contain' , 'Dynamic Tab 4 Panel' ) ;
106
166
} ) ;
107
167
108
- it ( 'Given 4 tabs, when selecting the 3rd one and adding a tab at the start, the correct tab should be displayed' , ( ) => {
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` , ( ) => {
109
171
cy . mount ( < DynamicTabsComponent tabsLength = { 4 } tabIndexToAdd = { 1 } /> ) ;
110
172
cy . findByRole ( 'tab' , { name : / D y n a m i c T a b 3 / i } ) . click ( ) ;
111
173
cy . findByRole ( 'button' , { name : / a d d t a b / i } ) . click ( ) ;
112
174
113
175
cy . findByRole ( 'tabpanel' ) . should ( 'contain' , 'Dynamic Tab 3 Panel' ) ;
114
176
} ) ;
177
+
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 /> ) ;
182
+
183
+ cy . findAllByRole ( 'tab' , { name : / T a b 2 / i } ) . first ( ) . click ( ) ;
184
+
185
+ cy . findByRole ( 'tabpanel' )
186
+ . should ( 'be.visible' )
187
+ . should ( 'contain' , 'Root Panel 2' ) ;
188
+ } ) ;
189
+
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 /> ) ;
194
+
195
+ cy . findAllByRole ( 'tab' , { name : / T a b 2 / i } ) . eq ( 1 ) . click ( ) ;
196
+
197
+ cy . findAllByRole ( 'tabpanel' ) . eq ( 1 ) . should ( 'contain' , 'Child Panel 2' ) ;
198
+ } ) ;
115
199
} ) ;
0 commit comments