import { createSignal, createContext, useContext, JSXElement, Show, For, createEffect } from 'solid-js'; import { createStore } from 'solid-js/store'; import { Dynamic } from 'solid-js/web'; // TreeView Context Type type TreeViewContextType = { expandedItems: string[]; toggleItem: (itemId: string) => void; isExpanded: (itemId: string) => boolean; }; // Create TreeView Context const TreeViewContext = createContext({ expandedItems: [], // eslint-disable-next-line toggleItem: () => {}, isExpanded: () => false, }); // Icons for expanded and collapsed states const ChevronRight = () => ( ); const ChevronDown = () => ( ); // Props for TreeView component type TreeViewProps = { children: JSXElement; defaultExpanded?: string[]; class?: string; }; // TreeView component export const TreeView = (props: TreeViewProps) => { const [expandedItems, setExpandedItems] = createSignal(props.defaultExpanded || []); const toggleItem = (itemId: string) => { setExpandedItems((prev) => { if (prev.includes(itemId)) { return prev.filter((id) => id !== itemId); } else { return [...prev, itemId]; } }); }; const isExpanded = (itemId: string) => { return expandedItems().includes(itemId); }; const contextValue = { expandedItems: expandedItems(), toggleItem, isExpanded, }; return (
{props.children}
); }; // Props for TreeItem component type TreeItemProps = { itemId: string; label: string | JSXElement; children?: JSXElement; icon?: JSXElement; endIcon?: JSXElement; }; // TreeItem component export const TreeItem = (props: TreeItemProps) => { const context = useContext(TreeViewContext); const hasChildren = !!props.children; return (
hasChildren && context.toggleItem(props.itemId)} >
{props.icon}
{props.label}
{props.endIcon}
{props.children}
); }; // Rich TreeView component with more features type RichTreeViewProps = TreeViewProps & { highlightItems?: string[]; onNodeSelect?: (itemId: string) => void; }; export const RichTreeView = (props: RichTreeViewProps) => { const [store, setStore] = createStore({ selectedItem: '', highlightedItems: props.highlightItems || [], }); createEffect(() => { if (props.highlightItems) { setStore('highlightedItems', props.highlightItems); } }); const handleNodeSelect = (itemId: string) => { setStore('selectedItem', itemId); props.onNodeSelect && props.onNodeSelect(itemId); }; // Enhanced context with selection functionality const enhancedContext = { selectedItem: () => store.selectedItem, highlightedItems: () => store.highlightedItems, handleNodeSelect, }; return ( {props.children} ); };