@dashforge/tw 0.7.0-beta → 0.8.0-beta
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 +193 -0
- package/dist/index.esm.js +1092 -74
- package/dist/src/components/DataGrid/DataGrid.d.ts.map +1 -1
- package/dist/src/components/DataGrid/dataGrid.types.d.ts +43 -0
- package/dist/src/components/DataGrid/dataGrid.types.d.ts.map +1 -1
- package/dist/src/components/DataGrid/dataGrid.variants.d.ts +6 -0
- package/dist/src/components/DataGrid/dataGrid.variants.d.ts.map +1 -1
- package/dist/src/components/DataGrid/filters/ColumnFilters.d.ts +23 -0
- package/dist/src/components/DataGrid/filters/ColumnFilters.d.ts.map +1 -0
- package/dist/src/components/DataGrid/reorder/useColumnReorder.d.ts +50 -0
- package/dist/src/components/DataGrid/reorder/useColumnReorder.d.ts.map +1 -0
- package/dist/src/components/DataGrid/resize/useColumnResize.d.ts +32 -0
- package/dist/src/components/DataGrid/resize/useColumnResize.d.ts.map +1 -0
- package/dist/src/components/DataGrid/visibility/ColumnVisibilityDialog.d.ts +33 -0
- package/dist/src/components/DataGrid/visibility/ColumnVisibilityDialog.d.ts.map +1 -0
- package/dist/src/components/Table/Table.d.ts.map +1 -1
- package/dist/src/components/Table/table.types.d.ts +69 -5
- package/dist/src/components/Table/table.types.d.ts.map +1 -1
- package/dist/src/components/_shared/data/useTableFilter.d.ts +30 -7
- package/dist/src/components/_shared/data/useTableFilter.d.ts.map +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/components/DataGrid/DataGrid.test.tsx +422 -1
- package/src/components/DataGrid/DataGrid.tsx +421 -53
- package/src/components/DataGrid/dataGrid.types.ts +50 -1
- package/src/components/DataGrid/dataGrid.variants.ts +9 -1
- package/src/components/DataGrid/filters/ColumnFilters.tsx +432 -0
- package/src/components/DataGrid/reorder/useColumnReorder.test.ts +38 -0
- package/src/components/DataGrid/reorder/useColumnReorder.ts +144 -0
- package/src/components/DataGrid/resize/useColumnResize.ts +106 -0
- package/src/components/DataGrid/visibility/ColumnVisibilityDialog.tsx +200 -0
- package/src/components/Table/Table.tsx +14 -0
- package/src/components/Table/table.types.ts +74 -5
- package/src/components/_shared/data/useTableFilter.test.ts +166 -0
- package/src/components/_shared/data/useTableFilter.ts +97 -16
- package/src/index.ts +2 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// @vitest-environment jsdom
|
|
2
2
|
import * as React from 'react';
|
|
3
|
-
import { describe, it, expect, afterEach, beforeAll } from 'vitest';
|
|
3
|
+
import { describe, it, expect, afterEach, beforeAll, vi } from 'vitest';
|
|
4
4
|
import { render, screen, fireEvent, cleanup } from '@testing-library/react';
|
|
5
5
|
import { DataGrid } from './DataGrid.js';
|
|
6
6
|
import type { TableColumn } from '../Table/table.types.js';
|
|
@@ -494,3 +494,424 @@ describe('DataGrid — i18n', () => {
|
|
|
494
494
|
expect(screen.queryByLabelText('Seleziona tutto')).not.toBeNull();
|
|
495
495
|
});
|
|
496
496
|
});
|
|
497
|
+
|
|
498
|
+
describe('DataGrid — per-column filter UI', () => {
|
|
499
|
+
it('renders a filter trigger button only for filterable columns', () => {
|
|
500
|
+
const cols: TableColumn<User>[] = [
|
|
501
|
+
{ field: 'name', header: 'Name', filterable: true },
|
|
502
|
+
{ field: 'email', header: 'Email' },
|
|
503
|
+
{ field: 'age', header: 'Age', filterable: true },
|
|
504
|
+
];
|
|
505
|
+
render(
|
|
506
|
+
<DataGrid
|
|
507
|
+
rows={generateUsers(5)}
|
|
508
|
+
cols={cols}
|
|
509
|
+
getRowId={getRowId}
|
|
510
|
+
rowHeight={48}
|
|
511
|
+
height="400px"
|
|
512
|
+
/>,
|
|
513
|
+
);
|
|
514
|
+
// 2 filterable cols → 2 filter buttons
|
|
515
|
+
const triggers = screen.getAllByRole('button', { name: 'Filter' });
|
|
516
|
+
expect(triggers).toHaveLength(2);
|
|
517
|
+
});
|
|
518
|
+
|
|
519
|
+
it('shows active state (aria-pressed=true) when a filter is applied', () => {
|
|
520
|
+
const cols: TableColumn<User>[] = [
|
|
521
|
+
{ field: 'name', header: 'Name', filterable: true },
|
|
522
|
+
];
|
|
523
|
+
render(
|
|
524
|
+
<DataGrid
|
|
525
|
+
rows={generateUsers(5)}
|
|
526
|
+
cols={cols}
|
|
527
|
+
getRowId={getRowId}
|
|
528
|
+
rowHeight={48}
|
|
529
|
+
height="400px"
|
|
530
|
+
filterModel={[{ field: 'name', op: 'contains', value: 'User 1' }]}
|
|
531
|
+
/>,
|
|
532
|
+
);
|
|
533
|
+
const trigger = screen.getByRole('button', { name: 'Filter' });
|
|
534
|
+
expect(trigger.getAttribute('aria-pressed')).toBe('true');
|
|
535
|
+
});
|
|
536
|
+
|
|
537
|
+
it('opens a text input when filterable string column is clicked', () => {
|
|
538
|
+
const cols: TableColumn<User>[] = [
|
|
539
|
+
{ field: 'name', header: 'Name', filterable: true },
|
|
540
|
+
];
|
|
541
|
+
render(
|
|
542
|
+
<DataGrid
|
|
543
|
+
rows={generateUsers(5)}
|
|
544
|
+
cols={cols}
|
|
545
|
+
getRowId={getRowId}
|
|
546
|
+
rowHeight={48}
|
|
547
|
+
height="400px"
|
|
548
|
+
/>,
|
|
549
|
+
);
|
|
550
|
+
fireEvent.click(screen.getByRole('button', { name: 'Filter' }));
|
|
551
|
+
// Apply button means the Popover opened
|
|
552
|
+
expect(screen.queryByRole('button', { name: 'Apply' })).not.toBeNull();
|
|
553
|
+
});
|
|
554
|
+
|
|
555
|
+
it('opens Min/Max inputs for filterable number column', () => {
|
|
556
|
+
const cols: TableColumn<User>[] = [
|
|
557
|
+
{ field: 'age', header: 'Age', filterable: true },
|
|
558
|
+
];
|
|
559
|
+
render(
|
|
560
|
+
<DataGrid
|
|
561
|
+
rows={generateUsers(5)}
|
|
562
|
+
cols={cols}
|
|
563
|
+
getRowId={getRowId}
|
|
564
|
+
rowHeight={48}
|
|
565
|
+
height="400px"
|
|
566
|
+
/>,
|
|
567
|
+
);
|
|
568
|
+
fireEvent.click(screen.getByRole('button', { name: 'Filter' }));
|
|
569
|
+
expect(screen.queryByText('Min')).not.toBeNull();
|
|
570
|
+
expect(screen.queryByText('Max')).not.toBeNull();
|
|
571
|
+
});
|
|
572
|
+
|
|
573
|
+
it('explicit col.filterType="text" overrides number autodetect', () => {
|
|
574
|
+
const cols: TableColumn<User>[] = [
|
|
575
|
+
{ field: 'age', header: 'Age', filterable: true, filterType: 'text' },
|
|
576
|
+
];
|
|
577
|
+
render(
|
|
578
|
+
<DataGrid
|
|
579
|
+
rows={generateUsers(5)}
|
|
580
|
+
cols={cols}
|
|
581
|
+
getRowId={getRowId}
|
|
582
|
+
rowHeight={48}
|
|
583
|
+
height="400px"
|
|
584
|
+
/>,
|
|
585
|
+
);
|
|
586
|
+
fireEvent.click(screen.getByRole('button', { name: 'Filter' }));
|
|
587
|
+
// Text filter has Apply but no Min/Max
|
|
588
|
+
expect(screen.queryByRole('button', { name: 'Apply' })).not.toBeNull();
|
|
589
|
+
expect(screen.queryByText('Min')).toBeNull();
|
|
590
|
+
});
|
|
591
|
+
|
|
592
|
+
it('emits onFilterChange when Apply is clicked', () => {
|
|
593
|
+
const onFilterChange = vi.fn();
|
|
594
|
+
const cols: TableColumn<User>[] = [
|
|
595
|
+
{ field: 'name', header: 'Name', filterable: true },
|
|
596
|
+
];
|
|
597
|
+
render(
|
|
598
|
+
<DataGrid
|
|
599
|
+
rows={generateUsers(5)}
|
|
600
|
+
cols={cols}
|
|
601
|
+
getRowId={getRowId}
|
|
602
|
+
rowHeight={48}
|
|
603
|
+
height="400px"
|
|
604
|
+
onFilterChange={onFilterChange}
|
|
605
|
+
/>,
|
|
606
|
+
);
|
|
607
|
+
fireEvent.click(screen.getByRole('button', { name: 'Filter' }));
|
|
608
|
+
const input = screen.getByPlaceholderText('…') as HTMLInputElement;
|
|
609
|
+
fireEvent.change(input, { target: { value: 'User 2' } });
|
|
610
|
+
fireEvent.click(screen.getByRole('button', { name: 'Apply' }));
|
|
611
|
+
expect(onFilterChange).toHaveBeenCalledWith([
|
|
612
|
+
{ field: 'name', op: 'contains', value: 'User 2' },
|
|
613
|
+
]);
|
|
614
|
+
});
|
|
615
|
+
|
|
616
|
+
it('translates filter labels via the labels prop', () => {
|
|
617
|
+
const cols: TableColumn<User>[] = [
|
|
618
|
+
{ field: 'age', header: 'Età', filterable: true },
|
|
619
|
+
];
|
|
620
|
+
render(
|
|
621
|
+
<DataGrid
|
|
622
|
+
rows={generateUsers(5)}
|
|
623
|
+
cols={cols}
|
|
624
|
+
getRowId={getRowId}
|
|
625
|
+
rowHeight={48}
|
|
626
|
+
height="400px"
|
|
627
|
+
labels={{
|
|
628
|
+
filterColumn: 'Filtra',
|
|
629
|
+
filterApply: 'Applica',
|
|
630
|
+
filterClear: 'Pulisci',
|
|
631
|
+
filterMin: 'Min',
|
|
632
|
+
filterMax: 'Max',
|
|
633
|
+
}}
|
|
634
|
+
/>,
|
|
635
|
+
);
|
|
636
|
+
fireEvent.click(screen.getByRole('button', { name: 'Filtra' }));
|
|
637
|
+
expect(screen.queryByRole('button', { name: 'Applica' })).not.toBeNull();
|
|
638
|
+
expect(screen.queryByRole('button', { name: 'Pulisci' })).not.toBeNull();
|
|
639
|
+
});
|
|
640
|
+
});
|
|
641
|
+
|
|
642
|
+
describe('DataGrid — column visibility', () => {
|
|
643
|
+
it('renders the Columns toolbar button by default', () => {
|
|
644
|
+
render(
|
|
645
|
+
<DataGrid
|
|
646
|
+
rows={generateUsers(5)}
|
|
647
|
+
cols={baseCols}
|
|
648
|
+
getRowId={getRowId}
|
|
649
|
+
rowHeight={48}
|
|
650
|
+
height="400px"
|
|
651
|
+
/>,
|
|
652
|
+
);
|
|
653
|
+
expect(screen.queryByRole('button', { name: 'Columns' })).not.toBeNull();
|
|
654
|
+
});
|
|
655
|
+
|
|
656
|
+
it('does NOT render the Columns button when enableColumnVisibility=false', () => {
|
|
657
|
+
render(
|
|
658
|
+
<DataGrid
|
|
659
|
+
rows={generateUsers(5)}
|
|
660
|
+
cols={baseCols}
|
|
661
|
+
getRowId={getRowId}
|
|
662
|
+
rowHeight={48}
|
|
663
|
+
height="400px"
|
|
664
|
+
enableColumnVisibility={false}
|
|
665
|
+
/>,
|
|
666
|
+
);
|
|
667
|
+
expect(screen.queryByRole('button', { name: 'Columns' })).toBeNull();
|
|
668
|
+
});
|
|
669
|
+
|
|
670
|
+
it('opens dialog with one checkbox per hideable column', () => {
|
|
671
|
+
const cols: TableColumn<User>[] = [
|
|
672
|
+
{ field: 'name', header: 'Name' },
|
|
673
|
+
{ field: 'email', header: 'Email' },
|
|
674
|
+
// hideable: false → not shown in the dialog (structurally required)
|
|
675
|
+
{ field: 'age', header: 'Age', hideable: false },
|
|
676
|
+
];
|
|
677
|
+
render(
|
|
678
|
+
<DataGrid
|
|
679
|
+
rows={generateUsers(5)}
|
|
680
|
+
cols={cols}
|
|
681
|
+
getRowId={getRowId}
|
|
682
|
+
rowHeight={48}
|
|
683
|
+
height="400px"
|
|
684
|
+
/>,
|
|
685
|
+
);
|
|
686
|
+
fireEvent.click(screen.getByRole('button', { name: 'Columns' }));
|
|
687
|
+
expect(screen.queryByRole('dialog')).not.toBeNull();
|
|
688
|
+
// The dialog should expose checkboxes for Name + Email (not Age).
|
|
689
|
+
const labels = screen.getAllByText(/Name|Email|Age/);
|
|
690
|
+
// Name + Email appear in BOTH the table header and the dialog; Age
|
|
691
|
+
// appears only in the header (hideable=false → excluded from dialog).
|
|
692
|
+
const dialog = screen.getByRole('dialog');
|
|
693
|
+
expect(dialog.textContent).toContain('Name');
|
|
694
|
+
expect(dialog.textContent).toContain('Email');
|
|
695
|
+
expect(dialog.textContent).not.toContain('Age');
|
|
696
|
+
void labels;
|
|
697
|
+
});
|
|
698
|
+
|
|
699
|
+
it('respects col.defaultHidden on first render', () => {
|
|
700
|
+
const cols: TableColumn<User>[] = [
|
|
701
|
+
{ field: 'name', header: 'Name' },
|
|
702
|
+
{ field: 'email', header: 'Email', defaultHidden: true },
|
|
703
|
+
];
|
|
704
|
+
render(
|
|
705
|
+
<DataGrid
|
|
706
|
+
rows={generateUsers(5)}
|
|
707
|
+
cols={cols}
|
|
708
|
+
getRowId={getRowId}
|
|
709
|
+
rowHeight={48}
|
|
710
|
+
height="400px"
|
|
711
|
+
/>,
|
|
712
|
+
);
|
|
713
|
+
// Email column header should NOT be rendered initially.
|
|
714
|
+
expect(screen.queryByText('Email')).toBeNull();
|
|
715
|
+
// Name column header SHOULD be rendered.
|
|
716
|
+
expect(screen.queryByText('Name')).not.toBeNull();
|
|
717
|
+
});
|
|
718
|
+
|
|
719
|
+
it('toggling a column hides it from the table after Done', () => {
|
|
720
|
+
const onHiddenColumnsChange = vi.fn();
|
|
721
|
+
render(
|
|
722
|
+
<DataGrid
|
|
723
|
+
rows={generateUsers(5)}
|
|
724
|
+
cols={baseCols}
|
|
725
|
+
getRowId={getRowId}
|
|
726
|
+
rowHeight={48}
|
|
727
|
+
height="400px"
|
|
728
|
+
onHiddenColumnsChange={onHiddenColumnsChange}
|
|
729
|
+
/>,
|
|
730
|
+
);
|
|
731
|
+
fireEvent.click(screen.getByRole('button', { name: 'Columns' }));
|
|
732
|
+
// Uncheck "Email" inside the dialog
|
|
733
|
+
const dialog = screen.getByRole('dialog');
|
|
734
|
+
const emailCheckbox = Array.from(
|
|
735
|
+
dialog.querySelectorAll('input[type="checkbox"]'),
|
|
736
|
+
).find((el) => {
|
|
737
|
+
const li = el.closest('label');
|
|
738
|
+
return li?.textContent?.includes('Email');
|
|
739
|
+
}) as HTMLInputElement | undefined;
|
|
740
|
+
expect(emailCheckbox).toBeDefined();
|
|
741
|
+
fireEvent.click(emailCheckbox!);
|
|
742
|
+
// Commit via Done
|
|
743
|
+
fireEvent.click(screen.getByRole('button', { name: 'Done' }));
|
|
744
|
+
expect(onHiddenColumnsChange).toHaveBeenCalledWith(['email']);
|
|
745
|
+
});
|
|
746
|
+
|
|
747
|
+
it('controlled hiddenColumns hides the matching columns', () => {
|
|
748
|
+
render(
|
|
749
|
+
<DataGrid
|
|
750
|
+
rows={generateUsers(5)}
|
|
751
|
+
cols={baseCols}
|
|
752
|
+
getRowId={getRowId}
|
|
753
|
+
rowHeight={48}
|
|
754
|
+
height="400px"
|
|
755
|
+
hiddenColumns={['email']}
|
|
756
|
+
/>,
|
|
757
|
+
);
|
|
758
|
+
expect(screen.queryByText('Email')).toBeNull();
|
|
759
|
+
expect(screen.queryByText('Name')).not.toBeNull();
|
|
760
|
+
});
|
|
761
|
+
});
|
|
762
|
+
|
|
763
|
+
describe('DataGrid — column resize', () => {
|
|
764
|
+
it('renders a resize handle (separator) for each column by default', () => {
|
|
765
|
+
render(
|
|
766
|
+
<DataGrid
|
|
767
|
+
rows={generateUsers(5)}
|
|
768
|
+
cols={baseCols}
|
|
769
|
+
getRowId={getRowId}
|
|
770
|
+
rowHeight={48}
|
|
771
|
+
height="400px"
|
|
772
|
+
/>,
|
|
773
|
+
);
|
|
774
|
+
// One separator per column (4 columns).
|
|
775
|
+
const handles = screen.getAllByRole('separator');
|
|
776
|
+
expect(handles.length).toBe(baseCols.length);
|
|
777
|
+
});
|
|
778
|
+
|
|
779
|
+
it('omits resize handles when enableColumnResize=false', () => {
|
|
780
|
+
render(
|
|
781
|
+
<DataGrid
|
|
782
|
+
rows={generateUsers(5)}
|
|
783
|
+
cols={baseCols}
|
|
784
|
+
getRowId={getRowId}
|
|
785
|
+
rowHeight={48}
|
|
786
|
+
height="400px"
|
|
787
|
+
enableColumnResize={false}
|
|
788
|
+
/>,
|
|
789
|
+
);
|
|
790
|
+
expect(screen.queryAllByRole('separator')).toHaveLength(0);
|
|
791
|
+
});
|
|
792
|
+
|
|
793
|
+
it('omits resize handle for col.resizable=false', () => {
|
|
794
|
+
const cols: TableColumn<User>[] = [
|
|
795
|
+
{ field: 'name', header: 'Name' },
|
|
796
|
+
{ field: 'email', header: 'Email', resizable: false },
|
|
797
|
+
];
|
|
798
|
+
render(
|
|
799
|
+
<DataGrid
|
|
800
|
+
rows={generateUsers(5)}
|
|
801
|
+
cols={cols}
|
|
802
|
+
getRowId={getRowId}
|
|
803
|
+
rowHeight={48}
|
|
804
|
+
height="400px"
|
|
805
|
+
/>,
|
|
806
|
+
);
|
|
807
|
+
// Only 1 separator (Name); Email opted out via resizable=false.
|
|
808
|
+
expect(screen.getAllByRole('separator')).toHaveLength(1);
|
|
809
|
+
});
|
|
810
|
+
|
|
811
|
+
it('applies columnWidths to <th> style.width', () => {
|
|
812
|
+
const cols: TableColumn<User>[] = [
|
|
813
|
+
{ field: 'name', header: 'Name', width: 100 },
|
|
814
|
+
];
|
|
815
|
+
render(
|
|
816
|
+
<DataGrid
|
|
817
|
+
rows={generateUsers(5)}
|
|
818
|
+
cols={cols}
|
|
819
|
+
getRowId={getRowId}
|
|
820
|
+
rowHeight={48}
|
|
821
|
+
height="400px"
|
|
822
|
+
columnWidths={{ name: 250 }}
|
|
823
|
+
/>,
|
|
824
|
+
);
|
|
825
|
+
const th = screen.getByText('Name').closest('th');
|
|
826
|
+
expect(th?.style.width).toBe('250px');
|
|
827
|
+
});
|
|
828
|
+
|
|
829
|
+
it('falls back to col.width when no resize state for the column', () => {
|
|
830
|
+
const cols: TableColumn<User>[] = [
|
|
831
|
+
{ field: 'name', header: 'Name', width: 100 },
|
|
832
|
+
];
|
|
833
|
+
render(
|
|
834
|
+
<DataGrid
|
|
835
|
+
rows={generateUsers(5)}
|
|
836
|
+
cols={cols}
|
|
837
|
+
getRowId={getRowId}
|
|
838
|
+
rowHeight={48}
|
|
839
|
+
height="400px"
|
|
840
|
+
/>,
|
|
841
|
+
);
|
|
842
|
+
const th = screen.getByText('Name').closest('th');
|
|
843
|
+
expect(th?.style.width).toBe('100px');
|
|
844
|
+
});
|
|
845
|
+
});
|
|
846
|
+
|
|
847
|
+
describe('DataGrid — column reorder', () => {
|
|
848
|
+
it('applies the columnOrder prop to header order', () => {
|
|
849
|
+
const { container } = render(
|
|
850
|
+
<DataGrid
|
|
851
|
+
rows={generateUsers(3)}
|
|
852
|
+
cols={baseCols}
|
|
853
|
+
getRowId={getRowId}
|
|
854
|
+
rowHeight={48}
|
|
855
|
+
height="400px"
|
|
856
|
+
columnOrder={['age', 'name', 'email', 'meta.city']}
|
|
857
|
+
/>,
|
|
858
|
+
);
|
|
859
|
+
const headerTexts = Array.from(
|
|
860
|
+
container.querySelectorAll('thead th'),
|
|
861
|
+
).map((th) => th.textContent?.trim() ?? '');
|
|
862
|
+
// First three column headers should match the order
|
|
863
|
+
expect(headerTexts[0]).toContain('Age');
|
|
864
|
+
expect(headerTexts[1]).toContain('Name');
|
|
865
|
+
expect(headerTexts[2]).toContain('Email');
|
|
866
|
+
});
|
|
867
|
+
|
|
868
|
+
it('headers are draggable by default', () => {
|
|
869
|
+
const { container } = render(
|
|
870
|
+
<DataGrid
|
|
871
|
+
rows={generateUsers(3)}
|
|
872
|
+
cols={baseCols}
|
|
873
|
+
getRowId={getRowId}
|
|
874
|
+
rowHeight={48}
|
|
875
|
+
height="400px"
|
|
876
|
+
/>,
|
|
877
|
+
);
|
|
878
|
+
const draggableThs = container.querySelectorAll('thead th[draggable="true"]');
|
|
879
|
+
expect(draggableThs.length).toBe(baseCols.length);
|
|
880
|
+
});
|
|
881
|
+
|
|
882
|
+
it('does NOT make headers draggable when enableColumnReorder=false', () => {
|
|
883
|
+
const { container } = render(
|
|
884
|
+
<DataGrid
|
|
885
|
+
rows={generateUsers(3)}
|
|
886
|
+
cols={baseCols}
|
|
887
|
+
getRowId={getRowId}
|
|
888
|
+
rowHeight={48}
|
|
889
|
+
height="400px"
|
|
890
|
+
enableColumnReorder={false}
|
|
891
|
+
/>,
|
|
892
|
+
);
|
|
893
|
+
expect(
|
|
894
|
+
container.querySelectorAll('thead th[draggable="true"]'),
|
|
895
|
+
).toHaveLength(0);
|
|
896
|
+
});
|
|
897
|
+
|
|
898
|
+
it('respects col.reorderable=false per-column', () => {
|
|
899
|
+
const cols: TableColumn<User>[] = [
|
|
900
|
+
{ field: 'name', header: 'Name', reorderable: false },
|
|
901
|
+
{ field: 'email', header: 'Email' },
|
|
902
|
+
];
|
|
903
|
+
const { container } = render(
|
|
904
|
+
<DataGrid
|
|
905
|
+
rows={generateUsers(3)}
|
|
906
|
+
cols={cols}
|
|
907
|
+
getRowId={getRowId}
|
|
908
|
+
rowHeight={48}
|
|
909
|
+
height="400px"
|
|
910
|
+
/>,
|
|
911
|
+
);
|
|
912
|
+
// Only the Email th should be draggable.
|
|
913
|
+
const draggableThs = container.querySelectorAll('thead th[draggable="true"]');
|
|
914
|
+
expect(draggableThs.length).toBe(1);
|
|
915
|
+
expect(draggableThs[0]?.textContent).toContain('Email');
|
|
916
|
+
});
|
|
917
|
+
});
|