@coveord/plasma-mantine 52.9.0 → 52.10.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/.turbo/turbo-build.log +3 -3
- package/.turbo/turbo-test.log +33 -32
- package/dist/.tsbuildinfo +1 -1
- package/dist/cjs/components/code-editor/CodeEditor.d.ts.map +1 -1
- package/dist/cjs/components/code-editor/CodeEditor.js +8 -3
- package/dist/cjs/components/code-editor/CodeEditor.js.map +1 -1
- package/dist/cjs/components/collection/Collection.js +5 -3
- package/dist/cjs/components/collection/Collection.js.map +1 -1
- package/dist/cjs/components/date-range-picker/DateRangePickerPresetSelect.d.ts.map +1 -1
- package/dist/cjs/components/date-range-picker/DateRangePickerPresetSelect.js +2 -1
- package/dist/cjs/components/date-range-picker/DateRangePickerPresetSelect.js.map +1 -1
- package/dist/cjs/components/date-range-picker/EditableDateRangePicker.js +2 -2
- package/dist/cjs/components/date-range-picker/EditableDateRangePicker.js.map +1 -1
- package/dist/cjs/components/modal-wizard/ModalWizard.js +2 -2
- package/dist/cjs/components/modal-wizard/ModalWizard.js.map +1 -1
- package/dist/cjs/components/table/Table.d.ts.map +1 -1
- package/dist/cjs/components/table/Table.js +25 -13
- package/dist/cjs/components/table/Table.js.map +1 -1
- package/dist/cjs/components/table/Table.styles.d.ts.map +1 -1
- package/dist/cjs/components/table/Table.styles.js +1 -10
- package/dist/cjs/components/table/Table.styles.js.map +1 -1
- package/dist/cjs/components/table/Table.types.d.ts +14 -3
- package/dist/cjs/components/table/Table.types.d.ts.map +1 -1
- package/dist/cjs/components/table/TableFooter.js +2 -2
- package/dist/cjs/components/table/TableFooter.js.map +1 -1
- package/dist/cjs/components/table/TableHeader.js +1 -1
- package/dist/cjs/components/table/TableHeader.js.map +1 -1
- package/dist/cjs/components/table/TableLastUpdated.d.ts +24 -0
- package/dist/cjs/components/table/TableLastUpdated.d.ts.map +1 -0
- package/dist/cjs/components/table/TableLastUpdated.js +73 -0
- package/dist/cjs/components/table/TableLastUpdated.js.map +1 -0
- package/dist/cjs/components/table/TablePagination.d.ts.map +1 -1
- package/dist/cjs/components/table/TablePagination.js +1 -0
- package/dist/cjs/components/table/TablePagination.js.map +1 -1
- package/dist/cjs/components/table/TablePerPage.js +5 -3
- package/dist/cjs/components/table/TablePerPage.js.map +1 -1
- package/dist/cjs/components/table/layouts/RowLayout.d.ts.map +1 -1
- package/dist/cjs/components/table/layouts/RowLayout.js +41 -9
- package/dist/cjs/components/table/layouts/RowLayout.js.map +1 -1
- package/dist/cjs/components/table/useRowSelection.d.ts +2 -2
- package/dist/cjs/components/table/useRowSelection.d.ts.map +1 -1
- package/dist/cjs/components/table/useRowSelection.js +8 -3
- package/dist/cjs/components/table/useRowSelection.js.map +1 -1
- package/dist/cjs/theme/Theme.js +1 -1
- package/dist/cjs/theme/Theme.js.map +1 -1
- package/dist/esm/components/code-editor/CodeEditor.d.ts.map +1 -1
- package/dist/esm/components/code-editor/CodeEditor.js +8 -3
- package/dist/esm/components/code-editor/CodeEditor.js.map +1 -1
- package/dist/esm/components/collection/Collection.js +5 -3
- package/dist/esm/components/collection/Collection.js.map +1 -1
- package/dist/esm/components/date-range-picker/DateRangePickerPresetSelect.d.ts.map +1 -1
- package/dist/esm/components/date-range-picker/DateRangePickerPresetSelect.js +2 -1
- package/dist/esm/components/date-range-picker/DateRangePickerPresetSelect.js.map +1 -1
- package/dist/esm/components/date-range-picker/EditableDateRangePicker.js +2 -2
- package/dist/esm/components/date-range-picker/EditableDateRangePicker.js.map +1 -1
- package/dist/esm/components/modal-wizard/ModalWizard.js +2 -2
- package/dist/esm/components/modal-wizard/ModalWizard.js.map +1 -1
- package/dist/esm/components/table/Table.d.ts.map +1 -1
- package/dist/esm/components/table/Table.js +27 -15
- package/dist/esm/components/table/Table.js.map +1 -1
- package/dist/esm/components/table/Table.styles.d.ts.map +1 -1
- package/dist/esm/components/table/Table.styles.js +1 -10
- package/dist/esm/components/table/Table.styles.js.map +1 -1
- package/dist/esm/components/table/Table.types.d.ts +14 -3
- package/dist/esm/components/table/Table.types.d.ts.map +1 -1
- package/dist/esm/components/table/Table.types.js.map +1 -1
- package/dist/esm/components/table/TableFooter.js +2 -2
- package/dist/esm/components/table/TableFooter.js.map +1 -1
- package/dist/esm/components/table/TableHeader.js +1 -1
- package/dist/esm/components/table/TableHeader.js.map +1 -1
- package/dist/esm/components/table/TableLastUpdated.d.ts +24 -0
- package/dist/esm/components/table/TableLastUpdated.d.ts.map +1 -0
- package/dist/esm/components/table/TableLastUpdated.js +62 -0
- package/dist/esm/components/table/TableLastUpdated.js.map +1 -0
- package/dist/esm/components/table/TablePagination.d.ts.map +1 -1
- package/dist/esm/components/table/TablePagination.js +1 -0
- package/dist/esm/components/table/TablePagination.js.map +1 -1
- package/dist/esm/components/table/TablePerPage.js +5 -3
- package/dist/esm/components/table/TablePerPage.js.map +1 -1
- package/dist/esm/components/table/layouts/RowLayout.d.ts.map +1 -1
- package/dist/esm/components/table/layouts/RowLayout.js +42 -10
- package/dist/esm/components/table/layouts/RowLayout.js.map +1 -1
- package/dist/esm/components/table/useRowSelection.d.ts +2 -2
- package/dist/esm/components/table/useRowSelection.d.ts.map +1 -1
- package/dist/esm/components/table/useRowSelection.js +8 -3
- package/dist/esm/components/table/useRowSelection.js.map +1 -1
- package/dist/esm/theme/Theme.js +1 -1
- package/dist/esm/theme/Theme.js.map +1 -1
- package/package.json +17 -17
- package/src/__tests__/VitestSetup.ts +12 -0
- package/src/components/code-editor/CodeEditor.tsx +5 -3
- package/src/components/code-editor/__tests__/CodeEditor.spec.tsx +1 -0
- package/src/components/date-range-picker/DateRangePickerPresetSelect.tsx +1 -0
- package/src/components/date-range-picker/__tests__/DateRangePickerInlineCalendar.spec.tsx +2 -0
- package/src/components/date-range-picker/__tests__/DateRangePickerPopoverCalendar.spec.tsx +4 -19
- package/src/components/date-range-picker/__tests__/EditableDateRangePicker.spec.tsx +3 -3
- package/src/components/modal-wizard/__tests__/ModalWizard.spec.tsx +19 -4
- package/src/components/table/Table.styles.ts +0 -9
- package/src/components/table/Table.tsx +22 -13
- package/src/components/table/Table.types.ts +14 -3
- package/src/components/table/TableFooter.tsx +1 -1
- package/src/components/table/TableHeader.tsx +1 -1
- package/src/components/table/TableLastUpdated.tsx +51 -0
- package/src/components/table/TablePagination.tsx +1 -0
- package/src/components/table/TablePerPage.tsx +3 -3
- package/src/components/table/__tests__/Table.spec.tsx +44 -5
- package/src/components/table/__tests__/TableActions.spec.tsx +4 -3
- package/src/components/table/__tests__/TableDateRangePicker.spec.tsx +26 -59
- package/src/components/table/__tests__/TableLastUpdated.spec.tsx +97 -0
- package/src/components/table/__tests__/TablePredicate.spec.tsx +7 -55
- package/src/components/table/layouts/RowLayout.tsx +45 -11
- package/src/components/table/useRowSelection.ts +13 -6
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import {ColumnDef, createColumnHelper} from '@tanstack/table-core';
|
|
2
|
-
import {render, screen, userEvent, waitFor} from '@test-utils';
|
|
3
|
-
import {act} from 'react-dom/test-utils';
|
|
2
|
+
import {render, screen, userEvent, waitFor, within} from '@test-utils';
|
|
4
3
|
|
|
5
4
|
import {Table} from '../Table';
|
|
6
5
|
|
|
@@ -20,62 +19,32 @@ const basicTableWithDateRangePicker = (
|
|
|
20
19
|
</Table>
|
|
21
20
|
);
|
|
22
21
|
|
|
23
|
-
// Since we're mocking the date and the animations are timer based we're mocking useReduceMotion to disable all the animations
|
|
24
|
-
// I tried wrapping the components in <MantineProvider theme={{components: {Transition: {defaultProps: {duration: 0}}}}}>
|
|
25
|
-
// but the animation was still happening. :(
|
|
26
|
-
vi.mock('@mantine/hooks', async () => {
|
|
27
|
-
const actual = await vi.importActual('@mantine/hooks');
|
|
28
|
-
return {
|
|
29
|
-
...actual,
|
|
30
|
-
useReduceMotion: () => true,
|
|
31
|
-
};
|
|
32
|
-
});
|
|
33
|
-
|
|
34
22
|
describe('Table.DateRangePicker', () => {
|
|
35
|
-
beforeEach(() => {
|
|
36
|
-
vi.useFakeTimers().setSystemTime(new Date(2022, 0, 15));
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
afterEach(() => {
|
|
40
|
-
vi.useRealTimers();
|
|
41
|
-
});
|
|
42
|
-
|
|
43
23
|
it('displays the initial dates', async () => {
|
|
44
24
|
render(basicTableWithDateRangePicker);
|
|
45
25
|
|
|
46
|
-
|
|
47
|
-
expect(screen.getByText('Jan 01, 2022 - Jan 07, 2022')).toBeVisible();
|
|
48
|
-
});
|
|
26
|
+
expect(screen.getByText('Jan 01, 2022 - Jan 07, 2022')).toBeVisible();
|
|
49
27
|
});
|
|
50
28
|
|
|
51
29
|
it('opens the dialog when clicking on the calendar button', async () => {
|
|
52
|
-
|
|
53
|
-
vi.useRealTimers();
|
|
54
|
-
const user = userEvent.setup({delay: null});
|
|
30
|
+
const user = userEvent.setup();
|
|
55
31
|
render(basicTableWithDateRangePicker);
|
|
56
32
|
|
|
57
|
-
await screen.
|
|
58
|
-
|
|
59
|
-
await user.click(screen.getByRole('button', {name: 'calendar'}));
|
|
60
|
-
});
|
|
61
|
-
expect(screen.queryByRole('dialog')).toBeVisible();
|
|
33
|
+
await user.click(screen.getByRole('button', {name: 'calendar'}));
|
|
34
|
+
expect(screen.getByRole('dialog', {name: 'calendar'})).toBeVisible();
|
|
62
35
|
});
|
|
63
36
|
|
|
64
37
|
it('closes the dialog when clicking back on the calendar button', async () => {
|
|
65
|
-
|
|
66
|
-
vi.useRealTimers();
|
|
67
|
-
const user = userEvent.setup({delay: null});
|
|
38
|
+
const user = userEvent.setup();
|
|
68
39
|
render(basicTableWithDateRangePicker);
|
|
69
40
|
|
|
70
|
-
await screen.
|
|
71
|
-
await
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
});
|
|
75
|
-
expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
|
|
76
|
-
});
|
|
41
|
+
await user.click(screen.getByRole('button', {name: 'calendar'}));
|
|
42
|
+
await user.click(screen.getByRole('button', {name: 'calendar'}));
|
|
43
|
+
expect(screen.queryByRole('dialog', {name: 'calendar'})).not.toBeInTheDocument();
|
|
44
|
+
}, 10000);
|
|
77
45
|
|
|
78
46
|
it('displays the selected date range in the table', async () => {
|
|
47
|
+
vi.useFakeTimers().setSystemTime(new Date(2022, 0, 15));
|
|
79
48
|
const user = userEvent.setup({delay: null});
|
|
80
49
|
const onChange = vi.fn();
|
|
81
50
|
render(
|
|
@@ -85,35 +54,33 @@ describe('Table.DateRangePicker', () => {
|
|
|
85
54
|
onChange={onChange}
|
|
86
55
|
initialState={{dateRange: [new Date(2022, 0, 1), new Date(2022, 0, 7)]}}
|
|
87
56
|
>
|
|
88
|
-
<Table.Header>
|
|
57
|
+
<Table.Header data-testid="table-header">
|
|
89
58
|
<Table.DateRangePicker
|
|
90
59
|
presets={{preset: {label: 'Preset', range: [new Date(2022, 0, 8), new Date(2022, 0, 14)]}}}
|
|
91
60
|
/>
|
|
92
61
|
</Table.Header>
|
|
93
62
|
</Table>
|
|
94
63
|
);
|
|
64
|
+
const tableHeader = screen.getByTestId('table-header');
|
|
95
65
|
|
|
96
|
-
|
|
97
|
-
await
|
|
98
|
-
|
|
99
|
-
await user.click(screen.getByRole('button', {name: 'calendar'}));
|
|
66
|
+
expect(within(tableHeader).getByText('Jan 01, 2022 - Jan 07, 2022')).toBeInTheDocument();
|
|
67
|
+
await user.click(within(tableHeader).getByRole('button', {name: 'calendar'}));
|
|
100
68
|
|
|
101
|
-
await screen.findByRole('dialog');
|
|
69
|
+
const calendar = await screen.findByRole('dialog', {name: 'calendar'});
|
|
102
70
|
|
|
103
71
|
// select a preset
|
|
104
|
-
await user.click(
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
})
|
|
108
|
-
);
|
|
109
|
-
await user.click(screen.getByRole('option', {name: 'Preset'}));
|
|
110
|
-
|
|
111
|
-
await user.click(screen.getByRole('button', {name: 'Apply'}));
|
|
112
|
-
vi.advanceTimersByTime(500);
|
|
72
|
+
await user.click(within(calendar).getByRole('searchbox', {name: 'Date range'}));
|
|
73
|
+
await user.click(within(calendar).getByRole('option', {name: 'Preset'}));
|
|
74
|
+
await user.click(within(calendar).getByRole('button', {name: 'Apply'}));
|
|
113
75
|
|
|
114
|
-
await waitFor(() =>
|
|
76
|
+
await waitFor(() => {
|
|
77
|
+
expect(onChange).toHaveBeenCalledTimes(1);
|
|
78
|
+
});
|
|
115
79
|
expect(onChange).toHaveBeenCalledWith(
|
|
116
80
|
expect.objectContaining({dateRange: [new Date(2022, 0, 8), new Date(2022, 0, 14)]})
|
|
117
81
|
);
|
|
118
|
-
|
|
82
|
+
expect(within(tableHeader).getByText('Jan 08, 2022 - Jan 14, 2022')).toBeInTheDocument();
|
|
83
|
+
|
|
84
|
+
vi.useRealTimers();
|
|
85
|
+
}, 20000);
|
|
119
86
|
});
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import {ColumnDef, createColumnHelper} from '@tanstack/table-core';
|
|
2
|
+
import {render, screen, userEvent} from '@test-utils';
|
|
3
|
+
import {useState} from 'react';
|
|
4
|
+
|
|
5
|
+
import {Table} from '../Table';
|
|
6
|
+
|
|
7
|
+
type RowData = {name: string};
|
|
8
|
+
|
|
9
|
+
const columnHelper = createColumnHelper<RowData>();
|
|
10
|
+
const columns: Array<ColumnDef<RowData>> = [columnHelper.accessor('name', {enableSorting: false})];
|
|
11
|
+
|
|
12
|
+
describe('Table.LastUpdated', () => {
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
vi.useFakeTimers().setSystemTime(new Date(2022, 0, 15, 13, 5, 50));
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
afterEach(() => {
|
|
18
|
+
vi.useRealTimers();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('displays the label and time', () => {
|
|
22
|
+
const {rerender} = render(
|
|
23
|
+
<Table data={[{name: 'fruit'}]} columns={columns}>
|
|
24
|
+
<Table.LastUpdated />
|
|
25
|
+
</Table>
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
expect(screen.getByText('Last update:')).toBeVisible();
|
|
29
|
+
expect(screen.getByRole('timer')).toHaveTextContent('1:05:50 PM');
|
|
30
|
+
|
|
31
|
+
rerender(
|
|
32
|
+
<Table data={[{name: 'fruit'}]} columns={columns}>
|
|
33
|
+
<Table.LastUpdated label="CUSTOM label:" />
|
|
34
|
+
</Table>
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
expect(screen.queryByText('Last update:')).not.toBeInTheDocument();
|
|
38
|
+
expect(screen.getByText('CUSTOM label:')).toBeVisible();
|
|
39
|
+
expect(screen.getByRole('timer')).toHaveTextContent('1:05:50 PM');
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('updates the time when a dependency changes', async () => {
|
|
43
|
+
const user = userEvent.setup({delay: null});
|
|
44
|
+
|
|
45
|
+
// Using a fixture to have a button that will trigger a change of a dependency
|
|
46
|
+
const Fixture = () => {
|
|
47
|
+
const [isClicked, setIsClicked] = useState(false);
|
|
48
|
+
return (
|
|
49
|
+
<>
|
|
50
|
+
<button onClick={() => setIsClicked(true)}>Click me</button>
|
|
51
|
+
<Table data={[{name: 'fruit'}]} columns={columns}>
|
|
52
|
+
<Table.LastUpdated dependencies={[isClicked]} />
|
|
53
|
+
</Table>
|
|
54
|
+
</>
|
|
55
|
+
);
|
|
56
|
+
};
|
|
57
|
+
render(<Fixture />);
|
|
58
|
+
|
|
59
|
+
expect(screen.getByText('Last update:')).toBeVisible();
|
|
60
|
+
expect(screen.getByRole('timer')).toHaveTextContent('1:05:50 PM');
|
|
61
|
+
|
|
62
|
+
vi.setSystemTime(new Date(2022, 0, 15, 14, 11, 22));
|
|
63
|
+
|
|
64
|
+
// the date changed but the dependency didn't change yet, so the timer is still the same
|
|
65
|
+
expect(screen.getByRole('timer')).toHaveTextContent('1:05:50 PM');
|
|
66
|
+
|
|
67
|
+
// When we click on the button the isClicked switch from false to true which triggers an update
|
|
68
|
+
await user.click(screen.getByRole('button', {name: 'Click me'}));
|
|
69
|
+
expect(screen.getByRole('timer')).toHaveTextContent('2:11:22 PM');
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('updates the time when the data changes', async () => {
|
|
73
|
+
const user = userEvent.setup({delay: null});
|
|
74
|
+
const Fixture = () => {
|
|
75
|
+
const [data, setData] = useState([{name: 'fruit'}]);
|
|
76
|
+
return (
|
|
77
|
+
<>
|
|
78
|
+
<button onClick={() => setData([{name: 'vegetable'}])}>Click me</button>
|
|
79
|
+
<Table data={data} columns={columns}>
|
|
80
|
+
<Table.LastUpdated />
|
|
81
|
+
</Table>
|
|
82
|
+
</>
|
|
83
|
+
);
|
|
84
|
+
};
|
|
85
|
+
render(<Fixture />);
|
|
86
|
+
|
|
87
|
+
expect(screen.getByRole('timer')).toHaveTextContent('1:05:50 PM');
|
|
88
|
+
|
|
89
|
+
vi.setSystemTime(new Date(2022, 0, 15, 14, 11, 22));
|
|
90
|
+
|
|
91
|
+
expect(screen.getByRole('timer')).toHaveTextContent('1:05:50 PM');
|
|
92
|
+
|
|
93
|
+
await user.click(screen.getByRole('button', {name: 'Click me'}));
|
|
94
|
+
|
|
95
|
+
expect(screen.getByRole('timer')).toHaveTextContent('2:11:22 PM');
|
|
96
|
+
});
|
|
97
|
+
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {ColumnDef, createColumnHelper} from '@tanstack/table-core';
|
|
2
|
-
import {
|
|
2
|
+
import {render, screen, userEvent, waitFor} from '@test-utils';
|
|
3
3
|
|
|
4
4
|
import {Table} from '../Table';
|
|
5
5
|
|
|
@@ -9,40 +9,6 @@ const columnHelper = createColumnHelper<RowData>();
|
|
|
9
9
|
const columns: Array<ColumnDef<RowData>> = [columnHelper.accessor('name', {enableSorting: false})];
|
|
10
10
|
|
|
11
11
|
describe('Table.Predicate', () => {
|
|
12
|
-
beforeEach(() => {
|
|
13
|
-
vi.useFakeTimers();
|
|
14
|
-
});
|
|
15
|
-
afterEach(() => {
|
|
16
|
-
vi.useRealTimers();
|
|
17
|
-
});
|
|
18
|
-
it('displays the intial value', async () => {
|
|
19
|
-
render(
|
|
20
|
-
<Table
|
|
21
|
-
data={[{name: 'fruit'}, {name: 'vegetable'}]}
|
|
22
|
-
columns={columns}
|
|
23
|
-
initialState={{predicates: {rank: 'second'}}}
|
|
24
|
-
>
|
|
25
|
-
<Table.Header>
|
|
26
|
-
<Table.Predicate
|
|
27
|
-
id="rank"
|
|
28
|
-
data={[
|
|
29
|
-
{value: 'first', label: 'First'},
|
|
30
|
-
{value: 'second', label: 'Second'},
|
|
31
|
-
]}
|
|
32
|
-
/>
|
|
33
|
-
</Table.Header>
|
|
34
|
-
</Table>
|
|
35
|
-
);
|
|
36
|
-
|
|
37
|
-
await waitFor(() => {
|
|
38
|
-
expect(
|
|
39
|
-
screen.getByRole('searchbox', {
|
|
40
|
-
name: 'rank',
|
|
41
|
-
})
|
|
42
|
-
).toHaveValue('Second');
|
|
43
|
-
});
|
|
44
|
-
});
|
|
45
|
-
|
|
46
12
|
it('calls onMount with the initial value', async () => {
|
|
47
13
|
const onMount = vi.fn();
|
|
48
14
|
render(
|
|
@@ -65,26 +31,17 @@ describe('Table.Predicate', () => {
|
|
|
65
31
|
);
|
|
66
32
|
|
|
67
33
|
await waitFor(() => {
|
|
68
|
-
expect(
|
|
69
|
-
screen.getByRole('searchbox', {
|
|
70
|
-
name: 'rank',
|
|
71
|
-
})
|
|
72
|
-
).toHaveValue('Second');
|
|
34
|
+
expect(screen.getByRole('searchbox', {name: 'rank'})).toHaveValue('Second');
|
|
73
35
|
});
|
|
74
36
|
expect(onMount).toHaveBeenCalledWith(expect.objectContaining({predicates: {rank: 'second'}}));
|
|
75
37
|
});
|
|
76
38
|
|
|
77
39
|
it('calls onChange when changing the predicate', async () => {
|
|
78
|
-
const user = userEvent.setup(
|
|
40
|
+
const user = userEvent.setup();
|
|
79
41
|
const onChange = vi.fn();
|
|
80
42
|
render(
|
|
81
|
-
<Table
|
|
82
|
-
data=
|
|
83
|
-
columns={columns}
|
|
84
|
-
onChange={onChange}
|
|
85
|
-
initialState={{predicates: {rank: 'second'}}}
|
|
86
|
-
>
|
|
87
|
-
<Table.Header>
|
|
43
|
+
<Table data={[{name: 'fruit'}, {name: 'vegetable'}]} columns={columns} onChange={onChange}>
|
|
44
|
+
<Table.Header data-testid="table-header">
|
|
88
45
|
<Table.Predicate
|
|
89
46
|
id="rank"
|
|
90
47
|
data={[
|
|
@@ -96,18 +53,13 @@ describe('Table.Predicate', () => {
|
|
|
96
53
|
</Table>
|
|
97
54
|
);
|
|
98
55
|
|
|
99
|
-
expect(screen.getByRole('searchbox', {name: 'rank'})).toHaveValue('Second');
|
|
100
|
-
|
|
101
56
|
await user.click(screen.getByRole('searchbox', {name: 'rank'}));
|
|
102
|
-
|
|
103
57
|
await user.click(screen.getByRole('option', {name: 'First'}));
|
|
104
58
|
|
|
105
59
|
expect(screen.getByRole('searchbox', {name: 'rank'})).toHaveValue('First');
|
|
106
|
-
|
|
107
|
-
|
|
60
|
+
await waitFor(() => {
|
|
61
|
+
expect(onChange).toHaveBeenCalledTimes(1);
|
|
108
62
|
});
|
|
109
|
-
|
|
110
|
-
expect(onChange).toHaveBeenCalledTimes(1);
|
|
111
63
|
expect(onChange).toHaveBeenCalledWith(expect.objectContaining({predicates: {rank: 'first'}}));
|
|
112
64
|
});
|
|
113
65
|
});
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import {ListSize16Px} from '@coveord/plasma-react-icons';
|
|
2
|
-
import {Box, Collapse, createStyles} from '@mantine/core';
|
|
2
|
+
import {Box, Collapse, createStyles, rem} from '@mantine/core';
|
|
3
3
|
import {flexRender} from '@tanstack/react-table';
|
|
4
4
|
import {defaultColumnSizing} from '@tanstack/table-core';
|
|
5
|
-
import {Fragment} from 'react';
|
|
5
|
+
import {Fragment, type MouseEvent} from 'react';
|
|
6
6
|
import {TableLayout, TableLayoutProps} from '../Table.types';
|
|
7
7
|
import {TableCollapsibleColumn} from '../TableCollapsibleColumn';
|
|
8
8
|
import {useTable} from '../TableContext';
|
|
9
9
|
import {TableLoading} from '../TableLoading';
|
|
10
|
+
import {TableSelectableColumn} from '../TableSelectableColumn';
|
|
10
11
|
import {Th} from '../Th';
|
|
11
12
|
|
|
12
13
|
interface TableStylesParams {
|
|
@@ -16,13 +17,12 @@ interface TableStylesParams {
|
|
|
16
17
|
|
|
17
18
|
const useStyles = createStyles<string, TableStylesParams>((theme, {multiRowSelectionEnabled, disableRowSelection}) => {
|
|
18
19
|
const rowBackgroundColor =
|
|
19
|
-
theme.colorScheme === 'dark'
|
|
20
|
-
|
|
21
|
-
: theme.colors[theme.primaryColor][0];
|
|
20
|
+
theme.colorScheme === 'dark' ? theme.fn.rgba(theme.colors[theme.primaryColor][7], 0.2) : theme.colors.gray[1];
|
|
21
|
+
const border = `${rem(1)} solid ${theme.colorScheme === 'dark' ? theme.colors.dark[4] : theme.colors.gray[3]}`;
|
|
22
22
|
return {
|
|
23
23
|
headerColumns: {
|
|
24
24
|
'& th:first-of-type > *': {
|
|
25
|
-
paddingLeft:
|
|
25
|
+
paddingLeft: '40px',
|
|
26
26
|
},
|
|
27
27
|
|
|
28
28
|
'& input[type=checkbox]': {
|
|
@@ -60,10 +60,26 @@ const useStyles = createStyles<string, TableStylesParams>((theme, {multiRowSelec
|
|
|
60
60
|
},
|
|
61
61
|
|
|
62
62
|
row: {
|
|
63
|
+
'& td:first-of-type': {
|
|
64
|
+
paddingLeft: '40px',
|
|
65
|
+
},
|
|
63
66
|
'&:hover': {
|
|
64
67
|
backgroundColor: rowBackgroundColor,
|
|
65
68
|
},
|
|
66
69
|
},
|
|
70
|
+
|
|
71
|
+
cell: {
|
|
72
|
+
verticalAlign: 'middle',
|
|
73
|
+
// We must use height instead of minHeight here, otherwise it doesn't apply
|
|
74
|
+
height: '56px',
|
|
75
|
+
padding: `${theme.spacing.xs} ${theme.spacing.sm}`,
|
|
76
|
+
borderBottom: border,
|
|
77
|
+
},
|
|
78
|
+
|
|
79
|
+
collapsible: {
|
|
80
|
+
backgroundColor: rowBackgroundColor,
|
|
81
|
+
borderBottom: border,
|
|
82
|
+
},
|
|
67
83
|
};
|
|
68
84
|
});
|
|
69
85
|
|
|
@@ -84,14 +100,27 @@ const RowLayoutBody = <T,>({table, doubleClickAction, getExpandChildren, loading
|
|
|
84
100
|
const {multiRowSelectionEnabled, disableRowSelection} = useTable();
|
|
85
101
|
const {classes, cx} = useStyles({disableRowSelection, multiRowSelectionEnabled});
|
|
86
102
|
|
|
103
|
+
const toggleCollapsible = (el: HTMLTableRowElement) => {
|
|
104
|
+
const cell = el.children[el.children.length - 1] as HTMLTableCellElement;
|
|
105
|
+
cell.querySelector('button').click();
|
|
106
|
+
};
|
|
107
|
+
|
|
87
108
|
const rows = table.getRowModel().rows.map((row) => {
|
|
88
109
|
const rowChildren = getExpandChildren?.(row.original) ?? null;
|
|
89
110
|
const isSelected = !!row.getIsSelected();
|
|
111
|
+
const onClick = (event: MouseEvent<HTMLTableRowElement>) => {
|
|
112
|
+
if (rowChildren) {
|
|
113
|
+
toggleCollapsible(event.currentTarget);
|
|
114
|
+
}
|
|
115
|
+
if (!disableRowSelection && !multiRowSelectionEnabled) {
|
|
116
|
+
row.toggleSelected();
|
|
117
|
+
}
|
|
118
|
+
};
|
|
90
119
|
|
|
91
120
|
return (
|
|
92
121
|
<Fragment key={row.id}>
|
|
93
122
|
<tr
|
|
94
|
-
onClick={
|
|
123
|
+
onClick={onClick}
|
|
95
124
|
onDoubleClick={() => doubleClickAction?.(row.original)}
|
|
96
125
|
className={cx(classes.row, {
|
|
97
126
|
[classes.rowSelected]: isSelected,
|
|
@@ -102,13 +131,20 @@ const RowLayoutBody = <T,>({table, doubleClickAction, getExpandChildren, loading
|
|
|
102
131
|
{row.getVisibleCells().map((cell) => {
|
|
103
132
|
const size = cell.column.getSize();
|
|
104
133
|
const width = size !== defaultColumnSizing.size ? size : undefined;
|
|
134
|
+
const onCollapsibleCellClick = (event: MouseEvent<HTMLTableCellElement>) => {
|
|
135
|
+
if (cell.column.id === TableSelectableColumn.id && !disableRowSelection) {
|
|
136
|
+
event.stopPropagation();
|
|
137
|
+
row.getToggleSelectedHandler();
|
|
138
|
+
}
|
|
139
|
+
};
|
|
105
140
|
return (
|
|
106
141
|
<td
|
|
107
142
|
key={cell.id}
|
|
108
143
|
style={{width}}
|
|
109
|
-
className={cx({
|
|
144
|
+
className={cx(classes.cell, {
|
|
110
145
|
[classes.rowCollapsibleButtonCell]: cell.column.id === TableCollapsibleColumn.id,
|
|
111
146
|
})}
|
|
147
|
+
onClick={onCollapsibleCellClick}
|
|
112
148
|
>
|
|
113
149
|
<TableLoading visible={loading}>
|
|
114
150
|
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
|
@@ -123,12 +159,10 @@ const RowLayoutBody = <T,>({table, doubleClickAction, getExpandChildren, loading
|
|
|
123
159
|
colSpan={table.getAllColumns().length}
|
|
124
160
|
style={{
|
|
125
161
|
padding: 0,
|
|
126
|
-
borderTop: row.getIsExpanded() ? undefined : 'none',
|
|
127
|
-
borderBottom: row.getIsExpanded() ? undefined : 'none',
|
|
128
162
|
}}
|
|
129
163
|
>
|
|
130
164
|
<Collapse in={row.getIsExpanded()}>
|
|
131
|
-
<Box px="sm" py="xs">
|
|
165
|
+
<Box className={classes.collapsible} px="sm" py="xs">
|
|
132
166
|
{rowChildren}
|
|
133
167
|
</Box>
|
|
134
168
|
</Collapse>
|
|
@@ -2,6 +2,7 @@ import {useClickOutside} from '@mantine/hooks';
|
|
|
2
2
|
import {functionalUpdate, RowSelectionState, Table} from '@tanstack/table-core';
|
|
3
3
|
import isEqual from 'fast-deep-equal';
|
|
4
4
|
|
|
5
|
+
import {useRef} from 'react';
|
|
5
6
|
import {RowSelectionWithData, TableProps, TableState} from './Table.types';
|
|
6
7
|
|
|
7
8
|
export const useRowSelection = <T>(
|
|
@@ -9,13 +10,19 @@ export const useRowSelection = <T>(
|
|
|
9
10
|
{
|
|
10
11
|
onRowSelectionChange,
|
|
11
12
|
multiRowSelectionEnabled,
|
|
12
|
-
|
|
13
|
+
additionalRootNodes = [],
|
|
14
|
+
}: Pick<TableProps<T>, 'onRowSelectionChange' | 'multiRowSelectionEnabled' | 'additionalRootNodes'>
|
|
13
15
|
) => {
|
|
14
|
-
const outsideClickRef =
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
const outsideClickRef = useRef<HTMLDivElement>();
|
|
17
|
+
useClickOutside(
|
|
18
|
+
() => {
|
|
19
|
+
if (!multiRowSelectionEnabled) {
|
|
20
|
+
clearSelection();
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
null,
|
|
24
|
+
[outsideClickRef.current, ...additionalRootNodes]
|
|
25
|
+
);
|
|
19
26
|
|
|
20
27
|
table.setOptions((prev) => ({
|
|
21
28
|
...prev,
|