@navikt/ds-react 8.10.4 → 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 +11 -13
- package/cjs/data/drag-and-drop/drag-handler/DragAndDropDragHandler.js.map +1 -1
- package/cjs/data/drag-and-drop/root/DragAndDrop.context.d.ts +4 -2
- package/cjs/data/drag-and-drop/root/DragAndDrop.context.js.map +1 -1
- package/cjs/data/drag-and-drop/root/DragAndDropRoot.js +44 -46
- package/cjs/data/drag-and-drop/root/DragAndDropRoot.js.map +1 -1
- package/cjs/data/drag-and-drop/types.d.ts +0 -4
- package/cjs/data/stories/Data.test-data.d.ts +2 -5
- package/cjs/data/stories/Data.test-data.js +30 -39
- 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 +9 -7
- package/cjs/data/table/helpers/collectTableRowEntries.js +18 -10
- package/cjs/data/table/helpers/collectTableRowEntries.js.map +1 -1
- 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/helpers/table-focus.d.ts +0 -3
- package/cjs/data/table/helpers/table-focus.js +38 -8
- package/cjs/data/table/helpers/table-focus.js.map +1 -1
- 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/useGridCache.js +2 -2
- package/cjs/data/table/hooks/useGridCache.js.map +1 -1
- package/cjs/data/table/hooks/useTableDetailsPanel.d.ts +10 -13
- package/cjs/data/table/hooks/useTableDetailsPanel.js +7 -6
- package/cjs/data/table/hooks/useTableDetailsPanel.js.map +1 -1
- package/cjs/data/table/hooks/useTableItems.d.ts +31 -17
- package/cjs/data/table/hooks/useTableItems.js +10 -20
- 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 +6 -5
- 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 -13
- 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 +56 -72
- 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 +11 -13
- package/esm/data/drag-and-drop/drag-handler/DragAndDropDragHandler.js.map +1 -1
- package/esm/data/drag-and-drop/root/DragAndDrop.context.d.ts +4 -2
- package/esm/data/drag-and-drop/root/DragAndDrop.context.js.map +1 -1
- package/esm/data/drag-and-drop/root/DragAndDropRoot.js +44 -46
- package/esm/data/drag-and-drop/root/DragAndDropRoot.js.map +1 -1
- package/esm/data/drag-and-drop/types.d.ts +0 -4
- package/esm/data/stories/Data.test-data.d.ts +2 -5
- package/esm/data/stories/Data.test-data.js +30 -39
- 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 +9 -7
- package/esm/data/table/helpers/collectTableRowEntries.js +18 -10
- package/esm/data/table/helpers/collectTableRowEntries.js.map +1 -1
- 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/helpers/table-focus.d.ts +0 -3
- package/esm/data/table/helpers/table-focus.js +38 -8
- package/esm/data/table/helpers/table-focus.js.map +1 -1
- 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/useGridCache.js +2 -2
- package/esm/data/table/hooks/useGridCache.js.map +1 -1
- package/esm/data/table/hooks/useTableDetailsPanel.d.ts +10 -13
- package/esm/data/table/hooks/useTableDetailsPanel.js +7 -6
- package/esm/data/table/hooks/useTableDetailsPanel.js.map +1 -1
- package/esm/data/table/hooks/useTableItems.d.ts +31 -17
- package/esm/data/table/hooks/useTableItems.js +11 -18
- 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 +7 -6
- 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 -13
- 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 +58 -74
- 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 +8 -7
- 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 +11 -17
- package/src/data/drag-and-drop/root/DragAndDrop.context.tsx +4 -2
- package/src/data/drag-and-drop/root/DragAndDropRoot.tsx +63 -52
- package/src/data/drag-and-drop/types.ts +0 -5
- package/src/data/stories/Data.test-data.tsx +52 -44
- 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 +63 -58
- package/src/data/table/column-header/useTableColumnResize.ts +55 -71
- package/src/data/table/details-panel-row/DataTableDetailsPanelRow.tsx +7 -3
- package/src/data/table/helpers/collectTableRowEntries.ts +32 -19
- 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/helpers/table-focus.ts +63 -9
- package/src/data/table/hooks/__tests__/useTableItems.test.ts +48 -8
- package/src/data/table/hooks/useColumnOptions.ts +48 -14
- package/src/data/table/hooks/useGridCache.ts +3 -2
- package/src/data/table/hooks/useTableDetailsPanel.tsx +25 -25
- package/src/data/table/hooks/useTableItems.ts +51 -42
- package/src/data/table/hooks/useTableKeyboardNav.ts +7 -15
- 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 -25
- 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 +271 -320
- 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-old/drag-handler/DataDragAndDropDragHandler.d.ts +0 -22
- package/cjs/data/drag-and-drop-old/drag-handler/DataDragAndDropDragHandler.js +0 -35
- package/cjs/data/drag-and-drop-old/drag-handler/DataDragAndDropDragHandler.js.map +0 -1
- package/cjs/data/drag-and-drop-old/item/DataDragAndDropItem.d.ts +0 -27
- package/cjs/data/drag-and-drop-old/item/DataDragAndDropItem.js +0 -86
- package/cjs/data/drag-and-drop-old/item/DataDragAndDropItem.js.map +0 -1
- package/cjs/data/drag-and-drop-old/root/DataDragAndDrop.context.d.ts +0 -5
- package/cjs/data/drag-and-drop-old/root/DataDragAndDrop.context.js +0 -6
- package/cjs/data/drag-and-drop-old/root/DataDragAndDrop.context.js.map +0 -1
- package/cjs/data/drag-and-drop-old/root/DataDragAndDropRoot.d.ts +0 -24
- package/cjs/data/drag-and-drop-old/root/DataDragAndDropRoot.js +0 -108
- package/cjs/data/drag-and-drop-old/root/DataDragAndDropRoot.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-old/drag-handler/DataDragAndDropDragHandler.d.ts +0 -22
- package/esm/data/drag-and-drop-old/drag-handler/DataDragAndDropDragHandler.js +0 -29
- package/esm/data/drag-and-drop-old/drag-handler/DataDragAndDropDragHandler.js.map +0 -1
- package/esm/data/drag-and-drop-old/item/DataDragAndDropItem.d.ts +0 -27
- package/esm/data/drag-and-drop-old/item/DataDragAndDropItem.js +0 -50
- package/esm/data/drag-and-drop-old/item/DataDragAndDropItem.js.map +0 -1
- package/esm/data/drag-and-drop-old/root/DataDragAndDrop.context.d.ts +0 -5
- package/esm/data/drag-and-drop-old/root/DataDragAndDrop.context.js +0 -3
- package/esm/data/drag-and-drop-old/root/DataDragAndDrop.context.js.map +0 -1
- package/esm/data/drag-and-drop-old/root/DataDragAndDropRoot.d.ts +0 -24
- package/esm/data/drag-and-drop-old/root/DataDragAndDropRoot.js +0 -68
- package/esm/data/drag-and-drop-old/root/DataDragAndDropRoot.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-old/drag-handler/DataDragAndDropDragHandler.tsx +0 -104
- package/src/data/drag-and-drop-old/item/DataDragAndDropItem.tsx +0 -74
- package/src/data/drag-and-drop-old/root/DataDragAndDrop.context.tsx +0 -11
- package/src/data/drag-and-drop-old/root/DataDragAndDropRoot.tsx +0 -96
- 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
|
@@ -1,107 +1,87 @@
|
|
|
1
|
+
import type { ChangeEventHandler, SetStateAction } from "react";
|
|
1
2
|
import type { CheckboxInputProps } from "../../../../form/checkbox/checkbox-input/CheckboxInput";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
type
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
3
|
+
import { consoleWarning } from "../../../../utils/helpers/consoleWarning";
|
|
4
|
+
import type { UseTableItemsReturn } from "../../hooks/useTableItems";
|
|
5
|
+
import type { TableRowEntryId } from "../../root/DataTable.types";
|
|
6
|
+
import type { SelectedKeysT, SelectionProps } from "./selection.types";
|
|
7
|
+
import { canSelectTableRow, mutateRowSelection } from "./selection.utils";
|
|
8
|
+
|
|
9
|
+
type GetMultipleSelectPropsArgs<T> = {
|
|
10
|
+
selectedKeysSet: Set<TableRowEntryId>;
|
|
11
|
+
selectedKeys: SelectedKeysT;
|
|
12
|
+
setSelectedKeys: (next: SetStateAction<SelectedKeysT>) => void;
|
|
13
|
+
tableItems: UseTableItemsReturn<T>;
|
|
14
|
+
} & Pick<SelectionProps<T>, "enableRowSelection">;
|
|
15
|
+
|
|
16
|
+
function getMultipleSelectProps<T>({
|
|
14
17
|
selectedKeysSet,
|
|
15
18
|
selectedKeys,
|
|
16
19
|
setSelectedKeys,
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
// Header selection traverses the visible roots and skips already visited
|
|
28
|
-
// descendants, so expanded trees stay linear in the number of rows.
|
|
29
|
-
const headerSelectableKeys = subtreeHelper.getSelectableKeys(visibleRowIds);
|
|
30
|
-
const headerSelectableKeysSet = new Set(headerSelectableKeys);
|
|
31
|
-
|
|
32
|
-
const selectedSelectableCount = headerSelectableKeys.filter((k) =>
|
|
33
|
-
selectedKeysSet.has(k),
|
|
34
|
-
).length;
|
|
35
|
-
|
|
36
|
-
const allSelectableSelected =
|
|
37
|
-
headerSelectableKeys.length > 0 &&
|
|
38
|
-
selectedSelectableCount === headerSelectableKeys.length;
|
|
39
|
-
|
|
40
|
-
const indeterminate =
|
|
41
|
-
selectedSelectableCount > 0 &&
|
|
42
|
-
selectedSelectableCount < headerSelectableKeys.length;
|
|
43
|
-
|
|
44
|
-
const selectedKeysNotInView = selectedKeys.filter(
|
|
45
|
-
(k) => !headerSelectableKeysSet.has(k),
|
|
46
|
-
);
|
|
47
|
-
const disabledSelected = selectedKeys.filter((k) => disabledKeysSet.has(k));
|
|
48
|
-
const preservedKeys = [
|
|
49
|
-
...new Set([...selectedKeysNotInView, ...disabledSelected]),
|
|
50
|
-
];
|
|
20
|
+
enableRowSelection,
|
|
21
|
+
tableItems,
|
|
22
|
+
}: GetMultipleSelectPropsArgs<T>) {
|
|
23
|
+
const selectableIdsSet: Set<TableRowEntryId> = new Set();
|
|
24
|
+
|
|
25
|
+
for (const [id, { rowData }] of tableItems.itemDetails) {
|
|
26
|
+
if (canSelectTableRow(enableRowSelection, { row: rowData, id })) {
|
|
27
|
+
selectableIdsSet.add(id);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
51
30
|
|
|
52
|
-
|
|
53
|
-
|
|
31
|
+
let selectedOnPageCount = 0;
|
|
32
|
+
for (const id of selectableIdsSet) {
|
|
33
|
+
selectedKeysSet.has(id) && selectedOnPageCount++;
|
|
34
|
+
}
|
|
54
35
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
);
|
|
59
|
-
};
|
|
36
|
+
const isAllSelected =
|
|
37
|
+
selectableIdsSet.size > 0 && selectedOnPageCount === selectableIdsSet.size;
|
|
38
|
+
const someSelected = selectedOnPageCount > 0;
|
|
60
39
|
|
|
61
|
-
const
|
|
62
|
-
if (
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
...new Set([...preservedKeys, ...headerSelectableKeys]),
|
|
67
|
-
]);
|
|
40
|
+
const handleToggleRow = (key: TableRowEntryId, row: T) => {
|
|
41
|
+
if (!row) {
|
|
42
|
+
consoleWarning(
|
|
43
|
+
`Row data is undefined for key ${key}. This may cause issues with selection if enableRowSelection is used.`,
|
|
44
|
+
);
|
|
68
45
|
}
|
|
69
|
-
};
|
|
70
46
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
47
|
+
const checked = !selectedKeysSet.has(key);
|
|
48
|
+
const nextSet = new Set(selectedKeysSet);
|
|
49
|
+
const changed = mutateRowSelection({
|
|
50
|
+
selectedRowIds: nextSet,
|
|
51
|
+
rowId: key,
|
|
52
|
+
checked,
|
|
53
|
+
childRowIdsById: tableItems.childRowIdsById,
|
|
54
|
+
itemDetails: tableItems.itemDetails,
|
|
55
|
+
enableRowSelection,
|
|
56
|
+
});
|
|
57
|
+
if (changed) {
|
|
58
|
+
setSelectedKeys([...nextSet]);
|
|
74
59
|
}
|
|
60
|
+
};
|
|
75
61
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
);
|
|
62
|
+
const toggleAllRowSelected: ChangeEventHandler<HTMLInputElement> = (
|
|
63
|
+
event,
|
|
64
|
+
) => {
|
|
65
|
+
if (event.target.checked) {
|
|
66
|
+
const preserved = selectedKeys.filter((k) => !selectableIdsSet.has(k));
|
|
67
|
+
setSelectedKeys([...preserved, ...selectableIdsSet]);
|
|
83
68
|
} else {
|
|
84
|
-
setSelectedKeys(
|
|
69
|
+
setSelectedKeys(selectedKeys.filter((k) => !selectableIdsSet.has(k)));
|
|
85
70
|
}
|
|
86
71
|
};
|
|
87
72
|
|
|
88
73
|
return {
|
|
89
74
|
getTheadCheckboxProps: (): CheckboxInputProps => ({
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
disabled: headerSelectableKeys.length === 0,
|
|
75
|
+
checked: isAllSelected,
|
|
76
|
+
indeterminate: !isAllSelected && someSelected,
|
|
77
|
+
onChange: toggleAllRowSelected,
|
|
94
78
|
}),
|
|
95
|
-
getRowCheckboxProps: (key:
|
|
96
|
-
const groupStats = subtreeHelper.getSelectionStats(key);
|
|
97
|
-
|
|
79
|
+
getRowCheckboxProps: (key: TableRowEntryId, row: T): CheckboxInputProps => {
|
|
98
80
|
return {
|
|
99
|
-
onChange: () => handleToggleRow(key),
|
|
100
|
-
checked:
|
|
101
|
-
indeterminate:
|
|
102
|
-
|
|
103
|
-
groupStats.selectedCount < groupStats.selectableCount,
|
|
104
|
-
disabled: disabledKeysSet.has(key),
|
|
81
|
+
onChange: () => handleToggleRow(key, row),
|
|
82
|
+
checked: selectedKeysSet.has(key),
|
|
83
|
+
indeterminate: false,
|
|
84
|
+
disabled: !canSelectTableRow(enableRowSelection, { row, id: key }),
|
|
105
85
|
};
|
|
106
86
|
},
|
|
107
87
|
toggleSelection: handleToggleRow,
|
|
@@ -1,33 +1,51 @@
|
|
|
1
1
|
import type { RadioInputProps } from "../../../../form/radio/radio-input/RadioInput";
|
|
2
|
+
import { consoleWarning } from "../../../../utils/helpers/consoleWarning";
|
|
3
|
+
import type { TableRowEntryId } from "../../root/DataTable.types";
|
|
4
|
+
import type { SelectedKeysT, SelectionProps } from "./selection.types";
|
|
5
|
+
import { canSelectTableRow } from "./selection.utils";
|
|
2
6
|
|
|
3
|
-
type GetSingleSelectPropsArgs = {
|
|
4
|
-
selectedKeysSet: Set<
|
|
5
|
-
setSelectedKeys: (keys:
|
|
6
|
-
disabledKeysSet: Set<string | number>;
|
|
7
|
+
type GetSingleSelectPropsArgs<T> = {
|
|
8
|
+
selectedKeysSet: Set<TableRowEntryId>;
|
|
9
|
+
setSelectedKeys: (keys: SelectedKeysT) => void;
|
|
7
10
|
name: string;
|
|
8
|
-
}
|
|
11
|
+
} & Pick<SelectionProps<T>, "enableRowSelection">;
|
|
9
12
|
|
|
10
|
-
function getSingleSelectProps({
|
|
13
|
+
function getSingleSelectProps<T>({
|
|
11
14
|
selectedKeysSet,
|
|
12
15
|
setSelectedKeys,
|
|
13
|
-
disabledKeysSet,
|
|
14
16
|
name,
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
enableRowSelection,
|
|
18
|
+
}: GetSingleSelectPropsArgs<T>) {
|
|
19
|
+
const handleSelectionChange = (key: TableRowEntryId, row: T) => {
|
|
20
|
+
if (!row) {
|
|
21
|
+
consoleWarning(
|
|
22
|
+
`Row data is undefined for key ${key}. This may cause issues with selection if enableRowSelection is used.`,
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
if (!canSelectTableRow(enableRowSelection, { row, id: key })) {
|
|
18
26
|
return;
|
|
19
27
|
}
|
|
28
|
+
|
|
20
29
|
setSelectedKeys([key]);
|
|
21
30
|
};
|
|
22
31
|
|
|
23
32
|
return {
|
|
24
|
-
getRowRadioProps: (key:
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
33
|
+
getRowRadioProps: (key: TableRowEntryId, row: T): RadioInputProps => {
|
|
34
|
+
const isSelectionDisabled = !canSelectTableRow(enableRowSelection, {
|
|
35
|
+
row,
|
|
36
|
+
id: key,
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
return {
|
|
40
|
+
checked: selectedKeysSet.has(key),
|
|
41
|
+
onChange: isSelectionDisabled
|
|
42
|
+
? () => null
|
|
43
|
+
: () => handleSelectionChange(key, row),
|
|
44
|
+
disabled: isSelectionDisabled,
|
|
45
|
+
value: key,
|
|
46
|
+
name,
|
|
47
|
+
};
|
|
48
|
+
},
|
|
31
49
|
toggleSelection: handleSelectionChange,
|
|
32
50
|
};
|
|
33
51
|
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type { CheckboxInputProps } from "../../../../form/checkbox/checkbox-input/CheckboxInput";
|
|
2
2
|
import type { RadioInputProps } from "../../../../form/radio/radio-input/RadioInput";
|
|
3
|
+
import type { TableRowEntryId } from "../../root/DataTable.types";
|
|
3
4
|
|
|
4
|
-
type SelectedKeysT =
|
|
5
|
+
type SelectedKeysT = TableRowEntryId[];
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
// TODO: Remove `any` if possible
|
|
8
|
+
type SelectionProps<T = any> = {
|
|
7
9
|
/**
|
|
8
10
|
* Enables selection of rows.
|
|
9
11
|
*
|
|
@@ -14,7 +16,7 @@ type SelectionProps = {
|
|
|
14
16
|
*
|
|
15
17
|
* @default "none"
|
|
16
18
|
*/
|
|
17
|
-
selectionMode
|
|
19
|
+
selectionMode: "none" | "single" | "multiple";
|
|
18
20
|
/**
|
|
19
21
|
* Controlled selected keys. Should be used in conjunction with `onSelectionChange`.
|
|
20
22
|
*/
|
|
@@ -28,45 +30,43 @@ type SelectionProps = {
|
|
|
28
30
|
*/
|
|
29
31
|
onSelectionChange?: (keys: SelectedKeysT) => void;
|
|
30
32
|
/**
|
|
31
|
-
*
|
|
33
|
+
* Callback to determine if a row should be enabled for selection.
|
|
32
34
|
*
|
|
33
35
|
*
|
|
34
|
-
*
|
|
36
|
+
* If set to a boolean, it will enable selection for all rows when true, and disable selection for all rows when false.
|
|
35
37
|
*/
|
|
36
|
-
|
|
38
|
+
enableRowSelection?:
|
|
39
|
+
| (({ row, id }: { row: T; id: TableRowEntryId }) => boolean)
|
|
40
|
+
| boolean;
|
|
37
41
|
/**
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* @default false
|
|
42
|
+
* Determines if selection is triggered by clicking the row or the selection control (checkbox/radio).
|
|
43
|
+
* @default "row"
|
|
41
44
|
*/
|
|
42
|
-
|
|
45
|
+
selectionTrigger?: "row" | "control";
|
|
43
46
|
};
|
|
44
47
|
|
|
45
48
|
type NoneSelection = {
|
|
46
49
|
selectionMode: "none";
|
|
47
50
|
selectedKeys: SelectedKeysT;
|
|
48
|
-
disabledSelectionKeys: SelectedKeysT;
|
|
49
51
|
};
|
|
50
52
|
|
|
51
53
|
type SingleSelection = {
|
|
52
54
|
selectionMode: "single";
|
|
53
55
|
selectedKeys: SelectedKeysT;
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
toggleSelection: (key: string | number) => void;
|
|
56
|
+
getRowRadioProps: (key: TableRowEntryId, row: any) => RadioInputProps;
|
|
57
|
+
toggleSelection: (key: TableRowEntryId, row: any) => void;
|
|
57
58
|
};
|
|
58
59
|
|
|
59
60
|
type MultipleSelection = {
|
|
60
61
|
selectionMode: "multiple";
|
|
61
62
|
selectedKeys: SelectedKeysT;
|
|
62
|
-
disabledSelectionKeys: SelectedKeysT;
|
|
63
63
|
getTheadCheckboxProps: () => CheckboxInputProps;
|
|
64
|
-
getRowCheckboxProps: (key:
|
|
65
|
-
toggleSelection: (key:
|
|
64
|
+
getRowCheckboxProps: (key: TableRowEntryId, row: any) => CheckboxInputProps;
|
|
65
|
+
toggleSelection: (key: TableRowEntryId, row: any) => void;
|
|
66
66
|
};
|
|
67
67
|
|
|
68
68
|
type TableSelectionBase = {
|
|
69
|
-
isRowSelected: (rowId:
|
|
69
|
+
isRowSelected: (rowId: TableRowEntryId) => boolean;
|
|
70
70
|
};
|
|
71
71
|
|
|
72
72
|
type TableSelection = TableSelectionBase &
|
|
@@ -75,8 +75,8 @@ type TableSelection = TableSelectionBase &
|
|
|
75
75
|
export type {
|
|
76
76
|
MultipleSelection,
|
|
77
77
|
NoneSelection,
|
|
78
|
+
SelectedKeysT,
|
|
78
79
|
SelectionProps,
|
|
79
80
|
SingleSelection,
|
|
80
81
|
TableSelection,
|
|
81
|
-
SelectedKeysT,
|
|
82
82
|
};
|
|
@@ -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 };
|
|
@@ -121,16 +121,70 @@ function prepareCellFocus(cell: Element): HTMLElement | null {
|
|
|
121
121
|
/**
|
|
122
122
|
* Applies focus and scroll to an element.
|
|
123
123
|
*/
|
|
124
|
+
function getStickyOffsets(element: HTMLElement): {
|
|
125
|
+
stickyOffsetStart: number;
|
|
126
|
+
stickyOffsetEnd: number;
|
|
127
|
+
stickyHeaderHeight: number;
|
|
128
|
+
} {
|
|
129
|
+
const table = element.closest(".aksel-data-table");
|
|
130
|
+
|
|
131
|
+
if (!table) {
|
|
132
|
+
return {
|
|
133
|
+
stickyOffsetStart: 0,
|
|
134
|
+
stickyOffsetEnd: 0,
|
|
135
|
+
stickyHeaderHeight: 0,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const stickyHeader = table.querySelector<HTMLElement>(
|
|
140
|
+
`.aksel-data-table__tr[data-sticky="true"]`,
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
const stickyNodesStart = table.querySelectorAll<HTMLElement>(
|
|
144
|
+
`.aksel-data-table__column-header[data-sticky="start"]`,
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
const stickyNodesEnd = table.querySelectorAll<HTMLElement>(
|
|
148
|
+
`.aksel-data-table__column-header[data-sticky="end"]`,
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
return {
|
|
152
|
+
stickyOffsetStart: Array.from(stickyNodesStart).reduce(
|
|
153
|
+
(offset, node) => offset + node.getBoundingClientRect().width,
|
|
154
|
+
0,
|
|
155
|
+
),
|
|
156
|
+
stickyOffsetEnd: Array.from(stickyNodesEnd).reduce(
|
|
157
|
+
(offset, node) => offset + node.getBoundingClientRect().width,
|
|
158
|
+
0,
|
|
159
|
+
),
|
|
160
|
+
stickyHeaderHeight: stickyHeader?.getBoundingClientRect().height ?? 0,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
|
|
124
164
|
function applyFocusAndScroll(element: HTMLElement): void {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
element.
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
165
|
+
const { stickyOffsetStart, stickyOffsetEnd, stickyHeaderHeight } =
|
|
166
|
+
getStickyOffsets(element);
|
|
167
|
+
|
|
168
|
+
const originalScrollMarginInline = element.style.scrollMarginInline;
|
|
169
|
+
const originalScrollMarginBlockStart = element.style.scrollMarginBlockStart;
|
|
170
|
+
|
|
171
|
+
element.style.scrollMarginInline = `${stickyOffsetStart}px ${stickyOffsetEnd}px`;
|
|
172
|
+
element.style.scrollMarginBlockStart = `${stickyHeaderHeight}px`;
|
|
173
|
+
|
|
174
|
+
try {
|
|
175
|
+
element.focus({
|
|
176
|
+
preventScroll: true,
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
element.scrollIntoView({
|
|
180
|
+
behavior: "auto",
|
|
181
|
+
block: "nearest",
|
|
182
|
+
inline: "nearest",
|
|
183
|
+
});
|
|
184
|
+
} finally {
|
|
185
|
+
element.style.scrollMarginBlockStart = originalScrollMarginBlockStart;
|
|
186
|
+
element.style.scrollMarginInline = originalScrollMarginInline;
|
|
187
|
+
}
|
|
134
188
|
}
|
|
135
189
|
|
|
136
190
|
/**
|