@navikt/ds-react 8.10.6 → 8.11.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.
Files changed (209) hide show
  1. package/cjs/data/drag-and-drop/root/DragAndDropRoot.d.ts +1 -1
  2. package/cjs/data/drag-and-drop/root/DragAndDropRoot.js +2 -2
  3. package/cjs/data/drag-and-drop/root/DragAndDropRoot.js.map +1 -1
  4. package/cjs/data/stories/Data.test-data.d.ts +2 -2
  5. package/cjs/data/stories/Data.test-data.js +37 -42
  6. package/cjs/data/stories/Data.test-data.js.map +1 -1
  7. package/cjs/data/table/base-cell/DataTableBaseCell.d.ts +4 -4
  8. package/cjs/data/table/base-cell/DataTableBaseCell.js +2 -2
  9. package/cjs/data/table/base-cell/DataTableBaseCell.js.map +1 -1
  10. package/cjs/data/table/column-header/DataTableColumnHeader.d.ts +3 -15
  11. package/cjs/data/table/column-header/DataTableColumnHeader.js +8 -5
  12. package/cjs/data/table/column-header/DataTableColumnHeader.js.map +1 -1
  13. package/cjs/data/table/column-header/useTableColumnResize.d.ts +2 -2
  14. package/cjs/data/table/column-header/useTableColumnResize.js +10 -10
  15. package/cjs/data/table/column-header/useTableColumnResize.js.map +1 -1
  16. package/cjs/data/table/helpers/collectTableRowEntries.d.ts +1 -1
  17. package/cjs/data/table/helpers/selection/getMultipleSelectProps.d.ts +6 -5
  18. package/cjs/data/table/helpers/selection/getMultipleSelectProps.js +6 -2
  19. package/cjs/data/table/helpers/selection/getMultipleSelectProps.js.map +1 -1
  20. package/cjs/data/table/helpers/selection/getSingleSelectProps.d.ts +3 -3
  21. package/cjs/data/table/helpers/selection/getSingleSelectProps.js +1 -1
  22. package/cjs/data/table/helpers/selection/getSingleSelectProps.js.map +1 -1
  23. package/cjs/data/table/helpers/selection/selection.types.d.ts +19 -27
  24. package/cjs/data/table/helpers/selection/selection.utils.d.ts +1 -1
  25. package/cjs/data/table/hooks/useColumnOptions.d.ts +3 -3
  26. package/cjs/data/table/hooks/useColumnOptions.js +2 -2
  27. package/cjs/data/table/hooks/useColumnOptions.js.map +1 -1
  28. package/cjs/data/table/hooks/useTableDetailsPanel.d.ts +8 -9
  29. package/cjs/data/table/hooks/useTableDetailsPanel.js.map +1 -1
  30. package/cjs/data/table/hooks/useTableItems.d.ts +10 -11
  31. package/cjs/data/table/hooks/useTableItems.js +11 -3
  32. package/cjs/data/table/hooks/useTableItems.js.map +1 -1
  33. package/cjs/data/table/hooks/useTableSelection.d.ts +2 -1
  34. package/cjs/data/table/hooks/useTableSelection.js +46 -29
  35. package/cjs/data/table/hooks/useTableSelection.js.map +1 -1
  36. package/cjs/data/table/hooks/useTableSort.d.ts +13 -7
  37. package/cjs/data/table/hooks/useTableSort.js +8 -9
  38. package/cjs/data/table/hooks/useTableSort.js.map +1 -1
  39. package/cjs/data/table/index.d.ts +1 -1
  40. package/cjs/data/table/index.js +3 -23
  41. package/cjs/data/table/index.js.map +1 -1
  42. package/cjs/data/table/root/{DataTable.types.d.ts → DataGridTable.types.d.ts} +16 -26
  43. package/cjs/data/table/root/DataGridTable.types.js +3 -0
  44. package/cjs/data/table/root/DataGridTable.types.js.map +1 -0
  45. package/cjs/data/table/root/DataGridTableRoot.d.ts +104 -0
  46. package/cjs/data/table/root/{DataTableRoot.js → DataGridTableRoot.js} +57 -37
  47. package/cjs/data/table/root/DataGridTableRoot.js.map +1 -0
  48. package/cjs/data/table/root/DataTableRoot.context.d.ts +6 -2
  49. package/cjs/data/table/root/DataTableRoot.context.js.map +1 -1
  50. package/cjs/data/table/tbody/DataTableTbody.js +3 -3
  51. package/cjs/data/table/tbody/DataTableTbody.js.map +1 -1
  52. package/cjs/data/table/tr/DataTableTr.d.ts +3 -3
  53. package/cjs/data/table/tr/DataTableTr.js +44 -20
  54. package/cjs/data/table/tr/DataTableTr.js.map +1 -1
  55. package/cjs/data/token-filter/TokenFilter.d.ts +0 -6
  56. package/cjs/data/token-filter/TokenFilter.js +1 -1
  57. package/cjs/data-grid/index.d.ts +2 -0
  58. package/cjs/data-grid/index.js +9 -0
  59. package/cjs/data-grid/index.js.map +1 -0
  60. package/cjs/data-grid/root/DataGrid.types.d.ts +35 -0
  61. package/cjs/{data/table/root/DataTable.types.js → data-grid/root/DataGrid.types.js} +1 -1
  62. package/cjs/data-grid/root/DataGrid.types.js.map +1 -0
  63. package/cjs/data-grid/root/DataGridRoot.context.d.ts +16 -0
  64. package/cjs/{data/data-grid → data-grid}/root/DataGridRoot.context.js +1 -1
  65. package/cjs/data-grid/root/DataGridRoot.context.js.map +1 -0
  66. package/cjs/data-grid/root/DataGridRoot.d.ts +89 -0
  67. package/cjs/{data/data-grid → data-grid}/root/DataGridRoot.js +33 -8
  68. package/cjs/data-grid/root/DataGridRoot.js.map +1 -0
  69. package/cjs/preview.d.ts +1 -0
  70. package/cjs/{data/data-grid/index.js → preview.js} +3 -3
  71. package/cjs/preview.js.map +1 -0
  72. package/cjs/table/ColumnHeader.js.map +1 -1
  73. package/esm/data/drag-and-drop/root/DragAndDropRoot.d.ts +1 -1
  74. package/esm/data/drag-and-drop/root/DragAndDropRoot.js +2 -2
  75. package/esm/data/drag-and-drop/root/DragAndDropRoot.js.map +1 -1
  76. package/esm/data/stories/Data.test-data.d.ts +2 -2
  77. package/esm/data/stories/Data.test-data.js +37 -42
  78. package/esm/data/stories/Data.test-data.js.map +1 -1
  79. package/esm/data/table/base-cell/DataTableBaseCell.d.ts +4 -4
  80. package/esm/data/table/base-cell/DataTableBaseCell.js +2 -2
  81. package/esm/data/table/base-cell/DataTableBaseCell.js.map +1 -1
  82. package/esm/data/table/column-header/DataTableColumnHeader.d.ts +3 -15
  83. package/esm/data/table/column-header/DataTableColumnHeader.js +8 -5
  84. package/esm/data/table/column-header/DataTableColumnHeader.js.map +1 -1
  85. package/esm/data/table/column-header/useTableColumnResize.d.ts +2 -2
  86. package/esm/data/table/column-header/useTableColumnResize.js +10 -10
  87. package/esm/data/table/column-header/useTableColumnResize.js.map +1 -1
  88. package/esm/data/table/helpers/collectTableRowEntries.d.ts +1 -1
  89. package/esm/data/table/helpers/selection/getMultipleSelectProps.d.ts +6 -5
  90. package/esm/data/table/helpers/selection/getMultipleSelectProps.js +6 -2
  91. package/esm/data/table/helpers/selection/getMultipleSelectProps.js.map +1 -1
  92. package/esm/data/table/helpers/selection/getSingleSelectProps.d.ts +3 -3
  93. package/esm/data/table/helpers/selection/getSingleSelectProps.js +1 -1
  94. package/esm/data/table/helpers/selection/getSingleSelectProps.js.map +1 -1
  95. package/esm/data/table/helpers/selection/selection.types.d.ts +19 -27
  96. package/esm/data/table/helpers/selection/selection.utils.d.ts +1 -1
  97. package/esm/data/table/hooks/useColumnOptions.d.ts +3 -3
  98. package/esm/data/table/hooks/useColumnOptions.js +2 -2
  99. package/esm/data/table/hooks/useColumnOptions.js.map +1 -1
  100. package/esm/data/table/hooks/useTableDetailsPanel.d.ts +8 -9
  101. package/esm/data/table/hooks/useTableDetailsPanel.js.map +1 -1
  102. package/esm/data/table/hooks/useTableItems.d.ts +10 -11
  103. package/esm/data/table/hooks/useTableItems.js +11 -3
  104. package/esm/data/table/hooks/useTableItems.js.map +1 -1
  105. package/esm/data/table/hooks/useTableSelection.d.ts +2 -1
  106. package/esm/data/table/hooks/useTableSelection.js +46 -29
  107. package/esm/data/table/hooks/useTableSelection.js.map +1 -1
  108. package/esm/data/table/hooks/useTableSort.d.ts +13 -7
  109. package/esm/data/table/hooks/useTableSort.js +9 -10
  110. package/esm/data/table/hooks/useTableSort.js.map +1 -1
  111. package/esm/data/table/index.d.ts +1 -1
  112. package/esm/data/table/index.js +1 -21
  113. package/esm/data/table/index.js.map +1 -1
  114. package/esm/data/table/root/{DataTable.types.d.ts → DataGridTable.types.d.ts} +16 -26
  115. package/esm/data/table/root/DataGridTable.types.js +2 -0
  116. package/esm/data/table/root/DataGridTable.types.js.map +1 -0
  117. package/esm/data/table/root/DataGridTableRoot.d.ts +104 -0
  118. package/esm/data/table/root/{DataTableRoot.js → DataGridTableRoot.js} +59 -38
  119. package/esm/data/table/root/DataGridTableRoot.js.map +1 -0
  120. package/esm/data/table/root/DataTableRoot.context.d.ts +6 -2
  121. package/esm/data/table/root/DataTableRoot.context.js.map +1 -1
  122. package/esm/data/table/tbody/DataTableTbody.js +3 -3
  123. package/esm/data/table/tbody/DataTableTbody.js.map +1 -1
  124. package/esm/data/table/tr/DataTableTr.d.ts +3 -3
  125. package/esm/data/table/tr/DataTableTr.js +44 -20
  126. package/esm/data/table/tr/DataTableTr.js.map +1 -1
  127. package/esm/data/token-filter/TokenFilter.d.ts +0 -6
  128. package/esm/data/token-filter/TokenFilter.js +1 -1
  129. package/esm/data-grid/index.d.ts +2 -0
  130. package/esm/data-grid/index.js +4 -0
  131. package/esm/data-grid/index.js.map +1 -0
  132. package/esm/data-grid/root/DataGrid.types.d.ts +35 -0
  133. package/esm/data-grid/root/DataGrid.types.js +2 -0
  134. package/esm/data-grid/root/DataGrid.types.js.map +1 -0
  135. package/esm/data-grid/root/DataGridRoot.context.d.ts +16 -0
  136. package/esm/{data/data-grid → data-grid}/root/DataGridRoot.context.js +1 -1
  137. package/esm/data-grid/root/DataGridRoot.context.js.map +1 -0
  138. package/esm/data-grid/root/DataGridRoot.d.ts +89 -0
  139. package/esm/data-grid/root/DataGridRoot.js +57 -0
  140. package/esm/data-grid/root/DataGridRoot.js.map +1 -0
  141. package/esm/preview.d.ts +1 -0
  142. package/esm/preview.js +3 -0
  143. package/esm/preview.js.map +1 -0
  144. package/esm/table/ColumnHeader.js.map +1 -1
  145. package/package.json +23 -3
  146. package/src/data/drag-and-drop/root/DragAndDropRoot.tsx +3 -3
  147. package/src/data/stories/Data.test-data.tsx +53 -51
  148. package/src/data/table/base-cell/DataTableBaseCell.tsx +6 -6
  149. package/src/data/table/column-header/DataTableColumnHeader.tsx +17 -20
  150. package/src/data/table/column-header/useTableColumnResize.ts +14 -14
  151. package/src/data/table/helpers/collectTableRowEntries.ts +1 -1
  152. package/src/data/table/helpers/selection/getMultipleSelectProps.ts +11 -5
  153. package/src/data/table/helpers/selection/getSingleSelectProps.ts +4 -4
  154. package/src/data/table/helpers/selection/selection.types.ts +19 -29
  155. package/src/data/table/helpers/selection/selection.utils.test.ts +1 -1
  156. package/src/data/table/helpers/selection/selection.utils.ts +1 -1
  157. package/src/data/table/hooks/__tests__/useTableItems.test.ts +1 -1
  158. package/src/data/table/hooks/useColumnOptions.ts +5 -5
  159. package/src/data/table/hooks/useTableDetailsPanel.tsx +14 -18
  160. package/src/data/table/hooks/useTableItems.ts +37 -23
  161. package/src/data/table/hooks/useTableSelection.ts +62 -45
  162. package/src/data/table/hooks/useTableSort.ts +29 -17
  163. package/src/data/table/index.tsx +4 -21
  164. package/src/data/table/root/{DataTable.types.ts → DataGridTable.types.ts} +17 -30
  165. package/src/data/table/root/{DataTableRoot.tsx → DataGridTableRoot.tsx} +196 -143
  166. package/src/data/table/root/DataTableRoot.context.ts +10 -8
  167. package/src/data/table/sub-row-toggle/DataTableSubRowToggle.tsx +1 -1
  168. package/src/data/table/tbody/DataTableTbody.tsx +3 -3
  169. package/src/data/table/tr/DataTableTr.tsx +51 -16
  170. package/src/data/token-filter/TokenFilter.tsx +1 -1
  171. package/src/data-grid/index.ts +3 -0
  172. package/src/data-grid/root/DataGrid.types.ts +36 -0
  173. package/src/data-grid/root/DataGridRoot.context.ts +21 -0
  174. package/src/data-grid/root/DataGridRoot.tsx +152 -0
  175. package/src/preview.ts +2 -0
  176. package/src/table/ColumnHeader.tsx +1 -0
  177. package/cjs/data/data-grid/index.d.ts +0 -2
  178. package/cjs/data/data-grid/index.js.map +0 -1
  179. package/cjs/data/data-grid/root/DataGridRoot.context.d.ts +0 -11
  180. package/cjs/data/data-grid/root/DataGridRoot.context.js.map +0 -1
  181. package/cjs/data/data-grid/root/DataGridRoot.d.ts +0 -38
  182. package/cjs/data/data-grid/root/DataGridRoot.js.map +0 -1
  183. package/cjs/data/table/root/DataTable.types.js.map +0 -1
  184. package/cjs/data/table/root/DataTableRoot.d.ts +0 -118
  185. package/cjs/data/table/root/DataTableRoot.js.map +0 -1
  186. package/cjs/data/table/root/DataTableRoot.legacy.d.ts +0 -172
  187. package/cjs/data/table/root/DataTableRoot.legacy.js +0 -118
  188. package/cjs/data/table/root/DataTableRoot.legacy.js.map +0 -1
  189. package/esm/data/data-grid/index.d.ts +0 -2
  190. package/esm/data/data-grid/index.js +0 -3
  191. package/esm/data/data-grid/index.js.map +0 -1
  192. package/esm/data/data-grid/root/DataGridRoot.context.d.ts +0 -11
  193. package/esm/data/data-grid/root/DataGridRoot.context.js.map +0 -1
  194. package/esm/data/data-grid/root/DataGridRoot.d.ts +0 -38
  195. package/esm/data/data-grid/root/DataGridRoot.js +0 -32
  196. package/esm/data/data-grid/root/DataGridRoot.js.map +0 -1
  197. package/esm/data/table/root/DataTable.types.js +0 -2
  198. package/esm/data/table/root/DataTable.types.js.map +0 -1
  199. package/esm/data/table/root/DataTableRoot.d.ts +0 -118
  200. package/esm/data/table/root/DataTableRoot.js.map +0 -1
  201. package/esm/data/table/root/DataTableRoot.legacy.d.ts +0 -172
  202. package/esm/data/table/root/DataTableRoot.legacy.js +0 -73
  203. package/esm/data/table/root/DataTableRoot.legacy.js.map +0 -1
  204. package/src/data/data-grid/index.ts +0 -3
  205. package/src/data/data-grid/root/DataGridRoot.context.ts +0 -16
  206. package/src/data/data-grid/root/DataGridRoot.tsx +0 -71
  207. package/src/data/table/Readme.md +0 -11
  208. package/src/data/table/agent-component-review.md +0 -175
  209. package/src/data/table/root/DataTableRoot.legacy.tsx +0 -305
