UNPKG

aura-glass

Version:

A comprehensive glassmorphism design system for React applications with 142+ production-ready components

158 lines (155 loc) 5.06 kB
'use client'; import { jsx } from 'react/jsx-runtime'; import { forwardRef, useState, useCallback, useMemo, createContext } from 'react'; import { cn } from '../../lib/utilsComprehensive.js'; import styles from './TreeView.module.css.js'; const TREE_COLOR_MAP = { default: { accent: 'rgba(248, 250, 252, 0.9)', highlight: 'rgba(99, 102, 241, 0.14)' }, primary: { accent: 'rgba(99, 102, 241, 0.9)', highlight: 'rgba(99, 102, 241, 0.18)' }, secondary: { accent: 'rgba(156, 39, 176, 0.9)', highlight: 'rgba(156, 39, 176, 0.16)' }, success: { accent: 'rgba(34, 197, 94, 0.9)', highlight: 'rgba(34, 197, 94, 0.18)' }, warning: { accent: 'rgba(251, 191, 36, 0.9)', highlight: 'rgba(251, 191, 36, 0.18)' }, danger: { accent: 'rgba(239, 68, 68, 0.9)', highlight: 'rgba(239, 68, 68, 0.18)' }, info: { accent: 'rgba(14, 165, 233, 0.9)', highlight: 'rgba(14, 165, 233, 0.18)' } }; // Create context for TreeView state const TreeViewContext = /*#__PURE__*/createContext(null); /** * TreeView Component Implementation */ function TreeViewComponent(props, ref) { const { selectedIds, expandedIds, onSelectionChange, onExpansionChange, multiSelect = false, showIcons = false, showLines = false, size = 'medium', disabled = false, glass = true, color = 'default', children, className, style, ...rest } = props; // State for uncontrolled component const [internalExpanded, setInternalExpanded] = useState(expandedIds || []); const [internalSelected, setInternalSelected] = useState(selectedIds || []); const [internalFocused, setInternalFocused] = useState(null); // Determine if component is controlled const isExpandedControlled = expandedIds !== undefined; const isSelectedControlled = selectedIds !== undefined; // Get values based on controlled/uncontrolled state const expanded = isExpandedControlled ? expandedIds : internalExpanded; const selected = isSelectedControlled ? selectedIds : internalSelected; const currentExpanded = expanded ?? []; const currentSelected = selected ?? []; const focusedIds = internalFocused ? [internalFocused] : []; // Toggle node expansion const toggleNode = useCallback(nodeId => { const isOpen = currentExpanded.includes(nodeId); const nextExpanded = isOpen ? currentExpanded.filter(id => id !== nodeId) : [...currentExpanded, nodeId]; if (!isExpandedControlled) { setInternalExpanded(nextExpanded); } onExpansionChange?.(nextExpanded); }, [currentExpanded, isExpandedControlled, onExpansionChange]); // Select node const selectNode = useCallback(nodeId => { let nextSelected; if (multiSelect) { const isActive = currentSelected.includes(nodeId); nextSelected = isActive ? currentSelected.filter(id => id !== nodeId) : [...currentSelected, nodeId]; } else { nextSelected = [nodeId]; } if (!isSelectedControlled) { setInternalSelected(nextSelected); } onSelectionChange?.(nextSelected); }, [currentSelected, isSelectedControlled, multiSelect, onSelectionChange]); // Focus node const focusNode = useCallback(nodeId => { setInternalFocused(nodeId); }, []); // Create context value const contextValue = useMemo(() => ({ expanded: currentExpanded, selected: currentSelected, focused: focusedIds, multiSelect, size, disabled, glass, selectNode, toggleNode, focusNode, showIcons, showLines }), [currentExpanded, currentSelected, focusedIds, multiSelect, size, disabled, glass, selectNode, toggleNode, focusNode, showIcons, showLines]); // Extract compatible HTML attributes (rest already contains HTML attributes from props) const compatibleRest = rest; const sizeClass = size === 'small' ? styles.sizeSmall : size === 'large' ? styles.sizeLarge : styles.sizeMedium; const containerVars = useMemo(() => ({ '--tree-view-color': (TREE_COLOR_MAP[color] ?? TREE_COLOR_MAP.default).accent, '--tree-view-selected-bg': (TREE_COLOR_MAP[color] ?? TREE_COLOR_MAP.default).highlight }), [color]); return jsx(TreeViewContext.Provider, { "data-glass-component": true, value: contextValue, children: jsx("ul", { ref: ref, role: "tree", className: cn(styles.root, sizeClass, disabled && styles.disabled, className), style: { ...containerVars, ...style }, "aria-multiselectable": multiSelect, ...compatibleRest, children: children }) }); } /** * TreeView Component * * A hierarchical list with collapsible items. */ const TreeView = /*#__PURE__*/forwardRef(TreeViewComponent); /** * GlassTreeView Component * * Glass variant of the TreeView component. */ const GlassTreeView = /*#__PURE__*/forwardRef((props, ref) => jsx(TreeView, { ...props, ref: ref })); GlassTreeView.displayName = 'GlassTreeView'; export { GlassTreeView, TreeView, TreeViewContext, TreeView as default }; //# sourceMappingURL=TreeView.js.map