@vuu-ui/vuu-table 0.8.95 → 0.8.96

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/cjs/Table.js +8 -3
  2. package/cjs/Table.js.map +1 -1
  3. package/cjs/cell-block/CellBlock.css.js +1 -1
  4. package/cjs/cell-block/CellBlock.js +12 -2
  5. package/cjs/cell-block/CellBlock.js.map +1 -1
  6. package/cjs/cell-block/cellblock-utils.js +71 -0
  7. package/cjs/cell-block/cellblock-utils.js.map +1 -1
  8. package/cjs/cell-block/useCellBlockSelection.js +69 -74
  9. package/cjs/cell-block/useCellBlockSelection.js.map +1 -1
  10. package/cjs/table-dom-utils.js +67 -10
  11. package/cjs/table-dom-utils.js.map +1 -1
  12. package/cjs/table-header/useTableHeader.js +1 -1
  13. package/cjs/table-header/useTableHeader.js.map +1 -1
  14. package/cjs/useCellFocus.js +56 -0
  15. package/cjs/useCellFocus.js.map +1 -0
  16. package/cjs/useKeyboardNavigation.js +5 -81
  17. package/cjs/useKeyboardNavigation.js.map +1 -1
  18. package/cjs/useMeasuredHeight.js +5 -5
  19. package/cjs/useMeasuredHeight.js.map +1 -1
  20. package/cjs/useTable.js +21 -7
  21. package/cjs/useTable.js.map +1 -1
  22. package/cjs/useTableContextMenu.js +2 -1
  23. package/cjs/useTableContextMenu.js.map +1 -1
  24. package/esm/Table.js +8 -3
  25. package/esm/Table.js.map +1 -1
  26. package/esm/cell-block/CellBlock.css.js +1 -1
  27. package/esm/cell-block/CellBlock.js +13 -3
  28. package/esm/cell-block/CellBlock.js.map +1 -1
  29. package/esm/cell-block/cellblock-utils.js +68 -1
  30. package/esm/cell-block/cellblock-utils.js.map +1 -1
  31. package/esm/cell-block/useCellBlockSelection.js +68 -73
  32. package/esm/cell-block/useCellBlockSelection.js.map +1 -1
  33. package/esm/table-dom-utils.js +64 -10
  34. package/esm/table-dom-utils.js.map +1 -1
  35. package/esm/table-header/useTableHeader.js +1 -1
  36. package/esm/table-header/useTableHeader.js.map +1 -1
  37. package/esm/useCellFocus.js +54 -0
  38. package/esm/useCellFocus.js.map +1 -0
  39. package/esm/useKeyboardNavigation.js +5 -81
  40. package/esm/useKeyboardNavigation.js.map +1 -1
  41. package/esm/useMeasuredHeight.js +5 -5
  42. package/esm/useMeasuredHeight.js.map +1 -1
  43. package/esm/useTable.js +21 -7
  44. package/esm/useTable.js.map +1 -1
  45. package/esm/useTableContextMenu.js +2 -1
  46. package/esm/useTableContextMenu.js.map +1 -1
  47. package/package.json +9 -9
  48. package/types/Table.d.ts +3 -0
  49. package/types/cell-block/CellBlock.d.ts +2 -1
  50. package/types/cell-block/cellblock-utils.d.ts +20 -0
  51. package/types/cell-block/useCellBlockSelection.d.ts +7 -2
  52. package/types/table-dom-utils.d.ts +6 -1
  53. package/types/useCellFocus.d.ts +13 -0
  54. package/types/useKeyboardNavigation.d.ts +5 -5
  55. package/types/useMeasuredHeight.d.ts +2 -2
  56. package/types/useTable.d.ts +2 -1
