@veracity/vui
Version:
Veracity UI is a React component library crafted for use within Veracity applications and pages. Based on Styled Components and @xstyled.
103 lines (101 loc) • 3.38 kB
JavaScript
import { filterUndefined } from "../utils/object.js";
import { cs } from "../utils/styles.js";
import { useStyleConfig } from "../core/theme.js";
import styled from "../core/styled.js";
import vui from "../core/vui.js";
import { List } from "../list/list.js";
import { TreeProvider } from "./context.js";
import { TreeIcon } from "./treeIcon.js";
import { TreeText } from "./treeText.js";
import { TreeItem } from "./treeItem.js";
import { useTreeState } from "./useTreeState.js";
import { Children, useEffect, useMemo } from "react";
import { jsx } from "react/jsx-runtime";
//#region src/tree/tree.tsx
const TreeBase = styled.divBox`
display: flex;
height: auto;
align-content: flex-start;
flex-direction: column;
`;
/** Displays a tree of tree link items and optional heading. Exposes some props to the children via context. */
const Tree = vui((props, ref) => {
const { activeItemId, children, className, iconCollapse, iconExpand, items, onClickItem, size, variant, ...rest } = props;
const styles = useStyleConfig("Tree", props);
const { itemsInternal, setItemsInternal, activeItemIndex, setActiveItemIndex } = useTreeState(activeItemId);
const context = useMemo(() => filterUndefined({
size,
variant
}), [size, variant]);
const iconCollapseInternal = iconCollapse ? iconCollapse : variant === "default" ? "falAngleRight" : "falMinus";
const iconExpandInternal = iconExpand ? iconExpand : variant === "default" ? "falAngleDown" : "falPlus";
const transformChildrenToItems = (children) => {
const t = [];
if (children) Children.toArray(children).forEach((child) => {
if (child?.props?.text) {
let items = [];
if (child.props.children) items = transformChildrenToItems(child.props.children);
t.push({
id: child.props.id,
text: child.props.text,
isActive: child.props.isActive,
items: child.props.items || items,
isCollapsed: child.props.isCollapsed,
disabled: child.props.disabled,
onClickTreeItem
});
}
});
return t;
};
useEffect(() => {
if (items) {
setItemsInternal(items);
return;
}
const t = [];
if (children) {
const transformed = transformChildrenToItems(children);
t.push(...transformed);
}
setItemsInternal(t);
if (activeItemId !== void 0 && t?.find((i) => i.id === activeItemId)) setActiveItemIndex(activeItemId);
}, [children, activeItemId]);
const onClickTreeItem = (id) => {
setActiveItemIndex(id);
if (onClickItem) onClickItem(id);
};
return /* @__PURE__ */ jsx(TreeProvider, {
value: context,
children: /* @__PURE__ */ jsx(TreeBase, {
className: cs("vui-tree", className),
ref,
...styles.container,
...rest,
children: /* @__PURE__ */ jsx(List, {
role: "tree",
w: 1,
children: itemsInternal?.map(({ id, isActive, ...props }, index) => {
return /* @__PURE__ */ jsx(TreeItem, {
activeItemIndex,
iconCollapse: iconCollapseInternal,
iconExpand: iconExpandInternal,
id,
isActive: isActive ? isActive : activeItemIndex ? activeItemIndex === id : false,
isFirstLevel: true,
onClickTreeItem,
...props
}, id ?? index);
})
})
})
});
});
Tree.Icon = TreeIcon;
Tree.Item = TreeItem;
Tree.Text = TreeText;
Tree.displayName = "Tree";
//#endregion
export { Tree, Tree as default, TreeBase };
globalThis.__vuiVersion__ = "5.3.1"
//# sourceMappingURL=tree.js.map