@1771technologies/lytenyte-pro
Version:
Blazingly fast headless React data grid with 100s of features.
64 lines (63 loc) • 3.24 kB
JavaScript
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 }) }));
}