import * as React from "react"; import { ContainerProps, classList } from "../util"; import { FocusList } from "./FocusList"; export interface TreeProps extends ContainerProps { role?: "tree" | "group"; } export interface TreeItemProps extends ContainerProps { role?: "treeitem"; onClick?: () => void; initiallyExpanded?: boolean; title?: string; } export interface TreeItemBodyProps extends ContainerProps { } export const Tree = (props: TreeProps) => { const { children, id, className, ariaLabel, ariaHidden, ariaDescribedBy, role, } = props; if (!role || role === "tree") { return ( {children} ) } return (
{children}
) }; export const TreeItem = (props: TreeItemProps) => { const { children, id, className, ariaLabel, ariaHidden, ariaDescribedBy, role, initiallyExpanded, onClick, title } = props; const [expanded, setExpanded] = React.useState(initiallyExpanded); const mappedChildren = React.Children.toArray(children); const hasSubtree = mappedChildren.length > 1; const subtreeContainer = React.useRef() React.useEffect(() => { if (!hasSubtree) return; if (expanded) { const focusable = subtreeContainer.current.querySelectorAll(`[tabindex]:not([tabindex="-1"]),[data-isfocusable]`); focusable.forEach(f => f.setAttribute("data-isfocusable", "true")); } else { const focusable = subtreeContainer.current.querySelectorAll(`[tabindex]:not([tabindex="-1"]),[data-isfocusable]`); focusable.forEach(f => f.setAttribute("data-isfocusable", "false")); } }, [expanded, hasSubtree]); const onTreeItemClick = React.useCallback(() => { if (hasSubtree) { setExpanded(!expanded); } if (onClick) { onClick(); } }, [hasSubtree, expanded]) return (
{hasSubtree && } {mappedChildren[0]}
{hasSubtree ? mappedChildren[1] : undefined}
); } export const TreeItemBody = (props: TreeItemBodyProps) => { const { children, id, className, ariaLabel, ariaHidden, ariaDescribedBy, role, } = props; return (
{children}
); }