@@ -1,20 +1,22 @@
1
1
  import React, {
2
2
  forwardRef,
3
+ memo,
3
4
  useCallback,
4
5
  useEffect,
5
6
  useRef,
6
7
  useState,
7
8
  } from "react";
9
+ import { useDataGridContext } from "../../../data-grid/root/DataGridRoot.context";
8
10
  import { Skeleton } from "../../../skeleton";
9
11
  import { useId } from "../../../utils-external";
10
12
  import { Slot } from "../../../utils/components/slot/Slot";
11
13
  import { cl } from "../../../utils/helpers";
12
14
  import { useMergeRefs } from "../../../utils/hooks";
13
- import { useDataGridContext } from "../../data-grid/root/DataGridRoot.context";
14
15
  import { DataTableBaseCell } from "../base-cell/DataTableBaseCell";
15
16
  import { DataTableColumnHeader } from "../column-header/DataTableColumnHeader";
16
17
  import { DataTableDetailsPanelRow } from "../details-panel-row/DataTableDetailsPanelRow";
17
18
  import { DataTableEmptyState } from "../empty-state/DataTableEmptyState";
19
+ import type { ItemDetail } from "../helpers/collectTableRowEntries";
18
20
  import { useColumnOptions } from "../hooks/useColumnOptions";
