dishui 0.0.106 → 0.0.110

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 (388) hide show
  1. package/dist/.release-verified.json +3 -2
  2. package/dist/components/Accordion/index.js.map +1 -1
  3. package/dist/components/Avatar/index.js.map +1 -1
  4. package/dist/components/Badge/index.js.map +1 -1
  5. package/dist/components/Button/index.js.map +1 -1
  6. package/dist/components/ButtonMenu/index.js.map +1 -1
  7. package/dist/components/Card/Metric2.js.map +1 -1
  8. package/dist/components/Card/Ticket2.js.map +1 -1
  9. package/dist/components/Card/index.js.map +1 -1
  10. package/dist/components/Chart/Chart.js.map +1 -1
  11. package/dist/components/Checkbox/index.js.map +1 -1
  12. package/dist/components/ChoicePicker/index.js.map +1 -1
  13. package/dist/components/Column/index.js.map +1 -1
  14. package/dist/components/ConfirmDialog/index.js.map +1 -1
  15. package/dist/components/DateTimeInput/index.js.map +1 -1
  16. package/dist/components/Demo/index.js.map +1 -1
  17. package/dist/components/Demo/source.js.map +1 -1
  18. package/dist/components/Divider/index.js.map +1 -1
  19. package/dist/components/EmptyState/index.js.map +1 -1
  20. package/dist/components/Field/index.js.map +1 -1
  21. package/dist/components/FileUploader/DropZone.js.map +1 -1
  22. package/dist/components/FileUploader/FileItem.js.map +1 -1
  23. package/dist/components/FileUploader/FileUploader.js.map +1 -1
  24. package/dist/components/FileUploader/UploadQueue.js.map +1 -1
  25. package/dist/components/GroupButton/index.js.map +1 -1
  26. package/dist/components/GroupedTable/index.js.map +1 -1
  27. package/dist/components/Icon/index.js.map +1 -1
  28. package/dist/components/Image/index.js.map +1 -1
  29. package/dist/components/Input/index.js.map +1 -1
  30. package/dist/components/Label/index.js.map +1 -1
  31. package/dist/components/Layout/index.js.map +1 -1
  32. package/dist/components/LayoutSuite/DashboardSuite.js.map +1 -1
  33. package/dist/components/LayoutSuite/index.js.map +1 -1
  34. package/dist/components/List/index.js.map +1 -1
  35. package/dist/components/Markdown/Markdown.js.map +1 -1
  36. package/dist/components/Markdown/codeThemes.js.map +1 -1
  37. package/dist/components/Markdown/markdownComponents.js.map +1 -1
  38. package/dist/components/Markdown/parseCodeBlockMeta.js.map +1 -1
  39. package/dist/components/Markdown/useMarkdownSource.js.map +1 -1
  40. package/dist/components/Markdown/useMarkmapRenderer.js.map +1 -1
  41. package/dist/components/Markdown/useMermaidRenderer.js.map +1 -1
  42. package/dist/components/Modal/focusScope.js.map +1 -1
  43. package/dist/components/Modal/index.js.map +1 -1
  44. package/dist/components/MultipleChoice/index.js.map +1 -1
  45. package/dist/components/NavigationList/index.js.map +1 -1
  46. package/dist/components/Page/Float2.js.map +1 -1
  47. package/dist/components/Page/index.js.map +1 -1
  48. package/dist/components/Page/resize2.js.map +1 -1
  49. package/dist/components/PageHeader/index.js.map +1 -1
  50. package/dist/components/PagePanel/index.js.map +1 -1
  51. package/dist/components/ProtectedRoute/index.js.map +1 -1
  52. package/dist/components/Resizable/ResizeGrip.js.map +1 -1
  53. package/dist/components/Resizable/index.js.map +1 -1
  54. package/dist/components/Resizable/useResize.js.map +1 -1
  55. package/dist/components/Row/index.js.map +1 -1
  56. package/dist/components/Section/index.js.map +1 -1
  57. package/dist/components/Select/index.js.map +1 -1
  58. package/dist/components/SidebarToggleButton/index.js.map +1 -1
  59. package/dist/components/Skeleton/index.js.map +1 -1
  60. package/dist/components/Slider/index.js.map +1 -1
  61. package/dist/components/Switch/index.js.map +1 -1
  62. package/dist/components/Tab/index.js.map +1 -1
  63. package/dist/components/Table/index.js.map +1 -1
  64. package/dist/components/Tabs/index.js.map +1 -1
  65. package/dist/components/Tabs/tabNavigation.js.map +1 -1
  66. package/dist/components/Text/index.js.map +1 -1
  67. package/dist/components/Textarea/index.js.map +1 -1
  68. package/dist/components/Tooltip/index.js.map +1 -1
  69. package/dist/components/Tree/Tree.js.map +1 -1
  70. package/dist/components/ai/AgentChat/index.js.map +1 -1
  71. package/dist/components/ai/AgentRunCard/index.js.map +1 -1
  72. package/dist/components/ai/AgentScreen/index.js.map +1 -1
  73. package/dist/components/ai/ApprovalCard/index.js.map +1 -1
  74. package/dist/components/ai/CodeView/index.js.map +1 -1
  75. package/dist/components/ai/CommandSearch/index.js.map +1 -1
  76. package/dist/components/ai/ContextCards/index.js.map +1 -1
  77. package/dist/components/ai/DiffTable/index.js.map +1 -1
  78. package/dist/components/ai/FilterTable/index.js.map +1 -1
  79. package/dist/components/ai/FineTuneCard/index.js.map +1 -1
  80. package/dist/components/ai/InsightCards/index.js.map +1 -1
  81. package/dist/components/ai/IssueCard/index.js.map +1 -1
  82. package/dist/components/ai/LoadingState/index.js.map +1 -1
  83. package/dist/components/ai/PromptBar/index.js.map +1 -1
  84. package/dist/components/ai/RecommendationCard/index.js.map +1 -1
  85. package/dist/components/ai/RecordsTable/index.js.map +1 -1
  86. package/dist/components/ai/SelectionActions/index.js.map +1 -1
  87. package/dist/components/ai/StateFlow/index.js.map +1 -1
  88. package/dist/components/ai/StreamingText/index.js.map +1 -1
  89. package/dist/components/ai/TaskRows/index.js.map +1 -1
  90. package/dist/components/ai/Thinking/index.js.map +1 -1
  91. package/dist/components/ai/ToolChips/index.js.map +1 -1
  92. package/dist/components/ai/shared.js.map +1 -1
  93. package/dist/components/pro/ArticleContextMenu/index.js.map +1 -1
  94. package/dist/components/pro/ArticleControl/ArticleControl2.js.map +1 -1
  95. package/dist/components/pro/ArticleControl/buildHeadingTree.js.map +1 -1
  96. package/dist/components/pro/ArticleControl/useArticleToc.js.map +1 -1
  97. package/dist/components/pro/Calendar/Calendar.js +165 -160
  98. package/dist/components/pro/Calendar/Calendar.js.map +1 -1
  99. package/dist/components/pro/Calendar/hooks/useCalendarDrag.js.map +1 -1
  100. package/dist/components/pro/Calendar/hooks/useCalendarState.js +31 -31
  101. package/dist/components/pro/Calendar/hooks/useCalendarState.js.map +1 -1
  102. package/dist/components/pro/Calendar/utils.js.map +1 -1
  103. package/dist/components/pro/CodeEditor/editors/CodeEditor.js.map +1 -1
  104. package/dist/components/pro/CodeEditor/editors/MarkdownEditor.js.map +1 -1
  105. package/dist/components/pro/CodeEditor/editors/markdownExtensions.js.map +1 -1
  106. package/dist/components/pro/CodeEditor/extensions/contextMenu.js.map +1 -1
  107. package/dist/components/pro/CodeEditor/extensions/index.js.map +1 -1
  108. package/dist/components/pro/CodeEditor/langs/index.js.map +1 -1
  109. package/dist/components/pro/CodeEditor/langs/javascript.js.map +1 -1
  110. package/dist/components/pro/CodeEditor/langs/python.js.map +1 -1
  111. package/dist/components/pro/CodeEditor/langs/snippets.js.map +1 -1
  112. package/dist/components/pro/CodeEditor/panels/FootnotePanel.js.map +1 -1
  113. package/dist/components/pro/CodeEditor/panels/HistoryPanel.js +65 -59
  114. package/dist/components/pro/CodeEditor/panels/HistoryPanel.js.map +1 -1
  115. package/dist/components/pro/CodeEditor/panels/OutlinePanel.js.map +1 -1
  116. package/dist/components/pro/CodeEditor/panels/TableOfContentsPanel.js.map +1 -1
  117. package/dist/components/pro/CodeEditor/panels/VariablePanel.js.map +1 -1
  118. package/dist/components/pro/CodeEditor/themes.js.map +1 -1
  119. package/dist/components/pro/CodeEditor/utils.js.map +1 -1
  120. package/dist/components/pro/DataTable/DataTable.js.map +1 -1
  121. package/dist/components/pro/DataTable/Filters.js.map +1 -1
  122. package/dist/components/pro/DataTable/PivotPanel.js.map +1 -1
  123. package/dist/components/pro/DataTable/PivotView.js.map +1 -1
  124. package/dist/components/pro/DataTable/components/BulkActions.js.map +1 -1
  125. package/dist/components/pro/DataTable/components/ColumnSelector.js.map +1 -1
  126. package/dist/components/pro/DataTable/components/FilterBar.js.map +1 -1
  127. package/dist/components/pro/DataTable/components/TableBody.js.map +1 -1
  128. package/dist/components/pro/DataTable/components/TableHeader.js.map +1 -1
  129. package/dist/components/pro/DataTable/components/TablePagination.js.map +1 -1
  130. package/dist/components/pro/DataTable/components/TableToolbar.js.map +1 -1
  131. package/dist/components/pro/DataTable/extension.js.map +1 -1
  132. package/dist/components/pro/DataTable/pivotEngine.js.map +1 -1
  133. package/dist/components/pro/DataTable/pivotExtension.js.map +1 -1
  134. package/dist/components/pro/DataTable/rowDetailExtension.js.map +1 -1
  135. package/dist/components/pro/DataTable/tanstack-table.js.map +1 -1
  136. package/dist/components/pro/DataTable/treeDataUtils.js.map +1 -1
  137. package/dist/components/pro/DataTable/useColumnDragReorder.js.map +1 -1
  138. package/dist/components/pro/DataTable/useDataTableModel.js +119 -104
  139. package/dist/components/pro/DataTable/useDataTableModel.js.map +1 -1
  140. package/dist/components/pro/DataTable/utils.js.map +1 -1
  141. package/dist/components/pro/FileExplorer/Breadcrumb.js.map +1 -1
  142. package/dist/components/pro/FileExplorer/CreateDialog.js.map +1 -1
  143. package/dist/components/pro/FileExplorer/FileExplorer.js.map +1 -1
  144. package/dist/components/pro/FileExplorer/FileIcon.js.map +1 -1
  145. package/dist/components/pro/FileExplorer/GridView.js.map +1 -1
  146. package/dist/components/pro/FileExplorer/ListView.js.map +1 -1
  147. package/dist/components/pro/FileExplorer/Toolbar.js.map +1 -1
  148. package/dist/components/pro/Flow/Flow.js.map +1 -1
  149. package/dist/components/pro/Flow/FlowCanvas.js.map +1 -1
  150. package/dist/components/pro/Flow/archify/build.js.map +1 -1
  151. package/dist/components/pro/Flow/archify/convert.js.map +1 -1
  152. package/dist/components/pro/Flow/archify/palette.js.map +1 -1
  153. package/dist/components/pro/Flow/archify/presets.js.map +1 -1
  154. package/dist/components/pro/Flow/archify/spec.js.map +1 -1
  155. package/dist/components/pro/Flow/canvas/AlignmentGuides.js.map +1 -1
  156. package/dist/components/pro/Flow/canvas/GridRenderer.js.map +1 -1
  157. package/dist/components/pro/Flow/canvas/MiniMapRenderer.js.map +1 -1
  158. package/dist/components/pro/Flow/canvas/PixiApp.js.map +1 -1
  159. package/dist/components/pro/Flow/canvas/SelectionOverlay.js.map +1 -1
  160. package/dist/components/pro/Flow/canvas/ViewportContainer.js.map +1 -1
  161. package/dist/components/pro/Flow/constants.js.map +1 -1
  162. package/dist/components/pro/Flow/context/FlowAIContext.js.map +1 -1
  163. package/dist/components/pro/Flow/context/FlowContext.js.map +1 -1
  164. package/dist/components/pro/Flow/context/FlowUIContext.js.map +1 -1
  165. package/dist/components/pro/Flow/edges/EdgeRenderer.js.map +1 -1
  166. package/dist/components/pro/Flow/edges/edgeMarkers.js.map +1 -1
  167. package/dist/components/pro/Flow/edges/edgePaths.js.map +1 -1
  168. package/dist/components/pro/Flow/hooks/useAlignmentGuides.js.map +1 -1
  169. package/dist/components/pro/Flow/hooks/useClipboard.js.map +1 -1
  170. package/dist/components/pro/Flow/hooks/useCompactMode.js.map +1 -1
  171. package/dist/components/pro/Flow/hooks/useDeleteSelection.js.map +1 -1
  172. package/dist/components/pro/Flow/hooks/useDraggablePanel.js.map +1 -1
  173. package/dist/components/pro/Flow/hooks/useEdgeMutations.js.map +1 -1
  174. package/dist/components/pro/Flow/hooks/useFlowImportExport.js.map +1 -1
  175. package/dist/components/pro/Flow/hooks/useKeyboardShortcuts.js.map +1 -1
  176. package/dist/components/pro/Flow/hooks/useLayoutActions.js.map +1 -1
  177. package/dist/components/pro/Flow/hooks/useLineMutations.js.map +1 -1
  178. package/dist/components/pro/Flow/hooks/useMindMap.js.map +1 -1
  179. package/dist/components/pro/Flow/hooks/useNodeMutations.js.map +1 -1
  180. package/dist/components/pro/Flow/hooks/usePdfExport.js.map +1 -1
  181. package/dist/components/pro/Flow/hooks/usePixiApp.js.map +1 -1
  182. package/dist/components/pro/Flow/hooks/useResizablePanel.js.map +1 -1
  183. package/dist/components/pro/Flow/hooks/useSelection.js.map +1 -1
  184. package/dist/components/pro/Flow/hooks/useUndoRedo.js.map +1 -1
  185. package/dist/components/pro/Flow/hooks/useViewport.js.map +1 -1
  186. package/dist/components/pro/Flow/lines/FreehandTool.js.map +1 -1
  187. package/dist/components/pro/Flow/lines/GeometricLineTool.js.map +1 -1
  188. package/dist/components/pro/Flow/lines/LineRenderer.js.map +1 -1
  189. package/dist/components/pro/Flow/lines/lineSmoothing.js.map +1 -1
  190. package/dist/components/pro/Flow/nodes/DataNodeView.js.map +1 -1
  191. package/dist/components/pro/Flow/nodes/MediaContent.js.map +1 -1
  192. package/dist/components/pro/Flow/nodes/MediaOverlay.js.map +1 -1
  193. package/dist/components/pro/Flow/nodes/Model3DView.js.map +1 -1
  194. package/dist/components/pro/Flow/nodes/NodeHandles.js.map +1 -1
  195. package/dist/components/pro/Flow/nodes/NodeRenderer.js.map +1 -1
  196. package/dist/components/pro/Flow/nodes/NodeText.js.map +1 -1
  197. package/dist/components/pro/Flow/nodes/aiClient.js.map +1 -1
  198. package/dist/components/pro/Flow/nodes/animAnchors.js.map +1 -1
  199. package/dist/components/pro/Flow/nodes/chartGeometryBudget.js.map +1 -1
  200. package/dist/components/pro/Flow/nodes/dataUtils.js.map +1 -1
  201. package/dist/components/pro/Flow/nodes/demandRender.js.map +1 -1
  202. package/dist/components/pro/Flow/nodes/nodeUtils.js.map +1 -1
  203. package/dist/components/pro/Flow/nodes/shapes.js.map +1 -1
  204. package/dist/components/pro/Flow/nodes/svgIconTexture.js.map +1 -1
  205. package/dist/components/pro/Flow/nodes/svgIcons.js.map +1 -1
  206. package/dist/components/pro/Flow/panels/AIPanel.js.map +1 -1
  207. package/dist/components/pro/Flow/panels/Breadcrumb.js.map +1 -1
  208. package/dist/components/pro/Flow/panels/ContextMenu.js.map +1 -1
  209. package/dist/components/pro/Flow/panels/DataInspectorSection.js.map +1 -1
  210. package/dist/components/pro/Flow/panels/ExpandableTextarea.js.map +1 -1
  211. package/dist/components/pro/Flow/panels/FlowPanelGroup.js.map +1 -1
  212. package/dist/components/pro/Flow/panels/FlowToolbar.js.map +1 -1
  213. package/dist/components/pro/Flow/panels/InspectorPanel.js.map +1 -1
  214. package/dist/components/pro/Flow/panels/OutlinePanel.js.map +1 -1
  215. package/dist/components/pro/Flow/panels/PresentationMode.js.map +1 -1
  216. package/dist/components/pro/Flow/panels/ProjectTitle.js.map +1 -1
  217. package/dist/components/pro/Flow/panels/ShapePalette.js.map +1 -1
  218. package/dist/components/pro/Flow/panels/toolbarIcons.js.map +1 -1
  219. package/dist/components/pro/Flow/types.js.map +1 -1
  220. package/dist/components/pro/Flow/utils/dashedLine.js.map +1 -1
  221. package/dist/components/pro/Flow/utils/gradient.js.map +1 -1
  222. package/dist/components/pro/Flow/utils/pdfExport.js.map +1 -1
  223. package/dist/components/pro/Flow/utils/themeColor.js.map +1 -1
  224. package/dist/components/pro/Gantt/Gantt.js.map +1 -1
  225. package/dist/components/pro/Gantt/hooks/useGanttDrag.js.map +1 -1
  226. package/dist/components/pro/Gantt/hooks/useGanttState.js +79 -71
  227. package/dist/components/pro/Gantt/hooks/useGanttState.js.map +1 -1
  228. package/dist/components/pro/Gantt/utils.js.map +1 -1
  229. package/dist/components/pro/Kanban/Kanban.js.map +1 -1
  230. package/dist/components/pro/Kanban/Swimlanes.js.map +1 -1
  231. package/dist/components/pro/Kanban/useKanbanDrag.js.map +1 -1
  232. package/dist/components/pro/Kanban/utils.js.map +1 -1
  233. package/dist/components/pro/RichTextEditor/AIRewrite.d.ts +1 -0
  234. package/dist/components/pro/RichTextEditor/AIRewrite.js +109 -88
  235. package/dist/components/pro/RichTextEditor/AIRewrite.js.map +1 -1
  236. package/dist/components/pro/RichTextEditor/BlockHandle.js.map +1 -1
  237. package/dist/components/pro/RichTextEditor/BubbleToolbar.js.map +1 -1
  238. package/dist/components/pro/RichTextEditor/CommentDialog.js.map +1 -1
  239. package/dist/components/pro/RichTextEditor/CommentPanel.js.map +1 -1
  240. package/dist/components/pro/RichTextEditor/CommentPopover.js.map +1 -1
  241. package/dist/components/pro/RichTextEditor/ContextMenu.js.map +1 -1
  242. package/dist/components/pro/RichTextEditor/RichTextEditor.js +133 -132
  243. package/dist/components/pro/RichTextEditor/RichTextEditor.js.map +1 -1
  244. package/dist/components/pro/RichTextEditor/SlashMenu.js.map +1 -1
  245. package/dist/components/pro/RichTextEditor/Toolbar/ColorPicker.js.map +1 -1
  246. package/dist/components/pro/RichTextEditor/Toolbar/FloatingDialogMenu.js.map +1 -1
  247. package/dist/components/pro/RichTextEditor/Toolbar/MarkdownTemplates.js.map +1 -1
  248. package/dist/components/pro/RichTextEditor/Toolbar/SelectDropdown.js.map +1 -1
  249. package/dist/components/pro/RichTextEditor/Toolbar/TableOpsMenu.js.map +1 -1
  250. package/dist/components/pro/RichTextEditor/Toolbar/Toolbar.js.map +1 -1
  251. package/dist/components/pro/RichTextEditor/Toolbar/ToolbarButton.js.map +1 -1
  252. package/dist/components/pro/RichTextEditor/Toolbar/useAnchoredDropdown.js.map +1 -1
  253. package/dist/components/pro/RichTextEditor/extensions/CodeBlockView.js.map +1 -1
  254. package/dist/components/pro/RichTextEditor/extensions/CommentMark.js.map +1 -1
  255. package/dist/components/pro/RichTextEditor/extensions/FloatingDialog.js.map +1 -1
  256. package/dist/components/pro/RichTextEditor/extensions/FontSize.js.map +1 -1
  257. package/dist/components/pro/RichTextEditor/extensions/MarkdownBlock.js.map +1 -1
  258. package/dist/components/pro/RichTextEditor/extensions/ResizableImage.js.map +1 -1
  259. package/dist/components/pro/RichTextEditor/extensions/legacyMermaid.js.map +1 -1
  260. package/dist/components/pro/RichTextEditor/types.d.ts +2 -0
  261. package/dist/components/pro/RichTextEditor/types.js.map +1 -1
  262. package/dist/components/pro/Sprite/Molly/animations.d.ts +6 -0
  263. package/dist/components/pro/Sprite/Molly/animations.js +52 -0
  264. package/dist/components/pro/Sprite/Molly/animations.js.map +1 -0
  265. package/dist/components/pro/Sprite/Molly/events.d.ts +2 -0
  266. package/dist/components/pro/Sprite/Molly/events.js +46 -0
  267. package/dist/components/pro/Sprite/Molly/events.js.map +1 -0
  268. package/dist/components/pro/Sprite/Molly/index.d.ts +1 -0
  269. package/dist/components/pro/Sprite/Molly/index.js +12 -0
  270. package/dist/components/pro/Sprite/Molly/index.js.map +1 -0
  271. package/dist/components/pro/Sprite/Molly/legFlexion.d.ts +3 -0
  272. package/dist/components/pro/Sprite/Molly/legFlexion.js +48 -0
  273. package/dist/components/pro/Sprite/Molly/legFlexion.js.map +1 -0
  274. package/dist/components/pro/Sprite/Molly/locomotion.d.ts +4 -0
  275. package/dist/components/pro/Sprite/Molly/locomotion.js +51 -0
  276. package/dist/components/pro/Sprite/Molly/locomotion.js.map +1 -0
  277. package/dist/components/pro/Sprite/Molly/model.d.ts +23 -0
  278. package/dist/components/pro/Sprite/Molly/model.js +614 -0
  279. package/dist/components/pro/Sprite/Molly/model.js.map +1 -0
  280. package/dist/components/pro/Sprite/Molly/rig.d.ts +25 -0
  281. package/dist/components/pro/Sprite/Molly/rig.js +102 -0
  282. package/dist/components/pro/Sprite/Molly/rig.js.map +1 -0
  283. package/dist/components/pro/Sprite/Ruby/animations.d.ts +6 -0
  284. package/dist/components/pro/Sprite/Ruby/animations.js +58 -0
  285. package/dist/components/pro/Sprite/Ruby/animations.js.map +1 -0
  286. package/dist/components/pro/Sprite/Ruby/events.d.ts +2 -0
  287. package/dist/components/pro/Sprite/Ruby/events.js +46 -0
  288. package/dist/components/pro/Sprite/Ruby/events.js.map +1 -0
  289. package/dist/components/pro/Sprite/Ruby/index.d.ts +1 -0
  290. package/dist/components/pro/Sprite/Ruby/index.js +12 -0
  291. package/dist/components/pro/Sprite/Ruby/index.js.map +1 -0
  292. package/dist/components/pro/Sprite/Ruby/locomotion.d.ts +4 -0
  293. package/dist/components/pro/Sprite/Ruby/locomotion.js +41 -0
  294. package/dist/components/pro/Sprite/Ruby/locomotion.js.map +1 -0
  295. package/dist/components/pro/Sprite/Ruby/model.d.ts +23 -0
  296. package/dist/components/pro/Sprite/Ruby/model.js +605 -0
  297. package/dist/components/pro/Sprite/Ruby/model.js.map +1 -0
  298. package/dist/components/pro/Sprite/Ruby/rig.d.ts +26 -0
  299. package/dist/components/pro/Sprite/Ruby/rig.js +112 -0
  300. package/dist/components/pro/Sprite/Ruby/rig.js.map +1 -0
  301. package/dist/components/pro/Sprite/Sprite.d.ts +23 -0
  302. package/dist/components/pro/Sprite/Sprite2.js +224 -0
  303. package/dist/components/pro/Sprite/Sprite2.js.map +1 -0
  304. package/dist/components/pro/Sprite/actions.d.ts +3 -0
  305. package/dist/components/pro/Sprite/actions.js +16 -0
  306. package/dist/components/pro/Sprite/actions.js.map +1 -0
  307. package/dist/components/pro/Sprite/createSpriteScene.d.ts +4 -0
  308. package/dist/components/pro/Sprite/createSpriteScene.js +14 -0
  309. package/dist/components/pro/Sprite/createSpriteScene.js.map +1 -0
  310. package/dist/components/pro/Sprite/index.d.ts +4 -0
  311. package/dist/components/pro/Sprite/shared/animation.d.ts +33 -0
  312. package/dist/components/pro/Sprite/shared/animation.js +39 -0
  313. package/dist/components/pro/Sprite/shared/animation.js.map +1 -0
  314. package/dist/components/pro/Sprite/shared/createSpriteStage.d.ts +14 -0
  315. package/dist/components/pro/Sprite/shared/createSpriteStage.js +127 -0
  316. package/dist/components/pro/Sprite/shared/createSpriteStage.js.map +1 -0
  317. package/dist/components/pro/Sprite/shared/events.d.ts +5 -0
  318. package/dist/components/pro/Sprite/shared/events.js +21 -0
  319. package/dist/components/pro/Sprite/shared/events.js.map +1 -0
  320. package/dist/components/pro/Sprite/shared/face.d.ts +15 -0
  321. package/dist/components/pro/Sprite/shared/face.js +33 -0
  322. package/dist/components/pro/Sprite/shared/face.js.map +1 -0
  323. package/dist/components/pro/Sprite/shared/faceSurface.d.ts +6 -0
  324. package/dist/components/pro/Sprite/shared/faceSurface.js +66 -0
  325. package/dist/components/pro/Sprite/shared/faceSurface.js.map +1 -0
  326. package/dist/components/pro/Sprite/shared/gait.d.ts +5 -0
  327. package/dist/components/pro/Sprite/shared/gait.js +19 -0
  328. package/dist/components/pro/Sprite/shared/gait.js.map +1 -0
  329. package/dist/components/pro/Sprite/shared/geometry.d.ts +8 -0
  330. package/dist/components/pro/Sprite/shared/geometry.js +59 -0
  331. package/dist/components/pro/Sprite/shared/geometry.js.map +1 -0
  332. package/dist/components/pro/Sprite/shared/magicEffect.d.ts +27 -0
  333. package/dist/components/pro/Sprite/shared/magicEffect.js +61 -0
  334. package/dist/components/pro/Sprite/shared/magicEffect.js.map +1 -0
  335. package/dist/components/pro/Sprite/shared/playback.d.ts +8 -0
  336. package/dist/components/pro/Sprite/shared/playback.js +74 -0
  337. package/dist/components/pro/Sprite/shared/playback.js.map +1 -0
  338. package/dist/components/pro/Sprite/shared/rig.d.ts +6 -0
  339. package/dist/components/pro/Sprite/shared/rig.js +48 -0
  340. package/dist/components/pro/Sprite/shared/rig.js.map +1 -0
  341. package/dist/components/pro/Sprite/shared/scene.d.ts +9 -0
  342. package/dist/components/pro/Sprite/shared/scene.js +21 -0
  343. package/dist/components/pro/Sprite/shared/scene.js.map +1 -0
  344. package/dist/components/pro/Sprite/shared/sculptor.d.ts +14 -0
  345. package/dist/components/pro/Sprite/shared/sculptor.js +78 -0
  346. package/dist/components/pro/Sprite/shared/sculptor.js.map +1 -0
  347. package/dist/components/pro/Sprite/shared/speechBubble.d.ts +15 -0
  348. package/dist/components/pro/Sprite/shared/speechBubble.js +129 -0
  349. package/dist/components/pro/Sprite/shared/speechBubble.js.map +1 -0
  350. package/dist/components/pro/Sprite/types.d.ts +40 -0
  351. package/dist/contexts/AppContext.js.map +1 -1
  352. package/dist/contexts/authentication.js.map +1 -1
  353. package/dist/data-table.js +3 -3
  354. package/dist/data-table.js.map +1 -1
  355. package/dist/dishui.css +1 -1
  356. package/dist/hooks/useClickOutside.js.map +1 -1
  357. package/dist/hooks/useContainerElement.js.map +1 -1
  358. package/dist/hooks/useControllableState.js.map +1 -1
  359. package/dist/hooks/useCopyToClipboard.js.map +1 -1
  360. package/dist/hooks/useDebounce.js.map +1 -1
  361. package/dist/hooks/useDraggable.js.map +1 -1
  362. package/dist/hooks/useTableColumns.js.map +1 -1
  363. package/dist/hooks/useTableData.js.map +1 -1
  364. package/dist/index-nostyled.d.ts +2 -0
  365. package/dist/index.d.ts +2 -0
  366. package/dist/index.js +116 -115
  367. package/dist/layouts/MainLayout.js.map +1 -1
  368. package/dist/layouts/Navbar.js.map +1 -1
  369. package/dist/layouts/Sidebar.js.map +1 -1
  370. package/dist/layouts/headbar/Headbar.js.map +1 -1
  371. package/dist/layouts/headbar/HeadbarLangSwitcher.js.map +1 -1
  372. package/dist/layouts/headbar/HeadbarSearch.js.map +1 -1
  373. package/dist/layouts/headbar/HeadbarThemeSwitcher.js.map +1 -1
  374. package/dist/layouts/headbar/HeadbarTitle.js.map +1 -1
  375. package/dist/sprite.js +2 -0
  376. package/dist/styles/themeStyles.js.map +1 -1
  377. package/dist/utils/cn.js.map +1 -1
  378. package/dist/utils/flexLayout.js.map +1 -1
  379. package/dist/utils/i18n.js.map +1 -1
  380. package/dist/utils/menu.js.map +1 -1
  381. package/dist/utils/rehype-code-meta.js.map +1 -1
  382. package/dist/utils/remark-code-meta.js.map +1 -1
  383. package/dist/utils/routerBuilder.js.map +1 -1
  384. package/dist/utils/safeStorage.js.map +1 -1
  385. package/dist/utils/selection.js +29 -20
  386. package/dist/utils/selection.js.map +1 -1
  387. package/dist/utils/themes.js.map +1 -1
  388. package/package.json +15 -11
