@mantine/core
Version:
React components library focused on usability, accessibility and developer experience
179 lines (178 loc) • 6.63 kB
JavaScript
"use client";
require("../../_virtual/_rolldown/runtime.cjs");
const require_find_element_ancestor = require("../../core/utils/find-element-ancestor/find-element-ancestor.cjs");
const require_Box = require("../../core/Box/Box.cjs");
const require_Loader = require("../Loader/Loader.cjs");
const require_use_tree_node_drag_drop = require("./use-tree-node-drag-drop.cjs");
let react = require("react");
let react_jsx_runtime = require("react/jsx-runtime");
//#region packages/@mantine/core/src/components/Tree/TreeNode.tsx
function getValuesRange(anchor, value, flatValues) {
if (!anchor || !value) return [];
const anchorIndex = flatValues.indexOf(anchor);
const valueIndex = flatValues.indexOf(value);
const start = Math.min(anchorIndex, valueIndex);
const end = Math.max(anchorIndex, valueIndex);
return flatValues.slice(start, end + 1);
}
function TreeNode({ node, getStyles, rootIndex, controller, expandOnClick, selectOnClick, isSubtree, level = 1, renderNode, flatValues, allowRangeSelection, expandOnSpace, checkOnSpace, keepMounted, onDragDrop, allowDrop, withDragHandle, dragStateRef, data }) {
const ref = (0, react.useRef)(null);
const hasLoadedChildren = Array.isArray(node.children);
const hasAsyncChildren = !!node.hasChildren && !hasLoadedChildren;
const hasChildren = hasLoadedChildren || hasAsyncChildren;
const isLoading = controller.isNodeLoading(node.value);
const loadError = controller.getNodeLoadError(node.value);
const isExpanded = controller.expandedState[node.value] || false;
const nested = (node.children || []).map((child) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TreeNode, {
node: child,
flatValues,
getStyles,
rootIndex: void 0,
level: level + 1,
controller,
expandOnClick,
isSubtree: true,
renderNode,
selectOnClick,
allowRangeSelection,
expandOnSpace,
checkOnSpace,
keepMounted,
onDragDrop,
allowDrop,
withDragHandle,
dragStateRef,
data
}, child.value));
const { elementProps: dragElementProps, dragHandleProps } = require_use_tree_node_drag_drop.useTreeNodeDragDrop({
nodeValue: node.value,
hasChildren,
data,
onDragDrop,
dragStateRef,
allowDrop,
withDragHandle
});
const handleKeyDown = (event) => {
if (event.nativeEvent.code === "ArrowRight") {
event.stopPropagation();
event.preventDefault();
if (isExpanded) event.currentTarget.querySelector("[role=treeitem]")?.focus();
else controller.expand(node.value);
}
if (event.nativeEvent.code === "ArrowLeft") {
event.stopPropagation();
event.preventDefault();
if (isExpanded && hasChildren) controller.collapse(node.value);
else if (isSubtree) require_find_element_ancestor.findElementAncestor(event.currentTarget, "[role=treeitem]")?.focus();
}
if (event.nativeEvent.code === "ArrowDown" || event.nativeEvent.code === "ArrowUp") {
const root = require_find_element_ancestor.findElementAncestor(event.currentTarget, "[data-tree-root]");
if (!root) return;
event.stopPropagation();
event.preventDefault();
const nodes = Array.from(root.querySelectorAll("[role=treeitem]")).filter((treeNode) => treeNode.style.display !== "none");
const index = nodes.indexOf(event.currentTarget);
if (index === -1) return;
const nextIndex = event.nativeEvent.code === "ArrowDown" ? index + 1 : index - 1;
nodes[nextIndex]?.focus();
if (event.shiftKey) {
const selectNode = nodes[nextIndex];
if (selectNode) controller.setSelectedState(getValuesRange(controller.anchorNode, selectNode.dataset.value, flatValues));
}
}
if (event.nativeEvent.code === "Space") {
if (expandOnSpace) {
event.stopPropagation();
event.preventDefault();
controller.toggleExpanded(node.value);
}
if (checkOnSpace) {
event.stopPropagation();
event.preventDefault();
controller.isNodeChecked(node.value) ? controller.uncheckNode(node.value) : controller.checkNode(node.value);
}
}
};
const handleNodeClick = (event) => {
event.stopPropagation();
if (allowRangeSelection && event.shiftKey && controller.anchorNode) {
controller.setSelectedState(getValuesRange(controller.anchorNode, node.value, flatValues));
ref.current?.focus();
} else {
if (expandOnClick) controller.toggleExpanded(node.value);
selectOnClick && controller.select(node.value);
ref.current?.focus();
}
};
const selected = controller.selectedState.includes(node.value);
const elementProps = {
...getStyles("label"),
onClick: handleNodeClick,
"data-selected": selected || void 0,
"data-value": node.value,
...dragElementProps
};
const withLoadingIndicator = isExpanded && isLoading && nested.length === 0;
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("li", {
...getStyles("node", { style: { "--label-offset": `calc(var(--level-offset) * ${level - 1})` } }),
role: "treeitem",
"aria-selected": selected,
"data-value": node.value,
"data-selected": selected || void 0,
"data-level": level,
tabIndex: rootIndex === 0 ? 0 : -1,
onKeyDown: handleKeyDown,
ref,
children: [
typeof renderNode === "function" ? renderNode({
node,
level,
selected,
tree: controller,
expanded: isExpanded,
hasChildren,
isLoading,
loadError,
elementProps,
dragHandleProps
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
...elementProps,
children: node.label
}),
withLoadingIndicator && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Box.Box, {
component: "ul",
role: "group",
...getStyles("subtree"),
"data-level": level,
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("li", {
...getStyles("node", { style: { "--label-offset": `calc(var(--level-offset) * ${level})` } }),
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
...getStyles("label"),
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Loader.Loader, { size: 16 })
})
})
}),
keepMounted && nested.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Activity, {
mode: isExpanded ? "visible" : "hidden",
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Box.Box, {
component: "ul",
role: "group",
...getStyles("subtree"),
"data-level": level,
children: nested
})
}) : isExpanded && nested.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Box.Box, {
component: "ul",
role: "group",
...getStyles("subtree"),
"data-level": level,
children: nested
})
]
});
}
TreeNode.displayName = "@mantine/core/TreeNode";
//#endregion
exports.TreeNode = TreeNode;
//# sourceMappingURL=TreeNode.cjs.map