@brycks/core-front 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/dist/components/data/List/List.cjs +1 -1
  2. package/dist/components/data/List/List.cjs.map +1 -1
  3. package/dist/components/data/List/List.js +68 -148
  4. package/dist/components/data/List/List.js.map +1 -1
  5. package/dist/components/data/Table/Table.cjs +1 -1
  6. package/dist/components/data/Table/Table.cjs.map +1 -1
  7. package/dist/components/data/Table/Table.js +142 -224
  8. package/dist/components/data/Table/Table.js.map +1 -1
  9. package/dist/components/data/TreeView/TreeView.cjs +1 -1
  10. package/dist/components/data/TreeView/TreeView.cjs.map +1 -1
  11. package/dist/components/data/TreeView/TreeView.js +141 -182
  12. package/dist/components/data/TreeView/TreeView.js.map +1 -1
  13. package/dist/components/feedback/Drawer/Drawer.cjs +1 -22
  14. package/dist/components/feedback/Drawer/Drawer.cjs.map +1 -1
  15. package/dist/components/feedback/Drawer/Drawer.js +84 -184
  16. package/dist/components/feedback/Drawer/Drawer.js.map +1 -1
  17. package/dist/components/feedback/Modal/Modal.cjs +1 -1
  18. package/dist/components/feedback/Modal/Modal.cjs.map +1 -1
  19. package/dist/components/feedback/Modal/Modal.js +65 -150
  20. package/dist/components/feedback/Modal/Modal.js.map +1 -1
  21. package/dist/components/feedback/Toast/Toast.cjs +1 -10
  22. package/dist/components/feedback/Toast/Toast.cjs.map +1 -1
  23. package/dist/components/feedback/Toast/Toast.js +94 -187
  24. package/dist/components/feedback/Toast/Toast.js.map +1 -1
  25. package/dist/components/form/Checkbox/Checkbox.cjs +1 -1
  26. package/dist/components/form/Checkbox/Checkbox.js +11 -11
  27. package/dist/components/form/Combobox/Combobox.cjs +1 -6
  28. package/dist/components/form/Combobox/Combobox.cjs.map +1 -1
  29. package/dist/components/form/Combobox/Combobox.js +187 -283
  30. package/dist/components/form/Combobox/Combobox.js.map +1 -1
  31. package/dist/components/form/Input/Input.cjs +1 -1
  32. package/dist/components/form/Input/Input.cjs.map +1 -1
  33. package/dist/components/form/Input/Input.js +38 -133
  34. package/dist/components/form/Input/Input.js.map +1 -1
  35. package/dist/components/form/Select/Select.cjs +1 -1
  36. package/dist/components/form/Select/Select.cjs.map +1 -1
  37. package/dist/components/form/Select/Select.js +36 -82
  38. package/dist/components/form/Select/Select.js.map +1 -1
  39. package/dist/components/form/TagInput/TagInput.cjs +1 -1
  40. package/dist/components/form/TagInput/TagInput.js +8 -8
  41. package/dist/components/form/Textarea/Textarea.cjs +1 -1
  42. package/dist/components/form/Textarea/Textarea.cjs.map +1 -1
  43. package/dist/components/form/Textarea/Textarea.js +61 -95
  44. package/dist/components/form/Textarea/Textarea.js.map +1 -1
  45. package/dist/components/navigation/ContextMenu/ContextMenu.cjs +1 -1
  46. package/dist/components/navigation/ContextMenu/ContextMenu.js +9 -9
  47. package/dist/components/navigation/Menu/Menu.cjs +1 -1
  48. package/dist/components/navigation/Menu/Menu.cjs.map +1 -1
  49. package/dist/components/navigation/Menu/Menu.js +70 -135
  50. package/dist/components/navigation/Menu/Menu.js.map +1 -1
  51. package/dist/components/navigation/Pagination/Pagination.cjs +1 -1
  52. package/dist/components/navigation/Pagination/Pagination.cjs.map +1 -1
  53. package/dist/components/navigation/Pagination/Pagination.js +87 -157
  54. package/dist/components/navigation/Pagination/Pagination.js.map +1 -1
  55. package/dist/styles.css +1 -1
  56. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"TreeView.cjs","sources":["../../../../src/components/data/TreeView/TreeView.tsx"],"sourcesContent":["/**\n * TreeView Component\n *\n * A hierarchical tree structure for displaying nested data.\n * Supports selection, expansion, and keyboard navigation.\n *\n * @module components/data/TreeView\n */\n\nimport {\n forwardRef,\n useState,\n useCallback,\n useMemo,\n type CSSProperties,\n type ReactNode,\n type KeyboardEvent,\n} from 'react'\nimport { cx } from '../../../utils/styles'\nimport { spacing, fontSizes, durations, easings } from '../../../design-system'\nimport { componentPaddingY, iconSizes } from '../../../design-system/primitives'\n\nexport interface TreeNode {\n /** Unique identifier */\n id: string\n /** Display label */\n label: string\n /** Optional icon */\n icon?: ReactNode\n /** Child nodes */\n children?: TreeNode[]\n /** Whether the node is disabled */\n disabled?: boolean\n /** Additional data */\n data?: unknown\n}\n\nexport type TreeViewSize = 'sm' | 'md' | 'lg'\n\nexport interface TreeViewProps {\n /** Tree data */\n data: TreeNode[]\n /** Selected node IDs (controlled) */\n selectedIds?: string[]\n /** Default selected node IDs (uncontrolled) */\n defaultSelectedIds?: string[]\n /** Expanded node IDs (controlled) */\n expandedIds?: string[]\n /** Default expanded node IDs (uncontrolled) */\n defaultExpandedIds?: string[]\n /** Callback when selection changes */\n onSelectionChange?: (selectedIds: string[]) => void\n /** Callback when expansion changes */\n onExpansionChange?: (expandedIds: string[]) => void\n /** Callback when a node is clicked */\n onNodeClick?: (node: TreeNode) => void\n /** Whether to allow multi-selection */\n multiSelect?: boolean\n /** Component size */\n size?: TreeViewSize\n /** Whether to show connecting lines */\n showLines?: boolean\n /** Custom node renderer */\n renderNode?: (node: TreeNode, isSelected: boolean, isExpanded: boolean) => ReactNode\n /** Label for accessibility */\n 'aria-label'?: string\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nconst sizeConfig: Record<TreeViewSize, { fontSize: number; iconSize: number; padding: number; indent: number }> = {\n sm: { fontSize: fontSizes.sm, iconSize: iconSizes.xs, padding: componentPaddingY.xs, indent: spacing[4] },\n md: { fontSize: fontSizes.base, iconSize: iconSizes.sm, padding: componentPaddingY.sm, indent: spacing[5] },\n lg: { fontSize: fontSizes.md, iconSize: iconSizes.md, padding: componentPaddingY.md, indent: spacing[6] },\n}\n\nfunction ChevronIcon({ expanded }: { expanded: boolean }) {\n return (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n aria-hidden=\"true\"\n style={{\n transform: expanded ? 'rotate(90deg)' : 'rotate(0)',\n transition: `transform ${durations.fast}ms ${easings.easeOut}`,\n }}\n >\n <path d=\"M6 4l4 4-4 4\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n )\n}\n\ninterface TreeNodeItemProps {\n node: TreeNode\n level: number\n config: typeof sizeConfig.md\n isSelected: boolean\n isExpanded: boolean\n showLines: boolean\n onToggle: (id: string) => void\n onSelect: (id: string, multi: boolean) => void\n renderNode?: TreeViewProps['renderNode']\n selectedIds: string[]\n expandedIds: string[]\n multiSelect: boolean\n}\n\nfunction TreeNodeItem({\n node,\n level,\n config,\n isSelected,\n isExpanded,\n showLines,\n onToggle,\n onSelect,\n renderNode,\n selectedIds,\n expandedIds,\n multiSelect,\n}: TreeNodeItemProps) {\n const hasChildren = node.children && node.children.length > 0\n\n const handleClick = useCallback(\n (e: React.MouseEvent) => {\n if (node.disabled) return\n onSelect(node.id, e.ctrlKey || e.metaKey)\n },\n [node.id, node.disabled, onSelect]\n )\n\n const handleToggle = useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation()\n if (hasChildren) {\n onToggle(node.id)\n }\n },\n [node.id, hasChildren, onToggle]\n )\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLDivElement>) => {\n if (node.disabled) return\n\n switch (e.key) {\n case 'Enter':\n case ' ':\n e.preventDefault()\n onSelect(node.id, e.ctrlKey || e.metaKey)\n break\n case 'ArrowRight':\n e.preventDefault()\n if (hasChildren && !isExpanded) {\n onToggle(node.id)\n }\n break\n case 'ArrowLeft':\n e.preventDefault()\n if (hasChildren && isExpanded) {\n onToggle(node.id)\n }\n break\n }\n },\n [node.id, node.disabled, hasChildren, isExpanded, onToggle, onSelect]\n )\n\n const itemStyle: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: spacing[1.5],\n padding: `${config.padding}px ${spacing[2]}px`,\n paddingLeft: spacing[2] + level * config.indent,\n fontSize: config.fontSize,\n color: node.disabled ? 'var(--brycks-foreground-disabled)' : 'var(--brycks-foreground-default)',\n backgroundColor: isSelected ? 'var(--brycks-primary-muted)' : 'transparent',\n borderRadius: 'var(--brycks-radius-md)',\n cursor: node.disabled ? 'not-allowed' : 'pointer',\n userSelect: 'none',\n transition: `background-color ${durations.fast}ms ${easings.easeOut}`,\n position: 'relative',\n }\n\n const toggleStyle: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: config.iconSize,\n height: config.iconSize,\n color: 'var(--brycks-foreground-muted)',\n cursor: 'pointer',\n flexShrink: 0,\n }\n\n const iconStyle: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: config.iconSize,\n height: config.iconSize,\n color: isSelected ? 'var(--brycks-primary-default)' : 'var(--brycks-foreground-muted)',\n flexShrink: 0,\n }\n\n const lineStyle: CSSProperties = showLines && level > 0 ? {\n position: 'absolute',\n left: spacing[2] + (level - 1) * config.indent + config.iconSize / 2,\n top: 0,\n bottom: 0,\n width: 1,\n backgroundColor: 'var(--brycks-border-default)',\n } : {}\n\n return (\n <li role=\"treeitem\" aria-selected={isSelected} aria-expanded={hasChildren ? isExpanded : undefined}>\n <div\n tabIndex={node.disabled ? -1 : 0}\n style={itemStyle}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n onMouseEnter={(e) => {\n if (!node.disabled && !isSelected) {\n e.currentTarget.style.backgroundColor = 'var(--brycks-background-muted)'\n }\n }}\n onMouseLeave={(e) => {\n if (!isSelected) {\n e.currentTarget.style.backgroundColor = 'transparent'\n }\n }}\n >\n {showLines && level > 0 && <span style={lineStyle} aria-hidden=\"true\" />}\n <span style={toggleStyle} onClick={handleToggle}>\n {hasChildren && <ChevronIcon expanded={isExpanded} />}\n </span>\n {node.icon && <span style={iconStyle}>{node.icon}</span>}\n {renderNode ? (\n renderNode(node, isSelected, isExpanded)\n ) : (\n <span style={{ flex: 1 }}>{node.label}</span>\n )}\n </div>\n {hasChildren && isExpanded && (\n <ul role=\"group\" style={{ listStyle: 'none', margin: 0, padding: 0 }}>\n {node.children!.map((child) => (\n <TreeNodeItem\n key={child.id}\n node={child}\n level={level + 1}\n config={config}\n isSelected={selectedIds.includes(child.id)}\n isExpanded={expandedIds.includes(child.id)}\n showLines={showLines}\n onToggle={onToggle}\n onSelect={onSelect}\n renderNode={renderNode}\n selectedIds={selectedIds}\n expandedIds={expandedIds}\n multiSelect={multiSelect}\n />\n ))}\n </ul>\n )}\n </li>\n )\n}\n\nexport const TreeView = forwardRef<HTMLUListElement, TreeViewProps>(function TreeView(\n {\n data,\n selectedIds: controlledSelectedIds,\n defaultSelectedIds = [],\n expandedIds: controlledExpandedIds,\n defaultExpandedIds = [],\n onSelectionChange,\n onExpansionChange,\n onNodeClick,\n multiSelect = false,\n size = 'md',\n showLines = false,\n renderNode,\n 'aria-label': ariaLabel = 'Tree',\n className,\n testId,\n },\n ref\n) {\n const [internalSelectedIds, setInternalSelectedIds] = useState<string[]>(defaultSelectedIds)\n const [internalExpandedIds, setInternalExpandedIds] = useState<string[]>(defaultExpandedIds)\n\n const selectedIds = controlledSelectedIds !== undefined ? controlledSelectedIds : internalSelectedIds\n const expandedIds = controlledExpandedIds !== undefined ? controlledExpandedIds : internalExpandedIds\n const config = sizeConfig[size]\n\n // Flatten all nodes for keyboard navigation\n const flatNodes = useMemo(() => {\n const flatten = (nodes: TreeNode[], result: TreeNode[] = []): TreeNode[] => {\n nodes.forEach((node) => {\n result.push(node)\n if (node.children && expandedIds.includes(node.id)) {\n flatten(node.children, result)\n }\n })\n return result\n }\n return flatten(data)\n }, [data, expandedIds])\n\n const handleToggle = useCallback(\n (id: string) => {\n const newExpandedIds = expandedIds.includes(id)\n ? expandedIds.filter((eid) => eid !== id)\n : [...expandedIds, id]\n\n if (controlledExpandedIds === undefined) {\n setInternalExpandedIds(newExpandedIds)\n }\n onExpansionChange?.(newExpandedIds)\n },\n [expandedIds, controlledExpandedIds, onExpansionChange]\n )\n\n const handleSelect = useCallback(\n (id: string, additive: boolean) => {\n const node = flatNodes.find((n) => n.id === id)\n if (node) {\n onNodeClick?.(node)\n }\n\n let newSelectedIds: string[]\n if (multiSelect && additive) {\n newSelectedIds = selectedIds.includes(id)\n ? selectedIds.filter((sid) => sid !== id)\n : [...selectedIds, id]\n } else {\n newSelectedIds = selectedIds.includes(id) && selectedIds.length === 1 ? [] : [id]\n }\n\n if (controlledSelectedIds === undefined) {\n setInternalSelectedIds(newSelectedIds)\n }\n onSelectionChange?.(newSelectedIds)\n },\n [flatNodes, multiSelect, selectedIds, controlledSelectedIds, onSelectionChange, onNodeClick]\n )\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLUListElement>) => {\n const currentIndex = flatNodes.findIndex((n) => selectedIds.includes(n.id))\n\n switch (e.key) {\n case 'ArrowDown': {\n e.preventDefault()\n const nextIndex = currentIndex < flatNodes.length - 1 ? currentIndex + 1 : 0\n handleSelect(flatNodes[nextIndex].id, false)\n break\n }\n case 'ArrowUp': {\n e.preventDefault()\n const prevIndex = currentIndex > 0 ? currentIndex - 1 : flatNodes.length - 1\n handleSelect(flatNodes[prevIndex].id, false)\n break\n }\n case 'Home':\n e.preventDefault()\n if (flatNodes.length > 0) {\n handleSelect(flatNodes[0].id, false)\n }\n break\n case 'End':\n e.preventDefault()\n if (flatNodes.length > 0) {\n handleSelect(flatNodes[flatNodes.length - 1].id, false)\n }\n break\n }\n },\n [flatNodes, selectedIds, handleSelect]\n )\n\n const containerStyle: CSSProperties = {\n listStyle: 'none',\n margin: 0,\n padding: spacing[1],\n outline: 'none',\n }\n\n return (\n <ul\n ref={ref}\n role=\"tree\"\n aria-label={ariaLabel}\n aria-multiselectable={multiSelect}\n tabIndex={0}\n className={cx('brycks-treeview', `brycks-treeview--${size}`, className)}\n style={containerStyle}\n data-testid={testId}\n onKeyDown={handleKeyDown}\n >\n {data.map((node) => (\n <TreeNodeItem\n key={node.id}\n node={node}\n level={0}\n config={config}\n isSelected={selectedIds.includes(node.id)}\n isExpanded={expandedIds.includes(node.id)}\n showLines={showLines}\n onToggle={handleToggle}\n onSelect={handleSelect}\n renderNode={renderNode}\n selectedIds={selectedIds}\n expandedIds={expandedIds}\n multiSelect={multiSelect}\n />\n ))}\n </ul>\n )\n})\n\nTreeView.displayName = 'TreeView'\n"],"names":["sizeConfig","fontSizes","iconSizes","componentPaddingY","spacing","ChevronIcon","expanded","jsx","durations","easings","TreeNodeItem","node","level","config","isSelected","isExpanded","showLines","onToggle","onSelect","renderNode","selectedIds","expandedIds","multiSelect","hasChildren","handleClick","useCallback","e","handleToggle","handleKeyDown","itemStyle","toggleStyle","iconStyle","lineStyle","jsxs","child","TreeView","forwardRef","data","controlledSelectedIds","defaultSelectedIds","controlledExpandedIds","defaultExpandedIds","onSelectionChange","onExpansionChange","onNodeClick","size","ariaLabel","className","testId","ref","internalSelectedIds","setInternalSelectedIds","useState","internalExpandedIds","setInternalExpandedIds","flatNodes","useMemo","flatten","nodes","result","id","newExpandedIds","eid","handleSelect","additive","n","newSelectedIds","sid","currentIndex","nextIndex","prevIndex","containerStyle","cx"],"mappings":"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"}
