UNPKG

@trail-ui/react

Version:
246 lines (243 loc) 10.1 kB
import { useTableContext } from "./chunk-A4IWBDSQ.mjs"; // src/editable-table/focus-handler/focus-handler-provider.tsx import { createContext, useCallback, useContext, useEffect, useMemo, useState } from "react"; import { jsx } from "react/jsx-runtime"; var FocusDataContext = createContext({ columnIndex: 0, rowId: null, cellType: "headerCell" /* headerCell */, groupId: null, rowIndex: 0 }); var FocusDispatchContext = createContext(() => { }); function FocusHandlerContextProvider(props) { const [focusedCell, setFocusedCell] = useState({ columnIndex: 0, rowId: null, cellType: "headerCell" /* headerCell */, groupId: null, rowIndex: 0 }); const { tableRef, allowBulkGroupSelection, hasFooter } = useTableContext(); function updateData(data) { setFocusedCell(data); } useEffect(() => { const handleKeyDown = (e) => { var _a, _b, _c, _d, _e, _f; if (!tableRef.current || !tableRef.current.contains(e.target)) { return; } const activeElement = document.activeElement; const isInsideCustomSelect = (el) => { return el && (el.closest('[role="listbox"]') || el.closest('[role="combobox"]')); }; if ((activeElement == null ? void 0 : activeElement.tagName) === "SELECT" || (activeElement == null ? void 0 : activeElement.tagName) === "INPUT" || isInsideCustomSelect(activeElement)) { return; } const { rowId, columnIndex, cellType, groupId, rowIndex } = focusedCell; const rows = props.table.getRowModel().rows; const tableHeaders = ((_a = props.table.getHeaderGroups()[0]) == null ? void 0 : _a.headers) || []; if (["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"].includes(e.key)) { e.preventDefault(); let newrowId = rowId; let newColumnIndex = columnIndex; let newCellType = cellType; let newGroupId = groupId; let newRowIndex = rowIndex; const isGroupView = props.groupData.length > 0; switch (e.key) { case "ArrowUp": if (cellType === "headerCell" /* headerCell */) { return; } if (hasFooter && cellType === "footerCell" /* footerCell */) { newCellType = "dataCell" /* dataCell */; newGroupId = null; newRowIndex = rows.length - 1; newrowId = rows[rows.length - 1].id; } else if (cellType === "groupHeaderCell" /* groupHeaderCell */) { const index = rows.findIndex( ({ original }) => original.editableTableGroupId === groupId ); if (index === 0) { newCellType = "headerCell" /* headerCell */; newrowId = null; newGroupId = null; newRowIndex = -1; } else { newCellType = "dataCell" /* dataCell */; newrowId = rows[index - 1].id; newGroupId = null; newRowIndex = index - 1; } } else if (cellType === "dataCell" /* dataCell */) { const index = rows.findIndex((row) => row.id === rowId); if (isGroupView) { if (index === 0 || rows[index].original.editableTableGroupId !== ((_c = (_b = rows[index - 1]) == null ? void 0 : _b.original) == null ? void 0 : _c.editableTableGroupId)) { newGroupId = rows[index].original.editableTableGroupId; newrowId = null; newCellType = "groupHeaderCell" /* groupHeaderCell */; newRowIndex = -1; } else { newrowId = rows[Math.min(rows.length - 1, index - 1)].id; newRowIndex = Math.min(rows.length - 1, index - 1); } } else { if (index === 0) { newCellType = "headerCell" /* headerCell */; newGroupId = null; newrowId = null; newRowIndex = -1; } else { newCellType = "dataCell" /* dataCell */; newGroupId = null; newrowId = rows[Math.max(0, index - 1)].id; newRowIndex = index - 1; } } } break; case "ArrowDown": if (cellType === "headerCell" /* headerCell */) { if (isGroupView) { newCellType = "groupHeaderCell" /* groupHeaderCell */; newGroupId = rows[0].original.editableTableGroupId; newrowId = null; newRowIndex = -1; } else { newGroupId = null; newCellType = "dataCell" /* dataCell */; newrowId = rows[Math.min(rows.length - 1, 0)].id; newRowIndex = Math.min(rows.length - 1, 0); } } else if (cellType === "groupHeaderCell" /* groupHeaderCell */) { newCellType = "dataCell" /* dataCell */; const index = rows.findIndex( ({ original }) => original.editableTableGroupId === groupId ); newrowId = rows[index].id; newGroupId = null; newRowIndex = index; } else if (cellType === "dataCell" /* dataCell */) { const index = rows.findIndex((row) => row.id === rowId); if (hasFooter && index + 1 > rows.length - 1) { newCellType = "footerCell" /* footerCell */; newRowIndex = -1; newGroupId = null; newrowId = null; break; } if (isGroupView && rows[index].original.editableTableGroupId !== ((_e = (_d = rows[index + 1]) == null ? void 0 : _d.original) == null ? void 0 : _e.editableTableGroupId)) { newGroupId = rows[index + 1].original.editableTableGroupId; newrowId = null; newCellType = "groupHeaderCell" /* groupHeaderCell */; newRowIndex = -1; } else { newrowId = rows[Math.min(rows.length - 1, index + 1)].id; newRowIndex = Math.min(rows.length - 1, index + 1); } } else if (hasFooter && cellType === "footerCell" /* footerCell */) { return; } break; case "ArrowLeft": { if (cellType === "groupHeaderCell" /* groupHeaderCell */) { if (allowBulkGroupSelection && columnIndex > 0) { newColumnIndex = 0; } } else { newColumnIndex = Math.max(0, newColumnIndex - 1); } break; } case "ArrowRight": { if (cellType === "groupHeaderCell" /* groupHeaderCell */) { if (allowBulkGroupSelection && columnIndex === 0) { newColumnIndex = 1; } } else { newColumnIndex = Math.min(tableHeaders.length - 1, newColumnIndex + 1); } break; } } setFocusedCell({ rowId: newrowId, columnIndex: newColumnIndex, cellType: newCellType, groupId: newGroupId, rowIndex: newRowIndex }); } if (e.key === "Enter" && cellType === "headerCell" /* headerCell */) { const header = (_f = tableHeaders[columnIndex]) == null ? void 0 : _f.column; if (header == null ? void 0 : header.getCanSort()) { header.toggleSorting(); } } }; const table = tableRef.current; table == null ? void 0 : table.addEventListener("keydown", handleKeyDown); return () => table == null ? void 0 : table.removeEventListener("keydown", handleKeyDown); }, [focusedCell, props.table]); return /* @__PURE__ */ jsx(FocusDispatchContext.Provider, { value: updateData, children: /* @__PURE__ */ jsx(FocusDataContext.Provider, { value: focusedCell, children: props.children }) }); } function useFocusHandler({ cellType, columnIndex, groupId, rowId, rowIndex }) { var _a; const focusedCell = useContext(FocusDataContext); const setFocusedCell = useContext(FocusDispatchContext); const { allowBulkGroupSelection, tableRef, table, serverPagination } = useTableContext(); const filteredRows = (_a = table == null ? void 0 : table.getRowModel().rows) != null ? _a : []; const localRowIndex = filteredRows.findIndex((row) => row.id === rowId); const isCurrentCellFocused = useMemo(() => { var _a2; const isFocused = ((_a2 = tableRef.current) == null ? void 0 : _a2.contains(document.activeElement)) && focusedCell.cellType === cellType; switch (cellType) { case "headerCell" /* headerCell */: case "footerCell" /* footerCell */: return isFocused && focusedCell.columnIndex === columnIndex; case "groupHeaderCell" /* groupHeaderCell */: { let isGroup = focusedCell.groupId === groupId; if (allowBulkGroupSelection) { isGroup && (isGroup = columnIndex === 0 ? focusedCell.columnIndex === 0 : focusedCell.columnIndex > 0); } return isFocused && isGroup; } case "dataCell" /* dataCell */: return isFocused && focusedCell.rowIndex === localRowIndex && focusedCell.columnIndex === columnIndex; default: return false; } }, [focusedCell, columnIndex, cellType, groupId, localRowIndex, allowBulkGroupSelection]); const focusCurrentCell = useCallback(() => { setFocusedCell == null ? void 0 : setFocusedCell({ columnIndex, rowId, cellType, groupId, rowIndex }); }, [columnIndex, rowId, cellType, groupId, rowIndex]); const resetFocus = useCallback(() => { setFocusedCell == null ? void 0 : setFocusedCell({ cellType: "headerCell" /* headerCell */, rowId: null, groupId: null, rowIndex: -1, columnIndex: 0 }); }, []); return { isCurrentCellFocused, focusCurrentCell, resetFocus }; } export { FocusHandlerContextProvider, useFocusHandler };