@coveord/plasma-mantine 56.8.0 → 56.9.0
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 +4 -4
- package/.turbo/turbo-test.log +108 -103
- package/dist/.tsbuildinfo +1 -1
- package/dist/cjs/components/CodeEditor/languages/xml.d.ts.map +1 -1
- package/dist/cjs/components/CodeEditor/languages/xml.js.map +1 -1
- package/dist/cjs/components/Collection/enhanceWithCollectionProps.d.ts.map +1 -1
- package/dist/cjs/components/Collection/enhanceWithCollectionProps.js.map +1 -1
- package/dist/cjs/components/DateRangePicker/DateRange.module.css +4 -0
- package/dist/cjs/components/DateRangePicker/DateRangePicker.d.ts.map +1 -1
- package/dist/cjs/components/DateRangePicker/DateRangePicker.js +2 -1
- package/dist/cjs/components/DateRangePicker/DateRangePicker.js.map +1 -1
- package/dist/cjs/components/RadioCard/RadioCard.d.ts +26 -0
- package/dist/cjs/components/RadioCard/RadioCard.d.ts.map +1 -0
- package/dist/cjs/components/RadioCard/RadioCard.js +82 -0
- package/dist/cjs/components/RadioCard/RadioCard.js.map +1 -0
- package/dist/cjs/components/Table/Table.d.ts +2 -12
- package/dist/cjs/components/Table/Table.d.ts.map +1 -1
- package/dist/cjs/components/Table/Table.js +0 -3
- package/dist/cjs/components/Table/Table.js.map +1 -1
- package/dist/cjs/components/Table/table-column/TableActionsColumn.d.ts +15 -0
- package/dist/cjs/components/Table/table-column/TableActionsColumn.d.ts.map +1 -1
- package/dist/cjs/components/Table/table-column/TableActionsColumn.js +14 -1
- package/dist/cjs/components/Table/table-column/TableActionsColumn.js.map +1 -1
- package/dist/cjs/components/Table/table-columns-selector/TableColumnsSelector.d.ts +11 -32
- package/dist/cjs/components/Table/table-columns-selector/TableColumnsSelector.d.ts.map +1 -1
- package/dist/cjs/components/Table/table-columns-selector/TableColumnsSelector.js +101 -97
- package/dist/cjs/components/Table/table-columns-selector/TableColumnsSelector.js.map +1 -1
- package/dist/cjs/index.d.ts +2 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +8 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/styles/RadioCard.module.css +44 -0
- package/dist/esm/components/CodeEditor/languages/xml.d.ts.map +1 -1
- package/dist/esm/components/CodeEditor/languages/xml.js.map +1 -1
- package/dist/esm/components/Collection/enhanceWithCollectionProps.d.ts.map +1 -1
- package/dist/esm/components/Collection/enhanceWithCollectionProps.js.map +1 -1
- package/dist/esm/components/DateRangePicker/DateRange.module.css +4 -0
- package/dist/esm/components/DateRangePicker/DateRangePicker.d.ts.map +1 -1
- package/dist/esm/components/DateRangePicker/DateRangePicker.js +2 -1
- package/dist/esm/components/DateRangePicker/DateRangePicker.js.map +1 -1
- package/dist/esm/components/RadioCard/RadioCard.d.ts +26 -0
- package/dist/esm/components/RadioCard/RadioCard.d.ts.map +1 -0
- package/dist/esm/components/RadioCard/RadioCard.js +63 -0
- package/dist/esm/components/RadioCard/RadioCard.js.map +1 -0
- package/dist/esm/components/Table/Table.d.ts +2 -12
- package/dist/esm/components/Table/Table.d.ts.map +1 -1
- package/dist/esm/components/Table/Table.js +0 -3
- package/dist/esm/components/Table/Table.js.map +1 -1
- package/dist/esm/components/Table/table-column/TableActionsColumn.d.ts +15 -0
- package/dist/esm/components/Table/table-column/TableActionsColumn.d.ts.map +1 -1
- package/dist/esm/components/Table/table-column/TableActionsColumn.js +12 -1
- package/dist/esm/components/Table/table-column/TableActionsColumn.js.map +1 -1
- package/dist/esm/components/Table/table-columns-selector/TableColumnsSelector.d.ts +11 -32
- package/dist/esm/components/Table/table-columns-selector/TableColumnsSelector.d.ts.map +1 -1
- package/dist/esm/components/Table/table-columns-selector/TableColumnsSelector.js +94 -84
- package/dist/esm/components/Table/table-columns-selector/TableColumnsSelector.js.map +1 -1
- package/dist/esm/index.d.ts +2 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +3 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/styles/RadioCard.module.css +44 -0
- package/package.json +19 -19
- package/src/components/CodeEditor/languages/xml.ts +2 -1
- package/src/components/Collection/enhanceWithCollectionProps.ts +2 -2
- package/src/components/DateRangePicker/DateRange.module.css +4 -0
- package/src/components/DateRangePicker/DateRangePicker.tsx +2 -1
- package/src/components/RadioCard/RadioCard.tsx +73 -0
- package/src/components/RadioCard/__tests__/RadioCard.component.spec.tsx +25 -0
- package/src/components/Table/Table.tsx +4 -9
- package/src/components/Table/__tests__/TableColumnsSelectorHeader.spec.tsx +325 -0
- package/src/components/Table/table-column/TableActionsColumn.tsx +28 -1
- package/src/components/Table/table-columns-selector/TableColumnsSelector.tsx +96 -125
- package/src/index.ts +4 -0
- package/src/styles/RadioCard.module.css +44 -0
- package/src/components/Table/__tests__/TableColumnsSelector.spec.tsx +0 -352
|
@@ -2,10 +2,10 @@ import {Box, Center, Factory, Loader, useProps, useStyles} from '@mantine/core';
|
|
|
2
2
|
import {useClickOutside, useMergedRef} from '@mantine/hooks';
|
|
3
3
|
import {
|
|
4
4
|
ColumnDef,
|
|
5
|
-
Row,
|
|
6
|
-
RowSelectionState,
|
|
7
5
|
defaultColumnSizing,
|
|
8
6
|
getCoreRowModel,
|
|
7
|
+
Row,
|
|
8
|
+
RowSelectionState,
|
|
9
9
|
useReactTable,
|
|
10
10
|
} from '@tanstack/react-table';
|
|
11
11
|
import isEqual from 'fast-deep-equal';
|
|
@@ -16,8 +16,8 @@ import {TableLayout, TableProps} from './Table.types.js';
|
|
|
16
16
|
import {TableProvider} from './TableContext.js';
|
|
17
17
|
import {TableLayouts} from './layouts/TableLayouts.js';
|
|
18
18
|
import {TableActionItem, TableActionItemStylesNames} from './table-actions/TableActionItem.js';
|
|
19
|
-
import {TableHeaderActionsStylesNames} from './table-actions/TableHeaderActions.js';
|
|
20
19
|
import {TableActionsListStylesNames} from './table-actions/TableActionsList.js';
|
|
20
|
+
import {TableHeaderActionsStylesNames} from './table-actions/TableHeaderActions.js';
|
|
21
21
|
import {TableActionsColumn} from './table-column/TableActionsColumn.js';
|
|
22
22
|
import {
|
|
23
23
|
TableAccordionColumn,
|
|
@@ -25,7 +25,6 @@ import {
|
|
|
25
25
|
TableCollapsibleColumnStylesNames,
|
|
26
26
|
} from './table-column/TableCollapsibleColumn.js';
|
|
27
27
|
import {TableSelectableColumn} from './table-column/TableSelectableColumn.js';
|
|
28
|
-
import {TableColumnsSelector, TableColumnsSelectorStylesNames} from './table-columns-selector/TableColumnsSelector.js';
|
|
29
28
|
import {TableDateRangePicker, TableDateRangePickerStylesNames} from './table-date-range-picker/TableDateRangePicker.js';
|
|
30
29
|
import {TableFilter, TableFilterStylesNames} from './table-filter/TableFilter.js';
|
|
31
30
|
import {TableFooter} from './table-footer/TableFooter.js';
|
|
@@ -53,8 +52,7 @@ type TableStylesNames =
|
|
|
53
52
|
| TableHeaderStylesNames
|
|
54
53
|
| TableThStylesNames
|
|
55
54
|
| TableLastUpdatedStylesNames
|
|
56
|
-
| TablePredicateStylesNames
|
|
57
|
-
| TableColumnsSelectorStylesNames;
|
|
55
|
+
| TablePredicateStylesNames;
|
|
58
56
|
|
|
59
57
|
export type PlasmaTableFactory = Factory<{
|
|
60
58
|
props: TableProps<unknown>;
|
|
@@ -65,7 +63,6 @@ export type PlasmaTableFactory = Factory<{
|
|
|
65
63
|
ActionsColumn: typeof TableActionsColumn;
|
|
66
64
|
ActionItem: typeof TableActionItem;
|
|
67
65
|
CollapsibleColumn: typeof TableCollapsibleColumn;
|
|
68
|
-
ColumnsSelector: typeof TableColumnsSelector;
|
|
69
66
|
DateRangePicker: typeof TableDateRangePicker;
|
|
70
67
|
Filter: typeof TableFilter;
|
|
71
68
|
Footer: typeof TableFooter;
|
|
@@ -297,7 +294,6 @@ export const TableComponentsOrder = {
|
|
|
297
294
|
Predicate: 5,
|
|
298
295
|
Filter: 4,
|
|
299
296
|
DateRangePicker: 3,
|
|
300
|
-
ColumnsSelector: 2,
|
|
301
297
|
LayoutControl: 1,
|
|
302
298
|
};
|
|
303
299
|
|
|
@@ -305,7 +301,6 @@ Table.AccordionColumn = TableAccordionColumn;
|
|
|
305
301
|
Table.ActionsColumn = TableActionsColumn;
|
|
306
302
|
Table.ActionItem = TableActionItem;
|
|
307
303
|
Table.CollapsibleColumn = TableCollapsibleColumn;
|
|
308
|
-
Table.ColumnsSelector = TableColumnsSelector;
|
|
309
304
|
Table.DateRangePicker = TableDateRangePicker;
|
|
310
305
|
Table.Filter = TableFilter;
|
|
311
306
|
Table.Footer = TableFooter;
|
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
import {ColumnDef, createColumnHelper} from '@tanstack/table-core';
|
|
2
|
+
import {render, screen, userEvent, waitFor} from '@test-utils';
|
|
3
|
+
|
|
4
|
+
import {Table} from '../Table.js';
|
|
5
|
+
import {TableActionsColumn} from '../table-column/TableActionsColumn.js';
|
|
6
|
+
import {useTable} from '../use-table.js';
|
|
7
|
+
|
|
8
|
+
type RowData = {name: string; age: number; email: string; phone: string};
|
|
9
|
+
const columnHelper = createColumnHelper<RowData>();
|
|
10
|
+
|
|
11
|
+
const mockData: RowData[] = [
|
|
12
|
+
{name: 'John', age: 30, email: 'john@test.com', phone: '123-456'},
|
|
13
|
+
{name: 'Jane', age: 25, email: 'jane@test.com', phone: '789-012'},
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
const getBaseColumns = (): Array<ColumnDef<RowData>> => [
|
|
17
|
+
columnHelper.accessor('name', {header: 'Name', enableSorting: false}),
|
|
18
|
+
columnHelper.accessor('age', {header: 'Age', enableSorting: false}),
|
|
19
|
+
columnHelper.accessor('email', {header: 'Email', enableSorting: false}),
|
|
20
|
+
columnHelper.accessor('phone', {header: 'Phone', enableSorting: false}),
|
|
21
|
+
TableActionsColumn as ColumnDef<RowData>,
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
describe('TableColumnsSelectorHeader', () => {
|
|
25
|
+
it('renders the column selector button in the actions column header when rowConfigurable is true', () => {
|
|
26
|
+
const Fixture = () => {
|
|
27
|
+
const store = useTable<RowData>();
|
|
28
|
+
return (
|
|
29
|
+
<Table
|
|
30
|
+
store={store}
|
|
31
|
+
data={mockData}
|
|
32
|
+
columns={getBaseColumns()}
|
|
33
|
+
options={{meta: {rowConfigurable: true}}}
|
|
34
|
+
/>
|
|
35
|
+
);
|
|
36
|
+
};
|
|
37
|
+
render(<Fixture />);
|
|
38
|
+
|
|
39
|
+
expect(screen.getByRole('button', {name: 'settings'})).toBeVisible();
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('renders all columns in the dropdown except control columns', async () => {
|
|
43
|
+
const user = userEvent.setup();
|
|
44
|
+
const Fixture = () => {
|
|
45
|
+
const store = useTable<RowData>();
|
|
46
|
+
return (
|
|
47
|
+
<Table
|
|
48
|
+
store={store}
|
|
49
|
+
data={mockData}
|
|
50
|
+
columns={getBaseColumns()}
|
|
51
|
+
options={{meta: {rowConfigurable: true}}}
|
|
52
|
+
/>
|
|
53
|
+
);
|
|
54
|
+
};
|
|
55
|
+
render(<Fixture />);
|
|
56
|
+
|
|
57
|
+
await user.click(screen.getByRole('button', {name: 'settings'}));
|
|
58
|
+
|
|
59
|
+
const columnsCheckboxes = await screen.findAllByRole('checkbox');
|
|
60
|
+
expect(columnsCheckboxes).toHaveLength(4);
|
|
61
|
+
expect(columnsCheckboxes[0]).toHaveAccessibleName('Name');
|
|
62
|
+
expect(columnsCheckboxes[1]).toHaveAccessibleName('Age');
|
|
63
|
+
expect(columnsCheckboxes[2]).toHaveAccessibleName('Email');
|
|
64
|
+
expect(columnsCheckboxes[3]).toHaveAccessibleName('Phone');
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('renders all checkboxes checked by default', async () => {
|
|
68
|
+
const user = userEvent.setup();
|
|
69
|
+
const Fixture = () => {
|
|
70
|
+
const store = useTable<RowData>();
|
|
71
|
+
return (
|
|
72
|
+
<Table
|
|
73
|
+
store={store}
|
|
74
|
+
data={mockData}
|
|
75
|
+
columns={getBaseColumns()}
|
|
76
|
+
options={{meta: {rowConfigurable: true}}}
|
|
77
|
+
/>
|
|
78
|
+
);
|
|
79
|
+
};
|
|
80
|
+
render(<Fixture />);
|
|
81
|
+
|
|
82
|
+
await user.click(screen.getByRole('button', {name: 'settings'}));
|
|
83
|
+
|
|
84
|
+
expect(await screen.findByRole('checkbox', {name: 'Name'})).toBeChecked();
|
|
85
|
+
expect(screen.getByRole('checkbox', {name: 'Age'})).toBeChecked();
|
|
86
|
+
expect(screen.getByRole('checkbox', {name: 'Email'})).toBeChecked();
|
|
87
|
+
expect(screen.getByRole('checkbox', {name: 'Phone'})).toBeChecked();
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('hides a column when the user unchecks it', async () => {
|
|
91
|
+
const user = userEvent.setup();
|
|
92
|
+
const Fixture = () => {
|
|
93
|
+
const store = useTable<RowData>();
|
|
94
|
+
return (
|
|
95
|
+
<Table
|
|
96
|
+
store={store}
|
|
97
|
+
data={mockData}
|
|
98
|
+
columns={getBaseColumns()}
|
|
99
|
+
options={{meta: {rowConfigurable: true}}}
|
|
100
|
+
/>
|
|
101
|
+
);
|
|
102
|
+
};
|
|
103
|
+
render(<Fixture />);
|
|
104
|
+
|
|
105
|
+
expect(screen.getByRole('columnheader', {name: 'Email'})).toBeVisible();
|
|
106
|
+
|
|
107
|
+
await user.click(screen.getByRole('button', {name: 'settings'}));
|
|
108
|
+
await user.click(await screen.findByRole('checkbox', {name: 'Email'}));
|
|
109
|
+
|
|
110
|
+
expect(screen.queryByRole('columnheader', {name: 'Email'})).not.toBeInTheDocument();
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it('shows a column when the user checks it', async () => {
|
|
114
|
+
const user = userEvent.setup();
|
|
115
|
+
const Fixture = () => {
|
|
116
|
+
const store = useTable<RowData>({
|
|
117
|
+
initialState: {columnVisibility: {email: false}},
|
|
118
|
+
});
|
|
119
|
+
return (
|
|
120
|
+
<Table
|
|
121
|
+
store={store}
|
|
122
|
+
data={mockData}
|
|
123
|
+
columns={getBaseColumns()}
|
|
124
|
+
options={{meta: {rowConfigurable: true}}}
|
|
125
|
+
/>
|
|
126
|
+
);
|
|
127
|
+
};
|
|
128
|
+
render(<Fixture />);
|
|
129
|
+
|
|
130
|
+
expect(screen.queryByRole('columnheader', {name: 'Email'})).not.toBeInTheDocument();
|
|
131
|
+
|
|
132
|
+
await user.click(screen.getByRole('button', {name: 'settings'}));
|
|
133
|
+
await user.click(await screen.findByRole('checkbox', {name: 'Email'}));
|
|
134
|
+
|
|
135
|
+
expect(screen.getByRole('columnheader', {name: 'Email'})).toBeVisible();
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it('renders a disabled checked checkbox for columns that are always visible', async () => {
|
|
139
|
+
const user = userEvent.setup();
|
|
140
|
+
const columnsWithNonHideable: Array<ColumnDef<RowData>> = [
|
|
141
|
+
columnHelper.accessor('name', {header: 'Name', enableSorting: false}),
|
|
142
|
+
columnHelper.accessor('age', {header: 'Age', enableSorting: false, enableHiding: false}),
|
|
143
|
+
columnHelper.accessor('email', {header: 'Email', enableSorting: false}),
|
|
144
|
+
TableActionsColumn as ColumnDef<RowData>,
|
|
145
|
+
];
|
|
146
|
+
|
|
147
|
+
const Fixture = () => {
|
|
148
|
+
const store = useTable<RowData>();
|
|
149
|
+
return (
|
|
150
|
+
<Table
|
|
151
|
+
store={store}
|
|
152
|
+
data={mockData}
|
|
153
|
+
columns={columnsWithNonHideable}
|
|
154
|
+
options={{meta: {rowConfigurable: true}}}
|
|
155
|
+
/>
|
|
156
|
+
);
|
|
157
|
+
};
|
|
158
|
+
render(<Fixture />);
|
|
159
|
+
|
|
160
|
+
await user.click(screen.getByRole('button', {name: 'settings'}));
|
|
161
|
+
|
|
162
|
+
const ageColumn = await screen.findByRole('checkbox', {name: 'Age'});
|
|
163
|
+
expect(ageColumn).toBeChecked();
|
|
164
|
+
expect(ageColumn).toBeDisabled();
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it('renders a tooltip when hovering a disabled always visible column checkbox', async () => {
|
|
168
|
+
const user = userEvent.setup();
|
|
169
|
+
const columnsWithNonHideable: Array<ColumnDef<RowData>> = [
|
|
170
|
+
columnHelper.accessor('name', {header: 'Name', enableSorting: false}),
|
|
171
|
+
columnHelper.accessor('age', {header: 'Age', enableSorting: false, enableHiding: false}),
|
|
172
|
+
TableActionsColumn as ColumnDef<RowData>,
|
|
173
|
+
];
|
|
174
|
+
|
|
175
|
+
const Fixture = () => {
|
|
176
|
+
const store = useTable<RowData>();
|
|
177
|
+
return (
|
|
178
|
+
<Table
|
|
179
|
+
store={store}
|
|
180
|
+
data={mockData}
|
|
181
|
+
columns={columnsWithNonHideable}
|
|
182
|
+
options={{meta: {rowConfigurable: true}}}
|
|
183
|
+
/>
|
|
184
|
+
);
|
|
185
|
+
};
|
|
186
|
+
render(<Fixture />);
|
|
187
|
+
|
|
188
|
+
await user.click(screen.getByRole('button', {name: 'settings'}));
|
|
189
|
+
const ageCheckbox = await screen.findByRole('checkbox', {name: 'Age'});
|
|
190
|
+
await user.hover(ageCheckbox.closest('div')!);
|
|
191
|
+
|
|
192
|
+
await waitFor(() => {
|
|
193
|
+
expect(screen.getByRole('tooltip', {name: 'This column is always visible.'})).toBeVisible();
|
|
194
|
+
});
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
it('renders unchecked checkboxes for columns that are not visible in the initial state', async () => {
|
|
198
|
+
const user = userEvent.setup();
|
|
199
|
+
const Fixture = () => {
|
|
200
|
+
const store = useTable<RowData>({
|
|
201
|
+
initialState: {columnVisibility: {email: false}},
|
|
202
|
+
});
|
|
203
|
+
return (
|
|
204
|
+
<Table
|
|
205
|
+
store={store}
|
|
206
|
+
data={mockData}
|
|
207
|
+
columns={getBaseColumns()}
|
|
208
|
+
options={{meta: {rowConfigurable: true}}}
|
|
209
|
+
/>
|
|
210
|
+
);
|
|
211
|
+
};
|
|
212
|
+
render(<Fixture />);
|
|
213
|
+
|
|
214
|
+
await user.click(screen.getByRole('button', {name: 'settings'}));
|
|
215
|
+
|
|
216
|
+
expect(await screen.findByRole('checkbox', {name: 'Name'})).toBeChecked();
|
|
217
|
+
expect(screen.getByRole('checkbox', {name: 'Age'})).toBeChecked();
|
|
218
|
+
expect(screen.getByRole('checkbox', {name: 'Email'})).not.toBeChecked();
|
|
219
|
+
expect(screen.getByRole('checkbox', {name: 'Phone'})).toBeChecked();
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
describe('maxSelectableColumns', () => {
|
|
223
|
+
it('disables unchecked columns when the maximum number of visible columns is reached', async () => {
|
|
224
|
+
const user = userEvent.setup();
|
|
225
|
+
const Fixture = () => {
|
|
226
|
+
const store = useTable<RowData>({
|
|
227
|
+
initialState: {columnVisibility: {email: false, phone: false}},
|
|
228
|
+
});
|
|
229
|
+
return (
|
|
230
|
+
<Table
|
|
231
|
+
store={store}
|
|
232
|
+
data={mockData}
|
|
233
|
+
columns={getBaseColumns()}
|
|
234
|
+
options={{meta: {rowConfigurable: {maxSelectableColumns: 2}}}}
|
|
235
|
+
/>
|
|
236
|
+
);
|
|
237
|
+
};
|
|
238
|
+
render(<Fixture />);
|
|
239
|
+
|
|
240
|
+
await user.click(screen.getByRole('button', {name: 'settings'}));
|
|
241
|
+
|
|
242
|
+
// Name and Age are visible (2 columns = max)
|
|
243
|
+
expect(await screen.findByRole('checkbox', {name: 'Name'})).toBeChecked();
|
|
244
|
+
expect(screen.getByRole('checkbox', {name: 'Name'})).not.toBeDisabled();
|
|
245
|
+
expect(screen.getByRole('checkbox', {name: 'Age'})).toBeChecked();
|
|
246
|
+
expect(screen.getByRole('checkbox', {name: 'Age'})).not.toBeDisabled();
|
|
247
|
+
|
|
248
|
+
// Email and Phone are hidden and should be disabled
|
|
249
|
+
expect(screen.getByRole('checkbox', {name: 'Email'})).not.toBeChecked();
|
|
250
|
+
expect(screen.getByRole('checkbox', {name: 'Email'})).toBeDisabled();
|
|
251
|
+
expect(screen.getByRole('checkbox', {name: 'Phone'})).not.toBeChecked();
|
|
252
|
+
expect(screen.getByRole('checkbox', {name: 'Phone'})).toBeDisabled();
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
it('renders a footer with the max columns message when maxSelectableColumns is set', async () => {
|
|
256
|
+
const user = userEvent.setup();
|
|
257
|
+
const Fixture = () => {
|
|
258
|
+
const store = useTable<RowData>();
|
|
259
|
+
return (
|
|
260
|
+
<Table
|
|
261
|
+
store={store}
|
|
262
|
+
data={mockData}
|
|
263
|
+
columns={getBaseColumns()}
|
|
264
|
+
options={{meta: {rowConfigurable: {maxSelectableColumns: 5}}}}
|
|
265
|
+
/>
|
|
266
|
+
);
|
|
267
|
+
};
|
|
268
|
+
render(<Fixture />);
|
|
269
|
+
|
|
270
|
+
await user.click(screen.getByRole('button', {name: 'settings'}));
|
|
271
|
+
|
|
272
|
+
expect(await screen.findByText('You can display up to 5 columns.')).toBeVisible();
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
it('does not render a footer when maxSelectableColumns is not set', async () => {
|
|
276
|
+
const user = userEvent.setup();
|
|
277
|
+
const Fixture = () => {
|
|
278
|
+
const store = useTable<RowData>();
|
|
279
|
+
return (
|
|
280
|
+
<Table
|
|
281
|
+
store={store}
|
|
282
|
+
data={mockData}
|
|
283
|
+
columns={getBaseColumns()}
|
|
284
|
+
options={{meta: {rowConfigurable: true}}}
|
|
285
|
+
/>
|
|
286
|
+
);
|
|
287
|
+
};
|
|
288
|
+
render(<Fixture />);
|
|
289
|
+
|
|
290
|
+
await user.click(screen.getByRole('button', {name: 'settings'}));
|
|
291
|
+
|
|
292
|
+
await screen.findByRole('checkbox', {name: 'Name'});
|
|
293
|
+
expect(screen.queryByText(/You can display up to/)).not.toBeInTheDocument();
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
it('enables a disabled column when a visible column is hidden', async () => {
|
|
297
|
+
const user = userEvent.setup();
|
|
298
|
+
const Fixture = () => {
|
|
299
|
+
const store = useTable<RowData>({
|
|
300
|
+
initialState: {columnVisibility: {email: false, phone: false}},
|
|
301
|
+
});
|
|
302
|
+
return (
|
|
303
|
+
<Table
|
|
304
|
+
store={store}
|
|
305
|
+
data={mockData}
|
|
306
|
+
columns={getBaseColumns()}
|
|
307
|
+
options={{meta: {rowConfigurable: {maxSelectableColumns: 2}}}}
|
|
308
|
+
/>
|
|
309
|
+
);
|
|
310
|
+
};
|
|
311
|
+
render(<Fixture />);
|
|
312
|
+
|
|
313
|
+
await user.click(screen.getByRole('button', {name: 'settings'}));
|
|
314
|
+
|
|
315
|
+
// Email is disabled because max is reached
|
|
316
|
+
expect(await screen.findByRole('checkbox', {name: 'Email'})).toBeDisabled();
|
|
317
|
+
|
|
318
|
+
// Hide Name column
|
|
319
|
+
await user.click(screen.getByRole('checkbox', {name: 'Name'}));
|
|
320
|
+
|
|
321
|
+
// Now Email should be enabled
|
|
322
|
+
expect(screen.getByRole('checkbox', {name: 'Email'})).not.toBeDisabled();
|
|
323
|
+
});
|
|
324
|
+
});
|
|
325
|
+
});
|
|
@@ -3,7 +3,27 @@ import {useProps} from '@mantine/core';
|
|
|
3
3
|
import {CellContext, ColumnDef} from '@tanstack/table-core';
|
|
4
4
|
import {FunctionComponent} from 'react';
|
|
5
5
|
import {TableActionsList, TableActionsListProps} from '../table-actions/TableActionsList.js';
|
|
6
|
+
|
|
6
7
|
import {useTableContext} from '../TableContext.js';
|
|
8
|
+
import {
|
|
9
|
+
TableColumnsSelectorHeader,
|
|
10
|
+
TableColumnsSelectorOptions,
|
|
11
|
+
} from '../table-columns-selector/TableColumnsSelector.js';
|
|
12
|
+
|
|
13
|
+
export interface TableActionsColumnMeta {
|
|
14
|
+
/**
|
|
15
|
+
* When set to `true` or an options object, displays a column selector button in the actions column header.
|
|
16
|
+
* Allows users to show/hide columns in the table.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* // Simple usage
|
|
20
|
+
* options={{ meta: { rowConfigurable: true } }}
|
|
21
|
+
*
|
|
22
|
+
* // With options
|
|
23
|
+
* options={{ meta: { rowConfigurable: { maxSelectableColumns: 5 } } }}
|
|
24
|
+
*/
|
|
25
|
+
rowConfigurable?: boolean | TableColumnsSelectorOptions;
|
|
26
|
+
}
|
|
7
27
|
|
|
8
28
|
/**
|
|
9
29
|
* Generic column to use when your table needs actions on rows
|
|
@@ -15,7 +35,14 @@ export const TableActionsColumn: ColumnDef<unknown> = {
|
|
|
15
35
|
meta: {
|
|
16
36
|
controlColumn: true,
|
|
17
37
|
},
|
|
18
|
-
header:
|
|
38
|
+
header: ({table}) => {
|
|
39
|
+
const rowConfigurable = (table.options.meta as TableActionsColumnMeta)?.rowConfigurable;
|
|
40
|
+
if (!rowConfigurable) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
const options = typeof rowConfigurable === 'boolean' ? {} : rowConfigurable;
|
|
44
|
+
return <TableColumnsSelectorHeader table={table} options={options} />;
|
|
45
|
+
},
|
|
19
46
|
size: 84, // 16px padding left + 28px ActionIcon + 40px padding right
|
|
20
47
|
cell: (info) => <ActionsMenu info={info} />,
|
|
21
48
|
};
|