@furystack/shades-common-components 12.0.0 → 12.0.1
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 +13 -0
- package/esm/components/command-palette/command-palette-input.spec.js +148 -148
- package/esm/components/command-palette/command-palette-input.spec.js.map +1 -1
- package/esm/components/command-palette/command-palette-suggestion-list.spec.js +258 -258
- package/esm/components/command-palette/command-palette-suggestion-list.spec.js.map +1 -1
- package/esm/components/context-menu/context-menu-manager.spec.js +211 -217
- package/esm/components/context-menu/context-menu-manager.spec.js.map +1 -1
- package/esm/components/data-grid/body.spec.js +173 -173
- package/esm/components/data-grid/body.spec.js.map +1 -1
- package/esm/components/data-grid/data-grid.spec.js +39 -130
- package/esm/components/data-grid/data-grid.spec.js.map +1 -1
- package/esm/services/click-away-service.spec.js +14 -12
- package/esm/services/click-away-service.spec.js.map +1 -1
- package/esm/services/list-service.spec.js +170 -141
- package/esm/services/list-service.spec.js.map +1 -1
- package/esm/services/tree-service.spec.js +190 -159
- package/esm/services/tree-service.spec.js.map +1 -1
- package/package.json +7 -8
- package/src/components/command-palette/command-palette-input.spec.tsx +183 -194
- package/src/components/command-palette/command-palette-suggestion-list.spec.tsx +303 -321
- package/src/components/context-menu/context-menu-manager.spec.ts +213 -258
- package/src/components/data-grid/body.spec.tsx +266 -276
- package/src/components/data-grid/data-grid.spec.tsx +137 -232
- package/src/services/click-away-service.spec.ts +14 -16
- package/src/services/list-service.spec.ts +170 -172
- package/src/services/tree-service.spec.ts +191 -207
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { FindOptions } from '@furystack/core'
|
|
1
2
|
import { Injector } from '@furystack/inject'
|
|
2
3
|
import { createComponent, initializeShadeRoot } from '@furystack/shades'
|
|
3
4
|
import { ObservableValue, sleepAsync, usingAsync } from '@furystack/utils'
|
|
@@ -29,12 +30,30 @@ describe('DataGrid', () => {
|
|
|
29
30
|
return service
|
|
30
31
|
}
|
|
31
32
|
|
|
33
|
+
const withTestGrid = async (
|
|
34
|
+
fn: (ctx: {
|
|
35
|
+
injector: Injector
|
|
36
|
+
service: CollectionService<TestEntry>
|
|
37
|
+
findOptions: ObservableValue<FindOptions<TestEntry, Array<keyof TestEntry>>>
|
|
38
|
+
}) => Promise<void>,
|
|
39
|
+
opts?: { createService?: () => CollectionService<TestEntry> },
|
|
40
|
+
) => {
|
|
41
|
+
await usingAsync(new Injector(), async (injector) => {
|
|
42
|
+
await usingAsync(opts?.createService?.() ?? createTestService(), async (service) => {
|
|
43
|
+
await usingAsync(
|
|
44
|
+
new ObservableValue<FindOptions<TestEntry, Array<keyof TestEntry>>>({}),
|
|
45
|
+
async (findOptions) => {
|
|
46
|
+
await fn({ injector, service, findOptions })
|
|
47
|
+
},
|
|
48
|
+
)
|
|
49
|
+
})
|
|
50
|
+
})
|
|
51
|
+
}
|
|
52
|
+
|
|
32
53
|
describe('rendering', () => {
|
|
33
54
|
it('should render with columns', async () => {
|
|
34
|
-
await
|
|
55
|
+
await withTestGrid(async ({ injector, service, findOptions }) => {
|
|
35
56
|
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
36
|
-
const service = createTestService()
|
|
37
|
-
const findOptions = new ObservableValue<any>({})
|
|
38
57
|
|
|
39
58
|
initializeShadeRoot({
|
|
40
59
|
injector,
|
|
@@ -58,17 +77,12 @@ describe('DataGrid', () => {
|
|
|
58
77
|
|
|
59
78
|
const headers = grid?.querySelectorAll('th')
|
|
60
79
|
expect(headers?.length).toBe(2)
|
|
61
|
-
|
|
62
|
-
service[Symbol.dispose]()
|
|
63
|
-
findOptions[Symbol.dispose]()
|
|
64
80
|
})
|
|
65
81
|
})
|
|
66
82
|
|
|
67
83
|
it('should render table structure', async () => {
|
|
68
|
-
await
|
|
84
|
+
await withTestGrid(async ({ injector, service, findOptions }) => {
|
|
69
85
|
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
70
|
-
const service = createTestService()
|
|
71
|
-
const findOptions = new ObservableValue<any>({})
|
|
72
86
|
|
|
73
87
|
initializeShadeRoot({
|
|
74
88
|
injector,
|
|
@@ -95,17 +109,12 @@ describe('DataGrid', () => {
|
|
|
95
109
|
expect(table).not.toBeNull()
|
|
96
110
|
expect(thead).not.toBeNull()
|
|
97
111
|
expect(tbody).not.toBeNull()
|
|
98
|
-
|
|
99
|
-
service[Symbol.dispose]()
|
|
100
|
-
findOptions[Symbol.dispose]()
|
|
101
112
|
})
|
|
102
113
|
})
|
|
103
114
|
|
|
104
115
|
it('should render custom header components when provided', async () => {
|
|
105
|
-
await
|
|
116
|
+
await withTestGrid(async ({ injector, service, findOptions }) => {
|
|
106
117
|
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
107
|
-
const service = createTestService()
|
|
108
|
-
const findOptions = new ObservableValue<any>({})
|
|
109
118
|
|
|
110
119
|
initializeShadeRoot({
|
|
111
120
|
injector,
|
|
@@ -130,17 +139,12 @@ describe('DataGrid', () => {
|
|
|
130
139
|
const customHeader = grid?.querySelector('[data-testid="custom-header-id"]')
|
|
131
140
|
expect(customHeader).not.toBeNull()
|
|
132
141
|
expect(customHeader?.textContent).toBe('Custom ID Header')
|
|
133
|
-
|
|
134
|
-
service[Symbol.dispose]()
|
|
135
|
-
findOptions[Symbol.dispose]()
|
|
136
142
|
})
|
|
137
143
|
})
|
|
138
144
|
|
|
139
145
|
it('should render default header components from headerComponents.default', async () => {
|
|
140
|
-
await
|
|
146
|
+
await withTestGrid(async ({ injector, service, findOptions }) => {
|
|
141
147
|
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
142
|
-
const service = createTestService()
|
|
143
|
-
const findOptions = new ObservableValue<any>({})
|
|
144
148
|
|
|
145
149
|
initializeShadeRoot({
|
|
146
150
|
injector,
|
|
@@ -167,17 +171,12 @@ describe('DataGrid', () => {
|
|
|
167
171
|
|
|
168
172
|
expect(defaultHeaderId?.textContent).toBe('Default: id')
|
|
169
173
|
expect(defaultHeaderName?.textContent).toBe('Default: name')
|
|
170
|
-
|
|
171
|
-
service[Symbol.dispose]()
|
|
172
|
-
findOptions[Symbol.dispose]()
|
|
173
174
|
})
|
|
174
175
|
})
|
|
175
176
|
|
|
176
177
|
it('should render DataGridHeader when no custom header is provided', async () => {
|
|
177
|
-
await
|
|
178
|
+
await withTestGrid(async ({ injector, service, findOptions }) => {
|
|
178
179
|
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
179
|
-
const service = createTestService()
|
|
180
|
-
const findOptions = new ObservableValue<any>({})
|
|
181
180
|
|
|
182
181
|
initializeShadeRoot({
|
|
183
182
|
injector,
|
|
@@ -199,19 +198,14 @@ describe('DataGrid', () => {
|
|
|
199
198
|
const grid = document.querySelector('shade-data-grid')
|
|
200
199
|
const defaultHeaders = grid?.querySelectorAll('data-grid-header')
|
|
201
200
|
expect(defaultHeaders?.length).toBe(2)
|
|
202
|
-
|
|
203
|
-
service[Symbol.dispose]()
|
|
204
|
-
findOptions[Symbol.dispose]()
|
|
205
201
|
})
|
|
206
202
|
})
|
|
207
203
|
})
|
|
208
204
|
|
|
209
205
|
describe('focus management', () => {
|
|
210
206
|
it('should set focus on click', async () => {
|
|
211
|
-
await
|
|
207
|
+
await withTestGrid(async ({ injector, service, findOptions }) => {
|
|
212
208
|
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
213
|
-
const service = createTestService()
|
|
214
|
-
const findOptions = new ObservableValue<any>({})
|
|
215
209
|
|
|
216
210
|
expect(service.hasFocus.getValue()).toBe(false)
|
|
217
211
|
|
|
@@ -238,17 +232,12 @@ describe('DataGrid', () => {
|
|
|
238
232
|
wrapper?.click()
|
|
239
233
|
|
|
240
234
|
expect(service.hasFocus.getValue()).toBe(true)
|
|
241
|
-
|
|
242
|
-
service[Symbol.dispose]()
|
|
243
|
-
findOptions[Symbol.dispose]()
|
|
244
235
|
})
|
|
245
236
|
})
|
|
246
237
|
|
|
247
238
|
it('should lose focus on click outside', async () => {
|
|
248
|
-
await
|
|
239
|
+
await withTestGrid(async ({ injector, service, findOptions }) => {
|
|
249
240
|
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
250
|
-
const service = createTestService()
|
|
251
|
-
const findOptions = new ObservableValue<any>({})
|
|
252
241
|
|
|
253
242
|
initializeShadeRoot({
|
|
254
243
|
injector,
|
|
@@ -280,19 +269,14 @@ describe('DataGrid', () => {
|
|
|
280
269
|
outside?.dispatchEvent(new MouseEvent('click', { bubbles: true }))
|
|
281
270
|
|
|
282
271
|
expect(service.hasFocus.getValue()).toBe(false)
|
|
283
|
-
|
|
284
|
-
service[Symbol.dispose]()
|
|
285
|
-
findOptions[Symbol.dispose]()
|
|
286
272
|
})
|
|
287
273
|
})
|
|
288
274
|
})
|
|
289
275
|
|
|
290
276
|
describe('keyboard navigation', () => {
|
|
291
277
|
it('should handle ArrowDown to move focus to next entry', async () => {
|
|
292
|
-
await
|
|
278
|
+
await withTestGrid(async ({ injector, service, findOptions }) => {
|
|
293
279
|
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
294
|
-
const service = createTestService()
|
|
295
|
-
const findOptions = new ObservableValue<any>({})
|
|
296
280
|
|
|
297
281
|
service.hasFocus.setValue(true)
|
|
298
282
|
service.focusedEntry.setValue(service.data.getValue().entries[0])
|
|
@@ -318,17 +302,12 @@ describe('DataGrid', () => {
|
|
|
318
302
|
window.dispatchEvent(keydownEvent)
|
|
319
303
|
|
|
320
304
|
expect(service.focusedEntry.getValue()).toEqual({ id: 2, name: 'Second' })
|
|
321
|
-
|
|
322
|
-
service[Symbol.dispose]()
|
|
323
|
-
findOptions[Symbol.dispose]()
|
|
324
305
|
})
|
|
325
306
|
})
|
|
326
307
|
|
|
327
308
|
it('should handle ArrowUp to move focus to previous entry', async () => {
|
|
328
|
-
await
|
|
309
|
+
await withTestGrid(async ({ injector, service, findOptions }) => {
|
|
329
310
|
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
330
|
-
const service = createTestService()
|
|
331
|
-
const findOptions = new ObservableValue<any>({})
|
|
332
311
|
|
|
333
312
|
service.hasFocus.setValue(true)
|
|
334
313
|
service.focusedEntry.setValue(service.data.getValue().entries[1])
|
|
@@ -354,17 +333,12 @@ describe('DataGrid', () => {
|
|
|
354
333
|
window.dispatchEvent(keydownEvent)
|
|
355
334
|
|
|
356
335
|
expect(service.focusedEntry.getValue()).toEqual({ id: 1, name: 'First' })
|
|
357
|
-
|
|
358
|
-
service[Symbol.dispose]()
|
|
359
|
-
findOptions[Symbol.dispose]()
|
|
360
336
|
})
|
|
361
337
|
})
|
|
362
338
|
|
|
363
339
|
it('should handle Home to move focus to first entry', async () => {
|
|
364
|
-
await
|
|
340
|
+
await withTestGrid(async ({ injector, service, findOptions }) => {
|
|
365
341
|
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
366
|
-
const service = createTestService()
|
|
367
|
-
const findOptions = new ObservableValue<any>({})
|
|
368
342
|
|
|
369
343
|
service.hasFocus.setValue(true)
|
|
370
344
|
service.focusedEntry.setValue(service.data.getValue().entries[2])
|
|
@@ -390,17 +364,12 @@ describe('DataGrid', () => {
|
|
|
390
364
|
window.dispatchEvent(keydownEvent)
|
|
391
365
|
|
|
392
366
|
expect(service.focusedEntry.getValue()).toEqual({ id: 1, name: 'First' })
|
|
393
|
-
|
|
394
|
-
service[Symbol.dispose]()
|
|
395
|
-
findOptions[Symbol.dispose]()
|
|
396
367
|
})
|
|
397
368
|
})
|
|
398
369
|
|
|
399
370
|
it('should handle End to move focus to last entry', async () => {
|
|
400
|
-
await
|
|
371
|
+
await withTestGrid(async ({ injector, service, findOptions }) => {
|
|
401
372
|
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
402
|
-
const service = createTestService()
|
|
403
|
-
const findOptions = new ObservableValue<any>({})
|
|
404
373
|
|
|
405
374
|
service.hasFocus.setValue(true)
|
|
406
375
|
service.focusedEntry.setValue(service.data.getValue().entries[0])
|
|
@@ -426,17 +395,12 @@ describe('DataGrid', () => {
|
|
|
426
395
|
window.dispatchEvent(keydownEvent)
|
|
427
396
|
|
|
428
397
|
expect(service.focusedEntry.getValue()).toEqual({ id: 3, name: 'Third' })
|
|
429
|
-
|
|
430
|
-
service[Symbol.dispose]()
|
|
431
|
-
findOptions[Symbol.dispose]()
|
|
432
398
|
})
|
|
433
399
|
})
|
|
434
400
|
|
|
435
401
|
it('should handle Tab to toggle focus', async () => {
|
|
436
|
-
await
|
|
402
|
+
await withTestGrid(async ({ injector, service, findOptions }) => {
|
|
437
403
|
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
438
|
-
const service = createTestService()
|
|
439
|
-
const findOptions = new ObservableValue<any>({})
|
|
440
404
|
|
|
441
405
|
service.hasFocus.setValue(true)
|
|
442
406
|
|
|
@@ -461,17 +425,12 @@ describe('DataGrid', () => {
|
|
|
461
425
|
window.dispatchEvent(keydownEvent)
|
|
462
426
|
|
|
463
427
|
expect(service.hasFocus.getValue()).toBe(false)
|
|
464
|
-
|
|
465
|
-
service[Symbol.dispose]()
|
|
466
|
-
findOptions[Symbol.dispose]()
|
|
467
428
|
})
|
|
468
429
|
})
|
|
469
430
|
|
|
470
431
|
it('should handle Escape to clear selection and search', async () => {
|
|
471
|
-
await
|
|
432
|
+
await withTestGrid(async ({ injector, service, findOptions }) => {
|
|
472
433
|
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
473
|
-
const service = createTestService()
|
|
474
|
-
const findOptions = new ObservableValue<any>({})
|
|
475
434
|
|
|
476
435
|
const { entries } = service.data.getValue()
|
|
477
436
|
service.hasFocus.setValue(true)
|
|
@@ -500,17 +459,12 @@ describe('DataGrid', () => {
|
|
|
500
459
|
|
|
501
460
|
expect(service.selection.getValue()).toEqual([])
|
|
502
461
|
expect(service.searchTerm.getValue()).toBe('')
|
|
503
|
-
|
|
504
|
-
service[Symbol.dispose]()
|
|
505
|
-
findOptions[Symbol.dispose]()
|
|
506
462
|
})
|
|
507
463
|
})
|
|
508
464
|
|
|
509
465
|
it('should handle Space to toggle selection of focused entry', async () => {
|
|
510
|
-
await
|
|
466
|
+
await withTestGrid(async ({ injector, service, findOptions }) => {
|
|
511
467
|
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
512
|
-
const service = createTestService()
|
|
513
|
-
const findOptions = new ObservableValue<any>({})
|
|
514
468
|
|
|
515
469
|
const { entries } = service.data.getValue()
|
|
516
470
|
service.hasFocus.setValue(true)
|
|
@@ -540,17 +494,12 @@ describe('DataGrid', () => {
|
|
|
540
494
|
|
|
541
495
|
window.dispatchEvent(new KeyboardEvent('keydown', { key: ' ', bubbles: true }))
|
|
542
496
|
expect(service.selection.getValue()).not.toContain(entries[0])
|
|
543
|
-
|
|
544
|
-
service[Symbol.dispose]()
|
|
545
|
-
findOptions[Symbol.dispose]()
|
|
546
497
|
})
|
|
547
498
|
})
|
|
548
499
|
|
|
549
500
|
it('should handle + to select all entries', async () => {
|
|
550
|
-
await
|
|
501
|
+
await withTestGrid(async ({ injector, service, findOptions }) => {
|
|
551
502
|
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
552
|
-
const service = createTestService()
|
|
553
|
-
const findOptions = new ObservableValue<any>({})
|
|
554
503
|
|
|
555
504
|
service.hasFocus.setValue(true)
|
|
556
505
|
|
|
@@ -575,17 +524,12 @@ describe('DataGrid', () => {
|
|
|
575
524
|
window.dispatchEvent(keydownEvent)
|
|
576
525
|
|
|
577
526
|
expect(service.selection.getValue().length).toBe(3)
|
|
578
|
-
|
|
579
|
-
service[Symbol.dispose]()
|
|
580
|
-
findOptions[Symbol.dispose]()
|
|
581
527
|
})
|
|
582
528
|
})
|
|
583
529
|
|
|
584
530
|
it('should handle - to deselect all entries', async () => {
|
|
585
|
-
await
|
|
531
|
+
await withTestGrid(async ({ injector, service, findOptions }) => {
|
|
586
532
|
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
587
|
-
const service = createTestService()
|
|
588
|
-
const findOptions = new ObservableValue<any>({})
|
|
589
533
|
|
|
590
534
|
const { entries } = service.data.getValue()
|
|
591
535
|
service.hasFocus.setValue(true)
|
|
@@ -612,17 +556,12 @@ describe('DataGrid', () => {
|
|
|
612
556
|
window.dispatchEvent(keydownEvent)
|
|
613
557
|
|
|
614
558
|
expect(service.selection.getValue().length).toBe(0)
|
|
615
|
-
|
|
616
|
-
service[Symbol.dispose]()
|
|
617
|
-
findOptions[Symbol.dispose]()
|
|
618
559
|
})
|
|
619
560
|
})
|
|
620
561
|
|
|
621
562
|
it('should handle * to invert selection', async () => {
|
|
622
|
-
await
|
|
563
|
+
await withTestGrid(async ({ injector, service, findOptions }) => {
|
|
623
564
|
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
624
|
-
const service = createTestService()
|
|
625
|
-
const findOptions = new ObservableValue<any>({})
|
|
626
565
|
|
|
627
566
|
const { entries } = service.data.getValue()
|
|
628
567
|
service.hasFocus.setValue(true)
|
|
@@ -652,17 +591,12 @@ describe('DataGrid', () => {
|
|
|
652
591
|
expect(selection).not.toContain(entries[0])
|
|
653
592
|
expect(selection).toContain(entries[1])
|
|
654
593
|
expect(selection).toContain(entries[2])
|
|
655
|
-
|
|
656
|
-
service[Symbol.dispose]()
|
|
657
|
-
findOptions[Symbol.dispose]()
|
|
658
594
|
})
|
|
659
595
|
})
|
|
660
596
|
|
|
661
597
|
it('should not handle keyboard when not focused', async () => {
|
|
662
|
-
await
|
|
598
|
+
await withTestGrid(async ({ injector, service, findOptions }) => {
|
|
663
599
|
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
664
|
-
const service = createTestService()
|
|
665
|
-
const findOptions = new ObservableValue<any>({})
|
|
666
600
|
|
|
667
601
|
service.hasFocus.setValue(false)
|
|
668
602
|
service.focusedEntry.setValue(service.data.getValue().entries[0])
|
|
@@ -688,17 +622,12 @@ describe('DataGrid', () => {
|
|
|
688
622
|
window.dispatchEvent(keydownEvent)
|
|
689
623
|
|
|
690
624
|
expect(service.focusedEntry.getValue()).toEqual({ id: 1, name: 'First' })
|
|
691
|
-
|
|
692
|
-
service[Symbol.dispose]()
|
|
693
|
-
findOptions[Symbol.dispose]()
|
|
694
625
|
})
|
|
695
626
|
})
|
|
696
627
|
|
|
697
628
|
it('should handle Insert to toggle selection and move to next', async () => {
|
|
698
|
-
await
|
|
629
|
+
await withTestGrid(async ({ injector, service, findOptions }) => {
|
|
699
630
|
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
700
|
-
const service = createTestService()
|
|
701
|
-
const findOptions = new ObservableValue<any>({})
|
|
702
631
|
|
|
703
632
|
const { entries } = service.data.getValue()
|
|
704
633
|
service.hasFocus.setValue(true)
|
|
@@ -726,19 +655,14 @@ describe('DataGrid', () => {
|
|
|
726
655
|
|
|
727
656
|
expect(service.selection.getValue()).toContain(entries[0])
|
|
728
657
|
expect(service.focusedEntry.getValue()).toEqual(entries[1])
|
|
729
|
-
|
|
730
|
-
service[Symbol.dispose]()
|
|
731
|
-
findOptions[Symbol.dispose]()
|
|
732
658
|
})
|
|
733
659
|
})
|
|
734
660
|
})
|
|
735
661
|
|
|
736
662
|
describe('styles', () => {
|
|
737
663
|
it('should apply wrapper styles when provided', async () => {
|
|
738
|
-
await
|
|
664
|
+
await withTestGrid(async ({ injector, service, findOptions }) => {
|
|
739
665
|
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
740
|
-
const service = createTestService()
|
|
741
|
-
const findOptions = new ObservableValue<any>({})
|
|
742
666
|
|
|
743
667
|
initializeShadeRoot({
|
|
744
668
|
injector,
|
|
@@ -761,17 +685,12 @@ describe('DataGrid', () => {
|
|
|
761
685
|
|
|
762
686
|
const grid = document.querySelector('shade-data-grid') as HTMLElement
|
|
763
687
|
expect(grid?.style.backgroundColor).toBe('red')
|
|
764
|
-
|
|
765
|
-
service[Symbol.dispose]()
|
|
766
|
-
findOptions[Symbol.dispose]()
|
|
767
688
|
})
|
|
768
689
|
})
|
|
769
690
|
|
|
770
691
|
it('should apply header styles when provided', async () => {
|
|
771
|
-
await
|
|
692
|
+
await withTestGrid(async ({ injector, service, findOptions }) => {
|
|
772
693
|
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
773
|
-
const service = createTestService()
|
|
774
|
-
const findOptions = new ObservableValue<any>({})
|
|
775
694
|
|
|
776
695
|
initializeShadeRoot({
|
|
777
696
|
injector,
|
|
@@ -795,138 +714,127 @@ describe('DataGrid', () => {
|
|
|
795
714
|
const grid = document.querySelector('shade-data-grid')
|
|
796
715
|
const headers = grid?.querySelectorAll('th') as NodeListOf<HTMLElement>
|
|
797
716
|
expect(headers?.[0]?.style.color).toBe('blue')
|
|
798
|
-
|
|
799
|
-
service[Symbol.dispose]()
|
|
800
|
-
findOptions[Symbol.dispose]()
|
|
801
717
|
})
|
|
802
718
|
})
|
|
803
719
|
})
|
|
804
720
|
|
|
805
721
|
describe('empty and loading states', () => {
|
|
806
722
|
it('should show empty component when no data', async () => {
|
|
807
|
-
await
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
)
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
findOptions[Symbol.dispose]()
|
|
837
|
-
})
|
|
723
|
+
await withTestGrid(
|
|
724
|
+
async ({ injector, service, findOptions }) => {
|
|
725
|
+
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
726
|
+
|
|
727
|
+
initializeShadeRoot({
|
|
728
|
+
injector,
|
|
729
|
+
rootElement,
|
|
730
|
+
jsxElement: (
|
|
731
|
+
<DataGrid<TestEntry, 'id' | 'name'>
|
|
732
|
+
columns={['id', 'name']}
|
|
733
|
+
collectionService={service}
|
|
734
|
+
findOptions={findOptions}
|
|
735
|
+
styles={{}}
|
|
736
|
+
headerComponents={{}}
|
|
737
|
+
rowComponents={{}}
|
|
738
|
+
emptyComponent={<div data-testid="empty-state">No data available</div>}
|
|
739
|
+
/>
|
|
740
|
+
),
|
|
741
|
+
})
|
|
742
|
+
|
|
743
|
+
await sleepAsync(50)
|
|
744
|
+
|
|
745
|
+
const grid = document.querySelector('shade-data-grid')
|
|
746
|
+
const emptyState = grid?.querySelector('[data-testid="empty-state"]')
|
|
747
|
+
expect(emptyState).not.toBeNull()
|
|
748
|
+
expect(emptyState?.textContent).toBe('No data available')
|
|
749
|
+
},
|
|
750
|
+
{ createService: () => new CollectionService<TestEntry>() },
|
|
751
|
+
)
|
|
838
752
|
})
|
|
839
753
|
})
|
|
840
754
|
|
|
841
755
|
describe('row interactions', () => {
|
|
842
756
|
it('should pass row click to collectionService', async () => {
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
)
|
|
867
|
-
})
|
|
868
|
-
|
|
869
|
-
await sleepAsync(50)
|
|
757
|
+
const onRowClick = vi.fn()
|
|
758
|
+
await withTestGrid(
|
|
759
|
+
async ({ injector, service, findOptions }) => {
|
|
760
|
+
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
761
|
+
|
|
762
|
+
service.data.setValue({
|
|
763
|
+
count: 1,
|
|
764
|
+
entries: [{ id: 1, name: 'Test' }],
|
|
765
|
+
})
|
|
766
|
+
|
|
767
|
+
initializeShadeRoot({
|
|
768
|
+
injector,
|
|
769
|
+
rootElement,
|
|
770
|
+
jsxElement: (
|
|
771
|
+
<DataGrid<TestEntry, 'id' | 'name'>
|
|
772
|
+
columns={['id', 'name']}
|
|
773
|
+
collectionService={service}
|
|
774
|
+
findOptions={findOptions}
|
|
775
|
+
styles={{}}
|
|
776
|
+
headerComponents={{}}
|
|
777
|
+
rowComponents={{}}
|
|
778
|
+
/>
|
|
779
|
+
),
|
|
780
|
+
})
|
|
870
781
|
|
|
871
|
-
|
|
872
|
-
const cell = grid?.querySelector('td') as HTMLTableCellElement
|
|
873
|
-
cell?.click()
|
|
782
|
+
await sleepAsync(50)
|
|
874
783
|
|
|
875
|
-
|
|
784
|
+
const grid = document.querySelector('shade-data-grid')
|
|
785
|
+
const cell = grid?.querySelector('td') as HTMLTableCellElement
|
|
786
|
+
cell?.click()
|
|
876
787
|
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
788
|
+
expect(onRowClick).toHaveBeenCalledWith({ id: 1, name: 'Test' })
|
|
789
|
+
},
|
|
790
|
+
{ createService: () => new CollectionService<TestEntry>({ onRowClick }) },
|
|
791
|
+
)
|
|
880
792
|
})
|
|
881
793
|
|
|
882
794
|
it('should pass row double click to collectionService', async () => {
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
)
|
|
907
|
-
})
|
|
908
|
-
|
|
909
|
-
await sleepAsync(50)
|
|
795
|
+
const onRowDoubleClick = vi.fn()
|
|
796
|
+
await withTestGrid(
|
|
797
|
+
async ({ injector, service, findOptions }) => {
|
|
798
|
+
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
799
|
+
|
|
800
|
+
service.data.setValue({
|
|
801
|
+
count: 1,
|
|
802
|
+
entries: [{ id: 1, name: 'Test' }],
|
|
803
|
+
})
|
|
804
|
+
|
|
805
|
+
initializeShadeRoot({
|
|
806
|
+
injector,
|
|
807
|
+
rootElement,
|
|
808
|
+
jsxElement: (
|
|
809
|
+
<DataGrid<TestEntry, 'id' | 'name'>
|
|
810
|
+
columns={['id', 'name']}
|
|
811
|
+
collectionService={service}
|
|
812
|
+
findOptions={findOptions}
|
|
813
|
+
styles={{}}
|
|
814
|
+
headerComponents={{}}
|
|
815
|
+
rowComponents={{}}
|
|
816
|
+
/>
|
|
817
|
+
),
|
|
818
|
+
})
|
|
910
819
|
|
|
911
|
-
|
|
912
|
-
const cell = grid?.querySelector('td') as HTMLTableCellElement
|
|
913
|
-
const dblClickEvent = new MouseEvent('dblclick', { bubbles: true })
|
|
914
|
-
cell?.dispatchEvent(dblClickEvent)
|
|
820
|
+
await sleepAsync(50)
|
|
915
821
|
|
|
916
|
-
|
|
822
|
+
const grid = document.querySelector('shade-data-grid')
|
|
823
|
+
const cell = grid?.querySelector('td') as HTMLTableCellElement
|
|
824
|
+
const dblClickEvent = new MouseEvent('dblclick', { bubbles: true })
|
|
825
|
+
cell?.dispatchEvent(dblClickEvent)
|
|
917
826
|
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
827
|
+
expect(onRowDoubleClick).toHaveBeenCalledWith({ id: 1, name: 'Test' })
|
|
828
|
+
},
|
|
829
|
+
{ createService: () => new CollectionService<TestEntry>({ onRowDoubleClick }) },
|
|
830
|
+
)
|
|
921
831
|
})
|
|
922
832
|
})
|
|
923
833
|
|
|
924
834
|
describe('keyboard listener cleanup', () => {
|
|
925
835
|
it('should remove keyboard listener when component is disconnected', async () => {
|
|
926
|
-
await
|
|
836
|
+
await withTestGrid(async ({ injector, service, findOptions }) => {
|
|
927
837
|
const rootElement = document.getElementById('root') as HTMLDivElement
|
|
928
|
-
const service = createTestService()
|
|
929
|
-
const findOptions = new ObservableValue<any>({})
|
|
930
838
|
|
|
931
839
|
service.hasFocus.setValue(true)
|
|
932
840
|
service.focusedEntry.setValue(service.data.getValue().entries[0])
|
|
@@ -955,9 +863,6 @@ describe('DataGrid', () => {
|
|
|
955
863
|
|
|
956
864
|
window.dispatchEvent(new KeyboardEvent('keydown', { key: 'ArrowDown', bubbles: true }))
|
|
957
865
|
expect(service.focusedEntry.getValue()).toEqual({ id: 1, name: 'First' })
|
|
958
|
-
|
|
959
|
-
service[Symbol.dispose]()
|
|
960
|
-
findOptions[Symbol.dispose]()
|
|
961
866
|
})
|
|
962
867
|
})
|
|
963
868
|
})
|