1
+ {"version":3,"file":"TreeView.cjs","sources":["../../../../src/components/data/TreeView/TreeView.tsx"],"sourcesContent":["/**\n * TreeView Component\n *\n * A hierarchical tree structure for displaying nested data.\n * Supports selection, expansion, and keyboard navigation.\n *\n * @module components/data/TreeView\n */\n\nimport {\n forwardRef,\n useState,\n useCallback,\n useMemo,\n type CSSProperties,\n type ReactNode,\n type KeyboardEvent,\n} from 'react'\nimport { cx } from '../../../utils/styles'\nimport { spacing, fontSizes, durations, easings } from '../../../design-system'\nimport { componentPaddingY, iconSizes } from '../../../design-system/primitives'\n\nexport interface TreeNode {\n /** Unique identifier */\n id: string\n /** Display label */\n label: string\n /** Optional icon */\n icon?: ReactNode\n /** Child nodes */\n children?: TreeNode[]\n /** Whether the node is disabled */\n disabled?: boolean\n /** Additional data */\n data?: unknown\n}\n\nexport type TreeViewSize = 'sm' | 'md' | 'lg'\n\nexport interface TreeViewProps {\n /** Tree data */\n data: TreeNode[]\n /** Selected node IDs (controlled) */\n selectedIds?: string[]\n /** Default selected node IDs (uncontrolled) */\n defaultSelectedIds?: string[]\n /** Expanded node IDs (controlled) */\n expandedIds?: string[]\n /** Default expanded node IDs (uncontrolled) */\n defaultExpandedIds?: string[]\n /** Callback when selection changes */\n onSelectionChange?: (selectedIds: string[]) => void\n /** Callback when expansion changes */\n onExpansionChange?: (expandedIds: string[]) => void\n /** Callback when a node is clicked */\n onNodeClick?: (node: TreeNode) => void\n /** Whether to allow multi-selection */\n multiSelect?: boolean\n /** Component size */\n size?: TreeViewSize\n /** Whether to show connecting lines */\n showLines?: boolean\n /** Custom node renderer */\n renderNode?: (node: TreeNode, isSelected: boolean, isExpanded: boolean) => ReactNode\n /** Label for accessibility */\n 'aria-label'?: string\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nconst sizeConfig: Record<TreeViewSize, { fontSize: number; iconSize: number; padding: number; indent: number }> = {\n sm: { fontSize: fontSizes.sm, iconSize: iconSizes.xs, padding: componentPaddingY.xs, indent: spacing[4] },\n md: { fontSize: fontSizes.base, iconSize: iconSizes.sm, padding: componentPaddingY.sm, indent: spacing[5] },\n lg: { fontSize: fontSizes.md, iconSize: iconSizes.md, padding: componentPaddingY.md, indent: spacing[6] },\n}\n\nfunction ChevronIcon({ expanded }: { expanded: boolean }) {\n return (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n aria-hidden=\"true\"\n style={{\n transform: expanded ? 'rotate(90deg)' : 'rotate(0)',\n transition: `transform ${durations.fast}ms ${easings.easeOut}`,\n }}\n >\n <path d=\"M6 4l4 4-4 4\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n )\n}\n\ninterface TreeNodeItemProps {\n node: TreeNode\n level: number\n config: typeof sizeConfig.md\n isSelected: boolean\n isExpanded: boolean\n showLines: boolean\n onToggle: (id: string) => void\n onSelect: (id: string, multi: boolean) => void\n renderNode?: TreeViewProps['renderNode']\n selectedIds: string[]\n expandedIds: string[]\n multiSelect: boolean\n}\n\nfunction TreeNodeItem({\n node,\n level,\n config,\n isSelected,\n isExpanded,\n showLines,\n onToggle,\n onSelect,\n renderNode,\n selectedIds,\n expandedIds,\n multiSelect,\n}: TreeNodeItemProps) {\n const hasChildren = node.children && node.children.length > 0\n\n const handleClick = useCallback(\n (e: React.MouseEvent) => {\n if (node.disabled) return\n onSelect(node.id, e.ctrlKey || e.metaKey)\n },\n [node.id, node.disabled, onSelect]\n )\n\n const handleToggle = useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation()\n if (hasChildren) {\n onToggle(node.id)\n }\n },\n [node.id, hasChildren, onToggle]\n )\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLDivElement>) => {\n if (node.disabled) return\n\n switch (e.key) {\n case 'Enter':\n case ' ':\n e.preventDefault()\n onSelect(node.id, e.ctrlKey || e.metaKey)\n break\n case 'ArrowRight':\n e.preventDefault()\n if (hasChildren && !isExpanded) {\n onToggle(node.id)\n }\n break\n case 'ArrowLeft':\n e.preventDefault()\n if (hasChildren && isExpanded) {\n onToggle(node.id)\n }\n break\n }\n },\n [node.id, node.disabled, hasChildren, isExpanded, onToggle, onSelect]\n )\n\n // Only the depth-based horizontal offset is dynamic (computed from `level`\n // and the per-size indent); everything else is class-driven.\n const itemStyle: CSSProperties = {\n paddingLeft: spacing[2] + level * config.indent,\n }\n\n // Connecting line offset is also depth-based.\n const lineStyle: CSSProperties = {\n left: spacing[2] + (level - 1) * config.indent + config.iconSize / 2,\n }\n\n return (\n <li role=\"treeitem\" aria-selected={isSelected} aria-expanded={hasChildren ? isExpanded : undefined}>\n <div\n tabIndex={node.disabled ? -1 : 0}\n className={cx(\n 'brycks-treeview__item',\n isSelected && 'brycks-treeview__item--selected',\n node.disabled && 'brycks-treeview__item--disabled'\n )}\n style={itemStyle}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n >\n {showLines && level > 0 && (\n <span className=\"brycks-treeview__line\" style={lineStyle} aria-hidden=\"true\" />\n )}\n <span className=\"brycks-treeview__toggle\" onClick={handleToggle}>\n {hasChildren && <ChevronIcon expanded={isExpanded} />}\n </span>\n {node.icon && <span className=\"brycks-treeview__icon\">{node.icon}</span>}\n {renderNode ? (\n renderNode(node, isSelected, isExpanded)\n ) : (\n <span className=\"brycks-treeview__label\">{node.label}</span>\n )}\n </div>\n {hasChildren && isExpanded && (\n <ul role=\"group\" className=\"brycks-treeview__group\">\n {node.children!.map((child) => (\n <TreeNodeItem\n key={child.id}\n node={child}\n level={level + 1}\n config={config}\n isSelected={selectedIds.includes(child.id)}\n isExpanded={expandedIds.includes(child.id)}\n showLines={showLines}\n onToggle={onToggle}\n onSelect={onSelect}\n renderNode={renderNode}\n selectedIds={selectedIds}\n expandedIds={expandedIds}\n multiSelect={multiSelect}\n />\n ))}\n </ul>\n )}\n </li>\n )\n}\n\nexport const TreeView = forwardRef<HTMLUListElement, TreeViewProps>(function TreeView(\n {\n data,\n selectedIds: controlledSelectedIds,\n defaultSelectedIds = [],\n expandedIds: controlledExpandedIds,\n defaultExpandedIds = [],\n onSelectionChange,\n onExpansionChange,\n onNodeClick,\n multiSelect = false,\n size = 'md',\n showLines = false,\n renderNode,\n 'aria-label': ariaLabel = 'Tree',\n className,\n testId,\n },\n ref\n) {\n const [internalSelectedIds, setInternalSelectedIds] = useState<string[]>(defaultSelectedIds)\n const [internalExpandedIds, setInternalExpandedIds] = useState<string[]>(defaultExpandedIds)\n\n const selectedIds = controlledSelectedIds !== undefined ? controlledSelectedIds : internalSelectedIds\n const expandedIds = controlledExpandedIds !== undefined ? controlledExpandedIds : internalExpandedIds\n const config = sizeConfig[size]\n\n // Flatten all nodes for keyboard navigation\n const flatNodes = useMemo(() => {\n const flatten = (nodes: TreeNode[], result: TreeNode[] = []): TreeNode[] => {\n nodes.forEach((node) => {\n result.push(node)\n if (node.children && expandedIds.includes(node.id)) {\n flatten(node.children, result)\n }\n })\n return result\n }\n return flatten(data)\n }, [data, expandedIds])\n\n const handleToggle = useCallback(\n (id: string) => {\n const newExpandedIds = expandedIds.includes(id)\n ? expandedIds.filter((eid) => eid !== id)\n : [...expandedIds, id]\n\n if (controlledExpandedIds === undefined) {\n setInternalExpandedIds(newExpandedIds)\n }\n onExpansionChange?.(newExpandedIds)\n },\n [expandedIds, controlledExpandedIds, onExpansionChange]\n )\n\n const handleSelect = useCallback(\n (id: string, additive: boolean) => {\n const node = flatNodes.find((n) => n.id === id)\n if (node) {\n onNodeClick?.(node)\n }\n\n let newSelectedIds: string[]\n if (multiSelect && additive) {\n newSelectedIds = selectedIds.includes(id)\n ? selectedIds.filter((sid) => sid !== id)\n : [...selectedIds, id]\n } else {\n newSelectedIds = selectedIds.includes(id) && selectedIds.length === 1 ? [] : [id]\n }\n\n if (controlledSelectedIds === undefined) {\n setInternalSelectedIds(newSelectedIds)\n }\n onSelectionChange?.(newSelectedIds)\n },\n [flatNodes, multiSelect, selectedIds, controlledSelectedIds, onSelectionChange, onNodeClick]\n )\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLUListElement>) => {\n const currentIndex = flatNodes.findIndex((n) => selectedIds.includes(n.id))\n\n switch (e.key) {\n case 'ArrowDown': {\n e.preventDefault()\n const nextIndex = currentIndex < flatNodes.length - 1 ? currentIndex + 1 : 0\n handleSelect(flatNodes[nextIndex].id, false)\n break\n }\n case 'ArrowUp': {\n e.preventDefault()\n const prevIndex = currentIndex > 0 ? currentIndex - 1 : flatNodes.length - 1\n handleSelect(flatNodes[prevIndex].id, false)\n break\n }\n case 'Home':\n e.preventDefault()\n if (flatNodes.length > 0) {\n handleSelect(flatNodes[0].id, false)\n }\n break\n case 'End':\n e.preventDefault()\n if (flatNodes.length > 0) {\n handleSelect(flatNodes[flatNodes.length - 1].id, false)\n }\n break\n }\n },\n [flatNodes, selectedIds, handleSelect]\n )\n\n return (\n <ul\n ref={ref}\n role=\"tree\"\n aria-label={ariaLabel}\n aria-multiselectable={multiSelect}\n tabIndex={0}\n className={cx('brycks-treeview', `brycks-treeview--${size}`, className)}\n data-testid={testId}\n onKeyDown={handleKeyDown}\n >\n {data.map((node) => (\n <TreeNodeItem\n key={node.id}\n node={node}\n level={0}\n config={config}\n isSelected={selectedIds.includes(node.id)}\n isExpanded={expandedIds.includes(node.id)}\n showLines={showLines}\n onToggle={handleToggle}\n onSelect={handleSelect}\n renderNode={renderNode}\n selectedIds={selectedIds}\n expandedIds={expandedIds}\n multiSelect={multiSelect}\n />\n ))}\n </ul>\n )\n})\n\nTreeView.displayName = 'TreeView'\n"],"names":["sizeConfig","fontSizes","iconSizes","componentPaddingY","spacing","ChevronIcon","expanded","jsx","durations","easings","TreeNodeItem","node","level","config","isSelected","isExpanded","showLines","onToggle","onSelect","renderNode","selectedIds","expandedIds","multiSelect","hasChildren","handleClick","useCallback","e","handleToggle","handleKeyDown","itemStyle","lineStyle","jsxs","cx","child","TreeView","forwardRef","data","controlledSelectedIds","defaultSelectedIds","controlledExpandedIds","defaultExpandedIds","onSelectionChange","onExpansionChange","onNodeClick","size","ariaLabel","className","testId","ref","internalSelectedIds","setInternalSelectedIds","useState","internalExpandedIds","setInternalExpandedIds","flatNodes","useMemo","flatten","nodes","result","id","newExpandedIds","eid","handleSelect","additive","n","newSelectedIds","sid","currentIndex","nextIndex","prevIndex"],"mappings":"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"}
@@ -1,17 +1,17 @@
1
- import { jsx as o, jsxs as V } from "react/jsx-runtime";
2
- import { forwardRef as q, useState as O, useMemo as F, useCallback as w } from "react";
3
- import { cx as G } from "../../../utils/styles.js";
4
- import { spacing as h } from "../../../design-system/tokens/spacing.js";
5
- import { componentPaddingY as M, iconSizes as L } from "../../../design-system/primitives/sizing.js";
6
- import { fontSizes as R } from "../../../design-system/tokens/typography.js";
7
- import { durations as P, easings as B } from "../../../design-system/tokens/motion.js";
8
- const J = {
9
- sm: { fontSize: R.sm, iconSize: L.xs, padding: M.xs, indent: h[4] },
10
- md: { fontSize: R.base, iconSize: L.sm, padding: M.sm, indent: h[5] },
11
- lg: { fontSize: R.md, iconSize: L.md, padding: M.md, indent: h[6] }
1
+ import { jsx as l, jsxs as T } from "react/jsx-runtime";
2
+ import { forwardRef as U, useState as V, useMemo as W, useCallback as v } from "react";
3
+ import { cx as $ } from "../../../utils/styles.js";
4
+ import { spacing as _ } from "../../../design-system/tokens/spacing.js";
5
+ import { componentPaddingY as A, iconSizes as j } from "../../../design-system/primitives/sizing.js";
6
+ import { fontSizes as L } from "../../../design-system/tokens/typography.js";
7
+ import { durations as Y, easings as q } from "../../../design-system/tokens/motion.js";
8
+ const F = {
9
+ sm: { fontSize: L.sm, iconSize: j.xs, padding: A.xs, indent: _[4] },
10
+ md: { fontSize: L.base, iconSize: j.sm, padding: A.sm, indent: _[5] },
11
+ lg: { fontSize: L.md, iconSize: j.md, padding: A.md, indent: _[6] }
12
12
  };
13
- function Q({ expanded: e }) {
14
- return /* @__PURE__ */ o(
13
+ function G({ expanded: e }) {
14
+ return /* @__PURE__ */ l(
15
15
  "svg",
16
16
  {
17
17
  width: "16",
@@ -21,236 +21,195 @@ function Q({ expanded: e }) {
21
21
  "aria-hidden": "true",
22
22
  style: {
23
23
  transform: e ? "rotate(90deg)" : "rotate(0)",
24
- transition: `transform ${P.fast}ms ${B.easeOut}`
24
+ transition: `transform ${Y.fast}ms ${q.easeOut}`
25
25
  },
26
- children: /* @__PURE__ */ o("path", { d: "M6 4l4 4-4 4", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })
26
+ children: /* @__PURE__ */ l("path", { d: "M6 4l4 4-4 4", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })
27
27
  }
28
28
  );
29
29
  }
30
- function H({
30
+ function M({
31
31
  node: e,
32
- level: f,
33
- config: i,
34
- isSelected: m,
35
- isExpanded: s,
32
+ level: u,
33
+ config: f,
34
+ isSelected: y,
35
+ isExpanded: n,
36
36
  showLines: x,
37
- onToggle: u,
38
- onSelect: y,
39
- renderNode: g,
40
- selectedIds: k,
41
- expandedIds: S,
42
- multiSelect: z
37
+ onToggle: o,
38
+ onSelect: h,
39
+ renderNode: w,
40
+ selectedIds: b,
41
+ expandedIds: g,
42
+ multiSelect: D
43
43
  }) {
44
- const d = e.children && e.children.length > 0, I = w(
45
- (r) => {
46
- e.disabled || y(e.id, r.ctrlKey || r.metaKey);
44
+ const c = e.children && e.children.length > 0, I = v(
45
+ (t) => {
46
+ e.disabled || h(e.id, t.ctrlKey || t.metaKey);
47
47
  },
48
- [e.id, e.disabled, y]
49
- ), D = w(
50
- (r) => {
51
- r.stopPropagation(), d && u(e.id);
48
+ [e.id, e.disabled, h]
49
+ ), z = v(
50
+ (t) => {
51
+ t.stopPropagation(), c && o(e.id);
52
52
  },
53
- [e.id, d, u]
54
- ), C = w(
55
- (r) => {
53
+ [e.id, c, o]
54
+ ), K = v(
55
+ (t) => {
56
56
  if (!e.disabled)
57
- switch (r.key) {
57
+ switch (t.key) {
58
58
  case "Enter":
59
59
  case " ":
60
- r.preventDefault(), y(e.id, r.ctrlKey || r.metaKey);
60
+ t.preventDefault(), h(e.id, t.ctrlKey || t.metaKey);
61
61
  break;
62
62
  case "ArrowRight":
63
- r.preventDefault(), d && !s && u(e.id);
63
+ t.preventDefault(), c && !n && o(e.id);
64
64
  break;
65
65
  case "ArrowLeft":
66
- r.preventDefault(), d && s && u(e.id);
66
+ t.preventDefault(), c && n && o(e.id);
67
67
  break;
68
68
  }
69
69
  },
70
- [e.id, e.disabled, d, s, u, y]
71
- ), K = {
72
- display: "flex",
73
- alignItems: "center",
74
- gap: h[1.5],
75
- padding: `${i.padding}px ${h[2]}px`,
76
- paddingLeft: h[2] + f * i.indent,
77
- fontSize: i.fontSize,
78
- color: e.disabled ? "var(--brycks-foreground-disabled)" : "var(--brycks-foreground-default)",
79
- backgroundColor: m ? "var(--brycks-primary-muted)" : "transparent",
80
- borderRadius: "var(--brycks-radius-md)",
81
- cursor: e.disabled ? "not-allowed" : "pointer",
82
- userSelect: "none",
83
- transition: `background-color ${P.fast}ms ${B.easeOut}`,
84
- position: "relative"
85
- }, $ = {
86
- display: "flex",
87
- alignItems: "center",
88
- justifyContent: "center",
89
- width: i.iconSize,
90
- height: i.iconSize,
91
- color: "var(--brycks-foreground-muted)",
92
- cursor: "pointer",
93
- flexShrink: 0
94
- }, j = {
95
- display: "flex",
96
- alignItems: "center",
97
- justifyContent: "center",
98
- width: i.iconSize,
99
- height: i.iconSize,
100
- color: m ? "var(--brycks-primary-default)" : "var(--brycks-foreground-muted)",
101
- flexShrink: 0
102
- }, T = x && f > 0 ? {
103
- position: "absolute",
104
- left: h[2] + (f - 1) * i.indent + i.iconSize / 2,
105
- top: 0,
106
- bottom: 0,
107
- width: 1,
108
- backgroundColor: "var(--brycks-border-default)"
109
- } : {};
110
- return /* @__PURE__ */ V("li", { role: "treeitem", "aria-selected": m, "aria-expanded": d ? s : void 0, children: [
111
- /* @__PURE__ */ V(
70
+ [e.id, e.disabled, c, n, o, h]
71
+ ), N = {
72
+ paddingLeft: _[2] + u * f.indent
73
+ }, S = {
74
+ left: _[2] + (u - 1) * f.indent + f.iconSize / 2
75
+ };
76
+ return /* @__PURE__ */ T("li", { role: "treeitem", "aria-selected": y, "aria-expanded": c ? n : void 0, children: [
77
+ /* @__PURE__ */ T(
112
78
  "div",
113
79
  {
114
80
  tabIndex: e.disabled ? -1 : 0,
115
- style: K,
81
+ className: $(
82
+ "brycks-treeview__item",
83
+ y && "brycks-treeview__item--selected",
84
+ e.disabled && "brycks-treeview__item--disabled"
85
+ ),
86
+ style: N,
116
87
  onClick: I,
117
- onKeyDown: C,
118
- onMouseEnter: (r) => {
119
- !e.disabled && !m && (r.currentTarget.style.backgroundColor = "var(--brycks-background-muted)");
120
- },
121
- onMouseLeave: (r) => {
122
- m || (r.currentTarget.style.backgroundColor = "transparent");
123
- },
88
+ onKeyDown: K,
124
89
  children: [
125
- x && f > 0 && /* @__PURE__ */ o("span", { style: T, "aria-hidden": "true" }),
126
- /* @__PURE__ */ o("span", { style: $, onClick: D, children: d && /* @__PURE__ */ o(Q, { expanded: s }) }),
127
- e.icon && /* @__PURE__ */ o("span", { style: j, children: e.icon }),
128
- g ? g(e, m, s) : /* @__PURE__ */ o("span", { style: { flex: 1 }, children: e.label })
90
+ x && u > 0 && /* @__PURE__ */ l("span", { className: "brycks-treeview__line", style: S, "aria-hidden": "true" }),
91
+ /* @__PURE__ */ l("span", { className: "brycks-treeview__toggle", onClick: z, children: c && /* @__PURE__ */ l(G, { expanded: n }) }),
92
+ e.icon && /* @__PURE__ */ l("span", { className: "brycks-treeview__icon", children: e.icon }),
93
+ w ? w(e, y, n) : /* @__PURE__ */ l("span", { className: "brycks-treeview__label", children: e.label })
129
94
  ]
130
95
  }
131
96
  ),
132
- d && s && /* @__PURE__ */ o("ul", { role: "group", style: { listStyle: "none", margin: 0, padding: 0 }, children: e.children.map((r) => /* @__PURE__ */ o(
133
- H,
97
+ c && n && /* @__PURE__ */ l("ul", { role: "group", className: "brycks-treeview__group", children: e.children.map((t) => /* @__PURE__ */ l(
98
+ M,
134
99
  {
135
- node: r,
136
- level: f + 1,
137
- config: i,
138
- isSelected: k.includes(r.id),
139
- isExpanded: S.includes(r.id),
100
+ node: t,
101
+ level: u + 1,
102
+ config: f,
103
+ isSelected: b.includes(t.id),
104
+ isExpanded: g.includes(t.id),
140
105
  showLines: x,
141
- onToggle: u,
142
- onSelect: y,
143
- renderNode: g,
144
- selectedIds: k,
145
- expandedIds: S,
146
- multiSelect: z
106
+ onToggle: o,
107
+ onSelect: h,
108
+ renderNode: w,
109
+ selectedIds: b,
110
+ expandedIds: g,
111
+ multiSelect: D
147
112
  },
148
- r.id
113
+ t.id
149
114
  )) })
150
115
  ] });
151
116
  }
152
- const X = q(function({
153
- data: f,
154
- selectedIds: i,
155
- defaultSelectedIds: m = [],
156
- expandedIds: s,
117
+ const J = U(function({
118
+ data: u,
119
+ selectedIds: f,
120
+ defaultSelectedIds: y = [],
121
+ expandedIds: n,
157
122
  defaultExpandedIds: x = [],
158
- onSelectionChange: u,
159
- onExpansionChange: y,
160
- onNodeClick: g,
161
- multiSelect: k = !1,
162
- size: S = "md",
163
- showLines: z = !1,
164
- renderNode: d,
123
+ onSelectionChange: o,
124
+ onExpansionChange: h,
125
+ onNodeClick: w,
126
+ multiSelect: b = !1,
127
+ size: g = "md",
128
+ showLines: D = !1,
129
+ renderNode: c,
165
130
  "aria-label": I = "Tree",
166
- className: D,
167
- testId: C
168
- }, K) {
169
- const [$, j] = O(m), [T, r] = O(x), c = i !== void 0 ? i : $, b = s !== void 0 ? s : T, N = J[S], a = F(() => {
170
- const t = (l, n = []) => (l.forEach((p) => {
171
- n.push(p), p.children && b.includes(p.id) && t(p.children, n);
172
- }), n);
173
- return t(f);
174
- }, [f, b]), U = w(
175
- (t) => {
176
- const l = b.includes(t) ? b.filter((n) => n !== t) : [...b, t];
177
- s === void 0 && r(l), y?.(l);
131
+ className: z,
132
+ testId: K
133
+ }, N) {
134
+ const [S, t] = V(y), [P, R] = V(x), d = f !== void 0 ? f : S, p = n !== void 0 ? n : P, B = F[g], s = W(() => {
135
+ const i = (a, r = []) => (a.forEach((m) => {
136
+ r.push(m), m.children && p.includes(m.id) && i(m.children, r);
137
+ }), r);
138
+ return i(u);
139
+ }, [u, p]), H = v(
140
+ (i) => {
141
+ const a = p.includes(i) ? p.filter((r) => r !== i) : [...p, i];
142
+ n === void 0 && R(a), h?.(a);
178
143
  },
179
- [b, s, y]
180
- ), v = w(
181
- (t, l) => {
182
- const n = a.find((A) => A.id === t);
183
- n && g?.(n);
184
- let p;
185
- k && l ? p = c.includes(t) ? c.filter((A) => A !== t) : [...c, t] : p = c.includes(t) && c.length === 1 ? [] : [t], i === void 0 && j(p), u?.(p);
144
+ [p, n, h]
145
+ ), k = v(
146
+ (i, a) => {
147
+ const r = s.find((C) => C.id === i);
148
+ r && w?.(r);
149
+ let m;
150
+ b && a ? m = d.includes(i) ? d.filter((C) => C !== i) : [...d, i] : m = d.includes(i) && d.length === 1 ? [] : [i], f === void 0 && t(m), o?.(m);
186
151
  },
187
- [a, k, c, i, u, g]
188
- ), W = w(
189
- (t) => {
190
- const l = a.findIndex((n) => c.includes(n.id));
191
- switch (t.key) {
152
+ [s, b, d, f, o, w]
153
+ ), O = v(
154
+ (i) => {
155
+ const a = s.findIndex((r) => d.includes(r.id));
156
+ switch (i.key) {
192
157
  case "ArrowDown": {
193
- t.preventDefault();
194
- const n = l < a.length - 1 ? l + 1 : 0;
195
- v(a[n].id, !1);
158
+ i.preventDefault();
159
+ const r = a < s.length - 1 ? a + 1 : 0;
160
+ k(s[r].id, !1);
196
161
  break;
197
162
  }
198
163
  case "ArrowUp": {
199
- t.preventDefault();
200
- const n = l > 0 ? l - 1 : a.length - 1;
201
- v(a[n].id, !1);
164
+ i.preventDefault();
165
+ const r = a > 0 ? a - 1 : s.length - 1;
166
+ k(s[r].id, !1);
202
167
  break;
203
168
  }
204
169
  case "Home":
205
- t.preventDefault(), a.length > 0 && v(a[0].id, !1);
170
+ i.preventDefault(), s.length > 0 && k(s[0].id, !1);
206
171
  break;
207
172
  case "End":
208
- t.preventDefault(), a.length > 0 && v(a[a.length - 1].id, !1);
173
+ i.preventDefault(), s.length > 0 && k(s[s.length - 1].id, !1);
209
174
  break;
210
175
  }
211
176
  },
212
- [a, c, v]
213
- ), Y = {
214
- listStyle: "none",
215
- margin: 0,
216
- padding: h[1],
217
- outline: "none"
218
- };
219
- return /* @__PURE__ */ o(
177
+ [s, d, k]
178
+ );
179
+ return /* @__PURE__ */ l(
220
180
  "ul",
221
181
  {
222
- ref: K,
182
+ ref: N,
223
183
  role: "tree",
224
184
  "aria-label": I,
225
- "aria-multiselectable": k,
185
+ "aria-multiselectable": b,
226
186
  tabIndex: 0,
227
- className: G("brycks-treeview", `brycks-treeview--${S}`, D),
228
- style: Y,
229
- "data-testid": C,
230
- onKeyDown: W,
231
- children: f.map((t) => /* @__PURE__ */ o(
232
- H,
187
+ className: $("brycks-treeview", `brycks-treeview--${g}`, z),
188
+ "data-testid": K,
189
+ onKeyDown: O,
190
+ children: u.map((i) => /* @__PURE__ */ l(
191
+ M,
233
192
  {
234
- node: t,
193
+ node: i,
235
194
  level: 0,
236
- config: N,
237
- isSelected: c.includes(t.id),
238
- isExpanded: b.includes(t.id),
239
- showLines: z,
240
- onToggle: U,
241
- onSelect: v,
242
- renderNode: d,
243
- selectedIds: c,
244
- expandedIds: b,
245
- multiSelect: k
195
+ config: B,
196
+ isSelected: d.includes(i.id),
197
+ isExpanded: p.includes(i.id),
198
+ showLines: D,
199
+ onToggle: H,
200
+ onSelect: k,
201
+ renderNode: c,
202
+ selectedIds: d,
203
+ expandedIds: p,
204
+ multiSelect: b
246
205
  },
247
- t.id
206
+ i.id
248
207
  ))
249
208
  }
250
209
  );
251
210
  });
252
- X.displayName = "TreeView";
211
+ J.displayName = "TreeView";
253
212
  export {
254
- X as TreeView
213
+ J as TreeView
255
214
  };
256
215
  //# sourceMappingURL=TreeView.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TreeView.js","sources":["../../../../src/components/data/TreeView/TreeView.tsx"],"sourcesContent":["/**\n * TreeView Component\n *\n * A hierarchical tree structure for displaying nested data.\n * Supports selection, expansion, and keyboard navigation.\n *\n * @module components/data/TreeView\n */\n\nimport {\n forwardRef,\n useState,\n useCallback,\n useMemo,\n type CSSProperties,\n type ReactNode,\n type KeyboardEvent,\n} from 'react'\nimport { cx } from '../../../utils/styles'\nimport { spacing, fontSizes, durations, easings } from '../../../design-system'\nimport { componentPaddingY, iconSizes } from '../../../design-system/primitives'\n\nexport interface TreeNode {\n /** Unique identifier */\n id: string\n /** Display label */\n label: string\n /** Optional icon */\n icon?: ReactNode\n /** Child nodes */\n children?: TreeNode[]\n /** Whether the node is disabled */\n disabled?: boolean\n /** Additional data */\n data?: unknown\n}\n\nexport type TreeViewSize = 'sm' | 'md' | 'lg'\n\nexport interface TreeViewProps {\n /** Tree data */\n data: TreeNode[]\n /** Selected node IDs (controlled) */\n selectedIds?: string[]\n /** Default selected node IDs (uncontrolled) */\n defaultSelectedIds?: string[]\n /** Expanded node IDs (controlled) */\n expandedIds?: string[]\n /** Default expanded node IDs (uncontrolled) */\n defaultExpandedIds?: string[]\n /** Callback when selection changes */\n onSelectionChange?: (selectedIds: string[]) => void\n /** Callback when expansion changes */\n onExpansionChange?: (expandedIds: string[]) => void\n /** Callback when a node is clicked */\n onNodeClick?: (node: TreeNode) => void\n /** Whether to allow multi-selection */\n multiSelect?: boolean\n /** Component size */\n size?: TreeViewSize\n /** Whether to show connecting lines */\n showLines?: boolean\n /** Custom node renderer */\n renderNode?: (node: TreeNode, isSelected: boolean, isExpanded: boolean) => ReactNode\n /** Label for accessibility */\n 'aria-label'?: string\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nconst sizeConfig: Record<TreeViewSize, { fontSize: number; iconSize: number; padding: number; indent: number }> = {\n sm: { fontSize: fontSizes.sm, iconSize: iconSizes.xs, padding: componentPaddingY.xs, indent: spacing[4] },\n md: { fontSize: fontSizes.base, iconSize: iconSizes.sm, padding: componentPaddingY.sm, indent: spacing[5] },\n lg: { fontSize: fontSizes.md, iconSize: iconSizes.md, padding: componentPaddingY.md, indent: spacing[6] },\n}\n\nfunction ChevronIcon({ expanded }: { expanded: boolean }) {\n return (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n aria-hidden=\"true\"\n style={{\n transform: expanded ? 'rotate(90deg)' : 'rotate(0)',\n transition: `transform ${durations.fast}ms ${easings.easeOut}`,\n }}\n >\n <path d=\"M6 4l4 4-4 4\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n )\n}\n\ninterface TreeNodeItemProps {\n node: TreeNode\n level: number\n config: typeof sizeConfig.md\n isSelected: boolean\n isExpanded: boolean\n showLines: boolean\n onToggle: (id: string) => void\n onSelect: (id: string, multi: boolean) => void\n renderNode?: TreeViewProps['renderNode']\n selectedIds: string[]\n expandedIds: string[]\n multiSelect: boolean\n}\n\nfunction TreeNodeItem({\n node,\n level,\n config,\n isSelected,\n isExpanded,\n showLines,\n onToggle,\n onSelect,\n renderNode,\n selectedIds,\n expandedIds,\n multiSelect,\n}: TreeNodeItemProps) {\n const hasChildren = node.children && node.children.length > 0\n\n const handleClick = useCallback(\n (e: React.MouseEvent) => {\n if (node.disabled) return\n onSelect(node.id, e.ctrlKey || e.metaKey)\n },\n [node.id, node.disabled, onSelect]\n )\n\n const handleToggle = useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation()\n if (hasChildren) {\n onToggle(node.id)\n }\n },\n [node.id, hasChildren, onToggle]\n )\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLDivElement>) => {\n if (node.disabled) return\n\n switch (e.key) {\n case 'Enter':\n case ' ':\n e.preventDefault()\n onSelect(node.id, e.ctrlKey || e.metaKey)\n break\n case 'ArrowRight':\n e.preventDefault()\n if (hasChildren && !isExpanded) {\n onToggle(node.id)\n }\n break\n case 'ArrowLeft':\n e.preventDefault()\n if (hasChildren && isExpanded) {\n onToggle(node.id)\n }\n break\n }\n },\n [node.id, node.disabled, hasChildren, isExpanded, onToggle, onSelect]\n )\n\n const itemStyle: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n gap: spacing[1.5],\n padding: `${config.padding}px ${spacing[2]}px`,\n paddingLeft: spacing[2] + level * config.indent,\n fontSize: config.fontSize,\n color: node.disabled ? 'var(--brycks-foreground-disabled)' : 'var(--brycks-foreground-default)',\n backgroundColor: isSelected ? 'var(--brycks-primary-muted)' : 'transparent',\n borderRadius: 'var(--brycks-radius-md)',\n cursor: node.disabled ? 'not-allowed' : 'pointer',\n userSelect: 'none',\n transition: `background-color ${durations.fast}ms ${easings.easeOut}`,\n position: 'relative',\n }\n\n const toggleStyle: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: config.iconSize,\n height: config.iconSize,\n color: 'var(--brycks-foreground-muted)',\n cursor: 'pointer',\n flexShrink: 0,\n }\n\n const iconStyle: CSSProperties = {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: config.iconSize,\n height: config.iconSize,\n color: isSelected ? 'var(--brycks-primary-default)' : 'var(--brycks-foreground-muted)',\n flexShrink: 0,\n }\n\n const lineStyle: CSSProperties = showLines && level > 0 ? {\n position: 'absolute',\n left: spacing[2] + (level - 1) * config.indent + config.iconSize / 2,\n top: 0,\n bottom: 0,\n width: 1,\n backgroundColor: 'var(--brycks-border-default)',\n } : {}\n\n return (\n <li role=\"treeitem\" aria-selected={isSelected} aria-expanded={hasChildren ? isExpanded : undefined}>\n <div\n tabIndex={node.disabled ? -1 : 0}\n style={itemStyle}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n onMouseEnter={(e) => {\n if (!node.disabled && !isSelected) {\n e.currentTarget.style.backgroundColor = 'var(--brycks-background-muted)'\n }\n }}\n onMouseLeave={(e) => {\n if (!isSelected) {\n e.currentTarget.style.backgroundColor = 'transparent'\n }\n }}\n >\n {showLines && level > 0 && <span style={lineStyle} aria-hidden=\"true\" />}\n <span style={toggleStyle} onClick={handleToggle}>\n {hasChildren && <ChevronIcon expanded={isExpanded} />}\n </span>\n {node.icon && <span style={iconStyle}>{node.icon}</span>}\n {renderNode ? (\n renderNode(node, isSelected, isExpanded)\n ) : (\n <span style={{ flex: 1 }}>{node.label}</span>\n )}\n </div>\n {hasChildren && isExpanded && (\n <ul role=\"group\" style={{ listStyle: 'none', margin: 0, padding: 0 }}>\n {node.children!.map((child) => (\n <TreeNodeItem\n key={child.id}\n node={child}\n level={level + 1}\n config={config}\n isSelected={selectedIds.includes(child.id)}\n isExpanded={expandedIds.includes(child.id)}\n showLines={showLines}\n onToggle={onToggle}\n onSelect={onSelect}\n renderNode={renderNode}\n selectedIds={selectedIds}\n expandedIds={expandedIds}\n multiSelect={multiSelect}\n />\n ))}\n </ul>\n )}\n </li>\n )\n}\n\nexport const TreeView = forwardRef<HTMLUListElement, TreeViewProps>(function TreeView(\n {\n data,\n selectedIds: controlledSelectedIds,\n defaultSelectedIds = [],\n expandedIds: controlledExpandedIds,\n defaultExpandedIds = [],\n onSelectionChange,\n onExpansionChange,\n onNodeClick,\n multiSelect = false,\n size = 'md',\n showLines = false,\n renderNode,\n 'aria-label': ariaLabel = 'Tree',\n className,\n testId,\n },\n ref\n) {\n const [internalSelectedIds, setInternalSelectedIds] = useState<string[]>(defaultSelectedIds)\n const [internalExpandedIds, setInternalExpandedIds] = useState<string[]>(defaultExpandedIds)\n\n const selectedIds = controlledSelectedIds !== undefined ? controlledSelectedIds : internalSelectedIds\n const expandedIds = controlledExpandedIds !== undefined ? controlledExpandedIds : internalExpandedIds\n const config = sizeConfig[size]\n\n // Flatten all nodes for keyboard navigation\n const flatNodes = useMemo(() => {\n const flatten = (nodes: TreeNode[], result: TreeNode[] = []): TreeNode[] => {\n nodes.forEach((node) => {\n result.push(node)\n if (node.children && expandedIds.includes(node.id)) {\n flatten(node.children, result)\n }\n })\n return result\n }\n return flatten(data)\n }, [data, expandedIds])\n\n const handleToggle = useCallback(\n (id: string) => {\n const newExpandedIds = expandedIds.includes(id)\n ? expandedIds.filter((eid) => eid !== id)\n : [...expandedIds, id]\n\n if (controlledExpandedIds === undefined) {\n setInternalExpandedIds(newExpandedIds)\n }\n onExpansionChange?.(newExpandedIds)\n },\n [expandedIds, controlledExpandedIds, onExpansionChange]\n )\n\n const handleSelect = useCallback(\n (id: string, additive: boolean) => {\n const node = flatNodes.find((n) => n.id === id)\n if (node) {\n onNodeClick?.(node)\n }\n\n let newSelectedIds: string[]\n if (multiSelect && additive) {\n newSelectedIds = selectedIds.includes(id)\n ? selectedIds.filter((sid) => sid !== id)\n : [...selectedIds, id]\n } else {\n newSelectedIds = selectedIds.includes(id) && selectedIds.length === 1 ? [] : [id]\n }\n\n if (controlledSelectedIds === undefined) {\n setInternalSelectedIds(newSelectedIds)\n }\n onSelectionChange?.(newSelectedIds)\n },\n [flatNodes, multiSelect, selectedIds, controlledSelectedIds, onSelectionChange, onNodeClick]\n )\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLUListElement>) => {\n const currentIndex = flatNodes.findIndex((n) => selectedIds.includes(n.id))\n\n switch (e.key) {\n case 'ArrowDown': {\n e.preventDefault()\n const nextIndex = currentIndex < flatNodes.length - 1 ? currentIndex + 1 : 0\n handleSelect(flatNodes[nextIndex].id, false)\n break\n }\n case 'ArrowUp': {\n e.preventDefault()\n const prevIndex = currentIndex > 0 ? currentIndex - 1 : flatNodes.length - 1\n handleSelect(flatNodes[prevIndex].id, false)\n break\n }\n case 'Home':\n e.preventDefault()\n if (flatNodes.length > 0) {\n handleSelect(flatNodes[0].id, false)\n }\n break\n case 'End':\n e.preventDefault()\n if (flatNodes.length > 0) {\n handleSelect(flatNodes[flatNodes.length - 1].id, false)\n }\n break\n }\n },\n [flatNodes, selectedIds, handleSelect]\n )\n\n const containerStyle: CSSProperties = {\n listStyle: 'none',\n margin: 0,\n padding: spacing[1],\n outline: 'none',\n }\n\n return (\n <ul\n ref={ref}\n role=\"tree\"\n aria-label={ariaLabel}\n aria-multiselectable={multiSelect}\n tabIndex={0}\n className={cx('brycks-treeview', `brycks-treeview--${size}`, className)}\n style={containerStyle}\n data-testid={testId}\n onKeyDown={handleKeyDown}\n >\n {data.map((node) => (\n <TreeNodeItem\n key={node.id}\n node={node}\n level={0}\n config={config}\n isSelected={selectedIds.includes(node.id)}\n isExpanded={expandedIds.includes(node.id)}\n showLines={showLines}\n onToggle={handleToggle}\n onSelect={handleSelect}\n renderNode={renderNode}\n selectedIds={selectedIds}\n expandedIds={expandedIds}\n multiSelect={multiSelect}\n />\n ))}\n </ul>\n )\n})\n\nTreeView.displayName = 'TreeView'\n"],"names":["sizeConfig","fontSizes","iconSizes","componentPaddingY","spacing","ChevronIcon","expanded","jsx","durations","easings","TreeNodeItem","node","level","config","isSelected","isExpanded","showLines","onToggle","onSelect","renderNode","selectedIds","expandedIds","multiSelect","hasChildren","handleClick","useCallback","e","handleToggle","handleKeyDown","itemStyle","toggleStyle","iconStyle","lineStyle","jsxs","child","TreeView","forwardRef","data","controlledSelectedIds","defaultSelectedIds","controlledExpandedIds","defaultExpandedIds","onSelectionChange","onExpansionChange","onNodeClick","size","ariaLabel","className","testId","ref","internalSelectedIds","setInternalSelectedIds","useState","internalExpandedIds","setInternalExpandedIds","flatNodes","useMemo","flatten","nodes","result","id","newExpandedIds","eid","handleSelect","additive","n","newSelectedIds","sid","currentIndex","nextIndex","prevIndex","containerStyle","cx"],"mappings":"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"}
1
+ {"version":3,"file":"TreeView.js","sources":["../../../../src/components/data/TreeView/TreeView.tsx"],"sourcesContent":["/**\n * TreeView Component\n *\n * A hierarchical tree structure for displaying nested data.\n * Supports selection, expansion, and keyboard navigation.\n *\n * @module components/data/TreeView\n */\n\nimport {\n forwardRef,\n useState,\n useCallback,\n useMemo,\n type CSSProperties,\n type ReactNode,\n type KeyboardEvent,\n} from 'react'\nimport { cx } from '../../../utils/styles'\nimport { spacing, fontSizes, durations, easings } from '../../../design-system'\nimport { componentPaddingY, iconSizes } from '../../../design-system/primitives'\n\nexport interface TreeNode {\n /** Unique identifier */\n id: string\n /** Display label */\n label: string\n /** Optional icon */\n icon?: ReactNode\n /** Child nodes */\n children?: TreeNode[]\n /** Whether the node is disabled */\n disabled?: boolean\n /** Additional data */\n data?: unknown\n}\n\nexport type TreeViewSize = 'sm' | 'md' | 'lg'\n\nexport interface TreeViewProps {\n /** Tree data */\n data: TreeNode[]\n /** Selected node IDs (controlled) */\n selectedIds?: string[]\n /** Default selected node IDs (uncontrolled) */\n defaultSelectedIds?: string[]\n /** Expanded node IDs (controlled) */\n expandedIds?: string[]\n /** Default expanded node IDs (uncontrolled) */\n defaultExpandedIds?: string[]\n /** Callback when selection changes */\n onSelectionChange?: (selectedIds: string[]) => void\n /** Callback when expansion changes */\n onExpansionChange?: (expandedIds: string[]) => void\n /** Callback when a node is clicked */\n onNodeClick?: (node: TreeNode) => void\n /** Whether to allow multi-selection */\n multiSelect?: boolean\n /** Component size */\n size?: TreeViewSize\n /** Whether to show connecting lines */\n showLines?: boolean\n /** Custom node renderer */\n renderNode?: (node: TreeNode, isSelected: boolean, isExpanded: boolean) => ReactNode\n /** Label for accessibility */\n 'aria-label'?: string\n /** Custom class name */\n className?: string\n /** Test ID */\n testId?: string\n}\n\nconst sizeConfig: Record<TreeViewSize, { fontSize: number; iconSize: number; padding: number; indent: number }> = {\n sm: { fontSize: fontSizes.sm, iconSize: iconSizes.xs, padding: componentPaddingY.xs, indent: spacing[4] },\n md: { fontSize: fontSizes.base, iconSize: iconSizes.sm, padding: componentPaddingY.sm, indent: spacing[5] },\n lg: { fontSize: fontSizes.md, iconSize: iconSizes.md, padding: componentPaddingY.md, indent: spacing[6] },\n}\n\nfunction ChevronIcon({ expanded }: { expanded: boolean }) {\n return (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n aria-hidden=\"true\"\n style={{\n transform: expanded ? 'rotate(90deg)' : 'rotate(0)',\n transition: `transform ${durations.fast}ms ${easings.easeOut}`,\n }}\n >\n <path d=\"M6 4l4 4-4 4\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n )\n}\n\ninterface TreeNodeItemProps {\n node: TreeNode\n level: number\n config: typeof sizeConfig.md\n isSelected: boolean\n isExpanded: boolean\n showLines: boolean\n onToggle: (id: string) => void\n onSelect: (id: string, multi: boolean) => void\n renderNode?: TreeViewProps['renderNode']\n selectedIds: string[]\n expandedIds: string[]\n multiSelect: boolean\n}\n\nfunction TreeNodeItem({\n node,\n level,\n config,\n isSelected,\n isExpanded,\n showLines,\n onToggle,\n onSelect,\n renderNode,\n selectedIds,\n expandedIds,\n multiSelect,\n}: TreeNodeItemProps) {\n const hasChildren = node.children && node.children.length > 0\n\n const handleClick = useCallback(\n (e: React.MouseEvent) => {\n if (node.disabled) return\n onSelect(node.id, e.ctrlKey || e.metaKey)\n },\n [node.id, node.disabled, onSelect]\n )\n\n const handleToggle = useCallback(\n (e: React.MouseEvent) => {\n e.stopPropagation()\n if (hasChildren) {\n onToggle(node.id)\n }\n },\n [node.id, hasChildren, onToggle]\n )\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLDivElement>) => {\n if (node.disabled) return\n\n switch (e.key) {\n case 'Enter':\n case ' ':\n e.preventDefault()\n onSelect(node.id, e.ctrlKey || e.metaKey)\n break\n case 'ArrowRight':\n e.preventDefault()\n if (hasChildren && !isExpanded) {\n onToggle(node.id)\n }\n break\n case 'ArrowLeft':\n e.preventDefault()\n if (hasChildren && isExpanded) {\n onToggle(node.id)\n }\n break\n }\n },\n [node.id, node.disabled, hasChildren, isExpanded, onToggle, onSelect]\n )\n\n // Only the depth-based horizontal offset is dynamic (computed from `level`\n // and the per-size indent); everything else is class-driven.\n const itemStyle: CSSProperties = {\n paddingLeft: spacing[2] + level * config.indent,\n }\n\n // Connecting line offset is also depth-based.\n const lineStyle: CSSProperties = {\n left: spacing[2] + (level - 1) * config.indent + config.iconSize / 2,\n }\n\n return (\n <li role=\"treeitem\" aria-selected={isSelected} aria-expanded={hasChildren ? isExpanded : undefined}>\n <div\n tabIndex={node.disabled ? -1 : 0}\n className={cx(\n 'brycks-treeview__item',\n isSelected && 'brycks-treeview__item--selected',\n node.disabled && 'brycks-treeview__item--disabled'\n )}\n style={itemStyle}\n onClick={handleClick}\n onKeyDown={handleKeyDown}\n >\n {showLines && level > 0 && (\n <span className=\"brycks-treeview__line\" style={lineStyle} aria-hidden=\"true\" />\n )}\n <span className=\"brycks-treeview__toggle\" onClick={handleToggle}>\n {hasChildren && <ChevronIcon expanded={isExpanded} />}\n </span>\n {node.icon && <span className=\"brycks-treeview__icon\">{node.icon}</span>}\n {renderNode ? (\n renderNode(node, isSelected, isExpanded)\n ) : (\n <span className=\"brycks-treeview__label\">{node.label}</span>\n )}\n </div>\n {hasChildren && isExpanded && (\n <ul role=\"group\" className=\"brycks-treeview__group\">\n {node.children!.map((child) => (\n <TreeNodeItem\n key={child.id}\n node={child}\n level={level + 1}\n config={config}\n isSelected={selectedIds.includes(child.id)}\n isExpanded={expandedIds.includes(child.id)}\n showLines={showLines}\n onToggle={onToggle}\n onSelect={onSelect}\n renderNode={renderNode}\n selectedIds={selectedIds}\n expandedIds={expandedIds}\n multiSelect={multiSelect}\n />\n ))}\n </ul>\n )}\n </li>\n )\n}\n\nexport const TreeView = forwardRef<HTMLUListElement, TreeViewProps>(function TreeView(\n {\n data,\n selectedIds: controlledSelectedIds,\n defaultSelectedIds = [],\n expandedIds: controlledExpandedIds,\n defaultExpandedIds = [],\n onSelectionChange,\n onExpansionChange,\n onNodeClick,\n multiSelect = false,\n size = 'md',\n showLines = false,\n renderNode,\n 'aria-label': ariaLabel = 'Tree',\n className,\n testId,\n },\n ref\n) {\n const [internalSelectedIds, setInternalSelectedIds] = useState<string[]>(defaultSelectedIds)\n const [internalExpandedIds, setInternalExpandedIds] = useState<string[]>(defaultExpandedIds)\n\n const selectedIds = controlledSelectedIds !== undefined ? controlledSelectedIds : internalSelectedIds\n const expandedIds = controlledExpandedIds !== undefined ? controlledExpandedIds : internalExpandedIds\n const config = sizeConfig[size]\n\n // Flatten all nodes for keyboard navigation\n const flatNodes = useMemo(() => {\n const flatten = (nodes: TreeNode[], result: TreeNode[] = []): TreeNode[] => {\n nodes.forEach((node) => {\n result.push(node)\n if (node.children && expandedIds.includes(node.id)) {\n flatten(node.children, result)\n }\n })\n return result\n }\n return flatten(data)\n }, [data, expandedIds])\n\n const handleToggle = useCallback(\n (id: string) => {\n const newExpandedIds = expandedIds.includes(id)\n ? expandedIds.filter((eid) => eid !== id)\n : [...expandedIds, id]\n\n if (controlledExpandedIds === undefined) {\n setInternalExpandedIds(newExpandedIds)\n }\n onExpansionChange?.(newExpandedIds)\n },\n [expandedIds, controlledExpandedIds, onExpansionChange]\n )\n\n const handleSelect = useCallback(\n (id: string, additive: boolean) => {\n const node = flatNodes.find((n) => n.id === id)\n if (node) {\n onNodeClick?.(node)\n }\n\n let newSelectedIds: string[]\n if (multiSelect && additive) {\n newSelectedIds = selectedIds.includes(id)\n ? selectedIds.filter((sid) => sid !== id)\n : [...selectedIds, id]\n } else {\n newSelectedIds = selectedIds.includes(id) && selectedIds.length === 1 ? [] : [id]\n }\n\n if (controlledSelectedIds === undefined) {\n setInternalSelectedIds(newSelectedIds)\n }\n onSelectionChange?.(newSelectedIds)\n },\n [flatNodes, multiSelect, selectedIds, controlledSelectedIds, onSelectionChange, onNodeClick]\n )\n\n const handleKeyDown = useCallback(\n (e: KeyboardEvent<HTMLUListElement>) => {\n const currentIndex = flatNodes.findIndex((n) => selectedIds.includes(n.id))\n\n switch (e.key) {\n case 'ArrowDown': {\n e.preventDefault()\n const nextIndex = currentIndex < flatNodes.length - 1 ? currentIndex + 1 : 0\n handleSelect(flatNodes[nextIndex].id, false)\n break\n }\n case 'ArrowUp': {\n e.preventDefault()\n const prevIndex = currentIndex > 0 ? currentIndex - 1 : flatNodes.length - 1\n handleSelect(flatNodes[prevIndex].id, false)\n break\n }\n case 'Home':\n e.preventDefault()\n if (flatNodes.length > 0) {\n handleSelect(flatNodes[0].id, false)\n }\n break\n case 'End':\n e.preventDefault()\n if (flatNodes.length > 0) {\n handleSelect(flatNodes[flatNodes.length - 1].id, false)\n }\n break\n }\n },\n [flatNodes, selectedIds, handleSelect]\n )\n\n return (\n <ul\n ref={ref}\n role=\"tree\"\n aria-label={ariaLabel}\n aria-multiselectable={multiSelect}\n tabIndex={0}\n className={cx('brycks-treeview', `brycks-treeview--${size}`, className)}\n data-testid={testId}\n onKeyDown={handleKeyDown}\n >\n {data.map((node) => (\n <TreeNodeItem\n key={node.id}\n node={node}\n level={0}\n config={config}\n isSelected={selectedIds.includes(node.id)}\n isExpanded={expandedIds.includes(node.id)}\n showLines={showLines}\n onToggle={handleToggle}\n onSelect={handleSelect}\n renderNode={renderNode}\n selectedIds={selectedIds}\n expandedIds={expandedIds}\n multiSelect={multiSelect}\n />\n ))}\n </ul>\n )\n})\n\nTreeView.displayName = 'TreeView'\n"],"names":["sizeConfig","fontSizes","iconSizes","componentPaddingY","spacing","ChevronIcon","expanded","jsx","durations","easings","TreeNodeItem","node","level","config","isSelected","isExpanded","showLines","onToggle","onSelect","renderNode","selectedIds","expandedIds","multiSelect","hasChildren","handleClick","useCallback","e","handleToggle","handleKeyDown","itemStyle","lineStyle","jsxs","cx","child","TreeView","forwardRef","data","controlledSelectedIds","defaultSelectedIds","controlledExpandedIds","defaultExpandedIds","onSelectionChange","onExpansionChange","onNodeClick","size","ariaLabel","className","testId","ref","internalSelectedIds","setInternalSelectedIds","useState","internalExpandedIds","setInternalExpandedIds","flatNodes","useMemo","flatten","nodes","result","id","newExpandedIds","eid","handleSelect","additive","n","newSelectedIds","sid","currentIndex","nextIndex","prevIndex"],"mappings":"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"}