@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.
@@ -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: typeof firstValue === 'number' ? /*#__PURE__*/jsxRuntime.jsxs(NumberContainer, {
173
- children: [/*#__PURE__*/jsxRuntime.jsx(DebouncedInput, {
174
- type: "number",
175
- values: sortedUniqueValues,
176
- min: Number(column.getFacetedMinMaxValues()?.[0] ?? ''),
177
- max: Number(column.getFacetedMinMaxValues()?.[1] ?? ''),
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
- asc: /*#__PURE__*/jsxRuntime.jsx(edsCoreReact.Icon, {
278
- data: edsIcons.arrow_up
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(Filter, {
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: () => row.getCanSelect() ? row.toggleSelected() : null,
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 [selection, setSelection] = react.useState(selectedRows ?? {});
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
- setSelection(selectedRows ?? {});
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: selection,
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
- if (onSelectRow) {
600
- onSelectRow(updaterOrValue);
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(row => /*#__PURE__*/jsxRuntime.jsx(TableRow, {
748
- row: table.getRowModel().rows[row.index]
749
- }, row.index)), paddingBottom > 0 && /*#__PURE__*/jsxRuntime.jsx(edsCoreReact.Table.Row, {
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;
@@ -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 { TableProvider } from './EdsDataGridContext.js';
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 [selection, setSelection] = useState(selectedRows ?? {});
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
- setSelection(selectedRows ?? {});
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: selection,
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
- if (onSelectRow) {
199
- onSelectRow(updaterOrValue);
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(row => /*#__PURE__*/jsx(TableRow, {
347
- row: table.getRowModel().rows[row.index]
348
- }, row.index)), paddingBottom > 0 && /*#__PURE__*/jsx(Table.Row, {
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", {
@@ -1,4 +1,4 @@
1
- import { createContext, useContext } from 'react';
1
+ import { useContext, createContext } from 'react';
2
2
  import { jsx } from 'react/jsx-runtime';
3
3
 
4
4
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -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 { useState, useRef, useMemo } from 'react';
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 { tokens } from '@equinor/eds-tokens';
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
- const hasActiveFilters = value => {
47
- if (Array.isArray(value)) {
48
- if (typeof firstValue === 'number') {
49
- return value.some(v => !isNaN(v) && !!v);
50
- } else {
51
- return value.filter(v => !!v).length > 0;
52
- }
53
- }
54
- return value;
55
- };
56
- return /*#__PURE__*/jsxs(Fragment, {
57
- children: [/*#__PURE__*/jsx(Button, {
58
- "aria-haspopup": true,
59
- "aria-expanded": open,
60
- "data-testid": 'open-filters',
61
- ref: filterIconRef,
62
- onClick: togglePopover,
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 { useTableContext } from '../EdsDataGridContext.js';
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, Icon } from '@equinor/eds-core-react';
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
- asc: /*#__PURE__*/jsx(Icon, {
84
- data: arrow_up
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(Filter, {
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: () => row.getCanSelect() ? row.toggleSelected() : null,
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
@@ -1 +1,4 @@
1
+ export { createColumnHelper } from '@tanstack/react-table';
1
2
  export { EdsDataGrid } from './EdsDataGrid.js';
3
+ export { FilterWrapper } from './components/FilterWrapper.js';
4
+ export { SortIndicator } from './components/SortIndicator.js';
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: ColumnDef<T>[];
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 {};
@@ -0,0 +1,4 @@
1
+ import { Column } from '@tanstack/react-table';
2
+ export declare const SortIndicator: <T>({ column, }: {
3
+ column: Column<T, unknown>;
4
+ }) => import("react/jsx-runtime").JSX.Element;
@@ -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 {};
@@ -1,3 +1,6 @@
1
+ export { createColumnHelper } from '@tanstack/react-table';
1
2
  export * from './EdsDataGrid';
2
3
  export * from './EdsDataGridProps';
4
+ export * from './components/FilterWrapper';
5
+ export * from './components/SortIndicator';
3
6
  export * from './types';
@@ -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, VisibilityState, Virtualizer, };
3
+ export type { Cell, CellContext, ColumnDef, ColumnPinningState, ColumnResizeMode, ColumnSort, ExpandedState, HeaderContext, OnChangeFn, Row, RowSelectionState, SortingState, Table, Virtualizer, VisibilityState, };
@@ -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.4.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": ">=4.2"
20
+ "styled-components": ">=5.1"
21
21
  },
22
22
  "dependencies": {
23
- "@tanstack/react-table": "^8.13.2",
24
- "@tanstack/react-virtual": "^3.1.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-tokens": "0.9.2",
27
- "@equinor/eds-utils": "^0.8.4"
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": "^7.5.1",
35
- "@storybook/addon-actions": "^7.5.1",
36
- "@storybook/addon-docs": "^7.5.1",
37
- "@storybook/addon-essentials": "^7.5.1",
38
- "@storybook/addon-links": "^7.5.1",
39
- "@storybook/blocks": "^7.5.1",
40
- "@storybook/builder-vite": "^7.5.1",
41
- "@storybook/client-api": "^7.5.1",
42
- "@storybook/react": "^7.5.1",
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.29.7",
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.29.1",
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": "^7.5.1",
69
- "styled-components": "6.1.0",
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": ">=10.0.0"
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",