UNPKG

@1771technologies/lytenyte-pro

Version:

Blazingly fast headless React data grid with 100s of features.

64 lines (63 loc) 3.24 kB
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime"; import { forwardRef, useEffect } from "react"; import { depthContext, useDepth } from "../depth-provider.js"; import { useTreeRoot } from "../context.js"; import { useBranchKeys } from "./use-branch-keys.js"; import { useEvent, useSlot, useTransitionedOpen, } from "@1771technologies/lytenyte-core/yinternal"; export const TreeBranch = forwardRef(function TreeBranch({ itemId, label, expander, transitionEnterMs, transitionExitMs, gridWrapped, labelWrap, ...props }, forwarded) { const depth = useDepth(); const root = useTreeRoot(); // Manage the open and close state of the branch const expanded = root.expansions[itemId] ?? root.expansionDefault ?? false; const { open, shouldMount, state, toggle } = useTransitionedOpen({ initial: expanded, timeEnter: transitionEnterMs ?? root.transitionEnterMs, timeExit: transitionExitMs ?? root.transitionExitMs, }); const onExpansionChange = useEvent((b) => { root.onExpansionChange({ ...root.expansions, [itemId]: b, }); }); useEffect(() => { if (expanded === open) return; toggle(expanded); }, [expanded, open, toggle]); // Component part rendering const labelRendered = useSlot({ props: [], slot: label ?? _jsx("div", {}), }); const expandedProps = { onClick: (e) => { e.stopPropagation(); onExpansionChange(!expanded); }, }; const expanderRendered = useSlot({ props: [expandedProps], slot: expander ?? _jsx("button", { children: ">" }), state: { toggle, expanded }, }); const wrapped = gridWrapped ?? root.gridWrappedBranches; const labelWrapSlot = useSlot({ props: [ { "data-tree-branch-label": true, children: (_jsxs(_Fragment, { children: [expanderRendered, labelRendered] })), }, ], slot: labelWrap ?? _jsx("div", {}), }); return (_jsx(depthContext.Provider, { value: depth + 1, children: _jsxs("li", { ...props, onKeyDown: useBranchKeys(itemId, root.expansionDefault ?? false, props.onKeyDown), tabIndex: -1, ref: forwarded, role: "treeitem", "aria-expanded": open, "aria-selected": root.selection.has(itemId), "aria-level": depth + 1, "data-ln-selected": root.selection.has(itemId), "data-ln-tree-node": true, "data-ln-tree-branch": true, "data-ln-tree-id": itemId, style: { ...props.style, "--ln-tree-depth": depth, }, children: [labelWrapSlot, _jsx("div", { children: _jsx(Wrapped, { wrapped: wrapped, expanded: open, children: shouldMount && (_jsx("ul", { "data-tree-branch-children": true, "data-expanded": open, "data-open-state": state, role: "group", children: props.children })) }) })] }) })); }); function Wrapped(props) { if (!props.wrapped) return _jsx(_Fragment, { children: props.children }); return (_jsx("div", { "data-tree-branch-grid-wrapped": true, "data-expanded": props.expanded, children: _jsx("div", { "data-tree-branch-grid-wrapped-content": true, children: props.children }) })); }