@deepdub/react-arborist
Version:
239 lines (238 loc) • 9.2 kB
JavaScript
"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;