dishui 0.0.82 → 0.0.84

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 (78) hide show
  1. package/dist/components/Button/index.d.ts +1 -0
  2. package/dist/components/Button/index.js.map +1 -1
  3. package/dist/components/ButtonMenu/index.d.ts +28 -0
  4. package/dist/components/ButtonMenu/index.js +197 -0
  5. package/dist/components/ButtonMenu/index.js.map +1 -0
  6. package/dist/components/Demo/index.d.ts +5 -0
  7. package/dist/components/Demo/index.js +131 -56
  8. package/dist/components/Demo/index.js.map +1 -1
  9. package/dist/components/Demo/source.d.ts +9 -0
  10. package/dist/components/Demo/source.js +32 -0
  11. package/dist/components/Demo/source.js.map +1 -0
  12. package/dist/components/Field/index.d.ts +8 -0
  13. package/dist/components/Field/index.js +43 -0
  14. package/dist/components/Field/index.js.map +1 -0
  15. package/dist/components/LayoutSuite/DashboardSuite.d.ts +35 -0
  16. package/dist/components/LayoutSuite/DashboardSuite.js +61 -0
  17. package/dist/components/LayoutSuite/DashboardSuite.js.map +1 -0
  18. package/dist/components/LayoutSuite/index.d.ts +56 -0
  19. package/dist/components/LayoutSuite/index.js +101 -0
  20. package/dist/components/LayoutSuite/index.js.map +1 -0
  21. package/dist/components/Modal/focusScope.d.ts +1 -0
  22. package/dist/components/Modal/focusScope.js +81 -0
  23. package/dist/components/Modal/focusScope.js.map +1 -0
  24. package/dist/components/Modal/index.d.ts +4 -1
  25. package/dist/components/Modal/index.js +48 -43
  26. package/dist/components/Modal/index.js.map +1 -1
  27. package/dist/components/Page/Float.d.ts +14 -0
  28. package/dist/components/Page/Float2.js +154 -0
  29. package/dist/components/Page/Float2.js.map +1 -0
  30. package/dist/components/Page/index.d.ts +34 -7
  31. package/dist/components/Page/index.js +117 -36
  32. package/dist/components/Page/index.js.map +1 -1
  33. package/dist/components/Page/resize.d.ts +28 -0
  34. package/dist/components/Page/resize2.js +95 -0
  35. package/dist/components/Page/resize2.js.map +1 -0
  36. package/dist/components/PageHeader/index.d.ts +10 -3
  37. package/dist/components/PageHeader/index.js +46 -25
  38. package/dist/components/PageHeader/index.js.map +1 -1
  39. package/dist/components/PagePanel/index.d.ts +29 -0
  40. package/dist/components/PagePanel/index.js +99 -0
  41. package/dist/components/PagePanel/index.js.map +1 -0
  42. package/dist/components/Resizable/ResizeGrip.d.ts +5 -0
  43. package/dist/components/Resizable/ResizeGrip.js +14 -0
  44. package/dist/components/Resizable/ResizeGrip.js.map +1 -0
  45. package/dist/components/Resizable/index.js +57 -59
  46. package/dist/components/Resizable/index.js.map +1 -1
  47. package/dist/components/Resizable/useResize.d.ts +6 -0
  48. package/dist/components/Resizable/useResize.js +29 -28
  49. package/dist/components/Resizable/useResize.js.map +1 -1
  50. package/dist/components/SidebarToggleButton/index.d.ts +5 -3
  51. package/dist/components/SidebarToggleButton/index.js +24 -21
  52. package/dist/components/SidebarToggleButton/index.js.map +1 -1
  53. package/dist/components/Table/index.d.ts +10 -12
  54. package/dist/components/Table/index.js +25 -20
  55. package/dist/components/Table/index.js.map +1 -1
  56. package/dist/components/Text/index.d.ts +2 -2
  57. package/dist/components/Text/index.js +13 -12
  58. package/dist/components/Text/index.js.map +1 -1
  59. package/dist/components/Textarea/index.d.ts +14 -0
  60. package/dist/components/Textarea/index.js +44 -0
  61. package/dist/components/Textarea/index.js.map +1 -0
  62. package/dist/components/Tree/Tree.d.ts +2 -0
  63. package/dist/components/Tree/Tree.js +49 -40
  64. package/dist/components/Tree/Tree.js.map +1 -1
  65. package/dist/dishui.css +1 -1
  66. package/dist/index-nostyled.d.ts +9 -0
  67. package/dist/index.d.ts +11 -2
  68. package/dist/index.js +119 -113
  69. package/dist/layouts/Sidebar.d.ts +14 -1
  70. package/dist/layouts/Sidebar.js +170 -137
  71. package/dist/layouts/Sidebar.js.map +1 -1
  72. package/dist/lite.d.ts +10 -2
  73. package/dist/lite.js +17 -12
  74. package/dist/utils/i18n.js +1 -1
  75. package/dist/utils/i18n.js.map +1 -1
  76. package/dist/utils/menu.js +14 -16
  77. package/dist/utils/menu.js.map +1 -1
  78. package/package.json +3 -1
