@coveord/plasma-mantine 49.3.3 → 49.3.4
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 +29 -29
- package/dist/.tsbuildinfo +1 -1
- package/dist/cjs/__tests__/VitestSetup.js.map +1 -1
- package/dist/cjs/components/table/Table.js +40 -31
- package/dist/cjs/components/table/Table.js.map +1 -1
- package/dist/cjs/components/table/TableContext.js.map +1 -1
- package/dist/definitions/__tests__/VitestSetup.d.ts +7 -1
- package/dist/definitions/__tests__/VitestSetup.d.ts.map +1 -1
- package/dist/definitions/components/table/Table.d.ts.map +1 -1
- package/dist/definitions/components/table/TableContext.d.ts +5 -0
- package/dist/definitions/components/table/TableContext.d.ts.map +1 -1
- package/dist/definitions/components/table/useTable.d.ts +1 -0
- package/dist/definitions/components/table/useTable.d.ts.map +1 -1
- package/dist/esm/__tests__/VitestSetup.js.map +1 -1
- package/dist/esm/components/table/Table.js +41 -32
- package/dist/esm/components/table/Table.js.map +1 -1
- package/dist/esm/components/table/TableContext.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/VitestSetup.ts +6 -1
- package/src/components/table/Table.tsx +34 -22
- package/src/components/table/TableContext.tsx +5 -0
- package/src/components/table/__tests__/Table.spec.tsx +62 -0
package/package.json
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
import matchers from '@testing-library/jest-dom/matchers';
|
|
1
|
+
import matchers, {TestingLibraryMatchers} from '@testing-library/jest-dom/matchers';
|
|
2
2
|
import {cleanup} from '@testing-library/react';
|
|
3
|
+
declare global {
|
|
4
|
+
namespace Vi {
|
|
5
|
+
interface JestAssertion<T = any> extends jest.Matchers<void, T>, TestingLibraryMatchers<T, void> {}
|
|
6
|
+
}
|
|
7
|
+
}
|
|
3
8
|
expect.extend(matchers);
|
|
4
9
|
Object.defineProperty(window, 'matchMedia', {
|
|
5
10
|
writable: true,
|
|
@@ -226,6 +226,11 @@ export const Table: TableType = <T,>({
|
|
|
226
226
|
onStateChange: setState,
|
|
227
227
|
}));
|
|
228
228
|
const {clearSelection, getSelectedRow, getSelectedRows} = useRowSelection(table);
|
|
229
|
+
const isFiltered =
|
|
230
|
+
!!state.globalFilter ||
|
|
231
|
+
Object.keys(form.values?.predicates ?? {}).some((predicate) => !!form.values.predicates[predicate]) ||
|
|
232
|
+
!!form.values.dateRange?.[0] ||
|
|
233
|
+
!!form.values.dateRange?.[1];
|
|
229
234
|
|
|
230
235
|
const triggerChange = debounce(() => onChange?.({...state, ...form.values}), 500);
|
|
231
236
|
|
|
@@ -244,7 +249,7 @@ export const Table: TableType = <T,>({
|
|
|
244
249
|
}, [state.globalFilter, state.pagination, state.sorting, form.values]);
|
|
245
250
|
|
|
246
251
|
const clearFilters = useCallback(() => {
|
|
247
|
-
form.setFieldValue('predicates', {});
|
|
252
|
+
form.setFieldValue('predicates', initialState.predicates ?? {});
|
|
248
253
|
setState((prevState) => ({...prevState, globalFilter: ''}));
|
|
249
254
|
}, []);
|
|
250
255
|
|
|
@@ -319,6 +324,7 @@ export const Table: TableType = <T,>({
|
|
|
319
324
|
value={{
|
|
320
325
|
onChange: triggerChange,
|
|
321
326
|
state,
|
|
327
|
+
isFiltered,
|
|
322
328
|
setState,
|
|
323
329
|
clearFilters,
|
|
324
330
|
getSelectedRow,
|
|
@@ -330,28 +336,34 @@ export const Table: TableType = <T,>({
|
|
|
330
336
|
getPageCount: table.getPageCount,
|
|
331
337
|
}}
|
|
332
338
|
>
|
|
333
|
-
{
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
339
|
+
{!rows.length && !isFiltered && !loading ? (
|
|
340
|
+
noDataChildren
|
|
341
|
+
) : (
|
|
342
|
+
<>
|
|
343
|
+
{header}
|
|
344
|
+
<MantineTable className={classes.table} horizontalSpacing="sm" verticalSpacing="xs" pb="sm">
|
|
345
|
+
<thead className={classes.header}>
|
|
346
|
+
{table.getHeaderGroups().map((headerGroup) => (
|
|
347
|
+
<tr key={headerGroup.id}>
|
|
348
|
+
{headerGroup.headers.map((columnHeader) => (
|
|
349
|
+
<Th key={columnHeader.id} header={columnHeader} />
|
|
350
|
+
))}
|
|
351
|
+
</tr>
|
|
340
352
|
))}
|
|
341
|
-
</
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
</
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
353
|
+
</thead>
|
|
354
|
+
<tbody>
|
|
355
|
+
{rows.length ? (
|
|
356
|
+
rows
|
|
357
|
+
) : (
|
|
358
|
+
<tr>
|
|
359
|
+
<td colSpan={columns.length}>{noDataChildren}</td>
|
|
360
|
+
</tr>
|
|
361
|
+
)}
|
|
362
|
+
</tbody>
|
|
363
|
+
</MantineTable>
|
|
364
|
+
{footer}
|
|
365
|
+
</>
|
|
366
|
+
)}
|
|
355
367
|
</TableContext.Provider>
|
|
356
368
|
</Box>
|
|
357
369
|
);
|
|
@@ -35,6 +35,11 @@ type TableContextType = {
|
|
|
35
35
|
* Function to update the table state
|
|
36
36
|
*/
|
|
37
37
|
setState: Dispatch<(prevState: TableState) => TableState>;
|
|
38
|
+
/**
|
|
39
|
+
* Whether the table currently as any kind of filter applied.
|
|
40
|
+
* Useful to determine if the noDataChildren is an empty state or just the result of a filter
|
|
41
|
+
*/
|
|
42
|
+
isFiltered: boolean;
|
|
38
43
|
/**
|
|
39
44
|
* Function that clears the filter and predicates
|
|
40
45
|
*/
|
|
@@ -3,6 +3,7 @@ import {render, screen, userEvent, waitFor, within} from '@test-utils';
|
|
|
3
3
|
import {FunctionComponent} from 'react';
|
|
4
4
|
|
|
5
5
|
import {Table} from '../Table';
|
|
6
|
+
import {useTable} from '../useTable';
|
|
6
7
|
|
|
7
8
|
type RowData = {firstName: string; lastName?: string};
|
|
8
9
|
|
|
@@ -68,6 +69,67 @@ describe('Table', () => {
|
|
|
68
69
|
expect(screen.getByRole('button', {name: 'Hello'})).toBeVisible();
|
|
69
70
|
});
|
|
70
71
|
|
|
72
|
+
it('hides the footer and header when the table is empty and not filtered', () => {
|
|
73
|
+
const NoData = () => <span data-testid="empty-state" />;
|
|
74
|
+
const customColumns: Array<ColumnDef<RowData>> = [
|
|
75
|
+
columnHelper.accessor('firstName', {
|
|
76
|
+
header: () => 'First Name',
|
|
77
|
+
cell: (info) => info.getValue().toUpperCase(),
|
|
78
|
+
enableSorting: false,
|
|
79
|
+
}),
|
|
80
|
+
columnHelper.accessor('lastName', {
|
|
81
|
+
header: () => 'Last Name',
|
|
82
|
+
cell: (info) => info.getValue().toUpperCase(),
|
|
83
|
+
enableSorting: false,
|
|
84
|
+
}),
|
|
85
|
+
];
|
|
86
|
+
render(
|
|
87
|
+
<Table data={[]} columns={customColumns} noDataChildren={<NoData />}>
|
|
88
|
+
<Table.Header data-testid="table-header">header</Table.Header>
|
|
89
|
+
<Table.Footer data-testid="table-footer">footer</Table.Footer>
|
|
90
|
+
</Table>
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
expect(screen.queryByTestId('table-header')).not.toBeInTheDocument();
|
|
94
|
+
expect(screen.queryByTestId('table-footer')).not.toBeInTheDocument();
|
|
95
|
+
expect(screen.getByTestId('empty-state')).toBeInTheDocument();
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it('does not hide the footer and header when the table is empty and filtered', () => {
|
|
99
|
+
const NoData = () => {
|
|
100
|
+
const {isFiltered} = useTable();
|
|
101
|
+
return isFiltered ? <span data-testid="filtered-empty-state" /> : <span data-testid="empty-state" />;
|
|
102
|
+
};
|
|
103
|
+
const customColumns: Array<ColumnDef<RowData>> = [
|
|
104
|
+
columnHelper.accessor('firstName', {
|
|
105
|
+
header: () => 'First Name',
|
|
106
|
+
cell: (info) => info.getValue().toUpperCase(),
|
|
107
|
+
enableSorting: false,
|
|
108
|
+
}),
|
|
109
|
+
columnHelper.accessor('lastName', {
|
|
110
|
+
header: () => 'Last Name',
|
|
111
|
+
cell: (info) => info.getValue().toUpperCase(),
|
|
112
|
+
enableSorting: false,
|
|
113
|
+
}),
|
|
114
|
+
];
|
|
115
|
+
render(
|
|
116
|
+
<Table
|
|
117
|
+
data={[]}
|
|
118
|
+
columns={customColumns}
|
|
119
|
+
noDataChildren={<NoData />}
|
|
120
|
+
initialState={{globalFilter: 'something'}}
|
|
121
|
+
>
|
|
122
|
+
<Table.Header data-testid="table-header">header</Table.Header>
|
|
123
|
+
<Table.Footer data-testid="table-footer">footer</Table.Footer>
|
|
124
|
+
</Table>
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
expect(screen.getByTestId('table-header')).toBeInTheDocument();
|
|
128
|
+
expect(screen.getByTestId('table-footer')).toBeInTheDocument();
|
|
129
|
+
expect(screen.getByTestId('filtered-empty-state')).toBeInTheDocument();
|
|
130
|
+
expect(screen.queryByTestId('empty-state')).not.toBeInTheDocument();
|
|
131
|
+
});
|
|
132
|
+
|
|
71
133
|
it('opens the collapsible rows when the user click on the toggle', async () => {
|
|
72
134
|
const user = userEvent.setup({delay: null});
|
|
73
135
|
const Fixture: FunctionComponent<{row: RowData}> = ({row}) => <div>Collapsible content: {row.lastName}</div>;
|