@navikt/ds-react 8.10.5 → 8.10.6
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/data/data-grid/index.d.ts +2 -0
- package/cjs/data/data-grid/index.js +7 -0
- package/cjs/data/data-grid/index.js.map +1 -0
- package/cjs/data/data-grid/root/DataGridRoot.context.d.ts +11 -0
- package/cjs/data/data-grid/root/DataGridRoot.context.js +11 -0
- package/cjs/data/data-grid/root/DataGridRoot.context.js.map +1 -0
- package/cjs/data/data-grid/root/DataGridRoot.d.ts +38 -0
- package/cjs/data/data-grid/root/DataGridRoot.js +68 -0
- package/cjs/data/data-grid/root/DataGridRoot.js.map +1 -0
- package/cjs/data/drag-and-drop/drag-handler/DragAndDropDragHandler.js +0 -1
- package/cjs/data/drag-and-drop/drag-handler/DragAndDropDragHandler.js.map +1 -1
- package/cjs/data/drag-and-drop/root/DragAndDropRoot.d.ts +5 -5
- package/cjs/data/drag-and-drop/root/DragAndDropRoot.js +4 -27
- package/cjs/data/drag-and-drop/root/DragAndDropRoot.js.map +1 -1
- package/cjs/data/stories/Data.test-data.d.ts +2 -5
- package/cjs/data/stories/Data.test-data.js +30 -38
- package/cjs/data/stories/Data.test-data.js.map +1 -1
- package/cjs/data/table/base-cell/DataTableBaseCell.d.ts +15 -15
- package/cjs/data/table/base-cell/DataTableBaseCell.js +4 -8
- package/cjs/data/table/base-cell/DataTableBaseCell.js.map +1 -1
- package/cjs/data/table/column-header/DataTableColumnHeader.d.ts +24 -6
- package/cjs/data/table/column-header/DataTableColumnHeader.js +22 -27
- package/cjs/data/table/column-header/DataTableColumnHeader.js.map +1 -1
- package/cjs/data/table/column-header/useTableColumnResize.d.ts +19 -29
- package/cjs/data/table/column-header/useTableColumnResize.js +24 -22
- package/cjs/data/table/column-header/useTableColumnResize.js.map +1 -1
- package/cjs/data/table/details-panel-row/DataTableDetailsPanelRow.d.ts +1 -1
- package/cjs/data/table/details-panel-row/DataTableDetailsPanelRow.js +2 -2
- package/cjs/data/table/details-panel-row/DataTableDetailsPanelRow.js.map +1 -1
- package/cjs/data/table/helpers/collectTableRowEntries.d.ts +2 -2
- package/cjs/data/table/helpers/selection/getMultipleSelectProps.d.ts +13 -11
- package/cjs/data/table/helpers/selection/getMultipleSelectProps.js +43 -53
- package/cjs/data/table/helpers/selection/getMultipleSelectProps.js.map +1 -1
- package/cjs/data/table/helpers/selection/getSingleSelectProps.d.ts +9 -8
- package/cjs/data/table/helpers/selection/getSingleSelectProps.js +23 -10
- package/cjs/data/table/helpers/selection/getSingleSelectProps.js.map +1 -1
- package/cjs/data/table/helpers/selection/selection.types.d.ts +19 -19
- package/cjs/data/table/helpers/selection/selection.utils.d.ts +21 -0
- package/cjs/data/table/helpers/selection/selection.utils.js +46 -0
- package/cjs/data/table/helpers/selection/selection.utils.js.map +1 -0
- package/cjs/data/table/hooks/useColumnOptions.d.ts +16 -5
- package/cjs/data/table/hooks/useColumnOptions.js +26 -8
- package/cjs/data/table/hooks/useColumnOptions.js.map +1 -1
- package/cjs/data/table/hooks/useTableDetailsPanel.d.ts +10 -13
- package/cjs/data/table/hooks/useTableDetailsPanel.js +6 -5
- package/cjs/data/table/hooks/useTableDetailsPanel.js.map +1 -1
- package/cjs/data/table/hooks/useTableItems.d.ts +29 -15
- package/cjs/data/table/hooks/useTableItems.js +2 -12
- package/cjs/data/table/hooks/useTableItems.js.map +1 -1
- package/cjs/data/table/hooks/useTableKeyboardNav.d.ts +1 -6
- package/cjs/data/table/hooks/useTableKeyboardNav.js +1 -4
- package/cjs/data/table/hooks/useTableKeyboardNav.js.map +1 -1
- package/cjs/data/table/hooks/useTableSelection.d.ts +6 -6
- package/cjs/data/table/hooks/useTableSelection.js +13 -13
- package/cjs/data/table/hooks/useTableSelection.js.map +1 -1
- package/cjs/data/table/hooks/useTableSort.d.ts +2 -2
- package/cjs/data/table/hooks/useTableSort.js +4 -5
- package/cjs/data/table/hooks/useTableSort.js.map +1 -1
- package/cjs/data/table/root/DataTable.types.d.ts +22 -10
- package/cjs/data/table/root/DataTableRoot.context.d.ts +13 -7
- package/cjs/data/table/root/DataTableRoot.context.js.map +1 -1
- package/cjs/data/table/root/DataTableRoot.d.ts +49 -72
- package/cjs/data/table/root/DataTableRoot.js +54 -66
- package/cjs/data/table/root/DataTableRoot.js.map +1 -1
- package/cjs/data/table/root/DataTableRoot.legacy.d.ts +2 -7
- package/cjs/data/table/root/DataTableRoot.legacy.js +17 -3
- package/cjs/data/table/root/DataTableRoot.legacy.js.map +1 -1
- package/cjs/data/table/sub-row-toggle/DataTableSubRowToggle.js +4 -4
- package/cjs/data/table/sub-row-toggle/DataTableSubRowToggle.js.map +1 -1
- package/cjs/data/table/tbody/DataTableTbody.js +4 -2
- package/cjs/data/table/tbody/DataTableTbody.js.map +1 -1
- package/cjs/data/table/tr/DataTableTr.d.ts +5 -3
- package/cjs/data/table/tr/DataTableTr.js +36 -23
- package/cjs/data/table/tr/DataTableTr.js.map +1 -1
- package/cjs/table/ColumnHeader.js +2 -1
- package/cjs/table/ColumnHeader.js.map +1 -1
- package/esm/data/data-grid/index.d.ts +2 -0
- package/esm/data/data-grid/index.js +3 -0
- package/esm/data/data-grid/index.js.map +1 -0
- package/esm/data/data-grid/root/DataGridRoot.context.d.ts +11 -0
- package/esm/data/data-grid/root/DataGridRoot.context.js +7 -0
- package/esm/data/data-grid/root/DataGridRoot.context.js.map +1 -0
- package/esm/data/data-grid/root/DataGridRoot.d.ts +38 -0
- package/esm/data/data-grid/root/DataGridRoot.js +32 -0
- package/esm/data/data-grid/root/DataGridRoot.js.map +1 -0
- package/esm/data/drag-and-drop/drag-handler/DragAndDropDragHandler.js +0 -1
- package/esm/data/drag-and-drop/drag-handler/DragAndDropDragHandler.js.map +1 -1
- package/esm/data/drag-and-drop/root/DragAndDropRoot.d.ts +5 -5
- package/esm/data/drag-and-drop/root/DragAndDropRoot.js +4 -27
- package/esm/data/drag-and-drop/root/DragAndDropRoot.js.map +1 -1
- package/esm/data/stories/Data.test-data.d.ts +2 -5
- package/esm/data/stories/Data.test-data.js +30 -38
- package/esm/data/stories/Data.test-data.js.map +1 -1
- package/esm/data/table/base-cell/DataTableBaseCell.d.ts +15 -15
- package/esm/data/table/base-cell/DataTableBaseCell.js +4 -8
- package/esm/data/table/base-cell/DataTableBaseCell.js.map +1 -1
- package/esm/data/table/column-header/DataTableColumnHeader.d.ts +24 -6
- package/esm/data/table/column-header/DataTableColumnHeader.js +23 -28
- package/esm/data/table/column-header/DataTableColumnHeader.js.map +1 -1
- package/esm/data/table/column-header/useTableColumnResize.d.ts +19 -29
- package/esm/data/table/column-header/useTableColumnResize.js +24 -22
- package/esm/data/table/column-header/useTableColumnResize.js.map +1 -1
- package/esm/data/table/details-panel-row/DataTableDetailsPanelRow.d.ts +1 -1
- package/esm/data/table/details-panel-row/DataTableDetailsPanelRow.js +2 -2
- package/esm/data/table/details-panel-row/DataTableDetailsPanelRow.js.map +1 -1
- package/esm/data/table/helpers/collectTableRowEntries.d.ts +2 -2
- package/esm/data/table/helpers/selection/getMultipleSelectProps.d.ts +13 -11
- package/esm/data/table/helpers/selection/getMultipleSelectProps.js +43 -53
- package/esm/data/table/helpers/selection/getMultipleSelectProps.js.map +1 -1
- package/esm/data/table/helpers/selection/getSingleSelectProps.d.ts +9 -8
- package/esm/data/table/helpers/selection/getSingleSelectProps.js +23 -10
- package/esm/data/table/helpers/selection/getSingleSelectProps.js.map +1 -1
- package/esm/data/table/helpers/selection/selection.types.d.ts +19 -19
- package/esm/data/table/helpers/selection/selection.utils.d.ts +21 -0
- package/esm/data/table/helpers/selection/selection.utils.js +43 -0
- package/esm/data/table/helpers/selection/selection.utils.js.map +1 -0
- package/esm/data/table/hooks/useColumnOptions.d.ts +16 -5
- package/esm/data/table/hooks/useColumnOptions.js +26 -8
- package/esm/data/table/hooks/useColumnOptions.js.map +1 -1
- package/esm/data/table/hooks/useTableDetailsPanel.d.ts +10 -13
- package/esm/data/table/hooks/useTableDetailsPanel.js +6 -5
- package/esm/data/table/hooks/useTableDetailsPanel.js.map +1 -1
- package/esm/data/table/hooks/useTableItems.d.ts +29 -15
- package/esm/data/table/hooks/useTableItems.js +3 -10
- package/esm/data/table/hooks/useTableItems.js.map +1 -1
- package/esm/data/table/hooks/useTableKeyboardNav.d.ts +1 -6
- package/esm/data/table/hooks/useTableKeyboardNav.js +1 -4
- package/esm/data/table/hooks/useTableKeyboardNav.js.map +1 -1
- package/esm/data/table/hooks/useTableSelection.d.ts +6 -6
- package/esm/data/table/hooks/useTableSelection.js +13 -13
- package/esm/data/table/hooks/useTableSelection.js.map +1 -1
- package/esm/data/table/hooks/useTableSort.d.ts +2 -2
- package/esm/data/table/hooks/useTableSort.js +4 -5
- package/esm/data/table/hooks/useTableSort.js.map +1 -1
- package/esm/data/table/root/DataTable.types.d.ts +22 -10
- package/esm/data/table/root/DataTableRoot.context.d.ts +13 -7
- package/esm/data/table/root/DataTableRoot.context.js.map +1 -1
- package/esm/data/table/root/DataTableRoot.d.ts +49 -72
- package/esm/data/table/root/DataTableRoot.js +56 -68
- package/esm/data/table/root/DataTableRoot.js.map +1 -1
- package/esm/data/table/root/DataTableRoot.legacy.d.ts +2 -7
- package/esm/data/table/root/DataTableRoot.legacy.js +17 -3
- package/esm/data/table/root/DataTableRoot.legacy.js.map +1 -1
- package/esm/data/table/sub-row-toggle/DataTableSubRowToggle.js +4 -4
- package/esm/data/table/sub-row-toggle/DataTableSubRowToggle.js.map +1 -1
- package/esm/data/table/tbody/DataTableTbody.js +4 -2
- package/esm/data/table/tbody/DataTableTbody.js.map +1 -1
- package/esm/data/table/tr/DataTableTr.d.ts +5 -3
- package/esm/data/table/tr/DataTableTr.js +35 -23
- package/esm/data/table/tr/DataTableTr.js.map +1 -1
- package/esm/table/ColumnHeader.js +2 -1
- package/esm/table/ColumnHeader.js.map +1 -1
- package/package.json +3 -3
- package/src/data/data-grid/index.ts +3 -0
- package/src/data/data-grid/root/DataGridRoot.context.ts +16 -0
- package/src/data/data-grid/root/DataGridRoot.tsx +71 -0
- package/src/data/drag-and-drop/drag-handler/DragAndDropDragHandler.tsx +0 -1
- package/src/data/drag-and-drop/root/DragAndDropRoot.tsx +15 -49
- package/src/data/stories/Data.test-data.tsx +52 -43
- package/src/data/table/agent-component-review.md +175 -0
- package/src/data/table/base-cell/DataTableBaseCell.tsx +31 -21
- package/src/data/table/column-header/DataTableColumnHeader.tsx +61 -58
- package/src/data/table/column-header/useTableColumnResize.ts +55 -71
- package/src/data/table/details-panel-row/DataTableDetailsPanelRow.tsx +3 -3
- package/src/data/table/helpers/collectTableRowEntries.ts +1 -2
- package/src/data/table/helpers/selection/getMultipleSelectProps.ts +65 -85
- package/src/data/table/helpers/selection/getSingleSelectProps.ts +35 -17
- package/src/data/table/helpers/selection/selection.types.ts +19 -19
- package/src/data/table/helpers/selection/selection.utils.test.ts +161 -0
- package/src/data/table/helpers/selection/selection.utils.ts +73 -0
- package/src/data/table/hooks/__tests__/useTableItems.test.ts +2 -1
- package/src/data/table/hooks/useColumnOptions.ts +48 -14
- package/src/data/table/hooks/useTableDetailsPanel.tsx +22 -25
- package/src/data/table/hooks/useTableItems.ts +32 -24
- package/src/data/table/hooks/useTableKeyboardNav.ts +1 -13
- package/src/data/table/hooks/useTableSelection.ts +26 -31
- package/src/data/table/hooks/useTableSort.ts +10 -9
- package/src/data/table/root/DataTable.types.ts +30 -22
- package/src/data/table/root/DataTableRoot.context.ts +19 -7
- package/src/data/table/root/DataTableRoot.legacy.tsx +22 -14
- package/src/data/table/root/DataTableRoot.tsx +244 -293
- package/src/data/table/sub-row-toggle/DataTableSubRowToggle.tsx +5 -4
- package/src/data/table/tbody/DataTableTbody.tsx +6 -2
- package/src/data/table/tr/DataTableTr.tsx +98 -35
- package/src/table/ColumnHeader.tsx +2 -1
- package/cjs/data/drag-and-drop-legacy/drag-handler/DragAndDropDragHandlerLegacy.d.ts +0 -22
- package/cjs/data/drag-and-drop-legacy/drag-handler/DragAndDropDragHandlerLegacy.js +0 -35
- package/cjs/data/drag-and-drop-legacy/drag-handler/DragAndDropDragHandlerLegacy.js.map +0 -1
- package/cjs/data/drag-and-drop-legacy/item/DragAndDropItemLegacy.d.ts +0 -27
- package/cjs/data/drag-and-drop-legacy/item/DragAndDropItemLegacy.js +0 -86
- package/cjs/data/drag-and-drop-legacy/item/DragAndDropItemLegacy.js.map +0 -1
- package/cjs/data/drag-and-drop-legacy/root/DragAndDropLegacy.context.d.ts +0 -5
- package/cjs/data/drag-and-drop-legacy/root/DragAndDropLegacy.context.js +0 -6
- package/cjs/data/drag-and-drop-legacy/root/DragAndDropLegacy.context.js.map +0 -1
- package/cjs/data/drag-and-drop-legacy/root/DragAndDropLegacyRoot.d.ts +0 -24
- package/cjs/data/drag-and-drop-legacy/root/DragAndDropLegacyRoot.js +0 -108
- package/cjs/data/drag-and-drop-legacy/root/DragAndDropLegacyRoot.js.map +0 -1
- package/cjs/data/table/helpers/selection/SelectionSubtreeHelper.d.ts +0 -46
- package/cjs/data/table/helpers/selection/SelectionSubtreeHelper.js +0 -112
- package/cjs/data/table/helpers/selection/SelectionSubtreeHelper.js.map +0 -1
- package/esm/data/drag-and-drop-legacy/drag-handler/DragAndDropDragHandlerLegacy.d.ts +0 -22
- package/esm/data/drag-and-drop-legacy/drag-handler/DragAndDropDragHandlerLegacy.js +0 -29
- package/esm/data/drag-and-drop-legacy/drag-handler/DragAndDropDragHandlerLegacy.js.map +0 -1
- package/esm/data/drag-and-drop-legacy/item/DragAndDropItemLegacy.d.ts +0 -27
- package/esm/data/drag-and-drop-legacy/item/DragAndDropItemLegacy.js +0 -50
- package/esm/data/drag-and-drop-legacy/item/DragAndDropItemLegacy.js.map +0 -1
- package/esm/data/drag-and-drop-legacy/root/DragAndDropLegacy.context.d.ts +0 -5
- package/esm/data/drag-and-drop-legacy/root/DragAndDropLegacy.context.js +0 -3
- package/esm/data/drag-and-drop-legacy/root/DragAndDropLegacy.context.js.map +0 -1
- package/esm/data/drag-and-drop-legacy/root/DragAndDropLegacyRoot.d.ts +0 -24
- package/esm/data/drag-and-drop-legacy/root/DragAndDropLegacyRoot.js +0 -68
- package/esm/data/drag-and-drop-legacy/root/DragAndDropLegacyRoot.js.map +0 -1
- package/esm/data/table/helpers/selection/SelectionSubtreeHelper.d.ts +0 -46
- package/esm/data/table/helpers/selection/SelectionSubtreeHelper.js +0 -109
- package/esm/data/table/helpers/selection/SelectionSubtreeHelper.js.map +0 -1
- package/src/data/drag-and-drop-legacy/drag-handler/DragAndDropDragHandlerLegacy.tsx +0 -104
- package/src/data/drag-and-drop-legacy/item/DragAndDropItemLegacy.tsx +0 -74
- package/src/data/drag-and-drop-legacy/root/DragAndDropLegacy.context.tsx +0 -11
- package/src/data/drag-and-drop-legacy/root/DragAndDropLegacyRoot.tsx +0 -94
- package/src/data/table/helpers/selection/SelectionSubtreeHelper.test.ts +0 -66
- package/src/data/table/helpers/selection/SelectionSubtreeHelper.ts +0 -162
- package/src/data/table/hooks/__tests__/useTableSelection.test.ts +0 -488
- package/src/data/table/root/agent-feature-gap.md +0 -96
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { describe, expect, test } from "vitest";
|
|
2
|
+
import type { TableRowEntryId } from "../../root/DataTable.types";
|
|
3
|
+
import type { ItemDetail } from "../collectTableRowEntries";
|
|
4
|
+
import { mutateRowSelection } from "./selection.utils";
|
|
5
|
+
|
|
6
|
+
function makeItemDetails<T>(
|
|
7
|
+
entries: { id: TableRowEntryId; rowData: T }[],
|
|
8
|
+
): Map<TableRowEntryId, ItemDetail<T>> {
|
|
9
|
+
return new Map(
|
|
10
|
+
entries.map(({ id, rowData }) => [
|
|
11
|
+
id,
|
|
12
|
+
{ id, rowData, level: 0, parentId: null, children: [] },
|
|
13
|
+
]),
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
describe("mutateRowSelection", () => {
|
|
18
|
+
test("adds rowId to set when checked", () => {
|
|
19
|
+
const set = new Set<TableRowEntryId>();
|
|
20
|
+
const itemDetails = makeItemDetails([{ id: "a", rowData: {} }]);
|
|
21
|
+
const changed = mutateRowSelection({
|
|
22
|
+
selectedRowIds: set,
|
|
23
|
+
rowId: "a",
|
|
24
|
+
checked: true,
|
|
25
|
+
childRowIdsById: new Map(),
|
|
26
|
+
itemDetails,
|
|
27
|
+
});
|
|
28
|
+
expect(set.has("a")).toBe(true);
|
|
29
|
+
expect(changed).toBe(true);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test("removes rowId from set when unchecked", () => {
|
|
33
|
+
const set = new Set<TableRowEntryId>(["a"]);
|
|
34
|
+
const itemDetails = makeItemDetails([{ id: "a", rowData: {} }]);
|
|
35
|
+
const changed = mutateRowSelection({
|
|
36
|
+
selectedRowIds: set,
|
|
37
|
+
rowId: "a",
|
|
38
|
+
checked: false,
|
|
39
|
+
childRowIdsById: new Map(),
|
|
40
|
+
itemDetails,
|
|
41
|
+
});
|
|
42
|
+
expect(set.has("a")).toBe(false);
|
|
43
|
+
expect(changed).toBe(true);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test("returns false and does not mutate when row is already in desired state", () => {
|
|
47
|
+
const set = new Set<TableRowEntryId>(["a"]);
|
|
48
|
+
const itemDetails = makeItemDetails([{ id: "a", rowData: {} }]);
|
|
49
|
+
const changed = mutateRowSelection({
|
|
50
|
+
selectedRowIds: set,
|
|
51
|
+
rowId: "a",
|
|
52
|
+
checked: true,
|
|
53
|
+
childRowIdsById: new Map(),
|
|
54
|
+
itemDetails,
|
|
55
|
+
});
|
|
56
|
+
expect(set.size).toBe(1);
|
|
57
|
+
expect(changed).toBe(false);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test("recursively selects all children", () => {
|
|
61
|
+
const set = new Set<TableRowEntryId>();
|
|
62
|
+
const itemDetails = makeItemDetails([
|
|
63
|
+
{ id: "parent", rowData: {} },
|
|
64
|
+
{ id: "child1", rowData: {} },
|
|
65
|
+
{ id: "child2", rowData: {} },
|
|
66
|
+
]);
|
|
67
|
+
const childRowIdsById = new Map<TableRowEntryId, TableRowEntryId[]>([
|
|
68
|
+
["parent", ["child1", "child2"]],
|
|
69
|
+
]);
|
|
70
|
+
mutateRowSelection({
|
|
71
|
+
selectedRowIds: set,
|
|
72
|
+
rowId: "parent",
|
|
73
|
+
checked: true,
|
|
74
|
+
childRowIdsById,
|
|
75
|
+
itemDetails,
|
|
76
|
+
});
|
|
77
|
+
expect(set).toEqual(new Set(["parent", "child1", "child2"]));
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
test("recursively deselects all children", () => {
|
|
81
|
+
const set = new Set<TableRowEntryId>(["parent", "child1", "child2"]);
|
|
82
|
+
const itemDetails = makeItemDetails([
|
|
83
|
+
{ id: "parent", rowData: {} },
|
|
84
|
+
{ id: "child1", rowData: {} },
|
|
85
|
+
{ id: "child2", rowData: {} },
|
|
86
|
+
]);
|
|
87
|
+
const childRowIdsById = new Map<TableRowEntryId, TableRowEntryId[]>([
|
|
88
|
+
["parent", ["child1", "child2"]],
|
|
89
|
+
]);
|
|
90
|
+
mutateRowSelection({
|
|
91
|
+
selectedRowIds: set,
|
|
92
|
+
rowId: "parent",
|
|
93
|
+
checked: false,
|
|
94
|
+
childRowIdsById,
|
|
95
|
+
itemDetails,
|
|
96
|
+
});
|
|
97
|
+
expect(set.size).toBe(0);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
test("handles deeply nested children", () => {
|
|
101
|
+
const set = new Set<TableRowEntryId>();
|
|
102
|
+
const itemDetails = makeItemDetails([
|
|
103
|
+
{ id: "a", rowData: {} },
|
|
104
|
+
{ id: "a1", rowData: {} },
|
|
105
|
+
{ id: "a1a", rowData: {} },
|
|
106
|
+
]);
|
|
107
|
+
const childRowIdsById = new Map<TableRowEntryId, TableRowEntryId[]>([
|
|
108
|
+
["a", ["a1"]],
|
|
109
|
+
["a1", ["a1a"]],
|
|
110
|
+
]);
|
|
111
|
+
mutateRowSelection({
|
|
112
|
+
selectedRowIds: set,
|
|
113
|
+
rowId: "a",
|
|
114
|
+
checked: true,
|
|
115
|
+
childRowIdsById,
|
|
116
|
+
itemDetails,
|
|
117
|
+
});
|
|
118
|
+
expect(set).toEqual(new Set(["a", "a1", "a1a"]));
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
test("skips disabled rows and their children", () => {
|
|
122
|
+
const set = new Set<TableRowEntryId>();
|
|
123
|
+
const itemDetails = makeItemDetails([
|
|
124
|
+
{ id: "parent", rowData: { disabled: false } },
|
|
125
|
+
{ id: "child1", rowData: { disabled: true } },
|
|
126
|
+
{ id: "child1a", rowData: { disabled: false } },
|
|
127
|
+
{ id: "child2", rowData: { disabled: false } },
|
|
128
|
+
]);
|
|
129
|
+
const childRowIdsById = new Map<TableRowEntryId, TableRowEntryId[]>([
|
|
130
|
+
["parent", ["child1", "child2"]],
|
|
131
|
+
["child1", ["child1a"]],
|
|
132
|
+
]);
|
|
133
|
+
mutateRowSelection({
|
|
134
|
+
selectedRowIds: set,
|
|
135
|
+
rowId: "parent",
|
|
136
|
+
checked: true,
|
|
137
|
+
childRowIdsById,
|
|
138
|
+
itemDetails,
|
|
139
|
+
enableRowSelection: ({ row }) => !row.disabled,
|
|
140
|
+
});
|
|
141
|
+
expect(set.has("parent")).toBe(true);
|
|
142
|
+
expect(set.has("child1")).toBe(false);
|
|
143
|
+
expect(set.has("child1a")).toBe(true);
|
|
144
|
+
expect(set.has("child2")).toBe(true);
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
test("returns false when all matching rows were already disabled", () => {
|
|
148
|
+
const set = new Set<TableRowEntryId>();
|
|
149
|
+
const itemDetails = makeItemDetails([{ id: "a", rowData: {} }]);
|
|
150
|
+
const changed = mutateRowSelection({
|
|
151
|
+
selectedRowIds: set,
|
|
152
|
+
rowId: "a",
|
|
153
|
+
checked: true,
|
|
154
|
+
childRowIdsById: new Map(),
|
|
155
|
+
itemDetails,
|
|
156
|
+
enableRowSelection: false,
|
|
157
|
+
});
|
|
158
|
+
expect(set.size).toBe(0);
|
|
159
|
+
expect(changed).toBe(false);
|
|
160
|
+
});
|
|
161
|
+
});
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { TableRowEntryId } from "../../root/DataTable.types";
|
|
2
|
+
import type { ItemDetail } from "../collectTableRowEntries";
|
|
3
|
+
import type { SelectionProps } from "./selection.types";
|
|
4
|
+
|
|
5
|
+
function canSelectTableRow<T>(
|
|
6
|
+
enableRowSelection: SelectionProps<T>["enableRowSelection"],
|
|
7
|
+
args: { row: T; id: TableRowEntryId },
|
|
8
|
+
): boolean {
|
|
9
|
+
if (typeof enableRowSelection === "function") {
|
|
10
|
+
return enableRowSelection(args);
|
|
11
|
+
}
|
|
12
|
+
return enableRowSelection ?? true;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
type MutateRowSelectionArgs<T> = {
|
|
16
|
+
selectedRowIds: Set<TableRowEntryId>;
|
|
17
|
+
rowId: TableRowEntryId;
|
|
18
|
+
checked: boolean;
|
|
19
|
+
childRowIdsById: Map<TableRowEntryId, TableRowEntryId[]>;
|
|
20
|
+
itemDetails: Map<TableRowEntryId, ItemDetail<T>>;
|
|
21
|
+
enableRowSelection?: SelectionProps<T>["enableRowSelection"];
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Traverses the row and its children and updates selected-state directly on given selectedRowIds set.
|
|
26
|
+
* Returns true if any changes were made to the set, false otherwise.
|
|
27
|
+
*/
|
|
28
|
+
function mutateRowSelection<T>({
|
|
29
|
+
selectedRowIds,
|
|
30
|
+
rowId,
|
|
31
|
+
checked,
|
|
32
|
+
childRowIdsById,
|
|
33
|
+
itemDetails,
|
|
34
|
+
enableRowSelection,
|
|
35
|
+
}: MutateRowSelectionArgs<T>): boolean {
|
|
36
|
+
let changed = false;
|
|
37
|
+
const item = itemDetails.get(rowId);
|
|
38
|
+
|
|
39
|
+
if (
|
|
40
|
+
item &&
|
|
41
|
+
canSelectTableRow(enableRowSelection, { row: item.rowData, id: rowId })
|
|
42
|
+
) {
|
|
43
|
+
if (checked && !selectedRowIds.has(rowId)) {
|
|
44
|
+
selectedRowIds.add(rowId);
|
|
45
|
+
changed = true;
|
|
46
|
+
} else if (!checked && selectedRowIds.has(rowId)) {
|
|
47
|
+
selectedRowIds.delete(rowId);
|
|
48
|
+
changed = true;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const children = childRowIdsById.get(rowId);
|
|
53
|
+
if (children) {
|
|
54
|
+
for (const childId of children) {
|
|
55
|
+
if (
|
|
56
|
+
mutateRowSelection({
|
|
57
|
+
selectedRowIds,
|
|
58
|
+
rowId: childId,
|
|
59
|
+
checked,
|
|
60
|
+
childRowIdsById,
|
|
61
|
+
itemDetails,
|
|
62
|
+
enableRowSelection,
|
|
63
|
+
})
|
|
64
|
+
) {
|
|
65
|
+
changed = true;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return changed;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export { canSelectTableRow, mutateRowSelection };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { renderHook } from "@testing-library/react";
|
|
2
2
|
import { describe, expect, test } from "vitest";
|
|
3
|
+
import type { TableRowEntryId } from "../../root/DataTable.types";
|
|
3
4
|
import { useTableItems } from "../useTableItems";
|
|
4
5
|
|
|
5
6
|
type TestRow = {
|
|
@@ -140,7 +141,7 @@ describe("useTableItems", () => {
|
|
|
140
141
|
},
|
|
141
142
|
}),
|
|
142
143
|
{
|
|
143
|
-
initialProps: { expandedIds: [] as
|
|
144
|
+
initialProps: { expandedIds: [] as TableRowEntryId[] },
|
|
144
145
|
},
|
|
145
146
|
);
|
|
146
147
|
|
|
@@ -3,38 +3,57 @@ import type {
|
|
|
3
3
|
ColumnDefinition,
|
|
4
4
|
ColumnDefinitions,
|
|
5
5
|
} from "../root/DataTable.types";
|
|
6
|
-
import
|
|
6
|
+
import { ACTION_CELL_WIDTH } from "../tr/DataTableTr";
|
|
7
7
|
|
|
8
8
|
type UseColumnOptions = {
|
|
9
9
|
stickyColumns?: {
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
start?: "1";
|
|
11
|
+
end?: "1";
|
|
12
12
|
};
|
|
13
|
-
|
|
13
|
+
hasSelection: boolean;
|
|
14
|
+
hasDetailsPanel: boolean;
|
|
15
|
+
layout: "fixed" | "auto";
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
type StickyStartState = {
|
|
19
|
+
selection: boolean;
|
|
20
|
+
expansion: boolean;
|
|
21
|
+
selectionOffset: number;
|
|
22
|
+
firstColumnOffset: number;
|
|
14
23
|
};
|
|
15
24
|
|
|
16
25
|
type UseColumnOptionsResult<T> = {
|
|
17
26
|
columns: {
|
|
18
27
|
isSticky: "start" | "end" | false;
|
|
28
|
+
isStickyLast?: boolean;
|
|
29
|
+
stickyLeftOffset?: number;
|
|
19
30
|
colDef: ColumnDefinition<T>;
|
|
20
31
|
}[];
|
|
21
|
-
|
|
32
|
+
stickyStart: StickyStartState;
|
|
33
|
+
totalColSpan: number;
|
|
22
34
|
};
|
|
23
35
|
|
|
24
36
|
function useColumnOptions<T>(
|
|
25
37
|
columnDefinitions: ColumnDefinitions<T>,
|
|
26
38
|
options: UseColumnOptions,
|
|
27
39
|
): UseColumnOptionsResult<T> {
|
|
28
|
-
const { stickyColumns,
|
|
40
|
+
const { stickyColumns, hasSelection, hasDetailsPanel, layout } = options;
|
|
41
|
+
|
|
42
|
+
const hasStickyStart = stickyColumns?.start === "1";
|
|
29
43
|
|
|
30
|
-
const
|
|
44
|
+
const stickyExpansion = hasStickyStart && hasDetailsPanel;
|
|
45
|
+
const stickySelection = hasStickyStart && hasSelection;
|
|
46
|
+
|
|
47
|
+
const stickySelectionOffset = stickyExpansion ? ACTION_CELL_WIDTH : 0;
|
|
48
|
+
const stickyFirstColumnOffset =
|
|
49
|
+
(stickyExpansion ? ACTION_CELL_WIDTH : 0) +
|
|
50
|
+
(stickySelection ? ACTION_CELL_WIDTH : 0);
|
|
31
51
|
|
|
32
52
|
const columns = useMemo(() => {
|
|
33
53
|
return columnDefinitions.map((colDef, index) => {
|
|
34
|
-
const isFirstSticky =
|
|
35
|
-
stickyColumns?.first === "1" && index === 0 && !hasSelection;
|
|
54
|
+
const isFirstSticky = hasStickyStart && index === 0;
|
|
36
55
|
const isLastSticky =
|
|
37
|
-
stickyColumns?.
|
|
56
|
+
stickyColumns?.end === "1" && index === columnDefinitions.length - 1;
|
|
38
57
|
|
|
39
58
|
return {
|
|
40
59
|
isSticky: isFirstSticky
|
|
@@ -42,21 +61,36 @@ function useColumnOptions<T>(
|
|
|
42
61
|
: isLastSticky
|
|
43
62
|
? ("end" as const)
|
|
44
63
|
: (false as const),
|
|
64
|
+
isStickyLast: isFirstSticky && !isLastSticky,
|
|
65
|
+
stickyLeftOffset: isFirstSticky ? stickyFirstColumnOffset : undefined,
|
|
45
66
|
colDef,
|
|
46
67
|
};
|
|
47
68
|
});
|
|
48
69
|
}, [
|
|
49
70
|
columnDefinitions,
|
|
50
|
-
|
|
51
|
-
stickyColumns
|
|
52
|
-
|
|
71
|
+
hasStickyStart,
|
|
72
|
+
stickyColumns,
|
|
73
|
+
stickyFirstColumnOffset,
|
|
53
74
|
]);
|
|
54
75
|
|
|
76
|
+
const totalColSpan =
|
|
77
|
+
columns.length +
|
|
78
|
+
(layout === "fixed" ? 1 : 0) +
|
|
79
|
+
(hasSelection ? 1 : 0) +
|
|
80
|
+
(hasDetailsPanel ? 1 : 0);
|
|
81
|
+
|
|
55
82
|
return {
|
|
56
|
-
|
|
83
|
+
stickyStart: {
|
|
84
|
+
selection: stickySelection,
|
|
85
|
+
expansion: stickyExpansion,
|
|
86
|
+
selectionOffset: stickySelectionOffset,
|
|
87
|
+
firstColumnOffset: stickyFirstColumnOffset,
|
|
88
|
+
},
|
|
57
89
|
columns,
|
|
90
|
+
totalColSpan,
|
|
58
91
|
};
|
|
59
92
|
}
|
|
60
93
|
|
|
61
94
|
export { useColumnOptions };
|
|
95
|
+
export type { StickyStartState };
|
|
62
96
|
export type { UseColumnOptionsResult };
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import React, { useCallback } from "react";
|
|
2
2
|
import { createStrictContext } from "../../../utils/helpers";
|
|
3
3
|
import { useControllableState } from "../../../utils/hooks";
|
|
4
|
-
import {
|
|
4
|
+
import type { TableRowEntryId } from "../root/DataTable.types";
|
|
5
|
+
import { useDataTableContext } from "../root/DataTableRoot.context";
|
|
5
6
|
|
|
6
7
|
type DetailsPanelProps<T> = {
|
|
7
8
|
/**
|
|
8
|
-
*
|
|
9
|
+
* Function to get the content to show in the details panel for a given row.
|
|
9
10
|
* When provided, an expand toggle column is added automatically.
|
|
10
11
|
*/
|
|
11
|
-
getContent
|
|
12
|
+
getContent: (rowData: T) => React.ReactNode;
|
|
12
13
|
/**
|
|
13
14
|
* Determines whether a row can be expanded to show details panel content.
|
|
14
15
|
* @default () => true
|
|
@@ -18,20 +19,16 @@ type DetailsPanelProps<T> = {
|
|
|
18
19
|
* Controlled list of expanded row IDs.
|
|
19
20
|
* Use with `onDetailsPanelChange` for controlled usage, or `defaultDetailsPanelRowIds` for uncontrolled.
|
|
20
21
|
*/
|
|
21
|
-
expandedRowIds?:
|
|
22
|
+
expandedRowIds?: TableRowEntryId[];
|
|
22
23
|
/**
|
|
23
24
|
* Initial list of expanded row IDs for uncontrolled usage.
|
|
24
25
|
* @default []
|
|
25
26
|
*/
|
|
26
|
-
defaultExpandedRowIds?:
|
|
27
|
+
defaultExpandedRowIds?: TableRowEntryId[];
|
|
27
28
|
/**
|
|
28
29
|
* Called when the list of expanded row IDs changes.
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
* TODO:
|
|
32
|
-
* - Docs: This pattern is called "Master / Detail" in general terms
|
|
33
30
|
*/
|
|
34
|
-
onExpandedRowIdsChange?: (ids:
|
|
31
|
+
onExpandedRowIdsChange?: (ids: TableRowEntryId[]) => void; // TODO: Docs: This pattern is called "Master / Detail" in general terms
|
|
35
32
|
/**
|
|
36
33
|
* Returns the height (in px) or `"auto"` for a row's details panel.
|
|
37
34
|
* When a number is returned, the panel scrolls within that fixed height.
|
|
@@ -46,9 +43,9 @@ type DetailsPanelProps<T> = {
|
|
|
46
43
|
};
|
|
47
44
|
|
|
48
45
|
type DataTableDetailsPanelContextT = {
|
|
49
|
-
isExpanded: (id:
|
|
50
|
-
isDetailsPanelExpandable: (id:
|
|
51
|
-
toggleExpansion: (id:
|
|
46
|
+
isExpanded: (id: TableRowEntryId) => boolean;
|
|
47
|
+
isDetailsPanelExpandable: (id: TableRowEntryId) => boolean;
|
|
48
|
+
toggleExpansion: (id: TableRowEntryId) => void;
|
|
52
49
|
toggleAll: () => void;
|
|
53
50
|
isAllExpanded: boolean;
|
|
54
51
|
getDetailsPanelContent?: (row: unknown) => React.ReactNode;
|
|
@@ -68,7 +65,7 @@ const {
|
|
|
68
65
|
|
|
69
66
|
function DataTableDetailsPanelProvider<T>({
|
|
70
67
|
children,
|
|
71
|
-
detailsPanel
|
|
68
|
+
detailsPanel,
|
|
72
69
|
}: { detailsPanel?: DetailsPanelProps<T> } & { children: React.ReactNode }) {
|
|
73
70
|
const {
|
|
74
71
|
expandedRowIds,
|
|
@@ -78,7 +75,7 @@ function DataTableDetailsPanelProvider<T>({
|
|
|
78
75
|
isRowExpandable,
|
|
79
76
|
getHeight,
|
|
80
77
|
showExpandAll = false,
|
|
81
|
-
} = detailsPanel;
|
|
78
|
+
} = detailsPanel || {};
|
|
82
79
|
|
|
83
80
|
const [expandedIds, setExpandedIds] = useControllableState({
|
|
84
81
|
value: expandedRowIds,
|
|
@@ -87,21 +84,21 @@ function DataTableDetailsPanelProvider<T>({
|
|
|
87
84
|
});
|
|
88
85
|
|
|
89
86
|
/* TODO: False is just fallback until auto and root is merged */
|
|
90
|
-
const
|
|
87
|
+
const tableContext = useDataTableContext(false);
|
|
91
88
|
|
|
92
|
-
const { itemDetails } =
|
|
89
|
+
const { itemDetails } = tableContext?.tableItems ?? {
|
|
93
90
|
itemDetails: new Map<
|
|
94
|
-
|
|
95
|
-
{ rowData: T; id:
|
|
91
|
+
TableRowEntryId,
|
|
92
|
+
{ rowData: T; id: TableRowEntryId; level: number }
|
|
96
93
|
>(),
|
|
97
94
|
};
|
|
98
95
|
|
|
99
96
|
const expandableIds = React.useMemo(() => {
|
|
100
97
|
if (!getContent) {
|
|
101
|
-
return new Set<
|
|
98
|
+
return new Set<TableRowEntryId>();
|
|
102
99
|
}
|
|
103
100
|
|
|
104
|
-
const ids = new Set<
|
|
101
|
+
const ids = new Set<TableRowEntryId>();
|
|
105
102
|
|
|
106
103
|
for (const { rowData, id, level } of itemDetails.values()) {
|
|
107
104
|
/* We only allow Master - Details pattern on top level rows */
|
|
@@ -118,18 +115,18 @@ function DataTableDetailsPanelProvider<T>({
|
|
|
118
115
|
}, [getContent, isRowExpandable, itemDetails]);
|
|
119
116
|
|
|
120
117
|
const isDetailsPanelExpandableById = useCallback(
|
|
121
|
-
(id:
|
|
118
|
+
(id: TableRowEntryId) => expandableIds.has(id),
|
|
122
119
|
[expandableIds],
|
|
123
120
|
);
|
|
124
121
|
|
|
125
122
|
const isExpanded = useCallback(
|
|
126
|
-
(id:
|
|
123
|
+
(id: TableRowEntryId) =>
|
|
127
124
|
isDetailsPanelExpandableById(id) && expandedIds.includes(id),
|
|
128
125
|
[expandedIds, isDetailsPanelExpandableById],
|
|
129
126
|
);
|
|
130
127
|
|
|
131
128
|
const toggleExpansion = useCallback(
|
|
132
|
-
(id:
|
|
129
|
+
(id: TableRowEntryId) => {
|
|
133
130
|
if (!isDetailsPanelExpandableById(id)) {
|
|
134
131
|
return;
|
|
135
132
|
}
|
|
@@ -172,7 +169,7 @@ function DataTableDetailsPanelProvider<T>({
|
|
|
172
169
|
);
|
|
173
170
|
}
|
|
174
171
|
|
|
175
|
-
function getDataTableDetailsPanelId(tableId: string, rowId:
|
|
172
|
+
function getDataTableDetailsPanelId(tableId: string, rowId: TableRowEntryId) {
|
|
176
173
|
return `${tableId}-expansion-${rowId}`;
|
|
177
174
|
}
|
|
178
175
|
|
|
@@ -1,18 +1,34 @@
|
|
|
1
1
|
import { useCallback, useMemo } from "react";
|
|
2
|
-
import { createStrictContext } from "../../../utils/helpers";
|
|
3
2
|
import { useControllableState } from "../../../utils/hooks";
|
|
4
3
|
import {
|
|
5
4
|
type ItemDetail,
|
|
6
|
-
type TableRowEntryId,
|
|
7
5
|
collectTableRowEntries,
|
|
8
6
|
} from "../helpers/collectTableRowEntries";
|
|
7
|
+
import type { TableRowEntryId } from "../root/DataTable.types";
|
|
9
8
|
|
|
10
9
|
type SubRowsProps<T> = {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
/**
|
|
11
|
+
* Function to get sub-rows for a given row.
|
|
12
|
+
*/
|
|
13
|
+
getRows: (rowData: T) => T[];
|
|
14
|
+
/**
|
|
15
|
+
* Controlled list of IDs of rows that should be expanded.
|
|
16
|
+
*/
|
|
17
|
+
expandedRowIds?: TableRowEntryId[];
|
|
18
|
+
/**
|
|
19
|
+
* IDs of rows that should be initially expanded.
|
|
20
|
+
* Only used when `expandedRowIds` is not provided, i.e. when the expanded state is uncontrolled.
|
|
21
|
+
*/
|
|
22
|
+
defaultExpandedRowIds?: TableRowEntryId[];
|
|
23
|
+
/**
|
|
24
|
+
* Called when the list of expanded row IDs changes.
|
|
25
|
+
*/
|
|
26
|
+
onExpandedRowIdsChange?: (ids: TableRowEntryId[]) => void;
|
|
27
|
+
/**
|
|
28
|
+
* Function to get whether a row should be expandable.
|
|
29
|
+
* By default, all rows are expandable when `getRows` is provided.
|
|
30
|
+
*/
|
|
14
31
|
isRowExpandable?: (rowData: T) => boolean;
|
|
15
|
-
onExpandedRowIdsChange?: (ids: (string | number)[]) => void;
|
|
16
32
|
};
|
|
17
33
|
|
|
18
34
|
type UseTableItemsArgs<T> = {
|
|
@@ -21,19 +37,19 @@ type UseTableItemsArgs<T> = {
|
|
|
21
37
|
subRows?: SubRowsProps<T>;
|
|
22
38
|
};
|
|
23
39
|
|
|
24
|
-
type
|
|
40
|
+
type UseTableItemsReturn<T> = {
|
|
25
41
|
items: T[];
|
|
26
42
|
itemDetails: Map<TableRowEntryId, ItemDetail<T>>;
|
|
27
43
|
/** Row ids for the rows currently rendered in the table body. */
|
|
28
44
|
visibleRowIds: TableRowEntryId[];
|
|
29
45
|
/** Direct child ids for each row, used to traverse selection groups lazily. */
|
|
30
46
|
childRowIdsById: Map<TableRowEntryId, TableRowEntryId[]>;
|
|
31
|
-
onExpandedRowIdsChange: (id:
|
|
32
|
-
isSubRowExpanded: (id:
|
|
47
|
+
onExpandedRowIdsChange: (id: TableRowEntryId) => void;
|
|
48
|
+
isSubRowExpanded: (id: TableRowEntryId) => boolean;
|
|
33
49
|
};
|
|
34
50
|
|
|
35
|
-
function useTableItems<T>(args: UseTableItemsArgs<T>):
|
|
36
|
-
const { items, subRows
|
|
51
|
+
function useTableItems<T>(args: UseTableItemsArgs<T>): UseTableItemsReturn<T> {
|
|
52
|
+
const { items, subRows, getRowId } = args;
|
|
37
53
|
|
|
38
54
|
const {
|
|
39
55
|
expandedRowIds,
|
|
@@ -41,7 +57,7 @@ function useTableItems<T>(args: UseTableItemsArgs<T>): useTableItemsReturn<T> {
|
|
|
41
57
|
getRows,
|
|
42
58
|
onExpandedRowIdsChange,
|
|
43
59
|
isRowExpandable,
|
|
44
|
-
} = subRows;
|
|
60
|
+
} = subRows || {};
|
|
45
61
|
|
|
46
62
|
const [nestedSubRowsExpandedIds, setNestedSubRowsExpandedIds] =
|
|
47
63
|
useControllableState({
|
|
@@ -106,7 +122,7 @@ function useTableItems<T>(args: UseTableItemsArgs<T>): useTableItemsReturn<T> {
|
|
|
106
122
|
}, [getRows, items, getRowId, isRowExpandable, expandedIdsSet]);
|
|
107
123
|
|
|
108
124
|
const handleExpandedSubRowIdChange = useCallback(
|
|
109
|
-
(id:
|
|
125
|
+
(id: TableRowEntryId) => {
|
|
110
126
|
setNestedSubRowsExpandedIds((prev) =>
|
|
111
127
|
prev.includes(id)
|
|
112
128
|
? prev.filter((expandedId) => expandedId !== id)
|
|
@@ -122,17 +138,9 @@ function useTableItems<T>(args: UseTableItemsArgs<T>): useTableItemsReturn<T> {
|
|
|
122
138
|
visibleRowIds,
|
|
123
139
|
childRowIdsById,
|
|
124
140
|
onExpandedRowIdsChange: handleExpandedSubRowIdChange,
|
|
125
|
-
isSubRowExpanded: (id:
|
|
141
|
+
isSubRowExpanded: (id: TableRowEntryId) => expandedIdsSet.has(id),
|
|
126
142
|
};
|
|
127
143
|
}
|
|
128
144
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
createStrictContext<Omit<useTableItemsReturn<any>, "childRowIdsById">>({
|
|
132
|
-
name: "TableItemsContext",
|
|
133
|
-
errorMessage:
|
|
134
|
-
"useTableItemsContext must be used within a TableItemsProvider",
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
export { useTableItems, TableItemsProvider, useTableItemsContext };
|
|
138
|
-
export type { ItemDetail, SubRowsProps };
|
|
145
|
+
export { useTableItems };
|
|
146
|
+
export type { ItemDetail, SubRowsProps, UseTableItemsReturn };
|
|
@@ -18,17 +18,9 @@ import { useGridCache } from "./useGridCache";
|
|
|
18
18
|
|
|
19
19
|
type UseTableKeyboardNavOptions = {
|
|
20
20
|
enabled: boolean;
|
|
21
|
-
/**
|
|
22
|
-
* Custom callback to determine if navigation should be blocked.
|
|
23
|
-
* Called before default blocking logic.
|
|
24
|
-
*/
|
|
25
|
-
shouldBlockNavigation?: (event: KeyboardEvent) => boolean;
|
|
26
21
|
};
|
|
27
22
|
|
|
28
|
-
function useTableKeyboardNav({
|
|
29
|
-
enabled,
|
|
30
|
-
shouldBlockNavigation: customBlockFn,
|
|
31
|
-
}: UseTableKeyboardNavOptions) {
|
|
23
|
+
function useTableKeyboardNav({ enabled }: UseTableKeyboardNavOptions) {
|
|
32
24
|
const [tableRef, setTableRef] = useState<HTMLTableElement | null>(null);
|
|
33
25
|
const { getTableGrid, activeCell, setActiveCell } = useGridCache(
|
|
34
26
|
tableRef,
|
|
@@ -110,10 +102,6 @@ function useTableKeyboardNav({
|
|
|
110
102
|
* Checks if navigation should be blocked based on current focus context.
|
|
111
103
|
*/
|
|
112
104
|
const handleTableKeyDown = useEventCallback((event: KeyboardEvent): void => {
|
|
113
|
-
if (customBlockFn?.(event)) {
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
105
|
const action = getNavigationAction(event);
|
|
118
106
|
if (!action) {
|
|
119
107
|
return;
|