@equinor/eds-data-grid-react 0.7.6 → 0.7.7

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.
@@ -189,7 +189,7 @@ function FilterWrapper({
189
189
  return value;
190
190
  };
191
191
  const onChange = react.useCallback(value => column.setFilterValue(value), [column]);
192
- return /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
192
+ return /*#__PURE__*/jsxRuntime.jsxs("span", {
193
193
  children: [/*#__PURE__*/jsxRuntime.jsx(edsCoreReact.Button, {
194
194
  "aria-haspopup": true,
195
195
  "aria-expanded": open,
@@ -245,7 +245,7 @@ const ResizeInner = styled__default.default.div.withConfig({
245
245
  const Resizer = styled__default.default.div.withConfig({
246
246
  displayName: "Resizer",
247
247
  componentId: "sc-plcbjs-1"
248
- })(["transform:", ";", "{opacity:", ";}position:absolute;right:0;top:0;height:100%;width:5px;cursor:col-resize;user-select:none;touch-action:none;display:flex;justify-content:flex-end;"], props => props.$columnResizeMode === 'onEnd' ? 'translateX(0px)' : 'none', ResizeInner, props => props.$isResizing ? 1 : 0);
248
+ })(["transform:", ";", "{opacity:", ";}position:absolute;right:0;top:0;height:100%;width:5px;cursor:col-resize;user-select:none;touch-action:none;display:flex;justify-content:flex-end;z-index:1;"], props => props.$columnResizeMode === 'onEnd' ? 'translateX(0px)' : 'none', ResizeInner, props => props.$isResizing ? 1 : 0);
249
249
 
250
250
  const TableCell = styled__default.default(edsCoreReact.Table.Cell).withConfig({
251
251
  displayName: "TableCell",
@@ -260,6 +260,14 @@ const TableCell = styled__default.default(edsCoreReact.Table.Cell).withConfig({
260
260
  if (p.$sticky || p.$pinned) return 'z-index: 12';
261
261
  }, ResizeInner, edsTokens.tokens.colors.interactive.primary__hover.rgba);
262
262
 
263
+ const SortButton = styled__default.default.button.withConfig({
264
+ displayName: "TableHeaderCell__SortButton",
265
+ componentId: "sc-1n0j3v0-0"
266
+ })(["cursor:pointer;height:100%;width:calc(100% - 5px);display:flex;flex-direction:row;align-items:center;background:transparent;border:none;padding-left:var(--eds_table__cell__padding_x,16px);padding-right:var(--eds_table__cell__padding_x,16px);margin:0;outline:none;color:inherit;text-align:left;font:inherit;"]);
267
+ const TableHeaderCellLabel = styled__default.default.div.withConfig({
268
+ displayName: "TableHeaderCell__TableHeaderCellLabel",
269
+ componentId: "sc-1n0j3v0-1"
270
+ })(["display:flex;flex-direction:column;"]);
263
271
  const getSortLabel = sorted => {
264
272
  if (sorted) {
265
273
  return `${sorted}ending`;
@@ -273,12 +281,23 @@ function TableHeaderCell({
273
281
  const ctx = useTableContext();
274
282
  const table = ctx.table;
275
283
  const pinned = header.column.getIsPinned();
284
+ const canSort = header.column.getCanSort();
285
+ const canFilter = header.column.getCanFilter();
276
286
  const offset = react.useMemo(() => {
277
287
  if (!pinned) {
278
288
  return null;
279
289
  }
280
290
  return pinned === 'left' ? header.getStart() : table.getTotalSize() - header.getStart() - header.getSize();
281
291
  }, [pinned, header, table]);
292
+ const tableCellPadding = react.useMemo(() => {
293
+ if (canSort && canFilter) {
294
+ return '0 var(--eds_table__cell__padding_x, 16px) 0 0';
295
+ }
296
+ if (canSort) {
297
+ return '0';
298
+ }
299
+ return '0 var(--eds_table__cell__padding_x, 16px) 0 var(--eds_table__cell__padding_x, 16px)';
300
+ }, [canSort, canFilter]);
282
301
  return header.isPlaceholder ? /*#__PURE__*/jsxRuntime.jsx(TableCell, {
283
302
  $sticky: ctx.stickyHeader,
284
303
  $offset: offset,
@@ -294,37 +313,29 @@ function TableHeaderCell({
294
313
  $pinned: pinned,
295
314
  className: ctx.headerClass ? ctx.headerClass(header.column) : '',
296
315
  "aria-sort": getSortLabel(header.column.getIsSorted()),
297
- onClick: header.column.getToggleSortingHandler(),
298
316
  colSpan: header.colSpan,
299
317
  style: {
300
318
  width: header.getSize(),
301
319
  verticalAlign: ctx.enableColumnFiltering ? 'top' : 'middle',
302
- ...(ctx.headerStyle ? ctx.headerStyle(header.column) : {})
320
+ ...(ctx.headerStyle ? ctx.headerStyle(header.column) : {}),
321
+ padding: tableCellPadding
303
322
  },
304
- children: [/*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
305
- children: [/*#__PURE__*/jsxRuntime.jsx("div", {
306
- style: {
307
- display: 'flex',
308
- flexDirection: 'column'
309
- },
310
- children: /*#__PURE__*/jsxRuntime.jsx("span", {
311
- className: "table-header-cell-label",
312
- children: reactTable.flexRender(header.column.columnDef.header, header.getContext())
313
- })
323
+ children: [canSort ? /*#__PURE__*/jsxRuntime.jsxs(SortButton, {
324
+ tabIndex: -1,
325
+ onClick: header.column.getToggleSortingHandler(),
326
+ "data-testid": `sort-button-${header.id}`,
327
+ children: [/*#__PURE__*/jsxRuntime.jsx(TableHeaderCellLabel, {
328
+ className: "table-header-cell-label",
329
+ children: reactTable.flexRender(header.column.columnDef.header, header.getContext())
314
330
  }), !header.column.columnDef.meta?.customFilterInput && /*#__PURE__*/jsxRuntime.jsx(SortIndicator, {
315
331
  column: header.column
316
- }), header.column.getCanFilter() && !header.column.columnDef.meta?.customFilterInput ?
317
- /*#__PURE__*/
318
- // Supressing this warning - div is not interactive, but prevents propagation of events to avoid unintended sorting
319
- // eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions
320
- jsxRuntime.jsx("div", {
321
- onClick: e => e.stopPropagation(),
322
- children: /*#__PURE__*/jsxRuntime.jsx(FilterWrapper, {
323
- column: header.column
324
- })
325
- }) : null]
326
- }), columnResizeMode && /*#__PURE__*/jsxRuntime.jsx(Resizer, {
327
- onClick: e => e.stopPropagation(),
332
+ })]
333
+ }) : /*#__PURE__*/jsxRuntime.jsx(TableHeaderCellLabel, {
334
+ className: "table-header-cell-label",
335
+ children: reactTable.flexRender(header.column.columnDef.header, header.getContext())
336
+ }), canFilter && !header.column.columnDef.meta?.customFilterInput ? /*#__PURE__*/jsxRuntime.jsx(FilterWrapper, {
337
+ column: header.column
338
+ }) : null, columnResizeMode && /*#__PURE__*/jsxRuntime.jsx(Resizer, {
328
339
  onMouseDown: header.getResizeHandler(),
329
340
  onTouchStart: header.getResizeHandler(),
330
341
  $isResizing: header.column.getIsResizing(),
@@ -965,6 +976,7 @@ function EdsDataGridInner({
965
976
  }, footerGroup.id))
966
977
  })]
967
978
  }), externalPaginator ? externalPaginator : enablePagination && /*#__PURE__*/jsxRuntime.jsx("div", {
979
+ className: "table-pagination",
968
980
  style: {
969
981
  maxWidth: `${table.getTotalSize()}px`
970
982
  },
@@ -1,5 +1,5 @@
1
- import { Typography, useEds, Table, Pagination } from '@equinor/eds-core-react';
2
- import { getExpandedRowModel, getCoreRowModel, getSortedRowModel, getFacetedRowModel, getFacetedUniqueValues, getFacetedMinMaxValues, getFilteredRowModel, getPaginationRowModel, useReactTable } from '@tanstack/react-table';
1
+ import { useEds, Table, Pagination, Typography } from '@equinor/eds-core-react';
2
+ import { getSortedRowModel, getCoreRowModel, getExpandedRowModel, getFacetedRowModel, getFacetedUniqueValues, getFacetedMinMaxValues, getFilteredRowModel, getPaginationRowModel, useReactTable } from '@tanstack/react-table';
3
3
  import { useVirtualizer } from '@tanstack/react-virtual';
4
4
  import { forwardRef, useState, useEffect, useMemo, useRef, useCallback } from 'react';
5
5
  import styled from 'styled-components';
@@ -9,7 +9,7 @@ import { TableFooterRow } from './components/TableFooterRow.js';
9
9
  import { TableRow } from './components/TableRow.js';
10
10
  import { addPxSuffixIfInputHasNoPrefix, logDevelopmentWarningOfPropUse } from './utils.js';
11
11
  import { mergeRefs } from '@equinor/eds-utils';
12
- import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
12
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
13
13
 
14
14
  /* eslint-disable @typescript-eslint/no-non-null-assertion */
15
15
  function EdsDataGridInner({
@@ -439,6 +439,7 @@ function EdsDataGridInner({
439
439
  }, footerGroup.id))
440
440
  })]
441
441
  }), externalPaginator ? externalPaginator : enablePagination && /*#__PURE__*/jsx("div", {
442
+ className: "table-pagination",
442
443
  style: {
443
444
  maxWidth: `${table.getTotalSize()}px`
444
445
  },
@@ -4,7 +4,7 @@ import { filter_alt_active, filter_alt } from '@equinor/eds-icons';
4
4
  import { tokens } from '@equinor/eds-tokens';
5
5
  import { Filter } from './Filter.js';
6
6
  import { useTableContext } from '../EdsDataGridContext.js';
7
- import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
7
+ import { jsxs, jsx } from 'react/jsx-runtime';
8
8
 
9
9
  /* istanbul ignore file */
10
10
 
@@ -34,7 +34,7 @@ function FilterWrapper({
34
34
  return value;
35
35
  };
36
36
  const onChange = useCallback(value => column.setFilterValue(value), [column]);
37
- return /*#__PURE__*/jsxs(Fragment, {
37
+ return /*#__PURE__*/jsxs("span", {
38
38
  children: [/*#__PURE__*/jsx(Button, {
39
39
  "aria-haspopup": true,
40
40
  "aria-expanded": open,
@@ -7,6 +7,6 @@ const ResizeInner = styled.div.withConfig({
7
7
  const Resizer = styled.div.withConfig({
8
8
  displayName: "Resizer",
9
9
  componentId: "sc-plcbjs-1"
10
- })(["transform:", ";", "{opacity:", ";}position:absolute;right:0;top:0;height:100%;width:5px;cursor:col-resize;user-select:none;touch-action:none;display:flex;justify-content:flex-end;"], props => props.$columnResizeMode === 'onEnd' ? 'translateX(0px)' : 'none', ResizeInner, props => props.$isResizing ? 1 : 0);
10
+ })(["transform:", ";", "{opacity:", ";}position:absolute;right:0;top:0;height:100%;width:5px;cursor:col-resize;user-select:none;touch-action:none;display:flex;justify-content:flex-end;z-index:1;"], props => props.$columnResizeMode === 'onEnd' ? 'translateX(0px)' : 'none', ResizeInner, props => props.$isResizing ? 1 : 0);
11
11
 
12
12
  export { ResizeInner, Resizer };
@@ -1,5 +1,5 @@
1
1
  import { Icon } from '@equinor/eds-core-react';
2
- import { arrow_up, arrow_down } from '@equinor/eds-icons';
2
+ import { arrow_down, arrow_up } from '@equinor/eds-icons';
3
3
  import { jsx } from 'react/jsx-runtime';
4
4
 
5
5
  const SortIndicator = ({
@@ -5,8 +5,17 @@ import { FilterWrapper } from './FilterWrapper.js';
5
5
  import { SortIndicator } from './SortIndicator.js';
6
6
  import { Resizer, ResizeInner } from './Resizer.js';
7
7
  import { TableCell } from './TableCell.js';
8
- import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
8
+ import styled from 'styled-components';
9
+ import { jsx, jsxs } from 'react/jsx-runtime';
9
10
 
11
+ const SortButton = styled.button.withConfig({
12
+ displayName: "TableHeaderCell__SortButton",
13
+ componentId: "sc-1n0j3v0-0"
14
+ })(["cursor:pointer;height:100%;width:calc(100% - 5px);display:flex;flex-direction:row;align-items:center;background:transparent;border:none;padding-left:var(--eds_table__cell__padding_x,16px);padding-right:var(--eds_table__cell__padding_x,16px);margin:0;outline:none;color:inherit;text-align:left;font:inherit;"]);
15
+ const TableHeaderCellLabel = styled.div.withConfig({
16
+ displayName: "TableHeaderCell__TableHeaderCellLabel",
17
+ componentId: "sc-1n0j3v0-1"
18
+ })(["display:flex;flex-direction:column;"]);
10
19
  const getSortLabel = sorted => {
11
20
  if (sorted) {
12
21
  return `${sorted}ending`;
@@ -20,12 +29,23 @@ function TableHeaderCell({
20
29
  const ctx = useTableContext();
21
30
  const table = ctx.table;
22
31
  const pinned = header.column.getIsPinned();
32
+ const canSort = header.column.getCanSort();
33
+ const canFilter = header.column.getCanFilter();
23
34
  const offset = useMemo(() => {
24
35
  if (!pinned) {
25
36
  return null;
26
37
  }
27
38
  return pinned === 'left' ? header.getStart() : table.getTotalSize() - header.getStart() - header.getSize();
28
39
  }, [pinned, header, table]);
40
+ const tableCellPadding = useMemo(() => {
41
+ if (canSort && canFilter) {
42
+ return '0 var(--eds_table__cell__padding_x, 16px) 0 0';
43
+ }
44
+ if (canSort) {
45
+ return '0';
46
+ }
47
+ return '0 var(--eds_table__cell__padding_x, 16px) 0 var(--eds_table__cell__padding_x, 16px)';
48
+ }, [canSort, canFilter]);
29
49
  return header.isPlaceholder ? /*#__PURE__*/jsx(TableCell, {
30
50
  $sticky: ctx.stickyHeader,
31
51
  $offset: offset,
@@ -41,37 +61,29 @@ function TableHeaderCell({
41
61
  $pinned: pinned,
42
62
  className: ctx.headerClass ? ctx.headerClass(header.column) : '',
43
63
  "aria-sort": getSortLabel(header.column.getIsSorted()),
44
- onClick: header.column.getToggleSortingHandler(),
45
64
  colSpan: header.colSpan,
46
65
  style: {
47
66
  width: header.getSize(),
48
67
  verticalAlign: ctx.enableColumnFiltering ? 'top' : 'middle',
49
- ...(ctx.headerStyle ? ctx.headerStyle(header.column) : {})
68
+ ...(ctx.headerStyle ? ctx.headerStyle(header.column) : {}),
69
+ padding: tableCellPadding
50
70
  },
51
- children: [/*#__PURE__*/jsxs(Fragment, {
52
- children: [/*#__PURE__*/jsx("div", {
53
- style: {
54
- display: 'flex',
55
- flexDirection: 'column'
56
- },
57
- children: /*#__PURE__*/jsx("span", {
58
- className: "table-header-cell-label",
59
- children: flexRender(header.column.columnDef.header, header.getContext())
60
- })
71
+ children: [canSort ? /*#__PURE__*/jsxs(SortButton, {
72
+ tabIndex: -1,
73
+ onClick: header.column.getToggleSortingHandler(),
74
+ "data-testid": `sort-button-${header.id}`,
75
+ children: [/*#__PURE__*/jsx(TableHeaderCellLabel, {
76
+ className: "table-header-cell-label",
77
+ children: flexRender(header.column.columnDef.header, header.getContext())
61
78
  }), !header.column.columnDef.meta?.customFilterInput && /*#__PURE__*/jsx(SortIndicator, {
62
79
  column: header.column
63
- }), header.column.getCanFilter() && !header.column.columnDef.meta?.customFilterInput ?
64
- /*#__PURE__*/
65
- // Supressing this warning - div is not interactive, but prevents propagation of events to avoid unintended sorting
66
- // eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-static-element-interactions
67
- jsx("div", {
68
- onClick: e => e.stopPropagation(),
69
- children: /*#__PURE__*/jsx(FilterWrapper, {
70
- column: header.column
71
- })
72
- }) : null]
73
- }), columnResizeMode && /*#__PURE__*/jsx(Resizer, {
74
- onClick: e => e.stopPropagation(),
80
+ })]
81
+ }) : /*#__PURE__*/jsx(TableHeaderCellLabel, {
82
+ className: "table-header-cell-label",
83
+ children: flexRender(header.column.columnDef.header, header.getContext())
84
+ }), canFilter && !header.column.columnDef.meta?.customFilterInput ? /*#__PURE__*/jsx(FilterWrapper, {
85
+ column: header.column
86
+ }) : null, columnResizeMode && /*#__PURE__*/jsx(Resizer, {
75
87
  onMouseDown: header.getResizeHandler(),
76
88
  onTouchStart: header.getResizeHandler(),
77
89
  $isResizing: header.column.getIsResizing(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@equinor/eds-data-grid-react",
3
- "version": "0.7.6",
3
+ "version": "0.7.7",
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",
@@ -20,53 +20,53 @@
20
20
  "styled-components": ">=5.1"
21
21
  },
22
22
  "dependencies": {
23
- "@tanstack/react-table": "^8.20.6",
24
- "@tanstack/react-virtual": "^3.13.2",
23
+ "@tanstack/react-table": "^8.21.3",
24
+ "@tanstack/react-virtual": "^3.13.6",
25
25
  "@equinor/eds-icons": "^0.22.0",
26
- "@equinor/eds-utils": "^0.8.7",
27
- "@equinor/eds-tokens": "0.9.2"
26
+ "@equinor/eds-tokens": "0.9.2",
27
+ "@equinor/eds-utils": "^0.8.7"
28
28
  },
29
29
  "devDependencies": {
30
30
  "@rollup/plugin-babel": "^6.0.4",
31
- "@rollup/plugin-commonjs": "^28.0.2",
32
- "@rollup/plugin-node-resolve": "^16.0.0",
33
- "@storybook/addon-a11y": "^8.4.7",
34
- "@storybook/addon-actions": "^8.4.7",
35
- "@storybook/addon-docs": "^8.4.7",
36
- "@storybook/addon-essentials": "^8.4.7",
37
- "@storybook/addon-links": "^8.4.7",
38
- "@storybook/blocks": "^8.4.7",
39
- "@storybook/preview-api": "^8.4.7",
40
- "@storybook/react": "^8.4.7",
41
- "@storybook/react-vite": "^8.4.7",
31
+ "@rollup/plugin-commonjs": "^28.0.3",
32
+ "@rollup/plugin-node-resolve": "^16.0.1",
33
+ "@storybook/addon-a11y": "^8.6.12",
34
+ "@storybook/addon-actions": "^8.6.12",
35
+ "@storybook/addon-docs": "^8.6.12",
36
+ "@storybook/addon-essentials": "^8.6.12",
37
+ "@storybook/addon-links": "^8.6.12",
38
+ "@storybook/blocks": "^8.6.12",
39
+ "@storybook/preview-api": "^8.6.12",
40
+ "@storybook/react": "^8.6.12",
41
+ "@storybook/react-vite": "^8.6.12",
42
42
  "@testing-library/dom": "^10.4.0",
43
43
  "@testing-library/jest-dom": "^6.6.3",
44
44
  "@testing-library/react": "16.3.0",
45
- "@testing-library/user-event": "^14.5.2",
45
+ "@testing-library/user-event": "^14.6.1",
46
46
  "@types/jest": "^29.5.14",
47
- "@types/node": "^22.13.14",
47
+ "@types/node": "^22.15.3",
48
48
  "@types/ramda": "^0.30.2",
49
- "@types/react": "^18.3.3",
50
- "@types/react-dom": "^18.3.0",
49
+ "@types/react": "^18.3.20",
50
+ "@types/react-dom": "^18.3.6",
51
51
  "babel-plugin-styled-components": "^2.1.4",
52
52
  "jest": "29.7.0",
53
53
  "jest-environment-jsdom": "29.7.0",
54
54
  "jest-styled-components": "^7.2.0",
55
55
  "js-file-download": "^0.4.12",
56
- "postcss": "^8.4.49",
56
+ "postcss": "^8.5.3",
57
57
  "ramda": "^0.30.1",
58
58
  "react": "^18.3.1",
59
59
  "react-dom": "^18.3.1",
60
- "react-hook-form": "^7.54.2",
61
- "rollup": "^4.29.1",
62
- "rollup-plugin-delete": "^2.1.0",
60
+ "react-hook-form": "^7.56.1",
61
+ "rollup": "^4.40.1",
62
+ "rollup-plugin-delete": "^2.2.0",
63
63
  "rollup-plugin-postcss": "^4.0.2",
64
- "storybook": "^8.4.7",
64
+ "storybook": "^8.6.12",
65
65
  "styled-components": "6.1.17",
66
- "ts-jest": "29.2.5",
66
+ "ts-jest": "29.3.1",
67
67
  "ts-node": "10.9.2",
68
68
  "tsc-watch": "^6.2.1",
69
- "typescript": "~5.8.2"
69
+ "typescript": "~5.8.3"
70
70
  },
71
71
  "homepage": "https://eds.equinor.com",
72
72
  "repository": {