@@ -1 +1 @@
1
- {"version":3,"file":"Tree.js","names":[],"sources":["../../../src/components/Tree/Tree.tsx"],"sourcesContent":["import React, { useState, useCallback, useMemo } from 'react';\nimport { generateTreeActiveStyles } from '../../styles/themeStyles';\n\n// ============= 类型定义 =============\n\nexport interface TreeNode {\n id: string | number;\n label: string;\n children?: TreeNode[];\n icon?: React.ReactNode;\n disabled?: boolean;\n meta?: Record<string, any>;\n}\n\nexport interface TreeProps {\n /** 树形数据 */\n data: TreeNode[];\n\n /** 节点点击回调 */\n onNodeClick?: (node: TreeNode, path: (string | number)[]) => void;\n\n /** 节点双击回调 */\n onNodeDoubleClick?: (node: TreeNode, path: (string | number)[]) => void;\n\n /** 节点展开/折叠回调 */\n onNodeToggle?: (nodeId: string | number, expanded: boolean) => void;\n\n /** 当前激活的节点 ID */\n activeNodeId?: string | number;\n\n /** 默认展开的节点 ID 列表 */\n defaultExpandedIds?: (string | number)[];\n\n /** 是否显示搜索框 */\n showSearch?: boolean;\n\n /** 搜索占位符 */\n searchPlaceholder?: string;\n\n /** 是否显示展开/折叠全部按钮 */\n showExpandAll?: boolean;\n\n /** 展开全部按钮文本 */\n expandAllText?: string;\n\n /** 折叠全部按钮文本 */\n collapseAllText?: string;\n\n /** 是否显示节点图标 */\n showIcon?: boolean;\n\n /** 默认图标 */\n defaultIcon?: React.ReactNode;\n\n /** 展开图标 */\n expandIcon?: React.ReactNode;\n\n /** 折叠图标 */\n collapseIcon?: React.ReactNode;\n\n /** 是否显示连接线 */\n showLine?: boolean;\n\n /** 最大高度 */\n maxHeight?: string;\n\n /** 自定义类名 */\n className?: string;\n\n /** 标题 */\n title?: string;\n\n /** 标题图标 */\n titleIcon?: React.ReactNode;\n\n /** 是否显示节点数量 */\n showCount?: boolean;\n\n /** 空状态文本 */\n emptyText?: string;\n\n /** 搜索无结果文本 */\n noResultsText?: string;\n\n /** 缩进宽度(像素) */\n indent?: number;\n\n /** 展开按钮位置:left(左侧)或 right(右侧) */\n togglePosition?: 'left' | 'right';\n\n /** 是否可拖拽(暂不实现) */\n draggable?: boolean;\n\n /** 是否可选择(暂不实现) */\n checkable?: boolean;\n\n /** 自定义渲染节点 */\n renderNode?: (node: TreeNode, defaultRender: React.ReactNode) => React.ReactNode;\n}\n\n// ============= Tree 组件 =============\n\nconst Tree: React.FC<TreeProps> = ({\n data,\n onNodeClick,\n onNodeDoubleClick,\n onNodeToggle,\n activeNodeId,\n defaultExpandedIds = [],\n showSearch = true,\n searchPlaceholder = 'Search...',\n showExpandAll = true,\n expandAllText = 'Expand All',\n collapseAllText = 'Collapse All',\n showIcon = true,\n defaultIcon,\n expandIcon,\n collapseIcon,\n showLine = false,\n maxHeight = '600px',\n className = '',\n title,\n titleIcon,\n showCount = true,\n emptyText = 'No data',\n noResultsText = 'No results found',\n indent = 16,\n togglePosition = 'left',\n renderNode,\n}) => {\n const [searchQuery, setSearchQuery] = useState('');\n const [expandedIds, setExpandedIds] = useState<Set<string | number>>(\n new Set(defaultExpandedIds)\n );\n\n // 当 defaultExpandedIds 变化时,同步更新 expandedIds(用于异步加载的数据)\n React.useEffect(() => {\n if (defaultExpandedIds.length > 0) {\n setExpandedIds(prev => {\n const newSet = new Set(prev);\n defaultExpandedIds.forEach(id => newSet.add(id));\n return newSet;\n });\n }\n }, [defaultExpandedIds]);\n\n // 默认展开/折叠图标\n const defaultExpandIconEl = expandIcon || (\n <svg className=\"w-3 h-3\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M19 9l-7 7-7-7\" />\n </svg>\n );\n\n const defaultCollapseIconEl = collapseIcon || (\n <svg className=\"w-3 h-3\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M9 5l7 7-7 7\" />\n </svg>\n );\n\n // 默认节点图标\n const defaultIconEl = defaultIcon || (\n <svg className=\"w-4 h-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z\"\n />\n </svg>\n );\n\n // 统计节点总数\n const countNodes = useCallback((nodes: TreeNode[]): number => {\n return nodes.reduce((count, node) => {\n return count + 1 + (node.children ? countNodes(node.children) : 0);\n }, 0);\n }, []);\n\n const totalCount = useMemo(() => countNodes(data), [data, countNodes]);\n\n // 过滤节点(支持搜索)\n const filterNodes = useCallback((nodes: TreeNode[], query: string): TreeNode[] => {\n if (!query) return nodes;\n\n const lowerQuery = query.toLowerCase();\n const filtered: TreeNode[] = [];\n\n for (const node of nodes) {\n const matches = node.label.toLowerCase().includes(lowerQuery);\n const filteredChildren = node.children ? filterNodes(node.children, query) : [];\n\n if (matches || filteredChildren.length > 0) {\n filtered.push({\n ...node,\n children: filteredChildren.length > 0 ? filteredChildren : node.children,\n });\n }\n }\n\n return filtered;\n }, []);\n\n const filteredData = useMemo(\n () => filterNodes(data, searchQuery),\n [data, searchQuery, filterNodes]\n );\n\n // 切换节点展开/折叠\n const toggleNode = useCallback(\n (nodeId: string | number) => {\n const newExpanded = new Set(expandedIds);\n if (newExpanded.has(nodeId)) {\n newExpanded.delete(nodeId);\n onNodeToggle?.(nodeId, false);\n } else {\n newExpanded.add(nodeId);\n onNodeToggle?.(nodeId, true);\n }\n setExpandedIds(newExpanded);\n },\n [expandedIds, onNodeToggle]\n );\n\n // 展开所有节点\n const expandAll = useCallback(() => {\n const allIds = new Set<string | number>();\n const collectIds = (nodes: TreeNode[]) => {\n nodes.forEach((node) => {\n if (node.children && node.children.length > 0) {\n allIds.add(node.id);\n collectIds(node.children);\n }\n });\n };\n collectIds(data);\n setExpandedIds(allIds);\n }, [data]);\n\n // 折叠所有节点\n const collapseAll = useCallback(() => {\n setExpandedIds(new Set());\n }, []);\n\n // 渲染单个节点\n const renderTreeNode = useCallback(\n (node: TreeNode, depth: number = 0, path: (string | number)[] = []) => {\n const hasChildren = node.children && node.children.length > 0;\n const isExpanded = expandedIds.has(node.id);\n const isActive = activeNodeId === node.id;\n const currentPath = [...path, node.id];\n\n const nodeContent = (\n <div\n key={node.id}\n data-node-id={node.id}\n className={`tree-node ${isActive ? 'tree-node-active' : ''} ${node.disabled ? 'tree-node-disabled' : ''\n }`}\n style={{\n paddingLeft: `${depth * indent}px`,\n }}\n >\n <div\n className={`tree-node-content flex items-center gap-2 px-2 py-1.5 rounded cursor-pointer transition-colors ${isActive ? 'tree-node-content-active' : 'tree-node-content-inactive'\n } ${node.disabled ? 'opacity-50 cursor-not-allowed' : ''}`}\n onClick={() => {\n if (!node.disabled) {\n onNodeClick?.(node, currentPath);\n }\n }}\n onDoubleClick={() => {\n if (!node.disabled) {\n onNodeDoubleClick?.(node, currentPath);\n }\n }}\n >\n {/* 左侧展开按钮 */}\n {togglePosition === 'left' && (\n <>\n {hasChildren ? (\n <button\n className={`tree-node-toggle btn btn-xs btn-ghost btn-circle ${isExpanded ? 'tree-node-toggle-expanded' : ''\n }`}\n onClick={(e) => {\n e.stopPropagation();\n if (!node.disabled) {\n toggleNode(node.id);\n }\n }}\n disabled={node.disabled}\n >\n {isExpanded ? defaultExpandIconEl : defaultCollapseIconEl}\n </button>\n ) : (\n <span className=\"tree-node-toggle-placeholder\" style={{ width: '1.5rem', height: '1.5rem', flexShrink: 0 }}></span>\n )}\n </>\n )}\n\n {/* 节点图标 */}\n {showIcon && (\n <span className=\"tree-node-icon\">{node.icon || defaultIconEl}</span>\n )}\n\n {/* 节点标签 */}\n <span className=\"tree-node-label text-sm truncate flex-1\" title={node.label}>\n {node.label}\n </span>\n\n {/* 子节点数量(优先使用 meta.count,否则回退到子节点个数) */}\n {node.meta?.count !== undefined && node.meta?.count !== null ? (\n <span className=\"tree-node-count text-xs opacity-60\">\n {node.meta.count}\n </span>\n ) : hasChildren && showCount ? (\n <span className=\"tree-node-count text-xs opacity-60\">\n ({node.children!.length})\n </span>\n ) : null}\n\n {/* 右侧展开按钮 */}\n {togglePosition === 'right' && hasChildren && (\n <button\n className={`tree-node-toggle tree-node-toggle-right btn btn-xs btn-ghost ${isExpanded ? 'tree-node-toggle-expanded' : ''\n }`}\n onClick={(e) => {\n e.stopPropagation();\n if (!node.disabled) {\n toggleNode(node.id);\n }\n }}\n disabled={node.disabled}\n >\n {isExpanded ? defaultExpandIconEl : defaultCollapseIconEl}\n </button>\n )}\n </div>\n\n {/* 子节点 */}\n {hasChildren && (\n <div\n className={`tree-node-children ${isExpanded ? 'tree-node-children-expanded' : 'tree-node-children-collapsed'}`}\n >\n {node.children!.map((child) => renderTreeNode(child, depth + 1, currentPath))}\n </div>\n )}\n </div>\n );\n\n // 自定义渲染\n if (renderNode) {\n return renderNode(node, nodeContent);\n }\n\n return nodeContent;\n },\n [\n expandedIds,\n activeNodeId,\n indent,\n showIcon,\n showCount,\n togglePosition,\n defaultExpandIconEl,\n defaultCollapseIconEl,\n defaultIconEl,\n onNodeClick,\n onNodeDoubleClick,\n toggleNode,\n renderNode,\n ]\n );\n\n return (\n <div className={`tree-component bg-base-100 border border-base-300 rounded-lg p-2 ${className}`}>\n {/* 标题 */}\n {title && (\n <div className=\"tree-header flex items-center gap-2 px-2 py-1 mb-2 border-b border-base-300\">\n {titleIcon}\n <span className=\"font-semibold\">{title}</span>\n {showCount && (\n <span className=\"text-xs opacity-60 ml-auto\">({totalCount})</span>\n )}\n </div>\n )}\n\n {/* 搜索框 */}\n {showSearch && (\n <input\n type=\"text\"\n placeholder={searchPlaceholder}\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"tree-search input input-sm input-bordered w-full mb-2\"\n />\n )}\n\n {/* 操作按钮 */}\n {showExpandAll && (\n <div className=\"tree-actions flex gap-1 mb-2\">\n <button className=\"btn btn-xs btn-ghost\" onClick={expandAll}>\n {expandAllText}\n </button>\n <button className=\"btn btn-xs btn-ghost\" onClick={collapseAll}>\n {collapseAllText}\n </button>\n </div>\n )}\n\n {/* 树形列表 */}\n <div\n className=\"tree-content overflow-y-auto\"\n style={{ maxHeight }}\n >\n {filteredData.length === 0 ? (\n <div className=\"tree-empty text-center text-sm opacity-60 py-4\">\n {searchQuery ? noResultsText : emptyText}\n </div>\n ) : (\n <div className={`tree-nodes ${showLine ? 'tree-show-line' : ''}`}>\n {filteredData.map((node) => renderTreeNode(node))}\n </div>\n )}\n </div>\n\n <style>{`\n .tree-node {\n user-select: none;\n }\n \n /* 子节点容器基础样式 */\n .tree-node-children {\n margin-top: 2px;\n overflow: hidden;\n transform-origin: top;\n box-sizing: border-box;\n }\n \n /* 折叠状态 - 初始隐藏 */\n .tree-node-children-collapsed {\n max-height: 0;\n opacity: 0;\n transform: scaleY(0.8);\n border-left: none !important;\n }\n \n /* 展开状态 - 显示内容 */\n .tree-node-children-expanded {\n max-height: 5000px;\n opacity: 1;\n transform: scaleY(1);\n transition: \n max-height 0.3s cubic-bezier(0.4, 0, 0.2, 1),\n opacity 0.25s cubic-bezier(0.4, 0, 0.2, 1),\n transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n /* 不对 border 做动画 */\n box-sizing: border-box;\n }\n \n /* 连接线样式 - 在展开状态显示,使用多重选择器提高优先级 */\n .tree-component .tree-show-line .tree-node-children-expanded,\n .tree-show-line .tree-node-children.tree-node-children-expanded {\n border-left: 1px solid var(--fallback-bc, oklch(var(--bc) / 0.2)) !important;\n margin-left: 8px !important;\n padding-left: 8px !important;\n position: relative;\n }\n \n /* 左侧连接线圆点装饰 */\n .tree-show-line .tree-node-children-expanded::before {\n content: '';\n position: absolute;\n left: -3px;\n top: 0;\n width: 5px;\n height: 5px;\n border-radius: 50%;\n background-color: var(--fallback-bc, oklch(var(--bc) / 0.3));\n }\n \n /* 折叠过渡 */\n .tree-node-children-collapsed {\n transition: \n max-height 0.3s cubic-bezier(0.4, 0, 0.2, 1),\n opacity 0.2s cubic-bezier(0.4, 0, 0.2, 1),\n transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n }\n \n /* 展开/折叠按钮图标旋转动画 */\n .tree-node-toggle {\n z-index: 2;\n transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n }\n \n .tree-node-toggle svg {\n transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n }\n \n /* 折叠状态的图标 - 向右 */\n .tree-node-toggle:not(.tree-node-toggle-expanded) svg {\n transform: rotate(0deg);\n }\n \n /* 展开状态的图标 - 向下(已经是向下的,所以不需要额外旋转) */\n .tree-node-toggle-expanded svg {\n transform: rotate(0deg);\n }\n \n .tree-component {\n position: relative;\n z-index: 1;\n }\n \n .tree-node-disabled {\n cursor: not-allowed;\n }\n \n .tree-node-disabled .tree-node-content {\n pointer-events: none;\n }\n \n /* 节点内容悬停效果 */\n .tree-node-content {\n transition: background-color 0.15s ease;\n }\n \n /* 优化性能 - 告诉浏览器这些属性会变化 */\n .tree-node-children {\n will-change: max-height, opacity, transform;\n }\n \n /* 动画完成后移除 will-change 以节省资源 */\n .tree-node-children-expanded,\n .tree-node-children-collapsed {\n animation: remove-will-change 0.3s forwards;\n }\n \n @keyframes remove-will-change {\n to {\n will-change: auto;\n }\n }\n \n /* 活跃节点基础样式 */\n .tree-node-content-active {\n font-weight: 600 !important;\n padding-left: calc(0.5rem - 4px) !important;\n border-radius: 0.375rem !important;\n }\n \n /* 主题活跃状态样式 - 从共用配置生成 */\n ${generateTreeActiveStyles()}\n \n /* 非活跃节点的悬停状态 */\n .tree-node-content-inactive:hover {\n background-color: oklch(var(--b2));\n }\n `}</style>\n </div>\n );\n};\n\nexport default Tree;\n\n"],"mappings":"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"}
1
+ {"version":3,"file":"Tree.js","names":[],"sources":["../../../src/components/Tree/Tree.tsx"],"sourcesContent":["import React, { useState, useCallback, useMemo } from 'react';\nimport { generateTreeActiveStyles } from '../../styles/themeStyles';\n\n// ============= 类型定义 =============\n\nexport interface TreeNode {\n id: string | number;\n label: string;\n children?: TreeNode[];\n icon?: React.ReactNode;\n disabled?: boolean;\n meta?: Record<string, any>;\n}\n\nexport interface TreeProps {\n /** 树形数据 */\n data: TreeNode[];\n\n /** 节点点击回调 */\n onNodeClick?: (node: TreeNode, path: (string | number)[]) => void;\n\n /** 节点双击回调 */\n onNodeDoubleClick?: (node: TreeNode, path: (string | number)[]) => void;\n\n /** 节点展开/折叠回调 */\n onNodeToggle?: (nodeId: string | number, expanded: boolean) => void;\n\n /** 当前激活的节点 ID */\n activeNodeId?: string | number;\n\n /** 默认展开的节点 ID 列表 */\n defaultExpandedIds?: (string | number)[];\n\n /** 是否显示搜索框 */\n showSearch?: boolean;\n\n /** 搜索占位符 */\n searchPlaceholder?: string;\n\n /** 是否显示展开/折叠全部按钮 */\n showExpandAll?: boolean;\n\n /** 展开全部按钮文本 */\n expandAllText?: string;\n\n /** 折叠全部按钮文本 */\n collapseAllText?: string;\n\n /** 是否显示节点图标 */\n showIcon?: boolean;\n\n /** 默认图标 */\n defaultIcon?: React.ReactNode;\n\n /** 展开图标 */\n expandIcon?: React.ReactNode;\n\n /** 折叠图标 */\n collapseIcon?: React.ReactNode;\n\n /** 是否显示连接线 */\n showLine?: boolean;\n\n /** 最大高度 */\n maxHeight?: string;\n\n /** 自定义类名 */\n className?: string;\n\n /** 标题 */\n title?: string;\n\n /** 标题图标 */\n titleIcon?: React.ReactNode;\n\n /** 是否显示节点数量 */\n showCount?: boolean;\n\n /** 空状态文本 */\n emptyText?: string;\n\n /** 搜索无结果文本 */\n noResultsText?: string;\n\n /** 缩进宽度(像素) */\n indent?: number;\n\n /** 展开按钮位置:left(左侧)或 right(右侧) */\n togglePosition?: 'left' | 'right';\n\n /** 是否可拖拽(暂不实现) */\n draggable?: boolean;\n\n /** 是否可选择(暂不实现) */\n checkable?: boolean;\n\n /** Custom label content; depth is zero-based. The string label remains the search text and native title. */\n renderLabel?: (node: TreeNode, depth: number) => React.ReactNode;\n\n /** 自定义渲染节点 */\n renderNode?: (node: TreeNode, defaultRender: React.ReactNode) => React.ReactNode;\n}\n\n// ============= Tree 组件 =============\n\nconst Tree: React.FC<TreeProps> = ({\n data,\n onNodeClick,\n onNodeDoubleClick,\n onNodeToggle,\n activeNodeId,\n defaultExpandedIds = [],\n showSearch = true,\n searchPlaceholder = 'Search...',\n showExpandAll = true,\n expandAllText = 'Expand All',\n collapseAllText = 'Collapse All',\n showIcon = true,\n defaultIcon,\n expandIcon,\n collapseIcon,\n showLine = false,\n maxHeight = '600px',\n className = '',\n title,\n titleIcon,\n showCount = true,\n emptyText = 'No data',\n noResultsText = 'No results found',\n indent = 16,\n togglePosition = 'left',\n renderLabel,\n renderNode,\n}) => {\n const [searchQuery, setSearchQuery] = useState('');\n const [expandedIds, setExpandedIds] = useState<Set<string | number>>(\n new Set(defaultExpandedIds)\n );\n\n // 当 defaultExpandedIds 变化时,同步更新 expandedIds(用于异步加载的数据)\n React.useEffect(() => {\n if (defaultExpandedIds.length > 0) {\n setExpandedIds(prev => {\n const newSet = new Set(prev);\n defaultExpandedIds.forEach(id => newSet.add(id));\n return newSet;\n });\n }\n }, [defaultExpandedIds]);\n\n // 默认展开/折叠图标\n const defaultExpandIconEl = expandIcon || (\n <svg className=\"w-3 h-3\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M19 9l-7 7-7-7\" />\n </svg>\n );\n\n const defaultCollapseIconEl = collapseIcon || (\n <svg className=\"w-3 h-3\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M9 5l7 7-7 7\" />\n </svg>\n );\n\n // 默认节点图标\n const defaultIconEl = defaultIcon || (\n <svg className=\"w-4 h-4\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d=\"M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z\"\n />\n </svg>\n );\n\n // 统计节点总数\n const countNodes = useCallback((nodes: TreeNode[]): number => {\n return nodes.reduce((count, node) => {\n return count + 1 + (node.children ? countNodes(node.children) : 0);\n }, 0);\n }, []);\n\n const totalCount = useMemo(() => countNodes(data), [data, countNodes]);\n\n // 过滤节点(支持搜索)\n const filterNodes = useCallback((nodes: TreeNode[], query: string): TreeNode[] => {\n if (!query) return nodes;\n\n const lowerQuery = query.toLowerCase();\n const filtered: TreeNode[] = [];\n\n for (const node of nodes) {\n const matches = node.label.toLowerCase().includes(lowerQuery);\n const filteredChildren = node.children ? filterNodes(node.children, query) : [];\n\n if (matches || filteredChildren.length > 0) {\n filtered.push({\n ...node,\n children: filteredChildren.length > 0 ? filteredChildren : node.children,\n });\n }\n }\n\n return filtered;\n }, []);\n\n const filteredData = useMemo(\n () => filterNodes(data, searchQuery),\n [data, searchQuery, filterNodes]\n );\n\n // 切换节点展开/折叠\n const toggleNode = useCallback(\n (nodeId: string | number) => {\n const newExpanded = new Set(expandedIds);\n if (newExpanded.has(nodeId)) {\n newExpanded.delete(nodeId);\n onNodeToggle?.(nodeId, false);\n } else {\n newExpanded.add(nodeId);\n onNodeToggle?.(nodeId, true);\n }\n setExpandedIds(newExpanded);\n },\n [expandedIds, onNodeToggle]\n );\n\n // 展开所有节点\n const expandAll = useCallback(() => {\n const allIds = new Set<string | number>();\n const collectIds = (nodes: TreeNode[]) => {\n nodes.forEach((node) => {\n if (node.children && node.children.length > 0) {\n allIds.add(node.id);\n collectIds(node.children);\n }\n });\n };\n collectIds(data);\n setExpandedIds(allIds);\n }, [data]);\n\n // 折叠所有节点\n const collapseAll = useCallback(() => {\n setExpandedIds(new Set());\n }, []);\n\n // 渲染单个节点\n const renderTreeNode = useCallback(\n (node: TreeNode, depth: number = 0, path: (string | number)[] = []) => {\n const hasChildren = node.children && node.children.length > 0;\n const isExpanded = expandedIds.has(node.id);\n const isActive = activeNodeId === node.id;\n const currentPath = [...path, node.id];\n\n const nodeContent = (\n <div\n key={node.id}\n data-node-id={node.id}\n data-depth={depth}\n data-level={depth + 1}\n className={`tree-node ${isActive ? 'tree-node-active' : ''} ${node.disabled ? 'tree-node-disabled' : ''\n }`}\n style={{\n paddingLeft: `${depth * indent}px`,\n }}\n >\n <div\n className={`tree-node-content flex items-center gap-2 px-2 py-1.5 rounded cursor-pointer transition-colors ${isActive ? 'tree-node-content-active' : 'tree-node-content-inactive'\n } ${node.disabled ? 'opacity-50 cursor-not-allowed' : ''}`}\n onClick={() => {\n if (!node.disabled) {\n onNodeClick?.(node, currentPath);\n }\n }}\n onDoubleClick={() => {\n if (!node.disabled) {\n onNodeDoubleClick?.(node, currentPath);\n }\n }}\n >\n {/* 左侧展开按钮 */}\n {togglePosition === 'left' && (\n <>\n {hasChildren ? (\n <button\n type=\"button\"\n aria-label={`${isExpanded ? 'Collapse' : 'Expand'} ${node.label}`}\n aria-expanded={isExpanded}\n className={`tree-node-toggle btn btn-xs btn-ghost btn-circle ${isExpanded ? 'tree-node-toggle-expanded' : ''\n }`}\n onClick={(e) => {\n e.stopPropagation();\n if (!node.disabled) {\n toggleNode(node.id);\n }\n }}\n disabled={node.disabled}\n >\n {isExpanded ? defaultExpandIconEl : defaultCollapseIconEl}\n </button>\n ) : (\n <span className=\"tree-node-toggle-placeholder\" style={{ width: '1.5rem', height: '1.5rem', flexShrink: 0 }}></span>\n )}\n </>\n )}\n\n {/* 节点图标 */}\n {showIcon && (\n <span className=\"tree-node-icon\">{node.icon || defaultIconEl}</span>\n )}\n\n {/* 节点标签 */}\n <span className=\"tree-node-label text-sm truncate flex-1\" title={node.label}>\n {renderLabel ? renderLabel(node, depth) : node.label}\n </span>\n\n {/* 子节点数量(优先使用 meta.count,否则回退到子节点个数) */}\n {node.meta?.count !== undefined && node.meta?.count !== null ? (\n <span className=\"tree-node-count text-xs opacity-60\">\n {node.meta.count}\n </span>\n ) : hasChildren && showCount ? (\n <span className=\"tree-node-count text-xs opacity-60\">\n ({node.children!.length})\n </span>\n ) : null}\n\n {/* 右侧展开按钮 */}\n {togglePosition === 'right' && hasChildren && (\n <button\n type=\"button\"\n aria-label={`${isExpanded ? 'Collapse' : 'Expand'} ${node.label}`}\n aria-expanded={isExpanded}\n className={`tree-node-toggle tree-node-toggle-right btn btn-xs btn-ghost ${isExpanded ? 'tree-node-toggle-expanded' : ''\n }`}\n onClick={(e) => {\n e.stopPropagation();\n if (!node.disabled) {\n toggleNode(node.id);\n }\n }}\n disabled={node.disabled}\n >\n {isExpanded ? defaultExpandIconEl : defaultCollapseIconEl}\n </button>\n )}\n </div>\n\n {/* 子节点 */}\n {hasChildren && (\n <div\n className={`tree-node-children ${isExpanded ? 'tree-node-children-expanded' : 'tree-node-children-collapsed'}`}\n >\n {node.children!.map((child) => renderTreeNode(child, depth + 1, currentPath))}\n </div>\n )}\n </div>\n );\n\n // 自定义渲染\n if (renderNode) {\n return renderNode(node, nodeContent);\n }\n\n return nodeContent;\n },\n [\n expandedIds,\n activeNodeId,\n indent,\n showIcon,\n showCount,\n togglePosition,\n defaultExpandIconEl,\n defaultCollapseIconEl,\n defaultIconEl,\n onNodeClick,\n onNodeDoubleClick,\n toggleNode,\n renderLabel,\n renderNode,\n ]\n );\n\n return (\n <div className={`tree-component bg-base-100 border border-base-300 rounded-lg p-2 ${className}`}>\n {/* 标题 */}\n {title && (\n <div className=\"tree-header flex items-center gap-2 px-2 py-1 mb-2 border-b border-base-300\">\n {titleIcon}\n <span className=\"font-semibold\">{title}</span>\n {showCount && (\n <span className=\"text-xs opacity-60 ml-auto\">({totalCount})</span>\n )}\n </div>\n )}\n\n {/* 搜索框 */}\n {showSearch && (\n <input\n type=\"text\"\n placeholder={searchPlaceholder}\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"tree-search input input-sm input-bordered w-full mb-2\"\n />\n )}\n\n {/* 操作按钮 */}\n {showExpandAll && (\n <div className=\"tree-actions flex gap-1 mb-2\">\n <button className=\"btn btn-xs btn-ghost\" onClick={expandAll}>\n {expandAllText}\n </button>\n <button className=\"btn btn-xs btn-ghost\" onClick={collapseAll}>\n {collapseAllText}\n </button>\n </div>\n )}\n\n {/* 树形列表 */}\n <div\n className=\"tree-content overflow-y-auto\"\n style={{ maxHeight }}\n >\n {filteredData.length === 0 ? (\n <div className=\"tree-empty text-center text-sm opacity-60 py-4\">\n {searchQuery ? noResultsText : emptyText}\n </div>\n ) : (\n <div className={`tree-nodes ${showLine ? 'tree-show-line' : ''}`}>\n {filteredData.map((node) => renderTreeNode(node))}\n </div>\n )}\n </div>\n\n <style>{`\n .tree-node {\n user-select: none;\n }\n \n /* 子节点容器基础样式 */\n .tree-node-children {\n margin-top: 2px;\n overflow: hidden;\n transform-origin: top;\n box-sizing: border-box;\n }\n \n /* 折叠状态 - 初始隐藏 */\n .tree-node-children-collapsed {\n max-height: 0;\n opacity: 0;\n transform: scaleY(0.8);\n border-left: none !important;\n }\n \n /* 展开状态 - 显示内容 */\n .tree-node-children-expanded {\n max-height: 5000px;\n opacity: 1;\n transform: scaleY(1);\n transition: \n max-height 0.3s cubic-bezier(0.4, 0, 0.2, 1),\n opacity 0.25s cubic-bezier(0.4, 0, 0.2, 1),\n transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n /* 不对 border 做动画 */\n box-sizing: border-box;\n }\n \n /* 连接线样式 - 在展开状态显示,使用多重选择器提高优先级 */\n .tree-component .tree-show-line .tree-node-children-expanded,\n .tree-show-line .tree-node-children.tree-node-children-expanded {\n border-left: 1px solid var(--fallback-bc, oklch(var(--bc) / 0.2)) !important;\n margin-left: 8px !important;\n padding-left: 8px !important;\n position: relative;\n }\n \n /* 左侧连接线圆点装饰 */\n .tree-show-line .tree-node-children-expanded::before {\n content: '';\n position: absolute;\n left: -3px;\n top: 0;\n width: 5px;\n height: 5px;\n border-radius: 50%;\n background-color: var(--fallback-bc, oklch(var(--bc) / 0.3));\n }\n \n /* 折叠过渡 */\n .tree-node-children-collapsed {\n transition: \n max-height 0.3s cubic-bezier(0.4, 0, 0.2, 1),\n opacity 0.2s cubic-bezier(0.4, 0, 0.2, 1),\n transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n }\n \n /* 展开/折叠按钮图标旋转动画 */\n .tree-node-toggle {\n z-index: 2;\n transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n }\n \n .tree-node-toggle svg {\n transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n }\n \n /* 折叠状态的图标 - 向右 */\n .tree-node-toggle:not(.tree-node-toggle-expanded) svg {\n transform: rotate(0deg);\n }\n \n /* 展开状态的图标 - 向下(已经是向下的,所以不需要额外旋转) */\n .tree-node-toggle-expanded svg {\n transform: rotate(0deg);\n }\n \n .tree-component {\n position: relative;\n z-index: 1;\n }\n \n .tree-node-disabled {\n cursor: not-allowed;\n }\n \n .tree-node-disabled .tree-node-content {\n pointer-events: none;\n }\n \n /* 节点内容悬停效果 */\n .tree-node-content {\n transition: background-color 0.15s ease;\n }\n \n /* 优化性能 - 告诉浏览器这些属性会变化 */\n .tree-node-children {\n will-change: max-height, opacity, transform;\n }\n \n /* 动画完成后移除 will-change 以节省资源 */\n .tree-node-children-expanded,\n .tree-node-children-collapsed {\n animation: remove-will-change 0.3s forwards;\n }\n \n @keyframes remove-will-change {\n to {\n will-change: auto;\n }\n }\n \n /* 活跃节点基础样式 */\n .tree-node-content-active {\n font-weight: 600 !important;\n padding-left: calc(0.5rem - 4px) !important;\n border-radius: 0.375rem !important;\n }\n \n /* 主题活跃状态样式 - 从共用配置生成 */\n ${generateTreeActiveStyles()}\n \n /* 非活跃节点的悬停状态 */\n .tree-node-content-inactive:hover {\n background-color: oklch(var(--b2));\n }\n `}</style>\n </div>\n );\n};\n\nexport default Tree;\n\n"],"mappings":"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"}