@vuu-ui/vuu-table 0.8.99 → 0.9.1
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/Row.css.js +1 -1
- package/cjs/Row.js +20 -7
- package/cjs/Row.js.map +1 -1
- package/cjs/Table.css.js +1 -1
- package/cjs/Table.js +31 -19
- package/cjs/Table.js.map +1 -1
- package/cjs/cell-block/CellBlock.css.js +1 -1
- package/cjs/cell-block/CellBlock.js +4 -0
- package/cjs/cell-block/CellBlock.js.map +1 -1
- package/cjs/cell-block/cellblock-utils.js +7 -22
- package/cjs/cell-block/cellblock-utils.js.map +1 -1
- package/cjs/cell-block/useCellBlockSelection.js +37 -15
- package/cjs/cell-block/useCellBlockSelection.js.map +1 -1
- package/cjs/column-header-pill/ColumnHeaderPill.js +2 -1
- package/cjs/column-header-pill/ColumnHeaderPill.js.map +1 -1
- package/cjs/column-menu/ColumnMenu.css.js +1 -1
- package/cjs/context-menu/buildContextMenuDescriptors.js +2 -2
- package/cjs/context-menu/buildContextMenuDescriptors.js.map +1 -1
- package/cjs/context-menu/useHandleTableContextMenu.js +2 -2
- package/cjs/context-menu/useHandleTableContextMenu.js.map +1 -1
- package/cjs/header-cell/GroupHeaderCell.css.js +1 -1
- package/cjs/header-cell/GroupHeaderCell.js +10 -1
- package/cjs/header-cell/GroupHeaderCell.js.map +1 -1
- package/cjs/header-cell/HeaderCell.css.js +1 -1
- package/cjs/table-cell/TableCell.css.js +1 -1
- package/cjs/table-cell/TableGroupCell.css.js +1 -1
- package/cjs/table-cell/TableGroupCell.js +16 -7
- package/cjs/table-cell/TableGroupCell.js.map +1 -1
- package/cjs/table-dom-utils.js +100 -28
- package/cjs/table-dom-utils.js.map +1 -1
- package/cjs/table-header/TableHeader.js +105 -66
- package/cjs/table-header/TableHeader.js.map +1 -1
- package/cjs/table-header/useTableHeader.js +9 -1
- package/cjs/table-header/useTableHeader.js.map +1 -1
- package/cjs/useCell.js +1 -2
- package/cjs/useCell.js.map +1 -1
- package/cjs/useCellFocus.js +3 -3
- package/cjs/useCellFocus.js.map +1 -1
- package/cjs/useKeyboardNavigation.js +93 -48
- package/cjs/useKeyboardNavigation.js.map +1 -1
- package/cjs/useSelection.js +2 -1
- package/cjs/useSelection.js.map +1 -1
- package/cjs/useTable.js +42 -21
- package/cjs/useTable.js.map +1 -1
- package/cjs/useTableContextMenu.js +5 -4
- package/cjs/useTableContextMenu.js.map +1 -1
- package/cjs/useTableModel.js +24 -9
- package/cjs/useTableModel.js.map +1 -1
- package/cjs/useTableScroll.js +2 -2
- package/cjs/useTableScroll.js.map +1 -1
- package/esm/Row.css.js +1 -1
- package/esm/Row.js +21 -8
- package/esm/Row.js.map +1 -1
- package/esm/Table.css.js +1 -1
- package/esm/Table.js +31 -19
- package/esm/Table.js.map +1 -1
- package/esm/cell-block/CellBlock.css.js +1 -1
- package/esm/cell-block/CellBlock.js +4 -0
- package/esm/cell-block/CellBlock.js.map +1 -1
- package/esm/cell-block/cellblock-utils.js +8 -23
- package/esm/cell-block/cellblock-utils.js.map +1 -1
- package/esm/cell-block/useCellBlockSelection.js +38 -16
- package/esm/cell-block/useCellBlockSelection.js.map +1 -1
- package/esm/column-header-pill/ColumnHeaderPill.js +2 -1
- package/esm/column-header-pill/ColumnHeaderPill.js.map +1 -1
- package/esm/column-menu/ColumnMenu.css.js +1 -1
- package/esm/context-menu/buildContextMenuDescriptors.js +2 -2
- package/esm/context-menu/buildContextMenuDescriptors.js.map +1 -1
- package/esm/context-menu/useHandleTableContextMenu.js +2 -2
- package/esm/context-menu/useHandleTableContextMenu.js.map +1 -1
- package/esm/header-cell/GroupHeaderCell.css.js +1 -1
- package/esm/header-cell/GroupHeaderCell.js +10 -1
- package/esm/header-cell/GroupHeaderCell.js.map +1 -1
- package/esm/header-cell/HeaderCell.css.js +1 -1
- package/esm/table-cell/TableCell.css.js +1 -1
- package/esm/table-cell/TableGroupCell.css.js +1 -1
- package/esm/table-cell/TableGroupCell.js +18 -9
- package/esm/table-cell/TableGroupCell.js.map +1 -1
- package/esm/table-dom-utils.js +94 -26
- package/esm/table-dom-utils.js.map +1 -1
- package/esm/table-header/TableHeader.js +106 -67
- package/esm/table-header/TableHeader.js.map +1 -1
- package/esm/table-header/useTableHeader.js +9 -1
- package/esm/table-header/useTableHeader.js.map +1 -1
- package/esm/useCell.js +1 -2
- package/esm/useCell.js.map +1 -1
- package/esm/useCellFocus.js +3 -3
- package/esm/useCellFocus.js.map +1 -1
- package/esm/useKeyboardNavigation.js +92 -47
- package/esm/useKeyboardNavigation.js.map +1 -1
- package/esm/useSelection.js +3 -2
- package/esm/useSelection.js.map +1 -1
- package/esm/useTable.js +43 -22
- package/esm/useTable.js.map +1 -1
- package/esm/useTableContextMenu.js +6 -5
- package/esm/useTableContextMenu.js.map +1 -1
- package/esm/useTableModel.js +24 -9
- package/esm/useTableModel.js.map +1 -1
- package/esm/useTableScroll.js +4 -4
- package/esm/useTableScroll.js.map +1 -1
- package/package.json +9 -9
- package/types/Row.d.ts +1 -1
- package/types/Table.d.ts +14 -3
- package/types/cell-block/useCellBlockSelection.d.ts +1 -3
- package/types/table-dom-utils.d.ts +10 -4
- package/types/table-header/TableHeader.d.ts +1 -1
- package/types/table-header/useTableHeader.d.ts +5 -3
- package/types/useKeyboardNavigation.d.ts +5 -2
- package/types/useTable.d.ts +9 -4
- package/types/useTableContextMenu.d.ts +2 -1
- package/types/useTableModel.d.ts +2 -2
package/cjs/useCellFocus.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCellFocus.js","sources":["../src/useCellFocus.ts"],"sourcesContent":["import {\n KeyboardEventHandler,\n MutableRefObject,\n RefCallback,\n RefObject,\n useCallback,\n} from \"react\";\nimport {\n dataCellQuery,\n getTableCell,\n headerCellQuery,\n} from \"./table-dom-utils\";\nimport { ScrollRequestHandler } from \"./useTableScroll\";\nimport { isArrowKey, queryClosest } from \"@vuu-ui/vuu-utils\";\nimport { CellFocusState, CellPos } from \"@vuu-ui/vuu-table-types\";\n\nexport interface CellFocusHookProps {\n cellFocusStateRef: MutableRefObject<CellFocusState>;\n containerRef: RefObject<HTMLElement>;\n disableFocus?: boolean;\n requestScroll?: ScrollRequestHandler;\n}\n\nconst getCellPosition = (el: HTMLElement) => {\n const top = parseInt(el.parentElement?.style.top ?? \"-1\");\n return { top };\n};\n\nexport type FocusCell = (cellPos: CellPos, fromKeyboard?: boolean) => void;\n\nexport const useCellFocus = ({\n cellFocusStateRef,\n containerRef,\n disableFocus = false,\n requestScroll,\n}: CellFocusHookProps) => {\n const focusCellPlaceholderRef = useCallback<RefCallback<HTMLDivElement>>(\n (el) => (cellFocusStateRef.current.placeholderEl = el),\n [cellFocusStateRef],\n );\n\n const focusCell = useCallback<FocusCell>(\n (cellPos, fromKeyboard = false) => {\n if (containerRef.current) {\n const { current: state } = cellFocusStateRef;\n\n if (fromKeyboard && state.outsideViewport) {\n state.cellPos = cellPos;\n } else {\n const activeCell = getTableCell(containerRef, cellPos);\n if (activeCell) {\n if (activeCell !== state.el) {\n state.el?.removeAttribute(\"tabindex\");\n activeCell.setAttribute(\"tabindex\", \"0\");\n\n // TODO no need to measure if we're navigating horizontally\n state.cellPos = cellPos;\n state.el = activeCell;\n state.pos = getCellPosition(activeCell);\n state.outsideViewport = false;\n\n if (state.placeholderEl) {\n state.placeholderEl.style.top = `${state.pos.top}px`;\n }\n }\n // TODO needs to be scroll cell to accommodate horizontal virtualization\n requestScroll?.({ type: \"scroll-row\", rowIndex: cellPos[0] });\n activeCell.focus({ preventScroll: true });\n }\n }\n }\n },\n [cellFocusStateRef, containerRef, requestScroll],\n );\n\n const tableBodyRef = useCallback<RefCallback<HTMLDivElement>>(\n (el) => {\n if (el) {\n const { current: state } = cellFocusStateRef;\n const table = queryClosest<HTMLDivElement>(el, \".vuuTable\");\n if (table) {\n if (state.el === null && !disableFocus) {\n const headerCell = table.querySelector<HTMLDivElement>(\n headerCellQuery(
|
|
1
|
+
{"version":3,"file":"useCellFocus.js","sources":["../src/useCellFocus.ts"],"sourcesContent":["import {\n KeyboardEventHandler,\n MutableRefObject,\n RefCallback,\n RefObject,\n useCallback,\n} from \"react\";\nimport {\n dataCellQuery,\n getTableCell,\n headerCellQuery,\n} from \"./table-dom-utils\";\nimport { ScrollRequestHandler } from \"./useTableScroll\";\nimport { isArrowKey, queryClosest } from \"@vuu-ui/vuu-utils\";\nimport { CellFocusState, CellPos } from \"@vuu-ui/vuu-table-types\";\n\nexport interface CellFocusHookProps {\n cellFocusStateRef: MutableRefObject<CellFocusState>;\n containerRef: RefObject<HTMLElement>;\n disableFocus?: boolean;\n requestScroll?: ScrollRequestHandler;\n}\n\nconst getCellPosition = (el: HTMLElement) => {\n const top = parseInt(el.parentElement?.style.top ?? \"-1\");\n return { top };\n};\n\nexport type FocusCell = (cellPos: CellPos, fromKeyboard?: boolean) => void;\n\nexport const useCellFocus = ({\n cellFocusStateRef,\n containerRef,\n disableFocus = false,\n requestScroll,\n}: CellFocusHookProps) => {\n const focusCellPlaceholderRef = useCallback<RefCallback<HTMLDivElement>>(\n (el) => (cellFocusStateRef.current.placeholderEl = el),\n [cellFocusStateRef],\n );\n\n const focusCell = useCallback<FocusCell>(\n (cellPos, fromKeyboard = false) => {\n if (containerRef.current) {\n const { current: state } = cellFocusStateRef;\n\n if (fromKeyboard && state.outsideViewport) {\n state.cellPos = cellPos;\n } else {\n const activeCell = getTableCell(containerRef, cellPos);\n if (activeCell) {\n if (activeCell !== state.el) {\n state.el?.removeAttribute(\"tabindex\");\n activeCell.setAttribute(\"tabindex\", \"0\");\n\n // TODO no need to measure if we're navigating horizontally\n state.cellPos = cellPos;\n state.el = activeCell;\n state.pos = getCellPosition(activeCell);\n state.outsideViewport = false;\n\n if (state.placeholderEl) {\n state.placeholderEl.style.top = `${state.pos.top}px`;\n }\n }\n // TODO needs to be scroll cell to accommodate horizontal virtualization\n requestScroll?.({ type: \"scroll-row\", rowIndex: cellPos[0] });\n activeCell.focus({ preventScroll: true });\n }\n }\n }\n },\n [cellFocusStateRef, containerRef, requestScroll],\n );\n\n const tableBodyRef = useCallback<RefCallback<HTMLDivElement>>(\n (el) => {\n if (el) {\n const { current: state } = cellFocusStateRef;\n const table = queryClosest<HTMLDivElement>(el, \".vuuTable\");\n if (table) {\n if (state.el === null && !disableFocus) {\n const headerCell = table.querySelector<HTMLDivElement>(\n headerCellQuery(1),\n );\n if (headerCell) {\n headerCell.setAttribute(\"tabindex\", \"0\");\n state.cellPos = [1, 1];\n state.el = headerCell;\n state.pos = { top: -20 };\n if (state.placeholderEl) {\n state.placeholderEl.style.top = `-20px`;\n }\n } else {\n const cell = table.querySelector<HTMLDivElement>(\n dataCellQuery(0, 0),\n );\n if (cell) {\n cell.setAttribute(\"tabindex\", \"0\");\n state.cellPos = [1, 1];\n state.el = cell;\n state.pos = { top: 0 };\n if (state.placeholderEl) {\n state.placeholderEl.style.top = `0px`;\n }\n }\n }\n }\n }\n }\n },\n [cellFocusStateRef, disableFocus],\n );\n\n const focusCellPlaceholderKeyDown = useCallback<KeyboardEventHandler>(\n (evt) => {\n const { outsideViewport, pos } = cellFocusStateRef.current;\n if (pos && isArrowKey(evt.key)) {\n // TODO depends on whether we're scrolling up or down\n if (outsideViewport === \"above\") {\n requestScroll?.({ type: \"scroll-top\", scrollPos: pos.top });\n } else if (outsideViewport === \"below\") {\n requestScroll?.({ type: \"scroll-bottom\", scrollPos: pos.top });\n } else {\n throw Error(\n `cellFocusPlaceholder should not have focus if inside viewport`,\n );\n }\n }\n },\n [cellFocusStateRef, requestScroll],\n );\n\n return {\n focusCell,\n focusCellPlaceholderKeyDown,\n focusCellPlaceholderRef,\n tableBodyRef,\n };\n};\n"],"names":["useCallback","getTableCell","queryClosest","headerCellQuery","dataCellQuery","isArrowKey"],"mappings":"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"}
|
|
@@ -13,12 +13,15 @@ const rowNavigationKeys = /* @__PURE__ */ new Set([
|
|
|
13
13
|
"ArrowDown",
|
|
14
14
|
"ArrowUp"
|
|
15
15
|
]);
|
|
16
|
+
const CellLocator = ".vuuTableCell,.vuuTableHeaderCell,.vuuTableGroupHeaderCell";
|
|
17
|
+
const CellControlLocator = ".vuuColumnMenu,.vuuColumnHeaderPill";
|
|
16
18
|
const cellNavigationKeys = new Set(rowNavigationKeys);
|
|
17
19
|
cellNavigationKeys.add("ArrowLeft");
|
|
18
20
|
cellNavigationKeys.add("ArrowRight");
|
|
19
21
|
const isNavigationKey = (key, navigationStyle) => {
|
|
20
22
|
switch (navigationStyle) {
|
|
21
23
|
case "cell":
|
|
24
|
+
case "tree":
|
|
22
25
|
return cellNavigationKeys.has(key);
|
|
23
26
|
case "row":
|
|
24
27
|
return rowNavigationKeys.has(key);
|
|
@@ -26,14 +29,38 @@ const isNavigationKey = (key, navigationStyle) => {
|
|
|
26
29
|
return false;
|
|
27
30
|
}
|
|
28
31
|
};
|
|
29
|
-
const
|
|
30
|
-
if (e.shiftKey && e.key.match(/Arrow(Left|Right)/)
|
|
32
|
+
const focusControlWithinCell = (e, el) => {
|
|
33
|
+
if (e.shiftKey && e.key.match(/Arrow(Left|Right)/)) {
|
|
31
34
|
if (el?.classList.contains("vuuTableHeaderCell")) {
|
|
32
35
|
const menuButton = el?.querySelector(".vuuColumnMenu");
|
|
33
36
|
if (menuButton) {
|
|
34
37
|
menuButton.focus();
|
|
35
38
|
return true;
|
|
36
39
|
}
|
|
40
|
+
} else if (el?.classList.contains("vuuTableGroupHeaderCell")) {
|
|
41
|
+
const headerPill = el?.querySelector(
|
|
42
|
+
".vuuColumnHeaderPill"
|
|
43
|
+
);
|
|
44
|
+
if (headerPill) {
|
|
45
|
+
headerPill.focus();
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
} else if (el?.classList.contains("vuuColumnHeaderPill")) {
|
|
49
|
+
const nextPill = el.parentElement?.nextElementSibling?.firstChild;
|
|
50
|
+
if (nextPill?.classList.contains("vuuColumnHeaderPill")) {
|
|
51
|
+
nextPill.focus();
|
|
52
|
+
return true;
|
|
53
|
+
} else {
|
|
54
|
+
const removeButton = vuuUtils.queryClosest(
|
|
55
|
+
el,
|
|
56
|
+
".vuuTableGroupHeaderCell",
|
|
57
|
+
true
|
|
58
|
+
).querySelector(".vuuTableGroupHeaderCell-removeAll");
|
|
59
|
+
if (removeButton) {
|
|
60
|
+
removeButton.focus();
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
37
64
|
}
|
|
38
65
|
}
|
|
39
66
|
return false;
|
|
@@ -47,10 +74,12 @@ const useKeyboardNavigation = ({
|
|
|
47
74
|
defaultHighlightedIndex,
|
|
48
75
|
disableHighlightOnFocus,
|
|
49
76
|
focusCell,
|
|
77
|
+
headerCount,
|
|
50
78
|
highlightedIndex: highlightedIndexProp,
|
|
51
79
|
navigationStyle,
|
|
52
80
|
requestScroll,
|
|
53
81
|
onHighlight,
|
|
82
|
+
onToggleGroup,
|
|
54
83
|
rowCount = 0,
|
|
55
84
|
viewportRowCount
|
|
56
85
|
}) => {
|
|
@@ -61,22 +90,15 @@ const useKeyboardNavigation = ({
|
|
|
61
90
|
name: "UseKeyboardNavigation"
|
|
62
91
|
});
|
|
63
92
|
highlightedIndexRef.current = highlightedIndex;
|
|
93
|
+
const maxRowIndex = rowCount + headerCount;
|
|
64
94
|
const setHighlightedIndex = react.useCallback(
|
|
65
95
|
(idx) => {
|
|
66
96
|
onHighlight?.(idx);
|
|
67
97
|
setHighlightedIdx(idx);
|
|
98
|
+
highlightedIndexRef.current = idx;
|
|
68
99
|
},
|
|
69
100
|
[onHighlight, setHighlightedIdx]
|
|
70
101
|
);
|
|
71
|
-
const getFocusedCell = (el) => {
|
|
72
|
-
if (el?.role == "cell" || el?.role === "columnheader") {
|
|
73
|
-
return el;
|
|
74
|
-
} else {
|
|
75
|
-
return el?.closest(
|
|
76
|
-
"[role='columnHeader'],[role='cell']"
|
|
77
|
-
);
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
102
|
const setActiveCell = react.useCallback(
|
|
81
103
|
(rowIdx, colIdx, fromKeyboard = false) => {
|
|
82
104
|
const pos = [rowIdx, colIdx];
|
|
@@ -110,15 +132,15 @@ const useKeyboardNavigation = ({
|
|
|
110
132
|
break;
|
|
111
133
|
}
|
|
112
134
|
case "Home": {
|
|
113
|
-
newRowIdx =
|
|
135
|
+
newRowIdx = headerCount + 1;
|
|
114
136
|
if (newRowIdx !== rowIdx) {
|
|
115
|
-
focusState.cellPos = [
|
|
137
|
+
focusState.cellPos = [newRowIdx, colIdx];
|
|
116
138
|
requestScroll?.({ type: "scroll-end", direction: "home" });
|
|
117
139
|
}
|
|
118
140
|
break;
|
|
119
141
|
}
|
|
120
142
|
case "End": {
|
|
121
|
-
newRowIdx = rowCount
|
|
143
|
+
newRowIdx = rowCount + headerCount;
|
|
122
144
|
if (newRowIdx !== rowIdx) {
|
|
123
145
|
focusState.cellPos = [newRowIdx, colIdx];
|
|
124
146
|
requestScroll?.({ type: "scroll-end", direction: "end" });
|
|
@@ -130,14 +152,14 @@ const useKeyboardNavigation = ({
|
|
|
130
152
|
resolve([newRowIdx, colIdx]);
|
|
131
153
|
}, 35);
|
|
132
154
|
}),
|
|
133
|
-
[cellFocusStateRef, requestScroll, rowCount, viewportRowCount]
|
|
155
|
+
[cellFocusStateRef, headerCount, requestScroll, rowCount, viewportRowCount]
|
|
134
156
|
);
|
|
135
157
|
const handleFocus = react.useCallback(() => {
|
|
136
158
|
if (disableHighlightOnFocus !== true) {
|
|
137
159
|
if (containerRef.current?.contains(document.activeElement)) {
|
|
138
|
-
const focusedCell = getFocusedCell(document.activeElement);
|
|
160
|
+
const focusedCell = tableDomUtils.getFocusedCell(document.activeElement);
|
|
139
161
|
if (focusedCell) {
|
|
140
|
-
cellFocusStateRef.current.cellPos = tableDomUtils.
|
|
162
|
+
cellFocusStateRef.current.cellPos = tableDomUtils.getAriaCellPos(focusedCell);
|
|
141
163
|
if (navigationStyle === "row") {
|
|
142
164
|
setHighlightedIdx(cellFocusStateRef.current.cellPos[0]);
|
|
143
165
|
}
|
|
@@ -152,17 +174,49 @@ const useKeyboardNavigation = ({
|
|
|
152
174
|
setHighlightedIdx
|
|
153
175
|
]);
|
|
154
176
|
const navigateChildItems = react.useCallback(
|
|
155
|
-
async (key) => {
|
|
156
|
-
const {
|
|
157
|
-
current: { cellPos }
|
|
158
|
-
} = cellFocusStateRef;
|
|
159
|
-
const [nextRowIdx, nextColIdx] = isPagingKey(key) ? await nextPageItemIdx(key, cellPos) : tableDomUtils.getNextCellPos(key, cellPos, columnCount, rowCount);
|
|
177
|
+
async (navigationStyle2 = "cell", key, shiftKey = false) => {
|
|
178
|
+
const { cellPos } = cellFocusStateRef.current;
|
|
160
179
|
const [rowIdx, colIdx] = cellPos;
|
|
180
|
+
let nextRowIdx = -1, nextColIdx = -1;
|
|
181
|
+
if (isPagingKey(key)) {
|
|
182
|
+
[nextRowIdx, nextColIdx] = await nextPageItemIdx(key, cellPos);
|
|
183
|
+
} else {
|
|
184
|
+
const treeNodeOperation = tableDomUtils.getTreeNodeOperation(
|
|
185
|
+
containerRef,
|
|
186
|
+
navigationStyle2,
|
|
187
|
+
cellPos,
|
|
188
|
+
key,
|
|
189
|
+
shiftKey
|
|
190
|
+
);
|
|
191
|
+
if (treeNodeOperation === "expand" || treeNodeOperation === "collapse") {
|
|
192
|
+
onToggleGroup(treeNodeOperation, rowIdx - headerCount - 1);
|
|
193
|
+
} else if (treeNodeOperation === "level-up") {
|
|
194
|
+
[nextRowIdx, nextColIdx] = tableDomUtils.getLevelUp(containerRef, cellPos);
|
|
195
|
+
} else {
|
|
196
|
+
[nextRowIdx, nextColIdx] = tableDomUtils.getNextCellPos(
|
|
197
|
+
key,
|
|
198
|
+
cellPos,
|
|
199
|
+
columnCount,
|
|
200
|
+
maxRowIndex
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
161
204
|
if (nextRowIdx !== rowIdx || nextColIdx !== colIdx) {
|
|
162
205
|
setActiveCell(nextRowIdx, nextColIdx, true);
|
|
206
|
+
setHighlightedIndex(nextRowIdx);
|
|
163
207
|
}
|
|
164
208
|
},
|
|
165
|
-
[
|
|
209
|
+
[
|
|
210
|
+
cellFocusStateRef,
|
|
211
|
+
nextPageItemIdx,
|
|
212
|
+
containerRef,
|
|
213
|
+
onToggleGroup,
|
|
214
|
+
headerCount,
|
|
215
|
+
columnCount,
|
|
216
|
+
maxRowIndex,
|
|
217
|
+
setActiveCell,
|
|
218
|
+
setHighlightedIndex
|
|
219
|
+
]
|
|
166
220
|
);
|
|
167
221
|
const scrollRowIntoViewIfNecessary = react.useCallback(
|
|
168
222
|
(rowIndex) => {
|
|
@@ -173,7 +227,7 @@ const useKeyboardNavigation = ({
|
|
|
173
227
|
const moveHighlightedRow = react.useCallback(
|
|
174
228
|
async (key) => {
|
|
175
229
|
const { current: highlighted } = highlightedIndexRef;
|
|
176
|
-
const [nextRowIdx] = isPagingKey(key) ? await nextPageItemIdx(key, [highlighted ?? -1, 0]) : tableDomUtils.getNextCellPos(key, [highlighted ?? -1, 0], columnCount,
|
|
230
|
+
const [nextRowIdx] = isPagingKey(key) ? await nextPageItemIdx(key, [highlighted ?? -1, 0]) : tableDomUtils.getNextCellPos(key, [highlighted ?? -1, 0], columnCount, maxRowIndex);
|
|
177
231
|
if (nextRowIdx !== highlighted) {
|
|
178
232
|
setHighlightedIndex(nextRowIdx);
|
|
179
233
|
scrollRowIntoViewIfNecessary(nextRowIdx);
|
|
@@ -181,8 +235,8 @@ const useKeyboardNavigation = ({
|
|
|
181
235
|
},
|
|
182
236
|
[
|
|
183
237
|
columnCount,
|
|
238
|
+
maxRowIndex,
|
|
184
239
|
nextPageItemIdx,
|
|
185
|
-
rowCount,
|
|
186
240
|
scrollRowIntoViewIfNecessary,
|
|
187
241
|
setHighlightedIndex
|
|
188
242
|
]
|
|
@@ -198,7 +252,7 @@ const useKeyboardNavigation = ({
|
|
|
198
252
|
(e) => {
|
|
199
253
|
const cell = vuuUtils.queryClosest(
|
|
200
254
|
e.target,
|
|
201
|
-
|
|
255
|
+
`${CellLocator},${CellControlLocator}`
|
|
202
256
|
);
|
|
203
257
|
if (tableDomUtils.cellDropdownShowing(cell)) {
|
|
204
258
|
return;
|
|
@@ -208,31 +262,22 @@ const useKeyboardNavigation = ({
|
|
|
208
262
|
e.stopPropagation();
|
|
209
263
|
if (navigationStyle === "row") {
|
|
210
264
|
moveHighlightedRow(e.key);
|
|
211
|
-
} else {
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
} = cellFocusStateRef;
|
|
215
|
-
if (!focusColumnMenuIfAppropriate(e, cellPos, cell)) {
|
|
216
|
-
navigateChildItems(e.key);
|
|
265
|
+
} else if (navigationStyle !== "none") {
|
|
266
|
+
if (!focusControlWithinCell(e, cell)) {
|
|
267
|
+
navigateChildItems(navigationStyle, e.key, e.shiftKey);
|
|
217
268
|
}
|
|
218
269
|
}
|
|
219
270
|
}
|
|
220
271
|
},
|
|
221
|
-
[
|
|
222
|
-
rowCount,
|
|
223
|
-
navigationStyle,
|
|
224
|
-
moveHighlightedRow,
|
|
225
|
-
cellFocusStateRef,
|
|
226
|
-
navigateChildItems
|
|
227
|
-
]
|
|
272
|
+
[rowCount, navigationStyle, moveHighlightedRow, navigateChildItems]
|
|
228
273
|
);
|
|
229
274
|
const handleClick = react.useCallback(
|
|
230
275
|
// Might not be a cell e.g the Settings button
|
|
231
276
|
(evt) => {
|
|
232
|
-
const target = evt.target;
|
|
233
|
-
const focusedCell = getFocusedCell(target);
|
|
277
|
+
const target = vuuUtils.queryClosest(evt.target, CellLocator);
|
|
278
|
+
const focusedCell = tableDomUtils.getFocusedCell(target);
|
|
234
279
|
if (focusedCell) {
|
|
235
|
-
const [rowIdx, colIdx] = tableDomUtils.
|
|
280
|
+
const [rowIdx, colIdx] = tableDomUtils.getAriaCellPos(focusedCell);
|
|
236
281
|
setActiveCell(rowIdx, colIdx);
|
|
237
282
|
}
|
|
238
283
|
},
|
|
@@ -243,19 +288,19 @@ const useKeyboardNavigation = ({
|
|
|
243
288
|
}, [setHighlightedIndex]);
|
|
244
289
|
const handleMouseMove = react.useCallback(
|
|
245
290
|
(evt) => {
|
|
246
|
-
const
|
|
247
|
-
if (
|
|
248
|
-
setHighlightedIndex(
|
|
291
|
+
const rowIdx = tableDomUtils.closestRowIndex(evt.target);
|
|
292
|
+
if (rowIdx !== -1 && rowIdx !== highlightedIndexRef.current) {
|
|
293
|
+
setHighlightedIndex(rowIdx);
|
|
249
294
|
}
|
|
250
295
|
},
|
|
251
296
|
[setHighlightedIndex]
|
|
252
297
|
);
|
|
253
|
-
const
|
|
254
|
-
navigateChildItems("ArrowDown");
|
|
298
|
+
const navigateCell = react.useCallback(() => {
|
|
299
|
+
navigateChildItems("cell", "ArrowDown");
|
|
255
300
|
}, [navigateChildItems]);
|
|
256
301
|
return {
|
|
257
302
|
highlightedIndexRef,
|
|
258
|
-
|
|
303
|
+
navigateCell,
|
|
259
304
|
onClick: handleClick,
|
|
260
305
|
onFocus: handleFocus,
|
|
261
306
|
onKeyDown: handleKeyDown,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useKeyboardNavigation.js","sources":["../src/useKeyboardNavigation.ts"],"sourcesContent":["import { VuuRange } from \"@vuu-ui/vuu-protocol-types\";\nimport { PageKey, queryClosest } from \"@vuu-ui/vuu-utils\";\nimport { useControlled } from \"@salt-ds/core\";\nimport {\n KeyboardEvent,\n MouseEvent,\n MutableRefObject,\n RefObject,\n useCallback,\n useEffect,\n useRef,\n} from \"react\";\nimport { TableNavigationStyle } from \"./Table\";\nimport {\n NavigationKey,\n cellDropdownShowing,\n closestRowIndex,\n getTableCellPos,\n getNextCellPos,\n} from \"./table-dom-utils\";\nimport { ScrollRequestHandler } from \"./useTableScroll\";\nimport { FocusCell } from \"./useCellFocus\";\nimport { CellFocusState, CellPos } from \"@vuu-ui/vuu-table-types\";\n\nconst rowNavigationKeys = new Set<NavigationKey>([\n \"Home\",\n \"End\",\n \"PageUp\",\n \"PageDown\",\n \"ArrowDown\",\n \"ArrowUp\",\n]);\n\nconst cellNavigationKeys = new Set(rowNavigationKeys);\ncellNavigationKeys.add(\"ArrowLeft\");\ncellNavigationKeys.add(\"ArrowRight\");\n\nexport const isNavigationKey = (\n key: string,\n navigationStyle: TableNavigationStyle,\n): key is NavigationKey => {\n switch (navigationStyle) {\n case \"cell\":\n return cellNavigationKeys.has(key as NavigationKey);\n case \"row\":\n return rowNavigationKeys.has(key as NavigationKey);\n default:\n return false;\n }\n};\n\nconst focusColumnMenuIfAppropriate = (\n e: KeyboardEvent,\n [rowIdx]: CellPos,\n el: HTMLElement | null,\n) => {\n if (e.shiftKey && e.key.match(/Arrow(Left|Right)/) && rowIdx === -1) {\n if (el?.classList.contains(\"vuuTableHeaderCell\")) {\n const menuButton = el?.querySelector<HTMLButtonElement>(\".vuuColumnMenu\");\n if (menuButton) {\n menuButton.focus();\n return true;\n }\n }\n }\n return false;\n};\n\nconst PageKeys = [\"Home\", \"End\", \"PageUp\", \"PageDown\"];\nexport const isPagingKey = (key: string): key is PageKey =>\n PageKeys.includes(key);\n\nexport interface NavigationHookProps {\n cellFocusStateRef: MutableRefObject<CellFocusState>;\n containerRef: RefObject<HTMLElement>;\n columnCount?: number;\n defaultHighlightedIndex?: number;\n disableFocus?: boolean;\n disableHighlightOnFocus?: boolean;\n focusCell: FocusCell;\n highlightedIndex?: number;\n label?: string;\n navigationStyle: TableNavigationStyle;\n viewportRange: VuuRange;\n onHighlight?: (idx: number) => void;\n requestScroll?: ScrollRequestHandler;\n restoreLastFocus?: boolean;\n rowCount?: number;\n selected?: unknown;\n viewportRowCount: number;\n}\n\nexport const useKeyboardNavigation = ({\n cellFocusStateRef,\n columnCount = 0,\n containerRef,\n defaultHighlightedIndex,\n disableHighlightOnFocus,\n focusCell,\n highlightedIndex: highlightedIndexProp,\n navigationStyle,\n requestScroll,\n onHighlight,\n rowCount = 0,\n viewportRowCount,\n}: NavigationHookProps) => {\n // Keep this in sync with state value. This can be used by functions that need\n // to reference highlightedIndex at call time but do not need to be regenerated\n // every time it changes (i.e keep highlightedIndex out of their dependency\n // arrays, as it can update frequently)\n const highlightedIndexRef = useRef<number | undefined>();\n\n const [highlightedIndex, setHighlightedIdx] = useControlled({\n controlled: highlightedIndexProp,\n default: defaultHighlightedIndex,\n name: \"UseKeyboardNavigation\",\n });\n highlightedIndexRef.current = highlightedIndex;\n const setHighlightedIndex = useCallback(\n (idx: number) => {\n onHighlight?.(idx);\n setHighlightedIdx(idx);\n },\n [onHighlight, setHighlightedIdx],\n );\n\n const getFocusedCell = (el: HTMLElement | Element | null) => {\n if (el?.role == \"cell\" || el?.role === \"columnheader\") {\n return el as HTMLDivElement;\n } else {\n return el?.closest(\n \"[role='columnHeader'],[role='cell']\",\n ) as HTMLDivElement | null;\n }\n };\n\n const setActiveCell = useCallback(\n (rowIdx: number, colIdx: number, fromKeyboard = false) => {\n const pos: CellPos = [rowIdx, colIdx];\n if (navigationStyle === \"row\") {\n setHighlightedIdx(rowIdx);\n } else {\n focusCell(pos, fromKeyboard);\n }\n },\n [focusCell, navigationStyle, setHighlightedIdx],\n );\n\n const nextPageItemIdx = useCallback(\n (\n key: \"PageDown\" | \"PageUp\" | \"Home\" | \"End\",\n [rowIdx, colIdx]: CellPos,\n ): Promise<CellPos> =>\n new Promise((resolve) => {\n let newRowIdx = rowIdx;\n const { current: focusState } = cellFocusStateRef;\n switch (key) {\n case \"PageDown\": {\n newRowIdx = Math.min(rowCount - 1, rowIdx + viewportRowCount);\n if (newRowIdx !== rowIdx) {\n focusState.cellPos = [newRowIdx, colIdx];\n requestScroll?.({ type: \"scroll-page\", direction: \"down\" });\n }\n break;\n }\n case \"PageUp\": {\n newRowIdx = Math.max(0, rowIdx - viewportRowCount);\n if (newRowIdx !== rowIdx) {\n focusState.cellPos = [newRowIdx, colIdx];\n requestScroll?.({ type: \"scroll-page\", direction: \"up\" });\n }\n break;\n }\n case \"Home\": {\n newRowIdx = 0;\n if (newRowIdx !== rowIdx) {\n focusState.cellPos = [0, colIdx];\n requestScroll?.({ type: \"scroll-end\", direction: \"home\" });\n }\n break;\n }\n case \"End\": {\n newRowIdx = rowCount - 1;\n if (newRowIdx !== rowIdx) {\n focusState.cellPos = [newRowIdx, colIdx];\n requestScroll?.({ type: \"scroll-end\", direction: \"end\" });\n }\n break;\n }\n }\n // Introduce a delay to allow the scroll operation to complete,\n // which will trigger a range reset and rerender of rows. We\n // might need to tweak how this works. If we introduce too big\n // a delay, we risk seeing the newly rendered rows, with the focus\n // still on the old cell, which will be apparent as a brief flash\n // of the old cell focus before switching to correct cell. If we were\n // to change the way re assign keys such that we can guarantee that\n // when we page down, rows in same position get same keys, then same\n // cell would be focussed in new page as previous and issue would not\n // arise.\n setTimeout(() => {\n resolve([newRowIdx, colIdx]);\n }, 35);\n }),\n [cellFocusStateRef, requestScroll, rowCount, viewportRowCount],\n );\n\n const handleFocus = useCallback(() => {\n if (disableHighlightOnFocus !== true) {\n if (containerRef.current?.contains(document.activeElement)) {\n // IF focus arrives via keyboard, a cell will have received focus,\n // we handle that here. If focus arrives via click on a cell with\n // no tabindex (i.e all cells except one) we leave that to the\n // click handler.\n const focusedCell = getFocusedCell(document.activeElement);\n if (focusedCell) {\n cellFocusStateRef.current.cellPos = getTableCellPos(focusedCell);\n if (navigationStyle === \"row\") {\n setHighlightedIdx(cellFocusStateRef.current.cellPos[0]);\n }\n }\n }\n }\n }, [\n disableHighlightOnFocus,\n containerRef,\n cellFocusStateRef,\n navigationStyle,\n setHighlightedIdx,\n ]);\n\n const navigateChildItems = useCallback(\n async (key: NavigationKey) => {\n const {\n current: { cellPos },\n } = cellFocusStateRef;\n const [nextRowIdx, nextColIdx] = isPagingKey(key)\n ? await nextPageItemIdx(key, cellPos)\n : getNextCellPos(key, cellPos, columnCount, rowCount);\n const [rowIdx, colIdx] = cellPos;\n if (nextRowIdx !== rowIdx || nextColIdx !== colIdx) {\n setActiveCell(nextRowIdx, nextColIdx, true);\n }\n },\n [cellFocusStateRef, columnCount, nextPageItemIdx, rowCount, setActiveCell],\n );\n\n const scrollRowIntoViewIfNecessary = useCallback(\n (rowIndex: number) => {\n requestScroll?.({ type: \"scroll-row\", rowIndex });\n },\n [requestScroll],\n );\n\n const moveHighlightedRow = useCallback(\n async (key: NavigationKey) => {\n const { current: highlighted } = highlightedIndexRef;\n const [nextRowIdx] = isPagingKey(key)\n ? await nextPageItemIdx(key, [highlighted ?? -1, 0])\n : getNextCellPos(key, [highlighted ?? -1, 0], columnCount, rowCount);\n if (nextRowIdx !== highlighted) {\n setHighlightedIndex(nextRowIdx);\n // TO(DO make this a scroll request)\n scrollRowIntoViewIfNecessary(nextRowIdx);\n }\n },\n [\n columnCount,\n nextPageItemIdx,\n rowCount,\n scrollRowIntoViewIfNecessary,\n setHighlightedIndex,\n ],\n );\n\n useEffect(() => {\n if (highlightedIndexProp !== undefined && highlightedIndexProp !== -1) {\n requestAnimationFrame(() => {\n // deferred call, ensuring table has fully rendered\n scrollRowIntoViewIfNecessary(highlightedIndexProp);\n });\n }\n }, [highlightedIndexProp, scrollRowIntoViewIfNecessary]);\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent) => {\n const cell = queryClosest<HTMLDivElement>(\n e.target,\n \".vuuTableCell,.vuuColumnMenu,.vuuTableHeaderCell\",\n );\n if (cellDropdownShowing(cell)) {\n return;\n }\n if (rowCount > 0 && isNavigationKey(e.key, navigationStyle)) {\n e.preventDefault();\n e.stopPropagation();\n if (navigationStyle === \"row\") {\n moveHighlightedRow(e.key);\n } else {\n const {\n current: { cellPos },\n } = cellFocusStateRef;\n if (!focusColumnMenuIfAppropriate(e, cellPos, cell)) {\n navigateChildItems(e.key);\n }\n }\n }\n },\n [\n rowCount,\n navigationStyle,\n moveHighlightedRow,\n cellFocusStateRef,\n navigateChildItems,\n ],\n );\n\n const handleClick = useCallback(\n // Might not be a cell e.g the Settings button\n (evt: MouseEvent) => {\n const target = evt.target as HTMLElement;\n const focusedCell = getFocusedCell(target);\n if (focusedCell) {\n const [rowIdx, colIdx] = getTableCellPos(focusedCell);\n setActiveCell(rowIdx, colIdx);\n }\n },\n [setActiveCell],\n );\n\n const handleMouseLeave = useCallback(() => {\n setHighlightedIndex(-1);\n }, [setHighlightedIndex]);\n\n const handleMouseMove = useCallback(\n (evt: MouseEvent) => {\n const idx = closestRowIndex(evt.target as HTMLElement);\n if (idx !== -1 && idx !== highlightedIndexRef.current) {\n setHighlightedIndex(idx);\n }\n },\n [setHighlightedIndex],\n );\n\n const navigate = useCallback(() => {\n navigateChildItems(\"ArrowDown\");\n }, [navigateChildItems]);\n\n return {\n highlightedIndexRef,\n navigate,\n onClick: handleClick,\n onFocus: handleFocus,\n onKeyDown: handleKeyDown,\n onMouseLeave: navigationStyle === \"row\" ? handleMouseLeave : undefined,\n onMouseMove: navigationStyle === \"row\" ? handleMouseMove : undefined,\n };\n};\n"],"names":["useRef","useControlled","useCallback","getTableCellPos","getNextCellPos","useEffect","queryClosest","cellDropdownShowing","closestRowIndex"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useKeyboardNavigation.js","sources":["../src/useKeyboardNavigation.ts"],"sourcesContent":["import { VuuRange } from \"@vuu-ui/vuu-protocol-types\";\nimport { PageKey, queryClosest } from \"@vuu-ui/vuu-utils\";\nimport { useControlled } from \"@salt-ds/core\";\nimport {\n KeyboardEvent,\n MouseEvent,\n MutableRefObject,\n RefObject,\n useCallback,\n useEffect,\n useRef,\n} from \"react\";\nimport { TableNavigationStyle } from \"./Table\";\nimport {\n NavigationKey,\n cellDropdownShowing,\n closestRowIndex,\n getAriaCellPos,\n getFocusedCell,\n getNextCellPos,\n getTreeNodeOperation,\n getLevelUp as getLevelUp,\n} from \"./table-dom-utils\";\nimport { ScrollRequestHandler } from \"./useTableScroll\";\nimport { FocusCell } from \"./useCellFocus\";\nimport { CellFocusState, CellPos } from \"@vuu-ui/vuu-table-types\";\n\nconst rowNavigationKeys = new Set<NavigationKey>([\n \"Home\",\n \"End\",\n \"PageUp\",\n \"PageDown\",\n \"ArrowDown\",\n \"ArrowUp\",\n]);\n\nconst CellLocator =\n \".vuuTableCell,.vuuTableHeaderCell,.vuuTableGroupHeaderCell\";\n\nconst CellControlLocator = \".vuuColumnMenu,.vuuColumnHeaderPill\";\n\nconst cellNavigationKeys = new Set(rowNavigationKeys);\ncellNavigationKeys.add(\"ArrowLeft\");\ncellNavigationKeys.add(\"ArrowRight\");\n\nexport const isNavigationKey = (\n key: string,\n navigationStyle: TableNavigationStyle,\n): key is NavigationKey => {\n switch (navigationStyle) {\n case \"cell\":\n case \"tree\":\n return cellNavigationKeys.has(key as NavigationKey);\n case \"row\":\n return rowNavigationKeys.has(key as NavigationKey);\n default:\n return false;\n }\n};\n\nconst focusControlWithinCell = (e: KeyboardEvent, el: HTMLElement | null) => {\n if (e.shiftKey && e.key.match(/Arrow(Left|Right)/)) {\n if (el?.classList.contains(\"vuuTableHeaderCell\")) {\n const menuButton = el?.querySelector<HTMLButtonElement>(\".vuuColumnMenu\");\n if (menuButton) {\n menuButton.focus();\n return true;\n }\n } else if (el?.classList.contains(\"vuuTableGroupHeaderCell\")) {\n const headerPill = el?.querySelector<HTMLButtonElement>(\n \".vuuColumnHeaderPill\",\n );\n if (headerPill) {\n headerPill.focus();\n return true;\n }\n } else if (el?.classList.contains(\"vuuColumnHeaderPill\")) {\n const nextPill = el.parentElement?.nextElementSibling\n ?.firstChild as HTMLElement;\n if (nextPill?.classList.contains(\"vuuColumnHeaderPill\")) {\n nextPill.focus();\n return true;\n } else {\n const removeButton = queryClosest(\n el,\n \".vuuTableGroupHeaderCell\",\n true,\n ).querySelector(\".vuuTableGroupHeaderCell-removeAll\") as HTMLElement;\n if (removeButton) {\n removeButton.focus();\n return true;\n }\n }\n }\n }\n return false;\n};\n\nconst PageKeys = [\"Home\", \"End\", \"PageUp\", \"PageDown\"];\nexport const isPagingKey = (key: string): key is PageKey =>\n PageKeys.includes(key);\n\nexport type GroupToggleHandler = (\n treeNodeOperation: \"expand\" | \"collapse\",\n rowIndex: number,\n) => void;\n\nexport interface NavigationHookProps {\n cellFocusStateRef: MutableRefObject<CellFocusState>;\n containerRef: RefObject<HTMLElement>;\n columnCount?: number;\n headerCount: number;\n defaultHighlightedIndex?: number;\n disableFocus?: boolean;\n disableHighlightOnFocus?: boolean;\n focusCell: FocusCell;\n highlightedIndex?: number;\n label?: string;\n navigationStyle: TableNavigationStyle;\n viewportRange: VuuRange;\n onHighlight?: (idx: number) => void;\n onToggleGroup: GroupToggleHandler;\n requestScroll?: ScrollRequestHandler;\n restoreLastFocus?: boolean;\n rowCount?: number;\n selected?: unknown;\n viewportRowCount: number;\n}\n\nexport const useKeyboardNavigation = ({\n cellFocusStateRef,\n columnCount = 0,\n containerRef,\n defaultHighlightedIndex,\n disableHighlightOnFocus,\n focusCell,\n headerCount,\n highlightedIndex: highlightedIndexProp,\n navigationStyle,\n requestScroll,\n onHighlight,\n onToggleGroup,\n rowCount = 0,\n viewportRowCount,\n}: NavigationHookProps) => {\n // Keep this in sync with state value. This can be used by functions that need\n // to reference highlightedIndex at call time but do not need to be regenerated\n // every time it changes (i.e keep highlightedIndex out of their dependency\n // arrays, as it can update frequently)\n const highlightedIndexRef = useRef<number | undefined>();\n\n const [highlightedIndex, setHighlightedIdx] = useControlled({\n controlled: highlightedIndexProp,\n default: defaultHighlightedIndex,\n name: \"UseKeyboardNavigation\",\n });\n highlightedIndexRef.current = highlightedIndex;\n\n // We use aria row index for tracking rows\n const maxRowIndex = rowCount + headerCount;\n\n const setHighlightedIndex = useCallback(\n (idx: number) => {\n onHighlight?.(idx);\n setHighlightedIdx(idx);\n highlightedIndexRef.current = idx;\n },\n [onHighlight, setHighlightedIdx],\n );\n\n const setActiveCell = useCallback(\n (rowIdx: number, colIdx: number, fromKeyboard = false) => {\n const pos: CellPos = [rowIdx, colIdx];\n if (navigationStyle === \"row\") {\n setHighlightedIdx(rowIdx);\n } else {\n focusCell(pos, fromKeyboard);\n }\n },\n [focusCell, navigationStyle, setHighlightedIdx],\n );\n\n const nextPageItemIdx = useCallback(\n (\n key: \"PageDown\" | \"PageUp\" | \"Home\" | \"End\",\n [rowIdx, colIdx]: CellPos,\n ): Promise<CellPos> =>\n new Promise((resolve) => {\n let newRowIdx = rowIdx;\n const { current: focusState } = cellFocusStateRef;\n switch (key) {\n case \"PageDown\": {\n newRowIdx = Math.min(rowCount - 1, rowIdx + viewportRowCount);\n if (newRowIdx !== rowIdx) {\n focusState.cellPos = [newRowIdx, colIdx];\n requestScroll?.({ type: \"scroll-page\", direction: \"down\" });\n }\n break;\n }\n case \"PageUp\": {\n newRowIdx = Math.max(0, rowIdx - viewportRowCount);\n if (newRowIdx !== rowIdx) {\n focusState.cellPos = [newRowIdx, colIdx];\n requestScroll?.({ type: \"scroll-page\", direction: \"up\" });\n }\n break;\n }\n case \"Home\": {\n newRowIdx = headerCount + 1;\n if (newRowIdx !== rowIdx) {\n focusState.cellPos = [newRowIdx, colIdx];\n requestScroll?.({ type: \"scroll-end\", direction: \"home\" });\n }\n break;\n }\n case \"End\": {\n newRowIdx = rowCount + headerCount;\n if (newRowIdx !== rowIdx) {\n focusState.cellPos = [newRowIdx, colIdx];\n requestScroll?.({ type: \"scroll-end\", direction: \"end\" });\n }\n break;\n }\n }\n // Introduce a delay to allow the scroll operation to complete,\n // which will trigger a range reset and rerender of rows. We\n // might need to tweak how this works. If we introduce too big\n // a delay, we risk seeing the newly rendered rows, with the focus\n // still on the old cell, which will be apparent as a brief flash\n // of the old cell focus before switching to correct cell. If we were\n // to change the way re assign keys such that we can guarantee that\n // when we page down, rows in same position get same keys, then same\n // cell would be focussed in new page as previous and issue would not\n // arise.\n setTimeout(() => {\n resolve([newRowIdx, colIdx]);\n }, 35);\n }),\n [cellFocusStateRef, headerCount, requestScroll, rowCount, viewportRowCount],\n );\n\n const handleFocus = useCallback(() => {\n if (disableHighlightOnFocus !== true) {\n if (containerRef.current?.contains(document.activeElement)) {\n // IF focus arrives via keyboard, a cell will have received focus,\n // we handle that here. If focus arrives via click on a cell with\n // no tabindex (i.e all cells except one) we leave that to the\n // click handler.\n const focusedCell = getFocusedCell(document.activeElement);\n if (focusedCell) {\n cellFocusStateRef.current.cellPos = getAriaCellPos(focusedCell);\n if (navigationStyle === \"row\") {\n setHighlightedIdx(cellFocusStateRef.current.cellPos[0]);\n }\n }\n }\n }\n }, [\n disableHighlightOnFocus,\n containerRef,\n cellFocusStateRef,\n navigationStyle,\n setHighlightedIdx,\n ]);\n\n const navigateChildItems = useCallback(\n async (\n navigationStyle: \"cell\" | \"tree\" = \"cell\",\n key: NavigationKey,\n shiftKey = false,\n ): Promise<undefined> => {\n const { cellPos } = cellFocusStateRef.current;\n const [rowIdx, colIdx] = cellPos;\n let nextRowIdx = -1,\n nextColIdx = -1;\n\n if (isPagingKey(key)) {\n [nextRowIdx, nextColIdx] = await nextPageItemIdx(key, cellPos);\n } else {\n const treeNodeOperation = getTreeNodeOperation(\n containerRef,\n navigationStyle,\n cellPos,\n key,\n shiftKey,\n );\n if (\n treeNodeOperation === \"expand\" ||\n treeNodeOperation === \"collapse\"\n ) {\n onToggleGroup(treeNodeOperation, rowIdx - headerCount - 1);\n } else if (treeNodeOperation === \"level-up\") {\n [nextRowIdx, nextColIdx] = getLevelUp(containerRef, cellPos);\n } else {\n [nextRowIdx, nextColIdx] = getNextCellPos(\n key,\n cellPos,\n columnCount,\n maxRowIndex,\n );\n }\n }\n\n if (nextRowIdx !== rowIdx || nextColIdx !== colIdx) {\n setActiveCell(nextRowIdx, nextColIdx, true);\n setHighlightedIndex(nextRowIdx);\n }\n },\n [\n cellFocusStateRef,\n nextPageItemIdx,\n containerRef,\n onToggleGroup,\n headerCount,\n columnCount,\n maxRowIndex,\n setActiveCell,\n setHighlightedIndex,\n ],\n );\n\n const scrollRowIntoViewIfNecessary = useCallback(\n (rowIndex: number) => {\n requestScroll?.({ type: \"scroll-row\", rowIndex });\n },\n [requestScroll],\n );\n\n const moveHighlightedRow = useCallback(\n async (key: NavigationKey) => {\n const { current: highlighted } = highlightedIndexRef;\n const [nextRowIdx] = isPagingKey(key)\n ? await nextPageItemIdx(key, [highlighted ?? -1, 0])\n : getNextCellPos(key, [highlighted ?? -1, 0], columnCount, maxRowIndex);\n if (nextRowIdx !== highlighted) {\n setHighlightedIndex(nextRowIdx);\n // TO(DO make this a scroll request)\n scrollRowIntoViewIfNecessary(nextRowIdx);\n }\n },\n [\n columnCount,\n maxRowIndex,\n nextPageItemIdx,\n scrollRowIntoViewIfNecessary,\n setHighlightedIndex,\n ],\n );\n\n useEffect(() => {\n if (highlightedIndexProp !== undefined && highlightedIndexProp !== -1) {\n requestAnimationFrame(() => {\n // deferred call, ensuring table has fully rendered\n scrollRowIntoViewIfNecessary(highlightedIndexProp);\n });\n }\n }, [highlightedIndexProp, scrollRowIntoViewIfNecessary]);\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent) => {\n const cell = queryClosest<HTMLDivElement>(\n e.target,\n `${CellLocator},${CellControlLocator}`,\n );\n if (cellDropdownShowing(cell)) {\n return;\n }\n if (rowCount > 0 && isNavigationKey(e.key, navigationStyle)) {\n e.preventDefault();\n e.stopPropagation();\n if (navigationStyle === \"row\") {\n moveHighlightedRow(e.key);\n } else if (navigationStyle !== \"none\") {\n if (!focusControlWithinCell(e, cell)) {\n navigateChildItems(navigationStyle, e.key, e.shiftKey);\n }\n }\n }\n },\n [rowCount, navigationStyle, moveHighlightedRow, navigateChildItems],\n );\n\n const handleClick = useCallback(\n // Might not be a cell e.g the Settings button\n (evt: MouseEvent) => {\n const target = queryClosest<HTMLDivElement>(evt.target, CellLocator);\n const focusedCell = getFocusedCell(target);\n if (focusedCell) {\n const [rowIdx, colIdx] = getAriaCellPos(focusedCell);\n setActiveCell(rowIdx, colIdx);\n }\n },\n [setActiveCell],\n );\n\n const handleMouseLeave = useCallback(() => {\n setHighlightedIndex(-1);\n }, [setHighlightedIndex]);\n\n const handleMouseMove = useCallback(\n (evt: MouseEvent) => {\n const rowIdx = closestRowIndex(evt.target as HTMLElement);\n if (rowIdx !== -1 && rowIdx !== highlightedIndexRef.current) {\n setHighlightedIndex(rowIdx);\n }\n },\n [setHighlightedIndex],\n );\n\n /**\n * used when editing cells\n */\n const navigateCell = useCallback(() => {\n navigateChildItems(\"cell\", \"ArrowDown\");\n }, [navigateChildItems]);\n\n return {\n highlightedIndexRef,\n navigateCell,\n onClick: handleClick,\n onFocus: handleFocus,\n onKeyDown: handleKeyDown,\n onMouseLeave: navigationStyle === \"row\" ? handleMouseLeave : undefined,\n onMouseMove: navigationStyle === \"row\" ? handleMouseMove : undefined,\n };\n};\n"],"names":["queryClosest","useRef","useControlled","useCallback","getFocusedCell","getAriaCellPos","navigationStyle","getTreeNodeOperation","getLevelUp","getNextCellPos","useEffect","cellDropdownShowing","closestRowIndex"],"mappings":"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"}
|
package/cjs/useSelection.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var vuuUtils = require('@vuu-ui/vuu-utils');
|
|
4
4
|
var react = require('react');
|
|
5
|
+
var tableDomUtils = require('./table-dom-utils.js');
|
|
5
6
|
|
|
6
7
|
const { IDX } = vuuUtils.metadataKeys;
|
|
7
8
|
const NO_SELECTION = [];
|
|
@@ -51,7 +52,7 @@ const useSelection = ({
|
|
|
51
52
|
if (isSelectionEvent(e)) {
|
|
52
53
|
const { current: rowIndex } = highlightedIndexRef;
|
|
53
54
|
if (rowIndex !== void 0 && rowIndex !== -1) {
|
|
54
|
-
const rowEl =
|
|
55
|
+
const rowEl = tableDomUtils.getRowElementByAriaIndex(e.target, rowIndex);
|
|
55
56
|
if (rowEl) {
|
|
56
57
|
vuuUtils.dispatchMouseEvent(rowEl, "click");
|
|
57
58
|
}
|
package/cjs/useSelection.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useSelection.js","sources":["../src/useSelection.ts"],"sourcesContent":["import {\n TableRowClickHandlerInternal,\n TableRowSelectHandlerInternal,\n TableSelectionModel,\n} from \"@vuu-ui/vuu-table-types\";\nimport {\n deselectItem,\n dispatchMouseEvent,\n
|
|
1
|
+
{"version":3,"file":"useSelection.js","sources":["../src/useSelection.ts"],"sourcesContent":["import {\n TableRowClickHandlerInternal,\n TableRowSelectHandlerInternal,\n TableSelectionModel,\n} from \"@vuu-ui/vuu-table-types\";\nimport {\n deselectItem,\n dispatchMouseEvent,\n isRowSelected,\n metadataKeys,\n queryClosest,\n selectItem,\n} from \"@vuu-ui/vuu-utils\";\nimport { Selection, SelectionChangeHandler } from \"@vuu-ui/vuu-data-types\";\nimport {\n KeyboardEvent,\n KeyboardEventHandler,\n MutableRefObject,\n useCallback,\n useRef,\n} from \"react\";\nimport { getRowElementByAriaIndex } from \"./table-dom-utils\";\n\nconst { IDX } = metadataKeys;\n\nconst NO_SELECTION: Selection = [];\n\nconst defaultSelectionKeys = [\"Enter\", \" \"];\n\nexport interface SelectionHookProps {\n highlightedIndexRef: MutableRefObject<number | undefined>;\n selectionKeys?: string[];\n selectionModel: TableSelectionModel;\n onSelect?: TableRowSelectHandlerInternal;\n onSelectionChange: SelectionChangeHandler;\n}\n\nexport const useSelection = ({\n highlightedIndexRef,\n selectionKeys = defaultSelectionKeys,\n selectionModel,\n onSelect,\n onSelectionChange,\n}: SelectionHookProps) => {\n selectionModel === \"extended\" || selectionModel === \"checkbox\";\n const lastActiveRef = useRef(-1);\n const selectedRef = useRef<Selection>(NO_SELECTION);\n\n const isSelectionEvent = useCallback(\n (evt: KeyboardEvent<HTMLElement>) => selectionKeys.includes(evt.key),\n [selectionKeys],\n );\n\n const handleRowClick = useCallback<TableRowClickHandlerInternal>(\n (e, row, rangeSelect, keepExistingSelection) => {\n const { [IDX]: idx } = row;\n const { current: active } = lastActiveRef;\n const { current: selected } = selectedRef;\n\n const selectOperation = isRowSelected(row) ? deselectItem : selectItem;\n\n if (selectionModel === \"checkbox\") {\n const cell = queryClosest(e.target, \".vuuTableCell\");\n if (!cell?.querySelector(\".vuuCheckboxRowSelector\")) {\n return;\n }\n }\n\n const newSelected = selectOperation(\n selectionModel,\n selected,\n idx,\n rangeSelect,\n keepExistingSelection,\n active,\n );\n\n selectedRef.current = newSelected;\n lastActiveRef.current = idx;\n\n onSelect?.(selectOperation === selectItem ? row : null);\n onSelectionChange?.(newSelected);\n },\n [onSelect, onSelectionChange, selectionModel],\n );\n\n const handleKeyDown = useCallback<KeyboardEventHandler<HTMLElement>>(\n (e) => {\n if (isSelectionEvent(e)) {\n const { current: rowIndex } = highlightedIndexRef;\n if (rowIndex !== undefined && rowIndex !== -1) {\n const rowEl = getRowElementByAriaIndex(e.target, rowIndex);\n if (rowEl) {\n dispatchMouseEvent(rowEl, \"click\");\n }\n }\n }\n },\n [highlightedIndexRef, isSelectionEvent],\n );\n\n return {\n onKeyDown: handleKeyDown,\n onRowClick: handleRowClick,\n };\n};\n"],"names":["metadataKeys","useRef","useCallback","isRowSelected","deselectItem","selectItem","queryClosest","getRowElementByAriaIndex","dispatchMouseEvent"],"mappings":";;;;;;AAuBA,MAAM,EAAE,KAAQ,GAAAA,qBAAA,CAAA;AAEhB,MAAM,eAA0B,EAAC,CAAA;AAEjC,MAAM,oBAAA,GAAuB,CAAC,OAAA,EAAS,GAAG,CAAA,CAAA;AAUnC,MAAM,eAAe,CAAC;AAAA,EAC3B,mBAAA;AAAA,EACA,aAAgB,GAAA,oBAAA;AAAA,EAChB,cAAA;AAAA,EACA,QAAA;AAAA,EACA,iBAAA;AACF,CAA0B,KAAA;AAExB,EAAM,MAAA,aAAA,GAAgBC,aAAO,CAAE,CAAA,CAAA,CAAA;AAC/B,EAAM,MAAA,WAAA,GAAcA,aAAkB,YAAY,CAAA,CAAA;AAElD,EAAA,MAAM,gBAAmB,GAAAC,iBAAA;AAAA,IACvB,CAAC,GAAA,KAAoC,aAAc,CAAA,QAAA,CAAS,IAAI,GAAG,CAAA;AAAA,IACnE,CAAC,aAAa,CAAA;AAAA,GAChB,CAAA;AAEA,EAAA,MAAM,cAAiB,GAAAA,iBAAA;AAAA,IACrB,CAAC,CAAA,EAAG,GAAK,EAAA,WAAA,EAAa,qBAA0B,KAAA;AAC9C,MAAA,MAAM,EAAE,CAAC,GAAG,GAAG,KAAQ,GAAA,GAAA,CAAA;AACvB,MAAM,MAAA,EAAE,OAAS,EAAA,MAAA,EAAW,GAAA,aAAA,CAAA;AAC5B,MAAM,MAAA,EAAE,OAAS,EAAA,QAAA,EAAa,GAAA,WAAA,CAAA;AAE9B,MAAA,MAAM,eAAkB,GAAAC,sBAAA,CAAc,GAAG,CAAA,GAAIC,qBAAe,GAAAC,mBAAA,CAAA;AAE5D,MAAA,IAAI,mBAAmB,UAAY,EAAA;AACjC,QAAA,MAAM,IAAO,GAAAC,qBAAA,CAAa,CAAE,CAAA,MAAA,EAAQ,eAAe,CAAA,CAAA;AACnD,QAAA,IAAI,CAAC,IAAA,EAAM,aAAc,CAAA,yBAAyB,CAAG,EAAA;AACnD,UAAA,OAAA;AAAA,SACF;AAAA,OACF;AAEA,MAAA,MAAM,WAAc,GAAA,eAAA;AAAA,QAClB,cAAA;AAAA,QACA,QAAA;AAAA,QACA,GAAA;AAAA,QACA,WAAA;AAAA,QACA,qBAAA;AAAA,QACA,MAAA;AAAA,OACF,CAAA;AAEA,MAAA,WAAA,CAAY,OAAU,GAAA,WAAA,CAAA;AACtB,MAAA,aAAA,CAAc,OAAU,GAAA,GAAA,CAAA;AAExB,MAAW,QAAA,GAAA,eAAA,KAAoBD,mBAAa,GAAA,GAAA,GAAM,IAAI,CAAA,CAAA;AACtD,MAAA,iBAAA,GAAoB,WAAW,CAAA,CAAA;AAAA,KACjC;AAAA,IACA,CAAC,QAAU,EAAA,iBAAA,EAAmB,cAAc,CAAA;AAAA,GAC9C,CAAA;AAEA,EAAA,MAAM,aAAgB,GAAAH,iBAAA;AAAA,IACpB,CAAC,CAAM,KAAA;AACL,MAAI,IAAA,gBAAA,CAAiB,CAAC,CAAG,EAAA;AACvB,QAAM,MAAA,EAAE,OAAS,EAAA,QAAA,EAAa,GAAA,mBAAA,CAAA;AAC9B,QAAI,IAAA,QAAA,KAAa,KAAa,CAAA,IAAA,QAAA,KAAa,CAAI,CAAA,EAAA;AAC7C,UAAA,MAAM,KAAQ,GAAAK,sCAAA,CAAyB,CAAE,CAAA,MAAA,EAAQ,QAAQ,CAAA,CAAA;AACzD,UAAA,IAAI,KAAO,EAAA;AACT,YAAAC,2BAAA,CAAmB,OAAO,OAAO,CAAA,CAAA;AAAA,WACnC;AAAA,SACF;AAAA,OACF;AAAA,KACF;AAAA,IACA,CAAC,qBAAqB,gBAAgB,CAAA;AAAA,GACxC,CAAA;AAEA,EAAO,OAAA;AAAA,IACL,SAAW,EAAA,aAAA;AAAA,IACX,UAAY,EAAA,cAAA;AAAA,GACd,CAAA;AACF;;;;"}
|
package/cjs/useTable.js
CHANGED
|
@@ -20,6 +20,14 @@ var useTableModel = require('./useTableModel.js');
|
|
|
20
20
|
var useTableScroll = require('./useTableScroll.js');
|
|
21
21
|
var useTableViewport = require('./useTableViewport.js');
|
|
22
22
|
|
|
23
|
+
const nullHeaderState = {
|
|
24
|
+
height: -1,
|
|
25
|
+
count: -1
|
|
26
|
+
};
|
|
27
|
+
const zeroHeaderState = {
|
|
28
|
+
height: 0,
|
|
29
|
+
count: 0
|
|
30
|
+
};
|
|
23
31
|
const stripInternalProperties = (tableConfig) => {
|
|
24
32
|
return tableConfig;
|
|
25
33
|
};
|
|
@@ -63,6 +71,7 @@ const useTable = ({
|
|
|
63
71
|
renderBufferSize = 0,
|
|
64
72
|
rowHeight = 20,
|
|
65
73
|
scrollingApiRef,
|
|
74
|
+
selectionBookendWidth,
|
|
66
75
|
selectionModel,
|
|
67
76
|
showColumnHeaders,
|
|
68
77
|
showPaginationControls,
|
|
@@ -75,7 +84,9 @@ const useTable = ({
|
|
|
75
84
|
const initialState = react.useMemo(() => ({ ...NullCellFocusState }), []);
|
|
76
85
|
const cellFocusStateRef = react.useRef(initialState);
|
|
77
86
|
const focusCellRef = react.useRef();
|
|
78
|
-
const [
|
|
87
|
+
const [headerState, setHeaderState] = react.useState(
|
|
88
|
+
showColumnHeaders ? nullHeaderState : zeroHeaderState
|
|
89
|
+
);
|
|
79
90
|
const [rowCount, setRowCount] = react.useState(dataSource.size);
|
|
80
91
|
if (dataSource === void 0) {
|
|
81
92
|
throw Error("no data source provided to Vuu Table");
|
|
@@ -84,7 +95,7 @@ const useTable = ({
|
|
|
84
95
|
setRowCount(size2);
|
|
85
96
|
}, []);
|
|
86
97
|
const virtualContentHeight = rowHeight * rowCount;
|
|
87
|
-
const viewportBodyHeight = size.height - (
|
|
98
|
+
const viewportBodyHeight = size.height - (headerState.height === -1 ? 0 : headerState.height);
|
|
88
99
|
const verticalScrollbarWidth = virtualContentHeight > viewportBodyHeight ? 10 : 0;
|
|
89
100
|
const availableWidth = size.width - (verticalScrollbarWidth + 8);
|
|
90
101
|
const rowClassNameGenerator = useRowClassNameGenerators.useRowClassNameGenerators(config);
|
|
@@ -104,17 +115,10 @@ const useTable = ({
|
|
|
104
115
|
dispatchTableModelAction({
|
|
105
116
|
availableWidth,
|
|
106
117
|
type: "init",
|
|
107
|
-
// tableConfig: config,
|
|
108
118
|
tableConfig: tableConfigRef.current,
|
|
109
119
|
dataSource
|
|
110
120
|
});
|
|
111
|
-
}, [
|
|
112
|
-
availableWidth,
|
|
113
|
-
config,
|
|
114
|
-
dataSource,
|
|
115
|
-
dispatchTableModelAction,
|
|
116
|
-
verticalScrollbarWidth
|
|
117
|
-
]);
|
|
121
|
+
}, [availableWidth, config, dataSource, dispatchTableModelAction]);
|
|
118
122
|
const applyTableConfigChange = react.useCallback(
|
|
119
123
|
(config2) => {
|
|
120
124
|
dispatchTableModelAction({
|
|
@@ -153,9 +157,10 @@ const useTable = ({
|
|
|
153
157
|
...viewportMeasurements
|
|
154
158
|
} = useTableViewport.useTableViewport({
|
|
155
159
|
columns,
|
|
156
|
-
headerHeight,
|
|
160
|
+
headerHeight: headerState.height,
|
|
157
161
|
rowCount,
|
|
158
162
|
rowHeight,
|
|
163
|
+
selectionEndSize: selectionBookendWidth,
|
|
159
164
|
size,
|
|
160
165
|
showPaginationControls
|
|
161
166
|
});
|
|
@@ -210,6 +215,7 @@ const useTable = ({
|
|
|
210
215
|
direction: "home"
|
|
211
216
|
});
|
|
212
217
|
}
|
|
218
|
+
console.log(`useTable dispatch tableConfig`);
|
|
213
219
|
dispatchTableModelAction({
|
|
214
220
|
type: "tableConfig",
|
|
215
221
|
...config2,
|
|
@@ -396,6 +402,16 @@ const useTable = ({
|
|
|
396
402
|
},
|
|
397
403
|
[columnMap, columns, dataSource, dispatchTableModelAction]
|
|
398
404
|
);
|
|
405
|
+
const handleToggleGroup = react.useCallback(
|
|
406
|
+
(treeNodeOperation, rowIdx) => {
|
|
407
|
+
if (treeNodeOperation === "expand") {
|
|
408
|
+
dataSource.openTreeNode(rowIdx);
|
|
409
|
+
} else {
|
|
410
|
+
dataSource.closeTreeNode(rowIdx);
|
|
411
|
+
}
|
|
412
|
+
},
|
|
413
|
+
[dataSource]
|
|
414
|
+
);
|
|
399
415
|
const {
|
|
400
416
|
focusCell,
|
|
401
417
|
focusCellPlaceholderKeyDown,
|
|
@@ -411,7 +427,7 @@ const useTable = ({
|
|
|
411
427
|
const columnCount = columns.filter((c) => c.hidden !== true).length;
|
|
412
428
|
const {
|
|
413
429
|
highlightedIndexRef,
|
|
414
|
-
navigate,
|
|
430
|
+
navigateCell: navigate,
|
|
415
431
|
onFocus: navigationFocus,
|
|
416
432
|
onKeyDown: navigationKeyDown,
|
|
417
433
|
...containerProps
|
|
@@ -421,11 +437,13 @@ const useTable = ({
|
|
|
421
437
|
containerRef,
|
|
422
438
|
disableFocus,
|
|
423
439
|
focusCell,
|
|
440
|
+
headerCount: headerState.count,
|
|
424
441
|
highlightedIndex: highlightedIndexProp,
|
|
425
442
|
navigationStyle,
|
|
426
443
|
requestScroll,
|
|
427
444
|
rowCount,
|
|
428
445
|
onHighlight,
|
|
446
|
+
onToggleGroup: handleToggleGroup,
|
|
429
447
|
viewportRange: range,
|
|
430
448
|
viewportRowCount: viewportMeasurements.rowCount
|
|
431
449
|
});
|
|
@@ -450,7 +468,8 @@ const useTable = ({
|
|
|
450
468
|
columns,
|
|
451
469
|
data,
|
|
452
470
|
dataSource,
|
|
453
|
-
getSelectedRows
|
|
471
|
+
getSelectedRows,
|
|
472
|
+
headerCount: headerState.count
|
|
454
473
|
});
|
|
455
474
|
const onMoveGroupColumn = react.useCallback(
|
|
456
475
|
(columns2) => {
|
|
@@ -463,7 +482,7 @@ const useTable = ({
|
|
|
463
482
|
if (vuuUtils.isGroupColumn(column)) {
|
|
464
483
|
dataSource.groupBy = [];
|
|
465
484
|
} else {
|
|
466
|
-
if (dataSource && dataSource.groupBy
|
|
485
|
+
if (dataSource && dataSource.groupBy?.includes(column.name)) {
|
|
467
486
|
dataSource.groupBy = dataSource.groupBy.filter(
|
|
468
487
|
(columnName) => columnName !== column.name
|
|
469
488
|
);
|
|
@@ -511,7 +530,6 @@ const useTable = ({
|
|
|
511
530
|
allowCellBlockSelection,
|
|
512
531
|
columnCount,
|
|
513
532
|
containerRef,
|
|
514
|
-
focusCell,
|
|
515
533
|
onSelectCellBlock: handleSelectCellBlock,
|
|
516
534
|
rowCount
|
|
517
535
|
});
|
|
@@ -580,18 +598,21 @@ const useTable = ({
|
|
|
580
598
|
const handleDragStartRow = react.useCallback(
|
|
581
599
|
(dragDropState) => {
|
|
582
600
|
const { initialDragElement } = dragDropState;
|
|
583
|
-
const rowIndex = tableDomUtils.
|
|
601
|
+
const rowIndex = tableDomUtils.getAriaRowIndex(initialDragElement) - headerState.count - 1;
|
|
584
602
|
const row = dataRef.current.find((row2) => row2[0] === rowIndex);
|
|
585
603
|
if (row) {
|
|
586
604
|
dragDropState.setPayload(row);
|
|
587
605
|
}
|
|
588
606
|
onDragStart?.(dragDropState);
|
|
589
607
|
},
|
|
590
|
-
[dataRef, onDragStart]
|
|
608
|
+
[dataRef, headerState.count, onDragStart]
|
|
609
|
+
);
|
|
610
|
+
const onHeaderHeightMeasured = react.useCallback(
|
|
611
|
+
(height, count) => {
|
|
612
|
+
setHeaderState({ height, count });
|
|
613
|
+
},
|
|
614
|
+
[]
|
|
591
615
|
);
|
|
592
|
-
const onHeaderHeightMeasured = react.useCallback((height) => {
|
|
593
|
-
setHeaderHeight(height);
|
|
594
|
-
}, []);
|
|
595
616
|
const { onMouseDown: rowDragMouseDown, draggable: draggableRow } = useRowDragDrop({
|
|
596
617
|
allowDragDrop,
|
|
597
618
|
containerRef,
|
|
@@ -623,7 +644,7 @@ const useTable = ({
|
|
|
623
644
|
focusCellPlaceholderRef,
|
|
624
645
|
getRowOffset,
|
|
625
646
|
handleContextMenuAction,
|
|
626
|
-
|
|
647
|
+
headerState,
|
|
627
648
|
headings,
|
|
628
649
|
highlightedIndex: highlightedIndexRef.current,
|
|
629
650
|
menuBuilder,
|