@equinor/eds-data-grid-react 0.4.0 → 0.6.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/dist/eds-data-grid-react.cjs +150 -68
- package/dist/esm/EdsDataGrid.js +51 -18
- package/dist/esm/EdsDataGridContext.js +1 -1
- package/dist/esm/components/DebouncedInput.js +0 -1
- package/dist/esm/components/Filter.js +28 -73
- package/dist/esm/components/FilterWrapper.js +73 -0
- package/dist/esm/components/SortIndicator.js +18 -0
- package/dist/esm/components/TableBodyCell.js +2 -2
- package/dist/esm/components/TableHeaderCell.js +9 -15
- package/dist/esm/components/TableRow.js +8 -6
- package/dist/esm/index.js +3 -0
- package/dist/esm/utils.js +14 -1
- package/dist/types/EdsDataGrid.d.ts +1 -1
- package/dist/types/EdsDataGridProps.d.ts +68 -18
- package/dist/types/components/FilterWrapper.d.ts +11 -0
- package/dist/types/components/SortIndicator.d.ts +4 -0
- package/dist/types/components/TableBodyCell.d.ts +2 -1
- package/dist/types/components/TableRow.d.ts +3 -1
- package/dist/types/index.d.ts +3 -0
- package/dist/types/types.d.ts +1 -1
- package/dist/types/utils.d.ts +4 -0
- package/package.json +21 -24
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var edsCoreReact = require('@equinor/eds-core-react');
|
|
4
3
|
var reactTable = require('@tanstack/react-table');
|
|
4
|
+
var edsCoreReact = require('@equinor/eds-core-react');
|
|
5
5
|
var reactVirtual = require('@tanstack/react-virtual');
|
|
6
6
|
var react = require('react');
|
|
7
|
-
var edsIcons = require('@equinor/eds-icons');
|
|
8
|
-
var jsxRuntime = require('react/jsx-runtime');
|
|
9
7
|
var styled = require('styled-components');
|
|
8
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
10
9
|
var edsTokens = require('@equinor/eds-tokens');
|
|
10
|
+
var edsIcons = require('@equinor/eds-icons');
|
|
11
11
|
|
|
12
12
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
13
13
|
|
|
@@ -71,7 +71,6 @@ function DebouncedInput({
|
|
|
71
71
|
/* eslint-disable-next-line @typescript-eslint/ban-ts-comment */,
|
|
72
72
|
label: `Select ${label ?? ''}`,
|
|
73
73
|
placeholder: props.placeholder ?? 'Search',
|
|
74
|
-
disablePortal: false /*TODO: Check with Oddbjørn re. sizing/position*/,
|
|
75
74
|
selectedOptions: value,
|
|
76
75
|
onOptionsChange: c => setValue(c.selectedItems),
|
|
77
76
|
multiline: true
|
|
@@ -110,12 +109,6 @@ function Filter({
|
|
|
110
109
|
table
|
|
111
110
|
}) {
|
|
112
111
|
const firstValue = table.getPreFilteredRowModel().flatRows[0]?.getValue(column.id);
|
|
113
|
-
const [open, setOpen] = react.useState(false);
|
|
114
|
-
const filterIconRef = react.useRef();
|
|
115
|
-
const togglePopover = event => {
|
|
116
|
-
event.stopPropagation();
|
|
117
|
-
setOpen(!open);
|
|
118
|
-
};
|
|
119
112
|
const columnText = react.useMemo(() => {
|
|
120
113
|
let header;
|
|
121
114
|
try {
|
|
@@ -136,6 +129,53 @@ function Filter({
|
|
|
136
129
|
const sortedUniqueValues = react.useMemo(() => typeof firstValue === 'number' ? [] : Array.from(column.getFacetedUniqueValues().keys()).sort().map(v => v ?? 'NULL_OR_UNDEFINED'),
|
|
137
130
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
138
131
|
[column.getFacetedUniqueValues()]);
|
|
132
|
+
return typeof firstValue === 'number' ? /*#__PURE__*/jsxRuntime.jsxs(NumberContainer, {
|
|
133
|
+
children: [/*#__PURE__*/jsxRuntime.jsx(DebouncedInput, {
|
|
134
|
+
type: "number",
|
|
135
|
+
values: sortedUniqueValues,
|
|
136
|
+
min: Number(column.getFacetedMinMaxValues()?.[0] ?? ''),
|
|
137
|
+
max: Number(column.getFacetedMinMaxValues()?.[1] ?? ''),
|
|
138
|
+
value: columnFilterValue?.[0] ?? '',
|
|
139
|
+
onChange: value => column.setFilterValue(old => [value, old?.[1]]),
|
|
140
|
+
placeholder: `Min ${column.getFacetedMinMaxValues()?.[0] ? `(${column.getFacetedMinMaxValues()?.[0]})` : ''}`
|
|
141
|
+
}), /*#__PURE__*/jsxRuntime.jsx(DebouncedInput, {
|
|
142
|
+
type: "number",
|
|
143
|
+
values: sortedUniqueValues,
|
|
144
|
+
min: Number(column.getFacetedMinMaxValues()?.[0] ?? ''),
|
|
145
|
+
max: Number(column.getFacetedMinMaxValues()?.[1] ?? ''),
|
|
146
|
+
value: columnFilterValue?.[1] ?? '',
|
|
147
|
+
onChange: value => column.setFilterValue(old => [old?.[0], value]),
|
|
148
|
+
placeholder: `Max ${column.getFacetedMinMaxValues()?.[1] ? `(${column.getFacetedMinMaxValues()?.[1]})` : ''}`
|
|
149
|
+
})]
|
|
150
|
+
}) : /*#__PURE__*/jsxRuntime.jsx(DebouncedInput, {
|
|
151
|
+
type: "text",
|
|
152
|
+
label: columnText,
|
|
153
|
+
values: sortedUniqueValues,
|
|
154
|
+
debounce: 100,
|
|
155
|
+
value: columnFilterValue ?? [],
|
|
156
|
+
onChange: value => column.setFilterValue(value),
|
|
157
|
+
placeholder: `${(columnFilterValue ?? []).length} / ${column.getFacetedUniqueValues().size} selected`,
|
|
158
|
+
list: column.id + 'list'
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/* istanbul ignore file */
|
|
163
|
+
|
|
164
|
+
function FilterWrapper({
|
|
165
|
+
column,
|
|
166
|
+
CustomComponent
|
|
167
|
+
}) {
|
|
168
|
+
const {
|
|
169
|
+
table
|
|
170
|
+
} = useTableContext();
|
|
171
|
+
const firstValue = table.getPreFilteredRowModel().flatRows[0]?.getValue(column.id);
|
|
172
|
+
const [open, setOpen] = react.useState(false);
|
|
173
|
+
const filterIconRef = react.useRef();
|
|
174
|
+
const togglePopover = event => {
|
|
175
|
+
event.stopPropagation();
|
|
176
|
+
setOpen(!open);
|
|
177
|
+
};
|
|
178
|
+
const columnFilterValue = column.getFilterValue();
|
|
139
179
|
const hasActiveFilters = value => {
|
|
140
180
|
if (Array.isArray(value)) {
|
|
141
181
|
if (typeof firstValue === 'number') {
|
|
@@ -146,6 +186,7 @@ function Filter({
|
|
|
146
186
|
}
|
|
147
187
|
return value;
|
|
148
188
|
};
|
|
189
|
+
const onChange = react.useCallback(value => column.setFilterValue(value), [column]);
|
|
149
190
|
return /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
150
191
|
children: [/*#__PURE__*/jsxRuntime.jsx(edsCoreReact.Button, {
|
|
151
192
|
"aria-haspopup": true,
|
|
@@ -154,6 +195,7 @@ function Filter({
|
|
|
154
195
|
ref: filterIconRef,
|
|
155
196
|
onClick: togglePopover,
|
|
156
197
|
variant: 'ghost_icon',
|
|
198
|
+
"aria-label": 'Show column filters',
|
|
157
199
|
children: /*#__PURE__*/jsxRuntime.jsx(edsCoreReact.Icon, {
|
|
158
200
|
color: edsTokens.tokens.colors.text.static_icons__default.hex,
|
|
159
201
|
data: hasActiveFilters(columnFilterValue) ? edsIcons.filter_alt_active : edsIcons.filter_alt
|
|
@@ -169,39 +211,31 @@ function Filter({
|
|
|
169
211
|
style: {
|
|
170
212
|
width: typeof firstValue === 'number' ? '180px' : '310px'
|
|
171
213
|
},
|
|
172
|
-
children:
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
value: columnFilterValue?.[0] ?? '',
|
|
179
|
-
onChange: value => column.setFilterValue(old => [value, old?.[1]]),
|
|
180
|
-
placeholder: `Min ${column.getFacetedMinMaxValues()?.[0] ? `(${column.getFacetedMinMaxValues()?.[0]})` : ''}`
|
|
181
|
-
}), /*#__PURE__*/jsxRuntime.jsx(DebouncedInput, {
|
|
182
|
-
type: "number",
|
|
183
|
-
values: sortedUniqueValues,
|
|
184
|
-
min: Number(column.getFacetedMinMaxValues()?.[0] ?? ''),
|
|
185
|
-
max: Number(column.getFacetedMinMaxValues()?.[1] ?? ''),
|
|
186
|
-
value: columnFilterValue?.[1] ?? '',
|
|
187
|
-
onChange: value => column.setFilterValue(old => [old?.[0], value]),
|
|
188
|
-
placeholder: `Max ${column.getFacetedMinMaxValues()?.[1] ? `(${column.getFacetedMinMaxValues()?.[1]})` : ''}`
|
|
189
|
-
})]
|
|
190
|
-
}) : /*#__PURE__*/jsxRuntime.jsx(DebouncedInput, {
|
|
191
|
-
type: "text",
|
|
192
|
-
label: columnText,
|
|
193
|
-
values: sortedUniqueValues,
|
|
194
|
-
debounce: 100,
|
|
195
|
-
value: columnFilterValue ?? [],
|
|
196
|
-
onChange: value => column.setFilterValue(value),
|
|
197
|
-
placeholder: `${(columnFilterValue ?? []).length} / ${column.getFacetedUniqueValues().size} selected`,
|
|
198
|
-
list: column.id + 'list'
|
|
214
|
+
children: CustomComponent ? /*#__PURE__*/jsxRuntime.jsx(CustomComponent, {
|
|
215
|
+
onChange: onChange,
|
|
216
|
+
value: columnFilterValue
|
|
217
|
+
}) : /*#__PURE__*/jsxRuntime.jsx(Filter, {
|
|
218
|
+
column: column,
|
|
219
|
+
table: table
|
|
199
220
|
})
|
|
200
221
|
})
|
|
201
222
|
})]
|
|
202
223
|
});
|
|
203
224
|
}
|
|
204
225
|
|
|
226
|
+
const SortIndicator = ({
|
|
227
|
+
column
|
|
228
|
+
}) => {
|
|
229
|
+
return {
|
|
230
|
+
asc: /*#__PURE__*/jsxRuntime.jsx(edsCoreReact.Icon, {
|
|
231
|
+
data: edsIcons.arrow_up
|
|
232
|
+
}),
|
|
233
|
+
desc: /*#__PURE__*/jsxRuntime.jsx(edsCoreReact.Icon, {
|
|
234
|
+
data: edsIcons.arrow_down
|
|
235
|
+
})
|
|
236
|
+
}[column.getIsSorted()] ?? null;
|
|
237
|
+
};
|
|
238
|
+
|
|
205
239
|
const getSortLabel = sorted => {
|
|
206
240
|
if (sorted) {
|
|
207
241
|
return `${sorted}ending`;
|
|
@@ -273,22 +307,16 @@ function TableHeaderCell({
|
|
|
273
307
|
className: "table-header-cell-label",
|
|
274
308
|
children: reactTable.flexRender(header.column.columnDef.header, header.getContext())
|
|
275
309
|
})
|
|
276
|
-
}), {
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
desc: /*#__PURE__*/jsxRuntime.jsx(edsCoreReact.Icon, {
|
|
281
|
-
data: edsIcons.arrow_down
|
|
282
|
-
})
|
|
283
|
-
}[header.column.getIsSorted()] ?? null, header.column.getCanFilter() ?
|
|
284
|
-
|
|
310
|
+
}), header.column.columnDef.meta?.customFilterInput && /*#__PURE__*/jsxRuntime.jsx(SortIndicator, {
|
|
311
|
+
column: header.column
|
|
312
|
+
}), header.column.getCanFilter() && !header.column.columnDef.meta?.customFilterInput ?
|
|
313
|
+
/*#__PURE__*/
|
|
285
314
|
// Supressing this warning - div is not interactive, but prevents propagation of events to avoid unintended sorting
|
|
286
315
|
// eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions
|
|
287
316
|
jsxRuntime.jsx("div", {
|
|
288
317
|
onClick: e => e.stopPropagation(),
|
|
289
|
-
children: /*#__PURE__*/jsxRuntime.jsx(
|
|
290
|
-
column: header.column
|
|
291
|
-
table: table
|
|
318
|
+
children: /*#__PURE__*/jsxRuntime.jsx(FilterWrapper, {
|
|
319
|
+
column: header.column
|
|
292
320
|
})
|
|
293
321
|
}) : null]
|
|
294
322
|
}), columnResizeMode && /*#__PURE__*/jsxRuntime.jsx(Resizer, {
|
|
@@ -359,7 +387,9 @@ function TableBodyCell({
|
|
|
359
387
|
}
|
|
360
388
|
|
|
361
389
|
function TableRow({
|
|
362
|
-
row
|
|
390
|
+
row,
|
|
391
|
+
onCellClick,
|
|
392
|
+
onClick
|
|
363
393
|
}) {
|
|
364
394
|
const {
|
|
365
395
|
rowClass,
|
|
@@ -367,13 +397,13 @@ function TableRow({
|
|
|
367
397
|
} = useTableContext();
|
|
368
398
|
return /*#__PURE__*/jsxRuntime.jsx(StyledTableRow, {
|
|
369
399
|
style: {
|
|
370
|
-
cursor: row.getCanSelect() ? 'pointer' : 'inherit',
|
|
371
400
|
...(rowStyle?.(row) ?? {})
|
|
372
401
|
},
|
|
373
402
|
className: `${row.getIsSelected() ? 'selected' : ''} ${rowClass?.(row)}`,
|
|
374
|
-
onClick:
|
|
403
|
+
onClick: onClick,
|
|
375
404
|
children: row.getVisibleCells().map(cell => /*#__PURE__*/jsxRuntime.jsx(TableBodyCell, {
|
|
376
|
-
cell: cell
|
|
405
|
+
cell: cell,
|
|
406
|
+
onClick: onCellClick ? event => onCellClick(cell, event) : undefined
|
|
377
407
|
}, cell.id))
|
|
378
408
|
});
|
|
379
409
|
}
|
|
@@ -409,6 +439,19 @@ function addPxSuffixIfInputHasNoPrefix(size) {
|
|
|
409
439
|
}
|
|
410
440
|
return size;
|
|
411
441
|
}
|
|
442
|
+
function logDevelopmentWarningOfPropUse(deprecatedProps) {
|
|
443
|
+
if (process.env.NODE_ENV !== 'development') {
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
446
|
+
for (const [key, {
|
|
447
|
+
value,
|
|
448
|
+
mitigationInfo
|
|
449
|
+
}] of Object.entries(deprecatedProps)) {
|
|
450
|
+
if (typeof value !== 'undefined') {
|
|
451
|
+
console.warn(`The prop '${key}' is deprecated and will be removed in a future release. ${mitigationInfo}`);
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
}
|
|
412
455
|
|
|
413
456
|
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
414
457
|
function EdsDataGrid({
|
|
@@ -417,13 +460,18 @@ function EdsDataGrid({
|
|
|
417
460
|
columnResizeMode,
|
|
418
461
|
pageSize,
|
|
419
462
|
rowSelection,
|
|
463
|
+
enableRowSelection,
|
|
464
|
+
enableMultiRowSelection,
|
|
465
|
+
enableSubRowSelection,
|
|
420
466
|
selectedRows,
|
|
467
|
+
rowSelectionState,
|
|
421
468
|
enableColumnFiltering,
|
|
422
469
|
debug,
|
|
423
470
|
enablePagination,
|
|
424
471
|
enableSorting,
|
|
425
472
|
stickyHeader,
|
|
426
473
|
onSelectRow,
|
|
474
|
+
onRowSelectionChange,
|
|
427
475
|
caption,
|
|
428
476
|
enableVirtual,
|
|
429
477
|
virtualHeight,
|
|
@@ -453,10 +501,30 @@ function EdsDataGrid({
|
|
|
453
501
|
expansionState,
|
|
454
502
|
setExpansionState,
|
|
455
503
|
getSubRows,
|
|
456
|
-
defaultColumn
|
|
504
|
+
defaultColumn,
|
|
505
|
+
onRowClick,
|
|
506
|
+
onCellClick
|
|
457
507
|
}) {
|
|
508
|
+
logDevelopmentWarningOfPropUse({
|
|
509
|
+
virtualHeight: {
|
|
510
|
+
value: virtualHeight,
|
|
511
|
+
mitigationInfo: "Use 'height' instead."
|
|
512
|
+
},
|
|
513
|
+
rowSelection: {
|
|
514
|
+
value: rowSelection,
|
|
515
|
+
mitigationInfo: "Use 'enableRowSelection' instead."
|
|
516
|
+
},
|
|
517
|
+
onSelectRow: {
|
|
518
|
+
value: onSelectRow,
|
|
519
|
+
mitigationInfo: "Use 'onRowSelectionChange' instead."
|
|
520
|
+
},
|
|
521
|
+
selectedRows: {
|
|
522
|
+
value: selectedRows,
|
|
523
|
+
mitigationInfo: "Use 'rowSelectionState' instead."
|
|
524
|
+
}
|
|
525
|
+
});
|
|
458
526
|
const [sorting, setSorting] = react.useState(sortingState ?? []);
|
|
459
|
-
const [
|
|
527
|
+
const [internalRowSelectionState, setInternalRowSelectionState] = react.useState(rowSelectionState ?? selectedRows ?? {});
|
|
460
528
|
const [columnPin, setColumnPin] = react.useState(columnPinState ?? {});
|
|
461
529
|
const [columnFilters, setColumnFilters] = react.useState([]);
|
|
462
530
|
const [internalColumnSize, setInternalColumnSize] = react.useState(columnSizing ?? {});
|
|
@@ -482,8 +550,8 @@ function EdsDataGrid({
|
|
|
482
550
|
setSorting(sortingState);
|
|
483
551
|
}, [sortingState]);
|
|
484
552
|
react.useEffect(() => {
|
|
485
|
-
|
|
486
|
-
}, [selectedRows]);
|
|
553
|
+
setInternalRowSelectionState(rowSelectionState ?? selectedRows ?? {});
|
|
554
|
+
}, [rowSelectionState, selectedRows]);
|
|
487
555
|
|
|
488
556
|
/**
|
|
489
557
|
* By default, the filter-function accepts single-value filters. This adds multi-filter functionality out of the box.
|
|
@@ -556,7 +624,7 @@ function EdsDataGrid({
|
|
|
556
624
|
state: {
|
|
557
625
|
sorting,
|
|
558
626
|
columnPinning: columnPin,
|
|
559
|
-
rowSelection:
|
|
627
|
+
rowSelection: internalRowSelectionState,
|
|
560
628
|
columnOrder: columnOrderState,
|
|
561
629
|
columnSizing: columnSizing ?? internalColumnSize,
|
|
562
630
|
expanded: expansionState
|
|
@@ -580,7 +648,9 @@ function EdsDataGrid({
|
|
|
580
648
|
debugTable: debug,
|
|
581
649
|
debugHeaders: debug,
|
|
582
650
|
debugColumns: debug,
|
|
583
|
-
enableRowSelection: rowSelection ?? false,
|
|
651
|
+
enableRowSelection: enableRowSelection ?? rowSelection ?? false,
|
|
652
|
+
enableMultiRowSelection: enableMultiRowSelection ?? false,
|
|
653
|
+
enableSubRowSelection: enableSubRowSelection ?? false,
|
|
584
654
|
enableColumnPinning: true,
|
|
585
655
|
enablePinning: true,
|
|
586
656
|
getRowId
|
|
@@ -594,12 +664,11 @@ function EdsDataGrid({
|
|
|
594
664
|
/**
|
|
595
665
|
* Set up handlers for rowSelection
|
|
596
666
|
*/
|
|
597
|
-
if (rowSelection ?? false) {
|
|
667
|
+
if (enableRowSelection ?? rowSelection ?? false) {
|
|
598
668
|
options.onRowSelectionChange = updaterOrValue => {
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
setSelection(updaterOrValue);
|
|
669
|
+
onSelectRow?.(updaterOrValue);
|
|
670
|
+
onRowSelectionChange?.(updaterOrValue);
|
|
671
|
+
setInternalRowSelectionState(updaterOrValue);
|
|
603
672
|
};
|
|
604
673
|
}
|
|
605
674
|
|
|
@@ -744,9 +813,14 @@ function EdsDataGrid({
|
|
|
744
813
|
height: `${paddingTop}px`
|
|
745
814
|
}
|
|
746
815
|
})
|
|
747
|
-
}), virtualRows.map(
|
|
748
|
-
row
|
|
749
|
-
|
|
816
|
+
}), virtualRows.map(virtualItem => {
|
|
817
|
+
const row = table.getRowModel().rows[virtualItem.index];
|
|
818
|
+
return /*#__PURE__*/jsxRuntime.jsx(TableRow, {
|
|
819
|
+
row: row,
|
|
820
|
+
onClick: onRowClick ? event => onRowClick(row, event) : undefined,
|
|
821
|
+
onCellClick: onCellClick
|
|
822
|
+
}, virtualItem.index);
|
|
823
|
+
}), paddingBottom > 0 && /*#__PURE__*/jsxRuntime.jsx(edsCoreReact.Table.Row, {
|
|
750
824
|
"data-testid": "virtual-padding-bottom",
|
|
751
825
|
className: 'virtual-padding-bottom',
|
|
752
826
|
style: {
|
|
@@ -759,7 +833,9 @@ function EdsDataGrid({
|
|
|
759
833
|
})
|
|
760
834
|
})]
|
|
761
835
|
}), !enableVirtual && table.getRowModel().rows.map(row => /*#__PURE__*/jsxRuntime.jsx(TableRow, {
|
|
762
|
-
row: row
|
|
836
|
+
row: row,
|
|
837
|
+
onClick: onRowClick ? event => onRowClick(row, event) : undefined,
|
|
838
|
+
onCellClick: onCellClick
|
|
763
839
|
}, row.id))]
|
|
764
840
|
})]
|
|
765
841
|
}), externalPaginator ? externalPaginator : enablePagination && /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
@@ -795,4 +871,10 @@ const TableWrapper = styled__default.default.div.withConfig({
|
|
|
795
871
|
$width
|
|
796
872
|
}) => Boolean($height) && Boolean($width) ? 'strict' : 'unset');
|
|
797
873
|
|
|
874
|
+
Object.defineProperty(exports, "createColumnHelper", {
|
|
875
|
+
enumerable: true,
|
|
876
|
+
get: function () { return reactTable.createColumnHelper; }
|
|
877
|
+
});
|
|
798
878
|
exports.EdsDataGrid = EdsDataGrid;
|
|
879
|
+
exports.FilterWrapper = FilterWrapper;
|
|
880
|
+
exports.SortIndicator = SortIndicator;
|
package/dist/esm/EdsDataGrid.js
CHANGED
|
@@ -2,11 +2,11 @@ import { Typography, useEds, Table, Pagination } from '@equinor/eds-core-react';
|
|
|
2
2
|
import { getExpandedRowModel, getCoreRowModel, getSortedRowModel, getFacetedRowModel, getFacetedUniqueValues, getFacetedMinMaxValues, getFilteredRowModel, getPaginationRowModel, useReactTable } from '@tanstack/react-table';
|
|
3
3
|
import { useVirtualizer } from '@tanstack/react-virtual';
|
|
4
4
|
import { useState, useEffect, useMemo, useRef, useCallback } from 'react';
|
|
5
|
+
import styled from 'styled-components';
|
|
6
|
+
import { TableProvider } from './EdsDataGridContext.js';
|
|
5
7
|
import { TableHeaderRow } from './components/TableHeaderRow.js';
|
|
6
8
|
import { TableRow } from './components/TableRow.js';
|
|
7
|
-
import {
|
|
8
|
-
import styled from 'styled-components';
|
|
9
|
-
import { addPxSuffixIfInputHasNoPrefix } from './utils.js';
|
|
9
|
+
import { addPxSuffixIfInputHasNoPrefix, logDevelopmentWarningOfPropUse } from './utils.js';
|
|
10
10
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
11
11
|
|
|
12
12
|
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
|
@@ -16,13 +16,18 @@ function EdsDataGrid({
|
|
|
16
16
|
columnResizeMode,
|
|
17
17
|
pageSize,
|
|
18
18
|
rowSelection,
|
|
19
|
+
enableRowSelection,
|
|
20
|
+
enableMultiRowSelection,
|
|
21
|
+
enableSubRowSelection,
|
|
19
22
|
selectedRows,
|
|
23
|
+
rowSelectionState,
|
|
20
24
|
enableColumnFiltering,
|
|
21
25
|
debug,
|
|
22
26
|
enablePagination,
|
|
23
27
|
enableSorting,
|
|
24
28
|
stickyHeader,
|
|
25
29
|
onSelectRow,
|
|
30
|
+
onRowSelectionChange,
|
|
26
31
|
caption,
|
|
27
32
|
enableVirtual,
|
|
28
33
|
virtualHeight,
|
|
@@ -52,10 +57,30 @@ function EdsDataGrid({
|
|
|
52
57
|
expansionState,
|
|
53
58
|
setExpansionState,
|
|
54
59
|
getSubRows,
|
|
55
|
-
defaultColumn
|
|
60
|
+
defaultColumn,
|
|
61
|
+
onRowClick,
|
|
62
|
+
onCellClick
|
|
56
63
|
}) {
|
|
64
|
+
logDevelopmentWarningOfPropUse({
|
|
65
|
+
virtualHeight: {
|
|
66
|
+
value: virtualHeight,
|
|
67
|
+
mitigationInfo: "Use 'height' instead."
|
|
68
|
+
},
|
|
69
|
+
rowSelection: {
|
|
70
|
+
value: rowSelection,
|
|
71
|
+
mitigationInfo: "Use 'enableRowSelection' instead."
|
|
72
|
+
},
|
|
73
|
+
onSelectRow: {
|
|
74
|
+
value: onSelectRow,
|
|
75
|
+
mitigationInfo: "Use 'onRowSelectionChange' instead."
|
|
76
|
+
},
|
|
77
|
+
selectedRows: {
|
|
78
|
+
value: selectedRows,
|
|
79
|
+
mitigationInfo: "Use 'rowSelectionState' instead."
|
|
80
|
+
}
|
|
81
|
+
});
|
|
57
82
|
const [sorting, setSorting] = useState(sortingState ?? []);
|
|
58
|
-
const [
|
|
83
|
+
const [internalRowSelectionState, setInternalRowSelectionState] = useState(rowSelectionState ?? selectedRows ?? {});
|
|
59
84
|
const [columnPin, setColumnPin] = useState(columnPinState ?? {});
|
|
60
85
|
const [columnFilters, setColumnFilters] = useState([]);
|
|
61
86
|
const [internalColumnSize, setInternalColumnSize] = useState(columnSizing ?? {});
|
|
@@ -81,8 +106,8 @@ function EdsDataGrid({
|
|
|
81
106
|
setSorting(sortingState);
|
|
82
107
|
}, [sortingState]);
|
|
83
108
|
useEffect(() => {
|
|
84
|
-
|
|
85
|
-
}, [selectedRows]);
|
|
109
|
+
setInternalRowSelectionState(rowSelectionState ?? selectedRows ?? {});
|
|
110
|
+
}, [rowSelectionState, selectedRows]);
|
|
86
111
|
|
|
87
112
|
/**
|
|
88
113
|
* By default, the filter-function accepts single-value filters. This adds multi-filter functionality out of the box.
|
|
@@ -155,7 +180,7 @@ function EdsDataGrid({
|
|
|
155
180
|
state: {
|
|
156
181
|
sorting,
|
|
157
182
|
columnPinning: columnPin,
|
|
158
|
-
rowSelection:
|
|
183
|
+
rowSelection: internalRowSelectionState,
|
|
159
184
|
columnOrder: columnOrderState,
|
|
160
185
|
columnSizing: columnSizing ?? internalColumnSize,
|
|
161
186
|
expanded: expansionState
|
|
@@ -179,7 +204,9 @@ function EdsDataGrid({
|
|
|
179
204
|
debugTable: debug,
|
|
180
205
|
debugHeaders: debug,
|
|
181
206
|
debugColumns: debug,
|
|
182
|
-
enableRowSelection: rowSelection ?? false,
|
|
207
|
+
enableRowSelection: enableRowSelection ?? rowSelection ?? false,
|
|
208
|
+
enableMultiRowSelection: enableMultiRowSelection ?? false,
|
|
209
|
+
enableSubRowSelection: enableSubRowSelection ?? false,
|
|
183
210
|
enableColumnPinning: true,
|
|
184
211
|
enablePinning: true,
|
|
185
212
|
getRowId
|
|
@@ -193,12 +220,11 @@ function EdsDataGrid({
|
|
|
193
220
|
/**
|
|
194
221
|
* Set up handlers for rowSelection
|
|
195
222
|
*/
|
|
196
|
-
if (rowSelection ?? false) {
|
|
223
|
+
if (enableRowSelection ?? rowSelection ?? false) {
|
|
197
224
|
options.onRowSelectionChange = updaterOrValue => {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
setSelection(updaterOrValue);
|
|
225
|
+
onSelectRow?.(updaterOrValue);
|
|
226
|
+
onRowSelectionChange?.(updaterOrValue);
|
|
227
|
+
setInternalRowSelectionState(updaterOrValue);
|
|
202
228
|
};
|
|
203
229
|
}
|
|
204
230
|
|
|
@@ -343,9 +369,14 @@ function EdsDataGrid({
|
|
|
343
369
|
height: `${paddingTop}px`
|
|
344
370
|
}
|
|
345
371
|
})
|
|
346
|
-
}), virtualRows.map(
|
|
347
|
-
row
|
|
348
|
-
|
|
372
|
+
}), virtualRows.map(virtualItem => {
|
|
373
|
+
const row = table.getRowModel().rows[virtualItem.index];
|
|
374
|
+
return /*#__PURE__*/jsx(TableRow, {
|
|
375
|
+
row: row,
|
|
376
|
+
onClick: onRowClick ? event => onRowClick(row, event) : undefined,
|
|
377
|
+
onCellClick: onCellClick
|
|
378
|
+
}, virtualItem.index);
|
|
379
|
+
}), paddingBottom > 0 && /*#__PURE__*/jsx(Table.Row, {
|
|
349
380
|
"data-testid": "virtual-padding-bottom",
|
|
350
381
|
className: 'virtual-padding-bottom',
|
|
351
382
|
style: {
|
|
@@ -358,7 +389,9 @@ function EdsDataGrid({
|
|
|
358
389
|
})
|
|
359
390
|
})]
|
|
360
391
|
}), !enableVirtual && table.getRowModel().rows.map(row => /*#__PURE__*/jsx(TableRow, {
|
|
361
|
-
row: row
|
|
392
|
+
row: row,
|
|
393
|
+
onClick: onRowClick ? event => onRowClick(row, event) : undefined,
|
|
394
|
+
onCellClick: onCellClick
|
|
362
395
|
}, row.id))]
|
|
363
396
|
})]
|
|
364
397
|
}), externalPaginator ? externalPaginator : enablePagination && /*#__PURE__*/jsx("div", {
|
|
@@ -42,7 +42,6 @@ function DebouncedInput({
|
|
|
42
42
|
/* eslint-disable-next-line @typescript-eslint/ban-ts-comment */,
|
|
43
43
|
label: `Select ${label ?? ''}`,
|
|
44
44
|
placeholder: props.placeholder ?? 'Search',
|
|
45
|
-
disablePortal: false /*TODO: Check with Oddbjørn re. sizing/position*/,
|
|
46
45
|
selectedOptions: value,
|
|
47
46
|
onOptionsChange: c => setValue(c.selectedItems),
|
|
48
47
|
multiline: true
|
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
2
|
import { DebouncedInput } from './DebouncedInput.js';
|
|
3
|
-
import { Button, Icon, Popover } from '@equinor/eds-core-react';
|
|
4
|
-
import { filter_alt_active, filter_alt } from '@equinor/eds-icons';
|
|
5
3
|
import styled from 'styled-components';
|
|
6
|
-
import {
|
|
7
|
-
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
4
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
8
5
|
|
|
9
6
|
/* istanbul ignore file */
|
|
10
7
|
|
|
@@ -17,12 +14,6 @@ function Filter({
|
|
|
17
14
|
table
|
|
18
15
|
}) {
|
|
19
16
|
const firstValue = table.getPreFilteredRowModel().flatRows[0]?.getValue(column.id);
|
|
20
|
-
const [open, setOpen] = useState(false);
|
|
21
|
-
const filterIconRef = useRef();
|
|
22
|
-
const togglePopover = event => {
|
|
23
|
-
event.stopPropagation();
|
|
24
|
-
setOpen(!open);
|
|
25
|
-
};
|
|
26
17
|
const columnText = useMemo(() => {
|
|
27
18
|
let header;
|
|
28
19
|
try {
|
|
@@ -43,69 +34,33 @@ function Filter({
|
|
|
43
34
|
const sortedUniqueValues = useMemo(() => typeof firstValue === 'number' ? [] : Array.from(column.getFacetedUniqueValues().keys()).sort().map(v => v ?? 'NULL_OR_UNDEFINED'),
|
|
44
35
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
45
36
|
[column.getFacetedUniqueValues()]);
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
variant: 'ghost_icon',
|
|
64
|
-
children: /*#__PURE__*/jsx(Icon, {
|
|
65
|
-
color: tokens.colors.text.static_icons__default.hex,
|
|
66
|
-
data: hasActiveFilters(columnFilterValue) ? filter_alt_active : filter_alt
|
|
67
|
-
})
|
|
68
|
-
}), /*#__PURE__*/jsx(Popover, {
|
|
69
|
-
style: {
|
|
70
|
-
width: typeof firstValue === 'number' ? '220px' : '340px'
|
|
71
|
-
},
|
|
72
|
-
anchorEl: filterIconRef.current,
|
|
73
|
-
open: open,
|
|
74
|
-
onClose: () => setOpen(false),
|
|
75
|
-
children: /*#__PURE__*/jsx(Popover.Content, {
|
|
76
|
-
style: {
|
|
77
|
-
width: typeof firstValue === 'number' ? '180px' : '310px'
|
|
78
|
-
},
|
|
79
|
-
children: typeof firstValue === 'number' ? /*#__PURE__*/jsxs(NumberContainer, {
|
|
80
|
-
children: [/*#__PURE__*/jsx(DebouncedInput, {
|
|
81
|
-
type: "number",
|
|
82
|
-
values: sortedUniqueValues,
|
|
83
|
-
min: Number(column.getFacetedMinMaxValues()?.[0] ?? ''),
|
|
84
|
-
max: Number(column.getFacetedMinMaxValues()?.[1] ?? ''),
|
|
85
|
-
value: columnFilterValue?.[0] ?? '',
|
|
86
|
-
onChange: value => column.setFilterValue(old => [value, old?.[1]]),
|
|
87
|
-
placeholder: `Min ${column.getFacetedMinMaxValues()?.[0] ? `(${column.getFacetedMinMaxValues()?.[0]})` : ''}`
|
|
88
|
-
}), /*#__PURE__*/jsx(DebouncedInput, {
|
|
89
|
-
type: "number",
|
|
90
|
-
values: sortedUniqueValues,
|
|
91
|
-
min: Number(column.getFacetedMinMaxValues()?.[0] ?? ''),
|
|
92
|
-
max: Number(column.getFacetedMinMaxValues()?.[1] ?? ''),
|
|
93
|
-
value: columnFilterValue?.[1] ?? '',
|
|
94
|
-
onChange: value => column.setFilterValue(old => [old?.[0], value]),
|
|
95
|
-
placeholder: `Max ${column.getFacetedMinMaxValues()?.[1] ? `(${column.getFacetedMinMaxValues()?.[1]})` : ''}`
|
|
96
|
-
})]
|
|
97
|
-
}) : /*#__PURE__*/jsx(DebouncedInput, {
|
|
98
|
-
type: "text",
|
|
99
|
-
label: columnText,
|
|
100
|
-
values: sortedUniqueValues,
|
|
101
|
-
debounce: 100,
|
|
102
|
-
value: columnFilterValue ?? [],
|
|
103
|
-
onChange: value => column.setFilterValue(value),
|
|
104
|
-
placeholder: `${(columnFilterValue ?? []).length} / ${column.getFacetedUniqueValues().size} selected`,
|
|
105
|
-
list: column.id + 'list'
|
|
106
|
-
})
|
|
107
|
-
})
|
|
37
|
+
return typeof firstValue === 'number' ? /*#__PURE__*/jsxs(NumberContainer, {
|
|
38
|
+
children: [/*#__PURE__*/jsx(DebouncedInput, {
|
|
39
|
+
type: "number",
|
|
40
|
+
values: sortedUniqueValues,
|
|
41
|
+
min: Number(column.getFacetedMinMaxValues()?.[0] ?? ''),
|
|
42
|
+
max: Number(column.getFacetedMinMaxValues()?.[1] ?? ''),
|
|
43
|
+
value: columnFilterValue?.[0] ?? '',
|
|
44
|
+
onChange: value => column.setFilterValue(old => [value, old?.[1]]),
|
|
45
|
+
placeholder: `Min ${column.getFacetedMinMaxValues()?.[0] ? `(${column.getFacetedMinMaxValues()?.[0]})` : ''}`
|
|
46
|
+
}), /*#__PURE__*/jsx(DebouncedInput, {
|
|
47
|
+
type: "number",
|
|
48
|
+
values: sortedUniqueValues,
|
|
49
|
+
min: Number(column.getFacetedMinMaxValues()?.[0] ?? ''),
|
|
50
|
+
max: Number(column.getFacetedMinMaxValues()?.[1] ?? ''),
|
|
51
|
+
value: columnFilterValue?.[1] ?? '',
|
|
52
|
+
onChange: value => column.setFilterValue(old => [old?.[0], value]),
|
|
53
|
+
placeholder: `Max ${column.getFacetedMinMaxValues()?.[1] ? `(${column.getFacetedMinMaxValues()?.[1]})` : ''}`
|
|
108
54
|
})]
|
|
55
|
+
}) : /*#__PURE__*/jsx(DebouncedInput, {
|
|
56
|
+
type: "text",
|
|
57
|
+
label: columnText,
|
|
58
|
+
values: sortedUniqueValues,
|
|
59
|
+
debounce: 100,
|
|
60
|
+
value: columnFilterValue ?? [],
|
|
61
|
+
onChange: value => column.setFilterValue(value),
|
|
62
|
+
placeholder: `${(columnFilterValue ?? []).length} / ${column.getFacetedUniqueValues().size} selected`,
|
|
63
|
+
list: column.id + 'list'
|
|
109
64
|
});
|
|
110
65
|
}
|
|
111
66
|
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { useState, useRef, useCallback } from 'react';
|
|
2
|
+
import { Button, Icon, Popover } from '@equinor/eds-core-react';
|
|
3
|
+
import { filter_alt_active, filter_alt } from '@equinor/eds-icons';
|
|
4
|
+
import { tokens } from '@equinor/eds-tokens';
|
|
5
|
+
import { Filter } from './Filter.js';
|
|
6
|
+
import { useTableContext } from '../EdsDataGridContext.js';
|
|
7
|
+
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
8
|
+
|
|
9
|
+
/* istanbul ignore file */
|
|
10
|
+
|
|
11
|
+
function FilterWrapper({
|
|
12
|
+
column,
|
|
13
|
+
CustomComponent
|
|
14
|
+
}) {
|
|
15
|
+
const {
|
|
16
|
+
table
|
|
17
|
+
} = useTableContext();
|
|
18
|
+
const firstValue = table.getPreFilteredRowModel().flatRows[0]?.getValue(column.id);
|
|
19
|
+
const [open, setOpen] = useState(false);
|
|
20
|
+
const filterIconRef = useRef();
|
|
21
|
+
const togglePopover = event => {
|
|
22
|
+
event.stopPropagation();
|
|
23
|
+
setOpen(!open);
|
|
24
|
+
};
|
|
25
|
+
const columnFilterValue = column.getFilterValue();
|
|
26
|
+
const hasActiveFilters = value => {
|
|
27
|
+
if (Array.isArray(value)) {
|
|
28
|
+
if (typeof firstValue === 'number') {
|
|
29
|
+
return value.some(v => !isNaN(v) && !!v);
|
|
30
|
+
} else {
|
|
31
|
+
return value.filter(v => !!v).length > 0;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return value;
|
|
35
|
+
};
|
|
36
|
+
const onChange = useCallback(value => column.setFilterValue(value), [column]);
|
|
37
|
+
return /*#__PURE__*/jsxs(Fragment, {
|
|
38
|
+
children: [/*#__PURE__*/jsx(Button, {
|
|
39
|
+
"aria-haspopup": true,
|
|
40
|
+
"aria-expanded": open,
|
|
41
|
+
"data-testid": 'open-filters',
|
|
42
|
+
ref: filterIconRef,
|
|
43
|
+
onClick: togglePopover,
|
|
44
|
+
variant: 'ghost_icon',
|
|
45
|
+
"aria-label": 'Show column filters',
|
|
46
|
+
children: /*#__PURE__*/jsx(Icon, {
|
|
47
|
+
color: tokens.colors.text.static_icons__default.hex,
|
|
48
|
+
data: hasActiveFilters(columnFilterValue) ? filter_alt_active : filter_alt
|
|
49
|
+
})
|
|
50
|
+
}), /*#__PURE__*/jsx(Popover, {
|
|
51
|
+
style: {
|
|
52
|
+
width: typeof firstValue === 'number' ? '220px' : '340px'
|
|
53
|
+
},
|
|
54
|
+
anchorEl: filterIconRef.current,
|
|
55
|
+
open: open,
|
|
56
|
+
onClose: () => setOpen(false),
|
|
57
|
+
children: /*#__PURE__*/jsx(Popover.Content, {
|
|
58
|
+
style: {
|
|
59
|
+
width: typeof firstValue === 'number' ? '180px' : '310px'
|
|
60
|
+
},
|
|
61
|
+
children: CustomComponent ? /*#__PURE__*/jsx(CustomComponent, {
|
|
62
|
+
onChange: onChange,
|
|
63
|
+
value: columnFilterValue
|
|
64
|
+
}) : /*#__PURE__*/jsx(Filter, {
|
|
65
|
+
column: column,
|
|
66
|
+
table: table
|
|
67
|
+
})
|
|
68
|
+
})
|
|
69
|
+
})]
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export { FilterWrapper };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Icon } from '@equinor/eds-core-react';
|
|
2
|
+
import { arrow_up, arrow_down } from '@equinor/eds-icons';
|
|
3
|
+
import { jsx } from 'react/jsx-runtime';
|
|
4
|
+
|
|
5
|
+
const SortIndicator = ({
|
|
6
|
+
column
|
|
7
|
+
}) => {
|
|
8
|
+
return {
|
|
9
|
+
asc: /*#__PURE__*/jsx(Icon, {
|
|
10
|
+
data: arrow_up
|
|
11
|
+
}),
|
|
12
|
+
desc: /*#__PURE__*/jsx(Icon, {
|
|
13
|
+
data: arrow_down
|
|
14
|
+
})
|
|
15
|
+
}[column.getIsSorted()] ?? null;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export { SortIndicator };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { flexRender } from '@tanstack/react-table';
|
|
2
1
|
import { Table } from '@equinor/eds-core-react';
|
|
3
|
-
import {
|
|
2
|
+
import { flexRender } from '@tanstack/react-table';
|
|
4
3
|
import { useMemo } from 'react';
|
|
5
4
|
import styled from 'styled-components';
|
|
5
|
+
import { useTableContext } from '../EdsDataGridContext.js';
|
|
6
6
|
import { jsx } from 'react/jsx-runtime';
|
|
7
7
|
|
|
8
8
|
const StyledCell = styled(Table.Cell).withConfig({
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { flexRender } from '@tanstack/react-table';
|
|
2
|
-
import { Table
|
|
3
|
-
import { arrow_up, arrow_down } from '@equinor/eds-icons';
|
|
2
|
+
import { Table } from '@equinor/eds-core-react';
|
|
4
3
|
import { useTableContext } from '../EdsDataGridContext.js';
|
|
5
|
-
import { Filter } from './Filter.js';
|
|
6
4
|
import styled from 'styled-components';
|
|
7
5
|
import { tokens } from '@equinor/eds-tokens';
|
|
8
6
|
import { useMemo } from 'react';
|
|
7
|
+
import { FilterWrapper } from './FilterWrapper.js';
|
|
8
|
+
import { SortIndicator } from './SortIndicator.js';
|
|
9
9
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
10
10
|
|
|
11
11
|
const getSortLabel = sorted => {
|
|
@@ -79,22 +79,16 @@ function TableHeaderCell({
|
|
|
79
79
|
className: "table-header-cell-label",
|
|
80
80
|
children: flexRender(header.column.columnDef.header, header.getContext())
|
|
81
81
|
})
|
|
82
|
-
}), {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
desc: /*#__PURE__*/jsx(Icon, {
|
|
87
|
-
data: arrow_down
|
|
88
|
-
})
|
|
89
|
-
}[header.column.getIsSorted()] ?? null, header.column.getCanFilter() ?
|
|
90
|
-
|
|
82
|
+
}), header.column.columnDef.meta?.customFilterInput && /*#__PURE__*/jsx(SortIndicator, {
|
|
83
|
+
column: header.column
|
|
84
|
+
}), header.column.getCanFilter() && !header.column.columnDef.meta?.customFilterInput ?
|
|
85
|
+
/*#__PURE__*/
|
|
91
86
|
// Supressing this warning - div is not interactive, but prevents propagation of events to avoid unintended sorting
|
|
92
87
|
// eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions
|
|
93
88
|
jsx("div", {
|
|
94
89
|
onClick: e => e.stopPropagation(),
|
|
95
|
-
children: /*#__PURE__*/jsx(
|
|
96
|
-
column: header.column
|
|
97
|
-
table: table
|
|
90
|
+
children: /*#__PURE__*/jsx(FilterWrapper, {
|
|
91
|
+
column: header.column
|
|
98
92
|
})
|
|
99
93
|
}) : null]
|
|
100
94
|
}), columnResizeMode && /*#__PURE__*/jsx(Resizer, {
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { Table } from '@equinor/eds-core-react';
|
|
2
|
-
import { TableBodyCell } from './TableBodyCell.js';
|
|
3
|
-
import { useTableContext } from '../EdsDataGridContext.js';
|
|
4
2
|
import styled from 'styled-components';
|
|
3
|
+
import { useTableContext } from '../EdsDataGridContext.js';
|
|
4
|
+
import { TableBodyCell } from './TableBodyCell.js';
|
|
5
5
|
import { jsx } from 'react/jsx-runtime';
|
|
6
6
|
|
|
7
7
|
function TableRow({
|
|
8
|
-
row
|
|
8
|
+
row,
|
|
9
|
+
onCellClick,
|
|
10
|
+
onClick
|
|
9
11
|
}) {
|
|
10
12
|
const {
|
|
11
13
|
rowClass,
|
|
@@ -13,13 +15,13 @@ function TableRow({
|
|
|
13
15
|
} = useTableContext();
|
|
14
16
|
return /*#__PURE__*/jsx(StyledTableRow, {
|
|
15
17
|
style: {
|
|
16
|
-
cursor: row.getCanSelect() ? 'pointer' : 'inherit',
|
|
17
18
|
...(rowStyle?.(row) ?? {})
|
|
18
19
|
},
|
|
19
20
|
className: `${row.getIsSelected() ? 'selected' : ''} ${rowClass?.(row)}`,
|
|
20
|
-
onClick:
|
|
21
|
+
onClick: onClick,
|
|
21
22
|
children: row.getVisibleCells().map(cell => /*#__PURE__*/jsx(TableBodyCell, {
|
|
22
|
-
cell: cell
|
|
23
|
+
cell: cell,
|
|
24
|
+
onClick: onCellClick ? event => onCellClick(cell, event) : undefined
|
|
23
25
|
}, cell.id))
|
|
24
26
|
});
|
|
25
27
|
}
|
package/dist/esm/index.js
CHANGED
package/dist/esm/utils.js
CHANGED
|
@@ -23,5 +23,18 @@ function addPxSuffixIfInputHasNoPrefix(size) {
|
|
|
23
23
|
}
|
|
24
24
|
return size;
|
|
25
25
|
}
|
|
26
|
+
function logDevelopmentWarningOfPropUse(deprecatedProps) {
|
|
27
|
+
if (process.env.NODE_ENV !== 'development') {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
for (const [key, {
|
|
31
|
+
value,
|
|
32
|
+
mitigationInfo
|
|
33
|
+
}] of Object.entries(deprecatedProps)) {
|
|
34
|
+
if (typeof value !== 'undefined') {
|
|
35
|
+
console.warn(`The prop '${key}' is deprecated and will be removed in a future release. ${mitigationInfo}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
26
39
|
|
|
27
|
-
export { addPxSuffixIfInputHasNoPrefix, isNumberOnlyString };
|
|
40
|
+
export { addPxSuffixIfInputHasNoPrefix, isNumberOnlyString, logDevelopmentWarningOfPropUse };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { EdsDataGridProps } from './EdsDataGridProps';
|
|
2
|
-
export declare function EdsDataGrid<T>({ rows, columns, columnResizeMode, pageSize, rowSelection, selectedRows, enableColumnFiltering, debug, enablePagination, enableSorting, stickyHeader, onSelectRow, caption, enableVirtual, virtualHeight, columnVisibility, columnVisibilityChange, emptyMessage, columnOrder, cellClass, cellStyle, rowClass, rowStyle, headerClass, headerStyle, externalPaginator, onSortingChange, manualSorting, sortingState, columnPinState, scrollbarHorizontal, width, minWidth, height, getRowId, rowVirtualizerInstanceRef, columnSizing, onColumnResize, expansionState, setExpansionState, getSubRows, defaultColumn, }: EdsDataGridProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
2
|
+
export declare function EdsDataGrid<T>({ rows, columns, columnResizeMode, pageSize, rowSelection, enableRowSelection, enableMultiRowSelection, enableSubRowSelection, selectedRows, rowSelectionState, enableColumnFiltering, debug, enablePagination, enableSorting, stickyHeader, onSelectRow, onRowSelectionChange, caption, enableVirtual, virtualHeight, columnVisibility, columnVisibilityChange, emptyMessage, columnOrder, cellClass, cellStyle, rowClass, rowStyle, headerClass, headerStyle, externalPaginator, onSortingChange, manualSorting, sortingState, columnPinState, scrollbarHorizontal, width, minWidth, height, getRowId, rowVirtualizerInstanceRef, columnSizing, onColumnResize, expansionState, setExpansionState, getSubRows, defaultColumn, onRowClick, onCellClick, }: EdsDataGridProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Column, ColumnDef, ColumnPinningState, ColumnResizeMode, ColumnSizingState, ExpandedState, OnChangeFn, Row, RowSelectionState, SortingState, TableOptions } from '@tanstack/react-table';
|
|
1
|
+
import { Cell, Column, ColumnDef, ColumnPinningState, ColumnResizeMode, ColumnSizingState, ExpandedState, OnChangeFn, Row, RowSelectionState, SortingState, TableOptions } from '@tanstack/react-table';
|
|
2
2
|
import { Virtualizer } from '@tanstack/react-virtual';
|
|
3
|
-
import { CSSProperties, MutableRefObject, ReactElement } from 'react';
|
|
3
|
+
import { CSSProperties, MouseEvent, MutableRefObject, ReactElement } from 'react';
|
|
4
4
|
type BaseProps<T> = {
|
|
5
5
|
/**
|
|
6
6
|
* The rows to display in the table
|
|
@@ -9,22 +9,13 @@ type BaseProps<T> = {
|
|
|
9
9
|
/**
|
|
10
10
|
* Definition of the columns to display in the table
|
|
11
11
|
*/
|
|
12
|
-
columns:
|
|
12
|
+
columns: TableOptions<T>['columns'];
|
|
13
13
|
/**
|
|
14
14
|
* The mode of column resizing. If not set, column resizing is disabled.
|
|
15
15
|
* Can be either 'onChange' or 'onEnd'
|
|
16
16
|
* @default undefined
|
|
17
17
|
*/
|
|
18
18
|
columnResizeMode?: ColumnResizeMode;
|
|
19
|
-
/**
|
|
20
|
-
* Set this to enable rowSelection. If a function is provided, it will be called for each row to determine if it is selectable.
|
|
21
|
-
* @default false
|
|
22
|
-
*/
|
|
23
|
-
rowSelection?: boolean | ((row: Row<T>) => boolean);
|
|
24
|
-
/**
|
|
25
|
-
* Callback for when row-selection changes
|
|
26
|
-
*/
|
|
27
|
-
onSelectRow?: OnChangeFn<RowSelectionState>;
|
|
28
19
|
/**
|
|
29
20
|
* Enable debug mode. See https://tanstack.com/table/v8/docs/api/core/table#debugall
|
|
30
21
|
* @default false
|
|
@@ -45,11 +36,6 @@ type BaseProps<T> = {
|
|
|
45
36
|
* @default undefined
|
|
46
37
|
*/
|
|
47
38
|
emptyMessage?: string;
|
|
48
|
-
/**
|
|
49
|
-
* The currently selected rows
|
|
50
|
-
* @default {}
|
|
51
|
-
*/
|
|
52
|
-
selectedRows?: Record<string | number, boolean>;
|
|
53
39
|
/**
|
|
54
40
|
* Whether there should be horizontal scrolling.
|
|
55
41
|
* This must be true for column pinning to work
|
|
@@ -90,6 +76,52 @@ type BaseProps<T> = {
|
|
|
90
76
|
*/
|
|
91
77
|
defaultColumn?: Partial<ColumnDef<T, unknown>>;
|
|
92
78
|
};
|
|
79
|
+
type RowSelectionProps<T> = {
|
|
80
|
+
/**
|
|
81
|
+
* Set this to enable rowSelection. If a function is provided, it will be called for each row to determine if it is selectable.
|
|
82
|
+
* @default false
|
|
83
|
+
*/
|
|
84
|
+
enableRowSelection?: boolean | ((row: Row<T>) => boolean);
|
|
85
|
+
/**
|
|
86
|
+
* Only used if row selection has been enabled via `enableRowSelection`
|
|
87
|
+
* Enables/disables multiple row selection for all rows in the table OR
|
|
88
|
+
* A function that given a row, returns whether to enable/disable multiple row selection for that row's children/grandchildren
|
|
89
|
+
* @default false
|
|
90
|
+
*/
|
|
91
|
+
enableMultiRowSelection?: boolean | ((row: Row<T>) => boolean);
|
|
92
|
+
/**
|
|
93
|
+
* Enables/disables automatic sub-row selection when a parent row is selected, or a function that enables/disables automatic sub-row selection
|
|
94
|
+
* @link https://tanstack.com/table/v8/docs/api/features/row-selection#enablesubrowselection
|
|
95
|
+
* @default false
|
|
96
|
+
*/
|
|
97
|
+
enableSubRowSelection?: boolean | ((row: Row<T>) => boolean);
|
|
98
|
+
/**
|
|
99
|
+
* The currently selected rows
|
|
100
|
+
* @deprecated Use `rowSelectionState`
|
|
101
|
+
* @default {}
|
|
102
|
+
*/
|
|
103
|
+
selectedRows?: Record<string | number, boolean>;
|
|
104
|
+
/**
|
|
105
|
+
* The currently selected rows
|
|
106
|
+
* @default {}
|
|
107
|
+
*/
|
|
108
|
+
rowSelectionState?: RowSelectionState;
|
|
109
|
+
/**
|
|
110
|
+
* Set this to enable rowSelection. If a function is provided, it will be called for each row to determine if it is selectable.
|
|
111
|
+
* @deprecated Use `enableRowSelection`
|
|
112
|
+
* @default false
|
|
113
|
+
*/
|
|
114
|
+
rowSelection?: boolean | ((row: Row<T>) => boolean);
|
|
115
|
+
/**
|
|
116
|
+
* Callback for when row-selection changes
|
|
117
|
+
* @deprecated Use `onRowSelectionChange`
|
|
118
|
+
*/
|
|
119
|
+
onSelectRow?: OnChangeFn<RowSelectionState>;
|
|
120
|
+
/**
|
|
121
|
+
* Callback for when row-selection changes
|
|
122
|
+
*/
|
|
123
|
+
onRowSelectionChange?: OnChangeFn<RowSelectionState>;
|
|
124
|
+
};
|
|
93
125
|
type StyleProps<T> = {
|
|
94
126
|
/**
|
|
95
127
|
* Function that can be used to set custom css on a cell
|
|
@@ -134,6 +166,24 @@ type FilterProps = {
|
|
|
134
166
|
*/
|
|
135
167
|
enableColumnFiltering?: boolean;
|
|
136
168
|
};
|
|
169
|
+
type HandlersProps<T> = {
|
|
170
|
+
/**
|
|
171
|
+
* Row click handler.
|
|
172
|
+
*
|
|
173
|
+
* @param row The current row
|
|
174
|
+
* @param event The click event
|
|
175
|
+
* @returns
|
|
176
|
+
*/
|
|
177
|
+
onRowClick?: (row: Row<T>, event: MouseEvent<HTMLTableRowElement>) => unknown;
|
|
178
|
+
/**
|
|
179
|
+
* Cell click handler.
|
|
180
|
+
*
|
|
181
|
+
* @param cell The current cell
|
|
182
|
+
* @param event The click event
|
|
183
|
+
* @returns
|
|
184
|
+
*/
|
|
185
|
+
onCellClick?: (cell: Cell<T, unknown>, event: MouseEvent<HTMLTableCellElement>) => unknown;
|
|
186
|
+
};
|
|
137
187
|
type PagingProps = {
|
|
138
188
|
/**
|
|
139
189
|
* Whether pagination should be enabled.
|
|
@@ -198,7 +248,7 @@ type ExpansionProps<T> = {
|
|
|
198
248
|
setExpansionState?: React.Dispatch<React.SetStateAction<ExpandedState>>;
|
|
199
249
|
getSubRows?: (row: T, rowIndex: number) => Array<T>;
|
|
200
250
|
};
|
|
201
|
-
export type EdsDataGridProps<T> = BaseProps<T> & StyleProps<T> & SortProps & FilterProps & PagingProps & ColumnProps & VirtualProps & RefProps & ExpansionProps<T> & {
|
|
251
|
+
export type EdsDataGridProps<T> = BaseProps<T> & RowSelectionProps<T> & StyleProps<T> & HandlersProps<T> & SortProps & FilterProps & PagingProps & ColumnProps & VirtualProps & RefProps & ExpansionProps<T> & {
|
|
202
252
|
/**
|
|
203
253
|
* Which columns are visible. If not set, all columns are visible. undefined means that the column is visible.
|
|
204
254
|
* @default undefined
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Column } from '@tanstack/react-table';
|
|
2
|
+
import { FC } from 'react';
|
|
3
|
+
type FilterProps<T = unknown, U = unknown> = {
|
|
4
|
+
column: Column<T>;
|
|
5
|
+
CustomComponent?: FC<{
|
|
6
|
+
onChange: (value: U) => void;
|
|
7
|
+
value: U;
|
|
8
|
+
}>;
|
|
9
|
+
};
|
|
10
|
+
export declare function FilterWrapper<T = unknown>({ column, CustomComponent, }: FilterProps<T>): import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
export {};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Cell } from '@tanstack/react-table';
|
|
2
|
+
import { HTMLAttributes } from 'react';
|
|
2
3
|
type Props<T> = {
|
|
3
4
|
cell: Cell<T, unknown>;
|
|
4
|
-
}
|
|
5
|
+
} & HTMLAttributes<HTMLTableCellElement>;
|
|
5
6
|
export declare function TableBodyCell<T>({ cell }: Props<T>): import("react/jsx-runtime").JSX.Element;
|
|
6
7
|
export {};
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { Row } from '@tanstack/react-table';
|
|
2
2
|
import { HTMLAttributes } from 'react';
|
|
3
|
+
import { EdsDataGridProps } from '../EdsDataGridProps';
|
|
3
4
|
type Props<T> = {
|
|
4
5
|
row: Row<T>;
|
|
6
|
+
onCellClick?: EdsDataGridProps<T>['onCellClick'];
|
|
5
7
|
} & HTMLAttributes<HTMLTableRowElement>;
|
|
6
|
-
export declare function TableRow<T>({ row }: Props<T>): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export declare function TableRow<T>({ row, onCellClick, onClick }: Props<T>): import("react/jsx-runtime").JSX.Element;
|
|
7
9
|
export {};
|
package/dist/types/index.d.ts
CHANGED
package/dist/types/types.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { Cell, CellContext, ColumnDef, ColumnPinningState, ColumnResizeMode, ColumnSort, ExpandedState, HeaderContext, OnChangeFn, Row, RowSelectionState, SortingState, Table, VisibilityState } from '@tanstack/react-table';
|
|
2
2
|
import type { Virtualizer } from '@tanstack/react-virtual';
|
|
3
|
-
export type { Cell, CellContext, ColumnDef, ColumnPinningState, ColumnResizeMode, ColumnSort, ExpandedState, HeaderContext, OnChangeFn, Row, RowSelectionState, SortingState, Table,
|
|
3
|
+
export type { Cell, CellContext, ColumnDef, ColumnPinningState, ColumnResizeMode, ColumnSort, ExpandedState, HeaderContext, OnChangeFn, Row, RowSelectionState, SortingState, Table, Virtualizer, VisibilityState, };
|
package/dist/types/utils.d.ts
CHANGED
|
@@ -16,3 +16,7 @@
|
|
|
16
16
|
*/
|
|
17
17
|
export declare function isNumberOnlyString(number: string): boolean;
|
|
18
18
|
export declare function addPxSuffixIfInputHasNoPrefix(size: number | string): string;
|
|
19
|
+
export declare function logDevelopmentWarningOfPropUse(deprecatedProps: Record<string, {
|
|
20
|
+
value: unknown;
|
|
21
|
+
mitigationInfo?: string;
|
|
22
|
+
}>): void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@equinor/eds-data-grid-react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "A feature-rich data-grid written in React, implementing the Equinor Design System",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"types": "dist/types/index.d.ts",
|
|
@@ -17,37 +17,35 @@
|
|
|
17
17
|
"@equinor/eds-core-react": ">=0.36.0",
|
|
18
18
|
"react": ">=16.8",
|
|
19
19
|
"react-dom": ">=16.8",
|
|
20
|
-
"styled-components": ">=
|
|
20
|
+
"styled-components": ">=5.1"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@tanstack/react-table": "^8.
|
|
24
|
-
"@tanstack/react-virtual": "^3.
|
|
23
|
+
"@tanstack/react-table": "^8.16.0",
|
|
24
|
+
"@tanstack/react-virtual": "^3.5.0",
|
|
25
25
|
"@equinor/eds-icons": "^0.21.0",
|
|
26
|
-
"@equinor/eds-
|
|
27
|
-
"@equinor/eds-
|
|
26
|
+
"@equinor/eds-utils": "^0.8.5",
|
|
27
|
+
"@equinor/eds-tokens": "0.9.2"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"@mdx-js/react": "2.3.0",
|
|
31
30
|
"@rollup/plugin-babel": "^6.0.4",
|
|
32
31
|
"@rollup/plugin-commonjs": "^25.0.7",
|
|
33
32
|
"@rollup/plugin-node-resolve": "^15.2.3",
|
|
34
|
-
"@storybook/addon-a11y": "^
|
|
35
|
-
"@storybook/addon-actions": "^
|
|
36
|
-
"@storybook/addon-docs": "^
|
|
37
|
-
"@storybook/addon-essentials": "^
|
|
38
|
-
"@storybook/addon-links": "^
|
|
39
|
-
"@storybook/blocks": "^
|
|
40
|
-
"@storybook/
|
|
41
|
-
"@storybook/
|
|
42
|
-
"@storybook/react": "^
|
|
43
|
-
"@storybook/react-vite": "^7.5.1",
|
|
33
|
+
"@storybook/addon-a11y": "^8.0.2",
|
|
34
|
+
"@storybook/addon-actions": "^8.0.2",
|
|
35
|
+
"@storybook/addon-docs": "^8.0.2",
|
|
36
|
+
"@storybook/addon-essentials": "^8.0.2",
|
|
37
|
+
"@storybook/addon-links": "^8.0.2",
|
|
38
|
+
"@storybook/blocks": "^8.0.2",
|
|
39
|
+
"@storybook/preview-api": "^8.0.2",
|
|
40
|
+
"@storybook/react": "^8.0.2",
|
|
41
|
+
"@storybook/react-vite": "^8.0.2",
|
|
44
42
|
"@testing-library/dom": "^9.3.3",
|
|
45
43
|
"@testing-library/jest-dom": "^6.1.4",
|
|
46
44
|
"@testing-library/react": "14.0.0",
|
|
47
45
|
"@testing-library/user-event": "^14.5.1",
|
|
48
46
|
"@types/jest": "^29.5.6",
|
|
49
47
|
"@types/node": "20.8.9",
|
|
50
|
-
"@types/ramda": "^0.
|
|
48
|
+
"@types/ramda": "^0.30.0",
|
|
51
49
|
"@types/react": "^18.2.33",
|
|
52
50
|
"@types/react-dom": "^18.2.14",
|
|
53
51
|
"babel-loader": "^9.1.3",
|
|
@@ -57,16 +55,15 @@
|
|
|
57
55
|
"jest-styled-components": "^7.2.0",
|
|
58
56
|
"js-file-download": "^0.4.12",
|
|
59
57
|
"postcss": "^8.4.31",
|
|
60
|
-
"ramda": "^0.
|
|
58
|
+
"ramda": "^0.30.0",
|
|
61
59
|
"react": "^18.2.0",
|
|
62
60
|
"react-dom": "^18.2.0",
|
|
63
61
|
"react-hook-form": "^7.47.0",
|
|
64
|
-
"remark-gfm": "^4.0.0",
|
|
65
62
|
"rollup": "^4.2.0",
|
|
66
63
|
"rollup-plugin-delete": "^2.0.0",
|
|
67
64
|
"rollup-plugin-postcss": "^4.0.2",
|
|
68
|
-
"storybook": "^
|
|
69
|
-
"styled-components": "6.1.
|
|
65
|
+
"storybook": "^8.0.2",
|
|
66
|
+
"styled-components": "6.1.11",
|
|
70
67
|
"ts-jest": "29.1.1",
|
|
71
68
|
"ts-node": "10.9.1",
|
|
72
69
|
"tsc-watch": "^6.0.4",
|
|
@@ -89,8 +86,8 @@
|
|
|
89
86
|
"data grid"
|
|
90
87
|
],
|
|
91
88
|
"engines": {
|
|
92
|
-
"pnpm": ">=4",
|
|
93
|
-
"node": "
|
|
89
|
+
"pnpm": ">=8.15.4",
|
|
90
|
+
"node": "^18.20.2"
|
|
94
91
|
},
|
|
95
92
|
"scripts": {
|
|
96
93
|
"build": "rollup -c --bundleConfigAsCjs && tsc -p tsconfig.build.json",
|