@navikt/ds-react 8.10.3 → 8.10.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/action-menu/ActionMenu.js +1 -1
- package/cjs/action-menu/ActionMenu.js.map +1 -1
- package/cjs/data/stories/Data.test-data.d.ts +24 -0
- package/cjs/data/stories/Data.test-data.js +1616 -0
- package/cjs/data/stories/Data.test-data.js.map +1 -0
- package/cjs/data/table/column-header/DataTableColumnHeader.d.ts +4 -1
- package/cjs/data/table/column-header/DataTableColumnHeader.js +2 -2
- package/cjs/data/table/column-header/DataTableColumnHeader.js.map +1 -1
- package/cjs/data/table/column-header/useTableColumnResize.d.ts +21 -18
- package/cjs/data/table/column-header/useTableColumnResize.js +7 -25
- package/cjs/data/table/column-header/useTableColumnResize.js.map +1 -1
- package/cjs/data/table/details-panel-row/DataTableDetailsPanelRow.d.ts +6 -0
- package/cjs/data/table/details-panel-row/DataTableDetailsPanelRow.js +32 -0
- package/cjs/data/table/details-panel-row/DataTableDetailsPanelRow.js.map +1 -0
- package/cjs/data/table/helpers/collectTableRowEntries.d.ts +4 -4
- package/cjs/data/table/helpers/collectTableRowEntries.js +6 -7
- package/cjs/data/table/helpers/collectTableRowEntries.js.map +1 -1
- package/cjs/data/table/hooks/useColumnOptions.js +18 -5
- package/cjs/data/table/hooks/useColumnOptions.js.map +1 -1
- package/cjs/data/table/hooks/useTableDetailsPanel.d.ts +62 -0
- package/cjs/data/table/hooks/{useTableExpansion.js → useTableDetailsPanel.js} +20 -19
- package/cjs/data/table/hooks/useTableDetailsPanel.js.map +1 -0
- package/cjs/data/table/hooks/useTableItems.d.ts +13 -16
- package/cjs/data/table/hooks/useTableItems.js +9 -8
- package/cjs/data/table/hooks/useTableItems.js.map +1 -1
- package/cjs/data/table/hooks/useTableSelection.d.ts +4 -2
- package/cjs/data/table/hooks/useTableSelection.js +6 -1
- package/cjs/data/table/hooks/useTableSelection.js.map +1 -1
- package/cjs/data/table/index.d.ts +1 -2
- package/cjs/data/table/index.js +22 -12
- package/cjs/data/table/index.js.map +1 -1
- package/cjs/data/table/root/DataTable.types.d.ts +7 -6
- package/cjs/data/table/root/DataTableRoot.context.d.ts +5 -1
- package/cjs/data/table/root/DataTableRoot.context.js.map +1 -1
- package/cjs/data/table/root/DataTableRoot.d.ts +79 -115
- package/cjs/data/table/root/DataTableRoot.js +167 -38
- package/cjs/data/table/root/DataTableRoot.js.map +1 -1
- package/cjs/data/table/root/DataTableRoot.legacy.d.ts +177 -0
- package/cjs/data/table/root/DataTableRoot.legacy.js +104 -0
- package/cjs/data/table/root/DataTableRoot.legacy.js.map +1 -0
- package/cjs/data/table/sub-row-toggle/DataTableSubRowToggle.d.ts +6 -0
- package/cjs/data/table/sub-row-toggle/DataTableSubRowToggle.js +21 -0
- package/cjs/data/table/sub-row-toggle/DataTableSubRowToggle.js.map +1 -0
- package/cjs/data/table/tr/DataTableTr.js +11 -11
- package/cjs/data/table/tr/DataTableTr.js.map +1 -1
- package/cjs/utils/components/dismissablelayer/DismissableLayer.js +1 -1
- package/cjs/utils/components/dismissablelayer/DismissableLayer.js.map +1 -1
- package/cjs/utils/components/floating/Floating.d.ts +16 -1
- package/cjs/utils/components/floating/Floating.js +50 -13
- package/cjs/utils/components/floating/Floating.js.map +1 -1
- package/cjs/utils/components/floating-menu/Menu.js +1 -1
- package/cjs/utils/components/floating-menu/Menu.js.map +1 -1
- package/cjs/utils/helpers/create-strict-context.js +1 -1
- package/cjs/utils/helpers/create-strict-context.js.map +1 -1
- package/cjs/utils/hooks/useControllableState.d.ts +5 -5
- package/cjs/utils/hooks/useControllableState.js.map +1 -1
- package/cjs/utils/hooks/useValueAsRef.js +1 -1
- package/cjs/utils/hooks/useValueAsRef.js.map +1 -1
- package/cjs/utils-external/hooks/useId.js +1 -1
- package/cjs/utils-external/hooks/useId.js.map +1 -1
- package/esm/action-menu/ActionMenu.js +1 -1
- package/esm/action-menu/ActionMenu.js.map +1 -1
- package/esm/data/stories/Data.test-data.d.ts +24 -0
- package/esm/data/stories/Data.test-data.js +1607 -0
- package/esm/data/stories/Data.test-data.js.map +1 -0
- package/esm/data/table/column-header/DataTableColumnHeader.d.ts +4 -1
- package/esm/data/table/column-header/DataTableColumnHeader.js +2 -2
- package/esm/data/table/column-header/DataTableColumnHeader.js.map +1 -1
- package/esm/data/table/column-header/useTableColumnResize.d.ts +21 -18
- package/esm/data/table/column-header/useTableColumnResize.js +7 -25
- package/esm/data/table/column-header/useTableColumnResize.js.map +1 -1
- package/esm/data/table/details-panel-row/DataTableDetailsPanelRow.d.ts +6 -0
- package/esm/data/table/details-panel-row/DataTableDetailsPanelRow.js +27 -0
- package/esm/data/table/details-panel-row/DataTableDetailsPanelRow.js.map +1 -0
- package/esm/data/table/helpers/collectTableRowEntries.d.ts +4 -4
- package/esm/data/table/helpers/collectTableRowEntries.js +6 -7
- package/esm/data/table/helpers/collectTableRowEntries.js.map +1 -1
- package/esm/data/table/hooks/useColumnOptions.js +18 -5
- package/esm/data/table/hooks/useColumnOptions.js.map +1 -1
- package/esm/data/table/hooks/useTableDetailsPanel.d.ts +62 -0
- package/esm/data/table/hooks/{useTableExpansion.js → useTableDetailsPanel.js} +17 -16
- package/esm/data/table/hooks/useTableDetailsPanel.js.map +1 -0
- package/esm/data/table/hooks/useTableItems.d.ts +13 -16
- package/esm/data/table/hooks/useTableItems.js +9 -8
- package/esm/data/table/hooks/useTableItems.js.map +1 -1
- package/esm/data/table/hooks/useTableSelection.d.ts +4 -2
- package/esm/data/table/hooks/useTableSelection.js +6 -1
- package/esm/data/table/hooks/useTableSelection.js.map +1 -1
- package/esm/data/table/index.d.ts +1 -2
- package/esm/data/table/index.js +21 -1
- package/esm/data/table/index.js.map +1 -1
- package/esm/data/table/root/DataTable.types.d.ts +7 -6
- package/esm/data/table/root/DataTableRoot.context.d.ts +5 -1
- package/esm/data/table/root/DataTableRoot.context.js.map +1 -1
- package/esm/data/table/root/DataTableRoot.d.ts +79 -115
- package/esm/data/table/root/DataTableRoot.js +174 -36
- package/esm/data/table/root/DataTableRoot.js.map +1 -1
- package/esm/data/table/root/DataTableRoot.legacy.d.ts +177 -0
- package/esm/data/table/root/DataTableRoot.legacy.js +59 -0
- package/esm/data/table/root/DataTableRoot.legacy.js.map +1 -0
- package/esm/data/table/sub-row-toggle/DataTableSubRowToggle.d.ts +6 -0
- package/esm/data/table/sub-row-toggle/DataTableSubRowToggle.js +16 -0
- package/esm/data/table/sub-row-toggle/DataTableSubRowToggle.js.map +1 -0
- package/esm/data/table/tr/DataTableTr.js +11 -11
- package/esm/data/table/tr/DataTableTr.js.map +1 -1
- package/esm/utils/components/dismissablelayer/DismissableLayer.js +1 -1
- package/esm/utils/components/dismissablelayer/DismissableLayer.js.map +1 -1
- package/esm/utils/components/floating/Floating.d.ts +16 -1
- package/esm/utils/components/floating/Floating.js +48 -13
- package/esm/utils/components/floating/Floating.js.map +1 -1
- package/esm/utils/components/floating-menu/Menu.js +2 -2
- package/esm/utils/components/floating-menu/Menu.js.map +1 -1
- package/esm/utils/helpers/create-strict-context.js +1 -1
- package/esm/utils/helpers/create-strict-context.js.map +1 -1
- package/esm/utils/hooks/useControllableState.d.ts +5 -5
- package/esm/utils/hooks/useControllableState.js.map +1 -1
- package/esm/utils/hooks/useValueAsRef.js +1 -1
- package/esm/utils/hooks/useValueAsRef.js.map +1 -1
- package/esm/utils-external/hooks/useId.js +1 -1
- package/esm/utils-external/hooks/useId.js.map +1 -1
- package/package.json +3 -3
- package/src/action-menu/ActionMenu.tsx +1 -1
- package/src/data/stories/Data.test-data.tsx +1703 -0
- package/src/data/table/column-header/DataTableColumnHeader.tsx +6 -6
- package/src/data/table/column-header/useTableColumnResize.ts +29 -44
- package/src/data/table/details-panel-row/DataTableDetailsPanelRow.tsx +53 -0
- package/src/data/table/helpers/collectTableRowEntries.ts +10 -18
- package/src/data/table/hooks/__tests__/useTableItems.test.ts +14 -7
- package/src/data/table/hooks/__tests__/useTableSelection.test.ts +57 -44
- package/src/data/table/hooks/useColumnOptions.ts +19 -5
- package/src/data/table/hooks/{useTableExpansion.tsx → useTableDetailsPanel.tsx} +81 -45
- package/src/data/table/hooks/useTableItems.ts +27 -36
- package/src/data/table/hooks/useTableSelection.ts +17 -6
- package/src/data/table/index.tsx +5 -3
- package/src/data/table/root/DataTable.types.ts +20 -6
- package/src/data/table/root/DataTableRoot.context.ts +5 -1
- package/src/data/table/root/DataTableRoot.legacy.tsx +297 -0
- package/src/data/table/root/DataTableRoot.tsx +482 -217
- package/src/data/table/sub-row-toggle/DataTableSubRowToggle.tsx +39 -0
- package/src/data/table/tr/DataTableTr.tsx +14 -13
- package/src/utils/components/dismissablelayer/DismissableLayer.tsx +1 -1
- package/src/utils/components/floating/Floating.tsx +56 -13
- package/src/utils/components/floating-menu/Menu.tsx +4 -1
- package/src/utils/helpers/create-strict-context.tsx +1 -1
- package/src/utils/hooks/useControllableState.ts +11 -8
- package/src/utils/hooks/useValueAsRef.ts +1 -1
- package/src/utils-external/hooks/useId.ts +1 -1
- package/cjs/data/table/hooks/useTableExpansion.d.ts +0 -27
- package/cjs/data/table/hooks/useTableExpansion.js.map +0 -1
- package/cjs/data/table/root/DataTableAuto.d.ts +0 -182
- package/cjs/data/table/root/DataTableAuto.js +0 -206
- package/cjs/data/table/root/DataTableAuto.js.map +0 -1
- package/esm/data/table/hooks/useTableExpansion.d.ts +0 -27
- package/esm/data/table/hooks/useTableExpansion.js.map +0 -1
- package/esm/data/table/root/DataTableAuto.d.ts +0 -182
- package/esm/data/table/root/DataTableAuto.js +0 -170
- package/esm/data/table/root/DataTableAuto.js.map +0 -1
- package/src/data/table/root/DataTableAuto.test.tsx +0 -244
- package/src/data/table/root/DataTableAuto.tsx +0 -612
|
@@ -17,11 +17,10 @@ import { type ResizeProps, useTableColumnResize } from "./useTableColumnResize";
|
|
|
17
17
|
|
|
18
18
|
interface DataTableColumnHeaderProps
|
|
19
19
|
extends ResizeProps, DataTableBaseCellProps {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
) => void;
|
|
20
|
+
/**
|
|
21
|
+
* Accessible name of the column.
|
|
22
|
+
*/
|
|
23
|
+
label: string;
|
|
25
24
|
/**
|
|
26
25
|
* Makes the column header sortable. The entire header cell content becomes
|
|
27
26
|
* a clickable button when true.
|
|
@@ -59,6 +58,7 @@ const DataTableColumnHeader = forwardRef<
|
|
|
59
58
|
{
|
|
60
59
|
className,
|
|
61
60
|
children,
|
|
61
|
+
label,
|
|
62
62
|
sortable = false,
|
|
63
63
|
sortDirection = "none",
|
|
64
64
|
onSortClick,
|
|
@@ -144,7 +144,7 @@ const DataTableColumnHeader = forwardRef<
|
|
|
144
144
|
aria-label={
|
|
145
145
|
resizeResult.isResizingWithKeyboard
|
|
146
146
|
? "Bruk pil venstre/høyre"
|
|
147
|
-
:
|
|
147
|
+
: `Endre bredde ${label}`
|
|
148
148
|
} // TODO Translate
|
|
149
149
|
data-active={resizeResult.isResizingWithKeyboard}
|
|
150
150
|
data-disable-keyboard-nav={resizeResult.isResizingWithKeyboard}
|
|
@@ -8,9 +8,8 @@ import {
|
|
|
8
8
|
import { useControllableState } from "../../../utils/hooks";
|
|
9
9
|
import { useDataTableContext } from "../root/DataTableRoot.context";
|
|
10
10
|
|
|
11
|
-
type ColumnWidth = number | string;
|
|
12
|
-
|
|
13
11
|
type ResizeProps = {
|
|
12
|
+
// If/when we add support for composition, consider mentioning that resizing only works on first row in thead.
|
|
14
13
|
/**
|
|
15
14
|
* Whether the column should be resizable by the user.
|
|
16
15
|
*
|
|
@@ -18,16 +17,6 @@ type ResizeProps = {
|
|
|
18
17
|
* @default true
|
|
19
18
|
*/
|
|
20
19
|
resizable?: boolean;
|
|
21
|
-
/**
|
|
22
|
-
* Controlled width of the column.
|
|
23
|
-
*
|
|
24
|
-
* Should only be used to fully control column width state. Otherwise, use `defaultWidth` and let the component handle resizing.
|
|
25
|
-
*/
|
|
26
|
-
width?: ColumnWidth;
|
|
27
|
-
/**
|
|
28
|
-
* Initial width of the column. Only used when `width` is not set and `resizable` is true.
|
|
29
|
-
*/
|
|
30
|
-
defaultWidth?: ColumnWidth;
|
|
31
20
|
/**
|
|
32
21
|
* Whether the column should automatically resize to fit its content. **Runs only once.**
|
|
33
22
|
*
|
|
@@ -40,21 +29,36 @@ type ResizeProps = {
|
|
|
40
29
|
*/
|
|
41
30
|
autoWidth?: boolean;
|
|
42
31
|
/**
|
|
43
|
-
* Minimum width of the column.
|
|
32
|
+
* Minimum width of the column when resizing. Only used when `resizable` or `autoWidth` is enabled.
|
|
33
|
+
* @default 40
|
|
34
|
+
*/
|
|
35
|
+
minWidth?: number;
|
|
36
|
+
/**
|
|
37
|
+
* Maximum width of the column when resizing. Only used when `resizable` or `autoWidth` is enabled.
|
|
38
|
+
*/
|
|
39
|
+
maxWidth?: number;
|
|
40
|
+
// TODO: Consider "allowing" %-width on last column, if we find a solution to the overflow issue (width becomes 0px).
|
|
41
|
+
/**
|
|
42
|
+
* Controlled width of the column. Does not respect `minWidth` and `maxWidth`.
|
|
44
43
|
*
|
|
45
|
-
* Should be used
|
|
44
|
+
* Should only be used to fully control column width state. Otherwise, use `defaultWidth` and let the component handle resizing.
|
|
45
|
+
*
|
|
46
|
+
* **NB:** Percentage as initial width does not work well with resizing.
|
|
46
47
|
*/
|
|
47
|
-
|
|
48
|
+
width?: number | string;
|
|
48
49
|
/**
|
|
49
|
-
*
|
|
50
|
+
* Initial width of the column. Only used when `width` is not set and `resizable` is true.
|
|
51
|
+
* Does not respect `minWidth` and `maxWidth`.
|
|
50
52
|
*
|
|
51
|
-
*
|
|
53
|
+
* **NB:** Percentage as initial width does not work well with resizing.
|
|
54
|
+
* @default 140px
|
|
52
55
|
*/
|
|
53
|
-
|
|
56
|
+
defaultWidth?: number | string;
|
|
54
57
|
/**
|
|
55
58
|
* Called when the column width changes.
|
|
59
|
+
* @param width New width in pixels.
|
|
56
60
|
*/
|
|
57
|
-
onWidthChange?: (width:
|
|
61
|
+
onWidthChange?: (width: number) => void;
|
|
58
62
|
/**
|
|
59
63
|
* Forwarded styles
|
|
60
64
|
*/
|
|
@@ -133,10 +137,7 @@ function useTableColumnResize(
|
|
|
133
137
|
|
|
134
138
|
const setClampedWidth = useCallback(
|
|
135
139
|
(newWidth: number) => {
|
|
136
|
-
|
|
137
|
-
const max = parseWidth(maxWidth) ?? Infinity;
|
|
138
|
-
const clamped = Math.min(Math.max(newWidth, min), max);
|
|
139
|
-
setWidth(clamped);
|
|
140
|
+
setWidth(Math.min(Math.max(newWidth, minWidth), maxWidth));
|
|
140
141
|
},
|
|
141
142
|
[minWidth, maxWidth, setWidth],
|
|
142
143
|
);
|
|
@@ -212,14 +213,11 @@ function useTableColumnResize(
|
|
|
212
213
|
const currentWidth = thRef.current?.offsetWidth ?? 0;
|
|
213
214
|
const newWidth = startWidth + (clientX - startX);
|
|
214
215
|
|
|
215
|
-
|
|
216
|
-
const max = parseWidth(maxWidth) ?? Infinity;
|
|
217
|
-
|
|
218
|
-
if (newWidth > max) {
|
|
216
|
+
if (newWidth > maxWidth) {
|
|
219
217
|
setWidth(newWidth < currentWidth ? newWidth : currentWidth);
|
|
220
218
|
return;
|
|
221
219
|
}
|
|
222
|
-
if (newWidth <
|
|
220
|
+
if (newWidth < minWidth) {
|
|
223
221
|
setWidth(newWidth > currentWidth ? newWidth : currentWidth);
|
|
224
222
|
return;
|
|
225
223
|
}
|
|
@@ -315,20 +313,6 @@ function useTableColumnResize(
|
|
|
315
313
|
};
|
|
316
314
|
}
|
|
317
315
|
|
|
318
|
-
function parseWidth(width: ColumnWidth | undefined): number | undefined {
|
|
319
|
-
if (width == null) {
|
|
320
|
-
return undefined;
|
|
321
|
-
}
|
|
322
|
-
if (typeof width === "number") {
|
|
323
|
-
return width;
|
|
324
|
-
}
|
|
325
|
-
if (typeof width === "string") {
|
|
326
|
-
const parsed = parseInt(width, 10);
|
|
327
|
-
return Number.isNaN(parsed) ? undefined : parsed;
|
|
328
|
-
}
|
|
329
|
-
return undefined;
|
|
330
|
-
}
|
|
331
|
-
|
|
332
316
|
function getAutoColumnWidth(
|
|
333
317
|
thRef: React.RefObject<HTMLTableCellElement | null>,
|
|
334
318
|
) {
|
|
@@ -341,7 +325,9 @@ function getAutoColumnWidth(
|
|
|
341
325
|
}
|
|
342
326
|
|
|
343
327
|
// Find needed width for header cell
|
|
344
|
-
const
|
|
328
|
+
const range = document.createRange();
|
|
329
|
+
range.selectNodeContents(thContent);
|
|
330
|
+
const contentWidth = range.getBoundingClientRect().width;
|
|
345
331
|
const paddingElStyle = window.getComputedStyle(thPaddingEl);
|
|
346
332
|
const thInlinePadding =
|
|
347
333
|
parseInt(paddingElStyle.paddingLeft, 10) +
|
|
@@ -357,7 +343,6 @@ function getAutoColumnWidth(
|
|
|
357
343
|
}
|
|
358
344
|
|
|
359
345
|
// Find needed width for each cell in column in tbody and tfoot
|
|
360
|
-
const range = document.createRange();
|
|
361
346
|
let skipRows = 0;
|
|
362
347
|
for (const row of rows) {
|
|
363
348
|
// Skip rows where the cell in this column is covered by a rowspan from a previous row
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import {
|
|
3
|
+
getDataTableDetailsPanelId,
|
|
4
|
+
useDataTableDetailsPanel,
|
|
5
|
+
} from "../hooks/useTableDetailsPanel";
|
|
6
|
+
import { useDataTableContext } from "../root/DataTableRoot.context";
|
|
7
|
+
|
|
8
|
+
function DataTableDetailsPanelRow<T>({
|
|
9
|
+
rowId,
|
|
10
|
+
rowData,
|
|
11
|
+
}: {
|
|
12
|
+
rowId: string | number;
|
|
13
|
+
rowData: T;
|
|
14
|
+
}) {
|
|
15
|
+
const { tableId, fullWidthColSpan } = useDataTableContext();
|
|
16
|
+
const {
|
|
17
|
+
enableDetailsPanel,
|
|
18
|
+
isExpanded,
|
|
19
|
+
getDetailsPanelContent,
|
|
20
|
+
getDetailsPanelHeight,
|
|
21
|
+
} = useDataTableDetailsPanel();
|
|
22
|
+
|
|
23
|
+
if (!enableDetailsPanel) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (!isExpanded(rowId)) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const content = getDetailsPanelContent?.(rowData);
|
|
32
|
+
const expansionId = getDataTableDetailsPanelId(tableId, rowId);
|
|
33
|
+
|
|
34
|
+
if (!content) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const panelHeight = getDetailsPanelHeight?.(rowData);
|
|
39
|
+
|
|
40
|
+
const style: React.CSSProperties = panelHeight
|
|
41
|
+
? { height: panelHeight, overflow: "auto" }
|
|
42
|
+
: { height: "auto" };
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<tr className="aksel-data-table__details-panel-row">
|
|
46
|
+
<td id={expansionId} colSpan={fullWidthColSpan}>
|
|
47
|
+
<div style={style}>{content}</div>
|
|
48
|
+
</td>
|
|
49
|
+
</tr>
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export { DataTableDetailsPanelRow };
|
|
@@ -2,9 +2,9 @@ type TableRowEntryId = string | number;
|
|
|
2
2
|
|
|
3
3
|
type CollectTableRowEntriesArgs<T> = {
|
|
4
4
|
items: T[];
|
|
5
|
-
getRowId
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
getRowId: (rowData: T, index: number) => TableRowEntryId;
|
|
6
|
+
getRows?: (rowData: T) => T[];
|
|
7
|
+
isRowExpandable?: (rowData: T) => boolean;
|
|
8
8
|
};
|
|
9
9
|
|
|
10
10
|
interface ItemDetail<T> {
|
|
@@ -26,8 +26,8 @@ type CollectTableRowEntriesReturn<T> = {
|
|
|
26
26
|
function collectTableRowEntries<T>({
|
|
27
27
|
items,
|
|
28
28
|
getRowId,
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
getRows,
|
|
30
|
+
isRowExpandable,
|
|
31
31
|
}: CollectTableRowEntriesArgs<T>): CollectTableRowEntriesReturn<T> {
|
|
32
32
|
const itemDetailsMap = new Map<T, ItemDetail<T>>();
|
|
33
33
|
const childRowIdsById = new Map<TableRowEntryId, TableRowEntryId[]>();
|
|
@@ -37,13 +37,11 @@ function collectTableRowEntries<T>({
|
|
|
37
37
|
rowIndex: number,
|
|
38
38
|
level: number,
|
|
39
39
|
parent: T | null,
|
|
40
|
-
parentId?: TableRowEntryId,
|
|
41
40
|
): TableRowEntryId => {
|
|
42
|
-
const rowId =
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
const children = (isRowExpandable ? getSubRows?.(rowData) : []) ?? [];
|
|
41
|
+
const rowId = getRowId(rowData, rowIndex);
|
|
42
|
+
|
|
43
|
+
const children =
|
|
44
|
+
((isRowExpandable?.(rowData) ?? true) ? getRows?.(rowData) : []) ?? [];
|
|
47
45
|
|
|
48
46
|
itemDetailsMap.set(rowData, {
|
|
49
47
|
id: rowId,
|
|
@@ -56,13 +54,7 @@ function collectTableRowEntries<T>({
|
|
|
56
54
|
|
|
57
55
|
for (let childIndex = 0; childIndex < children.length; childIndex++) {
|
|
58
56
|
const childRow = children[childIndex];
|
|
59
|
-
const childRowId = traverseRow(
|
|
60
|
-
childRow,
|
|
61
|
-
childIndex,
|
|
62
|
-
level + 1,
|
|
63
|
-
rowData,
|
|
64
|
-
rowId,
|
|
65
|
-
);
|
|
57
|
+
const childRowId = traverseRow(childRow, childIndex, level + 1, rowData);
|
|
66
58
|
childRowIds.push(childRowId);
|
|
67
59
|
}
|
|
68
60
|
|
|
@@ -78,8 +78,10 @@ describe("useTableItems", () => {
|
|
|
78
78
|
useTableItems({
|
|
79
79
|
items: nestedRows,
|
|
80
80
|
getRowId: (row) => row.id,
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
subRows: {
|
|
82
|
+
getRows: getSubRows,
|
|
83
|
+
defaultExpandedRowIds: ["a"],
|
|
84
|
+
},
|
|
83
85
|
}),
|
|
84
86
|
);
|
|
85
87
|
|
|
@@ -91,7 +93,7 @@ describe("useTableItems", () => {
|
|
|
91
93
|
useTableItems({
|
|
92
94
|
items: nestedRows,
|
|
93
95
|
getRowId: (row) => row.id,
|
|
94
|
-
getSubRows,
|
|
96
|
+
subRows: { getRows: getSubRows },
|
|
95
97
|
}),
|
|
96
98
|
);
|
|
97
99
|
|
|
@@ -104,8 +106,11 @@ describe("useTableItems", () => {
|
|
|
104
106
|
const { result } = renderHook(() =>
|
|
105
107
|
useTableItems({
|
|
106
108
|
items: fallbackRows,
|
|
107
|
-
|
|
108
|
-
|
|
109
|
+
getRowId: (_, index) => index,
|
|
110
|
+
subRows: {
|
|
111
|
+
getRows: (row: any) => row.subRows ?? [],
|
|
112
|
+
defaultExpandedRowIds: [0],
|
|
113
|
+
},
|
|
109
114
|
}),
|
|
110
115
|
);
|
|
111
116
|
|
|
@@ -121,8 +126,10 @@ describe("useTableItems", () => {
|
|
|
121
126
|
useTableItems({
|
|
122
127
|
items: nestedRows,
|
|
123
128
|
getRowId: (row) => row.id,
|
|
124
|
-
|
|
125
|
-
|
|
129
|
+
subRows: {
|
|
130
|
+
getRows: getSubRows,
|
|
131
|
+
expandedRowIds: expandedIds,
|
|
132
|
+
},
|
|
126
133
|
}),
|
|
127
134
|
{
|
|
128
135
|
initialProps: { expandedIds: [] as (string | number)[] },
|
|
@@ -42,7 +42,7 @@ describe("useTableSelection", () => {
|
|
|
42
42
|
test("returns empty selectedKeys and no prop getters", () => {
|
|
43
43
|
const { result } = renderHook(() =>
|
|
44
44
|
useTableSelection({
|
|
45
|
-
selectionMode: "none",
|
|
45
|
+
selection: { selectionMode: "none" },
|
|
46
46
|
visibleRowIds,
|
|
47
47
|
}),
|
|
48
48
|
);
|
|
@@ -56,7 +56,7 @@ describe("useTableSelection", () => {
|
|
|
56
56
|
test("returns getRowRadioProps", () => {
|
|
57
57
|
const { result } = renderHook(() =>
|
|
58
58
|
useTableSelection({
|
|
59
|
-
selectionMode: "single",
|
|
59
|
+
selection: { selectionMode: "single" },
|
|
60
60
|
visibleRowIds,
|
|
61
61
|
}),
|
|
62
62
|
);
|
|
@@ -69,9 +69,8 @@ describe("useTableSelection", () => {
|
|
|
69
69
|
const onChange = vi.fn();
|
|
70
70
|
const { result } = renderHook(() =>
|
|
71
71
|
useTableSelection({
|
|
72
|
-
selectionMode: "single",
|
|
72
|
+
selection: { selectionMode: "single", onSelectionChange: onChange },
|
|
73
73
|
visibleRowIds,
|
|
74
|
-
onSelectionChange: onChange,
|
|
75
74
|
}),
|
|
76
75
|
);
|
|
77
76
|
|
|
@@ -88,9 +87,8 @@ describe("useTableSelection", () => {
|
|
|
88
87
|
test("toggling the same row keeps it selected", () => {
|
|
89
88
|
const { result } = renderHook(() =>
|
|
90
89
|
useTableSelection({
|
|
91
|
-
selectionMode: "single",
|
|
90
|
+
selection: { selectionMode: "single", defaultSelectedKeys: ["a"] },
|
|
92
91
|
visibleRowIds,
|
|
93
|
-
defaultSelectedKeys: ["a"],
|
|
94
92
|
}),
|
|
95
93
|
);
|
|
96
94
|
|
|
@@ -106,9 +104,8 @@ describe("useTableSelection", () => {
|
|
|
106
104
|
test("selecting a new row replaces the previous", () => {
|
|
107
105
|
const { result } = renderHook(() =>
|
|
108
106
|
useTableSelection({
|
|
109
|
-
selectionMode: "single",
|
|
107
|
+
selection: { selectionMode: "single", defaultSelectedKeys: ["a"] },
|
|
110
108
|
visibleRowIds,
|
|
111
|
-
defaultSelectedKeys: ["a"],
|
|
112
109
|
}),
|
|
113
110
|
);
|
|
114
111
|
|
|
@@ -124,9 +121,8 @@ describe("useTableSelection", () => {
|
|
|
124
121
|
test("disabled rows have disabled prop", () => {
|
|
125
122
|
const { result } = renderHook(() =>
|
|
126
123
|
useTableSelection({
|
|
127
|
-
selectionMode: "single",
|
|
124
|
+
selection: { selectionMode: "single", disabledSelectionKeys: ["b"] },
|
|
128
125
|
visibleRowIds,
|
|
129
|
-
disabledSelectionKeys: ["b"],
|
|
130
126
|
}),
|
|
131
127
|
);
|
|
132
128
|
|
|
@@ -138,9 +134,8 @@ describe("useTableSelection", () => {
|
|
|
138
134
|
const { result, rerender } = renderHook(
|
|
139
135
|
({ selectedKeys }) =>
|
|
140
136
|
useTableSelection({
|
|
141
|
-
selectionMode: "single",
|
|
137
|
+
selection: { selectionMode: "single", selectedKeys },
|
|
142
138
|
visibleRowIds,
|
|
143
|
-
selectedKeys,
|
|
144
139
|
}),
|
|
145
140
|
{ initialProps: { selectedKeys: ["a"] as (string | number)[] } },
|
|
146
141
|
);
|
|
@@ -156,7 +151,7 @@ describe("useTableSelection", () => {
|
|
|
156
151
|
test("returns getTheadCheckboxProps and getRowCheckboxProps", () => {
|
|
157
152
|
const { result } = renderHook(() =>
|
|
158
153
|
useTableSelection({
|
|
159
|
-
selectionMode: "multiple",
|
|
154
|
+
selection: { selectionMode: "multiple" },
|
|
160
155
|
visibleRowIds,
|
|
161
156
|
}),
|
|
162
157
|
);
|
|
@@ -169,7 +164,7 @@ describe("useTableSelection", () => {
|
|
|
169
164
|
test("selecting individual rows", () => {
|
|
170
165
|
const { result } = renderHook(() =>
|
|
171
166
|
useTableSelection({
|
|
172
|
-
selectionMode: "multiple",
|
|
167
|
+
selection: { selectionMode: "multiple" },
|
|
173
168
|
visibleRowIds,
|
|
174
169
|
}),
|
|
175
170
|
);
|
|
@@ -194,9 +189,11 @@ describe("useTableSelection", () => {
|
|
|
194
189
|
test("deselecting a row", () => {
|
|
195
190
|
const { result } = renderHook(() =>
|
|
196
191
|
useTableSelection({
|
|
197
|
-
|
|
192
|
+
selection: {
|
|
193
|
+
selectionMode: "multiple",
|
|
194
|
+
defaultSelectedKeys: ["a", "b"],
|
|
195
|
+
},
|
|
198
196
|
visibleRowIds,
|
|
199
|
-
defaultSelectedKeys: ["a", "b"],
|
|
200
197
|
}),
|
|
201
198
|
);
|
|
202
199
|
|
|
@@ -212,7 +209,7 @@ describe("useTableSelection", () => {
|
|
|
212
209
|
test("select all via thead checkbox", () => {
|
|
213
210
|
const { result } = renderHook(() =>
|
|
214
211
|
useTableSelection({
|
|
215
|
-
selectionMode: "multiple",
|
|
212
|
+
selection: { selectionMode: "multiple" },
|
|
216
213
|
visibleRowIds,
|
|
217
214
|
}),
|
|
218
215
|
);
|
|
@@ -229,7 +226,7 @@ describe("useTableSelection", () => {
|
|
|
229
226
|
test("select all via thead includes hidden descendants for visible parents", () => {
|
|
230
227
|
const { result } = renderHook(() =>
|
|
231
228
|
useTableSelection({
|
|
232
|
-
selectionMode: "multiple",
|
|
229
|
+
selection: { selectionMode: "multiple" },
|
|
233
230
|
visibleRowIds: ["a"],
|
|
234
231
|
childRowIdsById,
|
|
235
232
|
}),
|
|
@@ -247,9 +244,11 @@ describe("useTableSelection", () => {
|
|
|
247
244
|
test("deselect all when all are selected", () => {
|
|
248
245
|
const { result } = renderHook(() =>
|
|
249
246
|
useTableSelection({
|
|
250
|
-
|
|
247
|
+
selection: {
|
|
248
|
+
selectionMode: "multiple",
|
|
249
|
+
defaultSelectedKeys: ["a", "b", "c"],
|
|
250
|
+
},
|
|
251
251
|
visibleRowIds,
|
|
252
|
-
defaultSelectedKeys: ["a", "b", "c"],
|
|
253
252
|
}),
|
|
254
253
|
);
|
|
255
254
|
|
|
@@ -265,10 +264,12 @@ describe("useTableSelection", () => {
|
|
|
265
264
|
test("deselect all clears hidden descendants for visible parents but preserves unrelated keys", () => {
|
|
266
265
|
const { result } = renderHook(() =>
|
|
267
266
|
useTableSelection({
|
|
268
|
-
|
|
267
|
+
selection: {
|
|
268
|
+
selectionMode: "multiple",
|
|
269
|
+
defaultSelectedKeys: ["a", "a1", "a2", "a2a", "external"],
|
|
270
|
+
},
|
|
269
271
|
visibleRowIds: ["a"],
|
|
270
272
|
childRowIdsById,
|
|
271
|
-
defaultSelectedKeys: ["a", "a1", "a2", "a2a", "external"],
|
|
272
273
|
}),
|
|
273
274
|
);
|
|
274
275
|
|
|
@@ -284,9 +285,11 @@ describe("useTableSelection", () => {
|
|
|
284
285
|
test("select all skips disabled keys", () => {
|
|
285
286
|
const { result } = renderHook(() =>
|
|
286
287
|
useTableSelection({
|
|
287
|
-
|
|
288
|
+
selection: {
|
|
289
|
+
selectionMode: "multiple",
|
|
290
|
+
disabledSelectionKeys: ["b"],
|
|
291
|
+
},
|
|
288
292
|
visibleRowIds,
|
|
289
|
-
disabledSelectionKeys: ["b"],
|
|
290
293
|
}),
|
|
291
294
|
);
|
|
292
295
|
|
|
@@ -302,10 +305,12 @@ describe("useTableSelection", () => {
|
|
|
302
305
|
test("deselect all preserves disabled-but-selected rows", () => {
|
|
303
306
|
const { result } = renderHook(() =>
|
|
304
307
|
useTableSelection({
|
|
305
|
-
|
|
308
|
+
selection: {
|
|
309
|
+
selectionMode: "multiple",
|
|
310
|
+
defaultSelectedKeys: ["a", "b", "c"],
|
|
311
|
+
disabledSelectionKeys: ["b"],
|
|
312
|
+
},
|
|
306
313
|
visibleRowIds,
|
|
307
|
-
defaultSelectedKeys: ["a", "b", "c"],
|
|
308
|
-
disabledSelectionKeys: ["b"],
|
|
309
314
|
}),
|
|
310
315
|
);
|
|
311
316
|
|
|
@@ -321,9 +326,8 @@ describe("useTableSelection", () => {
|
|
|
321
326
|
test("thead checkbox shows indeterminate when partially selected", () => {
|
|
322
327
|
const { result } = renderHook(() =>
|
|
323
328
|
useTableSelection({
|
|
324
|
-
selectionMode: "multiple",
|
|
329
|
+
selection: { selectionMode: "multiple", defaultSelectedKeys: ["a"] },
|
|
325
330
|
visibleRowIds,
|
|
326
|
-
defaultSelectedKeys: ["a"],
|
|
327
331
|
}),
|
|
328
332
|
);
|
|
329
333
|
|
|
@@ -335,9 +339,11 @@ describe("useTableSelection", () => {
|
|
|
335
339
|
test("thead checkbox shows checked when all selected", () => {
|
|
336
340
|
const { result } = renderHook(() =>
|
|
337
341
|
useTableSelection({
|
|
338
|
-
|
|
342
|
+
selection: {
|
|
343
|
+
selectionMode: "multiple",
|
|
344
|
+
defaultSelectedKeys: ["a", "b", "c"],
|
|
345
|
+
},
|
|
339
346
|
visibleRowIds,
|
|
340
|
-
defaultSelectedKeys: ["a", "b", "c"],
|
|
341
347
|
}),
|
|
342
348
|
);
|
|
343
349
|
|
|
@@ -349,10 +355,12 @@ describe("useTableSelection", () => {
|
|
|
349
355
|
test("thead checkbox shows checked when all selectable rows are selected", () => {
|
|
350
356
|
const { result } = renderHook(() =>
|
|
351
357
|
useTableSelection({
|
|
352
|
-
|
|
358
|
+
selection: {
|
|
359
|
+
selectionMode: "multiple",
|
|
360
|
+
defaultSelectedKeys: ["a", "c"],
|
|
361
|
+
disabledSelectionKeys: ["b"],
|
|
362
|
+
},
|
|
353
363
|
visibleRowIds,
|
|
354
|
-
defaultSelectedKeys: ["a", "c"],
|
|
355
|
-
disabledSelectionKeys: ["b"],
|
|
356
364
|
}),
|
|
357
365
|
);
|
|
358
366
|
|
|
@@ -364,9 +372,11 @@ describe("useTableSelection", () => {
|
|
|
364
372
|
test("deselecting one row when all rows are selected", () => {
|
|
365
373
|
const { result } = renderHook(() =>
|
|
366
374
|
useTableSelection({
|
|
367
|
-
|
|
375
|
+
selection: {
|
|
376
|
+
selectionMode: "multiple",
|
|
377
|
+
defaultSelectedKeys: ["a", "b", "c"],
|
|
378
|
+
},
|
|
368
379
|
visibleRowIds,
|
|
369
|
-
defaultSelectedKeys: ["a", "b", "c"],
|
|
370
380
|
}),
|
|
371
381
|
);
|
|
372
382
|
|
|
@@ -382,9 +392,11 @@ describe("useTableSelection", () => {
|
|
|
382
392
|
test("disabled rows have disabled prop", () => {
|
|
383
393
|
const { result } = renderHook(() =>
|
|
384
394
|
useTableSelection({
|
|
385
|
-
|
|
395
|
+
selection: {
|
|
396
|
+
selectionMode: "multiple",
|
|
397
|
+
disabledSelectionKeys: ["b"],
|
|
398
|
+
},
|
|
386
399
|
visibleRowIds,
|
|
387
|
-
disabledSelectionKeys: ["b"],
|
|
388
400
|
}),
|
|
389
401
|
);
|
|
390
402
|
|
|
@@ -395,9 +407,11 @@ describe("useTableSelection", () => {
|
|
|
395
407
|
test("thead checkbox disabled when all rows disabled", () => {
|
|
396
408
|
const { result } = renderHook(() =>
|
|
397
409
|
useTableSelection({
|
|
398
|
-
|
|
410
|
+
selection: {
|
|
411
|
+
selectionMode: "multiple",
|
|
412
|
+
disabledSelectionKeys: ["a", "b", "c"],
|
|
413
|
+
},
|
|
399
414
|
visibleRowIds,
|
|
400
|
-
disabledSelectionKeys: ["a", "b", "c"],
|
|
401
415
|
}),
|
|
402
416
|
);
|
|
403
417
|
|
|
@@ -407,10 +421,9 @@ describe("useTableSelection", () => {
|
|
|
407
421
|
test("parent rows show indeterminate when visible descendants are partially selected", () => {
|
|
408
422
|
const { result } = renderHook(() =>
|
|
409
423
|
useTableSelection({
|
|
410
|
-
selectionMode: "multiple",
|
|
424
|
+
selection: { selectionMode: "multiple", defaultSelectedKeys: ["a1"] },
|
|
411
425
|
visibleRowIds: ["a", "a1", "a2"],
|
|
412
426
|
childRowIdsById,
|
|
413
|
-
defaultSelectedKeys: ["a1"],
|
|
414
427
|
}),
|
|
415
428
|
);
|
|
416
429
|
|
|
@@ -423,7 +436,7 @@ describe("useTableSelection", () => {
|
|
|
423
436
|
test("toggling a parent row selects and deselects its descendants", () => {
|
|
424
437
|
const { result } = renderHook(() =>
|
|
425
438
|
useTableSelection({
|
|
426
|
-
selectionMode: "multiple",
|
|
439
|
+
selection: { selectionMode: "multiple" },
|
|
427
440
|
visibleRowIds: ["a", "a1", "a2"],
|
|
428
441
|
childRowIdsById,
|
|
429
442
|
}),
|
|
@@ -449,7 +462,7 @@ describe("useTableSelection", () => {
|
|
|
449
462
|
test("toggling a collapsed parent selects and deselects hidden descendants", () => {
|
|
450
463
|
const { result } = renderHook(() =>
|
|
451
464
|
useTableSelection({
|
|
452
|
-
selectionMode: "multiple",
|
|
465
|
+
selection: { selectionMode: "multiple" },
|
|
453
466
|
visibleRowIds: ["a"],
|
|
454
467
|
childRowIdsById,
|
|
455
468
|
}),
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { useMemo } from "react";
|
|
1
2
|
import type {
|
|
2
3
|
ColumnDefinition,
|
|
3
4
|
ColumnDefinitions,
|
|
@@ -28,19 +29,32 @@ function useColumnOptions<T>(
|
|
|
28
29
|
|
|
29
30
|
const hasSelection = selectionMode !== "none";
|
|
30
31
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
columns: columnDefinitions.map((colDef, index) => {
|
|
32
|
+
const columns = useMemo(() => {
|
|
33
|
+
return columnDefinitions.map((colDef, index) => {
|
|
34
34
|
const isFirstSticky =
|
|
35
35
|
stickyColumns?.first === "1" && index === 0 && !hasSelection;
|
|
36
36
|
const isLastSticky =
|
|
37
37
|
stickyColumns?.last === "1" && index === columnDefinitions.length - 1;
|
|
38
38
|
|
|
39
39
|
return {
|
|
40
|
-
isSticky: isFirstSticky
|
|
40
|
+
isSticky: isFirstSticky
|
|
41
|
+
? ("start" as const)
|
|
42
|
+
: isLastSticky
|
|
43
|
+
? ("end" as const)
|
|
44
|
+
: (false as const),
|
|
41
45
|
colDef,
|
|
42
46
|
};
|
|
43
|
-
})
|
|
47
|
+
});
|
|
48
|
+
}, [
|
|
49
|
+
columnDefinitions,
|
|
50
|
+
hasSelection,
|
|
51
|
+
stickyColumns?.first,
|
|
52
|
+
stickyColumns?.last,
|
|
53
|
+
]);
|
|
54
|
+
|
|
55
|
+
return {
|
|
56
|
+
stickySelection: selectionMode !== "none" && stickyColumns?.first === "1",
|
|
57
|
+
columns,
|
|
44
58
|
};
|
|
45
59
|
}
|
|
46
60
|
|