@equinor/eds-data-grid-react 0.4.0 → 0.5.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 +148 -68
- package/dist/esm/EdsDataGrid.js +49 -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 +62 -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 +19 -22
|
@@ -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,17 @@ function EdsDataGrid({
|
|
|
417
460
|
columnResizeMode,
|
|
418
461
|
pageSize,
|
|
419
462
|
rowSelection,
|
|
463
|
+
enableRowSelection,
|
|
464
|
+
enableMultiRowSelection,
|
|
420
465
|
selectedRows,
|
|
466
|
+
rowSelectionState,
|
|
421
467
|
enableColumnFiltering,
|
|
422
468
|
debug,
|
|
423
469
|
enablePagination,
|
|
424
470
|
enableSorting,
|
|
425
471
|
stickyHeader,
|
|
426
472
|
onSelectRow,
|
|
473
|
+
onRowSelectionChange,
|
|
427
474
|
caption,
|
|
428
475
|
enableVirtual,
|
|
429
476
|
virtualHeight,
|
|
@@ -453,10 +500,30 @@ function EdsDataGrid({
|
|
|
453
500
|
expansionState,
|
|
454
501
|
setExpansionState,
|
|
455
502
|
getSubRows,
|
|
456
|
-
defaultColumn
|
|
503
|
+
defaultColumn,
|
|
504
|
+
onRowClick,
|
|
505
|
+
onCellClick
|
|
457
506
|
}) {
|
|
507
|
+
logDevelopmentWarningOfPropUse({
|
|
508
|
+
virtualHeight: {
|
|
509
|
+
value: virtualHeight,
|
|
510
|
+
mitigationInfo: "Use 'height' instead."
|
|
511
|
+
},
|
|
512
|
+
rowSelection: {
|
|
513
|
+
value: rowSelection,
|
|
514
|
+
mitigationInfo: "Use 'enableRowSelection' instead."
|
|
515
|
+
},
|
|
516
|
+
onSelectRow: {
|
|
517
|
+
value: onSelectRow,
|
|
518
|
+
mitigationInfo: "Use 'onRowSelectionChange' instead."
|
|
519
|
+
},
|
|
520
|
+
selectedRows: {
|
|
521
|
+
value: selectedRows,
|
|
522
|
+
mitigationInfo: "Use 'rowSelectionState' instead."
|
|
523
|
+
}
|
|
524
|
+
});
|
|
458
525
|
const [sorting, setSorting] = react.useState(sortingState ?? []);
|
|
459
|
-
const [
|
|
526
|
+
const [internalRowSelectionState, setInternalRowSelectionState] = react.useState(rowSelectionState ?? selectedRows ?? {});
|
|
460
527
|
const [columnPin, setColumnPin] = react.useState(columnPinState ?? {});
|
|
461
528
|
const [columnFilters, setColumnFilters] = react.useState([]);
|
|
462
529
|
const [internalColumnSize, setInternalColumnSize] = react.useState(columnSizing ?? {});
|
|
@@ -482,8 +549,8 @@ function EdsDataGrid({
|
|
|
482
549
|
setSorting(sortingState);
|
|
483
550
|
}, [sortingState]);
|
|
484
551
|
react.useEffect(() => {
|
|
485
|
-
|
|
486
|
-
}, [selectedRows]);
|
|
552
|
+
setInternalRowSelectionState(rowSelectionState ?? selectedRows ?? {});
|
|
553
|
+
}, [rowSelectionState, selectedRows]);
|
|
487
554
|
|
|
488
555
|
/**
|
|
489
556
|
* By default, the filter-function accepts single-value filters. This adds multi-filter functionality out of the box.
|
|
@@ -556,7 +623,7 @@ function EdsDataGrid({
|
|
|
556
623
|
state: {
|
|
557
624
|
sorting,
|
|
558
625
|
columnPinning: columnPin,
|
|
559
|
-
rowSelection:
|
|
626
|
+
rowSelection: internalRowSelectionState,
|
|
560
627
|
columnOrder: columnOrderState,
|
|
561
628
|
columnSizing: columnSizing ?? internalColumnSize,
|
|
562
629
|
expanded: expansionState
|
|
@@ -580,7 +647,8 @@ function EdsDataGrid({
|
|
|
580
647
|
debugTable: debug,
|
|
581
648
|
debugHeaders: debug,
|
|
582
649
|
debugColumns: debug,
|
|
583
|
-
enableRowSelection: rowSelection ?? false,
|
|
650
|
+
enableRowSelection: enableRowSelection ?? rowSelection ?? false,
|
|
651
|
+
enableMultiRowSelection: enableMultiRowSelection ?? false,
|
|
584
652
|
enableColumnPinning: true,
|
|
585
653
|
enablePinning: true,
|
|
586
654
|
getRowId
|
|
@@ -594,12 +662,11 @@ function EdsDataGrid({
|
|
|
594
662
|
/**
|
|
595
663
|
* Set up handlers for rowSelection
|
|
596
664
|
*/
|
|
597
|
-
if (rowSelection ?? false) {
|
|
665
|
+
if (enableRowSelection ?? rowSelection ?? false) {
|
|
598
666
|
options.onRowSelectionChange = updaterOrValue => {
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
setSelection(updaterOrValue);
|
|
667
|
+
onSelectRow?.(updaterOrValue);
|
|
668
|
+
onRowSelectionChange?.(updaterOrValue);
|
|
669
|
+
setInternalRowSelectionState(updaterOrValue);
|
|
603
670
|
};
|
|
604
671
|
}
|
|
605
672
|
|
|
@@ -744,9 +811,14 @@ function EdsDataGrid({
|
|
|
744
811
|
height: `${paddingTop}px`
|
|
745
812
|
}
|
|
746
813
|
})
|
|
747
|
-
}), virtualRows.map(
|
|
748
|
-
row
|
|
749
|
-
|
|
814
|
+
}), virtualRows.map(virtualItem => {
|
|
815
|
+
const row = table.getRowModel().rows[virtualItem.index];
|
|
816
|
+
return /*#__PURE__*/jsxRuntime.jsx(TableRow, {
|
|
817
|
+
row: row,
|
|
818
|
+
onClick: onRowClick ? event => onRowClick(row, event) : undefined,
|
|
819
|
+
onCellClick: onCellClick
|
|
820
|
+
}, virtualItem.index);
|
|
821
|
+
}), paddingBottom > 0 && /*#__PURE__*/jsxRuntime.jsx(edsCoreReact.Table.Row, {
|
|
750
822
|
"data-testid": "virtual-padding-bottom",
|
|
751
823
|
className: 'virtual-padding-bottom',
|
|
752
824
|
style: {
|
|
@@ -759,7 +831,9 @@ function EdsDataGrid({
|
|
|
759
831
|
})
|
|
760
832
|
})]
|
|
761
833
|
}), !enableVirtual && table.getRowModel().rows.map(row => /*#__PURE__*/jsxRuntime.jsx(TableRow, {
|
|
762
|
-
row: row
|
|
834
|
+
row: row,
|
|
835
|
+
onClick: onRowClick ? event => onRowClick(row, event) : undefined,
|
|
836
|
+
onCellClick: onCellClick
|
|
763
837
|
}, row.id))]
|
|
764
838
|
})]
|
|
765
839
|
}), externalPaginator ? externalPaginator : enablePagination && /*#__PURE__*/jsxRuntime.jsx("div", {
|
|
@@ -795,4 +869,10 @@ const TableWrapper = styled__default.default.div.withConfig({
|
|
|
795
869
|
$width
|
|
796
870
|
}) => Boolean($height) && Boolean($width) ? 'strict' : 'unset');
|
|
797
871
|
|
|
872
|
+
Object.defineProperty(exports, "createColumnHelper", {
|
|
873
|
+
enumerable: true,
|
|
874
|
+
get: function () { return reactTable.createColumnHelper; }
|
|
875
|
+
});
|
|
798
876
|
exports.EdsDataGrid = EdsDataGrid;
|
|
877
|
+
exports.FilterWrapper = FilterWrapper;
|
|
878
|
+
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,17 @@ function EdsDataGrid({
|
|
|
16
16
|
columnResizeMode,
|
|
17
17
|
pageSize,
|
|
18
18
|
rowSelection,
|
|
19
|
+
enableRowSelection,
|
|
20
|
+
enableMultiRowSelection,
|
|
19
21
|
selectedRows,
|
|
22
|
+
rowSelectionState,
|
|
20
23
|
enableColumnFiltering,
|
|
21
24
|
debug,
|
|
22
25
|
enablePagination,
|
|
23
26
|
enableSorting,
|
|
24
27
|
stickyHeader,
|
|
25
28
|
onSelectRow,
|
|
29
|
+
onRowSelectionChange,
|
|
26
30
|
caption,
|
|
27
31
|
enableVirtual,
|
|
28
32
|
virtualHeight,
|
|
@@ -52,10 +56,30 @@ function EdsDataGrid({
|
|
|
52
56
|
expansionState,
|
|
53
57
|
setExpansionState,
|
|
54
58
|
getSubRows,
|
|
55
|
-
defaultColumn
|
|
59
|
+
defaultColumn,
|
|
60
|
+
onRowClick,
|
|
61
|
+
onCellClick
|
|
56
62
|
}) {
|
|
63
|
+
logDevelopmentWarningOfPropUse({
|
|
64
|
+
virtualHeight: {
|
|
65
|
+
value: virtualHeight,
|
|
66
|
+
mitigationInfo: "Use 'height' instead."
|
|
67
|
+
},
|
|
68
|
+
rowSelection: {
|
|
69
|
+
value: rowSelection,
|
|
70
|
+
mitigationInfo: "Use 'enableRowSelection' instead."
|
|
71
|
+
},
|
|
72
|
+
onSelectRow: {
|
|
73
|
+
value: onSelectRow,
|
|
74
|
+
mitigationInfo: "Use 'onRowSelectionChange' instead."
|
|
75
|
+
},
|
|
76
|
+
selectedRows: {
|
|
77
|
+
value: selectedRows,
|
|
78
|
+
mitigationInfo: "Use 'rowSelectionState' instead."
|
|
79
|
+
}
|
|
80
|
+
});
|
|
57
81
|
const [sorting, setSorting] = useState(sortingState ?? []);
|
|
58
|
-
const [
|
|
82
|
+
const [internalRowSelectionState, setInternalRowSelectionState] = useState(rowSelectionState ?? selectedRows ?? {});
|
|
59
83
|
const [columnPin, setColumnPin] = useState(columnPinState ?? {});
|
|
60
84
|
const [columnFilters, setColumnFilters] = useState([]);
|
|
61
85
|
const [internalColumnSize, setInternalColumnSize] = useState(columnSizing ?? {});
|
|
@@ -81,8 +105,8 @@ function EdsDataGrid({
|
|
|
81
105
|
setSorting(sortingState);
|
|
82
106
|
}, [sortingState]);
|
|
83
107
|
useEffect(() => {
|
|
84
|
-
|
|
85
|
-
}, [selectedRows]);
|
|
108
|
+
setInternalRowSelectionState(rowSelectionState ?? selectedRows ?? {});
|
|
109
|
+
}, [rowSelectionState, selectedRows]);
|
|
86
110
|
|
|
87
111
|
/**
|
|
88
112
|
* By default, the filter-function accepts single-value filters. This adds multi-filter functionality out of the box.
|
|
@@ -155,7 +179,7 @@ function EdsDataGrid({
|
|
|
155
179
|
state: {
|
|
156
180
|
sorting,
|
|
157
181
|
columnPinning: columnPin,
|
|
158
|
-
rowSelection:
|
|
182
|
+
rowSelection: internalRowSelectionState,
|
|
159
183
|
columnOrder: columnOrderState,
|
|
160
184
|
columnSizing: columnSizing ?? internalColumnSize,
|
|
161
185
|
expanded: expansionState
|
|
@@ -179,7 +203,8 @@ function EdsDataGrid({
|
|
|
179
203
|
debugTable: debug,
|
|
180
204
|
debugHeaders: debug,
|
|
181
205
|
debugColumns: debug,
|
|
182
|
-
enableRowSelection: rowSelection ?? false,
|
|
206
|
+
enableRowSelection: enableRowSelection ?? rowSelection ?? false,
|
|
207
|
+
enableMultiRowSelection: enableMultiRowSelection ?? false,
|
|
183
208
|
enableColumnPinning: true,
|
|
184
209
|
enablePinning: true,
|
|
185
210
|
getRowId
|
|
@@ -193,12 +218,11 @@ function EdsDataGrid({
|
|
|
193
218
|
/**
|
|
194
219
|
* Set up handlers for rowSelection
|
|
195
220
|
*/
|
|
196
|
-
if (rowSelection ?? false) {
|
|
221
|
+
if (enableRowSelection ?? rowSelection ?? false) {
|
|
197
222
|
options.onRowSelectionChange = updaterOrValue => {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
setSelection(updaterOrValue);
|
|
223
|
+
onSelectRow?.(updaterOrValue);
|
|
224
|
+
onRowSelectionChange?.(updaterOrValue);
|
|
225
|
+
setInternalRowSelectionState(updaterOrValue);
|
|
202
226
|
};
|
|
203
227
|
}
|
|
204
228
|
|
|
@@ -343,9 +367,14 @@ function EdsDataGrid({
|
|
|
343
367
|
height: `${paddingTop}px`
|
|
344
368
|
}
|
|
345
369
|
})
|
|
346
|
-
}), virtualRows.map(
|
|
347
|
-
row
|
|
348
|
-
|
|
370
|
+
}), virtualRows.map(virtualItem => {
|
|
371
|
+
const row = table.getRowModel().rows[virtualItem.index];
|
|
372
|
+
return /*#__PURE__*/jsx(TableRow, {
|
|
373
|
+
row: row,
|
|
374
|
+
onClick: onRowClick ? event => onRowClick(row, event) : undefined,
|
|
375
|
+
onCellClick: onCellClick
|
|
376
|
+
}, virtualItem.index);
|
|
377
|
+
}), paddingBottom > 0 && /*#__PURE__*/jsx(Table.Row, {
|
|
349
378
|
"data-testid": "virtual-padding-bottom",
|
|
350
379
|
className: 'virtual-padding-bottom',
|
|
351
380
|
style: {
|
|
@@ -358,7 +387,9 @@ function EdsDataGrid({
|
|
|
358
387
|
})
|
|
359
388
|
})]
|
|
360
389
|
}), !enableVirtual && table.getRowModel().rows.map(row => /*#__PURE__*/jsx(TableRow, {
|
|
361
|
-
row: row
|
|
390
|
+
row: row,
|
|
391
|
+
onClick: onRowClick ? event => onRowClick(row, event) : undefined,
|
|
392
|
+
onCellClick: onCellClick
|
|
362
393
|
}, row.id))]
|
|
363
394
|
})]
|
|
364
395
|
}), 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, 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,46 @@ 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
|
+
* The currently selected rows
|
|
94
|
+
* @deprecated Use `rowSelectionState`
|
|
95
|
+
* @default {}
|
|
96
|
+
*/
|
|
97
|
+
selectedRows?: Record<string | number, boolean>;
|
|
98
|
+
/**
|
|
99
|
+
* The currently selected rows
|
|
100
|
+
* @default {}
|
|
101
|
+
*/
|
|
102
|
+
rowSelectionState?: RowSelectionState;
|
|
103
|
+
/**
|
|
104
|
+
* Set this to enable rowSelection. If a function is provided, it will be called for each row to determine if it is selectable.
|
|
105
|
+
* @deprecated Use `enableRowSelection`
|
|
106
|
+
* @default false
|
|
107
|
+
*/
|
|
108
|
+
rowSelection?: boolean | ((row: Row<T>) => boolean);
|
|
109
|
+
/**
|
|
110
|
+
* Callback for when row-selection changes
|
|
111
|
+
* @deprecated Use `onRowSelectionChange`
|
|
112
|
+
*/
|
|
113
|
+
onSelectRow?: OnChangeFn<RowSelectionState>;
|
|
114
|
+
/**
|
|
115
|
+
* Callback for when row-selection changes
|
|
116
|
+
*/
|
|
117
|
+
onRowSelectionChange?: OnChangeFn<RowSelectionState>;
|
|
118
|
+
};
|
|
93
119
|
type StyleProps<T> = {
|
|
94
120
|
/**
|
|
95
121
|
* Function that can be used to set custom css on a cell
|
|
@@ -134,6 +160,24 @@ type FilterProps = {
|
|
|
134
160
|
*/
|
|
135
161
|
enableColumnFiltering?: boolean;
|
|
136
162
|
};
|
|
163
|
+
type HandlersProps<T> = {
|
|
164
|
+
/**
|
|
165
|
+
* Row click handler.
|
|
166
|
+
*
|
|
167
|
+
* @param row The current row
|
|
168
|
+
* @param event The click event
|
|
169
|
+
* @returns
|
|
170
|
+
*/
|
|
171
|
+
onRowClick?: (row: Row<T>, event: MouseEvent<HTMLTableRowElement>) => unknown;
|
|
172
|
+
/**
|
|
173
|
+
* Cell click handler.
|
|
174
|
+
*
|
|
175
|
+
* @param cell The current cell
|
|
176
|
+
* @param event The click event
|
|
177
|
+
* @returns
|
|
178
|
+
*/
|
|
179
|
+
onCellClick?: (cell: Cell<T, unknown>, event: MouseEvent<HTMLTableCellElement>) => unknown;
|
|
180
|
+
};
|
|
137
181
|
type PagingProps = {
|
|
138
182
|
/**
|
|
139
183
|
* Whether pagination should be enabled.
|
|
@@ -198,7 +242,7 @@ type ExpansionProps<T> = {
|
|
|
198
242
|
setExpansionState?: React.Dispatch<React.SetStateAction<ExpandedState>>;
|
|
199
243
|
getSubRows?: (row: T, rowIndex: number) => Array<T>;
|
|
200
244
|
};
|
|
201
|
-
export type EdsDataGridProps<T> = BaseProps<T> & StyleProps<T> & SortProps & FilterProps & PagingProps & ColumnProps & VirtualProps & RefProps & ExpansionProps<T> & {
|
|
245
|
+
export type EdsDataGridProps<T> = BaseProps<T> & RowSelectionProps<T> & StyleProps<T> & HandlersProps<T> & SortProps & FilterProps & PagingProps & ColumnProps & VirtualProps & RefProps & ExpansionProps<T> & {
|
|
202
246
|
/**
|
|
203
247
|
* Which columns are visible. If not set, all columns are visible. undefined means that the column is visible.
|
|
204
248
|
* @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.5.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",
|