@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.
@@ -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,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 [selection, setSelection] = react.useState(selectedRows ?? {});
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
- setSelection(selectedRows ?? {});
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: selection,
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
- if (onSelectRow) {
600
- onSelectRow(updaterOrValue);
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(row => /*#__PURE__*/jsxRuntime.jsx(TableRow, {
748
- row: table.getRowModel().rows[row.index]
749
- }, row.index)), paddingBottom > 0 && /*#__PURE__*/jsxRuntime.jsx(edsCoreReact.Table.Row, {
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;
@@ -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,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 [selection, setSelection] = useState(selectedRows ?? {});
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
- setSelection(selectedRows ?? {});
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: selection,
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
- if (onSelectRow) {
199
- onSelectRow(updaterOrValue);
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(row => /*#__PURE__*/jsx(TableRow, {
347
- row: table.getRowModel().rows[row.index]
348
- }, row.index)), paddingBottom > 0 && /*#__PURE__*/jsx(Table.Row, {
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", {
@@ -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, 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,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 {};
@@ -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.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": ">=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",