19
21
  import {
20
22
  DataTableDetailsPanelProvider,
@@ -22,26 +24,20 @@ import {
22
24
  } from "../hooks/useTableDetailsPanel";
23
25
  import { type SubRowsProps, useTableItems } from "../hooks/useTableItems";
24
26
  import { useTableKeyboardNav } from "../hooks/useTableKeyboardNav";
25
- import {
26
- type SelectionProps,
27
- useTableSelection,
28
- } from "../hooks/useTableSelection";
27
+ import { useTableSelection } from "../hooks/useTableSelection";
29
28
  import { type TableSortOptions, useTableSort } from "../hooks/useTableSort";
30
29
  import { DataTableLoadingState } from "../loading-state/DataTableLoadingState";
31
30
  import { DataTableSubRowToggle } from "../sub-row-toggle/DataTableSubRowToggle";
32
31
  import { DataTableTbody } from "../tbody/DataTableTbody";
33
32
  import { DataTableThead } from "../thead/DataTableThead";
34
33
  import { DataTableTr } from "../tr/DataTableTr";
35
- import type {
36
- DataTableLoadingConfig,
37
- TableRowEntryId,
38
- } from "./DataTable.types";
34
+ import type { DataTableLoadingConfig } from "./DataGridTable.types";
39
35
  import {
40
36
  DataTableContextProvider,
41
37
  useDataTableContext,
42
38
  } from "./DataTableRoot.context";
43
39
 
44
- /**
40
+ /*
45
41
  * TODO: For consideration:
46
42
  * - Use namespacing for types. There will be a lot of standalone types connected to this component,
47
43
  * it could make sense to access them under DataTable.X instead of separate imports.
@@ -50,35 +46,12 @@ import {
50
46
  * This would make props more focused and discoverable since its not mixed with htmltable-props.
51
47
  */
52
48
 
53
- /**
49
+ /*
54
50
  * TODO:
55
51
  * - Test `onColumnDefinitionChange` callback that is called when resize, sort, order etc changes
56
52
  */
57
- interface DataTableProps<T> extends React.HTMLAttributes<HTMLTableElement> {
53
+ interface DataGridTableProps<T> extends React.HTMLAttributes<HTMLTableElement> {
58
54
  children?: never;
59
- /**
60
- * Controls vertical cell padding.
61
- * @default "normal"
62
- */
63
- rowDensity?: "condensed" | "normal" | "spacious";
64
- /**
65
- * Zebra striped table
66
- * @default false
67
- */
68
- zebraStripes?: boolean;
69
- /**
70
- * Truncate content in cells and show ellipsis for overflowed text.
71
- *
72
- * **NB:** When using this together with `layout="auto"`,
73
- * you have to manually set a `maxWidth` on columns that should be truncated.
74
- * @default false if layout="auto", else true
75
- */
76
- truncateContent?: boolean;
77
- /**
78
- * Enables keyboard navigation for table rows and cells.
79
- * @default true
80
- */
81
- withKeyboardNav?: boolean;
82
55
  /**
83
56
  * Controls table layout.
84
57
  *
@@ -95,29 +68,45 @@ interface DataTableProps<T> extends React.HTMLAttributes<HTMLTableElement> {
95
68
  */
96
69
  layout?: "fixed" | "auto";
97
70
  /**
98
- * Sticky columns that remain visible when horizontally scrolling the table.
71
+ * Whether the header should be sticky.
72
+ * For this to work, you have to put the component in a flex container with a height restriction.
73
+ *
74
+ * @example
75
+ * <VStack height="100vh">
76
+ * <div>Content before DataGrid</div>
77
+ * <DataGrid>
78
+ * <DataGrid.Table />
79
+ * </DataGrid>
80
+ * <div>Content after DataGrid</div>
81
+ * </VStack>
82
+ *
83
+ * @example
84
+ * <div style={{ display: "flex", maxHeight: "500px" }}>
85
+ * <DataGrid>
86
+ * <DataGrid.Table />
87
+ * </DataGrid>
88
+ * </div>
99
89
  *
100
- * You can specify 1 sticky column on the left and 1 on the right.
101
- */
102
- stickyColumns?: {
103
- start?: "1";
104
- end?: "1";
105
- };
106
- /**
107
90
  * @default true
108
91
  */
109
92
  stickyHeader?: boolean;
110
93
  /**
111
- * Callback invoked when a data row is clicked.
112
- * Not called when clicking header, loading, or empty-state rows.
94
+ * Callback invoked when a row in the table body is clicked.
95
+ *
96
+ * Call `event.preventDefault()` inside the callback to prevent the default row click behavior, such as selection.
113
97
  */
114
- onRowClick?: (
115
- rowId: TableRowEntryId,
116
- event: React.MouseEvent<HTMLTableRowElement>,
117
- ) => void;
98
+ onRowAction?: ({
99
+ row,
100
+ id,
101
+ event,
102
+ }: {
103
+ row: T;
104
+ id: string;
105
+ event: React.MouseEvent<HTMLTableRowElement>;
106
+ }) => void;
118
107
  /**
119
108
  * Content to render when `data` is empty.
120
- * Rendered inside a `DataTable.EmptyState` row spanning all columns.
109
+ * Rendered inside a row spanning all columns.
121
110
  */
122
111
  emptyContent?: React.ReactNode;
123
112
  /**
@@ -127,17 +116,10 @@ interface DataTableProps<T> extends React.HTMLAttributes<HTMLTableElement> {
127
116
  * - `"content"` — renders custom content inside a full-width row.
128
117
  * - `"skeleton"` — renders skeleton placeholder rows.
129
118
  * - `"overlay"` — keeps existing data visible with a loading overlay.
119
+ *
120
+ * @default { variant: "skeleton", rows: 5 }
130
121
  */
131
- loading?: DataTableLoadingConfig;
132
- /**
133
- * Adjusts font-size
134
- * @default "medium"
135
- */
136
- textSize?: "small" | "medium";
137
- /**
138
- * Object with props related to row selection.
139
- */
140
- selection?: SelectionProps<T>;
122
+ loadingContent?: DataTableLoadingConfig;
141
123
  /**
142
124
  * Object with props related to nested rows (sub-rows).
143
125
  */
@@ -151,33 +133,46 @@ interface DataTableProps<T> extends React.HTMLAttributes<HTMLTableElement> {
151
133
  * Object with props related to sorting.
152
134
  */
153
135
  sorting?: TableSortOptions;
136
+ /**
137
+ * Determines if selection is triggered by clicking the row or the selection control (checkbox/radio).
138
+ * @default "row"
139
+ */
140
+ selectionTrigger?: "row" | "control";
154
141
  }
155
142
 
156
- const DataTableInternal = forwardRef<HTMLTableElement, DataTableProps<any>>(
143
+ const DataGridTableInternal = forwardRef<
144
+ HTMLTableElement,
145
+ DataGridTableProps<any>
146
+ >(
157
147
  (
158
148
  {
159
149
  className,
160
150
  id,
161
- rowDensity = "normal",
162
- textSize = "medium",
163
- withKeyboardNav = true,
164
- zebraStripes = false,
165
- truncateContent: truncateContentProp,
166
151
  layout = "fixed",
167
- stickyColumns,
168
152
  stickyHeader = true,
169
- onRowClick,
153
+ onRowAction,
170
154
  emptyContent,
171
- selection,
172
- loading,
155
+ loadingContent = {
156
+ variant: "skeleton",
157
+ rows: 5,
158
+ label: "Laster innhold",
159
+ }, // TODO translate label
173
160
  detailsPanel,
174
161
  subRows,
175
162
  sorting,
163
+ selectionTrigger = "row",
176
164
  ...rest
177
- }: DataTableProps<any>, // Have to use <any> for docgen to work
165
+ }: DataGridTableProps<unknown>,
178
166
  forwardedRef,
179
167
  ) => {
180
- const { columnDefinitions, data, getRowId } = useDataGridContext();
168
+ const {
169
+ columnDefinitions,
170
+ data,
171
+ getRowId,
172
+ selection,
173
+ isLoading,
174
+ tableSettings,
175
+ } = useDataGridContext();
181
176
 
182
177
  const sortingState = useTableSort(sorting);
183
178
 
@@ -189,14 +184,15 @@ const DataTableInternal = forwardRef<HTMLTableElement, DataTableProps<any>>(
189
184
 
190
185
  const tableSelectionState = useTableSelection({
191
186
  selection,
187
+ selectionTrigger,
192
188
  tableItems,
193
189
  });
194
190
 
195
191
  const { columns, stickyStart, totalColSpan } = useColumnOptions(
196
192
  columnDefinitions,
197
193
  {
198
- stickyColumns,
199
- hasSelection: tableSelectionState.selection.selectionMode !== "none",
194
+ stickyColumns: tableSettings?.stickyColumns,
195
+ hasSelection: tableSelectionState.selection.mode !== "none",
200
196
  hasDetailsPanel: !!detailsPanel?.getContent,
201
197
  layout,
202
198
  },
@@ -204,35 +200,43 @@ const DataTableInternal = forwardRef<HTMLTableElement, DataTableProps<any>>(
204
200
 
205
201
  const tableId = useId(id);
206
202
 
207
- const truncateContent = truncateContentProp ?? layout !== "auto";
203
+ const truncateContent = tableSettings?.truncateContent ?? layout !== "auto";
208
204
 
209
205
  return (
210
206
  <DataTableContextProvider
211
207
  layout={layout}
212
- withKeyboardNav={withKeyboardNav}
208
+ withKeyboardNav={true}
213
209
  selectionState={tableSelectionState}
214
210
  stickyStart={stickyStart}
215
211
  stickyHeader={stickyHeader}
216
212
  tableId={tableId}
217
- loading={loading}
218
- onRowClick={onRowClick}
213
+ loading={loadingContent}
214
+ onRowAction={onRowAction}
219
215
  columns={columns}
220
216
  totalColSpan={totalColSpan}
221
217
  tableItems={tableItems}
222
218
  sortingState={sortingState}
223
219
  >
224
- <TableElementWrapper enabled={withKeyboardNav}>
220
+ <TableElementWrapper
221
+ enabled={true}
222
+ hasStickyColumns={
223
+ !!(
224
+ tableSettings?.stickyColumns?.start ||
225
+ tableSettings?.stickyColumns?.end
226
+ )
227
+ }
228
+ >
225
229
  <table
226
230
  {...rest}
227
231
  ref={forwardedRef}
228
232
  className={cl("aksel-data-table", className)}
229
- data-zebra-stripes={zebraStripes}
233
+ data-zebra-stripes={tableSettings?.zebraStripes}
230
234
  data-truncate-content={truncateContent}
231
- data-density={rowDensity}
232
- data-text-size={textSize}
235
+ data-density={tableSettings?.rowDensity}
236
+ data-text-size={tableSettings?.textSize}
233
237
  data-layout={layout}
234
- data-loading={loading?.isLoading || undefined}
235
- aria-busy={loading?.isLoading || undefined}
238
+ data-loading={isLoading || undefined}
239
+ aria-busy={isLoading || undefined}
236
240
  >
237
241
  <DataTableDetailsPanelProvider detailsPanel={detailsPanel}>
238
242
  <DataTableThead>
@@ -243,11 +247,11 @@ const DataTableInternal = forwardRef<HTMLTableElement, DataTableProps<any>>(
243
247
  <DataTableColumnHeader
244
248
  id={colDef.id}
245
249
  width={colDef.width}
246
- textAlign={colDef.align ?? "left"}
250
+ align={colDef.align ?? "left"}
247
251
  key={colDef.id}
248
252
  isSticky={isSticky}
249
- sortable={colDef.sortable}
250
- label={colDef.label}
253
+ sortable={colDef.isSortable}
254
+ label={colDef.header}
251
255
  style={
252
256
  stickyLeftOffset
253
257
  ? { left: stickyLeftOffset }
@@ -255,7 +259,7 @@ const DataTableInternal = forwardRef<HTMLTableElement, DataTableProps<any>>(
255
259
  }
256
260
  data-sticky-last={isStickyLast || undefined}
257
261
  >
258
- {colDef.header ?? colDef.label}
262
+ {colDef.headerCell ?? colDef.header}
259
263
  </DataTableColumnHeader>
260
264
  );
261
265
  },
@@ -280,9 +284,11 @@ const DataTableInternal = forwardRef<HTMLTableElement, DataTableProps<any>>(
280
284
  function TableElementWrapper({
281
285
  children,
282
286
  enabled,
287
+ hasStickyColumns,
283
288
  }: {
284
289
  children: React.ReactNode;
285
290
  enabled: boolean;
291
+ hasStickyColumns: boolean;
286
292
  }) {
287
293
  const [applyStickyStyles, setApplyStickyStyles] = useState<boolean>(false);
288
294
 
@@ -319,6 +325,10 @@ function TableElementWrapper({
319
325
 
320
326
  useEffect(
321
327
  function observeAndUpdateStickyStyles() {
328
+ if (!hasStickyColumns) {
329
+ return;
330
+ }
331
+
322
332
  const tableWrapperElement = tableWrapperRef.current;
323
333
 
324
334
  if (!tableWrapperElement) {
@@ -349,7 +359,7 @@ function TableElementWrapper({
349
359
  }
350
360
  };
351
361
  },
352
- [scheduleStickyStylesUpdate],
362
+ [scheduleStickyStylesUpdate, hasStickyColumns],
353
363
  );
354
364
 
355
365
  return (
@@ -374,8 +384,9 @@ interface DataTableTBodyContentProps {
374
384
 
375
385
  function DataTableTBodyContent({ emptyContent }: DataTableTBodyContentProps) {
376
386
  const { columns, loading, totalColSpan, tableItems } = useDataTableContext();
387
+ const { isLoading } = useDataGridContext();
377
388
 
378
- if (loading?.isLoading && loading?.variant === "content") {
389
+ if (isLoading && loading?.variant === "content") {
379
390
  return (
380
391
  <DataTableLoadingState colSpan={totalColSpan}>
381
392
  {loading.content}
@@ -383,9 +394,9 @@ function DataTableTBodyContent({ emptyContent }: DataTableTBodyContentProps) {
383
394
  );
384
395
  }
385
396
 
386
- if (loading?.isLoading && loading?.variant === "skeleton") {
397
+ if (isLoading && loading?.variant === "skeleton") {
387
398
  const rows = loading.rows ?? 5;
388
- const label = loading.label ?? "Laster innhold";
399
+ const label = loading.label ?? "Laster innhold"; // TODO translate
389
400
  return (
390
401
  <>
391
402
  <tr>
@@ -401,7 +412,7 @@ function DataTableTBodyContent({ emptyContent }: DataTableTBodyContentProps) {
401
412
  colDefIndex,
402
413
  ) => (
403
414
  <DataTableBaseCell
404
- textAlign={colDef.align ?? "left"}
415
+ align={colDef.align ?? "left"}
405
416
  key={colDef.id || colDefIndex}
406
417
  as={colDef.isRowHeader ? "th" : "td"}
407
418
  isSticky={isSticky}
@@ -428,12 +439,11 @@ function DataTableTBodyContent({ emptyContent }: DataTableTBodyContentProps) {
428
439
  );
429
440
  }
430
441
 
431
- const renderLoadingAnnouncement =
432
- loading?.isLoading && loading?.variant === "overlay";
442
+ const renderLoadingAnnouncement = isLoading && loading?.variant === "overlay";
433
443
 
434
444
  const overlayLabel =
435
445
  loading?.variant === "overlay"
436
- ? (loading.label ?? "Laster innhold")
446
+ ? (loading.label ?? "Laster innhold") // TODO translate
437
447
  : "Laster innhold";
438
448
 
439
449
  return (
@@ -455,59 +465,102 @@ function DataTableTBodyContent({ emptyContent }: DataTableTBodyContentProps) {
455
465
  return null;
456
466
  }
457
467
 
458
- const hasSubRows = details.children.length > 0;
459
-
460
468
  return (
461
- <React.Fragment key={details.id}>
462
- <DataTableTr rowId={details.id}>
463
- {columns.map(
464
- (
465
- { isSticky, isStickyLast, stickyLeftOffset, colDef },
466
- colDefIndex,
467
- ) => {
468
- const renderNestedToggle = colDefIndex === 0 && hasSubRows;
469
- const renderNestedIndent =
470
- colDefIndex === 0 && (details.level > 0 || hasSubRows);
471
-
472
- const style: React.CSSProperties = {
473
- "--__axc-data-table-nested-depth": details.level,
474
- ...(stickyLeftOffset ? { left: stickyLeftOffset } : {}),
475
- };
476
-
477
- return (
478
- <DataTableBaseCell
479
- textAlign={colDef.align ?? "left"}
480
- key={colDef.id || colDefIndex}
481
- as={colDef.isRowHeader ? "th" : "td"}
482
- isSticky={isSticky}
483
- data-nested={renderNestedIndent || undefined}
484
- data-sticky-last={isStickyLast || undefined}
485
- style={style}
486
- beforeContent={
487
- renderNestedToggle ? (
488
- <DataTableSubRowToggle details={details} />
489
- ) : undefined
490
- }
491
- >
492
- {colDef.cell(rowData)}
493
- </DataTableBaseCell>
494
- );
495
- },
496
- )}
497
- </DataTableTr>
498
- <DataTableDetailsPanelRow rowId={details.id} rowData={rowData} />
499
- </React.Fragment>
469
+ <DataTableDataRow
470
+ key={details.id}
471
+ rowData={rowData}
472
+ details={details}
473
+ columns={columns}
474
+ />
500
475
  );
501
476
  })}
502
477
  </>
503
478
  );
504
479
  }
505
480
 
506
- const DataTable = DataTableInternal as <T>(
507
- props: DataTableProps<T> & React.RefAttributes<HTMLTableElement>,
481
+ interface DataTableDataRowProps {
482
+ rowData: any;
483
+ details: ItemDetail<any>;
484
+ columns: ReturnType<typeof useColumnOptions>["columns"];
485
+ }
486
+
487
+ const DataTableDataRow = memo(
488
+ function DataTableDataRow({
489
+ rowData,
490
+ details,
491
+ columns,
492
+ }: DataTableDataRowProps) {
493
+ const hasSubRows = details.children.length > 0;
494
+
495
+ return (
496
+ <>
497
+ <DataTableTr rowId={details.id}>
498
+ {columns.map(
499
+ (
500
+ { isSticky, isStickyLast, stickyLeftOffset, colDef },
501
+ colDefIndex,
502
+ ) => {
503
+ const renderNestedToggle = colDefIndex === 0 && hasSubRows;
504
+ const renderNestedIndent =
505
+ colDefIndex === 0 && (details.level > 0 || hasSubRows);
506
+
507
+ const style: React.CSSProperties = {
508
+ "--__axc-data-table-nested-depth": details.level,
509
+ ...(stickyLeftOffset ? { left: stickyLeftOffset } : {}),
510
+ };
511
+
512
+ return (
513
+ <DataTableBaseCell
514
+ align={colDef.align ?? "left"}
515
+ key={colDef.id || colDefIndex}
516
+ as={colDef.isRowHeader ? "th" : "td"}
517
+ isSticky={isSticky}
518
+ data-nested={renderNestedIndent || undefined}
519
+ data-sticky-last={isStickyLast || undefined}
520
+ style={style}
521
+ beforeContent={
522
+ renderNestedToggle ? (
523
+ <DataTableSubRowToggle details={details} />
524
+ ) : undefined
525
+ }
526
+ >
527
+ {colDef.bodyCell(rowData)}
528
+ </DataTableBaseCell>
529
+ );
530
+ },
531
+ )}
532
+ </DataTableTr>
533
+ <DataTableDetailsPanelRow rowId={details.id} rowData={rowData} />
534
+ </>
535
+ );
536
+ },
537
+ /* TODO: Might be some better metrics we could use to optimize this */
538
+ (prev, next) =>
539
+ prev.rowData === next.rowData &&
540
+ prev.columns === next.columns &&
541
+ prev.details.id === next.details.id &&
542
+ prev.details.level === next.details.level &&
543
+ prev.details.children.length === next.details.children.length,
544
+ );
545
+
546
+ const DataGridTable = DataGridTableInternal as <RowT>(
547
+ props: DataGridTableProps<RowT> & React.RefAttributes<HTMLTableElement>,
508
548
  ) => React.ReactElement | null;
509
549
 
510
- // docgen doesn't work well with type params, so we let it use DataTableInternal instead
511
- export { DataTable, DataTableInternal };
512
- export type { DataTableProps };
513
- export default DataTable;
550
+ // eslint-disable-next-line @typescript-eslint/no-namespace, import/export
551
+ export namespace DataGridTable {
552
+ export type Props<T = unknown> = DataGridTableProps<T>;
553
+ export type Sorting = TableSortOptions;
554
+ export type SortEntry = import("./DataGridTable.types").SortEntry;
555
+ export type SortChangeDetail =
556
+ import("./DataGridTable.types").SortChangeDetail;
557
+ export type LoadingContent = DataTableLoadingConfig;
558
+ export type SubRows<T = unknown> = SubRowsProps<T>;
559
+ export type DetailsPanel<T = unknown> = DetailsPanelProps<T>;
560
+ }
561
+
562
+ // docgen doesn't work well with type params, so we let it use DataGridTableInternal instead
563
+ // eslint-disable-next-line import/export
564
+ export { DataGridTable, DataGridTableInternal };
565
+ export type { DataGridTableProps };
566
+ export default DataGridTable;
@@ -6,10 +6,7 @@ import type {
6
6
  import type { UseTableItemsReturn } from "../hooks/useTableItems";
7
7
  import type { UseTableSelectionReturn } from "../hooks/useTableSelection";
8
8
  import type { UseTableSortResults } from "../hooks/useTableSort";
9
- import type {
10
- DataTableLoadingConfig,
11
- TableRowEntryId,
12
- } from "./DataTable.types";
9
+ import type { DataTableLoadingConfig } from "./DataGridTable.types";
13
10
 
14
11
  type DataTableContextProps<T> = {
15
12
  layout: "fixed" | "auto";
@@ -19,10 +16,15 @@ type DataTableContextProps<T> = {
19
16
  stickyHeader: boolean;
20
17
  tableId: string;
21
18
  loading: DataTableLoadingConfig | undefined;
22
- onRowClick?: (
23
- rowId: TableRowEntryId,
24
- event: React.MouseEvent<HTMLTableRowElement>,
25
- ) => void;
19
+ onRowAction?: ({
20
+ row,
21
+ id,
22
+ event,
23
+ }: {
24
+ row: T;
25
+ id: string;
26
+ event: React.MouseEvent<HTMLTableRowElement>;
27
+ }) => void;
26
28
  columns: UseColumnOptionsResult<T>["columns"];
27
29
  /**
28
30
  * Used to set exact colspan for detailsPanel, loadingState and emptyState.
@@ -23,7 +23,7 @@ function DataTableSubRowToggle({ details }: { details: ItemDetail<any> }) {
23
23
  tableItems.onExpandedRowIdsChange(details.id);
24
24
  }}
25
25
  aria-expanded={isRowExpanded}
26
- aria-label={isRowExpanded ? "Skjul under-rader" : "Vis under-rader"}
26
+ aria-label={isRowExpanded ? "Skjul under-rader" : "Vis under-rader"} // TODO translate
27
27
  icon={
28
28
  isRowExpanded ? (
29
29
  <ChevronDownIcon aria-hidden />
@@ -1,4 +1,5 @@
1
1
  import React, { forwardRef, version } from "react";
2
+ import { useDataGridContext } from "../../../data-grid/root/DataGridRoot.context";
2
3
  import { cl } from "../../../utils/helpers";
3
4
  import {
4
5
  DataTableLocationProvider,
@@ -11,6 +12,7 @@ const inertValue = parseInt(version.split(".")[0], 10) > 18 ? true : ""; // Supp
11
12
 
12
13
  const DataTableTbody = forwardRef<HTMLTableSectionElement, DataTableTbodyProps>(
13
14
  ({ className, ...rest }, forwardedRef) => {
15
+ const { isLoading } = useDataGridContext();
14
16
  const { loading } = useDataTableContext();
15
17
  return (
16
18
  <DataTableLocationProvider location="tbody">
@@ -20,9 +22,7 @@ const DataTableTbody = forwardRef<HTMLTableSectionElement, DataTableTbodyProps>(
20
22
  className={cl("aksel-data-table__tbody", className)}
21
23
  // @ts-expect-error - inert is not yet recognized by React's type definitions, but we want to use it for better accessibility when showing the loading overlay.
22
24
  inert={
23
- loading?.isLoading && loading.variant === "overlay"
24
- ? inertValue
25
- : false
25
+ isLoading && loading?.variant === "overlay" ? inertValue : false
26
26
  }
27
27
  />
28
28
  </DataTableLocationProvider>