UNPKG

@deepdub/react-arborist

Version:
239 lines (238 loc) 9.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DefaultContainer = void 0; const jsx_runtime_1 = require("react/jsx-runtime"); const react_window_1 = require("react-window"); const context_1 = require("../context"); const utils_1 = require("../utils"); const list_outer_element_1 = require("./list-outer-element"); const list_inner_element_1 = require("./list-inner-element"); const row_container_1 = require("./row-container"); let focusSearchTerm = ""; let timeoutId = null; /** * All these keyboard shortcuts seem like they should be configurable. * Each operation should be a given a name and separated from * the event handler. Future clean up welcome. */ function DefaultContainer() { (0, context_1.useDataUpdates)(); const tree = (0, context_1.useTreeApi)(); return ((0, jsx_runtime_1.jsx)("div", { role: "tree", style: { height: tree.height, width: tree.width, minHeight: 0, minWidth: 0, }, onContextMenu: tree.props.onContextMenu, onClick: tree.props.onClick, tabIndex: 0, onFocus: (e) => { if (!e.currentTarget.contains(e.relatedTarget)) { tree.onFocus(); } }, onBlur: (e) => { if (!e.currentTarget.contains(e.relatedTarget)) { tree.onBlur(); } }, onKeyDown: (e) => { var _a; if (tree.isEditing) { return; } if (e.key === "Backspace") { if (!tree.props.onDelete) return; const ids = Array.from(tree.selectedIds); if (ids.length > 1) { let nextFocus = tree.mostRecentNode; while (nextFocus && nextFocus.isSelected) { nextFocus = nextFocus.nextSibling; } if (!nextFocus) nextFocus = tree.lastNode; tree.focus(nextFocus, { scroll: false }); tree.delete(Array.from(ids)); } else { const node = tree.focusedNode; if (node) { const sib = node.nextSibling; const parent = node.parent; tree.focus(sib || parent, { scroll: false }); tree.delete(node); } } return; } if (e.key === "Tab" && !e.shiftKey) { e.preventDefault(); (0, utils_1.focusNextElement)(e.currentTarget); return; } if (e.key === "Tab" && e.shiftKey) { e.preventDefault(); (0, utils_1.focusPrevElement)(e.currentTarget); return; } if (e.key === "ArrowDown") { e.preventDefault(); const next = tree.nextNode; if (e.metaKey) { tree.select(tree.focusedNode); tree.activate(tree.focusedNode); return; } else if (!e.shiftKey || tree.props.disableMultiSelection) { tree.focus(next); return; } else { if (!next) return; const current = tree.focusedNode; if (!current) { tree.focus(tree.firstNode); } else if (current.isSelected) { tree.selectContiguous(next); } else { tree.selectMulti(next); } return; } } if (e.key === "ArrowUp") { e.preventDefault(); const prev = tree.prevNode; if (!e.shiftKey || tree.props.disableMultiSelection) { tree.focus(prev); return; } else { if (!prev) return; const current = tree.focusedNode; if (!current) { tree.focus(tree.lastNode); // ? } else if (current.isSelected) { tree.selectContiguous(prev); } else { tree.selectMulti(prev); } return; } } if (e.key === "ArrowRight") { const node = tree.focusedNode; if (!node) return; if (node.isInternal && node.isOpen) { tree.focus(tree.nextNode); } else if (node.isInternal) tree.open(node.id); return; } if (e.key === "ArrowLeft") { const node = tree.focusedNode; if (!node || node.isRoot) return; if (node.isInternal && node.isOpen) tree.close(node.id); else if (!((_a = node.parent) === null || _a === void 0 ? void 0 : _a.isRoot)) { tree.focus(node.parent); } return; } if (e.key === "a" && e.metaKey && !tree.props.disableMultiSelection) { e.preventDefault(); tree.selectAll(); return; } if (e.key === "a" && !e.metaKey && tree.props.onCreate) { tree.createLeaf(); return; } if (e.key === "A" && !e.metaKey) { if (!tree.props.onCreate) return; tree.createInternal(); return; } if (e.key === "Home") { // add shift keys e.preventDefault(); tree.focus(tree.firstNode); return; } if (e.key === "End") { // add shift keys e.preventDefault(); tree.focus(tree.lastNode); return; } if (e.key === "Enter") { const node = tree.focusedNode; if (!node) return; if (!node.isEditable || !tree.props.onRename) return; setTimeout(() => { if (node) tree.edit(node); }); return; } if (e.key === " ") { e.preventDefault(); const node = tree.focusedNode; if (!node) return; if (node.isLeaf) { node.select(); node.activate(); } else { node.toggle(); } return; } if (e.key === "*") { const node = tree.focusedNode; if (!node) return; tree.openSiblings(node); return; } if (e.key === "PageUp") { e.preventDefault(); tree.pageUp(); return; } if (e.key === "PageDown") { e.preventDefault(); tree.pageDown(); } // If they type a sequence of characters // collect them. Reset them after a timeout. // Use it to search the tree for a node, then focus it. // Clean this up a bit later clearTimeout(timeoutId); focusSearchTerm += e.key; timeoutId = setTimeout(() => { focusSearchTerm = ""; }, 600); const node = tree.visibleNodes.find((n) => { // @ts-ignore const name = n.data.name; if (typeof name === "string") { return name.toLowerCase().startsWith(focusSearchTerm); } else return false; }); if (node) tree.focus(node.id); }, children: (0, jsx_runtime_1.jsx)(react_window_1.FixedSizeList, { className: tree.props.className, outerRef: tree.listEl, itemCount: tree.visibleNodes.length, height: tree.height, width: tree.width, itemSize: tree.rowHeight, overscanCount: tree.overscanCount, itemKey: (index) => { var _a; return ((_a = tree.visibleNodes[index]) === null || _a === void 0 ? void 0 : _a.id) || index; }, outerElementType: list_outer_element_1.ListOuterElement, innerElementType: list_inner_element_1.ListInnerElement, onScroll: tree.props.onScroll, onItemsRendered: tree.onItemsRendered.bind(tree), ref: tree.list, children: row_container_1.RowContainer }) })); } exports.DefaultContainer = DefaultContainer;