@@ -1 +1 @@
1
- {"version":3,"file":"useCellBlockSelection.js","sources":["../../src/cell-block/useCellBlockSelection.tsx"],"sourcesContent":["import { queryClosest } from \"@vuu-ui/vuu-utils\";\nimport {\n KeyboardEventHandler,\n MouseEventHandler,\n ReactElement,\n RefCallback,\n useCallback,\n useRef,\n useState,\n} from \"react\";\nimport { CellBlock } from \"./CellBlock\";\nimport {\n CellBox,\n TableCellBlock,\n getEndCellDirection,\n getTableCellBlock,\n outsideBox,\n setElementBox,\n} from \"./cellblock-utils\";\n\nconst Hi = Number.MAX_SAFE_INTEGER;\n\ntype RefState = {\n dragState: \"pending\" | \"active\";\n cellBlock: HTMLDivElement | null;\n cellBlockClassName: string;\n endBox: CellBox;\n endCell: HTMLDivElement | null;\n mousePosX: number;\n mousePosY: number;\n mouseStartX: number;\n mouseStartY: number;\n startCell: HTMLDivElement | null;\n startBox: CellBox;\n};\n\nconst refState: RefState = {\n cellBlock: null,\n cellBlockClassName: \"\",\n dragState: \"pending\",\n endBox: { bottom: -1, left: Hi, right: -1, top: Hi },\n endCell: null,\n mousePosX: -1,\n mousePosY: -1,\n mouseStartX: -1,\n mouseStartY: -1,\n startBox: { bottom: -1, left: -1, right: -1, top: -1 },\n startCell: null,\n} as const;\n\ntype NativeKeyboardHandler = (evt: KeyboardEvent) => void;\ntype NativeMouseHandler = (evt: MouseEvent) => void;\ntype MouseHandlers = {\n mouseMove: NativeMouseHandler;\n mouseMovePreDrag: NativeMouseHandler;\n mouseUp: NativeMouseHandler;\n mouseUpPreDrag: NativeMouseHandler;\n};\n\nconst NullHandler = () => console.error(\"no handler installed\");\nconst mouseHandlers: MouseHandlers = {\n mouseMove: NullHandler,\n mouseMovePreDrag: NullHandler,\n mouseUp: NullHandler,\n mouseUpPreDrag: NullHandler,\n};\n\ntype MouseOperation = keyof typeof mouseHandlers;\n\nconst mouseType = (name: string) =>\n name.startsWith(\"mouseMove\") ? \"mousemove\" : \"mouseup\";\n\nconst DRAG_THRESHOLD = 5;\n\nexport interface CellblockSelectionHookProps {\n allowCellBlockSelection?: boolean;\n onSelectCellBlock?: (cellBlock: TableCellBlock) => void;\n}\n\nexport const useCellBlockSelection = ({\n allowCellBlockSelection,\n onSelectCellBlock,\n}: CellblockSelectionHookProps) => {\n const [cellBlock, setCellBlock] = useState<ReactElement | null>(null);\n const stateRef = useRef<RefState>(refState);\n const handlersRef = useRef<MouseHandlers>(mouseHandlers);\n\n const cellBlockRef = useCallback<RefCallback<HTMLDivElement>>((el) => {\n stateRef.current.cellBlock = el;\n }, []);\n\n const createCellBlock = useCallback(() => {\n const { startBox, startCell } = stateRef.current;\n if (startCell) {\n setElementBox(startCell, startBox);\n startCell.classList.add(\"vuu-cellblock-start\");\n setCellBlock(<CellBlock ref={cellBlockRef} />);\n }\n }, [cellBlockRef]);\n\n const initializeStateRef = useCallback(() => {\n const { cellBlock, cellBlockClassName, startCell, endCell } =\n stateRef.current;\n if (startCell) {\n startCell.classList.remove(\"vuu-cellblock-start\");\n }\n if (endCell) {\n endCell.classList.remove(\"vuu-cellblock-end\");\n }\n if (cellBlock?.classList.contains(cellBlockClassName)) {\n cellBlock.classList.remove(cellBlockClassName);\n }\n\n const { endBox, startBox } = refState;\n\n stateRef.current = {\n ...refState,\n cellBlock,\n endBox: { ...endBox },\n startBox: { ...startBox },\n };\n }, []);\n\n const addMouseListener = useCallback(\n (mouseOperation: MouseOperation, handler: NativeMouseHandler) => {\n window.addEventListener(mouseType(mouseOperation), handler);\n handlersRef.current[mouseOperation] = handler;\n },\n [],\n );\n\n const removeMouseListener = useCallback((name: MouseOperation) => {\n window.removeEventListener(mouseType(name), handlersRef.current[name]);\n }, []);\n\n handlersRef.current.mouseMove = useCallback((evt: MouseEvent) => {\n const { clientX: x, clientY: y } = evt;\n const { cellBlock, cellBlockClassName, endBox, startBox } =\n stateRef.current;\n if (outsideBox(startBox, x, y) && outsideBox(endBox, x, y)) {\n const cell = queryClosest<HTMLDivElement>(\n evt.target,\n \".vuuTableCell, .vuuCellBlock\",\n );\n const table = queryClosest<HTMLDivElement>(cell, \".vuuTable\");\n if (table) {\n table.classList.add(\"vuu-cellblock-select-in-progress\");\n }\n if (cell?.classList.contains(\"vuuTableCell\")) {\n setElementBox(cell, endBox);\n stateRef.current.endCell = cell;\n const endBlockDirection = getEndCellDirection(startBox, endBox);\n const newCellBlockClassName = `cellblock-direction-${endBlockDirection}`;\n if (newCellBlockClassName !== cellBlockClassName) {\n if (cellBlockClassName) {\n cellBlock?.classList.replace(\n cellBlockClassName,\n newCellBlockClassName,\n );\n } else {\n cellBlock?.classList.add(newCellBlockClassName);\n }\n stateRef.current.cellBlockClassName = newCellBlockClassName;\n }\n }\n }\n }, []);\n\n handlersRef.current.mouseUp = useCallback(\n (evt: MouseEvent) => {\n removeMouseListener(\"mouseMove\");\n removeMouseListener(\"mouseUp\");\n\n const { endCell, startCell } = stateRef.current;\n\n const table = queryClosest<HTMLDivElement>(evt.target, \".vuuTable\");\n endCell?.classList.add(\"vuu-cellblock-end\");\n if (table) {\n table.classList.remove(\"vuu-cellblock-select-in-progress\");\n }\n\n if (startCell && endCell) {\n const tableCellBlock = getTableCellBlock(startCell, endCell);\n onSelectCellBlock?.(tableCellBlock);\n }\n },\n [onSelectCellBlock, removeMouseListener],\n );\n\n handlersRef.current.mouseMovePreDrag = useCallback(\n (evt: MouseEvent) => {\n const { current: state } = stateRef;\n const { mouseStartX, mouseStartY } = state;\n\n const x = (state.mousePosX = evt.clientX);\n const y = (state.mousePosY = evt.clientY);\n\n const distance = Math.max(\n Math.abs(x - mouseStartX),\n Math.abs(y - mouseStartY),\n );\n\n if (distance > DRAG_THRESHOLD) {\n createCellBlock();\n\n const { mouseMove, mouseUp } = handlersRef.current;\n removeMouseListener(\"mouseMovePreDrag\");\n removeMouseListener(\"mouseUpPreDrag\");\n addMouseListener(\"mouseMove\", mouseMove);\n addMouseListener(\"mouseUp\", mouseUp);\n }\n },\n [addMouseListener, createCellBlock, removeMouseListener],\n );\n\n handlersRef.current.mouseUpPreDrag = useCallback(() => {\n removeMouseListener(\"mouseMovePreDrag\");\n removeMouseListener(\"mouseUpPreDrag\");\n }, [removeMouseListener]);\n\n const handleMouseDown = useCallback<MouseEventHandler>(\n (evt) => {\n initializeStateRef();\n const { current: state } = stateRef;\n const cell = queryClosest<HTMLDivElement>(evt.target, \".vuuTableCell\");\n if (cell) {\n state.startCell = cell;\n state.mouseStartX = evt.clientX;\n state.mouseStartY = evt.clientY;\n\n const { mouseMovePreDrag, mouseUpPreDrag } = handlersRef.current;\n addMouseListener(\"mouseMovePreDrag\", mouseMovePreDrag);\n addMouseListener(\"mouseUpPreDrag\", mouseUpPreDrag);\n }\n },\n [addMouseListener, initializeStateRef],\n );\n\n const shiftingRef = useRef(false);\n const cellBlockEndRef = useRef([0, 0]);\n const nativeKeyDownHandlerRef = useRef<NativeKeyboardHandler>(NullHandler);\n\n const handleNativeKeyUp = useCallback((evt: KeyboardEvent) => {\n if (evt.key === \"Shift\") {\n const { current: pos } = cellBlockEndRef;\n\n if (pos[0] || pos[1]) {\n console.log(`cell selection [${pos[0]},${pos[1]}]`);\n }\n console.log(\"abandon cellblock selection\");\n shiftingRef.current = false;\n\n window.removeEventListener(\"keydown\", nativeKeyDownHandlerRef.current, {\n capture: true,\n });\n window.removeEventListener(\"keyup\", handleNativeKeyUp, {\n capture: true,\n });\n }\n }, []);\n const handleNativeKeyDown = (nativeKeyDownHandlerRef.current = useCallback(\n (evt: KeyboardEvent) => {\n if (evt.key.startsWith(\"Arrow\")) {\n const { current: pos } = cellBlockEndRef;\n switch (evt.key) {\n case \"ArrowRight\":\n pos[0] += 1;\n break;\n case \"ArrowLEFT\":\n pos[0] -= 1;\n break;\n case \"ArrowUP\":\n pos[1] -= 1;\n break;\n case \"ArrowDown\":\n pos[1] += 1;\n break;\n }\n }\n },\n [],\n ));\n const handleKeyDown = useCallback<KeyboardEventHandler>(\n (evt) => {\n if (evt.key === \"Shift\") {\n shiftingRef.current = true;\n\n const cell = queryClosest<HTMLDivElement>(evt.target, \".vuuTableCell\");\n if (cell) {\n const { current: state } = stateRef;\n state.startCell = cell;\n window.addEventListener(\"keydown\", handleNativeKeyDown, {\n capture: true,\n });\n window.addEventListener(\"keyup\", handleNativeKeyUp, {\n capture: true,\n });\n\n evt.preventDefault();\n }\n }\n },\n [handleNativeKeyDown, handleNativeKeyUp],\n );\n\n return {\n cellBlock,\n onKeyDown: allowCellBlockSelection ? handleKeyDown : undefined,\n onMouseDown: allowCellBlockSelection ? handleMouseDown : undefined,\n };\n};\n"],"names":["useState","useRef","useCallback","setElementBox","jsx","CellBlock","cellBlock","outsideBox","queryClosest","getEndCellDirection","getTableCellBlock"],"mappings":"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"}
1
+ {"version":3,"file":"useCellBlockSelection.js","sources":["../../src/cell-block/useCellBlockSelection.tsx"],"sourcesContent":["import { isArrowKey, queryClosest } from \"@vuu-ui/vuu-utils\";\nimport {\n KeyboardEventHandler,\n MouseEventHandler,\n ReactElement,\n RefCallback,\n RefObject,\n useCallback,\n useRef,\n useState,\n} from \"react\";\nimport {\n getNextCellPos,\n getTableCell,\n getTableCellPos,\n} from \"../table-dom-utils\";\nimport { FocusCell } from \"../useCellFocus\";\nimport { CellBlock } from \"./CellBlock\";\nimport {\n PosTuple,\n RefState,\n TableCellBlock,\n getTableCellBlock,\n getTextFromCells,\n isNullCellBox,\n outsideBox,\n refState,\n setElementBox,\n updateCellBlockClassName,\n} from \"./cellblock-utils\";\n\nconst clone = (posTuple: PosTuple) => posTuple.slice() as PosTuple;\n\ntype NativeKeyboardHandler = (evt: KeyboardEvent) => void;\ntype NativeMouseHandler = (evt: MouseEvent) => void;\ntype MouseHandlers = {\n mouseMove: NativeMouseHandler;\n mouseMovePreDrag: NativeMouseHandler;\n mouseUp: NativeMouseHandler;\n mouseUpPreDrag: NativeMouseHandler;\n};\n\nconst NullHandler = () => console.error(\"no handler installed\");\nconst mouseHandlers: MouseHandlers = {\n mouseMove: NullHandler,\n mouseMovePreDrag: NullHandler,\n mouseUp: NullHandler,\n mouseUpPreDrag: NullHandler,\n};\n\ntype MouseOperation = keyof typeof mouseHandlers;\n\nconst mouseType = (name: string) =>\n name.startsWith(\"mouseMove\") ? \"mousemove\" : \"mouseup\";\n\nconst DRAG_THRESHOLD = 5;\n\nexport interface CellblockSelectionHookProps {\n allowCellBlockSelection?: boolean;\n columnCount?: number;\n containerRef: RefObject<HTMLElement>;\n focusCell: FocusCell;\n onSelectCellBlock?: (cellBlock: TableCellBlock) => void;\n rowCount?: number;\n}\n\nexport const useCellBlockSelection = ({\n allowCellBlockSelection,\n columnCount = 0,\n containerRef,\n focusCell,\n onSelectCellBlock,\n rowCount = 0,\n}: CellblockSelectionHookProps) => {\n const [cellBlock, setCellBlock] = useState<ReactElement | null>(null);\n const stateRef = useRef<RefState>(refState);\n const handlersRef = useRef<MouseHandlers>(mouseHandlers);\n\n const handleCopy = useCallback(async () => {\n const { startCell, endCell } = stateRef.current;\n if (startCell && endCell) {\n const tsvText = getTextFromCells(startCell, endCell);\n const type = \"text/plain\";\n const blob = new Blob([tsvText], { type });\n const data = [new ClipboardItem({ [type]: blob })];\n await navigator.clipboard.write(data);\n }\n }, []);\n\n const cellBlockRef = useCallback<RefCallback<HTMLDivElement>>((el) => {\n stateRef.current.cellBlock = el;\n }, []);\n\n const createCellBlock = useCallback(\n (method: \"mouse\" | \"keyboard\" = \"mouse\") => {\n const { startBox, startCell } = stateRef.current;\n if (startCell) {\n const table = queryClosest<HTMLDivElement>(startCell, \".vuuTable\");\n if (table) {\n table.classList.add(`vuu-cellblock-select-in-progress-${method}`);\n }\n setElementBox(startCell, startBox);\n startCell.classList.add(\"vuu-cellblock-start\");\n setCellBlock(<CellBlock onCopy={handleCopy} ref={cellBlockRef} />);\n }\n },\n [cellBlockRef, handleCopy],\n );\n\n const initializeStateRef = useCallback(() => {\n const { cellBlock, cellBlockClassName, startCell, endCell } =\n stateRef.current;\n if (startCell) {\n startCell.classList.remove(\"vuu-cellblock-start\");\n }\n if (endCell) {\n endCell.classList.remove(\"vuu-cellblock-end\");\n }\n if (cellBlock?.classList.contains(cellBlockClassName)) {\n cellBlock.classList.remove(cellBlockClassName);\n }\n\n const { endBox, startBox } = refState;\n\n stateRef.current = {\n ...refState,\n cellBlock,\n endBox: { ...endBox },\n endPos: [-1, -1],\n startBox: { ...startBox },\n startPos: [-1, -1],\n };\n }, []);\n\n const addMouseListener = useCallback(\n (mouseOperation: MouseOperation, handler: NativeMouseHandler) => {\n window.addEventListener(mouseType(mouseOperation), handler);\n handlersRef.current[mouseOperation] = handler;\n },\n [],\n );\n\n const removeMouseListener = useCallback((name: MouseOperation) => {\n window.removeEventListener(mouseType(name), handlersRef.current[name]);\n }, []);\n\n handlersRef.current.mouseMove = useCallback((evt: MouseEvent) => {\n const { clientX: x, clientY: y } = evt;\n const { endBox, startBox } = stateRef.current;\n if (outsideBox(startBox, x, y) && outsideBox(endBox, x, y)) {\n const cell = queryClosest<HTMLDivElement>(\n evt.target,\n \".vuuTableCell, .vuuCellBlock\",\n );\n if (cell?.classList.contains(\"vuuTableCell\")) {\n setElementBox(cell, endBox);\n stateRef.current.endCell = cell;\n updateCellBlockClassName(stateRef.current);\n }\n }\n }, []);\n\n handlersRef.current.mouseUp = useCallback(\n (evt: MouseEvent) => {\n removeMouseListener(\"mouseMove\");\n removeMouseListener(\"mouseUp\");\n\n const { cellBlock, endCell, startCell } = stateRef.current;\n\n const table = queryClosest<HTMLDivElement>(evt.target, \".vuuTable\");\n endCell?.classList.add(\"vuu-cellblock-end\");\n if (table) {\n table.classList.remove(\"vuu-cellblock-select-in-progress-mouse\");\n }\n\n if (startCell && endCell) {\n const tableCellBlock = getTableCellBlock(startCell, endCell);\n onSelectCellBlock?.(tableCellBlock);\n }\n\n if (cellBlock) {\n cellBlock.focus();\n }\n },\n [onSelectCellBlock, removeMouseListener],\n );\n\n handlersRef.current.mouseMovePreDrag = useCallback(\n (evt: MouseEvent) => {\n const { current: state } = stateRef;\n const { mouseStartX, mouseStartY } = state;\n\n const x = (state.mousePosX = evt.clientX);\n const y = (state.mousePosY = evt.clientY);\n\n const distance = Math.max(\n Math.abs(x - mouseStartX),\n Math.abs(y - mouseStartY),\n );\n\n if (distance > DRAG_THRESHOLD) {\n createCellBlock(\"mouse\");\n\n const { mouseMove, mouseUp } = handlersRef.current;\n removeMouseListener(\"mouseMovePreDrag\");\n removeMouseListener(\"mouseUpPreDrag\");\n addMouseListener(\"mouseMove\", mouseMove);\n addMouseListener(\"mouseUp\", mouseUp);\n }\n },\n [addMouseListener, createCellBlock, removeMouseListener],\n );\n\n handlersRef.current.mouseUpPreDrag = useCallback(() => {\n removeMouseListener(\"mouseMovePreDrag\");\n removeMouseListener(\"mouseUpPreDrag\");\n }, [removeMouseListener]);\n\n const handleMouseDown = useCallback<MouseEventHandler>(\n (evt) => {\n initializeStateRef();\n const { current: state } = stateRef;\n const cell = queryClosest<HTMLDivElement>(evt.target, \".vuuTableCell\");\n if (cell) {\n state.startCell = cell;\n state.mouseStartX = evt.clientX;\n state.mouseStartY = evt.clientY;\n\n const { mouseMovePreDrag, mouseUpPreDrag } = handlersRef.current;\n addMouseListener(\"mouseMovePreDrag\", mouseMovePreDrag);\n addMouseListener(\"mouseUpPreDrag\", mouseUpPreDrag);\n }\n },\n [addMouseListener, initializeStateRef],\n );\n\n const nativeKeyDownHandlerRef = useRef<NativeKeyboardHandler>(NullHandler);\n\n const handleNativeKeyUp = useCallback((evt: KeyboardEvent) => {\n if (evt.key === \"Shift\") {\n const { endCell } = stateRef.current;\n const table = queryClosest<HTMLDivElement>(evt.target, \".vuuTable\");\n endCell?.classList.add(\"vuu-cellblock-end\");\n if (table) {\n table.classList.remove(\"vuu-cellblock-select-in-progress-keyboard\");\n }\n\n window.removeEventListener(\"keydown\", nativeKeyDownHandlerRef.current, {\n capture: true,\n });\n window.removeEventListener(\"keyup\", handleNativeKeyUp, {\n capture: true,\n });\n }\n }, []);\n const handleNativeKeyDown = (nativeKeyDownHandlerRef.current = useCallback(\n ({ key }: KeyboardEvent) => {\n if (isArrowKey(key)) {\n const { endBox, endPos, startBox } = stateRef.current;\n if (isNullCellBox(startBox)) {\n createCellBlock(\"keyboard\");\n }\n const nextCell = getNextCellPos(key, endPos, columnCount, rowCount);\n stateRef.current.endPos = nextCell;\n focusCell(nextCell);\n const cell = getTableCell(containerRef, nextCell);\n stateRef.current.endCell = cell as HTMLDivElement;\n setElementBox(cell, endBox);\n updateCellBlockClassName(stateRef.current);\n }\n },\n [columnCount, containerRef, createCellBlock, focusCell, rowCount],\n ));\n const handleKeyDown = useCallback<KeyboardEventHandler>(\n (evt) => {\n if (evt.key === \"Shift\") {\n initializeStateRef();\n const cell = queryClosest<HTMLDivElement>(evt.target, \".vuuTableCell\");\n if (cell) {\n const startPos = getTableCellPos(cell);\n stateRef.current.startPos = startPos;\n stateRef.current.endPos = clone(startPos);\n const { current: state } = stateRef;\n state.startCell = cell;\n\n window.addEventListener(\"keydown\", handleNativeKeyDown, {\n capture: true,\n });\n window.addEventListener(\"keyup\", handleNativeKeyUp, {\n capture: true,\n });\n\n evt.preventDefault();\n }\n }\n },\n [handleNativeKeyDown, handleNativeKeyUp, initializeStateRef],\n );\n\n return {\n cellBlock,\n onKeyDown: allowCellBlockSelection ? handleKeyDown : undefined,\n onMouseDown: allowCellBlockSelection ? handleMouseDown : undefined,\n };\n};\n"],"names":["useState","useRef","refState","useCallback","getTextFromCells","queryClosest","setElementBox","CellBlock","cellBlock","outsideBox","updateCellBlockClassName","getTableCellBlock","isArrowKey","isNullCellBox","getNextCellPos","getTableCell","getTableCellPos"],"mappings":"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"}
@@ -1,7 +1,8 @@
1
1
  'use strict';