@@ -1 +1 @@
1
- {"version":3,"file":"Navbar.js","names":[],"sources":["../../src/layouts/Navbar.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef } from 'react';\nimport { ThemeType, useAppContext } from '../contexts/AppContext';\nimport { getTranslations } from '../utils/i18n';\nimport { ThemeConfig, getThemes as defaultGetThemes } from '../utils/themes';\n\nexport type SearchResult = {\n title: string;\n path: string;\n description: string;\n};\n\nexport type SearchConfig = {\n enabled: boolean;\n searchFunction?: (term: string, language: 'zh' | 'en') => SearchResult[];\n placeholder?: { zh: string; en: string };\n shortcut?: string;\n};\n\ntype NavbarProps = {\n onToggleSidebar: () => void;\n searchConfig?: SearchConfig;\n themes?: ThemeConfig[];\n height?: number; // Navbar 高度(像素)\n};\n\nconst Navbar: React.FC<NavbarProps> = ({ onToggleSidebar, searchConfig, themes: propThemes, height = 64 }) => {\n const { title = 'DiShUI', language, setLanguage, theme, setTheme } = useAppContext();\n const t = getTranslations(language);\n\n const [isSearchOpen, setIsSearchOpen] = useState(false);\n const [searchTerm, setSearchTerm] = useState('');\n const [searchResults, setSearchResults] = useState<SearchResult[]>([]);\n const searchInputRef = useRef<HTMLInputElement>(null);\n const modalRef = useRef<HTMLDialogElement>(null);\n\n // 获取主题配置:优先使用 propThemes,否则使用默认的\n const themes = propThemes || defaultGetThemes();\n\n // 获取当前主题\n const currentTheme = themes.find(t => t.id === theme) || themes[0];\n\n // 搜索是否启用\n const isSearchEnabled = searchConfig?.enabled ?? true;\n\n const toggleSearch = () => {\n setIsSearchOpen(!isSearchOpen);\n if (!isSearchOpen && modalRef.current) {\n modalRef.current.showModal();\n setTimeout(() => {\n searchInputRef.current?.focus();\n }, 100);\n } else if (modalRef.current) {\n modalRef.current.close();\n }\n };\n\n const handleSearch = (e: React.ChangeEvent<HTMLInputElement>) => {\n const value = e.target.value;\n setSearchTerm(value);\n // 使用外部提供的搜索函数\n const searchFn = searchConfig?.searchFunction;\n if (searchFn) {\n setSearchResults(searchFn(value, language));\n }\n };\n\n useEffect(() => {\n if (!isSearchEnabled) return;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if ((e.metaKey || e.ctrlKey) && e.key === 'k') {\n e.preventDefault();\n toggleSearch();\n }\n\n if (e.key === 'Escape' && isSearchOpen) {\n toggleSearch();\n }\n };\n\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n }, [isSearchOpen, isSearchEnabled]);\n\n // 当语言改变时,更新搜索结果\n useEffect(() => {\n if (searchTerm && isSearchEnabled && searchConfig?.searchFunction) {\n setSearchResults(searchConfig.searchFunction(searchTerm, language));\n }\n }, [language, searchConfig, isSearchEnabled, searchTerm]);\n\n return (\n <div className=\"navbar bg-base-100 shadow-md\" style={{ height: `${height}px`, minHeight: `${height}px`, maxHeight: `${height}px` }}>\n <div className=\"navbar-start\">\n <div className=\"flex-none lg:hidden\">\n <button className=\"btn btn-square btn-ghost\" onClick={onToggleSidebar}>\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" className=\"inline-block w-5 h-5 stroke-current\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth=\"2\" d=\"M4 6h16M4 12h16M4 18h16\"></path>\n </svg>\n </button>\n </div>\n <a href=\"/\" className=\"btn btn-ghost normal-case text-xl\">{title}</a>\n </div>\n\n {isSearchEnabled && (\n <div className=\"navbar-center hidden lg:flex\">\n <button\n className=\"btn btn-ghost gap-2\"\n onClick={toggleSearch}\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth=\"2\" d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\" />\n </svg>\n {searchConfig?.placeholder?.[language] || t.navbar.search} ({searchConfig?.shortcut || t.navbar.searchShortcut})\n </button>\n </div>\n )}\n\n <div className=\"navbar-end\">\n <div className=\"dropdown dropdown-end\">\n <label tabIndex={0} className=\"btn btn-ghost gap-1\">\n {language === 'zh' ? '中文' : 'English'}\n <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-4 w-4\" 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 </label>\n <ul tabIndex={0} className=\"menu dropdown-content p-2 shadow bg-base-100 rounded-box w-40 mt-4\">\n <li>\n <a\n className={language === 'zh' ? 'active' : ''}\n onClick={() => setLanguage('zh')}\n >\n 中文\n </a>\n </li>\n <li>\n <a\n className={language === 'en' ? 'active' : ''}\n onClick={() => setLanguage('en')}\n >\n English\n </a>\n </li>\n </ul>\n </div>\n\n <div className=\"dropdown dropdown-end\">\n <label tabIndex={0} className=\"btn btn-ghost\">\n {currentTheme.icon}\n </label>\n <ul tabIndex={0} className=\"menu dropdown-content p-2 shadow bg-base-100 rounded-box w-52 mt-4\">\n {themes.map((themeOption) => (\n <li key={themeOption.id}>\n <a\n className={theme === themeOption.id ? 'active' : ''}\n onClick={() => setTheme(themeOption.id)}\n >\n <span className=\"mr-2\">{themeOption.icon}</span>\n {language === 'zh' ? themeOption.name.zh : themeOption.name.en}\n </a>\n </li>\n ))}\n </ul>\n </div>\n </div>\n\n {/* 搜索对话框 */}\n {isSearchEnabled && (\n <dialog ref={modalRef} className=\"modal modal-bottom sm:modal-middle\" onClick={(e) => {\n if (e.target === modalRef.current) toggleSearch();\n }}>\n <div className=\"modal-box bg-base-100\">\n <div className=\"relative mb-4\">\n <input\n ref={searchInputRef}\n type=\"text\"\n placeholder={searchConfig?.placeholder?.[language] || t.navbar.searchPlaceholder}\n className=\"input input-bordered w-full pr-10\"\n value={searchTerm}\n onChange={handleSearch}\n />\n <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5 absolute top-3 right-3 opacity-50\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth=\"2\" d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\" />\n </svg>\n </div>\n\n <div className=\"search-results max-h-80 overflow-y-auto\">\n {searchResults.length > 0 ? (\n <ul className=\"menu bg-base-100 rounded-box\">\n {searchResults.map((result, index) => (\n <li key={index}>\n <a\n href={result.path}\n className=\"flex flex-col items-start\"\n onClick={() => toggleSearch()}\n >\n <div className=\"font-medium\">{result.title}</div>\n <div className=\"text-sm opacity-70\">{result.description}</div>\n </a>\n </li>\n ))}\n </ul>\n ) : searchTerm ? (\n <div className=\"py-4 text-center text-base-content/70\">\n {t.navbar.noResults}\n </div>\n ) : null}\n </div>\n\n <div className=\"modal-action\">\n <form method=\"dialog\">\n <button className=\"btn\" onClick={toggleSearch}>ESC</button>\n </form>\n </div>\n </div>\n </dialog>\n )}\n </div>\n );\n};\n\nexport default Navbar; "],"mappings":"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"}
1
+ {"version":3,"file":"Navbar.js","names":["defaultGetThemes","Navbar","propThemes","useAppContext","t","getTranslations","language","isSearchOpen","setIsSearchOpen","useState","searchTerm","setSearchTerm","searchResults","setSearchResults","searchInputRef","useRef","modalRef","themes","getThemes","currentTheme","theme","isSearchEnabled","searchConfig","toggleSearch","useEffect","handleKeyDown","height","onToggleSidebar","title","setLanguage","themeOption","setTheme","value","searchFn","result","index"],"sources":["../../src/layouts/Navbar.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef } from 'react';\nimport { ThemeType, useAppContext } from '../contexts/AppContext';\nimport { getTranslations } from '../utils/i18n';\nimport { ThemeConfig, getThemes as defaultGetThemes } from '../utils/themes';\n\nexport type SearchResult = {\n title: string;\n path: string;\n description: string;\n};\n\nexport type SearchConfig = {\n enabled: boolean;\n searchFunction?: (term: string, language: 'zh' | 'en') => SearchResult[];\n placeholder?: { zh: string; en: string };\n shortcut?: string;\n};\n\ntype NavbarProps = {\n onToggleSidebar: () => void;\n searchConfig?: SearchConfig;\n themes?: ThemeConfig[];\n height?: number; // Navbar 高度(像素)\n};\n\nconst Navbar: React.FC<NavbarProps> = ({ onToggleSidebar, searchConfig, themes: propThemes, height = 64 }) => {\n const { title = 'DiShUI', language, setLanguage, theme, setTheme } = useAppContext();\n const t = getTranslations(language);\n\n const [isSearchOpen, setIsSearchOpen] = useState(false);\n const [searchTerm, setSearchTerm] = useState('');\n const [searchResults, setSearchResults] = useState<SearchResult[]>([]);\n const searchInputRef = useRef<HTMLInputElement>(null);\n const modalRef = useRef<HTMLDialogElement>(null);\n\n // 获取主题配置:优先使用 propThemes,否则使用默认的\n const themes = propThemes || defaultGetThemes();\n\n // 获取当前主题\n const currentTheme = themes.find(t => t.id === theme) || themes[0];\n\n // 搜索是否启用\n const isSearchEnabled = searchConfig?.enabled ?? true;\n\n const toggleSearch = () => {\n setIsSearchOpen(!isSearchOpen);\n if (!isSearchOpen && modalRef.current) {\n modalRef.current.showModal();\n setTimeout(() => {\n searchInputRef.current?.focus();\n }, 100);\n } else if (modalRef.current) {\n modalRef.current.close();\n }\n };\n\n const handleSearch = (e: React.ChangeEvent<HTMLInputElement>) => {\n const value = e.target.value;\n setSearchTerm(value);\n // 使用外部提供的搜索函数\n const searchFn = searchConfig?.searchFunction;\n if (searchFn) {\n setSearchResults(searchFn(value, language));\n }\n };\n\n useEffect(() => {\n if (!isSearchEnabled) return;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if ((e.metaKey || e.ctrlKey) && e.key === 'k') {\n e.preventDefault();\n toggleSearch();\n }\n\n if (e.key === 'Escape' && isSearchOpen) {\n toggleSearch();\n }\n };\n\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n }, [isSearchOpen, isSearchEnabled]);\n\n // 当语言改变时,更新搜索结果\n useEffect(() => {\n if (searchTerm && isSearchEnabled && searchConfig?.searchFunction) {\n setSearchResults(searchConfig.searchFunction(searchTerm, language));\n }\n }, [language, searchConfig, isSearchEnabled, searchTerm]);\n\n return (\n <div className=\"navbar bg-base-100 shadow-md\" style={{ height: `${height}px`, minHeight: `${height}px`, maxHeight: `${height}px` }}>\n <div className=\"navbar-start\">\n <div className=\"flex-none lg:hidden\">\n <button className=\"btn btn-square btn-ghost\" onClick={onToggleSidebar}>\n <svg xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\" className=\"inline-block w-5 h-5 stroke-current\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth=\"2\" d=\"M4 6h16M4 12h16M4 18h16\"></path>\n </svg>\n </button>\n </div>\n <a href=\"/\" className=\"btn btn-ghost normal-case text-xl\">{title}</a>\n </div>\n\n {isSearchEnabled && (\n <div className=\"navbar-center hidden lg:flex\">\n <button\n className=\"btn btn-ghost gap-2\"\n onClick={toggleSearch}\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth=\"2\" d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\" />\n </svg>\n {searchConfig?.placeholder?.[language] || t.navbar.search} ({searchConfig?.shortcut || t.navbar.searchShortcut})\n </button>\n </div>\n )}\n\n <div className=\"navbar-end\">\n <div className=\"dropdown dropdown-end\">\n <label tabIndex={0} className=\"btn btn-ghost gap-1\">\n {language === 'zh' ? '中文' : 'English'}\n <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-4 w-4\" 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 </label>\n <ul tabIndex={0} className=\"menu dropdown-content p-2 shadow bg-base-100 rounded-box w-40 mt-4\">\n <li>\n <a\n className={language === 'zh' ? 'active' : ''}\n onClick={() => setLanguage('zh')}\n >\n 中文\n </a>\n </li>\n <li>\n <a\n className={language === 'en' ? 'active' : ''}\n onClick={() => setLanguage('en')}\n >\n English\n </a>\n </li>\n </ul>\n </div>\n\n <div className=\"dropdown dropdown-end\">\n <label tabIndex={0} className=\"btn btn-ghost\">\n {currentTheme.icon}\n </label>\n <ul tabIndex={0} className=\"menu dropdown-content p-2 shadow bg-base-100 rounded-box w-52 mt-4\">\n {themes.map((themeOption) => (\n <li key={themeOption.id}>\n <a\n className={theme === themeOption.id ? 'active' : ''}\n onClick={() => setTheme(themeOption.id)}\n >\n <span className=\"mr-2\">{themeOption.icon}</span>\n {language === 'zh' ? themeOption.name.zh : themeOption.name.en}\n </a>\n </li>\n ))}\n </ul>\n </div>\n </div>\n\n {/* 搜索对话框 */}\n {isSearchEnabled && (\n <dialog ref={modalRef} className=\"modal modal-bottom sm:modal-middle\" onClick={(e) => {\n if (e.target === modalRef.current) toggleSearch();\n }}>\n <div className=\"modal-box bg-base-100\">\n <div className=\"relative mb-4\">\n <input\n ref={searchInputRef}\n type=\"text\"\n placeholder={searchConfig?.placeholder?.[language] || t.navbar.searchPlaceholder}\n className=\"input input-bordered w-full pr-10\"\n value={searchTerm}\n onChange={handleSearch}\n />\n <svg xmlns=\"http://www.w3.org/2000/svg\" className=\"h-5 w-5 absolute top-3 right-3 opacity-50\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth=\"2\" d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\" />\n </svg>\n </div>\n\n <div className=\"search-results max-h-80 overflow-y-auto\">\n {searchResults.length > 0 ? (\n <ul className=\"menu bg-base-100 rounded-box\">\n {searchResults.map((result, index) => (\n <li key={index}>\n <a\n href={result.path}\n className=\"flex flex-col items-start\"\n onClick={() => toggleSearch()}\n >\n <div className=\"font-medium\">{result.title}</div>\n <div className=\"text-sm opacity-70\">{result.description}</div>\n </a>\n </li>\n ))}\n </ul>\n ) : searchTerm ? (\n <div className=\"py-4 text-center text-base-content/70\">\n {t.navbar.noResults}\n </div>\n ) : null}\n </div>\n\n <div className=\"modal-action\">\n <form method=\"dialog\">\n <button className=\"btn\" onClick={toggleSearch}>ESC</button>\n </form>\n </div>\n </div>\n </dialog>\n )}\n </div>\n );\n};\n\nexport default Navbar; "],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Sidebar.js","names":[],"sources":["../../src/layouts/Sidebar.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect, useMemo } from 'react';\nimport { createPortal } from 'react-dom';\nimport { Link, useNavigate, useRouterState } from '@tanstack/react-router';\nimport { MenuItem } from '../types/menu';\nimport { getMenuItems as defaultGetMenuItems } from '../utils/menu';\nimport { Tree, TreeNode } from '../components/Tree';\nimport { generateSidebarActiveStyles } from '../styles/themeStyles';\nimport { DesktopSidebarToggleButton } from '../components/SidebarToggleButton';\nimport Text, { type TextProps } from '../components/Text';\n\nexport type SidebarLevelText = Pick<TextProps, 'size' | 'weight' | 'color'>;\n\nexport type SidebarHeader = {\n name: React.ReactNode;\n icon?: React.ReactNode;\n onClick?: () => void;\n};\n\nexport type SidebarAction = {\n label: React.ReactNode;\n icon?: React.ReactNode;\n onClick?: () => void;\n};\n\nconst DefaultMenuIcon = () => (\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <rect x=\"4\" y=\"4\" width=\"16\" height=\"16\" rx=\"3\" />\n <path d=\"M8 9h8M8 13h8M8 17h5\" />\n </svg>\n);\n\nconst DefaultWorkspaceIcon = () => (\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"3\" />\n <path d=\"M9 3v18M9 10h12\" />\n </svg>\n);\n\nconst DefaultActionIcon = () => (\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\">\n <path d=\"M12 5v14M5 12h14\" />\n </svg>\n);\n\ntype RailTooltip = { target: HTMLElement; text: string; top: number; left: number; maxWidth: number; alignRight: boolean };\n\nconst getRailTooltip = (target: HTMLElement, sidebarElement: HTMLElement | null, side: 'left' | 'right', text: string): RailTooltip => {\n const rect = target.getBoundingClientRect();\n const sidebar = sidebarElement?.getBoundingClientRect() ?? rect;\n const spaceLeft = sidebar.left - 16;\n const spaceRight = window.innerWidth - sidebar.right - 16;\n const alignRight = side === 'right' ? spaceLeft >= 200 || spaceLeft > spaceRight : spaceRight < 200 && spaceLeft > spaceRight;\n return {\n target,\n text,\n top: Math.max(8, Math.min(rect.top, window.innerHeight - 48)),\n left: alignRight ? sidebar.left - 8 : sidebar.right + 8,\n maxWidth: Math.max(0, Math.min(320, alignRight ? spaceLeft : spaceRight)),\n alignRight,\n };\n};\n\nconst DEFAULT_LEVEL_TEXT = [\n { size: 'base', weight: 'semibold' },\n { size: 'sm', weight: 'medium' },\n { size: 'sm', weight: 'normal' },\n] as const satisfies readonly SidebarLevelText[];\n\n// 组件属性\nexport type SidebarProps = {\n isCollapsed: boolean;\n /** 侧栏所在侧,控制内侧 pill 的位置与调宽方向。 */\n side?: 'left' | 'right';\n language: 'zh' | 'en';\n items?: MenuItem[];\n /**\n * Opt-in typography for levels 1–3; deeper nodes reuse level 3.\n * Omitted: preserve legacy Sidebar/LayoutSuite typography. When supplied,\n * missing values default to base/sm/sm and semibold/medium/normal.\n * Levels 3+ default to theme-adaptive neutral gray, even without levelText.\n * Explicit colors retain Text semantics (secondary may be a theme accent).\n * Selected labels always inherit the active row color.\n */\n levelText?: readonly [SidebarLevelText?, SidebarLevelText?, SidebarLevelText?];\n getMenuItems?: (language: 'zh' | 'en') => MenuItem[];\n onWidthChange?: (width: number) => void;\n initialWidth?: number;\n collapsedWidth?: number;\n /**\n * 折叠 / 展开切换回调。传入后,侧边栏会在其边缘渲染统一的悬浮 pill 控制条\n * (点击折叠、拖拽调节宽度),无需再在外层单独渲染 SidebarToggleButtons。\n */\n onToggle?: () => void;\n /** 拖拽调节宽度的最小值(px) */\n minWidth?: number;\n /** 拖拽调节宽度的最大值(px) */\n maxWidth?: number;\n /** Optional AI-style workspace header shown above the tree. */\n workspace?: SidebarHeader;\n /** Optional primary sidebar action, such as “New chat”. */\n primaryAction?: SidebarAction;\n /** Optional footer rendered below the scrollable multi-level menu. */\n footer?: React.ReactNode;\n};\n\nconst Sidebar: React.FC<SidebarProps> = ({\n isCollapsed,\n side = 'left',\n language,\n items: propItems,\n levelText,\n getMenuItems,\n onWidthChange,\n initialWidth = 280,\n collapsedWidth = 64,\n onToggle,\n minWidth = 160,\n maxWidth = 400,\n workspace,\n primaryAction,\n footer,\n}) => {\n const [items, setItems] = useState<MenuItem[]>([]);\n const [activeNodeId, setActiveNodeId] = useState<string | number>('');\n const [sidebarWidth, setSidebarWidth] = useState(() => Math.max(minWidth, Math.min(initialWidth, maxWidth)));\n const sidebarRef = useRef<HTMLDivElement>(null);\n const scrollRef = useRef<HTMLDivElement>(null);\n const [railTooltip, setRailTooltip] = useState<RailTooltip | null>(null);\n const routerState = useRouterState({ select: (s: { location: { pathname: string } }) => s.location });\n const navigate = useNavigate();\n\n // 当 initialWidth 改变时,更新侧边栏宽度\n useEffect(() => {\n setSidebarWidth(Math.max(minWidth, Math.min(initialWidth, maxWidth)));\n }, [initialWidth, minWidth, maxWidth]);\n\n // 统一的宽度变更处理:同步内部状态并通知父组件。\n // pill 拖拽与外部同步都通过此入口,避免必须回传 initialWidth 才能生效。\n const handleInternalWidthChange = (width: number) => {\n const next = Math.max(minWidth, Math.min(width, maxWidth));\n setSidebarWidth(next);\n onWidthChange?.(next);\n };\n\n // 当语言改变或传入items prop时,更新菜单项\n useEffect(() => {\n if (propItems !== undefined) {\n setItems(propItems);\n } else if (getMenuItems) {\n setItems(getMenuItems(language));\n } else {\n setItems(defaultGetMenuItems(language));\n }\n }, [language, propItems, getMenuItems]);\n\n // 活跃节点变化时,自动滚动到可见区域(菜单过长时保证当前页可见)。\n // 延迟 350ms:Tree 展开动画(max-height 0.3s)期间布局仍在变化,立即\n // scrollIntoView 会计算到动画中途的位置而滚动不到位。\n useEffect(() => {\n if (!activeNodeId) return;\n const t = setTimeout(() => {\n scrollRef.current\n ?.querySelector(isCollapsed ? '[aria-current=\"page\"]' : '.tree-node-content-active')\n ?.scrollIntoView({ block: 'nearest', behavior: window.matchMedia('(prefers-reduced-motion: reduce)').matches ? 'instant' : 'smooth' });\n }, 350);\n return () => clearTimeout(t);\n }, [activeNodeId, isCollapsed]);\n\n // 兜底:确保鼠标悬停在菜单任意位置都能滚轮滚动。\n // 部分浏览器/嵌套滚动场景下原生滚轮可能不作用于该容器,这里用非被动\n // 监听手动滚动;成功滚动后 preventDefault,避免浏览器默认行为造成双重滚动。\n useEffect(() => {\n const el = scrollRef.current;\n if (!el) return;\n const onWheel = (e: WheelEvent) => {\n if (el.scrollHeight <= el.clientHeight) return;\n const dy = e.deltaMode === 1 ? e.deltaY * 16 : e.deltaY; // 行模式 → 像素\n if (dy === 0) return;\n const before = el.scrollTop;\n el.scrollTop = before + dy;\n if (el.scrollTop !== before) e.preventDefault();\n };\n el.addEventListener('wheel', onWheel, { passive: false });\n return () => el.removeEventListener('wheel', onWheel);\n }, [isCollapsed]);\n\n const showRailTooltip = (target: HTMLElement, text: string) => {\n setRailTooltip(getRailTooltip(target, sidebarRef.current, side, text));\n };\n\n const hideTooltipOnMouseLeave = (target: HTMLElement) => {\n if (document.activeElement !== target) setRailTooltip(current => current?.target === target ? null : current);\n };\n\n const hideTooltipOnBlur = (target: HTMLElement) => {\n if (!target.matches(':hover')) setRailTooltip(current => current?.target === target ? null : current);\n };\n\n useEffect(() => {\n if (!isCollapsed) return;\n const update = () => {\n setRailTooltip(current => current?.target.isConnected\n ? getRailTooltip(current.target, sidebarRef.current, side, current.text)\n : null);\n };\n window.addEventListener('resize', update);\n return () => window.removeEventListener('resize', update);\n }, [isCollapsed, side, sidebarRef]);\n\n // 将 MenuItem 转换为 TreeNode\n const convertToTreeNodes = (menuItems: MenuItem[]): TreeNode[] => {\n return menuItems.map(item => ({\n id: item.id,\n label: item.label,\n icon: item.icon ?? <DefaultMenuIcon />,\n children: item.children ? convertToTreeNodes(item.children) : undefined,\n meta: {\n path: item.path,\n },\n }));\n };\n\n // 转换后的树形数据\n const treeData = useMemo(() => convertToTreeNodes(items), [items]);\n\n // 获取默认展开的节点ID(默认全部展开)\n const defaultExpandedIds = useMemo(() => {\n if (items.length === 0) return [];\n\n // 收集所有有子节点的项的ID,使其默认全展开\n const collectAllExpandableIds = (menuItems: MenuItem[]): string[] => {\n let result: string[] = [];\n for (const item of menuItems) {\n if (item.children?.length) {\n result.push(item.id);\n result = [...result, ...collectAllExpandableIds(item.children)];\n }\n }\n return result;\n };\n\n return collectAllExpandableIds(items);\n }, [items]);\n\n // 更新活跃节点ID\n useEffect(() => {\n const currentPath = routerState.pathname;\n const findNodeByPath = (menuItems: MenuItem[]): string | null => {\n for (const item of menuItems) {\n if (item.path === currentPath) {\n return item.id;\n }\n if (item.children) {\n const found = findNodeByPath(item.children);\n if (found) return found;\n }\n }\n return null;\n };\n\n const nodeId = findNodeByPath(items);\n setActiveNodeId(nodeId ?? '');\n }, [items, routerState.pathname]);\n\n\n\n // 处理节点点击\n const handleNodeClick = (node: TreeNode) => {\n // 如果节点有路径,直接导航\n if (node.meta?.path) {\n setActiveNodeId(node.id);\n navigate({ to: node.meta.path });\n return;\n }\n\n // 如果没有路径但有子节点,寻找第一个有路径的后代节点\n if (node.children && node.children.length > 0) {\n const findFirstPath = (nodes: TreeNode[]): TreeNode | null => {\n for (const n of nodes) {\n if (n.meta?.path) return n;\n if (n.children && n.children.length > 0) {\n const found = findFirstPath(n.children);\n if (found) return found;\n }\n }\n return null;\n };\n\n const firstNodeWithPath = findFirstPath(node.children);\n if (firstNodeWithPath) {\n setActiveNodeId(firstNodeWithPath.id);\n navigate({ to: firstNodeWithPath.meta!.path });\n } else {\n // 全都没有路径则激活当前节点\n setActiveNodeId(node.id);\n }\n } else {\n setActiveNodeId(node.id);\n }\n };\n\n const collectLinks = (nodes: MenuItem[], parents: string[] = []): { item: MenuItem; trail: string }[] =>\n nodes.flatMap(item => {\n const trail = [...parents, item.label];\n return [\n ...(item.path ? [{ item, trail: trail.join(' / ') }] : []),\n ...collectLinks(item.children ?? [], trail),\n ];\n });\n\n /* Keep Tree mounted so rail toggles do not reset the user's expanded branches. */\n const rail = isCollapsed ? (\n <nav ref={scrollRef} className=\"sidebar-rail\" aria-label={language === 'zh' ? '侧边导航' : 'Sidebar navigation'} onScroll={() => {\n if (railTooltip?.target.isConnected) showRailTooltip(railTooltip.target, railTooltip.text);\n }}>\n {items.map(group => {\n const links = collectLinks([group]);\n return links.length > 0 ? (\n <div key={group.id} role=\"group\" aria-label={group.label} className=\"sidebar-rail-group\">\n {links.map(({ item, trail }) => (\n <Link\n key={item.id}\n to={item.path!}\n className=\"sidebar-rail-link\"\n aria-label={trail}\n title={trail}\n aria-current={routerState.pathname === item.path ? 'page' : undefined}\n onMouseEnter={event => showRailTooltip(event.currentTarget, trail)}\n onMouseLeave={event => hideTooltipOnMouseLeave(event.currentTarget)}\n onFocus={event => showRailTooltip(event.currentTarget, trail)}\n onBlur={event => hideTooltipOnBlur(event.currentTarget)}\n >\n <span aria-hidden=\"true\">{item.icon ?? <DefaultMenuIcon />}</span>\n </Link>\n ))}\n </div>\n ) : null;\n })}\n </nav>\n ) : null;\n\n return (\n <div\n ref={sidebarRef}\n className=\"dishui-sidebar sidebar-container h-full bg-base-200 overflow-visible flex flex-col transition-colors duration-200 ease-in-out relative\"\n style={isCollapsed ? { width: collapsedWidth } : { width: sidebarWidth, maxWidth, minWidth }}\n >\n {onToggle && (\n <DesktopSidebarToggleButton\n isCollapsed={isCollapsed}\n side={side}\n onToggle={onToggle}\n sidebarWidth={sidebarWidth}\n collapsedWidth={collapsedWidth}\n onWidthChange={onWidthChange ? handleInternalWidthChange : undefined}\n minWidth={minWidth}\n maxWidth={maxWidth}\n anchorRef={sidebarRef}\n />\n )}\n {(workspace || primaryAction) && (\n <div className=\"dishui-sidebar-ai-header\">\n {workspace && (\n <button\n type=\"button\"\n className=\"dishui-sidebar-ai-workspace\"\n onClick={workspace.onClick}\n aria-label={isCollapsed && typeof workspace.name === 'string' ? workspace.name : undefined}\n title={isCollapsed && typeof workspace.name === 'string' ? workspace.name : undefined}\n onMouseEnter={event => { if (isCollapsed && typeof workspace.name === 'string') showRailTooltip(event.currentTarget, workspace.name); }}\n onFocus={event => { if (isCollapsed && typeof workspace.name === 'string') showRailTooltip(event.currentTarget, workspace.name); }}\n onMouseLeave={event => hideTooltipOnMouseLeave(event.currentTarget)}\n onBlur={event => hideTooltipOnBlur(event.currentTarget)}\n >\n <span className=\"dishui-sidebar-ai-avatar\" aria-hidden=\"true\">{workspace.icon ?? <DefaultWorkspaceIcon />}</span>\n {!isCollapsed && <span className=\"dishui-sidebar-ai-workspace-name\">{workspace.name}</span>}\n </button>\n )}\n {primaryAction && (\n <button\n type=\"button\"\n className=\"dishui-sidebar-ai-action\"\n onClick={primaryAction.onClick}\n aria-label={isCollapsed && typeof primaryAction.label === 'string' ? primaryAction.label : undefined}\n title={isCollapsed && typeof primaryAction.label === 'string' ? primaryAction.label : undefined}\n onMouseEnter={event => { if (isCollapsed && typeof primaryAction.label === 'string') showRailTooltip(event.currentTarget, primaryAction.label); }}\n onFocus={event => { if (isCollapsed && typeof primaryAction.label === 'string') showRailTooltip(event.currentTarget, primaryAction.label); }}\n onMouseLeave={event => hideTooltipOnMouseLeave(event.currentTarget)}\n onBlur={event => hideTooltipOnBlur(event.currentTarget)}\n >\n <span aria-hidden=\"true\">{primaryAction.icon ?? <DefaultActionIcon />}</span>\n {!isCollapsed && <span>{primaryAction.label}</span>}\n </button>\n )}\n </div>\n )}\n {rail}\n {isCollapsed && railTooltip?.target.isConnected && createPortal(\n <div className=\"dishui-sidebar-rail-tooltip\" role=\"tooltip\" aria-hidden=\"true\" style={{ top: railTooltip.top, left: railTooltip.left, maxWidth: railTooltip.maxWidth, transform: railTooltip.alignRight ? 'translateX(-100%)' : undefined }}>\n {railTooltip.text}\n </div>,\n document.body,\n )}\n <div hidden={isCollapsed} style={isCollapsed ? { display: 'none' } : undefined} ref={isCollapsed ? undefined : scrollRef} className=\"sidebar-scroll min-h-0 flex-grow overflow-y-auto scrollbar-thin scrollbar-thumb-base-300 scrollbar-track-transparent\">\n <Tree\n data={treeData}\n activeNodeId={activeNodeId}\n defaultExpandedIds={defaultExpandedIds}\n showSearch={false}\n showExpandAll={false}\n showIcon={true}\n showCount={false}\n showLine={true}\n indent={1}\n togglePosition=\"right\"\n maxHeight=\"100%\"\n className={`sidebar-tree${levelText !== undefined ? ' sidebar-tree-level-text' : ''}`}\n renderLabel={(node, depth) => {\n const level = Math.min(depth, 2);\n const text = levelText?.[level];\n const defaults = DEFAULT_LEVEL_TEXT[level];\n return (\n <Text\n size={text?.size ?? defaults.size}\n weight={text?.weight ?? defaults.weight}\n color={activeNodeId === node.id ? 'inherit' : text?.color ?? 'inherit'}\n style={{\n ...(levelText === undefined ? { fontSize: 'inherit', lineHeight: 'inherit', fontWeight: 'inherit' } : {}),\n ...(level === 2 && text?.color === undefined && activeNodeId !== node.id\n ? { color: 'var(--sidebar-level-muted)' } : {}),\n }}\n >\n {node.label}\n {typeof node.id === 'string' && node.id.startsWith('ai-') && (\n <span className=\"dishui-sidebar-ai-native-badge\">AI</span>\n )}\n </Text>\n );\n }}\n onNodeClick={handleNodeClick}\n />\n </div>\n {footer && !isCollapsed && <div className=\"dishui-sidebar-ai-footer\">{footer}</div>}\n\n <style>{`\n .sidebar-container {\n --sidebar-level-muted: oklch(from color-mix(in oklab, var(--color-base-content) 76%, var(--color-base-200)) l 0 0);\n }\n /* LayoutSuite uses semantic surfaces even in colorful themes. Match its text luminance. */\n .dishui-layout-suite-sidebar > .sidebar-container {\n --sidebar-level-muted: oklch(from var(--dishui-text-tertiary) l 0 0);\n }\n .sidebar-rail { min-height: 0; height: 100%; overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain; padding: 6px; }\n .sidebar-rail-group { display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 4px 2px; margin-bottom: 8px; border: 1px solid var(--dishui-border-hairline, var(--color-base-300)); border-radius: 10px; }\n .sidebar-rail-link { display: flex; align-items: center; justify-content: center; width: 100%; max-width: 36px; min-height: 36px; flex-shrink: 0; border-radius: 6px; color: var(--sidebar-level-muted); text-decoration: none; transition: background-color 150ms, color 150ms; }\n .sidebar-rail-link > span { display: flex; align-items: center; justify-content: center; }\n .sidebar-rail-link svg { width: 16px; height: 16px; }\n .dishui-sidebar-ai-avatar svg, .dishui-sidebar-ai-action svg { width: 18px; height: 18px; }\n .dishui-sidebar-rail-tooltip { position: fixed; z-index: 1000; padding: 6px 8px; border: 1px solid var(--dishui-border-hairline, var(--color-base-300)); border-radius: 6px; background: var(--color-base-100); color: var(--color-base-content); box-shadow: 0 2px 8px color-mix(in oklab, var(--color-base-content) 15%, transparent); font-size: 12px; line-height: 1.4; overflow-wrap: anywhere; max-height: calc(100vh - 16px); overflow-y: auto; pointer-events: none; }\n .sidebar-rail-link:hover { background: var(--color-base-300); }\n .sidebar-rail-link[aria-current=\"page\"] { color: var(--color-primary); background: color-mix(in oklab, var(--color-primary) 12%, var(--color-base-200)); box-shadow: inset 2px 0 var(--color-primary); }\n .sidebar-rail-link:focus-visible { outline: 2px solid var(--dishui-ring, var(--color-primary)); outline-offset: -2px; }\n @media (prefers-reduced-motion: reduce) { .sidebar-rail-link { transition: none; } }\n /* Sidebar Tree 自定义样式 */\n .sidebar-tree {\n background: transparent;\n border: none;\n padding: 0.5rem;\n }\n \n .sidebar-tree .tree-node-content {\n padding: 0.5rem 1rem;\n border-radius: var(--dishui-radius-sm);\n transition: background-color var(--dishui-duration-normal) var(--dishui-ease-out), color var(--dishui-duration-normal) var(--dishui-ease-out), transform var(--dishui-duration-normal) var(--dishui-ease-out);\n }\n \n /* 活跃状态 - 为每个主题设置匹配的配色 */\n .sidebar-tree .tree-node-content-active {\n font-weight: 600 !important;\n padding-left: calc(1rem - 4px) !important;\n }\n \n /* 主题活跃状态样式 - 从共用配置生成 */\n ${generateSidebarActiveStyles()}\n \n /* 悬停状态 */\n .sidebar-tree .tree-node-content:hover:not(.tree-node-active .tree-node-content):not(.tree-node-content-active) {\n background-color: var(--color-base-200);\n }\n \n /* 右侧展开按钮样式 */\n .sidebar-tree .tree-node-toggle-right {\n width: auto;\n height: auto;\n min-width: auto;\n min-height: auto;\n padding: 0.25rem;\n opacity: 0.6;\n transition: opacity var(--dishui-duration-normal) var(--dishui-ease-out), background-color var(--dishui-duration-normal) var(--dishui-ease-out);\n border-radius: var(--dishui-radius-xs);\n }\n \n .sidebar-tree .tree-node-toggle-right:hover {\n opacity: 1;\n background-color: var(--color-base-300);\n }\n \n /* 右侧按钮图标旋转 */\n .sidebar-tree .tree-node-toggle-right svg {\n width: 1rem;\n height: 1rem;\n transition: transform var(--dishui-duration-normal) var(--dishui-ease-out);\n }\n \n .sidebar-tree .tree-node-toggle-right.tree-node-toggle-expanded svg {\n transform: rotate(90deg);\n }\n \n /* 图标样式 */\n .sidebar-tree .tree-node-icon {\n width: 20px;\n height: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n transition: color 0.2s ease;\n }\n \n .sidebar-tree .tree-node-icon svg {\n width: 20px;\n height: 20px;\n }\n \n /* 子节点图标稍小 */\n .sidebar-tree .tree-node-children .tree-node-icon svg {\n width: 18px;\n height: 18px;\n opacity: 0.8;\n }\n \n /* Preserve the legacy all-level appearance only when typography is not configured. */\n .sidebar-tree:not(.sidebar-tree-level-text) .tree-node-label {\n font-size: 1rem;\n line-height: 1.4rem;\n font-weight: 500;\n }\n \n /* 连接线样式 - 强制显示!向右移动并加粗,增加整体左边距 */\n /* 使用双重选择器增加优先级,避免被其他 Tree 组件样式覆盖 */\n .sidebar-tree.sidebar-tree .tree-show-line .tree-node-children-expanded,\n .sidebar-tree.sidebar-tree .tree-node-children.tree-node-children-expanded,\n div.sidebar-tree .tree-show-line .tree-node-children-expanded,\n div.sidebar-tree .tree-node-children.tree-node-children-expanded {\n border-left: 3px solid rgba(128, 128, 128, 0.35) !important;\n margin-left: 24px !important;\n padding-left: 8px !important;\n box-sizing: border-box !important;\n }\n \n /* 隐藏 Tree 组件的圆点装饰 - 避免与 Sidebar 样式冲突 */\n .sidebar-tree.sidebar-tree .tree-show-line .tree-node-children-expanded::before,\n div.sidebar-tree .tree-show-line .tree-node-children-expanded::before {\n display: none !important;\n }\n \n /* 隐藏 Tree 组件的标题和操作按钮 */\n .sidebar-tree .tree-header,\n .sidebar-tree .tree-search,\n .sidebar-tree .tree-actions {\n display: none;\n }\n \n /* 移除内边距 */\n .sidebar-tree > div:first-child {\n padding: 0;\n }\n \n /* 子节点动画优化 - 减小间距 */\n .sidebar-tree .tree-node-children {\n margin-top: 0.125rem !important;\n }\n \n /* 一级菜单项间距 */\n .sidebar-tree > div > .tree-nodes > .tree-node {\n margin-bottom: 0.375rem;\n }\n \n /* 二级菜单项间距 */\n .sidebar-tree .tree-node-children > .tree-node {\n margin-bottom: 0.125rem;\n }\n `}</style>\n </div>\n );\n};\n\nexport default Sidebar; "],"mappings":";;;;;;;;;;AAwBA,IAAM,UACJ,kBAAC,OAAD;CAAK,OAAM;CAA6B,SAAQ;CAAY,MAAK;CAAO,QAAO;CAAe,aAAY;CAAM,eAAc;CAAQ,gBAAe;CAArJ,UAAA,CACE,kBAAC,QAAD;EAAM,GAAE;EAAI,GAAE;EAAI,OAAM;EAAK,QAAO;EAAK,IAAG;CAAK,CAAA,GACjD,kBAAC,QAAD,EAAM,GAAE,uBAAwB,CAAA,CAC7B;IAGD,UACJ,kBAAC,OAAD;CAAK,OAAM;CAA6B,SAAQ;CAAY,MAAK;CAAO,QAAO;CAAe,aAAY;CAAM,eAAc;CAAQ,gBAAe;CAArJ,UAAA,CACE,kBAAC,QAAD;EAAM,GAAE;EAAI,GAAE;EAAI,OAAM;EAAK,QAAO;EAAK,IAAG;CAAK,CAAA,GACjD,kBAAC,QAAD,EAAM,GAAE,kBAAmB,CAAA,CACxB;IAGD,UACJ,kBAAC,OAAD;CAAK,OAAM;CAA6B,SAAQ;CAAY,MAAK;CAAO,QAAO;CAAe,aAAY;CAAM,eAAc;CAC5H,UAAA,kBAAC,QAAD,EAAM,GAAE,mBAAoB,CAAA;AACzB,CAAA,GAKD,KAAkB,GAAqB,GAAoC,GAAwB,MAA8B;CACrI,IAAM,IAAO,EAAO,sBAAsB,GACpC,IAAU,GAAgB,sBAAsB,KAAK,GACrD,IAAY,EAAQ,OAAO,IAC3B,IAAa,OAAO,aAAa,EAAQ,QAAQ,IACjD,IAAa,MAAS,UAAU,KAAa,OAAO,IAAY,IAAa,IAAa,OAAO,IAAY;CACnH,OAAO;EACL;EACA;EACA,KAAK,KAAK,IAAI,GAAG,KAAK,IAAI,EAAK,KAAK,OAAO,cAAc,EAAE,CAAC;EAC5D,MAAM,IAAa,EAAQ,OAAO,IAAI,EAAQ,QAAQ;EACtD,UAAU,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,IAAa,IAAY,CAAU,CAAC;EACxE;CACF;AACF,GAEM,IAAqB;CACzB;EAAE,MAAM;EAAQ,QAAQ;CAAW;CACnC;EAAE,MAAM;EAAM,QAAQ;CAAS;CAC/B;EAAE,MAAM;EAAM,QAAQ;CAAS;AACjC,GAuCM,KAAmC,EACvC,gBACA,UAAO,QACP,aACA,OAAO,GACP,cACA,cAAA,GACA,kBACA,kBAAe,KACf,oBAAiB,IACjB,aACA,cAAW,KACX,cAAW,KACX,cACA,kBACA,gBACI;CACJ,IAAM,CAAC,GAAO,KAAY,EAAqB,CAAC,CAAC,GAC3C,CAAC,GAAc,KAAmB,EAA0B,EAAE,GAC9D,CAAC,GAAc,KAAmB,QAAe,KAAK,IAAI,GAAU,KAAK,IAAI,GAAc,CAAQ,CAAC,CAAC,GACrG,IAAa,EAAuB,IAAI,GACxC,IAAY,EAAuB,IAAI,GACvC,CAAC,GAAa,KAAkB,EAA6B,IAAI,GACjE,IAAc,EAAe,EAAE,SAAS,MAA0C,EAAE,SAAS,CAAC,GAC9F,IAAW,EAAY;CAG7B,QAAgB;EACd,EAAgB,KAAK,IAAI,GAAU,KAAK,IAAI,GAAc,CAAQ,CAAC,CAAC;CACtE,GAAG;EAAC;EAAc;EAAU;CAAQ,CAAC;CAIrC,IAAM,KAA6B,MAAkB;EACnD,IAAM,IAAO,KAAK,IAAI,GAAU,KAAK,IAAI,GAAO,CAAQ,CAAC;EAEzD,AADA,EAAgB,CAAI,GACpB,IAAgB,CAAI;CACtB;CA6BA,AA1BA,QAAgB;EACd,AAGE,EAHE,MAAc,KAAA,IAEP,IACA,EAAa,CAAQ,IAErB,EAAoB,CAAQ,IAJ5B,CAI6B;CAE1C,GAAG;EAAC;EAAU;EAAW;CAAY,CAAC,GAKtC,QAAgB;EACd,IAAI,CAAC,GAAc;EACnB,IAAM,IAAI,iBAAiB;GACzB,EAAU,SACN,cAAc,IAAc,4BAA0B,2BAA2B,CAAC,EAClF,eAAe;IAAE,OAAO;IAAW,UAAU,OAAO,WAAW,kCAAkC,CAAC,CAAC,UAAU,YAAY;GAAS,CAAC;EACzI,GAAG,GAAG;EACN,aAAa,aAAa,CAAC;CAC7B,GAAG,CAAC,GAAc,CAAW,CAAC,GAK9B,QAAgB;EACd,IAAM,IAAK,EAAU;EACrB,IAAI,CAAC,GAAI;EACT,IAAM,KAAW,MAAkB;GACjC,IAAI,EAAG,gBAAgB,EAAG,cAAc;GACxC,IAAM,IAAK,EAAE,cAAc,IAAI,EAAE,SAAS,KAAK,EAAE;GACjD,IAAI,MAAO,GAAG;GACd,IAAM,IAAS,EAAG;GAElB,AADA,EAAG,YAAY,IAAS,GACpB,EAAG,cAAc,KAAQ,EAAE,eAAe;EAChD;EAEA,OADA,EAAG,iBAAiB,SAAS,GAAS,EAAE,SAAS,GAAM,CAAC,SAC3C,EAAG,oBAAoB,SAAS,CAAO;CACtD,GAAG,CAAC,CAAW,CAAC;CAEhB,IAAM,KAAmB,GAAqB,MAAiB;EAC7D,EAAe,EAAe,GAAQ,EAAW,SAAS,GAAM,CAAI,CAAC;CACvE,GAEM,KAA2B,MAAwB;EACvD,AAAI,SAAS,kBAAkB,KAAQ,GAAe,MAAW,GAAS,WAAW,IAAS,OAAO,CAAO;CAC9G,GAEM,KAAqB,MAAwB;EACjD,AAAK,EAAO,QAAQ,QAAQ,KAAG,GAAe,MAAW,GAAS,WAAW,IAAS,OAAO,CAAO;CACtG;CAEA,QAAgB;EACd,IAAI,CAAC,GAAa;EAClB,IAAM,UAAe;GACnB,GAAe,MAAW,GAAS,OAAO,cACtC,EAAe,EAAQ,QAAQ,EAAW,SAAS,GAAM,EAAQ,IAAI,IACrE,IAAI;EACV;EAEA,OADA,OAAO,iBAAiB,UAAU,CAAM,SAC3B,OAAO,oBAAoB,UAAU,CAAM;CAC1D,GAAG;EAAC;EAAa;EAAM;CAAU,CAAC;CAGlC,IAAM,KAAsB,MACnB,EAAU,KAAI,OAAS;EAC5B,IAAI,EAAK;EACT,OAAO,EAAK;EACZ,MAAM,EAAK,QAAQ,kBAAC,GAAD,CAAkB,CAAA;EACrC,UAAU,EAAK,WAAW,EAAmB,EAAK,QAAQ,IAAI,KAAA;EAC9D,MAAM,EACJ,MAAM,EAAK,KACb;CACF,EAAE,GAIE,IAAW,QAAc,EAAmB,CAAK,GAAG,CAAC,CAAK,CAAC,GAG3D,KAAqB,QAAc;EACvC,IAAI,EAAM,WAAW,GAAG,OAAO,CAAC;EAGhC,IAAM,KAA2B,MAAoC;GACnE,IAAI,IAAmB,CAAC;GACxB,KAAK,IAAM,KAAQ,GACjB,AAAI,EAAK,UAAU,WACjB,EAAO,KAAK,EAAK,EAAE,GACnB,IAAS,CAAC,GAAG,GAAQ,GAAG,EAAwB,EAAK,QAAQ,CAAC;GAGlE,OAAO;EACT;EAEA,OAAO,EAAwB,CAAK;CACtC,GAAG,CAAC,CAAK,CAAC;CAGV,QAAgB;EACd,IAAM,IAAc,EAAY,UAC1B,KAAkB,MAAyC;GAC/D,KAAK,IAAM,KAAQ,GAAW;IAC5B,IAAI,EAAK,SAAS,GAChB,OAAO,EAAK;IAEd,IAAI,EAAK,UAAU;KACjB,IAAM,IAAQ,EAAe,EAAK,QAAQ;KAC1C,IAAI,GAAO,OAAO;IACpB;GACF;GACA,OAAO;EACT,GAEM,IAAS,EAAe,CAAK;EACnC,EAAgB,KAAU,EAAE;CAC9B,GAAG,CAAC,GAAO,EAAY,QAAQ,CAAC;CAKhC,IAAM,MAAmB,MAAmB;EAE1C,IAAI,EAAK,MAAM,MAAM;GAEnB,AADA,EAAgB,EAAK,EAAE,GACvB,EAAS,EAAE,IAAI,EAAK,KAAK,KAAK,CAAC;GAC/B;EACF;EAGA,IAAI,EAAK,YAAY,EAAK,SAAS,SAAS,GAAG;GAC7C,IAAM,KAAiB,MAAuC;IAC5D,KAAK,IAAM,KAAK,GAAO;KACrB,IAAI,EAAE,MAAM,MAAM,OAAO;KACzB,IAAI,EAAE,YAAY,EAAE,SAAS,SAAS,GAAG;MACvC,IAAM,IAAQ,EAAc,EAAE,QAAQ;MACtC,IAAI,GAAO,OAAO;KACpB;IACF;IACA,OAAO;GACT,GAEM,IAAoB,EAAc,EAAK,QAAQ;GACrD,AAAI,KACF,EAAgB,EAAkB,EAAE,GACpC,EAAS,EAAE,IAAI,EAAkB,KAAM,KAAK,CAAC,KAG7C,EAAgB,EAAK,EAAE;EAE3B,OACE,EAAgB,EAAK,EAAE;CAE3B,GAEM,KAAgB,GAAmB,IAAoB,CAAC,MAC5D,EAAM,SAAQ,MAAQ;EACpB,IAAM,IAAQ,CAAC,GAAG,GAAS,EAAK,KAAK;EACrC,OAAO,CACL,GAAI,EAAK,OAAO,CAAC;GAAE;GAAM,OAAO,EAAM,KAAK,KAAK;EAAE,CAAC,IAAI,CAAC,GACxD,GAAG,EAAa,EAAK,YAAY,CAAC,GAAG,CAAK,CAC5C;CACF,CAAC,GAGG,KAAO,IACX,kBAAC,OAAD;EAAK,KAAK;EAAW,WAAU;EAAe,cAAY,MAAa,OAAO,SAAS;EAAsB,gBAAgB;GAC3H,AAAI,GAAa,OAAO,eAAa,EAAgB,EAAY,QAAQ,EAAY,IAAI;EAC3F;EACG,UAAA,EAAM,KAAI,MAAS;GAClB,IAAM,IAAQ,EAAa,CAAC,CAAK,CAAC;GAClC,OAAO,EAAM,SAAS,IACpB,kBAAC,OAAD;IAAoB,MAAK;IAAQ,cAAY,EAAM;IAAO,WAAU;IACjE,UAAA,EAAM,KAAK,EAAE,SAAM,eAClB,kBAAC,GAAD;KAEE,IAAI,EAAK;KACT,WAAU;KACV,cAAY;KACZ,OAAO;KACP,gBAAc,EAAY,aAAa,EAAK,OAAO,SAAS,KAAA;KAC5D,eAAc,MAAS,EAAgB,EAAM,eAAe,CAAK;KACjE,eAAc,MAAS,EAAwB,EAAM,aAAa;KAClE,UAAS,MAAS,EAAgB,EAAM,eAAe,CAAK;KAC5D,SAAQ,MAAS,EAAkB,EAAM,aAAa;KAEtD,UAAA,kBAAC,QAAD;MAAM,eAAY;MAAQ,UAAA,EAAK,QAAQ,kBAAC,GAAD,CAAkB,CAAA;KAAQ,CAAA;IAC7D,GAZC,EAAK,EAYN,CACP;GACE,GAjBK,EAAM,EAiBX,IACH;EACN,CAAC;CACE,CAAA,IACH;CAEJ,OACE,kBAAC,OAAD;EACE,KAAK;EACL,WAAU;EACV,OAAO,IAAc,EAAE,OAAO,EAAe,IAAI;GAAE,OAAO;GAAc;GAAU;EAAS;EAH7F,UAAA;GAKG,KACC,kBAAC,GAAD;IACe;IACP;IACI;IACI;IACE;IAChB,eAAe,IAAgB,IAA4B,KAAA;IACjD;IACA;IACV,WAAW;GACZ,CAAA;IAED,KAAa,MACb,kBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACG,KACC,kBAAC,UAAD;KACE,MAAK;KACL,WAAU;KACV,SAAS,EAAU;KACnB,cAAY,KAAe,OAAO,EAAU,QAAS,WAAW,EAAU,OAAO,KAAA;KACjF,OAAO,KAAe,OAAO,EAAU,QAAS,WAAW,EAAU,OAAO,KAAA;KAC5E,eAAc,MAAS;MAAE,AAAI,KAAe,OAAO,EAAU,QAAS,YAAU,EAAgB,EAAM,eAAe,EAAU,IAAI;KAAG;KACtI,UAAS,MAAS;MAAE,AAAI,KAAe,OAAO,EAAU,QAAS,YAAU,EAAgB,EAAM,eAAe,EAAU,IAAI;KAAG;KACjI,eAAc,MAAS,EAAwB,EAAM,aAAa;KAClE,SAAQ,MAAS,EAAkB,EAAM,aAAa;KATxD,UAAA,CAWE,kBAAC,QAAD;MAAM,WAAU;MAA2B,eAAY;MAAQ,UAAA,EAAU,QAAQ,kBAAC,GAAD,CAAuB,CAAA;KAAQ,CAAA,GAC/G,CAAC,KAAe,kBAAC,QAAD;MAAM,WAAU;MAAoC,UAAA,EAAU;KAAW,CAAA,CACpF;IAET,CAAA,GAAA,KACC,kBAAC,UAAD;KACE,MAAK;KACL,WAAU;KACV,SAAS,EAAc;KACvB,cAAY,KAAe,OAAO,EAAc,SAAU,WAAW,EAAc,QAAQ,KAAA;KAC3F,OAAO,KAAe,OAAO,EAAc,SAAU,WAAW,EAAc,QAAQ,KAAA;KACtF,eAAc,MAAS;MAAE,AAAI,KAAe,OAAO,EAAc,SAAU,YAAU,EAAgB,EAAM,eAAe,EAAc,KAAK;KAAG;KAChJ,UAAS,MAAS;MAAE,AAAI,KAAe,OAAO,EAAc,SAAU,YAAU,EAAgB,EAAM,eAAe,EAAc,KAAK;KAAG;KAC3I,eAAc,MAAS,EAAwB,EAAM,aAAa;KAClE,SAAQ,MAAS,EAAkB,EAAM,aAAa;KATxD,UAAA,CAWE,kBAAC,QAAD;MAAM,eAAY;MAAQ,UAAA,EAAc,QAAQ,kBAAC,GAAD,CAAoB,CAAA;KAAQ,CAAA,GAC3E,CAAC,KAAe,kBAAC,QAAD,EAAA,UAAO,EAAc,MAAY,CAAA,CAC5C;IAEP,CAAA,CAAA;;GAEN;GACA,KAAe,GAAa,OAAO,eAAe,EACjD,kBAAC,OAAD;IAAK,WAAU;IAA8B,MAAK;IAAU,eAAY;IAAO,OAAO;KAAE,KAAK,EAAY;KAAK,MAAM,EAAY;KAAM,UAAU,EAAY;KAAU,WAAW,EAAY,aAAa,sBAAsB,KAAA;IAAU;IACvO,UAAA,EAAY;GACV,CAAA,GACL,SAAS,IACX;GACA,kBAAC,OAAD;IAAK,QAAQ;IAAa,OAAO,IAAc,EAAE,SAAS,OAAO,IAAI,KAAA;IAAW,KAAK,IAAc,KAAA,IAAY;IAAW,WAAU;IAClI,UAAA,kBAAC,GAAD;KACE,MAAM;KACQ;KACM;KACpB,YAAY;KACZ,eAAe;KACf,UAAU;KACV,WAAW;KACX,UAAU;KACV,QAAQ;KACR,gBAAe;KACf,WAAU;KACV,WAAW,eAAe,MAAc,KAAA,IAAyC,KAA7B;KACpD,cAAc,GAAM,MAAU;MAC5B,IAAM,IAAQ,KAAK,IAAI,GAAO,CAAC,GACzB,IAAO,IAAY,IACnB,IAAW,EAAmB;MACpC,OACE,kBAAC,GAAD;OACE,MAAM,GAAM,QAAQ,EAAS;OAC7B,QAAQ,GAAM,UAAU,EAAS;OACjC,OAAO,MAAiB,EAAK,KAAK,YAAY,GAAM,SAAS;OAC7D,OAAO;QACL,GAAI,MAAc,KAAA,IAAY;SAAE,UAAU;SAAW,YAAY;SAAW,YAAY;QAAU,IAAI,CAAC;QACvG,GAAI,MAAU,KAAK,GAAM,UAAU,KAAA,KAAa,MAAiB,EAAK,KAClE,EAAE,OAAO,6BAA6B,IAAI,CAAC;OACjD;OARF,UAAA,CAUG,EAAK,OACL,OAAO,EAAK,MAAO,YAAY,EAAK,GAAG,WAAW,KAAK,KACtD,kBAAC,QAAD;QAAM,WAAU;QAAiC,UAAA;OAAQ,CAAA,CAEvD;;KAEV;KACA,aAAa;IACd,CAAA;GACE,CAAA;GACJ,KAAU,CAAC,KAAe,kBAAC,OAAD;IAAK,WAAU;IAA4B,UAAA;GAAY,CAAA;GAElF,kBAAC,SAAD,EAAA,UAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UAuCJ,EAA4B,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA6GzB,CAAA;EACN;;AAET"}
1
+ {"version":3,"file":"Sidebar.js","names":["getMenuItems","defaultGetMenuItems","Text","Tree","DefaultMenuIcon","DefaultWorkspaceIcon","DefaultActionIcon","getRailTooltip","rect","target","sidebar","sidebarElement","spaceLeft","spaceRight","alignRight","side","DEFAULT_LEVEL_TEXT","Sidebar","propItems","getMenuItems$1","items","setItems","useState","activeNodeId","setActiveNodeId","sidebarWidth","setSidebarWidth","minWidth","initialWidth","maxWidth","sidebarRef","useRef","scrollRef","railTooltip","setRailTooltip","routerState","useRouterState","s","navigate","useNavigate","handleInternalWidthChange","next","width","onWidthChange","useEffect","language","getMenuItems","t","isCollapsed","el","onWheel","dy","e","before","showRailTooltip","text","hideTooltipOnMouseLeave","current","hideTooltipOnBlur","update","convertToTreeNodes","menuItems","item","treeData","useMemo","defaultExpandedIds","collectAllExpandableIds","result","currentPath","findNodeByPath","found","nodeId","handleNodeClick","node","findFirstPath","nodes","firstNodeWithPath","collectLinks","trail","parents","rail","links","group","Link","event","collapsedWidth","onToggle","DesktopSidebarToggleButton","workspace","primaryAction","createPortal","levelText","level","depth","defaults","footer","generateSidebarActiveStyles"],"sources":["../../src/layouts/Sidebar.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect, useMemo } from 'react';\nimport { createPortal } from 'react-dom';\nimport { Link, useNavigate, useRouterState } from '@tanstack/react-router';\nimport { MenuItem } from '../types/menu';\nimport { getMenuItems as defaultGetMenuItems } from '../utils/menu';\nimport { Tree, TreeNode } from '../components/Tree';\nimport { generateSidebarActiveStyles } from '../styles/themeStyles';\nimport { DesktopSidebarToggleButton } from '../components/SidebarToggleButton';\nimport Text, { type TextProps } from '../components/Text';\n\nexport type SidebarLevelText = Pick<TextProps, 'size' | 'weight' | 'color'>;\n\nexport type SidebarHeader = {\n name: React.ReactNode;\n icon?: React.ReactNode;\n onClick?: () => void;\n};\n\nexport type SidebarAction = {\n label: React.ReactNode;\n icon?: React.ReactNode;\n onClick?: () => void;\n};\n\nconst DefaultMenuIcon = () => (\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <rect x=\"4\" y=\"4\" width=\"16\" height=\"16\" rx=\"3\" />\n <path d=\"M8 9h8M8 13h8M8 17h5\" />\n </svg>\n);\n\nconst DefaultWorkspaceIcon = () => (\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"3\" />\n <path d=\"M9 3v18M9 10h12\" />\n </svg>\n);\n\nconst DefaultActionIcon = () => (\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\">\n <path d=\"M12 5v14M5 12h14\" />\n </svg>\n);\n\ntype RailTooltip = { target: HTMLElement; text: string; top: number; left: number; maxWidth: number; alignRight: boolean };\n\nconst getRailTooltip = (target: HTMLElement, sidebarElement: HTMLElement | null, side: 'left' | 'right', text: string): RailTooltip => {\n const rect = target.getBoundingClientRect();\n const sidebar = sidebarElement?.getBoundingClientRect() ?? rect;\n const spaceLeft = sidebar.left - 16;\n const spaceRight = window.innerWidth - sidebar.right - 16;\n const alignRight = side === 'right' ? spaceLeft >= 200 || spaceLeft > spaceRight : spaceRight < 200 && spaceLeft > spaceRight;\n return {\n target,\n text,\n top: Math.max(8, Math.min(rect.top, window.innerHeight - 48)),\n left: alignRight ? sidebar.left - 8 : sidebar.right + 8,\n maxWidth: Math.max(0, Math.min(320, alignRight ? spaceLeft : spaceRight)),\n alignRight,\n };\n};\n\nconst DEFAULT_LEVEL_TEXT = [\n { size: 'base', weight: 'semibold' },\n { size: 'sm', weight: 'medium' },\n { size: 'sm', weight: 'normal' },\n] as const satisfies readonly SidebarLevelText[];\n\n// 组件属性\nexport type SidebarProps = {\n isCollapsed: boolean;\n /** 侧栏所在侧,控制内侧 pill 的位置与调宽方向。 */\n side?: 'left' | 'right';\n language: 'zh' | 'en';\n items?: MenuItem[];\n /**\n * Opt-in typography for levels 1–3; deeper nodes reuse level 3.\n * Omitted: preserve legacy Sidebar/LayoutSuite typography. When supplied,\n * missing values default to base/sm/sm and semibold/medium/normal.\n * Levels 3+ default to theme-adaptive neutral gray, even without levelText.\n * Explicit colors retain Text semantics (secondary may be a theme accent).\n * Selected labels always inherit the active row color.\n */\n levelText?: readonly [SidebarLevelText?, SidebarLevelText?, SidebarLevelText?];\n getMenuItems?: (language: 'zh' | 'en') => MenuItem[];\n onWidthChange?: (width: number) => void;\n initialWidth?: number;\n collapsedWidth?: number;\n /**\n * 折叠 / 展开切换回调。传入后,侧边栏会在其边缘渲染统一的悬浮 pill 控制条\n * (点击折叠、拖拽调节宽度),无需再在外层单独渲染 SidebarToggleButtons。\n */\n onToggle?: () => void;\n /** 拖拽调节宽度的最小值(px) */\n minWidth?: number;\n /** 拖拽调节宽度的最大值(px) */\n maxWidth?: number;\n /** Optional AI-style workspace header shown above the tree. */\n workspace?: SidebarHeader;\n /** Optional primary sidebar action, such as “New chat”. */\n primaryAction?: SidebarAction;\n /** Optional footer rendered below the scrollable multi-level menu. */\n footer?: React.ReactNode;\n};\n\nconst Sidebar: React.FC<SidebarProps> = ({\n isCollapsed,\n side = 'left',\n language,\n items: propItems,\n levelText,\n getMenuItems,\n onWidthChange,\n initialWidth = 280,\n collapsedWidth = 64,\n onToggle,\n minWidth = 160,\n maxWidth = 400,\n workspace,\n primaryAction,\n footer,\n}) => {\n const [items, setItems] = useState<MenuItem[]>([]);\n const [activeNodeId, setActiveNodeId] = useState<string | number>('');\n const [sidebarWidth, setSidebarWidth] = useState(() => Math.max(minWidth, Math.min(initialWidth, maxWidth)));\n const sidebarRef = useRef<HTMLDivElement>(null);\n const scrollRef = useRef<HTMLDivElement>(null);\n const [railTooltip, setRailTooltip] = useState<RailTooltip | null>(null);\n const routerState = useRouterState({ select: (s: { location: { pathname: string } }) => s.location });\n const navigate = useNavigate();\n\n // 当 initialWidth 改变时,更新侧边栏宽度\n useEffect(() => {\n setSidebarWidth(Math.max(minWidth, Math.min(initialWidth, maxWidth)));\n }, [initialWidth, minWidth, maxWidth]);\n\n // 统一的宽度变更处理:同步内部状态并通知父组件。\n // pill 拖拽与外部同步都通过此入口,避免必须回传 initialWidth 才能生效。\n const handleInternalWidthChange = (width: number) => {\n const next = Math.max(minWidth, Math.min(width, maxWidth));\n setSidebarWidth(next);\n onWidthChange?.(next);\n };\n\n // 当语言改变或传入items prop时,更新菜单项\n useEffect(() => {\n if (propItems !== undefined) {\n setItems(propItems);\n } else if (getMenuItems) {\n setItems(getMenuItems(language));\n } else {\n setItems(defaultGetMenuItems(language));\n }\n }, [language, propItems, getMenuItems]);\n\n // 活跃节点变化时,自动滚动到可见区域(菜单过长时保证当前页可见)。\n // 延迟 350ms:Tree 展开动画(max-height 0.3s)期间布局仍在变化,立即\n // scrollIntoView 会计算到动画中途的位置而滚动不到位。\n useEffect(() => {\n if (!activeNodeId) return;\n const t = setTimeout(() => {\n scrollRef.current\n ?.querySelector(isCollapsed ? '[aria-current=\"page\"]' : '.tree-node-content-active')\n ?.scrollIntoView({ block: 'nearest', behavior: window.matchMedia('(prefers-reduced-motion: reduce)').matches ? 'instant' : 'smooth' });\n }, 350);\n return () => clearTimeout(t);\n }, [activeNodeId, isCollapsed]);\n\n // 兜底:确保鼠标悬停在菜单任意位置都能滚轮滚动。\n // 部分浏览器/嵌套滚动场景下原生滚轮可能不作用于该容器,这里用非被动\n // 监听手动滚动;成功滚动后 preventDefault,避免浏览器默认行为造成双重滚动。\n useEffect(() => {\n const el = scrollRef.current;\n if (!el) return;\n const onWheel = (e: WheelEvent) => {\n if (el.scrollHeight <= el.clientHeight) return;\n const dy = e.deltaMode === 1 ? e.deltaY * 16 : e.deltaY; // 行模式 → 像素\n if (dy === 0) return;\n const before = el.scrollTop;\n el.scrollTop = before + dy;\n if (el.scrollTop !== before) e.preventDefault();\n };\n el.addEventListener('wheel', onWheel, { passive: false });\n return () => el.removeEventListener('wheel', onWheel);\n }, [isCollapsed]);\n\n const showRailTooltip = (target: HTMLElement, text: string) => {\n setRailTooltip(getRailTooltip(target, sidebarRef.current, side, text));\n };\n\n const hideTooltipOnMouseLeave = (target: HTMLElement) => {\n if (document.activeElement !== target) setRailTooltip(current => current?.target === target ? null : current);\n };\n\n const hideTooltipOnBlur = (target: HTMLElement) => {\n if (!target.matches(':hover')) setRailTooltip(current => current?.target === target ? null : current);\n };\n\n useEffect(() => {\n if (!isCollapsed) return;\n const update = () => {\n setRailTooltip(current => current?.target.isConnected\n ? getRailTooltip(current.target, sidebarRef.current, side, current.text)\n : null);\n };\n window.addEventListener('resize', update);\n return () => window.removeEventListener('resize', update);\n }, [isCollapsed, side, sidebarRef]);\n\n // 将 MenuItem 转换为 TreeNode\n const convertToTreeNodes = (menuItems: MenuItem[]): TreeNode[] => {\n return menuItems.map(item => ({\n id: item.id,\n label: item.label,\n icon: item.icon ?? <DefaultMenuIcon />,\n children: item.children ? convertToTreeNodes(item.children) : undefined,\n meta: {\n path: item.path,\n },\n }));\n };\n\n // 转换后的树形数据\n const treeData = useMemo(() => convertToTreeNodes(items), [items]);\n\n // 获取默认展开的节点ID(默认全部展开)\n const defaultExpandedIds = useMemo(() => {\n if (items.length === 0) return [];\n\n // 收集所有有子节点的项的ID,使其默认全展开\n const collectAllExpandableIds = (menuItems: MenuItem[]): string[] => {\n let result: string[] = [];\n for (const item of menuItems) {\n if (item.children?.length) {\n result.push(item.id);\n result = [...result, ...collectAllExpandableIds(item.children)];\n }\n }\n return result;\n };\n\n return collectAllExpandableIds(items);\n }, [items]);\n\n // 更新活跃节点ID\n useEffect(() => {\n const currentPath = routerState.pathname;\n const findNodeByPath = (menuItems: MenuItem[]): string | null => {\n for (const item of menuItems) {\n if (item.path === currentPath) {\n return item.id;\n }\n if (item.children) {\n const found = findNodeByPath(item.children);\n if (found) return found;\n }\n }\n return null;\n };\n\n const nodeId = findNodeByPath(items);\n setActiveNodeId(nodeId ?? '');\n }, [items, routerState.pathname]);\n\n\n\n // 处理节点点击\n const handleNodeClick = (node: TreeNode) => {\n // 如果节点有路径,直接导航\n if (node.meta?.path) {\n setActiveNodeId(node.id);\n navigate({ to: node.meta.path });\n return;\n }\n\n // 如果没有路径但有子节点,寻找第一个有路径的后代节点\n if (node.children && node.children.length > 0) {\n const findFirstPath = (nodes: TreeNode[]): TreeNode | null => {\n for (const n of nodes) {\n if (n.meta?.path) return n;\n if (n.children && n.children.length > 0) {\n const found = findFirstPath(n.children);\n if (found) return found;\n }\n }\n return null;\n };\n\n const firstNodeWithPath = findFirstPath(node.children);\n if (firstNodeWithPath) {\n setActiveNodeId(firstNodeWithPath.id);\n navigate({ to: firstNodeWithPath.meta!.path });\n } else {\n // 全都没有路径则激活当前节点\n setActiveNodeId(node.id);\n }\n } else {\n setActiveNodeId(node.id);\n }\n };\n\n const collectLinks = (nodes: MenuItem[], parents: string[] = []): { item: MenuItem; trail: string }[] =>\n nodes.flatMap(item => {\n const trail = [...parents, item.label];\n return [\n ...(item.path ? [{ item, trail: trail.join(' / ') }] : []),\n ...collectLinks(item.children ?? [], trail),\n ];\n });\n\n /* Keep Tree mounted so rail toggles do not reset the user's expanded branches. */\n const rail = isCollapsed ? (\n <nav ref={scrollRef} className=\"sidebar-rail\" aria-label={language === 'zh' ? '侧边导航' : 'Sidebar navigation'} onScroll={() => {\n if (railTooltip?.target.isConnected) showRailTooltip(railTooltip.target, railTooltip.text);\n }}>\n {items.map(group => {\n const links = collectLinks([group]);\n return links.length > 0 ? (\n <div key={group.id} role=\"group\" aria-label={group.label} className=\"sidebar-rail-group\">\n {links.map(({ item, trail }) => (\n <Link\n key={item.id}\n to={item.path!}\n className=\"sidebar-rail-link\"\n aria-label={trail}\n title={trail}\n aria-current={routerState.pathname === item.path ? 'page' : undefined}\n onMouseEnter={event => showRailTooltip(event.currentTarget, trail)}\n onMouseLeave={event => hideTooltipOnMouseLeave(event.currentTarget)}\n onFocus={event => showRailTooltip(event.currentTarget, trail)}\n onBlur={event => hideTooltipOnBlur(event.currentTarget)}\n >\n <span aria-hidden=\"true\">{item.icon ?? <DefaultMenuIcon />}</span>\n </Link>\n ))}\n </div>\n ) : null;\n })}\n </nav>\n ) : null;\n\n return (\n <div\n ref={sidebarRef}\n className=\"dishui-sidebar sidebar-container h-full bg-base-200 overflow-visible flex flex-col transition-colors duration-200 ease-in-out relative\"\n style={isCollapsed ? { width: collapsedWidth } : { width: sidebarWidth, maxWidth, minWidth }}\n >\n {onToggle && (\n <DesktopSidebarToggleButton\n isCollapsed={isCollapsed}\n side={side}\n onToggle={onToggle}\n sidebarWidth={sidebarWidth}\n collapsedWidth={collapsedWidth}\n onWidthChange={onWidthChange ? handleInternalWidthChange : undefined}\n minWidth={minWidth}\n maxWidth={maxWidth}\n anchorRef={sidebarRef}\n />\n )}\n {(workspace || primaryAction) && (\n <div className=\"dishui-sidebar-ai-header\">\n {workspace && (\n <button\n type=\"button\"\n className=\"dishui-sidebar-ai-workspace\"\n onClick={workspace.onClick}\n aria-label={isCollapsed && typeof workspace.name === 'string' ? workspace.name : undefined}\n title={isCollapsed && typeof workspace.name === 'string' ? workspace.name : undefined}\n onMouseEnter={event => { if (isCollapsed && typeof workspace.name === 'string') showRailTooltip(event.currentTarget, workspace.name); }}\n onFocus={event => { if (isCollapsed && typeof workspace.name === 'string') showRailTooltip(event.currentTarget, workspace.name); }}\n onMouseLeave={event => hideTooltipOnMouseLeave(event.currentTarget)}\n onBlur={event => hideTooltipOnBlur(event.currentTarget)}\n >\n <span className=\"dishui-sidebar-ai-avatar\" aria-hidden=\"true\">{workspace.icon ?? <DefaultWorkspaceIcon />}</span>\n {!isCollapsed && <span className=\"dishui-sidebar-ai-workspace-name\">{workspace.name}</span>}\n </button>\n )}\n {primaryAction && (\n <button\n type=\"button\"\n className=\"dishui-sidebar-ai-action\"\n onClick={primaryAction.onClick}\n aria-label={isCollapsed && typeof primaryAction.label === 'string' ? primaryAction.label : undefined}\n title={isCollapsed && typeof primaryAction.label === 'string' ? primaryAction.label : undefined}\n onMouseEnter={event => { if (isCollapsed && typeof primaryAction.label === 'string') showRailTooltip(event.currentTarget, primaryAction.label); }}\n onFocus={event => { if (isCollapsed && typeof primaryAction.label === 'string') showRailTooltip(event.currentTarget, primaryAction.label); }}\n onMouseLeave={event => hideTooltipOnMouseLeave(event.currentTarget)}\n onBlur={event => hideTooltipOnBlur(event.currentTarget)}\n >\n <span aria-hidden=\"true\">{primaryAction.icon ?? <DefaultActionIcon />}</span>\n {!isCollapsed && <span>{primaryAction.label}</span>}\n </button>\n )}\n </div>\n )}\n {rail}\n {isCollapsed && railTooltip?.target.isConnected && createPortal(\n <div className=\"dishui-sidebar-rail-tooltip\" role=\"tooltip\" aria-hidden=\"true\" style={{ top: railTooltip.top, left: railTooltip.left, maxWidth: railTooltip.maxWidth, transform: railTooltip.alignRight ? 'translateX(-100%)' : undefined }}>\n {railTooltip.text}\n </div>,\n document.body,\n )}\n <div hidden={isCollapsed} style={isCollapsed ? { display: 'none' } : undefined} ref={isCollapsed ? undefined : scrollRef} className=\"sidebar-scroll min-h-0 flex-grow overflow-y-auto scrollbar-thin scrollbar-thumb-base-300 scrollbar-track-transparent\">\n <Tree\n data={treeData}\n activeNodeId={activeNodeId}\n defaultExpandedIds={defaultExpandedIds}\n showSearch={false}\n showExpandAll={false}\n showIcon={true}\n showCount={false}\n showLine={true}\n indent={1}\n togglePosition=\"right\"\n maxHeight=\"100%\"\n className={`sidebar-tree${levelText !== undefined ? ' sidebar-tree-level-text' : ''}`}\n renderLabel={(node, depth) => {\n const level = Math.min(depth, 2);\n const text = levelText?.[level];\n const defaults = DEFAULT_LEVEL_TEXT[level];\n return (\n <Text\n size={text?.size ?? defaults.size}\n weight={text?.weight ?? defaults.weight}\n color={activeNodeId === node.id ? 'inherit' : text?.color ?? 'inherit'}\n style={{\n ...(levelText === undefined ? { fontSize: 'inherit', lineHeight: 'inherit', fontWeight: 'inherit' } : {}),\n ...(level === 2 && text?.color === undefined && activeNodeId !== node.id\n ? { color: 'var(--sidebar-level-muted)' } : {}),\n }}\n >\n {node.label}\n {typeof node.id === 'string' && node.id.startsWith('ai-') && (\n <span className=\"dishui-sidebar-ai-native-badge\">AI</span>\n )}\n </Text>\n );\n }}\n onNodeClick={handleNodeClick}\n />\n </div>\n {footer && !isCollapsed && <div className=\"dishui-sidebar-ai-footer\">{footer}</div>}\n\n <style>{`\n .sidebar-container {\n --sidebar-level-muted: oklch(from color-mix(in oklab, var(--color-base-content) 76%, var(--color-base-200)) l 0 0);\n }\n /* LayoutSuite uses semantic surfaces even in colorful themes. Match its text luminance. */\n .dishui-layout-suite-sidebar > .sidebar-container {\n --sidebar-level-muted: oklch(from var(--dishui-text-tertiary) l 0 0);\n }\n .sidebar-rail { min-height: 0; height: 100%; overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain; padding: 6px; }\n .sidebar-rail-group { display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 4px 2px; margin-bottom: 8px; border: 1px solid var(--dishui-border-hairline, var(--color-base-300)); border-radius: 10px; }\n .sidebar-rail-link { display: flex; align-items: center; justify-content: center; width: 100%; max-width: 36px; min-height: 36px; flex-shrink: 0; border-radius: 6px; color: var(--sidebar-level-muted); text-decoration: none; transition: background-color 150ms, color 150ms; }\n .sidebar-rail-link > span { display: flex; align-items: center; justify-content: center; }\n .sidebar-rail-link svg { width: 16px; height: 16px; }\n .dishui-sidebar-ai-avatar svg, .dishui-sidebar-ai-action svg { width: 18px; height: 18px; }\n .dishui-sidebar-rail-tooltip { position: fixed; z-index: 1000; padding: 6px 8px; border: 1px solid var(--dishui-border-hairline, var(--color-base-300)); border-radius: 6px; background: var(--color-base-100); color: var(--color-base-content); box-shadow: 0 2px 8px color-mix(in oklab, var(--color-base-content) 15%, transparent); font-size: 12px; line-height: 1.4; overflow-wrap: anywhere; max-height: calc(100vh - 16px); overflow-y: auto; pointer-events: none; }\n .sidebar-rail-link:hover { background: var(--color-base-300); }\n .sidebar-rail-link[aria-current=\"page\"] { color: var(--color-primary); background: color-mix(in oklab, var(--color-primary) 12%, var(--color-base-200)); box-shadow: inset 2px 0 var(--color-primary); }\n .sidebar-rail-link:focus-visible { outline: 2px solid var(--dishui-ring, var(--color-primary)); outline-offset: -2px; }\n @media (prefers-reduced-motion: reduce) { .sidebar-rail-link { transition: none; } }\n /* Sidebar Tree 自定义样式 */\n .sidebar-tree {\n background: transparent;\n border: none;\n padding: 0.5rem;\n }\n \n .sidebar-tree .tree-node-content {\n padding: 0.5rem 1rem;\n border-radius: var(--dishui-radius-sm);\n transition: background-color var(--dishui-duration-normal) var(--dishui-ease-out), color var(--dishui-duration-normal) var(--dishui-ease-out), transform var(--dishui-duration-normal) var(--dishui-ease-out);\n }\n \n /* 活跃状态 - 为每个主题设置匹配的配色 */\n .sidebar-tree .tree-node-content-active {\n font-weight: 600 !important;\n padding-left: calc(1rem - 4px) !important;\n }\n \n /* 主题活跃状态样式 - 从共用配置生成 */\n ${generateSidebarActiveStyles()}\n \n /* 悬停状态 */\n .sidebar-tree .tree-node-content:hover:not(.tree-node-active .tree-node-content):not(.tree-node-content-active) {\n background-color: var(--color-base-200);\n }\n \n /* 右侧展开按钮样式 */\n .sidebar-tree .tree-node-toggle-right {\n width: auto;\n height: auto;\n min-width: auto;\n min-height: auto;\n padding: 0.25rem;\n opacity: 0.6;\n transition: opacity var(--dishui-duration-normal) var(--dishui-ease-out), background-color var(--dishui-duration-normal) var(--dishui-ease-out);\n border-radius: var(--dishui-radius-xs);\n }\n \n .sidebar-tree .tree-node-toggle-right:hover {\n opacity: 1;\n background-color: var(--color-base-300);\n }\n \n /* 右侧按钮图标旋转 */\n .sidebar-tree .tree-node-toggle-right svg {\n width: 1rem;\n height: 1rem;\n transition: transform var(--dishui-duration-normal) var(--dishui-ease-out);\n }\n \n .sidebar-tree .tree-node-toggle-right.tree-node-toggle-expanded svg {\n transform: rotate(90deg);\n }\n \n /* 图标样式 */\n .sidebar-tree .tree-node-icon {\n width: 20px;\n height: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n transition: color 0.2s ease;\n }\n \n .sidebar-tree .tree-node-icon svg {\n width: 20px;\n height: 20px;\n }\n \n /* 子节点图标稍小 */\n .sidebar-tree .tree-node-children .tree-node-icon svg {\n width: 18px;\n height: 18px;\n opacity: 0.8;\n }\n \n /* Preserve the legacy all-level appearance only when typography is not configured. */\n .sidebar-tree:not(.sidebar-tree-level-text) .tree-node-label {\n font-size: 1rem;\n line-height: 1.4rem;\n font-weight: 500;\n }\n \n /* 连接线样式 - 强制显示!向右移动并加粗,增加整体左边距 */\n /* 使用双重选择器增加优先级,避免被其他 Tree 组件样式覆盖 */\n .sidebar-tree.sidebar-tree .tree-show-line .tree-node-children-expanded,\n .sidebar-tree.sidebar-tree .tree-node-children.tree-node-children-expanded,\n div.sidebar-tree .tree-show-line .tree-node-children-expanded,\n div.sidebar-tree .tree-node-children.tree-node-children-expanded {\n border-left: 3px solid rgba(128, 128, 128, 0.35) !important;\n margin-left: 24px !important;\n padding-left: 8px !important;\n box-sizing: border-box !important;\n }\n \n /* 隐藏 Tree 组件的圆点装饰 - 避免与 Sidebar 样式冲突 */\n .sidebar-tree.sidebar-tree .tree-show-line .tree-node-children-expanded::before,\n div.sidebar-tree .tree-show-line .tree-node-children-expanded::before {\n display: none !important;\n }\n \n /* 隐藏 Tree 组件的标题和操作按钮 */\n .sidebar-tree .tree-header,\n .sidebar-tree .tree-search,\n .sidebar-tree .tree-actions {\n display: none;\n }\n \n /* 移除内边距 */\n .sidebar-tree > div:first-child {\n padding: 0;\n }\n \n /* 子节点动画优化 - 减小间距 */\n .sidebar-tree .tree-node-children {\n margin-top: 0.125rem !important;\n }\n \n /* 一级菜单项间距 */\n .sidebar-tree > div > .tree-nodes > .tree-node {\n margin-bottom: 0.375rem;\n }\n \n /* 二级菜单项间距 */\n .sidebar-tree .tree-node-children > .tree-node {\n margin-bottom: 0.125rem;\n }\n `}</style>\n </div>\n );\n};\n\nexport default Sidebar; "],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Headbar.js","names":[],"sources":["../../../src/layouts/headbar/Headbar.tsx"],"sourcesContent":["import React from 'react';\n\nexport type HeadbarProps = {\n /** 左侧插槽内容 */\n left?: React.ReactNode;\n /** 中间插槽内容 */\n middle?: React.ReactNode;\n /** 右侧插槽内容 */\n right?: React.ReactNode;\n /** 高度(像素),默认 52 */\n height?: number;\n /** 自定义 className */\n className?: string;\n};\n\n/**\n * Headbar - 纯布局容器,提供 left / middle / right 三个插槽。\n * 不包含任何业务逻辑,所有内容通过 props 注入。\n */\nconst Headbar: React.FC<HeadbarProps> = ({\n left,\n middle,\n right,\n height = 52,\n className,\n}) => {\n return (\n <div\n className={`navbar bg-base-100 border-b border-base-300 ${className || ''}`}\n style={{\n height: `${height}px`,\n minHeight: `${height}px`,\n maxHeight: `${height}px`,\n }}\n >\n <div className=\"navbar-start\">{left}</div>\n <div className=\"navbar-center hidden lg:flex\">{middle}</div>\n <div className=\"navbar-end\">{right}</div>\n </div>\n );\n};\n\nexport default Headbar;\n"],"mappings":";;;AAmBA,IAAM,KAAmC,EACvC,SACA,WACA,UACA,YAAS,IACT,mBAGE,kBAAC,OAAD;CACE,WAAW,+CAA+C,KAAa;CACvE,OAAO;EACL,QAAQ,GAAG,EAAO;EAClB,WAAW,GAAG,EAAO;EACrB,WAAW,GAAG,EAAO;CACvB;CANF,UAAA;EAQE,kBAAC,OAAD;GAAK,WAAU;GAAgB,UAAA;EAAU,CAAA;EACzC,kBAAC,OAAD;GAAK,WAAU;GAAgC,UAAA;EAAY,CAAA;EAC3D,kBAAC,OAAD;GAAK,WAAU;GAAc,UAAA;EAAW,CAAA;CACrC"}
1
+ {"version":3,"file":"Headbar.js","names":["Headbar","className","height","left","middle","right"],"sources":["../../../src/layouts/headbar/Headbar.tsx"],"sourcesContent":["import React from 'react';\n\nexport type HeadbarProps = {\n /** 左侧插槽内容 */\n left?: React.ReactNode;\n /** 中间插槽内容 */\n middle?: React.ReactNode;\n /** 右侧插槽内容 */\n right?: React.ReactNode;\n /** 高度(像素),默认 52 */\n height?: number;\n /** 自定义 className */\n className?: string;\n};\n\n/**\n * Headbar - 纯布局容器,提供 left / middle / right 三个插槽。\n * 不包含任何业务逻辑,所有内容通过 props 注入。\n */\nconst Headbar: React.FC<HeadbarProps> = ({\n left,\n middle,\n right,\n height = 52,\n className,\n}) => {\n return (\n <div\n className={`navbar bg-base-100 border-b border-base-300 ${className || ''}`}\n style={{\n height: `${height}px`,\n minHeight: `${height}px`,\n maxHeight: `${height}px`,\n }}\n >\n <div className=\"navbar-start\">{left}</div>\n <div className=\"navbar-center hidden lg:flex\">{middle}</div>\n <div className=\"navbar-end\">{right}</div>\n </div>\n );\n};\n\nexport default Headbar;\n"],"mappings":";;;AAmBA,IAAMA,KAAmC,EACvC,SACA,WACA,UACA,YAAS,IACT,mBAGE,kBAAC,OAAD;CACE,WAAW,+CAA+CC,KAAa;CACvE,OAAO;EACL,QAAQ,GAAGC,EAAO;EAClB,WAAW,GAAGA,EAAO;EACrB,WAAW,GAAGA,EAAO;CACvB;CANF,UAAA;EAQE,kBAAC,OAAD;GAAK,WAAU;GAAgB,UAAAC;EAAU,CAAA;EACzC,kBAAC,OAAD;GAAK,WAAU;GAAgC,UAAAC;EAAY,CAAA;EAC3D,kBAAC,OAAD;GAAK,WAAU;GAAc,UAAAC;EAAW,CAAA;CACrC"}
@@ -1 +1 @@
1
- {"version":3,"file":"HeadbarLangSwitcher.js","names":[],"sources":["../../../src/layouts/headbar/HeadbarLangSwitcher.tsx"],"sourcesContent":["import React from 'react';\nimport { useAppContext } from '../../contexts/AppContext';\n\n/**\n * HeadbarLangSwitcher - 语言切换下拉菜单\n */\nconst HeadbarLangSwitcher: React.FC = () => {\n const { language, setLanguage } = useAppContext();\n\n return (\n <div className=\"dropdown dropdown-end\">\n <label tabIndex={0} className=\"btn btn-ghost gap-1\">\n {language === 'zh' ? '中文' : 'English'}\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"h-4 w-4\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"2\"\n d=\"M19 9l-7 7-7-7\"\n />\n </svg>\n </label>\n <ul\n tabIndex={0}\n className=\"menu dropdown-content p-2 shadow bg-base-100 rounded-box w-40 mt-4\"\n >\n <li>\n <a\n className={language === 'zh' ? 'active' : ''}\n onClick={() => setLanguage('zh')}\n >\n 中文\n </a>\n </li>\n <li>\n <a\n className={language === 'en' ? 'active' : ''}\n onClick={() => setLanguage('en')}\n >\n English\n </a>\n </li>\n </ul>\n </div>\n );\n};\n\nexport default HeadbarLangSwitcher;\n"],"mappings":";;;;AAMA,IAAM,UAAsC;CAC1C,IAAM,EAAE,aAAU,mBAAgB,EAAc;CAEhD,OACE,kBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,kBAAC,SAAD;GAAO,UAAU;GAAG,WAAU;GAA9B,UAAA,CACG,MAAa,OAAO,OAAO,WAC5B,kBAAC,OAAD;IACE,OAAM;IACN,WAAU;IACV,MAAK;IACL,SAAQ;IACR,QAAO;IAEP,UAAA,kBAAC,QAAD;KACE,eAAc;KACd,gBAAe;KACf,aAAY;KACZ,GAAE;IACH,CAAA;GACE,CAAA,CACA;EACP,CAAA,GAAA,kBAAC,MAAD;GACE,UAAU;GACV,WAAU;GAFZ,UAAA,CAIE,kBAAC,MAAD,EAAA,UACE,kBAAC,KAAD;IACE,WAAW,MAAa,OAAO,WAAW;IAC1C,eAAe,EAAY,IAAI;IAChC,UAAA;GAEE,CAAA,EACD,CAAA,GACJ,kBAAC,MAAD,EAAA,UACE,kBAAC,KAAD;IACE,WAAW,MAAa,OAAO,WAAW;IAC1C,eAAe,EAAY,IAAI;IAChC,UAAA;GAEE,CAAA,EACD,CAAA,CACF;EACD,CAAA,CAAA;;AAET"}
1
+ {"version":3,"file":"HeadbarLangSwitcher.js","names":["HeadbarLangSwitcher","useAppContext","language","setLanguage"],"sources":["../../../src/layouts/headbar/HeadbarLangSwitcher.tsx"],"sourcesContent":["import React from 'react';\nimport { useAppContext } from '../../contexts/AppContext';\n\n/**\n * HeadbarLangSwitcher - 语言切换下拉菜单\n */\nconst HeadbarLangSwitcher: React.FC = () => {\n const { language, setLanguage } = useAppContext();\n\n return (\n <div className=\"dropdown dropdown-end\">\n <label tabIndex={0} className=\"btn btn-ghost gap-1\">\n {language === 'zh' ? '中文' : 'English'}\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"h-4 w-4\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"2\"\n d=\"M19 9l-7 7-7-7\"\n />\n </svg>\n </label>\n <ul\n tabIndex={0}\n className=\"menu dropdown-content p-2 shadow bg-base-100 rounded-box w-40 mt-4\"\n >\n <li>\n <a\n className={language === 'zh' ? 'active' : ''}\n onClick={() => setLanguage('zh')}\n >\n 中文\n </a>\n </li>\n <li>\n <a\n className={language === 'en' ? 'active' : ''}\n onClick={() => setLanguage('en')}\n >\n English\n </a>\n </li>\n </ul>\n </div>\n );\n};\n\nexport default HeadbarLangSwitcher;\n"],"mappings":";;;;AAMA,IAAMA,UAAsC;CAC1C,IAAM,EAAE,aAAU,mBAAgBC,EAAc;CAEhD,OACE,kBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,kBAAC,SAAD;GAAO,UAAU;GAAG,WAAU;GAA9B,UAAA,CACGC,MAAa,OAAO,OAAO,WAC5B,kBAAC,OAAD;IACE,OAAM;IACN,WAAU;IACV,MAAK;IACL,SAAQ;IACR,QAAO;IAEP,UAAA,kBAAC,QAAD;KACE,eAAc;KACd,gBAAe;KACf,aAAY;KACZ,GAAE;IACH,CAAA;GACE,CAAA,CACA;EACP,CAAA,GAAA,kBAAC,MAAD;GACE,UAAU;GACV,WAAU;GAFZ,UAAA,CAIE,kBAAC,MAAD,EAAA,UACE,kBAAC,KAAD;IACE,WAAWA,MAAa,OAAO,WAAW;IAC1C,eAAeC,EAAY,IAAI;IAChC,UAAA;GAEE,CAAA,EACD,CAAA,GACJ,kBAAC,MAAD,EAAA,UACE,kBAAC,KAAD;IACE,WAAWD,MAAa,OAAO,WAAW;IAC1C,eAAeC,EAAY,IAAI;IAChC,UAAA;GAEE,CAAA,EACD,CAAA,CACF;EACD,CAAA,CAAA;;AAET"}
@@ -1 +1 @@
1
- {"version":3,"file":"HeadbarSearch.js","names":[],"sources":["../../../src/layouts/headbar/HeadbarSearch.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef } from 'react';\nimport { useAppContext } from '../../contexts/AppContext';\nimport { getTranslations } from '../../utils/i18n';\n\nexport type SearchResult = {\n title: string;\n path: string;\n description: string;\n};\n\nexport type SearchConfig = {\n enabled: boolean;\n searchFunction?: (term: string, language: 'zh' | 'en') => SearchResult[];\n placeholder?: { zh: string; en: string };\n shortcut?: string;\n};\n\nexport type HeadbarSearchProps = {\n /** 搜索配置 */\n searchConfig?: SearchConfig;\n};\n\n/**\n * HeadbarSearch - 搜索按钮 + 搜索对话框\n */\nconst HeadbarSearch: React.FC<HeadbarSearchProps> = ({ searchConfig }) => {\n const { language } = useAppContext();\n const t = getTranslations(language);\n\n const [isSearchOpen, setIsSearchOpen] = useState(false);\n const [searchTerm, setSearchTerm] = useState('');\n const [searchResults, setSearchResults] = useState<SearchResult[]>([]);\n const searchInputRef = useRef<HTMLInputElement>(null);\n const modalRef = useRef<HTMLDialogElement>(null);\n\n const isSearchEnabled = searchConfig?.enabled ?? true;\n\n const toggleSearch = () => {\n setIsSearchOpen(!isSearchOpen);\n if (!isSearchOpen && modalRef.current) {\n modalRef.current.showModal();\n setTimeout(() => {\n searchInputRef.current?.focus();\n }, 100);\n } else if (modalRef.current) {\n modalRef.current.close();\n }\n };\n\n const handleSearch = (e: React.ChangeEvent<HTMLInputElement>) => {\n const value = e.target.value;\n setSearchTerm(value);\n const searchFn = searchConfig?.searchFunction;\n if (searchFn) {\n setSearchResults(searchFn(value, language));\n }\n };\n\n useEffect(() => {\n if (!isSearchEnabled) return;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if ((e.metaKey || e.ctrlKey) && e.key === 'k') {\n e.preventDefault();\n toggleSearch();\n }\n if (e.key === 'Escape' && isSearchOpen) {\n toggleSearch();\n }\n };\n\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n }, [isSearchOpen, isSearchEnabled]);\n\n // 当语言改变时,更新搜索结果\n useEffect(() => {\n if (searchTerm && isSearchEnabled && searchConfig?.searchFunction) {\n setSearchResults(searchConfig.searchFunction(searchTerm, language));\n }\n }, [language, searchConfig, isSearchEnabled, searchTerm]);\n\n if (!isSearchEnabled) return null;\n\n return (\n <>\n <button className=\"btn btn-ghost gap-2\" onClick={toggleSearch}>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"h-5 w-5\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"2\"\n d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\"\n />\n </svg>\n {searchConfig?.placeholder?.[language] || t.navbar.search} (\n {searchConfig?.shortcut || t.navbar.searchShortcut})\n </button>\n\n {/* 搜索对话框 */}\n <dialog\n ref={modalRef}\n className=\"modal modal-bottom sm:modal-middle\"\n onClick={(e) => {\n if (e.target === modalRef.current) toggleSearch();\n }}\n >\n <div className=\"modal-box bg-base-100\">\n <div className=\"relative mb-4\">\n <input\n ref={searchInputRef}\n type=\"text\"\n placeholder={\n searchConfig?.placeholder?.[language] ||\n t.navbar.searchPlaceholder\n }\n className=\"input input-bordered w-full pr-10\"\n value={searchTerm}\n onChange={handleSearch}\n />\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"h-5 w-5 absolute top-3 right-3 opacity-50\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"2\"\n d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\"\n />\n </svg>\n </div>\n\n <div className=\"search-results max-h-80 overflow-y-auto\">\n {searchResults.length > 0 ? (\n <ul className=\"menu bg-base-100 rounded-box\">\n {searchResults.map((result, index) => (\n <li key={index}>\n <a\n href={result.path}\n className=\"flex flex-col items-start\"\n onClick={() => toggleSearch()}\n >\n <div className=\"font-medium\">{result.title}</div>\n <div className=\"text-sm opacity-70\">\n {result.description}\n </div>\n </a>\n </li>\n ))}\n </ul>\n ) : searchTerm ? (\n <div className=\"py-4 text-center text-base-content/70\">\n {t.navbar.noResults}\n </div>\n ) : null}\n </div>\n\n <div className=\"modal-action\">\n <form method=\"dialog\">\n <button className=\"btn\" onClick={toggleSearch}>\n ESC\n </button>\n </form>\n </div>\n </div>\n </dialog>\n </>\n );\n};\n\nexport default HeadbarSearch;\n"],"mappings":"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"}
1
+ {"version":3,"file":"HeadbarSearch.js","names":["_Fragment","HeadbarSearch","useAppContext","t","getTranslations","language","isSearchOpen","setIsSearchOpen","useState","searchTerm","setSearchTerm","searchResults","setSearchResults","searchInputRef","useRef","modalRef","isSearchEnabled","searchConfig","toggleSearch","useEffect","handleKeyDown","Fragment","value","searchFn","result","index"],"sources":["../../../src/layouts/headbar/HeadbarSearch.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef } from 'react';\nimport { useAppContext } from '../../contexts/AppContext';\nimport { getTranslations } from '../../utils/i18n';\n\nexport type SearchResult = {\n title: string;\n path: string;\n description: string;\n};\n\nexport type SearchConfig = {\n enabled: boolean;\n searchFunction?: (term: string, language: 'zh' | 'en') => SearchResult[];\n placeholder?: { zh: string; en: string };\n shortcut?: string;\n};\n\nexport type HeadbarSearchProps = {\n /** 搜索配置 */\n searchConfig?: SearchConfig;\n};\n\n/**\n * HeadbarSearch - 搜索按钮 + 搜索对话框\n */\nconst HeadbarSearch: React.FC<HeadbarSearchProps> = ({ searchConfig }) => {\n const { language } = useAppContext();\n const t = getTranslations(language);\n\n const [isSearchOpen, setIsSearchOpen] = useState(false);\n const [searchTerm, setSearchTerm] = useState('');\n const [searchResults, setSearchResults] = useState<SearchResult[]>([]);\n const searchInputRef = useRef<HTMLInputElement>(null);\n const modalRef = useRef<HTMLDialogElement>(null);\n\n const isSearchEnabled = searchConfig?.enabled ?? true;\n\n const toggleSearch = () => {\n setIsSearchOpen(!isSearchOpen);\n if (!isSearchOpen && modalRef.current) {\n modalRef.current.showModal();\n setTimeout(() => {\n searchInputRef.current?.focus();\n }, 100);\n } else if (modalRef.current) {\n modalRef.current.close();\n }\n };\n\n const handleSearch = (e: React.ChangeEvent<HTMLInputElement>) => {\n const value = e.target.value;\n setSearchTerm(value);\n const searchFn = searchConfig?.searchFunction;\n if (searchFn) {\n setSearchResults(searchFn(value, language));\n }\n };\n\n useEffect(() => {\n if (!isSearchEnabled) return;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if ((e.metaKey || e.ctrlKey) && e.key === 'k') {\n e.preventDefault();\n toggleSearch();\n }\n if (e.key === 'Escape' && isSearchOpen) {\n toggleSearch();\n }\n };\n\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n }, [isSearchOpen, isSearchEnabled]);\n\n // 当语言改变时,更新搜索结果\n useEffect(() => {\n if (searchTerm && isSearchEnabled && searchConfig?.searchFunction) {\n setSearchResults(searchConfig.searchFunction(searchTerm, language));\n }\n }, [language, searchConfig, isSearchEnabled, searchTerm]);\n\n if (!isSearchEnabled) return null;\n\n return (\n <>\n <button className=\"btn btn-ghost gap-2\" onClick={toggleSearch}>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"h-5 w-5\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"2\"\n d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\"\n />\n </svg>\n {searchConfig?.placeholder?.[language] || t.navbar.search} (\n {searchConfig?.shortcut || t.navbar.searchShortcut})\n </button>\n\n {/* 搜索对话框 */}\n <dialog\n ref={modalRef}\n className=\"modal modal-bottom sm:modal-middle\"\n onClick={(e) => {\n if (e.target === modalRef.current) toggleSearch();\n }}\n >\n <div className=\"modal-box bg-base-100\">\n <div className=\"relative mb-4\">\n <input\n ref={searchInputRef}\n type=\"text\"\n placeholder={\n searchConfig?.placeholder?.[language] ||\n t.navbar.searchPlaceholder\n }\n className=\"input input-bordered w-full pr-10\"\n value={searchTerm}\n onChange={handleSearch}\n />\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n className=\"h-5 w-5 absolute top-3 right-3 opacity-50\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"2\"\n d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\"\n />\n </svg>\n </div>\n\n <div className=\"search-results max-h-80 overflow-y-auto\">\n {searchResults.length > 0 ? (\n <ul className=\"menu bg-base-100 rounded-box\">\n {searchResults.map((result, index) => (\n <li key={index}>\n <a\n href={result.path}\n className=\"flex flex-col items-start\"\n onClick={() => toggleSearch()}\n >\n <div className=\"font-medium\">{result.title}</div>\n <div className=\"text-sm opacity-70\">\n {result.description}\n </div>\n </a>\n </li>\n ))}\n </ul>\n ) : searchTerm ? (\n <div className=\"py-4 text-center text-base-content/70\">\n {t.navbar.noResults}\n </div>\n ) : null}\n </div>\n\n <div className=\"modal-action\">\n <form method=\"dialog\">\n <button className=\"btn\" onClick={toggleSearch}>\n ESC\n </button>\n </form>\n </div>\n </div>\n </dialog>\n </>\n );\n};\n\nexport default HeadbarSearch;\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"HeadbarThemeSwitcher.js","names":[],"sources":["../../../src/layouts/headbar/HeadbarThemeSwitcher.tsx"],"sourcesContent":["import React from 'react';\nimport { useAppContext } from '../../contexts/AppContext';\nimport { ThemeConfig, getThemes as defaultGetThemes } from '../../utils/themes';\n\nexport type HeadbarThemeSwitcherProps = {\n /** 可选的主题配置列表,不传则使用默认主题列表 */\n themes?: ThemeConfig[];\n};\n\n/**\n * HeadbarThemeSwitcher - 主题切换下拉菜单\n */\nconst HeadbarThemeSwitcher: React.FC<HeadbarThemeSwitcherProps> = ({\n themes: propThemes,\n}) => {\n const { language, theme, setTheme } = useAppContext();\n\n const themes = propThemes || defaultGetThemes();\n const currentTheme = themes.find((t) => t.id === theme) || themes[0];\n\n return (\n <div className=\"dropdown dropdown-end\">\n <label tabIndex={0} className=\"btn btn-ghost\">\n {currentTheme.icon}\n </label>\n <ul\n tabIndex={0}\n className=\"menu dropdown-content p-2 shadow bg-base-100 rounded-box w-52 mt-4\"\n >\n {themes.map((themeOption) => (\n <li key={themeOption.id}>\n <a\n className={theme === themeOption.id ? 'active' : ''}\n onClick={() => setTheme(themeOption.id)}\n >\n <span className=\"mr-2\">{themeOption.icon}</span>\n {language === 'zh' ? themeOption.name.zh : themeOption.name.en}\n </a>\n </li>\n ))}\n </ul>\n </div>\n );\n};\n\nexport default HeadbarThemeSwitcher;\n"],"mappings":";;;;;AAYA,IAAM,KAA6D,EACjE,QAAQ,QACJ;CACJ,IAAM,EAAE,aAAU,UAAO,gBAAa,EAAc,GAE9C,IAAS,KAAc,EAAiB,GACxC,IAAe,EAAO,MAAM,MAAM,EAAE,OAAO,CAAK,KAAK,EAAO;CAElE,OACE,kBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,kBAAC,SAAD;GAAO,UAAU;GAAG,WAAU;GAC3B,UAAA,EAAa;EACT,CAAA,GACP,kBAAC,MAAD;GACE,UAAU;GACV,WAAU;GAET,UAAA,EAAO,KAAK,MACX,kBAAC,MAAD,EAAA,UACE,kBAAC,KAAD;IACE,WAAW,MAAU,EAAY,KAAK,WAAW;IACjD,eAAe,EAAS,EAAY,EAAE;IAFxC,UAAA,CAIE,kBAAC,QAAD;KAAM,WAAU;KAAQ,UAAA,EAAY;IAAW,CAAA,GAC9C,MAAa,OAAO,EAAY,KAAK,KAAK,EAAY,KAAK,EAC3D;GACD,CAAA,EAAA,GARK,EAAY,EAQjB,CACL;EACC,CAAA,CACD;;AAET"}
1
+ {"version":3,"file":"HeadbarThemeSwitcher.js","names":["defaultGetThemes","HeadbarThemeSwitcher","propThemes","useAppContext","themes","getThemes","currentTheme","t","theme","themeOption","setTheme","language"],"sources":["../../../src/layouts/headbar/HeadbarThemeSwitcher.tsx"],"sourcesContent":["import React from 'react';\nimport { useAppContext } from '../../contexts/AppContext';\nimport { ThemeConfig, getThemes as defaultGetThemes } from '../../utils/themes';\n\nexport type HeadbarThemeSwitcherProps = {\n /** 可选的主题配置列表,不传则使用默认主题列表 */\n themes?: ThemeConfig[];\n};\n\n/**\n * HeadbarThemeSwitcher - 主题切换下拉菜单\n */\nconst HeadbarThemeSwitcher: React.FC<HeadbarThemeSwitcherProps> = ({\n themes: propThemes,\n}) => {\n const { language, theme, setTheme } = useAppContext();\n\n const themes = propThemes || defaultGetThemes();\n const currentTheme = themes.find((t) => t.id === theme) || themes[0];\n\n return (\n <div className=\"dropdown dropdown-end\">\n <label tabIndex={0} className=\"btn btn-ghost\">\n {currentTheme.icon}\n </label>\n <ul\n tabIndex={0}\n className=\"menu dropdown-content p-2 shadow bg-base-100 rounded-box w-52 mt-4\"\n >\n {themes.map((themeOption) => (\n <li key={themeOption.id}>\n <a\n className={theme === themeOption.id ? 'active' : ''}\n onClick={() => setTheme(themeOption.id)}\n >\n <span className=\"mr-2\">{themeOption.icon}</span>\n {language === 'zh' ? themeOption.name.zh : themeOption.name.en}\n </a>\n </li>\n ))}\n </ul>\n </div>\n );\n};\n\nexport default HeadbarThemeSwitcher;\n"],"mappings":";;;;;AAYA,IAAMC,KAA6D,EACjE,QAAQC,QACJ;CACJ,IAAM,EAAE,aAAU,UAAO,gBAAaC,EAAc,GAE9CC,IAASF,KAAcF,EAAiB,GACxCM,IAAeF,EAAO,MAAM,MAAMG,EAAE,OAAOC,CAAK,KAAKJ,EAAO;CAElE,OACE,kBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,kBAAC,SAAD;GAAO,UAAU;GAAG,WAAU;GAC3B,UAAAE,EAAa;EACT,CAAA,GACP,kBAAC,MAAD;GACE,UAAU;GACV,WAAU;GAET,UAAAF,EAAO,KAAK,MACX,kBAAC,MAAD,EAAA,UACE,kBAAC,KAAD;IACE,WAAWI,MAAUC,EAAY,KAAK,WAAW;IACjD,eAAeC,EAASD,EAAY,EAAE;IAFxC,UAAA,CAIE,kBAAC,QAAD;KAAM,WAAU;KAAQ,UAAAA,EAAY;IAAW,CAAA,GAC9CE,MAAa,OAAOF,EAAY,KAAK,KAAKA,EAAY,KAAK,EAC3D;GACD,CAAA,EAAA,GARKA,EAAY,EAQjB,CACL;EACC,CAAA,CACD;;AAET"}
@@ -1 +1 @@
1
- {"version":3,"file":"HeadbarTitle.js","names":[],"sources":["../../../src/layouts/headbar/HeadbarTitle.tsx"],"sourcesContent":["import React from 'react';\n\nexport type HeadbarTitleProps = {\n /** 显示的标题 */\n title?: string;\n /** 点击 hamburger 按钮时的回调(移动端切换侧边栏) */\n onToggleSidebar?: () => void;\n};\n\n/**\n * HeadbarTitle - 左侧标题区域,包含移动端 hamburger 按钮 + 应用标题链接\n */\nconst HeadbarTitle: React.FC<HeadbarTitleProps> = ({\n title = 'DiShUI',\n onToggleSidebar,\n}) => {\n return (\n <>\n {onToggleSidebar && (\n <div className=\"flex-none lg:hidden\">\n <button className=\"btn btn-square btn-ghost\" onClick={onToggleSidebar}>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n className=\"inline-block w-5 h-5 stroke-current\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"2\"\n d=\"M4 6h16M4 12h16M4 18h16\"\n />\n </svg>\n </button>\n </div>\n )}\n <a href=\"/\" className=\"btn btn-ghost normal-case text-xl\">\n {title}\n </a>\n </>\n );\n};\n\nexport default HeadbarTitle;\n"],"mappings":";;;AAYA,IAAM,KAA6C,EACjD,WAAQ,UACR,yBAGE,kBAAA,GAAA,EAAA,UAAA,CACG,KACC,kBAAC,OAAD;CAAK,WAAU;CACb,UAAA,kBAAC,UAAD;EAAQ,WAAU;EAA2B,SAAS;EACpD,UAAA,kBAAC,OAAD;GACE,OAAM;GACN,MAAK;GACL,SAAQ;GACR,WAAU;GAEV,UAAA,kBAAC,QAAD;IACE,eAAc;IACd,gBAAe;IACf,aAAY;IACZ,GAAE;GACH,CAAA;EACE,CAAA;CACC,CAAA;AACL,CAAA,GAEP,kBAAC,KAAD;CAAG,MAAK;CAAI,WAAU;CACnB,UAAA;AACA,CAAA,CACH,EAAA,CAAA"}
1
+ {"version":3,"file":"HeadbarTitle.js","names":["_Fragment","HeadbarTitle","Fragment","onToggleSidebar","title"],"sources":["../../../src/layouts/headbar/HeadbarTitle.tsx"],"sourcesContent":["import React from 'react';\n\nexport type HeadbarTitleProps = {\n /** 显示的标题 */\n title?: string;\n /** 点击 hamburger 按钮时的回调(移动端切换侧边栏) */\n onToggleSidebar?: () => void;\n};\n\n/**\n * HeadbarTitle - 左侧标题区域,包含移动端 hamburger 按钮 + 应用标题链接\n */\nconst HeadbarTitle: React.FC<HeadbarTitleProps> = ({\n title = 'DiShUI',\n onToggleSidebar,\n}) => {\n return (\n <>\n {onToggleSidebar && (\n <div className=\"flex-none lg:hidden\">\n <button className=\"btn btn-square btn-ghost\" onClick={onToggleSidebar}>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n className=\"inline-block w-5 h-5 stroke-current\"\n >\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth=\"2\"\n d=\"M4 6h16M4 12h16M4 18h16\"\n />\n </svg>\n </button>\n </div>\n )}\n <a href=\"/\" className=\"btn btn-ghost normal-case text-xl\">\n {title}\n </a>\n </>\n );\n};\n\nexport default HeadbarTitle;\n"],"mappings":";;;AAYA,IAAMC,KAA6C,EACjD,WAAQ,UACR,yBAGE,kBAAAD,GAAA,EAAA,UAAA,CACGG,KACC,kBAAC,OAAD;CAAK,WAAU;CACb,UAAA,kBAAC,UAAD;EAAQ,WAAU;EAA2B,SAASA;EACpD,UAAA,kBAAC,OAAD;GACE,OAAM;GACN,MAAK;GACL,SAAQ;GACR,WAAU;GAEV,UAAA,kBAAC,QAAD;IACE,eAAc;IACd,gBAAe;IACf,aAAY;IACZ,GAAE;GACH,CAAA;EACE,CAAA;CACC,CAAA;AACL,CAAA,GAEP,kBAAC,KAAD;CAAG,MAAK;CAAI,WAAU;CACnB,UAAAC;AACA,CAAA,CACH,EAAA,CAAA"}
package/dist/sprite.js ADDED
@@ -0,0 +1,2 @@
1
+ import { Sprite as e } from "./components/pro/Sprite/Sprite2.js";
2
+ export { e as Sprite, e as default };
@@ -1 +1 @@
1
- {"version":3,"file":"themeStyles.js","names":[],"sources":["../../src/styles/themeStyles.ts"],"sourcesContent":["// 共用主题样式配置\n// 用于 Tree 组件和 Sidebar 组件的活跃状态样式\n\nexport interface ThemeActiveStyle {\n backgroundColor: string;\n borderColor: string;\n textColor: string;\n}\n\n// 主题配色映射\nexport const themeActiveStyles: Record<string, ThemeActiveStyle> = {\n light: {\n backgroundColor: 'var(--dishui-accent)',\n borderColor: 'var(--dishui-accent)',\n textColor: 'var(--dishui-accent-fg)',\n },\n dark: {\n backgroundColor: 'var(--dishui-accent)',\n borderColor: 'var(--dishui-accent)',\n textColor: 'var(--dishui-accent-fg)',\n },\n cursor: {\n backgroundColor: 'rgba(96, 165, 250, 0.16)',\n borderColor: 'rgb(96, 165, 250)',\n textColor: 'rgb(147, 197, 253)',\n },\n retro: {\n backgroundColor: 'rgba(239, 68, 68, 0.15)',\n borderColor: 'rgb(239, 68, 68)',\n textColor: 'rgb(239, 68, 68)',\n },\n cyberpunk: {\n backgroundColor: 'rgba(255, 221, 0, 0.18)',\n borderColor: 'rgb(255, 221, 0)',\n textColor: 'rgb(255, 221, 0)',\n },\n matrix: {\n backgroundColor: 'rgba(0, 255, 65, 0.15)',\n borderColor: 'rgb(0, 255, 65)',\n textColor: 'rgb(0, 255, 65)',\n },\n oceanblue: {\n backgroundColor: 'rgba(6, 95, 212, 0.18)',\n borderColor: 'rgb(6, 95, 212)',\n textColor: 'rgb(6, 95, 212)',\n },\n eyecare: {\n backgroundColor: 'rgba(34, 139, 34, 0.18)',\n borderColor: 'rgb(34, 139, 34)',\n textColor: 'rgb(34, 139, 34)',\n },\n ghibli: {\n backgroundColor: 'rgba(249, 115, 22, 0.18)',\n borderColor: 'rgb(249, 115, 22)',\n textColor: 'rgb(249, 115, 22)',\n },\n pinkgirl: {\n backgroundColor: 'rgba(236, 72, 153, 0.15)',\n borderColor: 'rgb(236, 72, 153)',\n textColor: 'rgb(236, 72, 153)',\n },\n mintgirl: {\n backgroundColor: 'rgba(52, 211, 153, 0.15)',\n borderColor: 'rgb(52, 211, 153)',\n textColor: 'rgb(52, 211, 153)',\n },\n\n wuxing: {\n backgroundColor: 'rgba(180, 120, 60, 0.15)',\n borderColor: 'rgb(180, 120, 60)',\n textColor: 'rgb(140, 90, 40)',\n },\n jukebox: {\n backgroundColor: 'rgba(147, 51, 234, 0.18)',\n borderColor: 'rgb(147, 51, 234)',\n textColor: 'rgb(167, 139, 250)',\n },\n};\n\n// 生成 Tree 组件的主题活跃状态 CSS\nexport const generateTreeActiveStyles = (): string => {\n return Object.entries(themeActiveStyles)\n .map(([theme, style]) => `\n /* ${theme.charAt(0).toUpperCase() + theme.slice(1)} 主题 */\n [data-theme=\"${theme}\"] .tree-node-content-active {\n background-color: ${style.backgroundColor} !important;\n border-left: 4px solid ${style.borderColor} !important;\n color: ${style.textColor} !important;\n }\n [data-theme=\"${theme}\"] .tree-node-content-active .tree-node-icon,\n [data-theme=\"${theme}\"] .tree-node-content-active .tree-node-label {\n color: ${style.textColor} !important;\n }`)\n .join('\\n');\n};\n\n// 生成 Sidebar 组件的主题活跃状态 CSS\nexport const generateSidebarActiveStyles = (): string => {\n return Object.entries(themeActiveStyles)\n .map(([theme, style]) => `\n /* ${theme.charAt(0).toUpperCase() + theme.slice(1)} 主题 */\n [data-theme=\"${theme}\"] .sidebar-tree .tree-node-content-active {\n background-color: ${style.backgroundColor} !important;\n border-left: 4px solid ${style.borderColor} !important;\n }\n [data-theme=\"${theme}\"] .sidebar-tree .tree-node-content-active .tree-node-label,\n [data-theme=\"${theme}\"] .sidebar-tree .tree-node-content-active .tree-node-icon svg {\n color: ${style.textColor} !important;\n stroke: ${style.textColor} !important;\n }`)\n .join('\\n');\n};\n\n"],"mappings":";AAUA,IAAa,IAAsD;CACjE,OAAO;EACL,iBAAiB;EACjB,aAAa;EACb,WAAW;CACb;CACA,MAAM;EACJ,iBAAiB;EACjB,aAAa;EACb,WAAW;CACb;CACA,QAAQ;EACN,iBAAiB;EACjB,aAAa;EACb,WAAW;CACb;CACA,OAAO;EACL,iBAAiB;EACjB,aAAa;EACb,WAAW;CACb;CACA,WAAW;EACT,iBAAiB;EACjB,aAAa;EACb,WAAW;CACb;CACA,QAAQ;EACN,iBAAiB;EACjB,aAAa;EACb,WAAW;CACb;CACA,WAAW;EACT,iBAAiB;EACjB,aAAa;EACb,WAAW;CACb;CACA,SAAS;EACP,iBAAiB;EACjB,aAAa;EACb,WAAW;CACb;CACA,QAAQ;EACN,iBAAiB;EACjB,aAAa;EACb,WAAW;CACb;CACA,UAAU;EACR,iBAAiB;EACjB,aAAa;EACb,WAAW;CACb;CACA,UAAU;EACR,iBAAiB;EACjB,aAAa;EACb,WAAW;CACb;CAEA,QAAQ;EACN,iBAAiB;EACjB,aAAa;EACb,WAAW;CACb;CACA,SAAS;EACP,iBAAiB;EACjB,aAAa;EACb,WAAW;CACb;AACF,GAGa,UACJ,OAAO,QAAQ,CAAiB,CAAC,CACrC,KAAK,CAAC,GAAO,OAAW;aAChB,EAAM,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,EAAM,MAAM,CAAC,EAAE;uBACrC,EAAM;8BACC,EAAM,gBAAgB;mCACjB,EAAM,YAAY;mBAClC,EAAM,UAAU;;uBAEZ,EAAM;uBACN,EAAM;mBACV,EAAM,UAAU;UACzB,CAAC,CACN,KAAK,IAAI,GAID,UACJ,OAAO,QAAQ,CAAiB,CAAC,CACrC,KAAK,CAAC,GAAO,OAAW;aAChB,EAAM,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,EAAM,MAAM,CAAC,EAAE;uBACrC,EAAM;8BACC,EAAM,gBAAgB;mCACjB,EAAM,YAAY;;uBAE9B,EAAM;uBACN,EAAM;mBACV,EAAM,UAAU;oBACf,EAAM,UAAU;UAC1B,CAAC,CACN,KAAK,IAAI"}
1
+ {"version":3,"file":"themeStyles.js","names":["themeActiveStyles","generateTreeActiveStyles","theme","style","generateSidebarActiveStyles"],"sources":["../../src/styles/themeStyles.ts"],"sourcesContent":["// 共用主题样式配置\n// 用于 Tree 组件和 Sidebar 组件的活跃状态样式\n\nexport interface ThemeActiveStyle {\n backgroundColor: string;\n borderColor: string;\n textColor: string;\n}\n\n// 主题配色映射\nexport const themeActiveStyles: Record<string, ThemeActiveStyle> = {\n light: {\n backgroundColor: 'var(--dishui-accent)',\n borderColor: 'var(--dishui-accent)',\n textColor: 'var(--dishui-accent-fg)',\n },\n dark: {\n backgroundColor: 'var(--dishui-accent)',\n borderColor: 'var(--dishui-accent)',\n textColor: 'var(--dishui-accent-fg)',\n },\n cursor: {\n backgroundColor: 'rgba(96, 165, 250, 0.16)',\n borderColor: 'rgb(96, 165, 250)',\n textColor: 'rgb(147, 197, 253)',\n },\n retro: {\n backgroundColor: 'rgba(239, 68, 68, 0.15)',\n borderColor: 'rgb(239, 68, 68)',\n textColor: 'rgb(239, 68, 68)',\n },\n cyberpunk: {\n backgroundColor: 'rgba(255, 221, 0, 0.18)',\n borderColor: 'rgb(255, 221, 0)',\n textColor: 'rgb(255, 221, 0)',\n },\n matrix: {\n backgroundColor: 'rgba(0, 255, 65, 0.15)',\n borderColor: 'rgb(0, 255, 65)',\n textColor: 'rgb(0, 255, 65)',\n },\n oceanblue: {\n backgroundColor: 'rgba(6, 95, 212, 0.18)',\n borderColor: 'rgb(6, 95, 212)',\n textColor: 'rgb(6, 95, 212)',\n },\n eyecare: {\n backgroundColor: 'rgba(34, 139, 34, 0.18)',\n borderColor: 'rgb(34, 139, 34)',\n textColor: 'rgb(34, 139, 34)',\n },\n ghibli: {\n backgroundColor: 'rgba(249, 115, 22, 0.18)',\n borderColor: 'rgb(249, 115, 22)',\n textColor: 'rgb(249, 115, 22)',\n },\n pinkgirl: {\n backgroundColor: 'rgba(236, 72, 153, 0.15)',\n borderColor: 'rgb(236, 72, 153)',\n textColor: 'rgb(236, 72, 153)',\n },\n mintgirl: {\n backgroundColor: 'rgba(52, 211, 153, 0.15)',\n borderColor: 'rgb(52, 211, 153)',\n textColor: 'rgb(52, 211, 153)',\n },\n\n wuxing: {\n backgroundColor: 'rgba(180, 120, 60, 0.15)',\n borderColor: 'rgb(180, 120, 60)',\n textColor: 'rgb(140, 90, 40)',\n },\n jukebox: {\n backgroundColor: 'rgba(147, 51, 234, 0.18)',\n borderColor: 'rgb(147, 51, 234)',\n textColor: 'rgb(167, 139, 250)',\n },\n};\n\n// 生成 Tree 组件的主题活跃状态 CSS\nexport const generateTreeActiveStyles = (): string => {\n return Object.entries(themeActiveStyles)\n .map(([theme, style]) => `\n /* ${theme.charAt(0).toUpperCase() + theme.slice(1)} 主题 */\n [data-theme=\"${theme}\"] .tree-node-content-active {\n background-color: ${style.backgroundColor} !important;\n border-left: 4px solid ${style.borderColor} !important;\n color: ${style.textColor} !important;\n }\n [data-theme=\"${theme}\"] .tree-node-content-active .tree-node-icon,\n [data-theme=\"${theme}\"] .tree-node-content-active .tree-node-label {\n color: ${style.textColor} !important;\n }`)\n .join('\\n');\n};\n\n// 生成 Sidebar 组件的主题活跃状态 CSS\nexport const generateSidebarActiveStyles = (): string => {\n return Object.entries(themeActiveStyles)\n .map(([theme, style]) => `\n /* ${theme.charAt(0).toUpperCase() + theme.slice(1)} 主题 */\n [data-theme=\"${theme}\"] .sidebar-tree .tree-node-content-active {\n background-color: ${style.backgroundColor} !important;\n border-left: 4px solid ${style.borderColor} !important;\n }\n [data-theme=\"${theme}\"] .sidebar-tree .tree-node-content-active .tree-node-label,\n [data-theme=\"${theme}\"] .sidebar-tree .tree-node-content-active .tree-node-icon svg {\n color: ${style.textColor} !important;\n stroke: ${style.textColor} !important;\n }`)\n .join('\\n');\n};\n\n"],"mappings":";AAUA,IAAaA,IAAsD;CACjE,OAAO;EACL,iBAAiB;EACjB,aAAa;EACb,WAAW;CACb;CACA,MAAM;EACJ,iBAAiB;EACjB,aAAa;EACb,WAAW;CACb;CACA,QAAQ;EACN,iBAAiB;EACjB,aAAa;EACb,WAAW;CACb;CACA,OAAO;EACL,iBAAiB;EACjB,aAAa;EACb,WAAW;CACb;CACA,WAAW;EACT,iBAAiB;EACjB,aAAa;EACb,WAAW;CACb;CACA,QAAQ;EACN,iBAAiB;EACjB,aAAa;EACb,WAAW;CACb;CACA,WAAW;EACT,iBAAiB;EACjB,aAAa;EACb,WAAW;CACb;CACA,SAAS;EACP,iBAAiB;EACjB,aAAa;EACb,WAAW;CACb;CACA,QAAQ;EACN,iBAAiB;EACjB,aAAa;EACb,WAAW;CACb;CACA,UAAU;EACR,iBAAiB;EACjB,aAAa;EACb,WAAW;CACb;CACA,UAAU;EACR,iBAAiB;EACjB,aAAa;EACb,WAAW;CACb;CAEA,QAAQ;EACN,iBAAiB;EACjB,aAAa;EACb,WAAW;CACb;CACA,SAAS;EACP,iBAAiB;EACjB,aAAa;EACb,WAAW;CACb;AACF,GAGaC,UACJ,OAAO,QAAQD,CAAiB,CAAC,CACrC,KAAK,CAACE,GAAOC,OAAW;aAChBD,EAAM,OAAO,CAAC,CAAC,CAAC,YAAY,IAAIA,EAAM,MAAM,CAAC,EAAE;uBACrCA,EAAM;8BACCC,EAAM,gBAAgB;mCACjBA,EAAM,YAAY;mBAClCA,EAAM,UAAU;;uBAEZD,EAAM;uBACNA,EAAM;mBACVC,EAAM,UAAU;UACzB,CAAC,CACN,KAAK,IAAI,GAIDC,UACJ,OAAO,QAAQJ,CAAiB,CAAC,CACrC,KAAK,CAACE,GAAOC,OAAW;aAChBD,EAAM,OAAO,CAAC,CAAC,CAAC,YAAY,IAAIA,EAAM,MAAM,CAAC,EAAE;uBACrCA,EAAM;8BACCC,EAAM,gBAAgB;mCACjBA,EAAM,YAAY;;uBAE9BD,EAAM;uBACNA,EAAM;mBACVC,EAAM,UAAU;oBACfA,EAAM,UAAU;UAC1B,CAAC,CACN,KAAK,IAAI"}
@@ -1 +1 @@
1
- {"version":3,"file":"cn.js","names":[],"sources":["../../src/utils/cn.ts"],"sourcesContent":["/**\n * cn - 轻量级 className 合并工具(零依赖)。\n *\n * 统一替代代码库中散落的 `[a, b, c].filter(Boolean).join(' ')` 写法。\n * 支持字符串、数字、数组以及对象(`{ 'foo': cond }`)形式的条件类名。\n *\n * @example\n * cn('btn', isActive && 'btn-active', { 'btn-lg': large })\n * // => 'btn btn-active btn-lg'\n */\nexport type ClassValue =\n | string\n | number\n | null\n | undefined\n | false\n | ClassValue[]\n | Record<string, boolean | null | undefined>;\n\nexport function cn(...inputs: ClassValue[]): string {\n const classes: string[] = [];\n\n for (const input of inputs) {\n if (!input) continue;\n\n if (typeof input === 'string' || typeof input === 'number') {\n classes.push(String(input));\n } else if (Array.isArray(input)) {\n const nested = cn(...input);\n if (nested) classes.push(nested);\n } else if (typeof input === 'object') {\n for (const key in input) {\n if (input[key]) classes.push(key);\n }\n }\n }\n\n return classes.join(' ');\n}\n\nexport default cn;\n"],"mappings":";AAmBA,SAAgB,EAAG,GAAG,GAA8B;CAClD,IAAM,IAAoB,CAAC;CAE3B,KAAK,IAAM,KAAS,GACb,OAEL;MAAI,OAAO,KAAU,YAAY,OAAO,KAAU,UAChD,EAAQ,KAAK,OAAO,CAAK,CAAC;OACrB,IAAI,MAAM,QAAQ,CAAK,GAAG;GAC/B,IAAM,IAAS,EAAG,GAAG,CAAK;GAC1B,AAAI,KAAQ,EAAQ,KAAK,CAAM;EACjC,OAAO,IAAI,OAAO,KAAU,UACrB,KAAA,IAAM,KAAO,GAChB,AAAI,EAAM,MAAM,EAAQ,KAAK,CAAG;CAClC;CAIJ,OAAO,EAAQ,KAAK,GAAG;AACzB"}
1
+ {"version":3,"file":"cn.js","names":["cn","inputs","classes","input","nested","key"],"sources":["../../src/utils/cn.ts"],"sourcesContent":["/**\n * cn - 轻量级 className 合并工具(零依赖)。\n *\n * 统一替代代码库中散落的 `[a, b, c].filter(Boolean).join(' ')` 写法。\n * 支持字符串、数字、数组以及对象(`{ 'foo': cond }`)形式的条件类名。\n *\n * @example\n * cn('btn', isActive && 'btn-active', { 'btn-lg': large })\n * // => 'btn btn-active btn-lg'\n */\nexport type ClassValue =\n | string\n | number\n | null\n | undefined\n | false\n | ClassValue[]\n | Record<string, boolean | null | undefined>;\n\nexport function cn(...inputs: ClassValue[]): string {\n const classes: string[] = [];\n\n for (const input of inputs) {\n if (!input) continue;\n\n if (typeof input === 'string' || typeof input === 'number') {\n classes.push(String(input));\n } else if (Array.isArray(input)) {\n const nested = cn(...input);\n if (nested) classes.push(nested);\n } else if (typeof input === 'object') {\n for (const key in input) {\n if (input[key]) classes.push(key);\n }\n }\n }\n\n return classes.join(' ');\n}\n\nexport default cn;\n"],"mappings":";AAmBA,SAAgBA,EAAG,GAAGC,GAA8B;CAClD,IAAMC,IAAoB,CAAC;CAE3B,KAAK,IAAMC,KAASF,GAClB,IAAKE,GAEL;MAAI,OAAOA,KAAU,YAAY,OAAOA,KAAU,UAChD,EAAQ,KAAK,OAAOA,CAAK,CAAC;OACrB,IAAI,MAAM,QAAQA,CAAK,GAAG;GAC/B,IAAMC,IAASJ,EAAG,GAAGG,CAAK;GAC1B,AAAIC,KAAQF,EAAQ,KAAKE,CAAM;EACjC,OAAO,IAAI,OAAOD,KAAU,UACrB,KAAA,IAAME,KAAOF,GAChB,AAAIA,EAAME,MAAMH,EAAQ,KAAKG,CAAG;CAClC;CAIJ,OAAOH,EAAQ,KAAK,GAAG;AACzB"}
@@ -1 +1 @@
1
- {"version":3,"file":"flexLayout.js","names":[],"sources":["../../src/utils/flexLayout.ts"],"sourcesContent":["export type FlexAlign = 'start' | 'center' | 'end' | 'baseline' | 'stretch';\nexport type FlexJustify = 'start' | 'center' | 'end' | 'between' | 'around' | 'evenly';\n\nexport const FLEX_ALIGN_CLASS: Record<FlexAlign, string> = {\n start: 'items-start',\n center: 'items-center',\n end: 'items-end',\n baseline: 'items-baseline',\n stretch: 'items-stretch',\n};\n\nexport const FLEX_JUSTIFY_CLASS: Record<FlexJustify, string> = {\n start: 'justify-start',\n center: 'justify-center',\n end: 'justify-end',\n between: 'justify-between',\n around: 'justify-around',\n evenly: 'justify-evenly',\n};\n\nexport const flexGap = (value: number | string | undefined): string | undefined =>\n typeof value === 'number' ? `${value}px` : value;\n"],"mappings":";AAGA,IAAa,IAA8C;CACzD,OAAO;CACP,QAAQ;CACR,KAAK;CACL,UAAU;CACV,SAAS;AACX,GAEa,IAAkD;CAC7D,OAAO;CACP,QAAQ;CACR,KAAK;CACL,SAAS;CACT,QAAQ;CACR,QAAQ;AACV,GAEa,KAAW,MACtB,OAAO,KAAU,WAAW,GAAG,EAAM,MAAM"}
1
+ {"version":3,"file":"flexLayout.js","names":["FLEX_ALIGN_CLASS","FLEX_JUSTIFY_CLASS","flexGap","value"],"sources":["../../src/utils/flexLayout.ts"],"sourcesContent":["export type FlexAlign = 'start' | 'center' | 'end' | 'baseline' | 'stretch';\nexport type FlexJustify = 'start' | 'center' | 'end' | 'between' | 'around' | 'evenly';\n\nexport const FLEX_ALIGN_CLASS: Record<FlexAlign, string> = {\n start: 'items-start',\n center: 'items-center',\n end: 'items-end',\n baseline: 'items-baseline',\n stretch: 'items-stretch',\n};\n\nexport const FLEX_JUSTIFY_CLASS: Record<FlexJustify, string> = {\n start: 'justify-start',\n center: 'justify-center',\n end: 'justify-end',\n between: 'justify-between',\n around: 'justify-around',\n evenly: 'justify-evenly',\n};\n\nexport const flexGap = (value: number | string | undefined): string | undefined =>\n typeof value === 'number' ? `${value}px` : value;\n"],"mappings":";AAGA,IAAaA,IAA8C;CACzD,OAAO;CACP,QAAQ;CACR,KAAK;CACL,UAAU;CACV,SAAS;AACX,GAEaC,IAAkD;CAC7D,OAAO;CACP,QAAQ;CACR,KAAK;CACL,SAAS;CACT,QAAQ;CACR,QAAQ;AACV,GAEaC,KAAW,MACtB,OAAOC,KAAU,WAAW,GAAGA,EAAM,MAAMA"}