@ducor/react
Version:
admin template ui interface
56 lines (55 loc) • 2.52 kB
JavaScript
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import React, { cloneElement, Fragment, isValidElement, memo, useState, } from "react";
import TreeItem from "./item";
import { TreeViewContext } from "./context";
import { isArray } from "./utils";
import { useElementSize } from "@ducor/hooks";
const MemoComponent = memo(({ component }) => {
const addUuidToChildren = (children, parentUuid = "") => {
return React.Children.map(children, (child, index) => {
if (!isValidElement(child))
return child;
const currentUuid = `${parentUuid}${index}`;
let newProps = Object.assign(Object.assign({}, child.props), { uuid: `menu-${currentUuid}`, children: undefined });
if (isArray(child.props.children)) {
newProps.children = addUuidToChildren(child.props.children, `${currentUuid}-`);
}
return cloneElement(child, newProps);
});
};
return _jsx(_Fragment, { children: addUuidToChildren(component) });
});
const TreeView = memo(({ defaultActivePath, onChange, children, ariaLabel }) => {
const { ref, height, width } = useElementSize();
const [activePath, setActivePath] = useState(defaultActivePath || "-");
const [expandedPaths, setExpandedPaths] = useState([]);
const handleActivePath = (pathname) => {
setActivePath(pathname);
if (typeof onChange === "function") {
onChange(pathname);
}
};
const addExpandedPath = (path) => {
setExpandedPaths((prevPaths) => prevPaths.includes(path) ? prevPaths : [...prevPaths, path]);
};
const removeExpandedPath = (path) => {
setExpandedPaths((prevPaths) => [...prevPaths.filter((p) => p !== path)]);
};
const value = {
ariaLabel,
height: height - 8,
width: width - 8,
expandedPaths,
setExpandedPaths,
addExpandedPath,
removeExpandedPath,
activePath,
setActivePath: handleActivePath,
//
};
return (_jsx(TreeViewContext.Provider, { value: value, children: _jsxs("nav", { ref: ref, "aria-label": ariaLabel || "Tree Navigation", className: 'ui-tree', children: [_jsx("span", { role: 'status', "aria-live": 'polite' }), _jsx("ul", { role: 'tree', className: 'tree-group', "data-dept": 0, children: _jsx(MemoComponent, { component: children }) })] }) }));
});
export default Object.assign(TreeView, {
Item: TreeItem,
Group: Fragment,
});