@@ -37,6 +37,57 @@ const items = ref([
37
37
} ,
38
38
] )
39
39
40
+ const sortableFields = defineTable ( [
41
+ { key : 'id' } ,
42
+ {
43
+ key : 'name' ,
44
+ sortable : true ,
45
+ } ,
46
+ {
47
+ key : 'gender' ,
48
+ sortable : true ,
49
+ } ,
50
+ {
51
+ key : 'age' ,
52
+ sortable : true ,
53
+ } ,
54
+ ] )
55
+
56
+ function generateItems ( ) {
57
+ return [
58
+ {
59
+ id : 1 ,
60
+ name : 'Dora' ,
61
+ gender : 'male' ,
62
+ age : 27 ,
63
+ } ,
64
+ {
65
+ id : 2 ,
66
+ name : 'Emilly' ,
67
+ gender : 'male' ,
68
+ age : 20 ,
69
+ } ,
70
+ {
71
+ id : 3 ,
72
+ name : 'Jane' ,
73
+ gender : 'female' ,
74
+ age : 30 ,
75
+ } ,
76
+ {
77
+ id : 4 ,
78
+ name : 'Andi' ,
79
+ gender : 'male' ,
80
+ age : 21 ,
81
+ } ,
82
+ {
83
+ id : 5 ,
84
+ name : 'Bella' ,
85
+ gender : 'female' ,
86
+ age : 24 ,
87
+ } ,
88
+ ]
89
+ }
90
+
40
91
it ( 'should render properly' , ( ) => {
41
92
const screen = render ( {
42
93
components : { Table } ,
@@ -305,3 +356,204 @@ it('should able to select all items (except disable one) in variant static', asy
305
356
306
357
expect ( selected . value ) . toHaveLength ( 0 )
307
358
} )
359
+
360
+ it ( 'should X field header have sortable class if have `sortable` property with `true` value & `sortable` prop is provided' , ( ) => {
361
+ const items = ref ( [ ] )
362
+ items . value = generateItems ( )
363
+
364
+ const screen = render ( {
365
+ components : { Table } ,
366
+ template : `
367
+ <Table
368
+ :fields="sortableFields"
369
+ v-model:items="items"
370
+ sortable
371
+ />` ,
372
+ setup ( ) {
373
+ return {
374
+ sortableFields,
375
+ items,
376
+ }
377
+ } ,
378
+ } )
379
+
380
+ const heads = screen . queryAllByTestId ( 'table-static-header' )
381
+
382
+ expect ( heads . at ( 0 ) ) . not . toHaveClass ( 'table-static__header--sortable' )
383
+ expect ( heads . at ( 1 ) ) . toHaveClass ( 'table-static__header--sortable' )
384
+ } )
385
+
386
+ it ( 'should X field header have caret up/down icon when sort by field' , async ( ) => {
387
+ const items = ref ( [ ] )
388
+ items . value = generateItems ( )
389
+
390
+ const screen = render ( {
391
+ components : { Table } ,
392
+ template : `
393
+ <Table
394
+ :fields="sortableFields"
395
+ v-model:items="items"
396
+ sortable
397
+ />` ,
398
+ setup ( ) {
399
+ return {
400
+ sortableFields,
401
+ items,
402
+ }
403
+ } ,
404
+ } )
405
+
406
+ const heads = screen . queryAllByTestId ( 'table-static-header' )
407
+
408
+ await fireEvent . click ( heads . at ( 1 ) )
409
+
410
+ const sortUp = heads . at ( 1 ) . querySelector ( '.table-static__header__sort-up' )
411
+
412
+ expect ( sortUp ) . toBeInTheDocument ( )
413
+
414
+ await fireEvent . click ( heads . at ( 1 ) )
415
+
416
+ const sortDown = heads . at ( 1 ) . querySelector ( '.table-static__header__sort-down' )
417
+
418
+ expect ( sortDown ) . toBeInTheDocument ( )
419
+ expect ( sortUp ) . not . toBeInTheDocument ( )
420
+
421
+ await fireEvent . click ( heads . at ( 1 ) )
422
+
423
+ expect ( sortDown ) . not . toBeInTheDocument ( )
424
+ } )
425
+
426
+ it ( 'should able to sort by field if `sortable` prop is provided' , async ( ) => {
427
+ const items = ref ( [ ] )
428
+ items . value = generateItems ( )
429
+
430
+ const sorts = ref ( [ ] )
431
+
432
+ const screen = render ( {
433
+ components : { Table } ,
434
+ template : `
435
+ <Table
436
+ :fields="sortableFields"
437
+ v-model:items="items"
438
+ sortable
439
+ @sort="sorts = $event"
440
+ />` ,
441
+ setup ( ) {
442
+ return {
443
+ sortableFields,
444
+ items,
445
+ sorts,
446
+ }
447
+ } ,
448
+ } )
449
+
450
+ expect ( sorts . value ) . toHaveLength ( 0 )
451
+
452
+ const heads = screen . queryAllByTestId ( 'table-static-header' )
453
+
454
+ await fireEvent . click ( heads . at ( 1 ) )
455
+
456
+ expect ( items . value . at ( 0 ) . name ) . toStrictEqual ( 'Andi' )
457
+ expect ( sorts . value ) . toHaveLength ( 1 )
458
+
459
+ await fireEvent . click ( heads . at ( 1 ) )
460
+
461
+ expect ( items . value . at ( 0 ) . name ) . toStrictEqual ( 'Jane' )
462
+
463
+ await fireEvent . click ( heads . at ( 1 ) )
464
+
465
+ expect ( items . value . at ( 0 ) . name ) . toStrictEqual ( 'Dora' )
466
+ } )
467
+
468
+ it ( 'should be not sort by field if field not `sortable` eventhough prop `sortable` is provided when render table' , async ( ) => {
469
+ const fields = defineTable ( [ { key : 'id' } , { key : 'name' } ] )
470
+ const items = ref ( [
471
+ {
472
+ id : 1 ,
473
+ name : 'Jane' ,
474
+ } ,
475
+ {
476
+ id : 2 ,
477
+ name : 'Tarjono' ,
478
+ } ,
479
+ ] )
480
+ const sorts = ref ( [ ] )
481
+
482
+ const screen = render ( {
483
+ components : { Table } ,
484
+ template : `
485
+ <Table
486
+ :fields="fields"
487
+ v-model:items="items"
488
+ sortable
489
+ @sort="sorts = $event"
490
+ />` ,
491
+ setup ( ) {
492
+ return {
493
+ fields,
494
+ items,
495
+ sorts,
496
+ }
497
+ } ,
498
+ } )
499
+
500
+ const heads = screen . queryAllByTestId ( 'table-static-header' )
501
+
502
+ await fireEvent . click ( heads . at ( 1 ) )
503
+
504
+ const sortUp = heads . at ( 1 ) . querySelector ( '.table-static__header__sort-up' )
505
+
506
+ expect ( sortUp ) . not . toBeInTheDocument ( )
507
+ expect ( sorts . value ) . toHaveLength ( 0 )
508
+ } )
509
+
510
+ it ( 'should able to sort by field if `sortable` prop is provided' , async ( ) => {
511
+ const items = ref ( [ ] )
512
+ items . value = generateItems ( )
513
+
514
+ const sorts = ref ( [ ] )
515
+
516
+ const screen = render ( {
517
+ components : { Table } ,
518
+ template : `
519
+ <Table
520
+ :fields="sortableFields"
521
+ v-model:items="items"
522
+ sortable
523
+ sortable-asyncronous
524
+ @sort="sorts = $event"
525
+ />` ,
526
+ setup ( ) {
527
+ return {
528
+ sortableFields,
529
+ items,
530
+ sorts,
531
+ }
532
+ } ,
533
+ } )
534
+
535
+ expect ( sorts . value ) . toHaveLength ( 0 )
536
+
537
+ const heads = screen . queryAllByTestId ( 'table-static-header' )
538
+
539
+ await fireEvent . click ( heads . at ( 2 ) ) // sort gender to ASC
540
+ expect ( sorts . value ) . toHaveLength ( 1 )
541
+ expect ( sorts . value . at ( 0 ) ) . toStrictEqual ( { key : 'gender' , value : 'asc' } )
542
+
543
+ await fireEvent . click ( heads . at ( 3 ) ) // sort age to ASC
544
+ expect ( sorts . value ) . toHaveLength ( 2 )
545
+ expect ( sorts . value . at ( 1 ) ) . toStrictEqual ( { key : 'age' , value : 'asc' } )
546
+
547
+ await fireEvent . click ( heads . at ( 2 ) ) // sort gender to DESC
548
+ expect ( sorts . value ) . toHaveLength ( 2 )
549
+ expect ( sorts . value . at ( 0 ) ) . toStrictEqual ( { key : 'gender' , value : 'desc' } )
550
+
551
+ await fireEvent . click ( heads . at ( 2 ) ) // clear gender sort
552
+ expect ( sorts . value ) . toHaveLength ( 1 )
553
+
554
+ await fireEvent . click ( heads . at ( 3 ) ) // sort age to DESC
555
+ expect ( sorts . value . at ( 0 ) ) . toStrictEqual ( { key : 'age' , value : 'desc' } )
556
+
557
+ await fireEvent . click ( heads . at ( 3 ) ) // clear age sort
558
+ expect ( sorts . value ) . toHaveLength ( 0 )
559
+ } )
0 commit comments