2
2
 
3
- const headerCellQuery = (colIdx) => `.vuuTable-col-headers .vuuTableHeaderCell:nth-child(${colIdx})`;
4
- const dataCellQuery = (rowIdx, colIdx) => `.vuuTable-body > [aria-rowindex='${rowIdx + 1}'] > [role='cell']:nth-child(${colIdx + 1})`;
3
+ const NULL_CELL_POS = [-1, -1];
4
+ const headerCellQuery = (colIdx) => `.vuuTable-col-headers .vuuTableHeaderCell[aria-colindex='${colIdx + 1}']`;
5
+ const dataCellQuery = (rowIdx, colIdx) => `.vuuTable-body > [aria-rowindex='${rowIdx + 1}'] > [aria-colindex='${colIdx + 1}']`;
5
6
  const getTableCell = (containerRef, [rowIdx, colIdx]) => {
6
7
  const cssQuery = rowIdx === -1 ? headerCellQuery(colIdx) : dataCellQuery(rowIdx, colIdx);
7
8
  const cell = containerRef.current?.querySelector(
@@ -22,17 +23,70 @@ const cellDropdownShowing = (cell) => {
22
23
  return false;
23
24
  };
24
25
  const cellIsTextInput = (cell) => cell.querySelector(".vuuTableInputCell") !== null;
25
- function getRowIndex(rowEl) {
26
- if (rowEl) {
27
- const idx = rowEl.ariaRowIndex;
28
- if (idx !== null) {
29
- return parseInt(idx, 10) - 1;
26
+ const getIndexFromRowElement = (rowElement) => {
27
+ const rowIndex = rowElement?.ariaRowIndex;
28
+ if (rowIndex != null) {
29
+ const index = parseInt(rowIndex) - 1;
30
+ if (!isNaN(index)) {
31
+ return index;
30
32
  }
31
33
  }
32
34
  return -1;
33
- }
35
+ };
36
+ const getIndexFromCellElement = (cellElement) => {
37
+ const colIndex = cellElement?.ariaColIndex;
38
+ if (colIndex != null) {
39
+ const index = parseInt(colIndex) - 1;
40
+ if (!isNaN(index)) {
41
+ return index;
42
+ }
43
+ }
44
+ return -1;
45
+ };
46
+ const getTableCellPos = (tableCell) => {
47
+ const colIdx = getIndexFromCellElement(tableCell);
48
+ if (tableCell.role === "columnHeader") {
49
+ return [-1, colIdx];
50
+ } else {
51
+ const focusedRow = tableCell.closest("[role='row']");
52
+ if (focusedRow) {
53
+ return [getIndexFromRowElement(focusedRow), colIdx];
54
+ }
55
+ }
56
+ return NULL_CELL_POS;
57
+ };
34
58
  const closestRow = (el) => el.closest('[role="row"]');
35
- const closestRowIndex = (el) => getRowIndex(closestRow(el));
59
+ const closestRowIndex = (el) => getIndexFromRowElement(closestRow(el));
60
+ function getNextCellPos(key, [rowIdx, colIdx], columnCount, rowCount) {
61
+ if (key === "ArrowUp") {
62
+ if (rowIdx > -1) {
63
+ return [rowIdx - 1, colIdx];
64
+ } else {
65
+ return [rowIdx, colIdx];
66
+ }
67
+ } else if (key === "ArrowDown") {
68
+ if (rowIdx === -1) {
69
+ return [0, colIdx];
70
+ } else if (rowIdx === rowCount - 1) {
71
+ return [rowIdx, colIdx];
72
+ } else {
73
+ return [rowIdx + 1, colIdx];
74
+ }
75
+ } else if (key === "ArrowRight") {
76
+ if (colIdx < columnCount - 1) {
77
+ return [rowIdx, colIdx + 1];
78
+ } else {
79
+ return [rowIdx, colIdx];
80
+ }
81
+ } else if (key === "ArrowLeft") {
82
+ if (colIdx > 0) {
83
+ return [rowIdx, colIdx - 1];
84
+ } else {
85
+ return [rowIdx, colIdx];
86
+ }
87
+ }
88
+ return [rowIdx, colIdx];
89
+ }
36
90
  const NO_SCROLL_NECESSARY = [void 0, void 0];
37
91
  const howFarIsRowOutsideViewport = (rowEl, totalHeaderHeight, contentContainer = rowEl.closest(".vuuTable-contentContainer")) => {
38
92
  if (contentContainer) {
@@ -60,8 +114,11 @@ exports.cellIsEditable = cellIsEditable;
60
114
  exports.cellIsTextInput = cellIsTextInput;
61
115
  exports.closestRowIndex = closestRowIndex;
62
116
  exports.dataCellQuery = dataCellQuery;
63
- exports.getRowIndex = getRowIndex;
117
+ exports.getIndexFromCellElement = getIndexFromCellElement;
118
+ exports.getIndexFromRowElement = getIndexFromRowElement;
119
+ exports.getNextCellPos = getNextCellPos;
64
120
  exports.getTableCell = getTableCell;
121
+ exports.getTableCellPos = getTableCellPos;
65
122
  exports.headerCellQuery = headerCellQuery;
66
123
  exports.howFarIsRowOutsideViewport = howFarIsRowOutsideViewport;
67
124
  //# sourceMappingURL=table-dom-utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"table-dom-utils.js","sources":["../src/table-dom-utils.ts"],"sourcesContent":["import { RefObject } from \"react\";\nimport { ScrollDirection } from \"./useTableScroll\";\n\n/**\n * [rowIndex, colIndex\n */\nexport type CellPos = [number, number];\n\nexport const headerCellQuery = (colIdx: number) =>\n `.vuuTable-col-headers .vuuTableHeaderCell:nth-child(${colIdx})`;\n\nexport const dataCellQuery = (rowIdx: number, colIdx: number) =>\n `.vuuTable-body > [aria-rowindex='${rowIdx + 1}'] > [role='cell']:nth-child(${\n colIdx + 1\n })`;\n\nexport const getTableCell = (\n containerRef: RefObject<HTMLElement>,\n\n [rowIdx, colIdx]: CellPos\n) => {\n const cssQuery =\n rowIdx === -1 ? headerCellQuery(colIdx) : dataCellQuery(rowIdx, colIdx);\n const cell = containerRef.current?.querySelector(\n cssQuery\n ) as HTMLTableCellElement;\n\n if (cellIsEditable(cell)) {\n // Dropdown gets focus, Input does not\n const focusableContent = cell.querySelector(\"button\") as HTMLElement;\n return focusableContent || cell;\n } else {\n return cell;\n }\n};\n\nexport const cellIsEditable = (cell: HTMLDivElement | null) =>\n cell?.classList.contains(\"vuuTableCell-editable\");\n\nexport const cellDropdownShowing = (cell: HTMLDivElement | null) => {\n if (cellIsEditable(cell)) {\n return cell?.querySelector('.saltDropdown[aria-expanded=\"true\"]') !== null;\n }\n return false;\n};\n\nexport const cellIsTextInput = (cell: HTMLElement) =>\n cell.querySelector(\".vuuTableInputCell\") !== null;\n\nexport function getRowIndex(rowEl?: HTMLElement) {\n if (rowEl) {\n const idx: string | null = rowEl.ariaRowIndex;\n if (idx !== null) {\n return parseInt(idx, 10) - 1;\n }\n }\n return -1;\n}\n\nconst closestRow = (el: HTMLElement) =>\n el.closest('[role=\"row\"]') as HTMLElement;\n\nexport const closestRowIndex = (el: HTMLElement) => getRowIndex(closestRow(el));\n\nconst NO_SCROLL_NECESSARY = [undefined, undefined] as const;\n\nexport const howFarIsRowOutsideViewport = (\n rowEl: HTMLElement,\n totalHeaderHeight: number,\n contentContainer = rowEl.closest(\".vuuTable-contentContainer\")\n): readonly [ScrollDirection | undefined, number | undefined] => {\n //TODO lots of scope for optimisation here\n if (contentContainer) {\n // TODO take totalHeaderHeight into consideration\n const viewport = contentContainer?.getBoundingClientRect();\n const upperBoundary = viewport.top + totalHeaderHeight;\n const row = rowEl.getBoundingClientRect();\n if (row) {\n if (row.bottom > viewport.bottom) {\n return [\"down\", row.bottom - viewport.bottom];\n } else if (row.top < upperBoundary) {\n return [\"up\", row.top - upperBoundary];\n } else {\n return NO_SCROLL_NECESSARY;\n }\n } else {\n throw Error(\"Whats going on, row not found\");\n }\n } else {\n throw Error(\"Whats going on, scrollbar container not found\");\n }\n};\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"table-dom-utils.js","sources":["../src/table-dom-utils.ts"],"sourcesContent":["import { RefObject } from \"react\";\nimport { ScrollDirection } from \"./useTableScroll\";\nimport type { ArrowKey, PageKey } from \"@vuu-ui/vuu-utils\";\n\nconst NULL_CELL_POS: CellPos = [-1, -1];\n\n/**\n * [rowIndex, colIndex\n */\nexport type CellPos = [number, number];\n\nexport type NavigationKey = PageKey | ArrowKey;\n\nexport const headerCellQuery = (colIdx: number) =>\n `.vuuTable-col-headers .vuuTableHeaderCell[aria-colindex='${colIdx + 1}']`;\n\nexport const dataCellQuery = (rowIdx: number, colIdx: number) =>\n `.vuuTable-body > [aria-rowindex='${rowIdx + 1}'] > [aria-colindex='${colIdx + 1}']`;\n\nexport const getTableCell = (\n containerRef: RefObject<HTMLElement>,\n [rowIdx, colIdx]: CellPos,\n) => {\n const cssQuery =\n rowIdx === -1 ? headerCellQuery(colIdx) : dataCellQuery(rowIdx, colIdx);\n const cell = containerRef.current?.querySelector(\n cssQuery,\n ) as HTMLTableCellElement;\n\n if (cellIsEditable(cell)) {\n // Dropdown gets focus, Input does not\n const focusableContent = cell.querySelector(\"button\") as HTMLElement;\n return focusableContent || cell;\n } else {\n return cell;\n }\n};\n\nexport const cellIsEditable = (cell: HTMLDivElement | null) =>\n cell?.classList.contains(\"vuuTableCell-editable\");\n\nexport const cellDropdownShowing = (cell: HTMLDivElement | null) => {\n if (cellIsEditable(cell)) {\n return cell?.querySelector('.saltDropdown[aria-expanded=\"true\"]') !== null;\n }\n return false;\n};\n\nexport const cellIsTextInput = (cell: HTMLElement) =>\n cell.querySelector(\".vuuTableInputCell\") !== null;\n\nexport const getIndexFromRowElement = (rowElement: HTMLElement | null) => {\n const rowIndex = rowElement?.ariaRowIndex;\n if (rowIndex != null) {\n const index = parseInt(rowIndex) - 1;\n if (!isNaN(index)) {\n return index;\n }\n }\n return -1;\n};\n\nexport const getIndexFromCellElement = (cellElement: HTMLElement | null) => {\n const colIndex = cellElement?.ariaColIndex;\n if (colIndex != null) {\n const index = parseInt(colIndex) - 1;\n if (!isNaN(index)) {\n return index;\n }\n }\n return -1;\n};\n\nexport const getTableCellPos = (tableCell: HTMLDivElement): CellPos => {\n const colIdx = getIndexFromCellElement(tableCell);\n if (tableCell.role === \"columnHeader\") {\n return [-1, colIdx];\n } else {\n const focusedRow = tableCell.closest(\"[role='row']\") as HTMLElement;\n if (focusedRow) {\n return [getIndexFromRowElement(focusedRow), colIdx];\n }\n }\n return NULL_CELL_POS;\n};\n\nconst closestRow = (el: HTMLElement) =>\n el.closest('[role=\"row\"]') as HTMLElement;\n\nexport const closestRowIndex = (el: HTMLElement) =>\n getIndexFromRowElement(closestRow(el));\n\nexport function getNextCellPos(\n key: ArrowKey,\n [rowIdx, colIdx]: CellPos,\n columnCount: number,\n rowCount: number,\n): CellPos {\n if (key === \"ArrowUp\") {\n if (rowIdx > -1) {\n return [rowIdx - 1, colIdx];\n } else {\n return [rowIdx, colIdx];\n }\n } else if (key === \"ArrowDown\") {\n if (rowIdx === -1) {\n return [0, colIdx];\n } else if (rowIdx === rowCount - 1) {\n return [rowIdx, colIdx];\n } else {\n return [rowIdx + 1, colIdx];\n }\n } else if (key === \"ArrowRight\") {\n if (colIdx < columnCount - 1) {\n return [rowIdx, colIdx + 1];\n } else {\n return [rowIdx, colIdx];\n }\n } else if (key === \"ArrowLeft\") {\n if (colIdx > 0) {\n return [rowIdx, colIdx - 1];\n } else {\n return [rowIdx, colIdx];\n }\n }\n return [rowIdx, colIdx];\n}\n\nconst NO_SCROLL_NECESSARY = [undefined, undefined] as const;\n\nexport const howFarIsRowOutsideViewport = (\n rowEl: HTMLElement,\n totalHeaderHeight: number,\n contentContainer = rowEl.closest(\".vuuTable-contentContainer\"),\n): readonly [ScrollDirection | undefined, number | undefined] => {\n //TODO lots of scope for optimisation here\n if (contentContainer) {\n // TODO take totalHeaderHeight into consideration\n const viewport = contentContainer?.getBoundingClientRect();\n const upperBoundary = viewport.top + totalHeaderHeight;\n const row = rowEl.getBoundingClientRect();\n if (row) {\n if (row.bottom > viewport.bottom) {\n return [\"down\", row.bottom - viewport.bottom];\n } else if (row.top < upperBoundary) {\n return [\"up\", row.top - upperBoundary];\n } else {\n return NO_SCROLL_NECESSARY;\n }\n } else {\n throw Error(\"Whats going on, row not found\");\n }\n } else {\n throw Error(\"Whats going on, scrollbar container not found\");\n }\n};\n"],"names":[],"mappings":"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"}
@@ -16,7 +16,7 @@ const useTableHeader = ({
16
16
  }) => {
17
17
  const containerRef = react.useRef(null);
18
18
  const scrollingContainerRef = react.useRef(null);
19
- const { rowRef } = useMeasuredHeight.useMeasuredHeight({
19
+ const { measuredRef: rowRef } = useMeasuredHeight.useMeasuredHeight({
20
20
  onHeightMeasured
21
21
  });
22
22
  const setContainerRef = react.useCallback((el) => {
@@ -1 +1 @@
1
- {"version":3,"file":"useTableHeader.js","sources":["../../src/table-header/useTableHeader.ts"],"sourcesContent":["import { ColumnDescriptor } from \"@vuu-ui/vuu-table-types\";\nimport {\n DropOptions,\n useDragDrop as useDragDrop,\n} from \"@vuu-ui/vuu-ui-controls\";\nimport {\n moveColumnTo,\n queryClosest,\n visibleColumnAtIndex,\n} from \"@vuu-ui/vuu-utils\";\nimport { RefCallback, useCallback, useRef } from \"react\";\nimport { TableHeaderProps } from \"./TableHeader\";\nimport { useMeasuredHeight } from \"../useMeasuredHeight\";\nimport { useForkRef } from \"@salt-ds/core\";\n\nexport interface TableHeaderHookProps\n extends Pick<\n TableHeaderProps,\n | \"allowDragColumnHeader\"\n | \"columns\"\n | \"onMoveColumn\"\n | \"onSortColumn\"\n | \"tableConfig\"\n > {\n label?: string;\n onHeightMeasured: (height: number) => void;\n onMoveColumn: (columns: ColumnDescriptor[]) => void;\n onSortColumn: (column: ColumnDescriptor, addToExistingSort: boolean) => void;\n}\n\nexport const useTableHeader = ({\n allowDragColumnHeader,\n columns,\n onHeightMeasured,\n onMoveColumn,\n onSortColumn,\n tableConfig,\n}: TableHeaderHookProps) => {\n const containerRef = useRef<HTMLDivElement | null>(null);\n const scrollingContainerRef = useRef<HTMLDivElement | null>(null);\n const { rowRef } = useMeasuredHeight({\n onHeightMeasured,\n });\n\n const setContainerRef = useCallback<RefCallback<HTMLDivElement>>((el) => {\n containerRef.current = el;\n if (el) {\n scrollingContainerRef.current = el.closest(\".vuuTable-contentContainer\");\n } else {\n scrollingContainerRef.current = null;\n }\n }, []);\n\n const handleDropColumnHeader = useCallback(\n ({ fromIndex: moveFrom, toIndex: moveTo }: DropOptions) => {\n const column = columns[moveFrom];\n // columns are what get rendered, so these are the columns that\n // the drop operation relates to. We must translate these into\n // columns within the table config. Grouping complicates this\n // as the group columns are not present in columns but ARE in\n // config.columns\n const orderedColumns = moveColumnTo(columns, column, moveTo);\n\n const ofColumn =\n ({ name }: ColumnDescriptor) =>\n (col: ColumnDescriptor) =>\n col.name === name;\n\n const targetIndex = orderedColumns.findIndex(ofColumn(column));\n const nextColumn = orderedColumns[targetIndex + 1];\n const insertPos = nextColumn\n ? tableConfig.columns.findIndex(ofColumn(nextColumn))\n : -1;\n\n if (moveTo > moveFrom && insertPos !== -1) {\n onMoveColumn(moveColumnTo(tableConfig.columns, column, insertPos - 1));\n } else {\n onMoveColumn(moveColumnTo(tableConfig.columns, column, insertPos));\n }\n },\n [columns, onMoveColumn, tableConfig.columns],\n );\n\n const handleColumnHeaderClick = useCallback(\n (evt: React.MouseEvent | React.KeyboardEvent) => {\n const headerCell = queryClosest(evt.target, \".vuuTableHeaderCell\");\n const colIdx = parseInt(headerCell?.dataset.index ?? \"-1\");\n const column = visibleColumnAtIndex(columns, colIdx);\n const isAdditive = evt.shiftKey;\n column && onSortColumn(column, isAdditive);\n },\n [columns, onSortColumn],\n );\n\n // Drag Drop column headers\n const {\n onMouseDown: columnHeaderDragMouseDown,\n draggable: draggableColumn,\n ...dragDropHook\n } = useDragDrop({\n allowDragDrop: allowDragColumnHeader,\n containerRef,\n draggableClassName: `vuuTable`,\n itemQuery: \".vuuTableHeaderCell\",\n onDrop: handleDropColumnHeader,\n orientation: \"horizontal\",\n scrollingContainerRef,\n });\n\n return {\n draggableColumn,\n draggedColumnIndex: dragDropHook.draggedItemIndex,\n onClick: handleColumnHeaderClick,\n onMouseDown: columnHeaderDragMouseDown,\n setContainerRef: useForkRef(setContainerRef, rowRef),\n };\n};\n"],"names":["useRef","useMeasuredHeight","useCallback","moveColumnTo","queryClosest","visibleColumnAtIndex","useDragDrop","useForkRef"],"mappings":"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"}
1
+ {"version":3,"file":"useTableHeader.js","sources":["../../src/table-header/useTableHeader.ts"],"sourcesContent":["import { ColumnDescriptor } from \"@vuu-ui/vuu-table-types\";\nimport {\n DropOptions,\n useDragDrop as useDragDrop,\n} from \"@vuu-ui/vuu-ui-controls\";\nimport {\n moveColumnTo,\n queryClosest,\n visibleColumnAtIndex,\n} from \"@vuu-ui/vuu-utils\";\nimport { RefCallback, useCallback, useRef } from \"react\";\nimport { TableHeaderProps } from \"./TableHeader\";\nimport { useMeasuredHeight } from \"../useMeasuredHeight\";\nimport { useForkRef } from \"@salt-ds/core\";\n\nexport interface TableHeaderHookProps\n extends Pick<\n TableHeaderProps,\n | \"allowDragColumnHeader\"\n | \"columns\"\n | \"onMoveColumn\"\n | \"onSortColumn\"\n | \"tableConfig\"\n > {\n label?: string;\n onHeightMeasured: (height: number) => void;\n onMoveColumn: (columns: ColumnDescriptor[]) => void;\n onSortColumn: (column: ColumnDescriptor, addToExistingSort: boolean) => void;\n}\n\nexport const useTableHeader = ({\n allowDragColumnHeader,\n columns,\n onHeightMeasured,\n onMoveColumn,\n onSortColumn,\n tableConfig,\n}: TableHeaderHookProps) => {\n const containerRef = useRef<HTMLDivElement | null>(null);\n const scrollingContainerRef = useRef<HTMLDivElement | null>(null);\n const { measuredRef: rowRef } = useMeasuredHeight({\n onHeightMeasured,\n });\n\n const setContainerRef = useCallback<RefCallback<HTMLDivElement>>((el) => {\n containerRef.current = el;\n if (el) {\n scrollingContainerRef.current = el.closest(\".vuuTable-contentContainer\");\n } else {\n scrollingContainerRef.current = null;\n }\n }, []);\n\n const handleDropColumnHeader = useCallback(\n ({ fromIndex: moveFrom, toIndex: moveTo }: DropOptions) => {\n const column = columns[moveFrom];\n // columns are what get rendered, so these are the columns that\n // the drop operation relates to. We must translate these into\n // columns within the table config. Grouping complicates this\n // as the group columns are not present in columns but ARE in\n // config.columns\n const orderedColumns = moveColumnTo(columns, column, moveTo);\n\n const ofColumn =\n ({ name }: ColumnDescriptor) =>\n (col: ColumnDescriptor) =>\n col.name === name;\n\n const targetIndex = orderedColumns.findIndex(ofColumn(column));\n const nextColumn = orderedColumns[targetIndex + 1];\n const insertPos = nextColumn\n ? tableConfig.columns.findIndex(ofColumn(nextColumn))\n : -1;\n\n if (moveTo > moveFrom && insertPos !== -1) {\n onMoveColumn(moveColumnTo(tableConfig.columns, column, insertPos - 1));\n } else {\n onMoveColumn(moveColumnTo(tableConfig.columns, column, insertPos));\n }\n },\n [columns, onMoveColumn, tableConfig.columns],\n );\n\n const handleColumnHeaderClick = useCallback(\n (evt: React.MouseEvent | React.KeyboardEvent) => {\n const headerCell = queryClosest(evt.target, \".vuuTableHeaderCell\");\n const colIdx = parseInt(headerCell?.dataset.index ?? \"-1\");\n const column = visibleColumnAtIndex(columns, colIdx);\n const isAdditive = evt.shiftKey;\n column && onSortColumn(column, isAdditive);\n },\n [columns, onSortColumn],\n );\n\n // Drag Drop column headers\n const {\n onMouseDown: columnHeaderDragMouseDown,\n draggable: draggableColumn,\n ...dragDropHook\n } = useDragDrop({\n allowDragDrop: allowDragColumnHeader,\n containerRef,\n draggableClassName: `vuuTable`,\n itemQuery: \".vuuTableHeaderCell\",\n onDrop: handleDropColumnHeader,\n orientation: \"horizontal\",\n scrollingContainerRef,\n });\n\n return {\n draggableColumn,\n draggedColumnIndex: dragDropHook.draggedItemIndex,\n onClick: handleColumnHeaderClick,\n onMouseDown: columnHeaderDragMouseDown,\n setContainerRef: useForkRef(setContainerRef, rowRef),\n };\n};\n"],"names":["useRef","useMeasuredHeight","useCallback","moveColumnTo","queryClosest","visibleColumnAtIndex","useDragDrop","useForkRef"],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ 'use strict';
2
+
3
+ var react = require('react');
4
+ var tableDomUtils = require('./table-dom-utils.js');
5
+ var vuuUtils = require('@vuu-ui/vuu-utils');
6
+
7
+ const useCellFocus = ({
8
+ containerRef,
9
+ disableFocus = false,
10
+ requestScroll
11
+ }) => {
12
+ const focusableCell = react.useRef();
13
+ const focusCell = react.useCallback(
14
+ (cellPos) => {
15
+ if (containerRef.current) {
16
+ const activeCell = tableDomUtils.getTableCell(containerRef, cellPos);
17
+ if (activeCell) {
18
+ if (activeCell !== focusableCell.current) {
19
+ focusableCell.current?.removeAttribute("tabindex");
20
+ focusableCell.current = activeCell;
21
+ activeCell.setAttribute("tabindex", "0");
22
+ }
23
+ requestScroll?.({ type: "scroll-row", rowIndex: cellPos[0] });
24
+ activeCell.focus({ preventScroll: true });
25
+ }
26
+ }
27
+ },
28
+ // TODO we recreate this function whenever viewportRange changes, which will
29
+ // be often whilst scrolling - store range in a a ref ?
30
+ [containerRef, requestScroll]
31
+ );
32
+ const tableBodyRef = react.useCallback(
33
+ (el) => {
34
+ if (el) {
35
+ const table = vuuUtils.queryClosest(el, ".vuuTable");
36
+ if (table) {
37
+ if (focusableCell.current === void 0 && !disableFocus) {
38
+ const cell = table.querySelector(tableDomUtils.headerCellQuery(0)) || table.querySelector(tableDomUtils.dataCellQuery(0, 0));
39
+ if (cell) {
40
+ cell.setAttribute("tabindex", "0");
41
+ focusableCell.current = cell;
42
+ }
43
+ }
44
+ }
45
+ }
46
+ },
47
+ [disableFocus]
48
+ );
49
+ return {
50
+ focusCell,
51
+ tableBodyRef
52
+ };
53
+ };
54
+
55
+ exports.useCellFocus = useCellFocus;
56
+ //# sourceMappingURL=useCellFocus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useCellFocus.js","sources":["../src/useCellFocus.ts"],"sourcesContent":["import { RefCallback, RefObject, useCallback, useRef } from \"react\";\nimport {\n CellPos,\n dataCellQuery,\n getTableCell,\n headerCellQuery,\n} from \"./table-dom-utils\";\nimport { ScrollRequestHandler } from \"./useTableScroll\";\nimport { queryClosest } from \"@vuu-ui/vuu-utils\";\n\nexport interface CellFocusHookProps {\n containerRef: RefObject<HTMLElement>;\n disableFocus?: boolean;\n requestScroll?: ScrollRequestHandler;\n}\n\nexport type FocusCell = (cellPos: CellPos) => void;\n\nexport const useCellFocus = ({\n containerRef,\n disableFocus = false,\n requestScroll,\n}: CellFocusHookProps) => {\n const focusableCell = useRef<HTMLElement>();\n\n const focusCell = useCallback<FocusCell>(\n (cellPos) => {\n if (containerRef.current) {\n const activeCell = getTableCell(containerRef, cellPos);\n if (activeCell) {\n if (activeCell !== focusableCell.current) {\n focusableCell.current?.removeAttribute(\"tabindex\");\n focusableCell.current = activeCell;\n activeCell.setAttribute(\"tabindex\", \"0\");\n }\n // TODO needs to be scroll cell\n requestScroll?.({ type: \"scroll-row\", rowIndex: cellPos[0] });\n activeCell.focus({ preventScroll: true });\n }\n }\n },\n // TODO we recreate this function whenever viewportRange changes, which will\n // be often whilst scrolling - store range in a a ref ?\n [containerRef, requestScroll],\n );\n\n const tableBodyRef = useCallback<RefCallback<HTMLDivElement>>(\n (el) => {\n if (el) {\n const table = queryClosest<HTMLDivElement>(el, \".vuuTable\");\n if (table) {\n if (focusableCell.current === undefined && !disableFocus) {\n const cell =\n table.querySelector<HTMLDivElement>(headerCellQuery(0)) ||\n table.querySelector<HTMLDivElement>(dataCellQuery(0, 0));\n if (cell) {\n cell.setAttribute(\"tabindex\", \"0\");\n focusableCell.current = cell;\n }\n }\n }\n }\n },\n [disableFocus],\n );\n\n return {\n focusCell,\n tableBodyRef,\n };\n};\n"],"names":["useRef","useCallback","getTableCell","queryClosest","headerCellQuery","dataCellQuery"],"mappings":";;;;;;AAkBO,MAAM,eAAe,CAAC;AAAA,EAC3B,YAAA;AAAA,EACA,YAAe,GAAA,KAAA;AAAA,EACf,aAAA;AACF,CAA0B,KAAA;AACxB,EAAA,MAAM,gBAAgBA,YAAoB,EAAA,CAAA;AAE1C,EAAA,MAAM,SAAY,GAAAC,iBAAA;AAAA,IAChB,CAAC,OAAY,KAAA;AACX,MAAA,IAAI,aAAa,OAAS,EAAA;AACxB,QAAM,MAAA,UAAA,GAAaC,0BAAa,CAAA,YAAA,EAAc,OAAO,CAAA,CAAA;AACrD,QAAA,IAAI,UAAY,EAAA;AACd,UAAI,IAAA,UAAA,KAAe,cAAc,OAAS,EAAA;AACxC,YAAc,aAAA,CAAA,OAAA,EAAS,gBAAgB,UAAU,CAAA,CAAA;AACjD,YAAA,aAAA,CAAc,OAAU,GAAA,UAAA,CAAA;AACxB,YAAW,UAAA,CAAA,YAAA,CAAa,YAAY,GAAG,CAAA,CAAA;AAAA,WACzC;AAEA,UAAA,aAAA,GAAgB,EAAE,IAAM,EAAA,YAAA,EAAc,UAAU,OAAQ,CAAA,CAAC,GAAG,CAAA,CAAA;AAC5D,UAAA,UAAA,CAAW,KAAM,CAAA,EAAE,aAAe,EAAA,IAAA,EAAM,CAAA,CAAA;AAAA,SAC1C;AAAA,OACF;AAAA,KACF;AAAA;AAAA;AAAA,IAGA,CAAC,cAAc,aAAa,CAAA;AAAA,GAC9B,CAAA;AAEA,EAAA,MAAM,YAAe,GAAAD,iBAAA;AAAA,IACnB,CAAC,EAAO,KAAA;AACN,MAAA,IAAI,EAAI,EAAA;AACN,QAAM,MAAA,KAAA,GAAQE,qBAA6B,CAAA,EAAA,EAAI,WAAW,CAAA,CAAA;AAC1D,QAAA,IAAI,KAAO,EAAA;AACT,UAAA,IAAI,aAAc,CAAA,OAAA,KAAY,KAAa,CAAA,IAAA,CAAC,YAAc,EAAA;AACxD,YAAA,MAAM,IACJ,GAAA,KAAA,CAAM,aAA8B,CAAAC,6BAAA,CAAgB,CAAC,CAAC,CACtD,IAAA,KAAA,CAAM,aAA8B,CAAAC,2BAAA,CAAc,CAAG,EAAA,CAAC,CAAC,CAAA,CAAA;AACzD,YAAA,IAAI,IAAM,EAAA;AACR,cAAK,IAAA,CAAA,YAAA,CAAa,YAAY,GAAG,CAAA,CAAA;AACjC,cAAA,aAAA,CAAc,OAAU,GAAA,IAAA,CAAA;AAAA,aAC1B;AAAA,WACF;AAAA,SACF;AAAA,OACF;AAAA,KACF;AAAA,IACA,CAAC,YAAY,CAAA;AAAA,GACf,CAAA;AAEA,EAAO,OAAA;AAAA,IACL,SAAA;AAAA,IACA,YAAA;AAAA,GACF,CAAA;AACF;;;;"}
@@ -28,43 +28,12 @@ const isNavigationKey = (key, navigationStyle) => {
28
28
  };
29
29
  const PageKeys = ["Home", "End", "PageUp", "PageDown"];
30
30
  const isPagingKey = (key) => PageKeys.includes(key);
31
- const NULL_CELL_POS = [-1, -1];
32
- function nextCellPos(key, [rowIdx, colIdx], columnCount, rowCount) {
33
- if (key === "ArrowUp") {
34
- if (rowIdx > -1) {
35
- return [rowIdx - 1, colIdx];
36
- } else {
37
- return [rowIdx, colIdx];
38
- }
39
- } else if (key === "ArrowDown") {
40
- if (rowIdx === -1) {
41
- return [0, colIdx];
42
- } else if (rowIdx === rowCount - 1) {
43
- return [rowIdx, colIdx];
44
- } else {
45
- return [rowIdx + 1, colIdx];
46
- }
47
- } else if (key === "ArrowRight") {
48
- if (colIdx < columnCount) {
49
- return [rowIdx, colIdx + 1];
50
- } else {
51
- return [rowIdx, colIdx];
52
- }
53
- } else if (key === "ArrowLeft") {
54
- if (colIdx > 1) {
55
- return [rowIdx, colIdx - 1];
56
- } else {
57
- return [rowIdx, colIdx];
58
- }
59
- }
60
- return [rowIdx, colIdx];
61
- }
62
31
  const useKeyboardNavigation = ({
63
32
  columnCount = 0,
64
33
  containerRef,
65
- disableFocus = false,
66
34
  defaultHighlightedIndex,
67
35
  disableHighlightOnFocus,
36
+ focusCell,
68
37
  highlightedIndex: highlightedIndexProp,
69
38
  navigationStyle,
70
39
  requestScroll,
@@ -73,7 +42,6 @@ const useKeyboardNavigation = ({
73
42
  viewportRowCount
74
43
  }) => {
75
44
  const focusedCellPos = react.useRef([-1, -1]);
76
- const focusableCell = react.useRef();
77
45
  const activeCellPos = react.useRef([-1, 0]);
78
46
  const highlightedIndexRef = react.useRef();
79
47
  const [highlightedIndex, setHighlightedIdx] = core.useControlled({
@@ -92,39 +60,6 @@ const useKeyboardNavigation = ({
92
60
  const getFocusedCell = (element) => element?.closest(
93
61
  "[role='columnHeader'],[role='cell']"
94
62
  );
95
- const getTableCellPos = (tableCell) => {
96
- if (tableCell.role === "columnHeader") {
97
- const colIdx = parseInt(tableCell.dataset.idx ?? "-1", 10);
98
- return [-1, colIdx];
99
- } else {
100
- const focusedRow = tableCell.closest("[role='row']");
101
- if (focusedRow) {
102
- const rowIdx = vuuUtils.getIndexFromRowElement(focusedRow);
103
- const colIdx = Array.from(focusedRow.childNodes).indexOf(tableCell);
104
- return [rowIdx, colIdx];
105
- }
106
- }
107
- return NULL_CELL_POS;
108
- };
109
- const focusCell = react.useCallback(
110
- (cellPos) => {
111
- if (containerRef.current) {
112
- const activeCell = tableDomUtils.getTableCell(containerRef, cellPos);
113
- if (activeCell) {
114
- if (activeCell !== focusableCell.current) {
115
- focusableCell.current?.removeAttribute("tabindex");
116
- focusableCell.current = activeCell;
117
- activeCell.setAttribute("tabindex", "0");
118
- }
119
- requestScroll?.({ type: "scroll-row", rowIndex: cellPos[0] });
120
- activeCell.focus({ preventScroll: true });
121
- }
122
- }
123
- },
124
- // TODO we recreate this function whenever viewportRange changes, which will
125
- // be often whilst scrolling - store range in a a ref ?
126
- [containerRef, requestScroll]
127
- );
128
63
  const setActiveCell = react.useCallback(
129
64
  (rowIdx, colIdx, fromKeyboard = false) => {
130
65
  const pos = [rowIdx, colIdx];
@@ -184,7 +119,7 @@ const useKeyboardNavigation = ({
184
119
  if (containerRef.current?.contains(document.activeElement)) {
185
120
  const focusedCell = getFocusedCell(document.activeElement);
186
121
  if (focusedCell) {
187
- focusedCellPos.current = getTableCellPos(focusedCell);
122
+ focusedCellPos.current = tableDomUtils.getTableCellPos(focusedCell);
188
123
  if (navigationStyle === "row") {
189
124
  setHighlightedIdx(focusedCellPos.current[0]);
190
125
  }
@@ -199,7 +134,7 @@ const useKeyboardNavigation = ({
199
134
  ]);
200
135
  const navigateChildItems = react.useCallback(
201
136
  async (key) => {
202
- const [nextRowIdx, nextColIdx] = isPagingKey(key) ? await nextPageItemIdx(key, activeCellPos.current) : nextCellPos(key, activeCellPos.current, columnCount, rowCount);
137
+ const [nextRowIdx, nextColIdx] = isPagingKey(key) ? await nextPageItemIdx(key, activeCellPos.current) : tableDomUtils.getNextCellPos(key, activeCellPos.current, columnCount, rowCount);
203
138
  const [rowIdx, colIdx] = activeCellPos.current;
204
139
  if (nextRowIdx !== rowIdx || nextColIdx !== colIdx) {
205
140
  setActiveCell(nextRowIdx, nextColIdx, true);
@@ -216,7 +151,7 @@ const useKeyboardNavigation = ({
216
151
  const moveHighlightedRow = react.useCallback(
217
152
  async (key) => {
218
153
  const { current: highlighted } = highlightedIndexRef;
219
- const [nextRowIdx] = isPagingKey(key) ? await nextPageItemIdx(key, [highlighted ?? -1, 0]) : nextCellPos(key, [highlighted ?? -1, 0], columnCount, rowCount);
154
+ const [nextRowIdx] = isPagingKey(key) ? await nextPageItemIdx(key, [highlighted ?? -1, 0]) : tableDomUtils.getNextCellPos(key, [highlighted ?? -1, 0], columnCount, rowCount);
220
155
  if (nextRowIdx !== highlighted) {
221
156
  setHighlightedIndex(nextRowIdx);
222
157
  scrollRowIntoViewIfNecessary(nextRowIdx);
@@ -261,7 +196,7 @@ const useKeyboardNavigation = ({
261
196
  const target = evt.target;
262
197
  const focusedCell = getFocusedCell(target);
263
198
  if (focusedCell) {
264
- const [rowIdx, colIdx] = getTableCellPos(focusedCell);
199
+ const [rowIdx, colIdx] = tableDomUtils.getTableCellPos(focusedCell);
265
200
  setActiveCell(rowIdx, colIdx);
266
201
  }
267
202
  },
@@ -282,17 +217,6 @@ const useKeyboardNavigation = ({
282
217
  const navigate = react.useCallback(() => {
283
218
  navigateChildItems("ArrowDown");
284
219
  }, [navigateChildItems]);
285
- const fullyRendered = containerRef.current?.firstChild != null;
286
- react.useEffect(() => {
287
- if (fullyRendered && focusableCell.current === void 0 && !disableFocus) {
288
- const { current: container } = containerRef;
289
- const cell = container?.querySelector(tableDomUtils.headerCellQuery(0)) || container?.querySelector(tableDomUtils.dataCellQuery(0, 0));
290
- if (cell) {
291
- cell.setAttribute("tabindex", "0");
292
- focusableCell.current = cell;
293
- }
294
- }
295
- }, [containerRef, disableFocus, fullyRendered]);
296
220
  return {
297
221
  highlightedIndexRef,
298
222
  navigate,
@@ -1 +1 @@
1
- {"version":3,"file":"useKeyboardNavigation.js","sources":["../src/useKeyboardNavigation.ts"],"sourcesContent":["import { VuuRange } from \"@vuu-ui/vuu-protocol-types\";\nimport { getIndexFromRowElement, queryClosest } from \"@vuu-ui/vuu-utils\";\nimport { useControlled } from \"@salt-ds/core\";\nimport {\n KeyboardEvent,\n MouseEvent,\n RefObject,\n useCallback,\n useEffect,\n useRef,\n} from \"react\";\nimport { TableNavigationStyle } from \"./Table\";\nimport {\n CellPos,\n cellDropdownShowing,\n closestRowIndex,\n dataCellQuery,\n getTableCell,\n headerCellQuery,\n} from \"./table-dom-utils\";\nimport { ScrollRequestHandler } from \"./useTableScroll\";\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\ntype ArrowKey = \"ArrowUp\" | \"ArrowDown\" | \"ArrowLeft\" | \"ArrowRight\";\ntype PageKey = \"Home\" | \"End\" | \"PageUp\" | \"PageDown\";\ntype NavigationKey = PageKey | ArrowKey;\n\nconst PageKeys = [\"Home\", \"End\", \"PageUp\", \"PageDown\"];\nexport const isPagingKey = (key: string): key is PageKey =>\n PageKeys.includes(key);\n\nconst NULL_CELL_POS: CellPos = [-1, -1];\n\nfunction nextCellPos(\n key: ArrowKey,\n [rowIdx, colIdx]: CellPos,\n columnCount: number,\n rowCount: number,\n): CellPos {\n if (key === \"ArrowUp\") {\n if (rowIdx > -1) {\n return [rowIdx - 1, colIdx];\n } else {\n return [rowIdx, colIdx];\n }\n } else if (key === \"ArrowDown\") {\n if (rowIdx === -1) {\n return [0, colIdx];\n } else if (rowIdx === rowCount - 1) {\n return [rowIdx, colIdx];\n } else {\n return [rowIdx + 1, colIdx];\n }\n } else if (key === \"ArrowRight\") {\n // The colIdx is 1 based, because of the selection decorator\n if (colIdx < columnCount) {\n return [rowIdx, colIdx + 1];\n } else {\n return [rowIdx, colIdx];\n }\n } else if (key === \"ArrowLeft\") {\n if (colIdx > 1) {\n return [rowIdx, colIdx - 1];\n } else {\n return [rowIdx, colIdx];\n }\n }\n return [rowIdx, colIdx];\n}\n\nexport interface NavigationHookProps {\n containerRef: RefObject<HTMLElement>;\n columnCount?: number;\n defaultHighlightedIndex?: number;\n disableFocus?: boolean;\n disableHighlightOnFocus?: boolean;\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 columnCount = 0,\n containerRef,\n disableFocus = false,\n defaultHighlightedIndex,\n disableHighlightOnFocus,\n highlightedIndex: highlightedIndexProp,\n navigationStyle,\n requestScroll,\n onHighlight,\n rowCount = 0,\n viewportRowCount,\n}: // viewportRange,\nNavigationHookProps) => {\n // const { from: viewportFirstRow, to: viewportLastRow } = viewportRange;\n const focusedCellPos = useRef<CellPos>([-1, -1]);\n const focusableCell = useRef<HTMLElement>();\n const activeCellPos = useRef<CellPos>([-1, 0]);\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, fromKeyboard = false) => {\n onHighlight?.(idx);\n setHighlightedIdx(idx);\n if (fromKeyboard) {\n // lastFocus.current = idx;\n }\n },\n [onHighlight, setHighlightedIdx],\n );\n\n const getFocusedCell = (element: HTMLElement | Element | null) =>\n element?.closest(\n \"[role='columnHeader'],[role='cell']\",\n ) as HTMLDivElement | null;\n\n const getTableCellPos = (tableCell: HTMLDivElement): CellPos => {\n if (tableCell.role === \"columnHeader\") {\n const colIdx = parseInt(tableCell.dataset.idx ?? \"-1\", 10);\n return [-1, colIdx];\n } else {\n const focusedRow = tableCell.closest(\"[role='row']\") as HTMLElement;\n if (focusedRow) {\n const rowIdx = getIndexFromRowElement(focusedRow);\n // TODO will get trickier when we introduce horizontal virtualisation\n const colIdx = Array.from(focusedRow.childNodes).indexOf(tableCell);\n return [rowIdx, colIdx];\n }\n }\n return NULL_CELL_POS;\n };\n\n const focusCell = useCallback(\n (cellPos: CellPos) => {\n if (containerRef.current) {\n const activeCell = getTableCell(containerRef, cellPos);\n if (activeCell) {\n if (activeCell !== focusableCell.current) {\n focusableCell.current?.removeAttribute(\"tabindex\");\n focusableCell.current = activeCell;\n activeCell.setAttribute(\"tabindex\", \"0\");\n }\n // TODO needs to be scroll cell\n requestScroll?.({ type: \"scroll-row\", rowIndex: cellPos[0] });\n activeCell.focus({ preventScroll: true });\n }\n }\n },\n // TODO we recreate this function whenever viewportRange changes, which will\n // be often whilst scrolling - store range in a a ref ?\n [containerRef, requestScroll],\n );\n\n const setActiveCell = useCallback(\n (rowIdx: number, colIdx: number, fromKeyboard = false) => {\n const pos: CellPos = [rowIdx, colIdx];\n activeCellPos.current = pos;\n if (navigationStyle === \"row\") {\n setHighlightedIdx(rowIdx);\n } else {\n focusCell(pos);\n }\n if (fromKeyboard) {\n focusedCellPos.current = pos;\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 switch (key) {\n case \"PageDown\": {\n newRowIdx = Math.min(rowCount - 1, rowIdx + viewportRowCount);\n if (newRowIdx !== rowIdx) {\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 requestScroll?.({ type: \"scroll-page\", direction: \"up\" });\n }\n break;\n }\n case \"Home\": {\n newRowIdx = 0;\n if (newRowIdx !== rowIdx) {\n requestScroll?.({ type: \"scroll-end\", direction: \"home\" });\n }\n break;\n }\n case \"End\": {\n newRowIdx = rowCount - 1;\n if (newRowIdx !== rowIdx) {\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 [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 focusedCellPos.current = getTableCellPos(focusedCell);\n if (navigationStyle === \"row\") {\n setHighlightedIdx(focusedCellPos.current[0]);\n }\n }\n }\n }\n }, [\n disableHighlightOnFocus,\n containerRef,\n navigationStyle,\n setHighlightedIdx,\n ]);\n\n const navigateChildItems = useCallback(\n async (key: NavigationKey) => {\n const [nextRowIdx, nextColIdx] = isPagingKey(key)\n ? await nextPageItemIdx(key, activeCellPos.current)\n : nextCellPos(key, activeCellPos.current, columnCount, rowCount);\n const [rowIdx, colIdx] = activeCellPos.current;\n if (nextRowIdx !== rowIdx || nextColIdx !== colIdx) {\n setActiveCell(nextRowIdx, nextColIdx, true);\n }\n },\n [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 : nextCellPos(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>(e.target, \".vuuTableCell\");\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 void navigateChildItems(e.key);\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 = 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 // First render will only render the outer container when explicit\n // sizing has not been provided. Outer container is measured and\n // only then, on second render, is content rendered.\n const fullyRendered = containerRef.current?.firstChild != null;\n useEffect(() => {\n if (fullyRendered && focusableCell.current === undefined && !disableFocus) {\n const { current: container } = containerRef;\n const cell = (container?.querySelector(headerCellQuery(0)) ||\n container?.querySelector(dataCellQuery(0, 0))) as HTMLElement;\n if (cell) {\n cell.setAttribute(\"tabindex\", \"0\");\n focusableCell.current = cell;\n }\n }\n }, [containerRef, disableFocus, fullyRendered]);\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","getIndexFromRowElement","getTableCell","useEffect","queryClosest","cellDropdownShowing","closestRowIndex","headerCellQuery","dataCellQuery"],"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 RefObject,\n useCallback,\n useEffect,\n useRef,\n} from \"react\";\nimport { TableNavigationStyle } from \"./Table\";\nimport {\n CellPos,\n NavigationKey,\n cellDropdownShowing,\n closestRowIndex,\n getTableCellPos,\n getNextCellPos,\n} from \"./table-dom-utils\";\nimport { ScrollRequestHandler } from \"./useTableScroll\";\nimport { FocusCell } from \"./useCellFocus\";\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 PageKeys = [\"Home\", \"End\", \"PageUp\", \"PageDown\"];\nexport const isPagingKey = (key: string): key is PageKey =>\n PageKeys.includes(key);\n\nexport interface NavigationHookProps {\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 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 const focusedCellPos = useRef<CellPos>([-1, -1]);\n const activeCellPos = useRef<CellPos>([-1, 0]);\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, fromKeyboard = false) => {\n onHighlight?.(idx);\n setHighlightedIdx(idx);\n if (fromKeyboard) {\n // lastFocus.current = idx;\n }\n },\n [onHighlight, setHighlightedIdx],\n );\n\n const getFocusedCell = (element: HTMLElement | Element | null) =>\n element?.closest(\n \"[role='columnHeader'],[role='cell']\",\n ) as HTMLDivElement | null;\n\n const setActiveCell = useCallback(\n (rowIdx: number, colIdx: number, fromKeyboard = false) => {\n const pos: CellPos = [rowIdx, colIdx];\n activeCellPos.current = pos;\n if (navigationStyle === \"row\") {\n setHighlightedIdx(rowIdx);\n } else {\n focusCell(pos);\n }\n if (fromKeyboard) {\n focusedCellPos.current = pos;\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 switch (key) {\n case \"PageDown\": {\n newRowIdx = Math.min(rowCount - 1, rowIdx + viewportRowCount);\n if (newRowIdx !== rowIdx) {\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 requestScroll?.({ type: \"scroll-page\", direction: \"up\" });\n }\n break;\n }\n case \"Home\": {\n newRowIdx = 0;\n if (newRowIdx !== rowIdx) {\n requestScroll?.({ type: \"scroll-end\", direction: \"home\" });\n }\n break;\n }\n case \"End\": {\n newRowIdx = rowCount - 1;\n if (newRowIdx !== rowIdx) {\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 [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 focusedCellPos.current = getTableCellPos(focusedCell);\n if (navigationStyle === \"row\") {\n setHighlightedIdx(focusedCellPos.current[0]);\n }\n }\n }\n }\n }, [\n disableHighlightOnFocus,\n containerRef,\n navigationStyle,\n setHighlightedIdx,\n ]);\n\n const navigateChildItems = useCallback(\n async (key: NavigationKey) => {\n const [nextRowIdx, nextColIdx] = isPagingKey(key)\n ? await nextPageItemIdx(key, activeCellPos.current)\n : getNextCellPos(key, activeCellPos.current, columnCount, rowCount);\n const [rowIdx, colIdx] = activeCellPos.current;\n if (nextRowIdx !== rowIdx || nextColIdx !== colIdx) {\n setActiveCell(nextRowIdx, nextColIdx, true);\n }\n },\n [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>(e.target, \".vuuTableCell\");\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 void navigateChildItems(e.key);\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 = 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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"}
@@ -7,26 +7,26 @@ const useMeasuredHeight = ({
7
7
  onHeightMeasured,
8
8
  height: heightProp = 0
9
9
  }) => {
10
- const [rowHeight, setRowHeight] = react.useState(heightProp);
10
+ const [measuredHeight, setMeasuredHeight] = react.useState(heightProp);
11
11
  const resizeObserver = react.useMemo(() => {
12
12
  return new ResizeObserver((entries) => {
13
13
  for (const entry of entries) {
14
14
  const [{ blockSize: measuredSize }] = entry.borderBoxSize;
15
15
  const newHeight = Math.round(measuredSize);
16
16
  if (vuuUtils.isValidNumber(newHeight)) {
17
- setRowHeight(newHeight);
17
+ setMeasuredHeight(newHeight);
18
18
  onHeightMeasured?.(newHeight);
19
19
  }
20
20
  }
21
21
  });
22
22
  }, [onHeightMeasured]);
23
- const rowRef = react.useCallback(
23
+ const measuredRef = react.useCallback(
24
24
  (el) => {
25
25
  if (el) {
26
26
  if (heightProp === 0) {
27
27
  const { height } = el.getBoundingClientRect();
28
28
  resizeObserver.observe(el);
29
- setRowHeight(height);
29
+ setMeasuredHeight(Math.round(height));
30
30
  }
31
31
  } else {
32
32
  resizeObserver.disconnect();
@@ -34,7 +34,7 @@ const useMeasuredHeight = ({
34
34
  },
35
35
  [resizeObserver, heightProp]
36
36
  );
37
- return { rowHeight, rowRef };
37
+ return { measuredHeight, measuredRef };
38
38
  };
39
39
 
40
40
  exports.useMeasuredHeight = useMeasuredHeight;