UNPKG

@flanksource/clicky-ui

Version:

Flanksource Clicky UI — React component library built on shadcn/ui with light/dark and density theming.

101 lines (100 loc) 3.43 kB
import { jsxs, jsx } from "react/jsx-runtime"; import { useState, useRef, useEffect } from "react"; import { cn } from "../lib/utils.js"; import { Icon } from "./Icon.js"; function TreeNode({ node, depth = 0, expandAll = null, forcedOpenKeys = null, selected = null, defaultOpen, getChildren, getKey, onSelect, renderRow, rowClass, indentPx = 16, basePaddingPx = 8, isSecondary }) { const children = getChildren(node); const hasChildren = ((children == null ? void 0 : children.length) ?? 0) > 0; const initialOpen = defaultOpen ? defaultOpen(node, depth) : depth < 1; const [open, setOpen] = useState(initialOpen); const prevExpandAll = useRef(expandAll); const isSelected = selected === node; const key = getKey(node); const isForcedOpen = (forcedOpenKeys == null ? void 0 : forcedOpenKeys.has(key)) ?? false; const isOpen = isForcedOpen || open; const secondaryNode = (isSecondary == null ? void 0 : isSecondary(node)) ?? false; const childrenAllSecondary = hasChildren && isSecondary != null && children.every((c) => isSecondary(c)); const skipExpandAll = secondaryNode || childrenAllSecondary; useEffect(() => { if (expandAll !== null && expandAll !== prevExpandAll.current && !skipExpandAll) { setOpen(expandAll); } prevExpandAll.current = expandAll; }, [expandAll, skipExpandAll]); function toggle() { if (hasChildren) setOpen((o) => !o); } const defaultRowBg = isSelected ? "bg-primary/10 border-l-2 border-primary" : "hover:bg-accent"; const rowClassName = rowClass ? rowClass(node, isSelected) : defaultRowBg; return /* @__PURE__ */ jsxs( "div", { role: "treeitem", "aria-expanded": hasChildren ? isOpen : void 0, "aria-selected": isSelected, children: [ /* @__PURE__ */ jsxs( "div", { className: cn("flex items-center gap-1.5 py-1 px-2 cursor-pointer text-sm", rowClassName), style: { paddingLeft: `${depth * indentPx + basePaddingPx}px` }, onClick: (e) => { e.stopPropagation(); onSelect == null ? void 0 : onSelect(node); toggle(); }, children: [ hasChildren ? /* @__PURE__ */ jsx( Icon, { name: isOpen ? "codicon:chevron-down" : "codicon:chevron-right", className: "text-muted-foreground text-xs w-3" } ) : /* @__PURE__ */ jsx("span", { className: "w-3 shrink-0", "aria-hidden": true }), renderRow({ node, depth, open: isOpen, selected: isSelected, hasChildren, toggle }) ] } ), isOpen && hasChildren && /* @__PURE__ */ jsx("div", { role: "group", children: children.map((child) => /* @__PURE__ */ jsx( TreeNode, { node: child, depth: depth + 1, expandAll, forcedOpenKeys, selected, getChildren, getKey, renderRow, indentPx, basePaddingPx, ...defaultOpen ? { defaultOpen } : {}, ...onSelect ? { onSelect } : {}, ...rowClass ? { rowClass } : {}, ...isSecondary ? { isSecondary } : {} }, getKey(child) )) }) ] } ); } export { TreeNode }; //# sourceMappingURL=TreeNode.js.map