@v-c/collapse 0.0.3 → 0.0.5
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/dist/Collapse.cjs +1 -1
- package/dist/Collapse.js +48 -57
- package/dist/Panel.cjs +1 -1
- package/dist/Panel.js +5 -5
- package/dist/index.d.ts +1 -1
- package/dist/interface.d.ts +0 -2
- package/package.json +4 -1
- package/assets/index.less +0 -117
- package/assets/motion.less +0 -14
- package/docs/collapse.stories.vue +0 -45
- package/docs/custom-icon.vue +0 -185
- package/docs/simple.vue +0 -218
- package/src/Collapse.tsx +0 -110
- package/src/Panel.tsx +0 -178
- package/src/PanelContent.tsx +0 -63
- package/src/hooks/useItems.tsx +0 -202
- package/src/index.ts +0 -8
- package/src/interface.ts +0 -75
- package/tests/__snapshots__/index.test.tsx.snap +0 -3
- package/tests/index.test.tsx +0 -954
- package/tsconfig.json +0 -7
- package/vite.config.ts +0 -18
- package/vitest.config.ts +0 -11
package/tests/index.test.tsx
DELETED
|
@@ -1,954 +0,0 @@
|
|
|
1
|
-
import type { Mock } from 'vitest'
|
|
2
|
-
import type { CollapseProps } from '../src'
|
|
3
|
-
import KeyCode from '@v-c/util/dist/KeyCode'
|
|
4
|
-
import { mount } from '@vue/test-utils'
|
|
5
|
-
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
|
6
|
-
import { defineComponent, ref } from 'vue'
|
|
7
|
-
import Collapse, { Panel } from '../src/index'
|
|
8
|
-
|
|
9
|
-
describe('collapse', () => {
|
|
10
|
-
let changeHook: Mock<any> | null
|
|
11
|
-
|
|
12
|
-
beforeEach(() => {
|
|
13
|
-
vi.useFakeTimers()
|
|
14
|
-
})
|
|
15
|
-
|
|
16
|
-
afterEach(() => {
|
|
17
|
-
vi.useRealTimers()
|
|
18
|
-
changeHook = null
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
function onChange(this: any, ...args: any[]) {
|
|
22
|
-
if (changeHook) {
|
|
23
|
-
changeHook.apply(this, args)
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function runNormalTest(element: any) {
|
|
28
|
-
let collapse: ReturnType<typeof mount>
|
|
29
|
-
|
|
30
|
-
beforeEach(() => {
|
|
31
|
-
collapse = mount(element)
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
afterEach(() => {
|
|
35
|
-
collapse.unmount()
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
it('add className', () => {
|
|
39
|
-
const el = collapse.findAll('.vc-collapse-item')?.[2]
|
|
40
|
-
|
|
41
|
-
expect(el.classes()).toContain('vc-collapse-item')
|
|
42
|
-
expect(el.classes()).toContain('important')
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
it('create works', () => {
|
|
46
|
-
expect(collapse.findAll('.vc-collapse')).toHaveLength(1)
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
it('header works', () => {
|
|
50
|
-
expect(collapse.findAll('.vc-collapse-header')).toHaveLength(3)
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
it('panel works', () => {
|
|
54
|
-
expect(collapse.findAll('.vc-collapse-item')).toHaveLength(3)
|
|
55
|
-
expect(collapse.findAll('.vc-collapse-panel')).toHaveLength(0)
|
|
56
|
-
})
|
|
57
|
-
|
|
58
|
-
it('should render custom arrow icon correctly', () => {
|
|
59
|
-
expect(collapse.find('.vc-collapse-header')?.text()).toContain('text>')
|
|
60
|
-
})
|
|
61
|
-
|
|
62
|
-
it('default active works', () => {
|
|
63
|
-
expect(collapse.findAll('.vc-collapse-item-active').length).toBeFalsy()
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
it('extra works', () => {
|
|
67
|
-
const extraNodes = collapse.findAll('.vc-collapse-extra')
|
|
68
|
-
expect(extraNodes.length).toBe(1)
|
|
69
|
-
expect(extraNodes[0].html()).toContain('<span>Extra span</span>')
|
|
70
|
-
})
|
|
71
|
-
|
|
72
|
-
it('onChange works', async () => {
|
|
73
|
-
changeHook = vi.fn()
|
|
74
|
-
const headerNode = collapse.findAll('.vc-collapse-header')?.[1]
|
|
75
|
-
await headerNode?.trigger('click')
|
|
76
|
-
expect(changeHook.mock.calls[0][0]).toEqual(['2'])
|
|
77
|
-
})
|
|
78
|
-
|
|
79
|
-
it('click should toggle panel state', async () => {
|
|
80
|
-
const header = collapse.findAll('.vc-collapse-header')?.[1]
|
|
81
|
-
await header?.trigger('click')
|
|
82
|
-
expect(collapse.findAll('.vc-collapse-panel-active')).toHaveLength(1)
|
|
83
|
-
await header?.trigger('click')
|
|
84
|
-
expect(
|
|
85
|
-
collapse.find('.vc-collapse-panel-inactive')?.element.innerHTML,
|
|
86
|
-
).toBe('<div class="vc-collapse-body">second</div>')
|
|
87
|
-
expect(collapse.findAll('.vc-collapse-panel-active').length).toBeFalsy()
|
|
88
|
-
})
|
|
89
|
-
|
|
90
|
-
it('click should not toggle disabled panel state', async () => {
|
|
91
|
-
const header = collapse.find('.vc-collapse-header')
|
|
92
|
-
expect(header.element).toBeTruthy()
|
|
93
|
-
await header.trigger('click')
|
|
94
|
-
expect(collapse.findAll('.vc-collapse-panel-active').length).toBeFalsy()
|
|
95
|
-
})
|
|
96
|
-
|
|
97
|
-
it('should not have role', () => {
|
|
98
|
-
const item = collapse.find('.vc-collapse')
|
|
99
|
-
expect(item.element).toBeTruthy()
|
|
100
|
-
expect(item.attributes().role).toBe(undefined)
|
|
101
|
-
})
|
|
102
|
-
|
|
103
|
-
it('should set button role on panel title', () => {
|
|
104
|
-
const item = collapse.find('.vc-collapse-header')
|
|
105
|
-
expect(item.element).toBeTruthy()
|
|
106
|
-
expect(item.attributes().role).toBe('button')
|
|
107
|
-
})
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
describe('collapse', () => {
|
|
111
|
-
const expandIcon = () => (
|
|
112
|
-
<span>
|
|
113
|
-
text
|
|
114
|
-
{'>'}
|
|
115
|
-
</span>
|
|
116
|
-
)
|
|
117
|
-
|
|
118
|
-
const items: CollapseProps['items'] = [
|
|
119
|
-
{
|
|
120
|
-
label: 'collapse 1',
|
|
121
|
-
key: '1',
|
|
122
|
-
collapsible: 'disabled',
|
|
123
|
-
children: 'first',
|
|
124
|
-
},
|
|
125
|
-
{
|
|
126
|
-
label: 'collapse 2',
|
|
127
|
-
key: '2',
|
|
128
|
-
extra: <span>Extra span</span>,
|
|
129
|
-
children: 'second',
|
|
130
|
-
},
|
|
131
|
-
{
|
|
132
|
-
label: 'collapse 3',
|
|
133
|
-
key: '3',
|
|
134
|
-
className: 'important',
|
|
135
|
-
children: 'third',
|
|
136
|
-
},
|
|
137
|
-
]
|
|
138
|
-
const element = (
|
|
139
|
-
<Collapse items={items} expandIcon={expandIcon} onChange={onChange} />
|
|
140
|
-
)
|
|
141
|
-
|
|
142
|
-
runNormalTest(element)
|
|
143
|
-
|
|
144
|
-
it('controlled', async () => {
|
|
145
|
-
const onChangeSpy = vi.fn()
|
|
146
|
-
|
|
147
|
-
const ControlledCollapse = defineComponent(() => {
|
|
148
|
-
const activeKey = ref<CollapseProps['activeKey']>(['2'])
|
|
149
|
-
const handleChange: CollapseProps['onChange'] = (key) => {
|
|
150
|
-
activeKey.value = key
|
|
151
|
-
onChangeSpy(key)
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
const items: CollapseProps['items'] = [
|
|
155
|
-
{
|
|
156
|
-
label: 'collapse 1',
|
|
157
|
-
key: '1',
|
|
158
|
-
children: 'first',
|
|
159
|
-
},
|
|
160
|
-
{
|
|
161
|
-
label: 'collapse 2',
|
|
162
|
-
key: '2',
|
|
163
|
-
children: 'second',
|
|
164
|
-
},
|
|
165
|
-
{
|
|
166
|
-
label: 'collapse 3',
|
|
167
|
-
key: '3',
|
|
168
|
-
children: 'third',
|
|
169
|
-
},
|
|
170
|
-
]
|
|
171
|
-
return () => (
|
|
172
|
-
<Collapse
|
|
173
|
-
onChange={handleChange}
|
|
174
|
-
activeKey={activeKey.value}
|
|
175
|
-
items={items}
|
|
176
|
-
/>
|
|
177
|
-
)
|
|
178
|
-
})
|
|
179
|
-
|
|
180
|
-
const el = mount(ControlledCollapse)
|
|
181
|
-
|
|
182
|
-
expect(el.findAll('.vc-collapse-panel-active')).toHaveLength(1)
|
|
183
|
-
const header = el.find('.vc-collapse-header')
|
|
184
|
-
expect(header.element).toBeTruthy()
|
|
185
|
-
await header.trigger('click')
|
|
186
|
-
expect(el.findAll('.vc-collapse-panel-active')).toHaveLength(2)
|
|
187
|
-
expect(onChangeSpy).toBeCalledWith(['2', '1'])
|
|
188
|
-
})
|
|
189
|
-
})
|
|
190
|
-
|
|
191
|
-
describe('it should support number key', () => {
|
|
192
|
-
const expandIcon = () => (
|
|
193
|
-
<span>
|
|
194
|
-
text
|
|
195
|
-
{'>'}
|
|
196
|
-
</span>
|
|
197
|
-
)
|
|
198
|
-
const items: CollapseProps['items'] = [
|
|
199
|
-
{
|
|
200
|
-
label: 'collapse 1',
|
|
201
|
-
key: '1',
|
|
202
|
-
collapsible: 'disabled',
|
|
203
|
-
children: 'first',
|
|
204
|
-
},
|
|
205
|
-
{
|
|
206
|
-
label: 'collapse 2',
|
|
207
|
-
key: '2',
|
|
208
|
-
extra: <span>Extra span</span>,
|
|
209
|
-
children: 'second',
|
|
210
|
-
},
|
|
211
|
-
{
|
|
212
|
-
label: 'collapse 3',
|
|
213
|
-
key: '3',
|
|
214
|
-
className: 'important',
|
|
215
|
-
children: 'third',
|
|
216
|
-
},
|
|
217
|
-
]
|
|
218
|
-
|
|
219
|
-
const element = (
|
|
220
|
-
<Collapse onChange={onChange} expandIcon={expandIcon} items={items} />
|
|
221
|
-
)
|
|
222
|
-
runNormalTest(element)
|
|
223
|
-
})
|
|
224
|
-
|
|
225
|
-
describe('prop: headerClass', () => {
|
|
226
|
-
it('applies the passed headerClass to the header', () => {
|
|
227
|
-
const items = [
|
|
228
|
-
{
|
|
229
|
-
label: 'collapse 1',
|
|
230
|
-
key: '1',
|
|
231
|
-
headerClass: 'custom-class',
|
|
232
|
-
children: 'first',
|
|
233
|
-
},
|
|
234
|
-
]
|
|
235
|
-
const element = <Collapse onChange={onChange} items={items} />
|
|
236
|
-
|
|
237
|
-
const wrapper = mount(element)
|
|
238
|
-
const header = wrapper.find('.vc-collapse-header')
|
|
239
|
-
|
|
240
|
-
expect(header.element?.classList.contains('custom-class')).toBeTruthy()
|
|
241
|
-
})
|
|
242
|
-
|
|
243
|
-
it('should support extra whit number 0', () => {
|
|
244
|
-
const items = [
|
|
245
|
-
{
|
|
246
|
-
label: 'collapse 0',
|
|
247
|
-
key: 0,
|
|
248
|
-
extra: 0,
|
|
249
|
-
children: 'zero',
|
|
250
|
-
},
|
|
251
|
-
]
|
|
252
|
-
const wrapper = mount(
|
|
253
|
-
<Collapse onChange={onChange} activeKey={0} items={items}></Collapse>,
|
|
254
|
-
)
|
|
255
|
-
|
|
256
|
-
const extraNodes = wrapper.findAll('.vc-collapse-extra')
|
|
257
|
-
expect(extraNodes).toHaveLength(1)
|
|
258
|
-
expect(extraNodes[0].element.innerHTML).toBe('0')
|
|
259
|
-
})
|
|
260
|
-
|
|
261
|
-
it('should support activeKey number 0', () => {
|
|
262
|
-
const items = [
|
|
263
|
-
{
|
|
264
|
-
label: 'collapse 0',
|
|
265
|
-
key: 0,
|
|
266
|
-
children: 'zero',
|
|
267
|
-
},
|
|
268
|
-
{
|
|
269
|
-
label: 'collapse 1',
|
|
270
|
-
key: 1,
|
|
271
|
-
children: 'first',
|
|
272
|
-
},
|
|
273
|
-
{
|
|
274
|
-
label: 'collapse 2',
|
|
275
|
-
key: 2,
|
|
276
|
-
children: 'second',
|
|
277
|
-
},
|
|
278
|
-
]
|
|
279
|
-
const wrapper = mount(
|
|
280
|
-
<Collapse onChange={onChange} activeKey={0} items={items} />,
|
|
281
|
-
)
|
|
282
|
-
|
|
283
|
-
// activeKey number 0, should open one item
|
|
284
|
-
expect(wrapper.findAll('.vc-collapse-panel-active')).toHaveLength(1)
|
|
285
|
-
})
|
|
286
|
-
|
|
287
|
-
it('click should toggle panel state', async () => {
|
|
288
|
-
const items = [
|
|
289
|
-
{
|
|
290
|
-
label: 'collapse 1',
|
|
291
|
-
key: '1',
|
|
292
|
-
children: 'first',
|
|
293
|
-
},
|
|
294
|
-
{
|
|
295
|
-
label: 'collapse 2',
|
|
296
|
-
key: '2',
|
|
297
|
-
children: 'second',
|
|
298
|
-
},
|
|
299
|
-
{
|
|
300
|
-
label: 'collapse 3',
|
|
301
|
-
key: '3',
|
|
302
|
-
children: 'second',
|
|
303
|
-
className: 'important',
|
|
304
|
-
},
|
|
305
|
-
]
|
|
306
|
-
|
|
307
|
-
const wrapper = mount(
|
|
308
|
-
<Collapse
|
|
309
|
-
onChange={onChange}
|
|
310
|
-
destroyInactivePanel
|
|
311
|
-
items={items}
|
|
312
|
-
>
|
|
313
|
-
</Collapse>,
|
|
314
|
-
)
|
|
315
|
-
|
|
316
|
-
const header = wrapper.findAll('.vc-collapse-header')?.[1]
|
|
317
|
-
await header.trigger('click')
|
|
318
|
-
expect(wrapper.findAll('.vc-collapse-panel-active')).toHaveLength(1)
|
|
319
|
-
await header.trigger('click')
|
|
320
|
-
expect(wrapper.findAll('.vc-collapse-panel-inactive').length).toBeFalsy()
|
|
321
|
-
})
|
|
322
|
-
})
|
|
323
|
-
|
|
324
|
-
function runAccordionTest(element: any) {
|
|
325
|
-
let collapse: ReturnType<typeof mount>
|
|
326
|
-
|
|
327
|
-
beforeEach(() => {
|
|
328
|
-
collapse = mount(element)
|
|
329
|
-
})
|
|
330
|
-
|
|
331
|
-
afterEach(() => {
|
|
332
|
-
collapse.unmount()
|
|
333
|
-
})
|
|
334
|
-
|
|
335
|
-
it('accordion content, should default open zero item', () => {
|
|
336
|
-
expect(collapse.findAll('.vc-collapse-panel-active')).toHaveLength(0)
|
|
337
|
-
})
|
|
338
|
-
|
|
339
|
-
it('accordion item, should default open zero item', () => {
|
|
340
|
-
expect(collapse.findAll('.vc-collapse-item-active')).toHaveLength(0)
|
|
341
|
-
})
|
|
342
|
-
|
|
343
|
-
it('should toggle show on panel', async () => {
|
|
344
|
-
let header = collapse.findAll('.vc-collapse-header')?.[1]
|
|
345
|
-
await header.trigger('click')
|
|
346
|
-
expect(collapse.findAll('.vc-collapse-panel-active')).toHaveLength(1)
|
|
347
|
-
expect(collapse.findAll('.vc-collapse-item-active')).toHaveLength(1)
|
|
348
|
-
header = collapse.findAll('.vc-collapse-header')?.[1]
|
|
349
|
-
await header.trigger('click')
|
|
350
|
-
expect(collapse.findAll('.vc-collapse-panel-active')).toHaveLength(0)
|
|
351
|
-
expect(collapse.findAll('.vc-collapse-item-active')).toHaveLength(0)
|
|
352
|
-
})
|
|
353
|
-
|
|
354
|
-
it('should only show on panel', async () => {
|
|
355
|
-
let header = collapse.find('.vc-collapse-header')
|
|
356
|
-
expect(header.element).toBeTruthy()
|
|
357
|
-
await header.trigger('click')
|
|
358
|
-
expect(collapse.findAll('.vc-collapse-panel-active')).toHaveLength(1)
|
|
359
|
-
expect(collapse.findAll('.vc-collapse-item-active')).toHaveLength(1)
|
|
360
|
-
header = collapse.findAll('.vc-collapse-header')?.[2]
|
|
361
|
-
await header.trigger('click')
|
|
362
|
-
expect(collapse.findAll('.vc-collapse-panel-active')).toHaveLength(1)
|
|
363
|
-
expect(collapse.findAll('.vc-collapse-item-active')).toHaveLength(1)
|
|
364
|
-
})
|
|
365
|
-
|
|
366
|
-
it('should add tab role on panel title', () => {
|
|
367
|
-
const item = collapse.find('.vc-collapse-header')
|
|
368
|
-
expect(item.element).toBeTruthy()
|
|
369
|
-
expect(item.element.getAttribute('role')).toBe('tab')
|
|
370
|
-
})
|
|
371
|
-
|
|
372
|
-
it('should add tablist role on accordion', () => {
|
|
373
|
-
const item = collapse.find('.vc-collapse')
|
|
374
|
-
expect(item.element).toBeTruthy()
|
|
375
|
-
expect(item.element.getAttribute('role')).toBe('tablist')
|
|
376
|
-
})
|
|
377
|
-
|
|
378
|
-
it('should add tablist role on PanelContent', async () => {
|
|
379
|
-
const header = collapse.find('.vc-collapse-header')
|
|
380
|
-
expect(header.element).toBeTruthy()
|
|
381
|
-
await header.trigger('click')
|
|
382
|
-
const item = collapse.find('.vc-collapse-panel')
|
|
383
|
-
expect(item.element).toBeTruthy()
|
|
384
|
-
expect(item!.element.getAttribute('role')).toBe('tabpanel')
|
|
385
|
-
})
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
describe('prop: accordion', () => {
|
|
389
|
-
const items: CollapseProps['items'] = [
|
|
390
|
-
{
|
|
391
|
-
label: 'collapse 1',
|
|
392
|
-
key: '1',
|
|
393
|
-
children: 'first',
|
|
394
|
-
},
|
|
395
|
-
{
|
|
396
|
-
label: 'collapse 2',
|
|
397
|
-
key: '2',
|
|
398
|
-
children: 'second',
|
|
399
|
-
},
|
|
400
|
-
{
|
|
401
|
-
label: 'collapse 3',
|
|
402
|
-
key: '3',
|
|
403
|
-
children: 'third',
|
|
404
|
-
},
|
|
405
|
-
]
|
|
406
|
-
|
|
407
|
-
const element = <Collapse items={items} accordion onChange={onChange} />
|
|
408
|
-
|
|
409
|
-
runAccordionTest(element)
|
|
410
|
-
})
|
|
411
|
-
|
|
412
|
-
describe('forceRender', () => {
|
|
413
|
-
it('when forceRender is not supplied it should lazy render the panel content', () => {
|
|
414
|
-
const items: CollapseProps['items'] = [
|
|
415
|
-
{
|
|
416
|
-
label: 'collapse 1',
|
|
417
|
-
key: '1',
|
|
418
|
-
collapsible: 'disabled',
|
|
419
|
-
children: 'first',
|
|
420
|
-
},
|
|
421
|
-
{
|
|
422
|
-
label: 'collapse 2',
|
|
423
|
-
key: '2',
|
|
424
|
-
children: 'second',
|
|
425
|
-
},
|
|
426
|
-
]
|
|
427
|
-
const wrapper = mount(<Collapse items={items} />)
|
|
428
|
-
expect(wrapper.findAll('.vc-collapse-panel')).toHaveLength(0)
|
|
429
|
-
})
|
|
430
|
-
|
|
431
|
-
it('when forceRender is FALSE it should lazy render the panel content', () => {
|
|
432
|
-
const items: CollapseProps['items'] = [
|
|
433
|
-
{
|
|
434
|
-
label: 'collapse 1',
|
|
435
|
-
key: '1',
|
|
436
|
-
collapsible: 'disabled',
|
|
437
|
-
forceRender: false,
|
|
438
|
-
children: 'first',
|
|
439
|
-
},
|
|
440
|
-
{
|
|
441
|
-
label: 'collapse 2',
|
|
442
|
-
key: '2',
|
|
443
|
-
children: 'second',
|
|
444
|
-
},
|
|
445
|
-
]
|
|
446
|
-
|
|
447
|
-
const wrapper = mount(<Collapse items={items} />)
|
|
448
|
-
expect(wrapper.findAll('.vc-collapse-panel')).toHaveLength(0)
|
|
449
|
-
})
|
|
450
|
-
|
|
451
|
-
it('when forceRender is TRUE then it should render all the panel content to the DOM', () => {
|
|
452
|
-
const items: CollapseProps['items'] = [
|
|
453
|
-
{
|
|
454
|
-
label: 'collapse 1',
|
|
455
|
-
key: '1',
|
|
456
|
-
collapsible: 'disabled',
|
|
457
|
-
forceRender: true,
|
|
458
|
-
children: 'first',
|
|
459
|
-
},
|
|
460
|
-
{
|
|
461
|
-
label: 'collapse 2',
|
|
462
|
-
key: '2',
|
|
463
|
-
children: 'second',
|
|
464
|
-
},
|
|
465
|
-
]
|
|
466
|
-
const wrapper = mount(<Collapse items={items} />)
|
|
467
|
-
|
|
468
|
-
expect(wrapper.findAll('.vc-collapse-panel')).toHaveLength(1)
|
|
469
|
-
expect(wrapper.findAll('.vc-collapse-panel-active')).toHaveLength(0)
|
|
470
|
-
const inactiveDom = wrapper.find('div.vc-collapse-panel-inactive')
|
|
471
|
-
expect(inactiveDom.element).not.toBeFalsy()
|
|
472
|
-
expect(getComputedStyle(inactiveDom!.element)).toHaveProperty(
|
|
473
|
-
'display',
|
|
474
|
-
'none',
|
|
475
|
-
)
|
|
476
|
-
})
|
|
477
|
-
})
|
|
478
|
-
|
|
479
|
-
it('should toggle panel when press enter', async () => {
|
|
480
|
-
const myKeyEvent = {
|
|
481
|
-
keyCode: KeyCode.ENTER,
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
const items: CollapseProps['items'] = [
|
|
485
|
-
{
|
|
486
|
-
label: 'collapse 1',
|
|
487
|
-
key: '1',
|
|
488
|
-
|
|
489
|
-
children: 'first',
|
|
490
|
-
},
|
|
491
|
-
{
|
|
492
|
-
label: 'collapse 2',
|
|
493
|
-
key: '2',
|
|
494
|
-
children: 'second',
|
|
495
|
-
},
|
|
496
|
-
{
|
|
497
|
-
label: 'collapse 3',
|
|
498
|
-
key: '3',
|
|
499
|
-
children: 'second',
|
|
500
|
-
collapsible: 'disabled',
|
|
501
|
-
},
|
|
502
|
-
]
|
|
503
|
-
const wrapper = mount(<Collapse items={items} />)
|
|
504
|
-
|
|
505
|
-
// fireEvent.keyDown(container.querySelectorAll('.rc-collapse-header')?.[2], myKeyEvent);
|
|
506
|
-
const el = wrapper.findAll('.vc-collapse-header')?.[2]
|
|
507
|
-
await el.trigger('keydown', myKeyEvent)
|
|
508
|
-
expect(wrapper.findAll('.vc-collapse-panel-active')).toHaveLength(0)
|
|
509
|
-
|
|
510
|
-
await wrapper.find('.vc-collapse-header')?.trigger('keydown', myKeyEvent)
|
|
511
|
-
|
|
512
|
-
expect(wrapper.findAll('.vc-collapse-panel-active')).toHaveLength(1)
|
|
513
|
-
|
|
514
|
-
expect(wrapper.find('.vc-collapse-panel').element.className).toContain(
|
|
515
|
-
'vc-collapse-panel-active',
|
|
516
|
-
)
|
|
517
|
-
|
|
518
|
-
await wrapper.find('.vc-collapse-header').trigger('keydown', myKeyEvent)
|
|
519
|
-
|
|
520
|
-
expect(wrapper.findAll('.vc-collapse-panel-active')).toHaveLength(0)
|
|
521
|
-
expect(wrapper.find('.vc-collapse-panel')!.element.className).not.toContain(
|
|
522
|
-
'vc-collapse-panel-active',
|
|
523
|
-
)
|
|
524
|
-
})
|
|
525
|
-
|
|
526
|
-
it('should support return null icon', () => {
|
|
527
|
-
const items: CollapseProps['items'] = [
|
|
528
|
-
{ label: 'title', key: '1', children: 'first' },
|
|
529
|
-
]
|
|
530
|
-
const wrapper = mount(
|
|
531
|
-
<Collapse expandIcon={() => null} items={items}></Collapse>,
|
|
532
|
-
)
|
|
533
|
-
|
|
534
|
-
const childrenNodes = wrapper.find('.vc-collapse-header').element.childNodes
|
|
535
|
-
let len = 0
|
|
536
|
-
for (const node of childrenNodes) {
|
|
537
|
-
if (node.nodeType !== 8) {
|
|
538
|
-
len++
|
|
539
|
-
}
|
|
540
|
-
}
|
|
541
|
-
expect(len).toBe(1)
|
|
542
|
-
})
|
|
543
|
-
|
|
544
|
-
describe('prop: collapsible', () => {
|
|
545
|
-
it('default', async () => {
|
|
546
|
-
const items: CollapseProps['items'] = [
|
|
547
|
-
{ label: 'collapse 1', key: '1', children: 'first' },
|
|
548
|
-
]
|
|
549
|
-
const wrapper = mount(<Collapse items={items}></Collapse>)
|
|
550
|
-
expect(wrapper.find('.vc-collapse-title')).toBeTruthy()
|
|
551
|
-
await wrapper.find('.vc-collapse-header')?.trigger('click')
|
|
552
|
-
expect(wrapper.findAll('.vc-collapse-item-active')).toHaveLength(1)
|
|
553
|
-
})
|
|
554
|
-
it('should work when value is header', async () => {
|
|
555
|
-
const items: CollapseProps['items'] = [
|
|
556
|
-
{ label: 'collapse 1', key: '1', children: 'first' },
|
|
557
|
-
]
|
|
558
|
-
const wrapper = mount(
|
|
559
|
-
<Collapse collapsible="header" items={items}></Collapse>,
|
|
560
|
-
)
|
|
561
|
-
expect(wrapper.find('.vc-collapse-title')).toBeTruthy()
|
|
562
|
-
await wrapper.find('.vc-collapse-header').trigger('click')
|
|
563
|
-
expect(wrapper.findAll('.vc-collapse-item-active')).toHaveLength(0)
|
|
564
|
-
await wrapper.find('.vc-collapse-title').trigger('click')
|
|
565
|
-
expect(wrapper.findAll('.vc-collapse-item-active')).toHaveLength(1)
|
|
566
|
-
})
|
|
567
|
-
|
|
568
|
-
it('should work when value is icon', async () => {
|
|
569
|
-
const items: CollapseProps['items'] = [
|
|
570
|
-
{ label: 'collapse 1', key: '1', children: 'first' },
|
|
571
|
-
]
|
|
572
|
-
const wrapper = mount(
|
|
573
|
-
<Collapse collapsible="icon" items={items}></Collapse>,
|
|
574
|
-
)
|
|
575
|
-
expect(wrapper.find('.vc-collapse-expand-icon')).toBeTruthy()
|
|
576
|
-
await wrapper.find('.vc-collapse-header')!.trigger('click')
|
|
577
|
-
expect(wrapper.findAll('.vc-collapse-item-active')).toHaveLength(0)
|
|
578
|
-
await wrapper.find('.vc-collapse-expand-icon')!.trigger('click')
|
|
579
|
-
expect(wrapper.findAll('.vc-collapse-item-active')).toHaveLength(1)
|
|
580
|
-
})
|
|
581
|
-
|
|
582
|
-
it('should disabled when value is disabled', async () => {
|
|
583
|
-
const items: CollapseProps['items'] = [
|
|
584
|
-
{ label: 'collapse 1', key: '1', children: 'first' },
|
|
585
|
-
]
|
|
586
|
-
const wrapper = mount(
|
|
587
|
-
<Collapse collapsible="disabled" items={items}></Collapse>,
|
|
588
|
-
)
|
|
589
|
-
expect(wrapper.find('.vc-collapse-title')).toBeTruthy()
|
|
590
|
-
expect(wrapper.findAll('.vc-collapse-item-disabled')).toHaveLength(1)
|
|
591
|
-
await wrapper.find('.vc-collapse-header').trigger('click')
|
|
592
|
-
expect(wrapper.findAll('.vc-collapse-item-active')).toHaveLength(0)
|
|
593
|
-
})
|
|
594
|
-
|
|
595
|
-
it('the value of panel should be read first', async () => {
|
|
596
|
-
const items: CollapseProps['items'] = [
|
|
597
|
-
{
|
|
598
|
-
label: 'collapse 1',
|
|
599
|
-
key: '1',
|
|
600
|
-
children: 'first',
|
|
601
|
-
collapsible: 'disabled',
|
|
602
|
-
},
|
|
603
|
-
]
|
|
604
|
-
const wrapper = mount(
|
|
605
|
-
<Collapse collapsible="header" items={items}></Collapse>,
|
|
606
|
-
)
|
|
607
|
-
expect(wrapper.find('.vc-collapse-title')).toBeTruthy()
|
|
608
|
-
|
|
609
|
-
expect(wrapper.findAll('.vc-collapse-item-disabled')).toHaveLength(1)
|
|
610
|
-
|
|
611
|
-
await wrapper.find('.vc-collapse-header').trigger('click')
|
|
612
|
-
expect(wrapper.findAll('.vc-collapse-item-active')).toHaveLength(0)
|
|
613
|
-
})
|
|
614
|
-
|
|
615
|
-
it('icon trigger when collapsible equal header', async () => {
|
|
616
|
-
const items: CollapseProps['items'] = [
|
|
617
|
-
{ label: 'collapse 1', key: '1', children: 'first' },
|
|
618
|
-
]
|
|
619
|
-
const wrapper = mount(
|
|
620
|
-
<Collapse collapsible="header" items={items}></Collapse>,
|
|
621
|
-
)
|
|
622
|
-
|
|
623
|
-
await wrapper.find('.vc-collapse-header .arrow').trigger('click')
|
|
624
|
-
expect(wrapper.findAll('.vc-collapse-item-active')).toHaveLength(1)
|
|
625
|
-
})
|
|
626
|
-
|
|
627
|
-
it('header not trigger when collapsible equal icon', async () => {
|
|
628
|
-
const items: CollapseProps['items'] = [
|
|
629
|
-
{ label: 'collapse 1', key: '1', children: 'first' },
|
|
630
|
-
]
|
|
631
|
-
const wrapper = mount(
|
|
632
|
-
<Collapse collapsible="icon" items={items}></Collapse>,
|
|
633
|
-
)
|
|
634
|
-
await wrapper.find('.vc-collapse-title').trigger('click')
|
|
635
|
-
expect(wrapper.findAll('.vc-collapse-item-active')).toHaveLength(0)
|
|
636
|
-
})
|
|
637
|
-
})
|
|
638
|
-
|
|
639
|
-
it('!showArrow', () => {
|
|
640
|
-
const items: CollapseProps['items'] = [
|
|
641
|
-
{ label: 'collapse 1', key: '1', children: 'first', showArrow: false },
|
|
642
|
-
]
|
|
643
|
-
const wrapper = mount(<Collapse items={items}></Collapse>)
|
|
644
|
-
|
|
645
|
-
expect(wrapper.findAll('.vc-collapse-expand-icon')).toHaveLength(0)
|
|
646
|
-
})
|
|
647
|
-
|
|
648
|
-
it('panel container dom can set event handler', async () => {
|
|
649
|
-
const clickHandler = vi.fn()
|
|
650
|
-
const items: CollapseProps['items'] = [
|
|
651
|
-
{
|
|
652
|
-
label: 'collapse 1',
|
|
653
|
-
key: '1',
|
|
654
|
-
children: <div class="target">Click this</div>,
|
|
655
|
-
showArrow: false,
|
|
656
|
-
// @ts-expect-error: ignore error
|
|
657
|
-
onClick: clickHandler,
|
|
658
|
-
},
|
|
659
|
-
]
|
|
660
|
-
|
|
661
|
-
const wrapper = mount(
|
|
662
|
-
<Collapse defaultActiveKey="1" items={items}></Collapse>,
|
|
663
|
-
)
|
|
664
|
-
|
|
665
|
-
await wrapper.find('.target').trigger('click')
|
|
666
|
-
expect(clickHandler).toHaveBeenCalled()
|
|
667
|
-
})
|
|
668
|
-
|
|
669
|
-
it('falsy Panel', () => {
|
|
670
|
-
const wrapper = mount(
|
|
671
|
-
<Collapse>
|
|
672
|
-
{null}
|
|
673
|
-
<Panel header="collapse 1" key="1">
|
|
674
|
-
<p>Panel 1 content</p>
|
|
675
|
-
</Panel>
|
|
676
|
-
{0}
|
|
677
|
-
<Panel header="collapse 2" key="2">
|
|
678
|
-
<p>Panel 2 content</p>
|
|
679
|
-
</Panel>
|
|
680
|
-
{undefined}
|
|
681
|
-
{false}
|
|
682
|
-
{true}
|
|
683
|
-
</Collapse>,
|
|
684
|
-
)
|
|
685
|
-
expect(wrapper.findAll('.vc-collapse-item')).toHaveLength(2)
|
|
686
|
-
})
|
|
687
|
-
|
|
688
|
-
it('ref should work', async () => {
|
|
689
|
-
const panelRef = ref()
|
|
690
|
-
const items: CollapseProps['items'] = [
|
|
691
|
-
{ label: 'collapse 1', key: '1', children: 'first', ref: panelRef },
|
|
692
|
-
]
|
|
693
|
-
const wrapper = mount(<Collapse items={items} />)
|
|
694
|
-
await wrapper.vm.$nextTick()
|
|
695
|
-
|
|
696
|
-
expect(wrapper.vm.ref).toBe(wrapper.vm.$el)
|
|
697
|
-
expect(panelRef.value.ref).toBe(wrapper.find('.vc-collapse-item').element)
|
|
698
|
-
})
|
|
699
|
-
|
|
700
|
-
// https://github.com/react-component/collapse/issues/235
|
|
701
|
-
it('onItemClick should work', async () => {
|
|
702
|
-
const onItemClick = vi.fn()
|
|
703
|
-
const items: CollapseProps['items'] = [
|
|
704
|
-
{
|
|
705
|
-
label: 'collapse 1',
|
|
706
|
-
key: '1',
|
|
707
|
-
children: 'first',
|
|
708
|
-
onItemClick,
|
|
709
|
-
},
|
|
710
|
-
]
|
|
711
|
-
const wrapper = mount(<Collapse items={items}></Collapse>)
|
|
712
|
-
await wrapper.find('.vc-collapse-header').trigger('click')
|
|
713
|
-
expect(onItemClick).toHaveBeenCalled()
|
|
714
|
-
})
|
|
715
|
-
|
|
716
|
-
it('onItemClick should not work when collapsible is disabled', async () => {
|
|
717
|
-
const onItemClick = vi.fn()
|
|
718
|
-
const items: CollapseProps['items'] = [
|
|
719
|
-
{
|
|
720
|
-
label: 'collapse 1',
|
|
721
|
-
key: '1',
|
|
722
|
-
children: 'first',
|
|
723
|
-
onItemClick,
|
|
724
|
-
},
|
|
725
|
-
]
|
|
726
|
-
const wrapper = mount(
|
|
727
|
-
<Collapse collapsible="disabled" items={items}></Collapse>,
|
|
728
|
-
)
|
|
729
|
-
await wrapper.find('.vc-collapse-header').trigger('click')
|
|
730
|
-
expect(onItemClick).not.toHaveBeenCalled()
|
|
731
|
-
})
|
|
732
|
-
|
|
733
|
-
it('panel style should work', () => {
|
|
734
|
-
const items: CollapseProps['items'] = [
|
|
735
|
-
{
|
|
736
|
-
label: 'collapse 1',
|
|
737
|
-
key: '1',
|
|
738
|
-
children: 'first',
|
|
739
|
-
style: { color: 'red' },
|
|
740
|
-
},
|
|
741
|
-
]
|
|
742
|
-
const wrapper = mount(<Collapse items={items}></Collapse>)
|
|
743
|
-
expect(
|
|
744
|
-
(wrapper.find('.vc-collapse-item').element as HTMLDivElement)?.style.color,
|
|
745
|
-
).toBe('red')
|
|
746
|
-
})
|
|
747
|
-
|
|
748
|
-
describe('props items', () => {
|
|
749
|
-
const items: CollapseProps['items'] = [
|
|
750
|
-
{
|
|
751
|
-
key: '1',
|
|
752
|
-
label: 'collapse 1',
|
|
753
|
-
children: 'first',
|
|
754
|
-
collapsible: 'disabled',
|
|
755
|
-
},
|
|
756
|
-
{
|
|
757
|
-
key: '2',
|
|
758
|
-
label: 'collapse 2',
|
|
759
|
-
children: 'second',
|
|
760
|
-
extra: <span>Extra span</span>,
|
|
761
|
-
},
|
|
762
|
-
{
|
|
763
|
-
key: '3',
|
|
764
|
-
label: 'collapse 3',
|
|
765
|
-
className: 'important',
|
|
766
|
-
children: 'third',
|
|
767
|
-
},
|
|
768
|
-
]
|
|
769
|
-
|
|
770
|
-
runNormalTest(
|
|
771
|
-
<Collapse
|
|
772
|
-
onChange={onChange}
|
|
773
|
-
expandIcon={() => (
|
|
774
|
-
<span>
|
|
775
|
-
text
|
|
776
|
-
{'>'}
|
|
777
|
-
</span>
|
|
778
|
-
)}
|
|
779
|
-
items={items}
|
|
780
|
-
/>,
|
|
781
|
-
)
|
|
782
|
-
|
|
783
|
-
runAccordionTest(
|
|
784
|
-
<Collapse
|
|
785
|
-
onChange={onChange}
|
|
786
|
-
accordion
|
|
787
|
-
items={[
|
|
788
|
-
{
|
|
789
|
-
key: '1',
|
|
790
|
-
label: 'collapse 1',
|
|
791
|
-
children: 'first',
|
|
792
|
-
},
|
|
793
|
-
{
|
|
794
|
-
key: '2',
|
|
795
|
-
label: 'collapse 2',
|
|
796
|
-
children: 'second',
|
|
797
|
-
},
|
|
798
|
-
{
|
|
799
|
-
key: '3',
|
|
800
|
-
label: 'collapse 3',
|
|
801
|
-
children: 'third',
|
|
802
|
-
},
|
|
803
|
-
]}
|
|
804
|
-
/>,
|
|
805
|
-
)
|
|
806
|
-
|
|
807
|
-
it('should work with onItemClick', async () => {
|
|
808
|
-
const onItemClick = vi.fn()
|
|
809
|
-
const wrapper = mount(
|
|
810
|
-
<Collapse
|
|
811
|
-
items={[
|
|
812
|
-
{
|
|
813
|
-
label: 'title 3',
|
|
814
|
-
onItemClick,
|
|
815
|
-
},
|
|
816
|
-
]}
|
|
817
|
-
/>,
|
|
818
|
-
)
|
|
819
|
-
await wrapper.find('.vc-collapse-header').trigger('click')
|
|
820
|
-
expect(onItemClick).toHaveBeenCalled()
|
|
821
|
-
expect(onItemClick).lastCalledWith('0')
|
|
822
|
-
})
|
|
823
|
-
|
|
824
|
-
it('should work with collapsible', async () => {
|
|
825
|
-
const onItemClick = vi.fn()
|
|
826
|
-
const onChangeFn = vi.fn()
|
|
827
|
-
const wrapper = mount(
|
|
828
|
-
<Collapse
|
|
829
|
-
onChange={onChangeFn}
|
|
830
|
-
items={[
|
|
831
|
-
...items.slice(0, 1),
|
|
832
|
-
{
|
|
833
|
-
label: 'title 3',
|
|
834
|
-
onItemClick,
|
|
835
|
-
collapsible: 'icon',
|
|
836
|
-
},
|
|
837
|
-
]}
|
|
838
|
-
/>,
|
|
839
|
-
)
|
|
840
|
-
|
|
841
|
-
await wrapper.find('.vc-collapse-header').trigger('click')
|
|
842
|
-
|
|
843
|
-
expect(onItemClick).not.toHaveBeenCalled()
|
|
844
|
-
await wrapper
|
|
845
|
-
.find('.vc-collapse-item:nth-child(2) .vc-collapse-expand-icon')
|
|
846
|
-
.trigger('click')
|
|
847
|
-
expect(onItemClick).toHaveBeenCalled()
|
|
848
|
-
expect(onChangeFn).toBeCalledTimes(1)
|
|
849
|
-
expect(onChangeFn).lastCalledWith(['1'])
|
|
850
|
-
})
|
|
851
|
-
|
|
852
|
-
it('should work with nested', () => {
|
|
853
|
-
const wrapper = mount(
|
|
854
|
-
<Collapse
|
|
855
|
-
items={[
|
|
856
|
-
...items,
|
|
857
|
-
{
|
|
858
|
-
label: 'title 3',
|
|
859
|
-
children: <Collapse items={items} />,
|
|
860
|
-
},
|
|
861
|
-
]}
|
|
862
|
-
/>,
|
|
863
|
-
)
|
|
864
|
-
expect(wrapper.element.firstChild).toMatchSnapshot()
|
|
865
|
-
})
|
|
866
|
-
|
|
867
|
-
it('should not support expandIcon', () => {
|
|
868
|
-
const wrapper = mount(
|
|
869
|
-
<Collapse
|
|
870
|
-
expandIcon={() => <i class="custom-icon">p</i>}
|
|
871
|
-
items={[
|
|
872
|
-
{
|
|
873
|
-
label: 'title',
|
|
874
|
-
expandIcon: () => <i class="custom-icon">c</i>,
|
|
875
|
-
} as any,
|
|
876
|
-
]}
|
|
877
|
-
/>,
|
|
878
|
-
)
|
|
879
|
-
|
|
880
|
-
expect(wrapper.findAll('.custom-icon')).toHaveLength(1)
|
|
881
|
-
expect(wrapper.find('.custom-icon').element?.innerHTML).toBe('p')
|
|
882
|
-
})
|
|
883
|
-
|
|
884
|
-
it('should support data- and aria- attributes', () => {
|
|
885
|
-
const wrapper = mount(
|
|
886
|
-
<Collapse
|
|
887
|
-
data-testid="1234"
|
|
888
|
-
aria-label="test"
|
|
889
|
-
items={[
|
|
890
|
-
{
|
|
891
|
-
label: 'title',
|
|
892
|
-
} as any,
|
|
893
|
-
]}
|
|
894
|
-
/>,
|
|
895
|
-
)
|
|
896
|
-
|
|
897
|
-
expect(
|
|
898
|
-
wrapper.find('.vc-collapse').element?.getAttribute('data-testid'),
|
|
899
|
-
).toBe('1234')
|
|
900
|
-
expect(
|
|
901
|
-
wrapper.find('.vc-collapse').element?.getAttribute('aria-label'),
|
|
902
|
-
).toBe('test')
|
|
903
|
-
})
|
|
904
|
-
|
|
905
|
-
it('should support styles and classNames', () => {
|
|
906
|
-
const customStyles = {
|
|
907
|
-
header: { color: 'red' },
|
|
908
|
-
body: { color: 'blue' },
|
|
909
|
-
title: { color: 'green' },
|
|
910
|
-
icon: { color: 'yellow' },
|
|
911
|
-
}
|
|
912
|
-
const customClassnames = {
|
|
913
|
-
header: 'custom-header',
|
|
914
|
-
body: 'custom-body',
|
|
915
|
-
title: 'custom-title',
|
|
916
|
-
icon: 'custom-icon',
|
|
917
|
-
}
|
|
918
|
-
|
|
919
|
-
const wrapper = mount(
|
|
920
|
-
<Collapse
|
|
921
|
-
activeKey={['1']}
|
|
922
|
-
styles={customStyles}
|
|
923
|
-
classNames={customClassnames}
|
|
924
|
-
items={[
|
|
925
|
-
{
|
|
926
|
-
key: '1',
|
|
927
|
-
label: 'title',
|
|
928
|
-
},
|
|
929
|
-
]}
|
|
930
|
-
/>,
|
|
931
|
-
)
|
|
932
|
-
const headerElement = wrapper.find('.vc-collapse-header')
|
|
933
|
-
.element as HTMLElement
|
|
934
|
-
const bodyElement = wrapper.find('.vc-collapse-body')
|
|
935
|
-
.element as HTMLElement
|
|
936
|
-
const titleElement = wrapper.find('.vc-collapse-title')
|
|
937
|
-
.element as HTMLElement
|
|
938
|
-
const iconElement = wrapper.find('.vc-collapse-expand-icon')
|
|
939
|
-
.element as HTMLElement
|
|
940
|
-
|
|
941
|
-
// check classNames
|
|
942
|
-
expect(headerElement.classList).toContain('custom-header')
|
|
943
|
-
expect(bodyElement.classList).toContain('custom-body')
|
|
944
|
-
expect(titleElement.classList).toContain('custom-title')
|
|
945
|
-
expect(iconElement.classList).toContain('custom-icon')
|
|
946
|
-
|
|
947
|
-
// check styles
|
|
948
|
-
expect(headerElement.style.color).toBe('red')
|
|
949
|
-
expect(bodyElement.style.color).toBe('blue')
|
|
950
|
-
expect(titleElement.style.color).toBe('green')
|
|
951
|
-
expect(iconElement.style.color).toBe('yellow')
|
|
952
|
-
})
|
|
953
|
-
})
|
|
954
|
-
})
|