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,6 +1,7 @@
1
1
  {
2
- "version": "0.0.106",
2
+ "version": "0.0.110",
3
+ "fingerprint": "4841db79e8f7f62f30b5bd2ec6e9a59a4ae0ccaeb3b6f4eedfedfa431d62e392",
3
4
  "full": false,
4
5
  "node": "v22.13.1",
5
- "verifiedAt": "2026-09-24T14:14:24.880Z"
6
+ "verifiedAt": "2026-09-29T14:57:55.329Z"
6
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/Accordion/index.tsx"],"sourcesContent":["import React from 'react';\nimport { cn } from '../../utils/cn';\n\nexport type AccordionItemType = {\n /** 唯一标识(用于展开状态管理)。 */\n key: string;\n /** 标题。 */\n title: React.ReactNode;\n /** 展开区域内容。 */\n content: React.ReactNode;\n /** 标题左侧图标。 */\n icon?: React.ReactNode;\n /** 标题行右侧、展开指示器之前的附加内容。 */\n extra?: React.ReactNode;\n /** 禁用该项。 */\n disabled?: boolean;\n};\n\nexport type AccordionProps = {\n /** 手风琴项(数据驱动,可动态增删)。 */\n items: AccordionItemType[];\n /** 受控:当前展开项的 key 列表。 */\n openKeys?: string[];\n /** 非受控:默认展开项的 key 列表。 */\n defaultOpenKeys?: string[];\n /** 是否允许同时展开多项;默认 false(互斥展开,展开新项时收起其它项)。 */\n multiple?: boolean;\n /** 展开状态变化回调。 */\n onChange?: (openKeys: string[]) => void;\n /** 是否显示右侧展开指示箭头,默认 true。 */\n indicator?: boolean;\n /** 是否显示外层边框,默认 true。 */\n bordered?: boolean;\n className?: string;\n};\n\nconst ChevronGlyph: React.FC<{ className?: string }> = ({ className }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={cn('h-4 w-4', className)}\n aria-hidden=\"true\"\n >\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n);\n\n/**\n * Accordion —— 手风琴组件:动态交互式的聚合展开列表。\n * 数据驱动(items 可动态增删),支持受控 / 非受控、互斥或多开、\n * 禁用项、图标与自定义内容,展开 / 收起带平滑过渡动画。\n */\nconst Accordion: React.FC<AccordionProps> = ({\n items,\n openKeys,\n defaultOpenKeys = [],\n multiple = false,\n onChange,\n indicator = true,\n bordered = true,\n className = '',\n}) => {\n const [innerKeys, setInnerKeys] = React.useState<string[]>(defaultOpenKeys);\n const isControlled = openKeys !== undefined;\n const currentKeys = isControlled ? (openKeys ?? []) : innerKeys;\n\n const toggle = (key: string, disabled?: boolean) => {\n if (disabled) return;\n const nextKeys = currentKeys.includes(key)\n ? currentKeys.filter((k) => k !== key)\n : multiple\n ? [...currentKeys, key]\n : [key];\n if (!isControlled) setInnerKeys(nextKeys);\n onChange?.(nextKeys);\n };\n\n return (\n <div\n className={cn(\n 'dishui-accordion w-full divide-y divide-base-300 overflow-hidden bg-base-100 text-body leading-5 text-base-content',\n bordered && 'rounded-lg border border-base-300',\n className,\n )}\n >\n {items.map((item) => {\n const open = currentKeys.includes(item.key);\n return (\n <div key={item.key} className={cn(open && !item.disabled && 'bg-base-200/40')}>\n <button\n type=\"button\"\n disabled={item.disabled}\n aria-expanded={open}\n onClick={() => toggle(item.key, item.disabled)}\n className={cn(\n 'flex min-h-10 w-full items-center gap-2 px-4 py-2 text-left text-body font-medium transition-colors duration-150 motion-reduce:transition-none focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-current',\n item.disabled\n ? 'cursor-not-allowed opacity-50'\n : 'cursor-pointer hover:bg-base-200/60',\n open && !item.disabled && 'text-base-content',\n )}\n >\n {item.icon && <span className=\"flex shrink-0 items-center text-base-content/70 [&>svg]:h-4 [&>svg]:w-4\">{item.icon}</span>}\n <span className=\"min-w-0 flex-1 truncate\">{item.title}</span>\n {item.extra && <span className=\"flex shrink-0 items-center\">{item.extra}</span>}\n {indicator && (\n <span className={cn('shrink-0 text-base-content/70 transition-transform duration-200 motion-reduce:transition-none', open && 'rotate-180')}>\n <ChevronGlyph />\n </span>\n )}\n </button>\n <div\n className=\"grid transition-[grid-template-rows] duration-200 ease-out motion-reduce:transition-none\"\n style={{ gridTemplateRows: open ? '1fr' : '0fr' }}\n >\n <div className=\"overflow-hidden\">\n <div className=\"px-4 pb-3 pt-1 text-body leading-5 text-base-content/70\">\n {item.content}\n </div>\n </div>\n </div>\n </div>\n );\n })}\n </div>\n );\n};\n\nexport default Accordion;\n"],"mappings":";;;;AAoCA,IAAM,KAAkD,EAAE,mBACxD,kBAAC,OAAD;CACE,OAAM;CACN,SAAQ;CACR,MAAK;CACL,QAAO;CACP,aAAa;CACb,eAAc;CACd,gBAAe;CACf,WAAW,EAAG,WAAW,CAAS;CAClC,eAAY;CAEZ,UAAA,kBAAC,QAAD,EAAM,GAAE,eAAgB,CAAA;AACrB,CAAA,GAQD,KAAuC,EAC3C,UACA,aACA,qBAAkB,CAAC,GACnB,cAAW,IACX,aACA,eAAY,IACZ,cAAW,IACX,eAAY,SACR;CACJ,IAAM,CAAC,GAAW,KAAgB,EAAM,SAAmB,CAAe,GACpE,IAAe,MAAa,KAAA,GAC5B,IAAc,IAAgB,KAAY,CAAC,IAAK,GAEhD,KAAU,GAAa,MAAuB;EAClD,IAAI,GAAU;EACd,IAAM,IAAW,EAAY,SAAS,CAAG,IACrC,EAAY,QAAQ,MAAM,MAAM,CAAG,IACnC,IACE,CAAC,GAAG,GAAa,CAAG,IACpB,CAAC,CAAG;EAEV,AADK,KAAc,EAAa,CAAQ,GACxC,IAAW,CAAQ;CACrB;CAEA,OACE,kBAAC,OAAD;EACE,WAAW,EACT,sHACA,KAAY,qCACZ,CACF;EAEC,UAAA,EAAM,KAAK,MAAS;GACnB,IAAM,IAAO,EAAY,SAAS,EAAK,GAAG;GAC1C,OACE,kBAAC,OAAD;IAAoB,WAAW,EAAG,KAAQ,CAAC,EAAK,YAAY,gBAAgB;IAA5E,UAAA,CACE,kBAAC,UAAD;KACE,MAAK;KACL,UAAU,EAAK;KACf,iBAAe;KACf,eAAe,EAAO,EAAK,KAAK,EAAK,QAAQ;KAC7C,WAAW,EACT,wOACA,EAAK,WACD,kCACA,uCACJ,KAAQ,CAAC,EAAK,YAAY,mBAC5B;KAXF,UAAA;MAaG,EAAK,QAAQ,kBAAC,QAAD;OAAM,WAAU;OAA2E,UAAA,EAAK;MAAW,CAAA;MACzH,kBAAC,QAAD;OAAM,WAAU;OAA2B,UAAA,EAAK;MAAY,CAAA;MAC3D,EAAK,SAAS,kBAAC,QAAD;OAAM,WAAU;OAA8B,UAAA,EAAK;MAAY,CAAA;MAC7E,KACC,kBAAC,QAAD;OAAM,WAAW,EAAG,iGAAiG,KAAQ,YAAY;OACvI,UAAA,kBAAC,GAAD,CAAe,CAAA;MACX,CAAA;KAEF;IACR,CAAA,GAAA,kBAAC,OAAD;KACE,WAAU;KACV,OAAO,EAAE,kBAAkB,IAAO,QAAQ,MAAM;KAEhD,UAAA,kBAAC,OAAD;MAAK,WAAU;MACb,UAAA,kBAAC,OAAD;OAAK,WAAU;OACZ,UAAA,EAAK;MACH,CAAA;KACF,CAAA;IACF,CAAA,CACF;GAjCK,GAAA,EAAK,GAiCV;EAET,CAAC;CACE,CAAA;AAET"}
1
+ {"version":3,"file":"index.js","names":["React","ChevronGlyph","cn","className","Accordion","innerKeys","setInnerKeys","defaultOpenKeys","isControlled","openKeys","currentKeys","toggle","disabled","nextKeys","key","k","multiple","onChange","bordered","items","open","item","indicator"],"sources":["../../../src/components/Accordion/index.tsx"],"sourcesContent":["import React from 'react';\nimport { cn } from '../../utils/cn';\n\nexport type AccordionItemType = {\n /** 唯一标识(用于展开状态管理)。 */\n key: string;\n /** 标题。 */\n title: React.ReactNode;\n /** 展开区域内容。 */\n content: React.ReactNode;\n /** 标题左侧图标。 */\n icon?: React.ReactNode;\n /** 标题行右侧、展开指示器之前的附加内容。 */\n extra?: React.ReactNode;\n /** 禁用该项。 */\n disabled?: boolean;\n};\n\nexport type AccordionProps = {\n /** 手风琴项(数据驱动,可动态增删)。 */\n items: AccordionItemType[];\n /** 受控:当前展开项的 key 列表。 */\n openKeys?: string[];\n /** 非受控:默认展开项的 key 列表。 */\n defaultOpenKeys?: string[];\n /** 是否允许同时展开多项;默认 false(互斥展开,展开新项时收起其它项)。 */\n multiple?: boolean;\n /** 展开状态变化回调。 */\n onChange?: (openKeys: string[]) => void;\n /** 是否显示右侧展开指示箭头,默认 true。 */\n indicator?: boolean;\n /** 是否显示外层边框,默认 true。 */\n bordered?: boolean;\n className?: string;\n};\n\nconst ChevronGlyph: React.FC<{ className?: string }> = ({ className }) => (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={2}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={cn('h-4 w-4', className)}\n aria-hidden=\"true\"\n >\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n);\n\n/**\n * Accordion —— 手风琴组件:动态交互式的聚合展开列表。\n * 数据驱动(items 可动态增删),支持受控 / 非受控、互斥或多开、\n * 禁用项、图标与自定义内容,展开 / 收起带平滑过渡动画。\n */\nconst Accordion: React.FC<AccordionProps> = ({\n items,\n openKeys,\n defaultOpenKeys = [],\n multiple = false,\n onChange,\n indicator = true,\n bordered = true,\n className = '',\n}) => {\n const [innerKeys, setInnerKeys] = React.useState<string[]>(defaultOpenKeys);\n const isControlled = openKeys !== undefined;\n const currentKeys = isControlled ? (openKeys ?? []) : innerKeys;\n\n const toggle = (key: string, disabled?: boolean) => {\n if (disabled) return;\n const nextKeys = currentKeys.includes(key)\n ? currentKeys.filter((k) => k !== key)\n : multiple\n ? [...currentKeys, key]\n : [key];\n if (!isControlled) setInnerKeys(nextKeys);\n onChange?.(nextKeys);\n };\n\n return (\n <div\n className={cn(\n 'dishui-accordion w-full divide-y divide-base-300 overflow-hidden bg-base-100 text-body leading-5 text-base-content',\n bordered && 'rounded-lg border border-base-300',\n className,\n )}\n >\n {items.map((item) => {\n const open = currentKeys.includes(item.key);\n return (\n <div key={item.key} className={cn(open && !item.disabled && 'bg-base-200/40')}>\n <button\n type=\"button\"\n disabled={item.disabled}\n aria-expanded={open}\n onClick={() => toggle(item.key, item.disabled)}\n className={cn(\n 'flex min-h-10 w-full items-center gap-2 px-4 py-2 text-left text-body font-medium transition-colors duration-150 motion-reduce:transition-none focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-current',\n item.disabled\n ? 'cursor-not-allowed opacity-50'\n : 'cursor-pointer hover:bg-base-200/60',\n open && !item.disabled && 'text-base-content',\n )}\n >\n {item.icon && <span className=\"flex shrink-0 items-center text-base-content/70 [&>svg]:h-4 [&>svg]:w-4\">{item.icon}</span>}\n <span className=\"min-w-0 flex-1 truncate\">{item.title}</span>\n {item.extra && <span className=\"flex shrink-0 items-center\">{item.extra}</span>}\n {indicator && (\n <span className={cn('shrink-0 text-base-content/70 transition-transform duration-200 motion-reduce:transition-none', open && 'rotate-180')}>\n <ChevronGlyph />\n </span>\n )}\n </button>\n <div\n className=\"grid transition-[grid-template-rows] duration-200 ease-out motion-reduce:transition-none\"\n style={{ gridTemplateRows: open ? '1fr' : '0fr' }}\n >\n <div className=\"overflow-hidden\">\n <div className=\"px-4 pb-3 pt-1 text-body leading-5 text-base-content/70\">\n {item.content}\n </div>\n </div>\n </div>\n </div>\n );\n })}\n </div>\n );\n};\n\nexport default Accordion;\n"],"mappings":";;;;AAoCA,IAAMC,KAAkD,EAAE,mBACxD,kBAAC,OAAD;CACE,OAAM;CACN,SAAQ;CACR,MAAK;CACL,QAAO;CACP,aAAa;CACb,eAAc;CACd,gBAAe;CACf,WAAWC,EAAG,WAAWC,CAAS;CAClC,eAAY;CAEZ,UAAA,kBAAC,QAAD,EAAM,GAAE,eAAgB,CAAA;AACrB,CAAA,GAQDC,KAAuC,EAC3C,UACA,aACA,qBAAkB,CAAC,GACnB,cAAW,IACX,aACA,eAAY,IACZ,cAAW,IACX,eAAY,SACR;CACJ,IAAM,CAACC,GAAWC,KAAgBN,EAAM,SAAmBO,CAAe,GACpEC,IAAeC,MAAa,KAAA,GAC5BC,IAAcF,IAAgBC,KAAY,CAAC,IAAKJ,GAEhDM,KAAU,GAAa,MAAuB;EAClD,IAAIC,GAAU;EACd,IAAMC,IAAWH,EAAY,SAASI,CAAG,IACrCJ,EAAY,QAAQ,MAAMK,MAAMD,CAAG,IACnCE,IACE,CAAC,GAAGN,GAAaI,CAAG,IACpB,CAACA,CAAG;EAEV,AADKN,KAAcF,EAAaO,CAAQ,GACxCI,IAAWJ,CAAQ;CACrB;CAEA,OACE,kBAAC,OAAD;EACE,WAAWX,EACT,sHACAgB,KAAY,qCACZf,CACF;EAEC,UAAAgB,EAAM,KAAK,MAAS;GACnB,IAAMC,IAAOV,EAAY,SAASW,EAAK,GAAG;GAC1C,OACE,kBAAC,OAAD;IAAoB,WAAWnB,EAAGkB,KAAQ,CAACC,EAAK,YAAY,gBAAgB;IAA5E,UAAA,CACE,kBAAC,UAAD;KACE,MAAK;KACL,UAAUA,EAAK;KACf,iBAAeD;KACf,eAAeT,EAAOU,EAAK,KAAKA,EAAK,QAAQ;KAC7C,WAAWnB,EACT,wOACAmB,EAAK,WACD,kCACA,uCACJD,KAAQ,CAACC,EAAK,YAAY,mBAC5B;KAXF,UAAA;MAaGA,EAAK,QAAQ,kBAAC,QAAD;OAAM,WAAU;OAA2E,UAAAA,EAAK;MAAW,CAAA;MACzH,kBAAC,QAAD;OAAM,WAAU;OAA2B,UAAAA,EAAK;MAAY,CAAA;MAC3DA,EAAK,SAAS,kBAAC,QAAD;OAAM,WAAU;OAA8B,UAAAA,EAAK;MAAY,CAAA;MAC7EC,KACC,kBAAC,QAAD;OAAM,WAAWpB,EAAG,iGAAiGkB,KAAQ,YAAY;OACvI,UAAA,kBAACnB,GAAD,CAAe,CAAA;MACX,CAAA;KAEF;IACR,CAAA,GAAA,kBAAC,OAAD;KACE,WAAU;KACV,OAAO,EAAE,kBAAkBmB,IAAO,QAAQ,MAAM;KAEhD,UAAA,kBAAC,OAAD;MAAK,WAAU;MACb,UAAA,kBAAC,OAAD;OAAK,WAAU;OACZ,UAAAC,EAAK;MACH,CAAA;KACF,CAAA;IACF,CAAA,CACF;GAjCK,GAAAA,EAAK,GAiCV;EAET,CAAC;CACE,CAAA;AAET"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/Avatar/index.tsx"],"sourcesContent":["import React from 'react';\nimport { cn } from '../../utils/cn';\n\nexport type AvatarShape = 'circle' | 'square' | 'squircle';\nexport type AvatarBorderStyle = 'solid' | 'dashed' | 'dotted';\nexport type AvatarNotificationPosition = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';\n\nexport type AvatarProps = {\n /** 头像图片地址;缺省或加载失败时回退为 `name` 的关键字母。 */\n src?: string;\n /** 图片 alt 描述。 */\n alt?: string;\n /** 名称 / 描述:未配置头像时取其关键字母(两个单词取首字母,否则取前两个字符)作为回退展示。 */\n name?: string;\n /** 方形尺寸;数字按 px 处理。默认 40。 */\n size?: number | string;\n /** 边框(整体)形态:circle 圆形(默认)/ square 方形 / squircle 超椭圆圆角方。 */\n shape?: AvatarShape;\n /** shape=\"square\" 时的自定义圆角(数字按 px)。 */\n radius?: number | string;\n /** 边框宽度(数字按 px);默认 0,旧 maskBorder 模式默认 2。不改变 maskSrc 图片。 */\n borderWidth?: number | string;\n /** 边框颜色。 */\n borderColor?: string;\n /** 边框线型:solid(默认)/ dashed / dotted。 */\n borderStyle?: AvatarBorderStyle;\n /** 装饰图片 URL(SVG / PNG / WebP 等,需自带透明中心),按 contain 覆盖头像;不受 shape 裁剪。优先于 maskBorder,失败时隐藏装饰。 */\n maskSrc?: string;\n /** @deprecated 仅兼容旧 CSS 颜色 / 渐变环,并非图片 mask。图片覆盖请使用 maskSrc;两者同时传入时忽略 maskBorder。 */\n maskBorder?: string;\n /** 头像图片 / 字母内容透明度 0–1,默认 1;不影响装饰图片或通知角标。 */\n centerOpacity?: number;\n /** 角标通知位置,默认 top-right。 */\n notificationPosition?: AvatarNotificationPosition;\n /** 角标通知内容(如计数数值 / 短文本);传 `true` 显示小圆点,不传则不渲染角标。 */\n notification?: React.ReactNode;\n /** 角标背景色,默认 var(--color-error)。 */\n notificationColor?: string;\n /** Extra class names on the wrapper. */\n className?: string;\n /** Inline styles on the wrapper. */\n style?: React.CSSProperties;\n /** Click handler. */\n onClick?: (e: React.MouseEvent<HTMLSpanElement>) => void;\n};\n\n/** 从名称/描述中提取关键字母:两个单词取首字母,否则取前两个字符(统一大写)。 */\nconst initialsOf = (name: string): string => {\n const parts = name.trim().split(/\\s+/).filter(Boolean);\n if (parts.length >= 2) return (parts[0][0] + parts[1][0]).toUpperCase();\n return name.trim().slice(0, 2).toUpperCase();\n};\n\nconst SHAPE_CLASS: Record<AvatarShape, string> = {\n circle: 'rounded-full',\n square: '',\n squircle: 'mask mask-squircle',\n};\n\nconst NOTIFICATION_POSITION_CLASS: Record<AvatarNotificationPosition, string> = {\n 'top-left': 'top-0 left-0 -translate-x-1/3 -translate-y-1/3',\n 'top-right': 'top-0 right-0 translate-x-1/3 -translate-y-1/3',\n 'bottom-left': 'bottom-0 left-0 -translate-x-1/3 translate-y-1/3',\n 'bottom-right': 'bottom-0 right-0 translate-x-1/3 translate-y-1/3',\n};\n\n/**\n * Avatar —— 头像组件。\n * 展示图片头像;未配置(或加载失败)时回退为 `name` 的关键字母。\n * 支持自定义边框形态 / 颜色 / 线型、透明中心装饰图片 overlay(maskSrc)\n * 以及四角 notification 短描述(计数 / 文本 / 圆点)。\n */\nconst Avatar: React.FC<AvatarProps> = ({\n src,\n alt,\n name,\n size = 40,\n shape = 'circle',\n radius,\n borderWidth,\n borderColor,\n borderStyle = 'solid',\n maskBorder,\n maskSrc,\n centerOpacity = 1,\n notificationPosition = 'top-right',\n notification,\n notificationColor = 'var(--color-error)',\n className = '',\n style,\n onClick,\n}) => {\n const px = typeof size === 'number' ? `${size}px` : size;\n const [imgFailed, setImgFailed] = React.useState(false);\n React.useEffect(() => setImgFailed(false), [src]);\n\n const showImage = Boolean(src) && !imgFailed;\n const initials = name ? initialsOf(name) : '';\n const fontSize = `calc(${px} * 0.36)`;\n\n const shapeStyle: React.CSSProperties = shape === 'square' ? { borderRadius: radius ?? '0.5rem' } : {};\n const legacyMaskBorder = maskSrc ? undefined : maskBorder;\n const ringWidth = borderWidth === undefined ? (legacyMaskBorder ? '2px' : '0px') : typeof borderWidth === 'number' ? `${borderWidth}px` : borderWidth;\n\n const showNotification = notification !== undefined && notification !== null && notification !== false;\n\n return (\n <span\n className={cn('relative inline-flex shrink-0 leading-none', onClick && 'cursor-pointer', className)}\n style={{ width: px, height: px, ...style }}\n onClick={onClick}\n >\n {/* 仅保留旧版 CSS 环兼容;图片 overlay 不使用 CSS mask。 */}\n {legacyMaskBorder && (\n <span\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute inset-0 z-10\"\n style={{\n padding: ringWidth,\n background: legacyMaskBorder,\n WebkitMask: 'linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0)',\n WebkitMaskComposite: 'xor',\n mask: 'linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0)',\n maskComposite: 'exclude',\n ...shapeStyle,\n } as React.CSSProperties}\n />\n )}\n <span\n className={cn(\n 'relative flex h-full w-full select-none items-center justify-center overflow-hidden bg-base-200 text-center font-semibold text-base-content/70',\n SHAPE_CLASS[shape],\n )}\n style={{\n fontSize,\n opacity: centerOpacity,\n borderWidth: legacyMaskBorder ? 0 : ringWidth,\n borderStyle: legacyMaskBorder ? undefined : borderStyle,\n borderColor: legacyMaskBorder ? undefined : borderColor,\n ...shapeStyle,\n }}\n >\n {showImage ? (\n <img\n src={src}\n alt={alt ?? name ?? ''}\n className=\"h-full w-full object-cover\"\n onError={() => setImgFailed(true)}\n />\n ) : (\n initials\n )}\n </span>\n {maskSrc && <AvatarMaskImage key={maskSrc} src={maskSrc} />}\n {showNotification && (\n <span\n className={cn(\n 'absolute z-20 flex items-center justify-center rounded-full border-2 border-base-100 font-bold leading-none text-white',\n NOTIFICATION_POSITION_CLASS[notificationPosition],\n notification === true ? 'h-3 w-3 p-0' : 'h-[18px] min-w-[18px] px-1 text-[10px]',\n )}\n style={{ backgroundColor: notificationColor }}\n >\n {notification === true ? '' : notification}\n </span>\n )}\n </span>\n );\n};\n\n// A new URL remounts this layer so a failed decoration can recover independently.\nconst AvatarMaskImage: React.FC<{ src: string }> = ({ src }) => {\n const [failed, setFailed] = React.useState(false);\n if (failed) return null;\n return (\n <img\n src={src}\n alt=\"\"\n aria-hidden=\"true\"\n draggable={false}\n className=\"pointer-events-none absolute inset-0 z-10 h-full w-full select-none object-contain\"\n onError={() => setFailed(true)}\n />\n );\n};\n\nexport default Avatar;\n"],"mappings":";;;;AA+CA,IAAM,KAAc,MAAyB;CAC3C,IAAM,IAAQ,EAAK,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,OAAO,OAAO;CAErD,OADI,EAAM,UAAU,KAAW,EAAM,EAAE,CAAC,KAAK,EAAM,EAAE,CAAC,GAAA,CAAI,YAAY,IAC/D,EAAK,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,YAAY;AAC7C,GAEM,IAA2C;CAC/C,QAAQ;CACR,QAAQ;CACR,UAAU;AACZ,GAEM,IAA0E;CAC9E,YAAY;CACZ,aAAa;CACb,eAAe;CACf,gBAAgB;AAClB,GAQM,KAAiC,EACrC,QACA,QACA,SACA,UAAO,IACP,WAAQ,UACR,WACA,gBACA,gBACA,iBAAc,SACd,eACA,YACA,mBAAgB,GAChB,0BAAuB,aACvB,iBACA,uBAAoB,sBACpB,eAAY,IACZ,UACA,iBACI;CACJ,IAAM,IAAK,OAAO,KAAS,WAAW,GAAG,EAAK,MAAM,GAC9C,CAAC,GAAW,KAAgB,EAAM,SAAS,EAAK;CACtD,EAAM,gBAAgB,EAAa,EAAK,GAAG,CAAC,CAAG,CAAC;CAEhD,IAAM,IAAY,EAAQ,KAAQ,CAAC,GAC7B,IAAW,IAAO,EAAW,CAAI,IAAI,IACrC,IAAW,QAAQ,EAAG,WAEtB,IAAkC,MAAU,WAAW,EAAE,cAAc,KAAU,SAAS,IAAI,CAAC,GAC/F,IAAmB,IAAU,KAAA,IAAY,GACzC,IAAY,MAAgB,KAAA,IAAa,IAAmB,QAAQ,QAAS,OAAO,KAAgB,WAAW,GAAG,EAAY,MAAM,GAEpI,IAAmB,KAA+C,QAAQ,MAAiB;CAEjG,OACE,kBAAC,QAAD;EACE,WAAW,EAAG,8CAA8C,KAAW,kBAAkB,CAAS;EAClG,OAAO;GAAE,OAAO;GAAI,QAAQ;GAAI,GAAG;EAAM;EAChC;EAHX,UAAA;GAMG,KACC,kBAAC,QAAD;IACE,eAAY;IACZ,WAAU;IACV,OAAO;KACL,SAAS;KACT,YAAY;KACZ,YAAY;KACZ,qBAAqB;KACrB,MAAM;KACN,eAAe;KACf,GAAG;IACL;GACD,CAAA;GAEH,kBAAC,QAAD;IACE,WAAW,EACT,kJACA,EAAY,EACd;IACA,OAAO;KACL;KACA,SAAS;KACT,aAAa,IAAmB,IAAI;KACpC,aAAa,IAAmB,KAAA,IAAY;KAC5C,aAAa,IAAmB,KAAA,IAAY;KAC5C,GAAG;IACL;IAEC,UAAA,IACC,kBAAC,OAAD;KACO;KACL,KAAK,KAAO,KAAQ;KACpB,WAAU;KACV,eAAe,EAAa,EAAI;IACjC,CAAA,IAED;GAEE,CAAA;GACL,KAAW,kBAAC,GAAD,EAA+B,KAAK,EAAU,GAAxB,CAAwB;GACzD,KACC,kBAAC,QAAD;IACE,WAAW,EACT,0HACA,EAA4B,IAC5B,MAAiB,KAAO,gBAAgB,wCAC1C;IACA,OAAO,EAAE,iBAAiB,EAAkB;IAE3C,UAAA,MAAiB,KAAO,KAAK;GAC1B,CAAA;EAEJ;;AAEV,GAGM,KAA8C,EAAE,aAAU;CAC9D,IAAM,CAAC,GAAQ,KAAa,EAAM,SAAS,EAAK;CAEhD,OADI,IAAe,OAEjB,kBAAC,OAAD;EACO;EACL,KAAI;EACJ,eAAY;EACZ,WAAW;EACX,WAAU;EACV,eAAe,EAAU,EAAI;CAC9B,CAAA;AAEL"}
1
+ {"version":3,"file":"index.js","names":["React","initialsOf","parts","name","SHAPE_CLASS","NOTIFICATION_POSITION_CLASS","Avatar","px","size","imgFailed","setImgFailed","src","showImage","initials","fontSize","shapeStyle","shape","radius","legacyMaskBorder","maskSrc","maskBorder","ringWidth","borderWidth","showNotification","notification","cn","onClick","className","style","centerOpacity","borderStyle","borderColor","alt","AvatarMaskImage","notificationPosition","notificationColor","failed","setFailed"],"sources":["../../../src/components/Avatar/index.tsx"],"sourcesContent":["import React from 'react';\nimport { cn } from '../../utils/cn';\n\nexport type AvatarShape = 'circle' | 'square' | 'squircle';\nexport type AvatarBorderStyle = 'solid' | 'dashed' | 'dotted';\nexport type AvatarNotificationPosition = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';\n\nexport type AvatarProps = {\n /** 头像图片地址;缺省或加载失败时回退为 `name` 的关键字母。 */\n src?: string;\n /** 图片 alt 描述。 */\n alt?: string;\n /** 名称 / 描述:未配置头像时取其关键字母(两个单词取首字母,否则取前两个字符)作为回退展示。 */\n name?: string;\n /** 方形尺寸;数字按 px 处理。默认 40。 */\n size?: number | string;\n /** 边框(整体)形态:circle 圆形(默认)/ square 方形 / squircle 超椭圆圆角方。 */\n shape?: AvatarShape;\n /** shape=\"square\" 时的自定义圆角(数字按 px)。 */\n radius?: number | string;\n /** 边框宽度(数字按 px);默认 0,旧 maskBorder 模式默认 2。不改变 maskSrc 图片。 */\n borderWidth?: number | string;\n /** 边框颜色。 */\n borderColor?: string;\n /** 边框线型:solid(默认)/ dashed / dotted。 */\n borderStyle?: AvatarBorderStyle;\n /** 装饰图片 URL(SVG / PNG / WebP 等,需自带透明中心),按 contain 覆盖头像;不受 shape 裁剪。优先于 maskBorder,失败时隐藏装饰。 */\n maskSrc?: string;\n /** @deprecated 仅兼容旧 CSS 颜色 / 渐变环,并非图片 mask。图片覆盖请使用 maskSrc;两者同时传入时忽略 maskBorder。 */\n maskBorder?: string;\n /** 头像图片 / 字母内容透明度 0–1,默认 1;不影响装饰图片或通知角标。 */\n centerOpacity?: number;\n /** 角标通知位置,默认 top-right。 */\n notificationPosition?: AvatarNotificationPosition;\n /** 角标通知内容(如计数数值 / 短文本);传 `true` 显示小圆点,不传则不渲染角标。 */\n notification?: React.ReactNode;\n /** 角标背景色,默认 var(--color-error)。 */\n notificationColor?: string;\n /** Extra class names on the wrapper. */\n className?: string;\n /** Inline styles on the wrapper. */\n style?: React.CSSProperties;\n /** Click handler. */\n onClick?: (e: React.MouseEvent<HTMLSpanElement>) => void;\n};\n\n/** 从名称/描述中提取关键字母:两个单词取首字母,否则取前两个字符(统一大写)。 */\nconst initialsOf = (name: string): string => {\n const parts = name.trim().split(/\\s+/).filter(Boolean);\n if (parts.length >= 2) return (parts[0][0] + parts[1][0]).toUpperCase();\n return name.trim().slice(0, 2).toUpperCase();\n};\n\nconst SHAPE_CLASS: Record<AvatarShape, string> = {\n circle: 'rounded-full',\n square: '',\n squircle: 'mask mask-squircle',\n};\n\nconst NOTIFICATION_POSITION_CLASS: Record<AvatarNotificationPosition, string> = {\n 'top-left': 'top-0 left-0 -translate-x-1/3 -translate-y-1/3',\n 'top-right': 'top-0 right-0 translate-x-1/3 -translate-y-1/3',\n 'bottom-left': 'bottom-0 left-0 -translate-x-1/3 translate-y-1/3',\n 'bottom-right': 'bottom-0 right-0 translate-x-1/3 translate-y-1/3',\n};\n\n/**\n * Avatar —— 头像组件。\n * 展示图片头像;未配置(或加载失败)时回退为 `name` 的关键字母。\n * 支持自定义边框形态 / 颜色 / 线型、透明中心装饰图片 overlay(maskSrc)\n * 以及四角 notification 短描述(计数 / 文本 / 圆点)。\n */\nconst Avatar: React.FC<AvatarProps> = ({\n src,\n alt,\n name,\n size = 40,\n shape = 'circle',\n radius,\n borderWidth,\n borderColor,\n borderStyle = 'solid',\n maskBorder,\n maskSrc,\n centerOpacity = 1,\n notificationPosition = 'top-right',\n notification,\n notificationColor = 'var(--color-error)',\n className = '',\n style,\n onClick,\n}) => {\n const px = typeof size === 'number' ? `${size}px` : size;\n const [imgFailed, setImgFailed] = React.useState(false);\n React.useEffect(() => setImgFailed(false), [src]);\n\n const showImage = Boolean(src) && !imgFailed;\n const initials = name ? initialsOf(name) : '';\n const fontSize = `calc(${px} * 0.36)`;\n\n const shapeStyle: React.CSSProperties = shape === 'square' ? { borderRadius: radius ?? '0.5rem' } : {};\n const legacyMaskBorder = maskSrc ? undefined : maskBorder;\n const ringWidth = borderWidth === undefined ? (legacyMaskBorder ? '2px' : '0px') : typeof borderWidth === 'number' ? `${borderWidth}px` : borderWidth;\n\n const showNotification = notification !== undefined && notification !== null && notification !== false;\n\n return (\n <span\n className={cn('relative inline-flex shrink-0 leading-none', onClick && 'cursor-pointer', className)}\n style={{ width: px, height: px, ...style }}\n onClick={onClick}\n >\n {/* 仅保留旧版 CSS 环兼容;图片 overlay 不使用 CSS mask。 */}\n {legacyMaskBorder && (\n <span\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute inset-0 z-10\"\n style={{\n padding: ringWidth,\n background: legacyMaskBorder,\n WebkitMask: 'linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0)',\n WebkitMaskComposite: 'xor',\n mask: 'linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0)',\n maskComposite: 'exclude',\n ...shapeStyle,\n } as React.CSSProperties}\n />\n )}\n <span\n className={cn(\n 'relative flex h-full w-full select-none items-center justify-center overflow-hidden bg-base-200 text-center font-semibold text-base-content/70',\n SHAPE_CLASS[shape],\n )}\n style={{\n fontSize,\n opacity: centerOpacity,\n borderWidth: legacyMaskBorder ? 0 : ringWidth,\n borderStyle: legacyMaskBorder ? undefined : borderStyle,\n borderColor: legacyMaskBorder ? undefined : borderColor,\n ...shapeStyle,\n }}\n >\n {showImage ? (\n <img\n src={src}\n alt={alt ?? name ?? ''}\n className=\"h-full w-full object-cover\"\n onError={() => setImgFailed(true)}\n />\n ) : (\n initials\n )}\n </span>\n {maskSrc && <AvatarMaskImage key={maskSrc} src={maskSrc} />}\n {showNotification && (\n <span\n className={cn(\n 'absolute z-20 flex items-center justify-center rounded-full border-2 border-base-100 font-bold leading-none text-white',\n NOTIFICATION_POSITION_CLASS[notificationPosition],\n notification === true ? 'h-3 w-3 p-0' : 'h-[18px] min-w-[18px] px-1 text-[10px]',\n )}\n style={{ backgroundColor: notificationColor }}\n >\n {notification === true ? '' : notification}\n </span>\n )}\n </span>\n );\n};\n\n// A new URL remounts this layer so a failed decoration can recover independently.\nconst AvatarMaskImage: React.FC<{ src: string }> = ({ src }) => {\n const [failed, setFailed] = React.useState(false);\n if (failed) return null;\n return (\n <img\n src={src}\n alt=\"\"\n aria-hidden=\"true\"\n draggable={false}\n className=\"pointer-events-none absolute inset-0 z-10 h-full w-full select-none object-contain\"\n onError={() => setFailed(true)}\n />\n );\n};\n\nexport default Avatar;\n"],"mappings":";;;;AA+CA,IAAMC,KAAc,MAAyB;CAC3C,IAAMC,IAAQC,EAAK,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,OAAO,OAAO;CAErD,OADID,EAAM,UAAU,KAAWA,EAAM,EAAE,CAAC,KAAKA,EAAM,EAAE,CAAC,GAAA,CAAI,YAAY,IAC/DC,EAAK,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,YAAY;AAC7C,GAEMC,IAA2C;CAC/C,QAAQ;CACR,QAAQ;CACR,UAAU;AACZ,GAEMC,IAA0E;CAC9E,YAAY;CACZ,aAAa;CACb,eAAe;CACf,gBAAgB;AAClB,GAQMC,KAAiC,EACrC,QACA,QACA,SACA,UAAO,IACP,WAAQ,UACR,WACA,gBACA,gBACA,iBAAc,SACd,eACA,YACA,mBAAgB,GAChB,0BAAuB,aACvB,iBACA,uBAAoB,sBACpB,eAAY,IACZ,UACA,iBACI;CACJ,IAAMC,IAAK,OAAOC,KAAS,WAAW,GAAGA,EAAK,MAAMA,GAC9C,CAACC,GAAWC,KAAgBV,EAAM,SAAS,EAAK;CACtD,EAAM,gBAAgBU,EAAa,EAAK,GAAG,CAACC,CAAG,CAAC;CAEhD,IAAMC,IAAY,EAAQD,KAAQ,CAACF,GAC7BI,IAAWV,IAAOF,EAAWE,CAAI,IAAI,IACrCW,IAAW,QAAQP,EAAG,WAEtBQ,IAAkCC,MAAU,WAAW,EAAE,cAAcC,KAAU,SAAS,IAAI,CAAC,GAC/FC,IAAmBC,IAAU,KAAA,IAAYC,GACzCC,IAAYC,MAAgB,KAAA,IAAaJ,IAAmB,QAAQ,QAAS,OAAOI,KAAgB,WAAW,GAAGA,EAAY,MAAMA,GAEpIC,IAAmBC,KAA+C,QAAQA,MAAiB;CAEjG,OACE,kBAAC,QAAD;EACE,WAAWC,EAAG,8CAA8CC,KAAW,kBAAkBC,CAAS;EAClG,OAAO;GAAE,OAAOpB;GAAI,QAAQA;GAAI,GAAGqB;EAAM;EAChC;EAHX,UAAA;GAMGV,KACC,kBAAC,QAAD;IACE,eAAY;IACZ,WAAU;IACV,OAAO;KACL,SAASG;KACT,YAAYH;KACZ,YAAY;KACZ,qBAAqB;KACrB,MAAM;KACN,eAAe;KACf,GAAGH;IACL;GACD,CAAA;GAEH,kBAAC,QAAD;IACE,WAAWU,EACT,kJACArB,EAAYY,EACd;IACA,OAAO;KACL;KACA,SAASa;KACT,aAAaX,IAAmB,IAAIG;KACpC,aAAaH,IAAmB,KAAA,IAAYY;KAC5C,aAAaZ,IAAmB,KAAA,IAAYa;KAC5C,GAAGhB;IACL;IAEC,UAAAH,IACC,kBAAC,OAAD;KACO;KACL,KAAKoB,KAAO7B,KAAQ;KACpB,WAAU;KACV,eAAeO,EAAa,EAAI;IACjC,CAAA,IAEDG;GAEE,CAAA;GACLM,KAAW,kBAACc,GAAD,EAA+B,KAAKd,EAAU,GAAxBA,CAAwB;GACzDI,KACC,kBAAC,QAAD;IACE,WAAWE,EACT,0HACApB,EAA4B6B,IAC5BV,MAAiB,KAAO,gBAAgB,wCAC1C;IACA,OAAO,EAAE,iBAAiBW,EAAkB;IAE3C,UAAAX,MAAiB,KAAO,KAAKA;GAC1B,CAAA;EAEJ;;AAEV,GAGMS,KAA8C,EAAE,aAAU;CAC9D,IAAM,CAACG,GAAQC,KAAarC,EAAM,SAAS,EAAK;CAEhD,OADIoC,IAAe,OAEjB,kBAAC,OAAD;EACO;EACL,KAAI;EACJ,eAAY;EACZ,WAAW;EACX,WAAU;EACV,eAAeC,EAAU,EAAI;CAC9B,CAAA;AAEL"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/Badge/index.tsx"],"sourcesContent":["import React from 'react';\nimport { cn } from '../../utils/cn';\n\nexport type BadgeProps = {\n children: React.ReactNode;\n variant?: 'primary' | 'secondary' | 'accent' | 'info' | 'success' | 'warning' | 'error' | 'ghost';\n size?: 'xs' | 'sm' | 'md' | 'lg';\n outline?: boolean;\n className?: string;\n};\n\nconst Badge: React.FC<BadgeProps> = ({\n children,\n variant = 'primary',\n size = 'sm',\n outline = false,\n className = '',\n}) => {\n const baseClass = 'badge';\n const variantClass = variant ? `badge-${variant}` : '';\n const sizeClass = size ? `badge-${size}` : '';\n const outlineClass = outline ? 'badge-outline' : '';\n \n const badgeClasses = cn(\n baseClass,\n variantClass,\n sizeClass,\n outlineClass,\n className\n );\n\n return (\n <div className={badgeClasses}>\n {children}\n </div>\n );\n};\n\nexport default Badge; "],"mappings":";;;;AAWA,IAAM,KAA+B,EACnC,aACA,aAAU,WACV,UAAO,MACP,aAAU,IACV,eAAY,SACR;CACJ,IACM,IAAe,IAAU,SAAS,MAAY,IAC9C,IAAY,IAAO,SAAS,MAAS,IAGrC,IAAe,EACnB,SACA,GACA,GALmB,IAAU,kBAAkB,IAO/C,CACF;CAEA,OACE,kBAAC,OAAD;EAAK,WAAW;EACb;CACE,CAAA;AAET"}
1
+ {"version":3,"file":"index.js","names":["Badge","variantClass","variant","sizeClass","size","badgeClasses","cn","outline","className"],"sources":["../../../src/components/Badge/index.tsx"],"sourcesContent":["import React from 'react';\nimport { cn } from '../../utils/cn';\n\nexport type BadgeProps = {\n children: React.ReactNode;\n variant?: 'primary' | 'secondary' | 'accent' | 'info' | 'success' | 'warning' | 'error' | 'ghost';\n size?: 'xs' | 'sm' | 'md' | 'lg';\n outline?: boolean;\n className?: string;\n};\n\nconst Badge: React.FC<BadgeProps> = ({\n children,\n variant = 'primary',\n size = 'sm',\n outline = false,\n className = '',\n}) => {\n const baseClass = 'badge';\n const variantClass = variant ? `badge-${variant}` : '';\n const sizeClass = size ? `badge-${size}` : '';\n const outlineClass = outline ? 'badge-outline' : '';\n \n const badgeClasses = cn(\n baseClass,\n variantClass,\n sizeClass,\n outlineClass,\n className\n );\n\n return (\n <div className={badgeClasses}>\n {children}\n </div>\n );\n};\n\nexport default Badge; "],"mappings":";;;;AAWA,IAAMA,KAA+B,EACnC,aACA,aAAU,WACV,UAAO,MACP,aAAU,IACV,eAAY,SACR;CACJ,IACMC,IAAeC,IAAU,SAASA,MAAY,IAC9CC,IAAYC,IAAO,SAASA,MAAS,IAGrCC,IAAeC,EACnB,SACAL,GACAE,GALmBI,IAAU,kBAAkB,IAO/CC,CACF;CAEA,OACE,kBAAC,OAAD;EAAK,WAAWH;EACb;CACE,CAAA;AAET"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/Button/index.tsx"],"sourcesContent":["import React, { ReactElement, useState, useCallback } from 'react';\nimport { cn } from '../../utils/cn';\n\n// 状态项定义\nexport type ButtonState = {\n label: string; // 显示的字符/文本\n key: string; // 状态的唯一标识\n variant?: 'neutral' | 'primary' | 'secondary' | 'accent' | 'info' | 'success' | 'warning' | 'error' | 'destructive' | 'ghost' | 'link';\n icon?: React.ReactNode; // 可选的图标\n};\n\nexport type ButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> & {\n ref?: React.Ref<HTMLButtonElement>;\n children?: React.ReactNode;\n variant?: 'neutral' | 'primary' | 'secondary' | 'accent' | 'info' | 'success' | 'warning' | 'error' | 'destructive' | 'ghost' | 'link';\n size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';\n outline?: boolean;\n dash?: boolean;\n soft?: boolean;\n active?: boolean;\n disabled?: boolean;\n wide?: boolean;\n block?: boolean;\n square?: boolean;\n circle?: boolean;\n leftSection?: React.ReactNode;\n rightSection?: React.ReactNode;\n onClick?: React.MouseEventHandler<HTMLButtonElement>;\n /** 原生 button type;不传时保持浏览器默认行为(表单内默认 submit) */\n type?: 'button' | 'submit' | 'reset';\n className?: string;\n\n // 状态切换相关\n states?: ButtonState[]; // 状态列表\n initialStateIndex?: number; // 初始状态索引\n onStateChange?: (state: ButtonState, clickCount: number, stateIndex: number) => void; // 状态改变回调\n};\n\nconst Button = ({\n children,\n variant = 'primary',\n size = 'sm',\n outline = false,\n dash = false,\n soft = false,\n active = false,\n disabled = false,\n wide = false,\n block = false,\n square = false,\n circle = false,\n leftSection,\n rightSection,\n onClick,\n type,\n className = '',\n states,\n initialStateIndex = 0,\n onStateChange,\n title,\n ...rest\n}: ButtonProps) => {\n // 状态管理\n const [currentStateIndex, setCurrentStateIndex] = useState(initialStateIndex);\n const [clickCount, setClickCount] = useState(0);\n\n // 是否是状态按钮\n const isStateful = states && states.length > 0;\n\n // 获取当前状态\n const currentState = isStateful ? states[currentStateIndex] : null;\n\n // 处理点击\n const handleClick = useCallback((event: React.MouseEvent<HTMLButtonElement>) => {\n if (isStateful) {\n const newClickCount = clickCount + 1;\n const newStateIndex = (currentStateIndex + 1) % states.length;\n const newState = states[newStateIndex];\n\n setClickCount(newClickCount);\n setCurrentStateIndex(newStateIndex);\n\n // 调用状态改变回调\n if (onStateChange) {\n onStateChange(newState, newClickCount, newStateIndex);\n }\n }\n\n // 调用原始 onClick\n if (onClick) {\n onClick(event);\n }\n }, [isStateful, states, currentStateIndex, clickCount, onStateChange, onClick]);\n\n // 确定使用的 variant\n const effectiveVariant = currentState?.variant || variant;\n\n // 确定显示的内容\n const displayContent = isStateful ? (\n <>\n {currentState?.icon && <span className=\"mr-1\">{currentState.icon}</span>}\n {currentState?.label}\n </>\n ) : children;\n\n const baseClass = 'btn';\n const variantClass = effectiveVariant === 'destructive' ? 'btn-error btn-destructive' : effectiveVariant ? `btn-${effectiveVariant}` : '';\n const sizeClass = size ? `btn-${size}` : '';\n const outlineClass = outline ? 'btn-outline' : '';\n const dashClass = dash ? 'btn-dash' : '';\n const softClass = soft ? 'btn-soft' : '';\n const activeClass = active || isStateful ? 'btn-active' : '';\n const wideClass = wide ? 'btn-wide' : '';\n const blockClass = block ? 'btn-block' : '';\n const squareClass = square ? 'btn-square' : '';\n const circleClass = circle ? 'btn-circle' : '';\n\n const buttonClasses = cn(\n baseClass,\n variantClass,\n sizeClass,\n outlineClass,\n dashClass,\n softClass,\n activeClass,\n wideClass,\n blockClass,\n squareClass,\n circleClass,\n className\n );\n\n return (\n <button\n {...rest}\n type={type}\n className={buttonClasses}\n disabled={disabled}\n onClick={handleClick}\n title={title ?? (isStateful ? `当前状态: ${currentState?.key} (点击次数: ${clickCount})` : undefined)}\n >\n {!isStateful && leftSection && <span className=\"mr-2\">{leftSection}</span>}\n {displayContent}\n {!isStateful && rightSection && <span className=\"ml-2\">{rightSection}</span>}\n </button>\n );\n};\n\n// Button.Group 组件\nexport type ButtonGroupProps = {\n children: React.ReactNode;\n vertical?: boolean;\n className?: string;\n rounded?: 'left' | 'right' | 'both' | 'none' | 'top' | 'bottom';\n radius?: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full';\n roundedStyle?: {\n left?: string;\n right?: string;\n top?: string;\n bottom?: string;\n };\n};\n\nconst ButtonGroup = ({\n children,\n vertical = false,\n className = '',\n rounded = 'none',\n radius = 'full',\n roundedStyle,\n}: ButtonGroupProps) => {\n const joinClasses = cn(\n 'join',\n vertical ? 'join-vertical' : 'join-horizontal',\n className\n );\n\n // 当rounded不为'none'时,强制使用'full'作为radius值\n const effectiveRadius = rounded !== 'none' ? 'full' : radius;\n\n return (\n <div className={joinClasses}>\n {React.Children.map(children, (child, index) => {\n // 只处理有效的React元素\n if (!React.isValidElement(child)) return child;\n\n const childElement = child as ReactElement<{ className?: string }>;\n const childClassName = childElement.props.className || '';\n const isFirstChild = index === 0;\n const isLastChild = index === React.Children.count(children) - 1;\n\n // 根据rounded属性添加额外的圆角类\n let roundedClasses = '';\n\n if (roundedStyle) {\n // 使用自定义圆角样式\n if (vertical) {\n if ((rounded === 'left' || rounded === 'top') && isFirstChild && roundedStyle.top) {\n roundedClasses = roundedStyle.top;\n } else if ((rounded === 'right' || rounded === 'bottom') && isLastChild && roundedStyle.bottom) {\n roundedClasses = roundedStyle.bottom;\n } else if (rounded === 'both') {\n if (isFirstChild && roundedStyle.top) roundedClasses = roundedStyle.top;\n if (isLastChild && roundedStyle.bottom) roundedClasses = roundedStyle.bottom;\n }\n } else {\n if ((rounded === 'left' || rounded === 'top') && isFirstChild && roundedStyle.left) {\n roundedClasses = roundedStyle.left;\n } else if ((rounded === 'right' || rounded === 'bottom') && isLastChild && roundedStyle.right) {\n roundedClasses = roundedStyle.right;\n } else if (rounded === 'both') {\n if (isFirstChild && roundedStyle.left) roundedClasses = roundedStyle.left;\n if (isLastChild && roundedStyle.right) roundedClasses = roundedStyle.right;\n }\n }\n } else {\n // 使用默认的圆角大小\n if (vertical) {\n // 垂直布局时,圆角应用在上下方\n if (rounded === 'left' || rounded === 'top') {\n if (isFirstChild) roundedClasses = `rounded-t-${effectiveRadius}`;\n } else if (rounded === 'right' || rounded === 'bottom') {\n if (isLastChild) roundedClasses = `rounded-b-${effectiveRadius}`;\n } else if (rounded === 'both') {\n if (isFirstChild) roundedClasses = `rounded-t-${effectiveRadius}`;\n if (isLastChild) roundedClasses = `rounded-b-${effectiveRadius}`;\n }\n } else {\n // 水平布局时,圆角应用在左右方\n if (rounded === 'left' || rounded === 'top') {\n if (isFirstChild) roundedClasses = `rounded-l-${effectiveRadius}`;\n } else if (rounded === 'right' || rounded === 'bottom') {\n if (isLastChild) roundedClasses = `rounded-r-${effectiveRadius}`;\n } else if (rounded === 'both') {\n if (isFirstChild) roundedClasses = `rounded-l-${effectiveRadius}`;\n if (isLastChild) roundedClasses = `rounded-r-${effectiveRadius}`;\n }\n }\n }\n\n const newClassName = `${childClassName} join-item ${roundedClasses}`.trim();\n\n return React.cloneElement(childElement, {\n className: newClassName,\n });\n })}\n </div>\n );\n};\n\n// Button.GroupSection 组件\nexport type ButtonGroupSectionProps = {\n children: React.ReactNode;\n className?: string;\n};\n\nconst ButtonGroupSection = ({\n children,\n className = '',\n}: ButtonGroupSectionProps) => {\n const sectionClasses = cn(\n 'join-item',\n 'flex',\n 'items-center',\n 'px-4',\n 'bg-base-200',\n 'border',\n 'border-base-300',\n className\n );\n\n return (\n <div className={sectionClasses}>\n {children}\n </div>\n );\n};\n\n// 扩展Button组件,添加Group和GroupSection子组件\ninterface ButtonCompound extends React.FC<ButtonProps> {\n Group: React.FC<ButtonGroupProps>;\n GroupSection: React.FC<ButtonGroupSectionProps>;\n}\n\nconst ButtonWithCompounds = Button as ButtonCompound;\nButtonWithCompounds.Group = ButtonGroup;\nButtonWithCompounds.GroupSection = ButtonGroupSection;\n\nexport default ButtonWithCompounds; "],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["_Fragment","React","Button","rest","currentStateIndex","setCurrentStateIndex","useState","initialStateIndex","clickCount","setClickCount","isStateful","states","currentState","handleClick","useCallback","newClickCount","newStateIndex","newState","onStateChange","onClick","event","effectiveVariant","variant","displayContent","Fragment","children","variantClass","sizeClass","size","buttonClasses","cn","outline","dash","soft","active","wide","block","square","circle","className","title","leftSection","rightSection","ButtonGroup","joinClasses","vertical","effectiveRadius","rounded","radius","child","childElement","childClassName","isFirstChild","index","isLastChild","roundedClasses","roundedStyle","newClassName","ButtonGroupSection","sectionClasses","ButtonWithCompounds"],"sources":["../../../src/components/Button/index.tsx"],"sourcesContent":["import React, { ReactElement, useState, useCallback } from 'react';\nimport { cn } from '../../utils/cn';\n\n// 状态项定义\nexport type ButtonState = {\n label: string; // 显示的字符/文本\n key: string; // 状态的唯一标识\n variant?: 'neutral' | 'primary' | 'secondary' | 'accent' | 'info' | 'success' | 'warning' | 'error' | 'destructive' | 'ghost' | 'link';\n icon?: React.ReactNode; // 可选的图标\n};\n\nexport type ButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> & {\n ref?: React.Ref<HTMLButtonElement>;\n children?: React.ReactNode;\n variant?: 'neutral' | 'primary' | 'secondary' | 'accent' | 'info' | 'success' | 'warning' | 'error' | 'destructive' | 'ghost' | 'link';\n size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';\n outline?: boolean;\n dash?: boolean;\n soft?: boolean;\n active?: boolean;\n disabled?: boolean;\n wide?: boolean;\n block?: boolean;\n square?: boolean;\n circle?: boolean;\n leftSection?: React.ReactNode;\n rightSection?: React.ReactNode;\n onClick?: React.MouseEventHandler<HTMLButtonElement>;\n /** 原生 button type;不传时保持浏览器默认行为(表单内默认 submit) */\n type?: 'button' | 'submit' | 'reset';\n className?: string;\n\n // 状态切换相关\n states?: ButtonState[]; // 状态列表\n initialStateIndex?: number; // 初始状态索引\n onStateChange?: (state: ButtonState, clickCount: number, stateIndex: number) => void; // 状态改变回调\n};\n\nconst Button = ({\n children,\n variant = 'primary',\n size = 'sm',\n outline = false,\n dash = false,\n soft = false,\n active = false,\n disabled = false,\n wide = false,\n block = false,\n square = false,\n circle = false,\n leftSection,\n rightSection,\n onClick,\n type,\n className = '',\n states,\n initialStateIndex = 0,\n onStateChange,\n title,\n ...rest\n}: ButtonProps) => {\n // 状态管理\n const [currentStateIndex, setCurrentStateIndex] = useState(initialStateIndex);\n const [clickCount, setClickCount] = useState(0);\n\n // 是否是状态按钮\n const isStateful = states && states.length > 0;\n\n // 获取当前状态\n const currentState = isStateful ? states[currentStateIndex] : null;\n\n // 处理点击\n const handleClick = useCallback((event: React.MouseEvent<HTMLButtonElement>) => {\n if (isStateful) {\n const newClickCount = clickCount + 1;\n const newStateIndex = (currentStateIndex + 1) % states.length;\n const newState = states[newStateIndex];\n\n setClickCount(newClickCount);\n setCurrentStateIndex(newStateIndex);\n\n // 调用状态改变回调\n if (onStateChange) {\n onStateChange(newState, newClickCount, newStateIndex);\n }\n }\n\n // 调用原始 onClick\n if (onClick) {\n onClick(event);\n }\n }, [isStateful, states, currentStateIndex, clickCount, onStateChange, onClick]);\n\n // 确定使用的 variant\n const effectiveVariant = currentState?.variant || variant;\n\n // 确定显示的内容\n const displayContent = isStateful ? (\n <>\n {currentState?.icon && <span className=\"mr-1\">{currentState.icon}</span>}\n {currentState?.label}\n </>\n ) : children;\n\n const baseClass = 'btn';\n const variantClass = effectiveVariant === 'destructive' ? 'btn-error btn-destructive' : effectiveVariant ? `btn-${effectiveVariant}` : '';\n const sizeClass = size ? `btn-${size}` : '';\n const outlineClass = outline ? 'btn-outline' : '';\n const dashClass = dash ? 'btn-dash' : '';\n const softClass = soft ? 'btn-soft' : '';\n const activeClass = active || isStateful ? 'btn-active' : '';\n const wideClass = wide ? 'btn-wide' : '';\n const blockClass = block ? 'btn-block' : '';\n const squareClass = square ? 'btn-square' : '';\n const circleClass = circle ? 'btn-circle' : '';\n\n const buttonClasses = cn(\n baseClass,\n variantClass,\n sizeClass,\n outlineClass,\n dashClass,\n softClass,\n activeClass,\n wideClass,\n blockClass,\n squareClass,\n circleClass,\n className\n );\n\n return (\n <button\n {...rest}\n type={type}\n className={buttonClasses}\n disabled={disabled}\n onClick={handleClick}\n title={title ?? (isStateful ? `当前状态: ${currentState?.key} (点击次数: ${clickCount})` : undefined)}\n >\n {!isStateful && leftSection && <span className=\"mr-2\">{leftSection}</span>}\n {displayContent}\n {!isStateful && rightSection && <span className=\"ml-2\">{rightSection}</span>}\n </button>\n );\n};\n\n// Button.Group 组件\nexport type ButtonGroupProps = {\n children: React.ReactNode;\n vertical?: boolean;\n className?: string;\n rounded?: 'left' | 'right' | 'both' | 'none' | 'top' | 'bottom';\n radius?: 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full';\n roundedStyle?: {\n left?: string;\n right?: string;\n top?: string;\n bottom?: string;\n };\n};\n\nconst ButtonGroup = ({\n children,\n vertical = false,\n className = '',\n rounded = 'none',\n radius = 'full',\n roundedStyle,\n}: ButtonGroupProps) => {\n const joinClasses = cn(\n 'join',\n vertical ? 'join-vertical' : 'join-horizontal',\n className\n );\n\n // 当rounded不为'none'时,强制使用'full'作为radius值\n const effectiveRadius = rounded !== 'none' ? 'full' : radius;\n\n return (\n <div className={joinClasses}>\n {React.Children.map(children, (child, index) => {\n // 只处理有效的React元素\n if (!React.isValidElement(child)) return child;\n\n const childElement = child as ReactElement<{ className?: string }>;\n const childClassName = childElement.props.className || '';\n const isFirstChild = index === 0;\n const isLastChild = index === React.Children.count(children) - 1;\n\n // 根据rounded属性添加额外的圆角类\n let roundedClasses = '';\n\n if (roundedStyle) {\n // 使用自定义圆角样式\n if (vertical) {\n if ((rounded === 'left' || rounded === 'top') && isFirstChild && roundedStyle.top) {\n roundedClasses = roundedStyle.top;\n } else if ((rounded === 'right' || rounded === 'bottom') && isLastChild && roundedStyle.bottom) {\n roundedClasses = roundedStyle.bottom;\n } else if (rounded === 'both') {\n if (isFirstChild && roundedStyle.top) roundedClasses = roundedStyle.top;\n if (isLastChild && roundedStyle.bottom) roundedClasses = roundedStyle.bottom;\n }\n } else {\n if ((rounded === 'left' || rounded === 'top') && isFirstChild && roundedStyle.left) {\n roundedClasses = roundedStyle.left;\n } else if ((rounded === 'right' || rounded === 'bottom') && isLastChild && roundedStyle.right) {\n roundedClasses = roundedStyle.right;\n } else if (rounded === 'both') {\n if (isFirstChild && roundedStyle.left) roundedClasses = roundedStyle.left;\n if (isLastChild && roundedStyle.right) roundedClasses = roundedStyle.right;\n }\n }\n } else {\n // 使用默认的圆角大小\n if (vertical) {\n // 垂直布局时,圆角应用在上下方\n if (rounded === 'left' || rounded === 'top') {\n if (isFirstChild) roundedClasses = `rounded-t-${effectiveRadius}`;\n } else if (rounded === 'right' || rounded === 'bottom') {\n if (isLastChild) roundedClasses = `rounded-b-${effectiveRadius}`;\n } else if (rounded === 'both') {\n if (isFirstChild) roundedClasses = `rounded-t-${effectiveRadius}`;\n if (isLastChild) roundedClasses = `rounded-b-${effectiveRadius}`;\n }\n } else {\n // 水平布局时,圆角应用在左右方\n if (rounded === 'left' || rounded === 'top') {\n if (isFirstChild) roundedClasses = `rounded-l-${effectiveRadius}`;\n } else if (rounded === 'right' || rounded === 'bottom') {\n if (isLastChild) roundedClasses = `rounded-r-${effectiveRadius}`;\n } else if (rounded === 'both') {\n if (isFirstChild) roundedClasses = `rounded-l-${effectiveRadius}`;\n if (isLastChild) roundedClasses = `rounded-r-${effectiveRadius}`;\n }\n }\n }\n\n const newClassName = `${childClassName} join-item ${roundedClasses}`.trim();\n\n return React.cloneElement(childElement, {\n className: newClassName,\n });\n })}\n </div>\n );\n};\n\n// Button.GroupSection 组件\nexport type ButtonGroupSectionProps = {\n children: React.ReactNode;\n className?: string;\n};\n\nconst ButtonGroupSection = ({\n children,\n className = '',\n}: ButtonGroupSectionProps) => {\n const sectionClasses = cn(\n 'join-item',\n 'flex',\n 'items-center',\n 'px-4',\n 'bg-base-200',\n 'border',\n 'border-base-300',\n className\n );\n\n return (\n <div className={sectionClasses}>\n {children}\n </div>\n );\n};\n\n// 扩展Button组件,添加Group和GroupSection子组件\ninterface ButtonCompound extends React.FC<ButtonProps> {\n Group: React.FC<ButtonGroupProps>;\n GroupSection: React.FC<ButtonGroupSectionProps>;\n}\n\nconst ButtonWithCompounds = Button as ButtonCompound;\nButtonWithCompounds.Group = ButtonGroup;\nButtonWithCompounds.GroupSection = ButtonGroupSection;\n\nexport default ButtonWithCompounds; "],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/ButtonMenu/index.tsx"],"sourcesContent":["import React, { useCallback, useId, useLayoutEffect, useRef, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport Button, { type ButtonProps } from '../Button';\nimport Text from '../Text';\nimport './style.css';\n\nexport type ButtonMenuItem = {\n id: string;\n label: string;\n icon?: React.ReactNode;\n disabled?: boolean;\n onSelect?: () => void;\n};\n\nexport type ButtonMenuProps = {\n label: string;\n icon?: React.ReactNode;\n iconOnly?: boolean;\n items: ButtonMenuItem[];\n selectedId?: string;\n onSelect?: (id: string) => void;\n align?: 'start' | 'end';\n disabled?: boolean;\n variant?: ButtonProps['variant'];\n size?: ButtonProps['size'];\n className?: string;\n 'aria-label'?: string;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n};\n\nconst Chevron = () => <svg viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\"><path d=\"m4 6 4 4 4-4\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" /></svg>;\nconst Check = () => <svg viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\"><path d=\"m3 8 3 3 7-7\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" /></svg>;\n\n/** A button-triggered action menu, or a single-choice menu when selectedId is supplied. */\nexport default function ButtonMenu({\n label, icon, iconOnly = false, items, selectedId, onSelect, align = 'start',\n disabled = false, variant = 'ghost', size = 'sm', className = '',\n 'aria-label': ariaLabel, open, defaultOpen = false, onOpenChange,\n}: ButtonMenuProps) {\n const id = useId();\n const triggerRef = useRef<HTMLButtonElement>(null);\n const menuRef = useRef<HTMLDivElement>(null);\n const initialFocus = useRef<'first' | 'last' | 'selected'>('selected');\n const [internalOpen, setInternalOpen] = useState(defaultOpen);\n const unavailable = disabled || items.length === 0;\n const isOpen = (open ?? internalOpen) && !unavailable;\n const [activeId, setActiveId] = useState<string>();\n const wasOpen = useRef(false);\n const requestOpen = useCallback((next: boolean) => {\n if (open === undefined) setInternalOpen(next);\n if (next !== (open ?? internalOpen)) onOpenChange?.(next);\n }, [open, internalOpen, onOpenChange]);\n const focusTrigger = () => triggerRef.current?.focus({ preventScroll: true });\n const close = () => { requestOpen(false); focusTrigger(); };\n const enabledElements = () => Array.from(menuRef.current?.querySelectorAll<HTMLButtonElement>('button:not(:disabled)') ?? []);\n const focusItem = (element?: HTMLButtonElement) => {\n if (!element) { menuRef.current?.focus({ preventScroll: true }); return; }\n element.focus({ preventScroll: true });\n element.scrollIntoView({ block: 'nearest', inline: 'nearest' });\n };\n\n useLayoutEffect(() => {\n if (!isOpen) return;\n const trigger = triggerRef.current!;\n const menu = menuRef.current!;\n const position = () => {\n const theme = trigger.closest('[data-theme]')?.getAttribute('data-theme');\n if (theme !== null && theme !== undefined) menu.setAttribute('data-theme', theme);\n else menu.removeAttribute('data-theme');\n const rtl = getComputedStyle(trigger).direction === 'rtl';\n menu.dir = rtl ? 'rtl' : 'ltr';\n const viewport = window.visualViewport;\n const leftEdge = (viewport?.offsetLeft ?? 0) + 8;\n const topEdge = (viewport?.offsetTop ?? 0) + 8;\n const rightEdge = leftEdge + (viewport?.width ?? document.documentElement.clientWidth) - 16;\n const bottomEdge = topEdge + (viewport?.height ?? window.innerHeight) - 16;\n menu.style.maxWidth = `${Math.max(0, Math.min(320, rightEdge - leftEdge))}px`;\n const rect = trigger.getBoundingClientRect();\n const below = Math.max(0, bottomEdge - rect.bottom - 4);\n const above = Math.max(0, rect.top - topEdge - 4);\n const desiredHeight = Math.min(menu.scrollHeight + 2, 352);\n const upwards = below < desiredHeight && above > below;\n menu.style.maxHeight = `${Math.min(352, upwards ? above : below)}px`;\n const box = menu.getBoundingClientRect();\n const end = (align === 'end') !== rtl;\n const left = end ? rect.right - box.width : rect.left;\n const top = upwards ? rect.top - box.height - 4 : rect.bottom + 4;\n menu.style.left = `${Math.max(leftEdge, Math.min(left, rightEdge - box.width))}px`;\n menu.style.top = `${Math.max(topEdge, Math.min(top, bottomEdge - box.height))}px`;\n };\n position();\n const resize = new ResizeObserver(position);\n resize.observe(trigger);\n resize.observe(menu);\n const themeObserver = new MutationObserver(position);\n for (let ancestor: HTMLElement | null = trigger; ancestor; ancestor = ancestor.parentElement) {\n themeObserver.observe(ancestor, { attributes: true, attributeFilter: ['data-theme', 'dir'] });\n }\n window.addEventListener('resize', position);\n window.addEventListener('scroll', position, true);\n window.visualViewport?.addEventListener('resize', position);\n window.visualViewport?.addEventListener('scroll', position);\n return () => {\n resize.disconnect();\n themeObserver.disconnect();\n window.removeEventListener('resize', position);\n window.removeEventListener('scroll', position, true);\n window.visualViewport?.removeEventListener('resize', position);\n window.visualViewport?.removeEventListener('scroll', position);\n };\n }, [isOpen, align, items]);\n\n useLayoutEffect(() => {\n if (isOpen && !wasOpen.current) {\n const enabled = enabledElements();\n const target = initialFocus.current === 'last' ? enabled.at(-1)\n : initialFocus.current === 'first' ? enabled[0]\n : enabled.find(element => element.dataset.itemId === selectedId) ?? enabled[0];\n focusItem(target);\n initialFocus.current = 'selected';\n } else if (!isOpen && wasOpen.current && document.activeElement === document.body) {\n // External controlled closes should not strand focus on the removed portal.\n focusTrigger();\n } else if (isOpen && (document.activeElement === document.body || menuRef.current?.contains(document.activeElement))) {\n const focused = document.activeElement;\n if (focused === menuRef.current || focused?.matches(':disabled') || !menuRef.current?.contains(focused)) focusItem(enabledElements()[0]);\n }\n wasOpen.current = isOpen;\n });\n\n useLayoutEffect(() => {\n if (!isOpen) return;\n const dismiss = (event: Event) => {\n const target = event.target;\n if (target instanceof Node && !triggerRef.current?.contains(target) && !menuRef.current?.contains(target)) requestOpen(false);\n };\n document.addEventListener('pointerdown', dismiss, true);\n document.addEventListener('focusin', dismiss);\n return () => {\n document.removeEventListener('pointerdown', dismiss, true);\n document.removeEventListener('focusin', dismiss);\n };\n }, [isOpen, requestOpen]);\n\n const handleKeyDown = (event: React.KeyboardEvent) => {\n if (event.key === 'Escape') {\n event.preventDefault();\n event.stopPropagation();\n close();\n } else if (event.key === 'Tab') {\n // The portal is last in DOM order. Resume native traversal from its trigger,\n // without preventing Tab, so both directions reach the adjacent page control.\n focusTrigger();\n requestOpen(false);\n } else if (['ArrowDown', 'ArrowUp', 'Home', 'End'].includes(event.key)) {\n event.preventDefault();\n const enabled = enabledElements();\n const index = enabled.indexOf(document.activeElement as HTMLButtonElement);\n const next = event.key === 'Home' ? 0 : event.key === 'End' ? enabled.length - 1\n : (index + (event.key === 'ArrowDown' ? 1 : -1) + enabled.length) % enabled.length;\n focusItem(enabled[next]);\n }\n };\n\n return <>\n <Button ref={triggerRef} id={`${id}-trigger`} type=\"button\" variant={variant} size={size}\n square={iconOnly} disabled={unavailable}\n className={`dishui-button-menu-trigger ${className}`}\n aria-label={ariaLabel ?? label} title={iconOnly ? label : undefined}\n aria-haspopup=\"menu\" aria-expanded={isOpen} aria-controls={isOpen ? `${id}-menu` : undefined}\n onClick={() => { initialFocus.current = 'selected'; requestOpen(!isOpen); }}\n onKeyDown={event => {\n if (unavailable) return;\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n initialFocus.current = event.key === 'ArrowUp' ? 'last' : 'first';\n if (isOpen) focusItem(event.key === 'ArrowUp' ? enabledElements().at(-1) : enabledElements()[0]);\n else requestOpen(true);\n } else if (isOpen && event.key === 'Escape') handleKeyDown(event);\n }}>\n {icon != null && <span className=\"dishui-button-menu-icon\" aria-hidden=\"true\">{icon}</span>}\n {!iconOnly && <Text size=\"sm\" weight=\"medium\" color=\"inherit\" className=\"dishui-button-menu-label\">{label}</Text>}\n {(!iconOnly || icon == null) && <span className=\"dishui-button-menu-icon\" aria-hidden=\"true\"><Chevron /></span>}\n </Button>\n {isOpen && typeof document !== 'undefined' && createPortal(\n <div ref={menuRef} id={`${id}-menu`} role=\"menu\" aria-labelledby={`${id}-trigger`}\n tabIndex={-1} className=\"dishui-button-menu-surface\" onKeyDown={handleKeyDown}>\n {items.map(item => <button key={item.id} type=\"button\" data-item-id={item.id}\n role={selectedId === undefined ? 'menuitem' : 'menuitemradio'}\n aria-checked={selectedId === undefined ? undefined : selectedId === item.id}\n disabled={item.disabled} aria-disabled={item.disabled || undefined}\n tabIndex={!item.disabled && activeId === item.id ? 0 : -1}\n className=\"dishui-button-menu-item\" onFocus={() => setActiveId(item.id)}\n onClick={() => {\n if (item.disabled) return;\n close();\n item.onSelect?.();\n onSelect?.(item.id);\n }}>\n {item.icon != null && <span className=\"dishui-button-menu-icon\" aria-hidden=\"true\">{item.icon}</span>}\n <Text size=\"sm\" color=\"inherit\" className=\"dishui-button-menu-label\">{item.label}</Text>\n {selectedId !== undefined && <span className=\"dishui-button-menu-check\" aria-hidden=\"true\">{selectedId === item.id && <Check />}</span>}\n </button>)}\n </div>, document.body)}\n </>;\n}\n"],"mappings":";;;;;;;AAgCA,IAAM,UAAgB,kBAAC,OAAD;CAAK,SAAQ;CAAY,MAAK;CAAO,eAAY;CAAO,UAAA,kBAAC,QAAD;EAAM,GAAE;EAAe,QAAO;EAAe,aAAY;EAAM,eAAc;EAAQ,gBAAe;CAAS,CAAA;AAAM,CAAA,GAC3L,UAAc,kBAAC,OAAD;CAAK,SAAQ;CAAY,MAAK;CAAO,eAAY;CAAO,UAAA,kBAAC,QAAD;EAAM,GAAE;EAAe,QAAO;EAAe,aAAY;EAAM,eAAc;EAAQ,gBAAe;CAAS,CAAA;AAAM,CAAA;AAG/L,SAAwB,EAAW,EACjC,UAAO,SAAM,cAAW,IAAO,UAAO,eAAY,aAAU,WAAQ,SACpE,cAAW,IAAO,aAAU,SAAS,UAAO,MAAM,eAAY,IAC9D,cAAc,GAAW,SAAM,iBAAc,IAAO,mBAClC;CAClB,IAAM,IAAK,EAAM,GACX,IAAa,EAA0B,IAAI,GAC3C,IAAU,EAAuB,IAAI,GACrC,IAAe,EAAsC,UAAU,GAC/D,CAAC,GAAc,KAAmB,EAAS,CAAW,GACtD,IAAc,KAAY,EAAM,WAAW,GAC3C,KAAU,KAAQ,MAAiB,CAAC,GACpC,CAAC,GAAU,KAAe,EAAiB,GAC3C,IAAU,EAAO,EAAK,GACtB,IAAc,GAAa,MAAkB;EAEjD,AADI,MAAS,KAAA,KAAW,EAAgB,CAAI,GACxC,OAAU,KAAQ,MAAe,IAAe,CAAI;CAC1D,GAAG;EAAC;EAAM;EAAc;CAAY,CAAC,GAC/B,UAAqB,EAAW,SAAS,MAAM,EAAE,eAAe,GAAK,CAAC,GACtE,UAAc;EAAsB,AAApB,EAAY,EAAK,GAAG,EAAa;CAAG,GACpD,UAAwB,MAAM,KAAK,EAAQ,SAAS,iBAAoC,uBAAuB,KAAK,CAAC,CAAC,GACtH,KAAa,MAAgC;EACjD,IAAI,CAAC,GAAS;GAAE,EAAQ,SAAS,MAAM,EAAE,eAAe,GAAK,CAAC;GAAG;EAAQ;EAEzE,AADA,EAAQ,MAAM,EAAE,eAAe,GAAK,CAAC,GACrC,EAAQ,eAAe;GAAE,OAAO;GAAW,QAAQ;EAAU,CAAC;CAChE;CAuEA,AArEA,QAAsB;EACpB,IAAI,CAAC,GAAQ;EACb,IAAM,IAAU,EAAW,SACrB,IAAO,EAAQ,SACf,UAAiB;GACrB,IAAM,IAAQ,EAAQ,QAAQ,cAAc,CAAC,EAAE,aAAa,YAAY;GACxE,AAAI,KAAU,OACT,EAAK,gBAAgB,YAAY,IADK,EAAK,aAAa,cAAc,CAAK;GAEhF,IAAM,IAAM,iBAAiB,CAAO,CAAC,CAAC,cAAc;GACpD,EAAK,MAAM,IAAM,QAAQ;GACzB,IAAM,IAAW,OAAO,gBAClB,KAAY,GAAU,cAAc,KAAK,GACzC,KAAW,GAAU,aAAa,KAAK,GACvC,IAAY,KAAY,GAAU,SAAS,SAAS,gBAAgB,eAAe,IACnF,IAAa,KAAW,GAAU,UAAU,OAAO,eAAe;GACxE,EAAK,MAAM,WAAW,GAAG,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,IAAY,CAAQ,CAAC,EAAE;GAC1E,IAAM,IAAO,EAAQ,sBAAsB,GACrC,IAAQ,KAAK,IAAI,GAAG,IAAa,EAAK,SAAS,CAAC,GAChD,IAAQ,KAAK,IAAI,GAAG,EAAK,MAAM,IAAU,CAAC,GAE1C,IAAU,IADM,KAAK,IAAI,EAAK,eAAe,GAAG,GAC9B,KAAiB,IAAQ;GACjD,EAAK,MAAM,YAAY,GAAG,KAAK,IAAI,KAAK,IAAU,IAAQ,CAAK,EAAE;GACjE,IAAM,IAAM,EAAK,sBAAsB,GAEjC,IADO,MAAU,UAAW,IACU,EAAK,OAA9B,EAAK,QAAQ,EAAI,OAC9B,IAAM,IAAU,EAAK,MAAM,EAAI,SAAS,IAAI,EAAK,SAAS;GAEhE,AADA,EAAK,MAAM,OAAO,GAAG,KAAK,IAAI,GAAU,KAAK,IAAI,GAAM,IAAY,EAAI,KAAK,CAAC,EAAE,KAC/E,EAAK,MAAM,MAAM,GAAG,KAAK,IAAI,GAAS,KAAK,IAAI,GAAK,IAAa,EAAI,MAAM,CAAC,EAAE;EAChF;EACA,EAAS;EACT,IAAM,IAAS,IAAI,eAAe,CAAQ;EAE1C,AADA,EAAO,QAAQ,CAAO,GACtB,EAAO,QAAQ,CAAI;EACnB,IAAM,IAAgB,IAAI,iBAAiB,CAAQ;EACnD,KAAK,IAAI,IAA+B,GAAS,GAAU,IAAW,EAAS,eAC7E,EAAc,QAAQ,GAAU;GAAE,YAAY;GAAM,iBAAiB,CAAC,cAAc,KAAK;EAAE,CAAC;EAM9F,OAJA,OAAO,iBAAiB,UAAU,CAAQ,GAC1C,OAAO,iBAAiB,UAAU,GAAU,EAAI,GAChD,OAAO,gBAAgB,iBAAiB,UAAU,CAAQ,GAC1D,OAAO,gBAAgB,iBAAiB,UAAU,CAAQ,SAC7C;GAMX,AALA,EAAO,WAAW,GAClB,EAAc,WAAW,GACzB,OAAO,oBAAoB,UAAU,CAAQ,GAC7C,OAAO,oBAAoB,UAAU,GAAU,EAAI,GACnD,OAAO,gBAAgB,oBAAoB,UAAU,CAAQ,GAC7D,OAAO,gBAAgB,oBAAoB,UAAU,CAAQ;EAC/D;CACF,GAAG;EAAC;EAAQ;EAAO;CAAK,CAAC,GAEzB,QAAsB;EACpB,IAAI,KAAU,CAAC,EAAQ,SAAS;GAC9B,IAAM,IAAU,EAAgB,GAC1B,IAAS,EAAa,YAAY,SAAS,EAAQ,GAAG,EAAE,IAC1D,EAAa,YAAY,UAAU,EAAQ,KAC3C,EAAQ,MAAK,MAAW,EAAQ,QAAQ,WAAW,CAAU,KAAK,EAAQ;GAE9E,AADA,EAAU,CAAM,GAChB,EAAa,UAAU;EACzB,OAAO,IAAI,CAAC,KAAU,EAAQ,WAAW,SAAS,kBAAkB,SAAS,MAE3E,EAAa;OACR,IAAI,MAAW,SAAS,kBAAkB,SAAS,QAAQ,EAAQ,SAAS,SAAS,SAAS,aAAa,IAAI;GACpH,IAAM,IAAU,SAAS;GACzB,CAAI,MAAY,EAAQ,WAAW,GAAS,QAAQ,WAAW,KAAK,CAAC,EAAQ,SAAS,SAAS,CAAO,MAAG,EAAU,EAAgB,CAAC,CAAC,EAAE;EACzI;EACA,EAAQ,UAAU;CACpB,CAAC,GAED,QAAsB;EACpB,IAAI,CAAC,GAAQ;EACb,IAAM,KAAW,MAAiB;GAChC,IAAM,IAAS,EAAM;GACrB,AAAI,aAAkB,QAAQ,CAAC,EAAW,SAAS,SAAS,CAAM,KAAK,CAAC,EAAQ,SAAS,SAAS,CAAM,KAAG,EAAY,EAAK;EAC9H;EAGA,OAFA,SAAS,iBAAiB,eAAe,GAAS,EAAI,GACtD,SAAS,iBAAiB,WAAW,CAAO,SAC/B;GAEX,AADA,SAAS,oBAAoB,eAAe,GAAS,EAAI,GACzD,SAAS,oBAAoB,WAAW,CAAO;EACjD;CACF,GAAG,CAAC,GAAQ,CAAW,CAAC;CAExB,IAAM,KAAiB,MAA+B;EACpD,IAAI,EAAM,QAAQ,UAGhB,AAFA,EAAM,eAAe,GACrB,EAAM,gBAAgB,GACtB,EAAM;OACD,IAAI,EAAM,QAAQ,OAIvB,AADA,EAAa,GACb,EAAY,EAAK;OACZ,IAAI;GAAC;GAAa;GAAW;GAAQ;EAAK,CAAC,CAAC,SAAS,EAAM,GAAG,GAAG;GACtE,EAAM,eAAe;GACrB,IAAM,IAAU,EAAgB,GAC1B,IAAQ,EAAQ,QAAQ,SAAS,aAAkC,GACnE,IAAO,EAAM,QAAQ,SAAS,IAAI,EAAM,QAAQ,QAAQ,EAAQ,SAAS,KAC1E,KAAS,EAAM,QAAQ,cAAc,IAAI,MAAM,EAAQ,UAAU,EAAQ;GAC9E,EAAU,EAAQ,EAAK;EACzB;CACF;CAEA,OAAO,kBAAA,GAAA,EAAA,UAAA,CACL,kBAAC,GAAD;EAAQ,KAAK;EAAY,IAAI,GAAG,EAAG;EAAW,MAAK;EAAkB;EAAe;EAClF,QAAQ;EAAU,UAAU;EAC5B,WAAW,8BAA8B;EACzC,cAAY,KAAa;EAAO,OAAO,IAAW,IAAQ,KAAA;EAC1D,iBAAc;EAAO,iBAAe;EAAQ,iBAAe,IAAS,GAAG,EAAG,SAAS,KAAA;EACnF,eAAe;GAAqC,AAAnC,EAAa,UAAU,YAAY,EAAY,CAAC,CAAM;EAAG;EAC1E,YAAW,MAAS;GACd,MACA,EAAM,QAAQ,eAAe,EAAM,QAAQ,aAC7C,EAAM,eAAe,GACrB,EAAa,UAAU,EAAM,QAAQ,YAAY,SAAS,SACtD,IAAQ,EAAU,EAAM,QAAQ,YAAY,EAAgB,CAAC,CAAC,GAAG,EAAE,IAAI,EAAgB,CAAC,CAAC,EAAE,IAC1F,EAAY,EAAI,KACZ,KAAU,EAAM,QAAQ,YAAU,EAAc,CAAK;EAClE;EAdF,UAAA;GAeG,KAAQ,QAAQ,kBAAC,QAAD;IAAM,WAAU;IAA0B,eAAY;IAAQ,UAAA;GAAW,CAAA;GACzF,CAAC,KAAY,kBAAC,GAAD;IAAM,MAAK;IAAK,QAAO;IAAS,OAAM;IAAU,WAAU;IAA4B,UAAA;GAAY,CAAA;IAC9G,CAAC,KAAY,KAAQ,SAAS,kBAAC,QAAD;IAAM,WAAU;IAA0B,eAAY;IAAO,UAAA,kBAAC,GAAD,CAAU,CAAA;GAAO,CAAA;EACxG;CACP,CAAA,GAAA,KAAU,OAAO,WAAa,OAAe,EAC5C,kBAAC,OAAD;EAAK,KAAK;EAAS,IAAI,GAAG,EAAG;EAAQ,MAAK;EAAO,mBAAiB,GAAG,EAAG;EACtE,UAAU;EAAI,WAAU;EAA6B,WAAW;EAC/D,UAAA,EAAM,KAAI,MAAQ,kBAAC,UAAD;GAAsB,MAAK;GAAS,gBAAc,EAAK;GACxE,MAAM,MAAe,KAAA,IAAY,aAAa;GAC9C,gBAAc,MAAe,KAAA,IAAY,KAAA,IAAY,MAAe,EAAK;GACzE,UAAU,EAAK;GAAU,iBAAe,EAAK,YAAY,KAAA;GACzD,UAAU,CAAC,EAAK,YAAY,MAAa,EAAK,KAAK,IAAI;GACvD,WAAU;GAA0B,eAAe,EAAY,EAAK,EAAE;GACtE,eAAe;IACT,EAAK,aACT,EAAM,GACN,EAAK,WAAW,GAChB,IAAW,EAAK,EAAE;GACpB;GAXiB,UAAA;IAYhB,EAAK,QAAQ,QAAQ,kBAAC,QAAD;KAAM,WAAU;KAA0B,eAAY;KAAQ,UAAA,EAAK;IAAW,CAAA;IACpG,kBAAC,GAAD;KAAM,MAAK;KAAK,OAAM;KAAU,WAAU;KAA4B,UAAA,EAAK;IAAY,CAAA;IACtF,MAAe,KAAA,KAAa,kBAAC,QAAD;KAAM,WAAU;KAA2B,eAAY;KAAQ,UAAA,MAAe,EAAK,MAAM,kBAAC,GAAD,CAAQ,CAAA;IAAQ,CAAA;GAChI;EAfwB,GAAA,EAAK,EAe7B,CAAC;CACN,CAAA,GAAG,SAAS,IAAI,CACvB,EAAA,CAAA;AACJ"}
1
+ {"version":3,"file":"index.js","names":["_Fragment","Button","ButtonWithCompounds","Text","Chevron","Check","ButtonMenu","ariaLabel","id","useId","triggerRef","useRef","menuRef","initialFocus","internalOpen","setInternalOpen","useState","defaultOpen","unavailable","disabled","items","isOpen","open","activeId","setActiveId","wasOpen","requestOpen","useCallback","next","onOpenChange","focusTrigger","close","enabledElements","focusItem","element","useLayoutEffect","trigger","menu","position","theme","rtl","viewport","leftEdge","topEdge","rightEdge","bottomEdge","rect","below","above","upwards","box","left","align","top","resize","themeObserver","ancestor","enabled","target","selectedId","focused","dismiss","event","handleKeyDown","index","Fragment","iconOnly","className","label","icon","createPortal","item","onSelect"],"sources":["../../../src/components/ButtonMenu/index.tsx"],"sourcesContent":["import React, { useCallback, useId, useLayoutEffect, useRef, useState } from 'react';\nimport { createPortal } from 'react-dom';\nimport Button, { type ButtonProps } from '../Button';\nimport Text from '../Text';\nimport './style.css';\n\nexport type ButtonMenuItem = {\n id: string;\n label: string;\n icon?: React.ReactNode;\n disabled?: boolean;\n onSelect?: () => void;\n};\n\nexport type ButtonMenuProps = {\n label: string;\n icon?: React.ReactNode;\n iconOnly?: boolean;\n items: ButtonMenuItem[];\n selectedId?: string;\n onSelect?: (id: string) => void;\n align?: 'start' | 'end';\n disabled?: boolean;\n variant?: ButtonProps['variant'];\n size?: ButtonProps['size'];\n className?: string;\n 'aria-label'?: string;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n};\n\nconst Chevron = () => <svg viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\"><path d=\"m4 6 4 4 4-4\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" /></svg>;\nconst Check = () => <svg viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\"><path d=\"m3 8 3 3 7-7\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" /></svg>;\n\n/** A button-triggered action menu, or a single-choice menu when selectedId is supplied. */\nexport default function ButtonMenu({\n label, icon, iconOnly = false, items, selectedId, onSelect, align = 'start',\n disabled = false, variant = 'ghost', size = 'sm', className = '',\n 'aria-label': ariaLabel, open, defaultOpen = false, onOpenChange,\n}: ButtonMenuProps) {\n const id = useId();\n const triggerRef = useRef<HTMLButtonElement>(null);\n const menuRef = useRef<HTMLDivElement>(null);\n const initialFocus = useRef<'first' | 'last' | 'selected'>('selected');\n const [internalOpen, setInternalOpen] = useState(defaultOpen);\n const unavailable = disabled || items.length === 0;\n const isOpen = (open ?? internalOpen) && !unavailable;\n const [activeId, setActiveId] = useState<string>();\n const wasOpen = useRef(false);\n const requestOpen = useCallback((next: boolean) => {\n if (open === undefined) setInternalOpen(next);\n if (next !== (open ?? internalOpen)) onOpenChange?.(next);\n }, [open, internalOpen, onOpenChange]);\n const focusTrigger = () => triggerRef.current?.focus({ preventScroll: true });\n const close = () => { requestOpen(false); focusTrigger(); };\n const enabledElements = () => Array.from(menuRef.current?.querySelectorAll<HTMLButtonElement>('button:not(:disabled)') ?? []);\n const focusItem = (element?: HTMLButtonElement) => {\n if (!element) { menuRef.current?.focus({ preventScroll: true }); return; }\n element.focus({ preventScroll: true });\n element.scrollIntoView({ block: 'nearest', inline: 'nearest' });\n };\n\n useLayoutEffect(() => {\n if (!isOpen) return;\n const trigger = triggerRef.current!;\n const menu = menuRef.current!;\n const position = () => {\n const theme = trigger.closest('[data-theme]')?.getAttribute('data-theme');\n if (theme !== null && theme !== undefined) menu.setAttribute('data-theme', theme);\n else menu.removeAttribute('data-theme');\n const rtl = getComputedStyle(trigger).direction === 'rtl';\n menu.dir = rtl ? 'rtl' : 'ltr';\n const viewport = window.visualViewport;\n const leftEdge = (viewport?.offsetLeft ?? 0) + 8;\n const topEdge = (viewport?.offsetTop ?? 0) + 8;\n const rightEdge = leftEdge + (viewport?.width ?? document.documentElement.clientWidth) - 16;\n const bottomEdge = topEdge + (viewport?.height ?? window.innerHeight) - 16;\n menu.style.maxWidth = `${Math.max(0, Math.min(320, rightEdge - leftEdge))}px`;\n const rect = trigger.getBoundingClientRect();\n const below = Math.max(0, bottomEdge - rect.bottom - 4);\n const above = Math.max(0, rect.top - topEdge - 4);\n const desiredHeight = Math.min(menu.scrollHeight + 2, 352);\n const upwards = below < desiredHeight && above > below;\n menu.style.maxHeight = `${Math.min(352, upwards ? above : below)}px`;\n const box = menu.getBoundingClientRect();\n const end = (align === 'end') !== rtl;\n const left = end ? rect.right - box.width : rect.left;\n const top = upwards ? rect.top - box.height - 4 : rect.bottom + 4;\n menu.style.left = `${Math.max(leftEdge, Math.min(left, rightEdge - box.width))}px`;\n menu.style.top = `${Math.max(topEdge, Math.min(top, bottomEdge - box.height))}px`;\n };\n position();\n const resize = new ResizeObserver(position);\n resize.observe(trigger);\n resize.observe(menu);\n const themeObserver = new MutationObserver(position);\n for (let ancestor: HTMLElement | null = trigger; ancestor; ancestor = ancestor.parentElement) {\n themeObserver.observe(ancestor, { attributes: true, attributeFilter: ['data-theme', 'dir'] });\n }\n window.addEventListener('resize', position);\n window.addEventListener('scroll', position, true);\n window.visualViewport?.addEventListener('resize', position);\n window.visualViewport?.addEventListener('scroll', position);\n return () => {\n resize.disconnect();\n themeObserver.disconnect();\n window.removeEventListener('resize', position);\n window.removeEventListener('scroll', position, true);\n window.visualViewport?.removeEventListener('resize', position);\n window.visualViewport?.removeEventListener('scroll', position);\n };\n }, [isOpen, align, items]);\n\n useLayoutEffect(() => {\n if (isOpen && !wasOpen.current) {\n const enabled = enabledElements();\n const target = initialFocus.current === 'last' ? enabled.at(-1)\n : initialFocus.current === 'first' ? enabled[0]\n : enabled.find(element => element.dataset.itemId === selectedId) ?? enabled[0];\n focusItem(target);\n initialFocus.current = 'selected';\n } else if (!isOpen && wasOpen.current && document.activeElement === document.body) {\n // External controlled closes should not strand focus on the removed portal.\n focusTrigger();\n } else if (isOpen && (document.activeElement === document.body || menuRef.current?.contains(document.activeElement))) {\n const focused = document.activeElement;\n if (focused === menuRef.current || focused?.matches(':disabled') || !menuRef.current?.contains(focused)) focusItem(enabledElements()[0]);\n }\n wasOpen.current = isOpen;\n });\n\n useLayoutEffect(() => {\n if (!isOpen) return;\n const dismiss = (event: Event) => {\n const target = event.target;\n if (target instanceof Node && !triggerRef.current?.contains(target) && !menuRef.current?.contains(target)) requestOpen(false);\n };\n document.addEventListener('pointerdown', dismiss, true);\n document.addEventListener('focusin', dismiss);\n return () => {\n document.removeEventListener('pointerdown', dismiss, true);\n document.removeEventListener('focusin', dismiss);\n };\n }, [isOpen, requestOpen]);\n\n const handleKeyDown = (event: React.KeyboardEvent) => {\n if (event.key === 'Escape') {\n event.preventDefault();\n event.stopPropagation();\n close();\n } else if (event.key === 'Tab') {\n // The portal is last in DOM order. Resume native traversal from its trigger,\n // without preventing Tab, so both directions reach the adjacent page control.\n focusTrigger();\n requestOpen(false);\n } else if (['ArrowDown', 'ArrowUp', 'Home', 'End'].includes(event.key)) {\n event.preventDefault();\n const enabled = enabledElements();\n const index = enabled.indexOf(document.activeElement as HTMLButtonElement);\n const next = event.key === 'Home' ? 0 : event.key === 'End' ? enabled.length - 1\n : (index + (event.key === 'ArrowDown' ? 1 : -1) + enabled.length) % enabled.length;\n focusItem(enabled[next]);\n }\n };\n\n return <>\n <Button ref={triggerRef} id={`${id}-trigger`} type=\"button\" variant={variant} size={size}\n square={iconOnly} disabled={unavailable}\n className={`dishui-button-menu-trigger ${className}`}\n aria-label={ariaLabel ?? label} title={iconOnly ? label : undefined}\n aria-haspopup=\"menu\" aria-expanded={isOpen} aria-controls={isOpen ? `${id}-menu` : undefined}\n onClick={() => { initialFocus.current = 'selected'; requestOpen(!isOpen); }}\n onKeyDown={event => {\n if (unavailable) return;\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault();\n initialFocus.current = event.key === 'ArrowUp' ? 'last' : 'first';\n if (isOpen) focusItem(event.key === 'ArrowUp' ? enabledElements().at(-1) : enabledElements()[0]);\n else requestOpen(true);\n } else if (isOpen && event.key === 'Escape') handleKeyDown(event);\n }}>\n {icon != null && <span className=\"dishui-button-menu-icon\" aria-hidden=\"true\">{icon}</span>}\n {!iconOnly && <Text size=\"sm\" weight=\"medium\" color=\"inherit\" className=\"dishui-button-menu-label\">{label}</Text>}\n {(!iconOnly || icon == null) && <span className=\"dishui-button-menu-icon\" aria-hidden=\"true\"><Chevron /></span>}\n </Button>\n {isOpen && typeof document !== 'undefined' && createPortal(\n <div ref={menuRef} id={`${id}-menu`} role=\"menu\" aria-labelledby={`${id}-trigger`}\n tabIndex={-1} className=\"dishui-button-menu-surface\" onKeyDown={handleKeyDown}>\n {items.map(item => <button key={item.id} type=\"button\" data-item-id={item.id}\n role={selectedId === undefined ? 'menuitem' : 'menuitemradio'}\n aria-checked={selectedId === undefined ? undefined : selectedId === item.id}\n disabled={item.disabled} aria-disabled={item.disabled || undefined}\n tabIndex={!item.disabled && activeId === item.id ? 0 : -1}\n className=\"dishui-button-menu-item\" onFocus={() => setActiveId(item.id)}\n onClick={() => {\n if (item.disabled) return;\n close();\n item.onSelect?.();\n onSelect?.(item.id);\n }}>\n {item.icon != null && <span className=\"dishui-button-menu-icon\" aria-hidden=\"true\">{item.icon}</span>}\n <Text size=\"sm\" color=\"inherit\" className=\"dishui-button-menu-label\">{item.label}</Text>\n {selectedId !== undefined && <span className=\"dishui-button-menu-check\" aria-hidden=\"true\">{selectedId === item.id && <Check />}</span>}\n </button>)}\n </div>, document.body)}\n </>;\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Metric2.js","names":[],"sources":["../../../src/components/Card/Metric.tsx"],"sourcesContent":["import React from 'react';\nimport { cn } from '../../utils/cn';\nimport './Metric.css';\n\nexport type CardMetricItem = {\n /** Stable identity for items that may be reordered. */\n key?: React.Key;\n label: React.ReactNode;\n value: React.ReactNode;\n};\n\nexport type CardMetricProps = Omit<React.HTMLAttributes<HTMLElement>, 'title' | 'children'> & {\n title: React.ReactNode;\n meta?: React.ReactNode;\n period?: React.ReactNode;\n value: React.ReactNode;\n description?: React.ReactNode;\n items?: CardMetricItem[];\n loading?: boolean;\n};\n\nconst EMPTY_ITEMS: CardMetricItem[] = [];\n\nexport const CardMetric = ({\n title, meta, period, value, description, items = EMPTY_ITEMS, loading = false,\n className, ...rest\n}: CardMetricProps) => (\n <article {...rest} className={cn('dishui-card-metric', className)} aria-busy={loading || undefined}>\n <div className=\"dishui-card-metric__body\">\n {((meta !== null && meta !== undefined) || (period !== null && period !== undefined)) && (\n <div className=\"dishui-card-metric__meta\">\n <span>{meta}</span>\n <span className=\"dishui-card-metric__period\">{period}</span>\n </div>\n )}\n <h3 className=\"dishui-card-metric__title\">{title}</h3>\n <div className=\"dishui-card-metric__value\">\n {loading ? <span className=\"dishui-card-metric__skeleton\" aria-hidden=\"true\" /> : value}\n </div>\n {description !== null && description !== undefined && <div className=\"dishui-card-metric__description\">{description}</div>}\n </div>\n {items.length > 0 && (\n <dl className=\"dishui-card-metric__footer\">\n {items.map((item, index) => (\n <div className=\"dishui-card-metric__item\" key={item.key ?? index}>\n <dt>{item.label}</dt>\n <dd>{loading ? <span className=\"dishui-card-metric__skeleton\" aria-hidden=\"true\" /> : item.value}</dd>\n </div>\n ))}\n </dl>\n )}\n </article>\n);\n"],"mappings":";;;;;AAqBA,IAAM,IAAgC,CAAC,GAE1B,KAAc,EACzB,UAAO,SAAM,WAAQ,UAAO,gBAAa,WAAQ,GAAa,aAAU,IACxE,cAAW,GAAG,QAEd,kBAAC,WAAD;CAAS,GAAI;CAAM,WAAW,EAAG,sBAAsB,CAAS;CAAG,aAAW,KAAW,KAAA;CAAzF,UAAA,CACE,kBAAC,OAAD;EAAK,WAAU;EAAf,UAAA;IACK,KAAS,QAAgC,KAAW,SACrD,kBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,kBAAC,QAAD,EAAA,UAAO,EAAW,CAAA,GAClB,kBAAC,QAAD;KAAM,WAAU;KAA8B,UAAA;IAAa,CAAA,CACxD;;GAEP,kBAAC,MAAD;IAAI,WAAU;IAA6B,UAAA;GAAU,CAAA;GACrD,kBAAC,OAAD;IAAK,WAAU;IACZ,UAAA,IAAU,kBAAC,QAAD;KAAM,WAAU;KAA+B,eAAY;IAAQ,CAAA,IAAI;GAC/E,CAAA;GACJ,KAAgB,QAAqC,kBAAC,OAAD;IAAK,WAAU;IAAmC,UAAA;GAAiB,CAAA;EACtH;CACJ,CAAA,GAAA,EAAM,SAAS,KACd,kBAAC,MAAD;EAAI,WAAU;EACX,UAAA,EAAM,KAAK,GAAM,MAChB,kBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACE,kBAAC,MAAD,EAAA,UAAK,EAAK,MAAU,CAAA,GACpB,kBAAC,MAAD,EAAA,UAAK,IAAU,kBAAC,QAAD;IAAM,WAAU;IAA+B,eAAY;GAAQ,CAAA,IAAI,EAAK,MAAU,CAAA,CAClG;EAH0C,GAAA,EAAK,OAAO,CAGtD,CACN;CACC,CAAA,CAEC"}
1
+ {"version":3,"file":"Metric2.js","names":["EMPTY_ITEMS","CardMetric","rest","cn","className","loading","meta","period","title","value","description","items","item","index"],"sources":["../../../src/components/Card/Metric.tsx"],"sourcesContent":["import React from 'react';\nimport { cn } from '../../utils/cn';\nimport './Metric.css';\n\nexport type CardMetricItem = {\n /** Stable identity for items that may be reordered. */\n key?: React.Key;\n label: React.ReactNode;\n value: React.ReactNode;\n};\n\nexport type CardMetricProps = Omit<React.HTMLAttributes<HTMLElement>, 'title' | 'children'> & {\n title: React.ReactNode;\n meta?: React.ReactNode;\n period?: React.ReactNode;\n value: React.ReactNode;\n description?: React.ReactNode;\n items?: CardMetricItem[];\n loading?: boolean;\n};\n\nconst EMPTY_ITEMS: CardMetricItem[] = [];\n\nexport const CardMetric = ({\n title, meta, period, value, description, items = EMPTY_ITEMS, loading = false,\n className, ...rest\n}: CardMetricProps) => (\n <article {...rest} className={cn('dishui-card-metric', className)} aria-busy={loading || undefined}>\n <div className=\"dishui-card-metric__body\">\n {((meta !== null && meta !== undefined) || (period !== null && period !== undefined)) && (\n <div className=\"dishui-card-metric__meta\">\n <span>{meta}</span>\n <span className=\"dishui-card-metric__period\">{period}</span>\n </div>\n )}\n <h3 className=\"dishui-card-metric__title\">{title}</h3>\n <div className=\"dishui-card-metric__value\">\n {loading ? <span className=\"dishui-card-metric__skeleton\" aria-hidden=\"true\" /> : value}\n </div>\n {description !== null && description !== undefined && <div className=\"dishui-card-metric__description\">{description}</div>}\n </div>\n {items.length > 0 && (\n <dl className=\"dishui-card-metric__footer\">\n {items.map((item, index) => (\n <div className=\"dishui-card-metric__item\" key={item.key ?? index}>\n <dt>{item.label}</dt>\n <dd>{loading ? <span className=\"dishui-card-metric__skeleton\" aria-hidden=\"true\" /> : item.value}</dd>\n </div>\n ))}\n </dl>\n )}\n </article>\n);\n"],"mappings":";;;;;AAqBA,IAAMA,IAAgC,CAAC,GAE1BC,KAAc,EACzB,UAAO,SAAM,WAAQ,UAAO,gBAAa,WAAQD,GAAa,aAAU,IACxE,cAAW,GAAGE,QAEd,kBAAC,WAAD;CAAS,GAAIA;CAAM,WAAWC,EAAG,sBAAsBC,CAAS;CAAG,aAAWC,KAAW,KAAA;CAAzF,UAAA,CACE,kBAAC,OAAD;EAAK,WAAU;EAAf,UAAA;IACKC,KAAS,QAAgCC,KAAW,SACrD,kBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,kBAAC,QAAD,EAAA,UAAOD,EAAW,CAAA,GAClB,kBAAC,QAAD;KAAM,WAAU;KAA8B,UAAAC;IAAa,CAAA,CACxD;;GAEP,kBAAC,MAAD;IAAI,WAAU;IAA6B,UAAAC;GAAU,CAAA;GACrD,kBAAC,OAAD;IAAK,WAAU;IACZ,UAAAH,IAAU,kBAAC,QAAD;KAAM,WAAU;KAA+B,eAAY;IAAQ,CAAA,IAAII;GAC/E,CAAA;GACJC,KAAgB,QAAqC,kBAAC,OAAD;IAAK,WAAU;IAAmC,UAAAA;GAAiB,CAAA;EACtH;CACJ,CAAA,GAAAC,EAAM,SAAS,KACd,kBAAC,MAAD;EAAI,WAAU;EACX,UAAAA,EAAM,KAAK,GAAM,MAChB,kBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACE,kBAAC,MAAD,EAAA,UAAKC,EAAK,MAAU,CAAA,GACpB,kBAAC,MAAD,EAAA,UAAKP,IAAU,kBAAC,QAAD;IAAM,WAAU;IAA+B,eAAY;GAAQ,CAAA,IAAIO,EAAK,MAAU,CAAA,CAClG;EAH0C,GAAAA,EAAK,OAAOC,CAGtD,CACN;CACC,CAAA,CAEC"}
@@ -1 +1 @@
1
- {"version":3,"file":"Ticket2.js","names":[],"sources":["../../../src/components/Card/Ticket.tsx"],"sourcesContent":["import React, { useState } from 'react';\nimport { cn } from '../../utils/cn';\nimport './Ticket.css';\n\nexport type CardTicketTone = 'neutral' | 'info' | 'success' | 'warning' | 'danger';\nexport type CardTicketPriorityLevel = 'none' | 'lowest' | 'low' | 'medium' | 'high' | 'highest';\n\nexport type CardTicketStatus = {\n label: React.ReactNode;\n tone?: CardTicketTone;\n};\n\nexport type CardTicketIssueType = {\n label: React.ReactNode;\n icon?: React.ReactNode;\n tone?: CardTicketTone;\n};\n\nexport type CardTicketAssignee = {\n id?: React.Key;\n name: string;\n avatarUrl?: string;\n avatarAlt?: string;\n};\n\nexport type CardTicketPriority = {\n level: CardTicketPriorityLevel;\n label?: React.ReactNode;\n};\n\nexport type CardTicketLabel = {\n id?: React.Key;\n label: React.ReactNode;\n};\n\nexport type CardTicketSubtaskProgress = {\n completed: number;\n total: number;\n label?: React.ReactNode;\n};\n\nexport type CardTicketProps = Omit<React.HTMLAttributes<HTMLElement>, 'title' | 'id' | 'onClick'> & {\n /** DOM id for linking the ticket to other UI. Use React's reserved `key` separately in lists. */\n id?: string;\n /** Human-facing issue key, for example `WEB-142`. */\n issueKey?: React.ReactNode;\n title: React.ReactNode;\n description?: React.ReactNode;\n status?: CardTicketStatus | React.ReactNode;\n issueType?: CardTicketIssueType | React.ReactNode;\n assignees?: CardTicketAssignee[];\n priority?: CardTicketPriority | CardTicketPriorityLevel;\n labels?: Array<CardTicketLabel | React.ReactNode>;\n dueDate?: React.ReactNode;\n estimate?: React.ReactNode;\n subtaskProgress?: CardTicketSubtaskProgress;\n selected?: boolean;\n disabled?: boolean;\n onClick?: React.MouseEventHandler<HTMLElement>;\n className?: string;\n};\n\nconst EMPTY_ASSIGNEES: CardTicketAssignee[] = [];\nconst EMPTY_LABELS: Array<CardTicketLabel | React.ReactNode> = [];\n\nconst PRIORITY_LABELS: Record<CardTicketPriorityLevel, string> = {\n none: 'No priority',\n lowest: 'Lowest priority',\n low: 'Low priority',\n medium: 'Medium priority',\n high: 'High priority',\n highest: 'Highest priority',\n};\n\nconst getInitials = (name: string) => {\n const parts = name.trim().split(/\\s+/).filter(Boolean);\n if (parts.length === 0) return '?';\n return parts.slice(0, 2).map(part => Array.from(part)[0]).join('').toUpperCase();\n};\n\nconst DefaultIssueIcon = () => (\n <svg viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <rect x=\"2.5\" y=\"2.5\" width=\"11\" height=\"11\" rx=\"2\" stroke=\"currentColor\" />\n <path d=\"M5 6h6M5 8.5h4.5\" stroke=\"currentColor\" strokeLinecap=\"round\" />\n </svg>\n);\n\nconst MetaIcon = ({ type }: { type: 'calendar' | 'estimate' | 'subtask' }) => {\n if (type === 'calendar') return <svg viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\"><rect x=\"2.5\" y=\"3.5\" width=\"11\" height=\"10\" rx=\"2\" stroke=\"currentColor\" /><path d=\"M5 2v3M11 2v3M3 6.5h10\" stroke=\"currentColor\" /></svg>;\n if (type === 'estimate') return <svg viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\"><circle cx=\"8\" cy=\"8\" r=\"5.5\" stroke=\"currentColor\" /><path d=\"M8 5v3.5l2 1\" stroke=\"currentColor\" strokeLinecap=\"round\" strokeLinejoin=\"round\" /></svg>;\n return <svg viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\"><rect x=\"2.5\" y=\"2.5\" width=\"11\" height=\"11\" rx=\"2\" stroke=\"currentColor\" /><path d=\"m5 8 2 2 4-4\" stroke=\"currentColor\" strokeLinecap=\"round\" strokeLinejoin=\"round\" /></svg>;\n};\n\nconst TicketAvatar = ({ assignee }: { assignee: CardTicketAssignee }) => {\n const [failed, setFailed] = useState(false);\n const showImage = !!assignee.avatarUrl && !failed;\n\n return (\n <span className=\"dishui-card-ticket__avatar\" title={assignee.name} aria-label={assignee.name}>\n {showImage ? (\n <img\n src={assignee.avatarUrl}\n alt={assignee.avatarAlt ?? ''}\n onError={() => setFailed(true)}\n />\n ) : (\n <span aria-hidden=\"true\">{getInitials(assignee.name)}</span>\n )}\n </span>\n );\n};\n\nconst normalizeStatus = (status: CardTicketProps['status']): CardTicketStatus | undefined => {\n if (status === null || status === undefined) return undefined;\n if (typeof status === 'object' && !React.isValidElement(status) && 'label' in status) return status as CardTicketStatus;\n return { label: status, tone: 'neutral' };\n};\n\nconst normalizeIssueType = (issueType: CardTicketProps['issueType']): CardTicketIssueType | undefined => {\n if (issueType === null || issueType === undefined) return undefined;\n if (typeof issueType === 'object' && !React.isValidElement(issueType) && 'label' in issueType) return issueType as CardTicketIssueType;\n return { label: issueType, tone: 'neutral' };\n};\n\nexport const CardTicket = ({\n id,\n issueKey,\n title,\n description,\n status,\n issueType,\n assignees = EMPTY_ASSIGNEES,\n priority = 'none',\n labels = EMPTY_LABELS,\n dueDate,\n estimate,\n subtaskProgress,\n selected = false,\n disabled = false,\n onClick,\n className,\n ...rest\n}: CardTicketProps) => {\n const interactive = !!onClick;\n const statusValue = normalizeStatus(status);\n const issueTypeValue = normalizeIssueType(issueType);\n const priorityValue = typeof priority === 'string' ? { level: priority } : priority;\n const priorityLabel = priorityValue.label ?? PRIORITY_LABELS[priorityValue.level];\n const completed = Math.max(0, subtaskProgress?.completed ?? 0);\n const total = Math.max(0, subtaskProgress?.total ?? 0);\n const progress = total > 0 ? Math.min(100, (completed / total) * 100) : 0;\n\n return (\n <article\n {...rest}\n id={id}\n className={cn(\n 'dishui-card-ticket',\n interactive && !disabled && 'dishui-card-ticket--interactive',\n selected && 'dishui-card-ticket--selected',\n disabled && 'dishui-card-ticket--disabled',\n className,\n )}\n role={interactive ? 'button' : undefined}\n tabIndex={interactive && !disabled ? 0 : undefined}\n aria-pressed={interactive ? selected : undefined}\n aria-disabled={disabled || undefined}\n onClick={interactive && !disabled ? onClick : undefined}\n onKeyDown={interactive && !disabled ? event => {\n if (event.target !== event.currentTarget) return;\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n if (!event.repeat) event.currentTarget.click();\n }\n } : undefined}\n >\n <div className=\"dishui-card-ticket__header\">\n {issueTypeValue && (\n <span\n className={cn('dishui-card-ticket__type', `dishui-card-ticket__type--${issueTypeValue.tone ?? 'neutral'}`)}\n title={typeof issueTypeValue.label === 'string' ? issueTypeValue.label : undefined}\n >\n <span className=\"dishui-card-ticket__type-icon\" aria-hidden=\"true\">{issueTypeValue.icon ?? <DefaultIssueIcon />}</span>\n <span className=\"dishui-card-ticket__type-label\">{issueTypeValue.label}</span>\n </span>\n )}\n {issueKey !== null && issueKey !== undefined && <span className=\"dishui-card-ticket__key\">{issueKey}</span>}\n {statusValue && (\n <span className={cn('dishui-card-ticket__status', `dishui-card-ticket__status--${statusValue.tone ?? 'neutral'}`)}>\n {statusValue.label}\n </span>\n )}\n </div>\n\n <h3 className=\"dishui-card-ticket__title\">{title}</h3>\n {description !== null && description !== undefined && <div className=\"dishui-card-ticket__description\">{description}</div>}\n\n {labels.length > 0 && (\n <div className=\"dishui-card-ticket__labels\" aria-label=\"Labels\">\n {labels.map((item, index) => {\n const value = typeof item === 'object' && item !== null && !React.isValidElement(item) && 'label' in item\n ? item as CardTicketLabel\n : { label: item };\n return <span className=\"dishui-card-ticket__label\" key={value.id ?? index}>{value.label}</span>;\n })}\n </div>\n )}\n\n <div className=\"dishui-card-ticket__footer\">\n <span\n className={cn('dishui-card-ticket__priority', `dishui-card-ticket__priority--${priorityValue.level}`)}\n title={typeof priorityLabel === 'string' ? priorityLabel : undefined}\n >\n <span className=\"dishui-card-ticket__priority-bars\" aria-hidden=\"true\"><i /><i /><i /></span>\n <span>{priorityLabel}</span>\n </span>\n\n <div className=\"dishui-card-ticket__metadata\">\n {dueDate !== null && dueDate !== undefined && <span className=\"dishui-card-ticket__meta\"><MetaIcon type=\"calendar\" /><span>{dueDate}</span></span>}\n {estimate !== null && estimate !== undefined && <span className=\"dishui-card-ticket__meta\"><MetaIcon type=\"estimate\" /><span>{estimate}</span></span>}\n {subtaskProgress && (\n <span className=\"dishui-card-ticket__meta dishui-card-ticket__subtasks\" aria-label={typeof subtaskProgress.label === 'string' ? subtaskProgress.label : `${completed} of ${total} subtasks complete`}>\n <MetaIcon type=\"subtask\" />\n <span>{subtaskProgress.label ?? `${completed}/${total}`}</span>\n <span className=\"dishui-card-ticket__progress\" aria-hidden=\"true\"><span style={{ width: `${progress}%` }} /></span>\n </span>\n )}\n </div>\n\n {assignees.length > 0 && (\n <div className=\"dishui-card-ticket__assignees\" aria-label=\"Assignees\">\n {assignees.map((assignee, index) => <TicketAvatar key={assignee.id ?? `${assignee.name}-${index}`} assignee={assignee} />)}\n </div>\n )}\n </div>\n </article>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"Ticket2.js","names":["React","EMPTY_ASSIGNEES","EMPTY_LABELS","PRIORITY_LABELS","getInitials","parts","name","part","DefaultIssueIcon","MetaIcon","type","TicketAvatar","failed","setFailed","useState","showImage","assignee","normalizeStatus","status","normalizeIssueType","issueType","CardTicket","rest","interactive","onClick","statusValue","issueTypeValue","priorityValue","priority","priorityLabel","completed","subtaskProgress","total","progress","cn","disabled","selected","className","event","issueKey","title","description","labels","value","item","index","dueDate","estimate","assignees"],"sources":["../../../src/components/Card/Ticket.tsx"],"sourcesContent":["import React, { useState } from 'react';\nimport { cn } from '../../utils/cn';\nimport './Ticket.css';\n\nexport type CardTicketTone = 'neutral' | 'info' | 'success' | 'warning' | 'danger';\nexport type CardTicketPriorityLevel = 'none' | 'lowest' | 'low' | 'medium' | 'high' | 'highest';\n\nexport type CardTicketStatus = {\n label: React.ReactNode;\n tone?: CardTicketTone;\n};\n\nexport type CardTicketIssueType = {\n label: React.ReactNode;\n icon?: React.ReactNode;\n tone?: CardTicketTone;\n};\n\nexport type CardTicketAssignee = {\n id?: React.Key;\n name: string;\n avatarUrl?: string;\n avatarAlt?: string;\n};\n\nexport type CardTicketPriority = {\n level: CardTicketPriorityLevel;\n label?: React.ReactNode;\n};\n\nexport type CardTicketLabel = {\n id?: React.Key;\n label: React.ReactNode;\n};\n\nexport type CardTicketSubtaskProgress = {\n completed: number;\n total: number;\n label?: React.ReactNode;\n};\n\nexport type CardTicketProps = Omit<React.HTMLAttributes<HTMLElement>, 'title' | 'id' | 'onClick'> & {\n /** DOM id for linking the ticket to other UI. Use React's reserved `key` separately in lists. */\n id?: string;\n /** Human-facing issue key, for example `WEB-142`. */\n issueKey?: React.ReactNode;\n title: React.ReactNode;\n description?: React.ReactNode;\n status?: CardTicketStatus | React.ReactNode;\n issueType?: CardTicketIssueType | React.ReactNode;\n assignees?: CardTicketAssignee[];\n priority?: CardTicketPriority | CardTicketPriorityLevel;\n labels?: Array<CardTicketLabel | React.ReactNode>;\n dueDate?: React.ReactNode;\n estimate?: React.ReactNode;\n subtaskProgress?: CardTicketSubtaskProgress;\n selected?: boolean;\n disabled?: boolean;\n onClick?: React.MouseEventHandler<HTMLElement>;\n className?: string;\n};\n\nconst EMPTY_ASSIGNEES: CardTicketAssignee[] = [];\nconst EMPTY_LABELS: Array<CardTicketLabel | React.ReactNode> = [];\n\nconst PRIORITY_LABELS: Record<CardTicketPriorityLevel, string> = {\n none: 'No priority',\n lowest: 'Lowest priority',\n low: 'Low priority',\n medium: 'Medium priority',\n high: 'High priority',\n highest: 'Highest priority',\n};\n\nconst getInitials = (name: string) => {\n const parts = name.trim().split(/\\s+/).filter(Boolean);\n if (parts.length === 0) return '?';\n return parts.slice(0, 2).map(part => Array.from(part)[0]).join('').toUpperCase();\n};\n\nconst DefaultIssueIcon = () => (\n <svg viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <rect x=\"2.5\" y=\"2.5\" width=\"11\" height=\"11\" rx=\"2\" stroke=\"currentColor\" />\n <path d=\"M5 6h6M5 8.5h4.5\" stroke=\"currentColor\" strokeLinecap=\"round\" />\n </svg>\n);\n\nconst MetaIcon = ({ type }: { type: 'calendar' | 'estimate' | 'subtask' }) => {\n if (type === 'calendar') return <svg viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\"><rect x=\"2.5\" y=\"3.5\" width=\"11\" height=\"10\" rx=\"2\" stroke=\"currentColor\" /><path d=\"M5 2v3M11 2v3M3 6.5h10\" stroke=\"currentColor\" /></svg>;\n if (type === 'estimate') return <svg viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\"><circle cx=\"8\" cy=\"8\" r=\"5.5\" stroke=\"currentColor\" /><path d=\"M8 5v3.5l2 1\" stroke=\"currentColor\" strokeLinecap=\"round\" strokeLinejoin=\"round\" /></svg>;\n return <svg viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\"><rect x=\"2.5\" y=\"2.5\" width=\"11\" height=\"11\" rx=\"2\" stroke=\"currentColor\" /><path d=\"m5 8 2 2 4-4\" stroke=\"currentColor\" strokeLinecap=\"round\" strokeLinejoin=\"round\" /></svg>;\n};\n\nconst TicketAvatar = ({ assignee }: { assignee: CardTicketAssignee }) => {\n const [failed, setFailed] = useState(false);\n const showImage = !!assignee.avatarUrl && !failed;\n\n return (\n <span className=\"dishui-card-ticket__avatar\" title={assignee.name} aria-label={assignee.name}>\n {showImage ? (\n <img\n src={assignee.avatarUrl}\n alt={assignee.avatarAlt ?? ''}\n onError={() => setFailed(true)}\n />\n ) : (\n <span aria-hidden=\"true\">{getInitials(assignee.name)}</span>\n )}\n </span>\n );\n};\n\nconst normalizeStatus = (status: CardTicketProps['status']): CardTicketStatus | undefined => {\n if (status === null || status === undefined) return undefined;\n if (typeof status === 'object' && !React.isValidElement(status) && 'label' in status) return status as CardTicketStatus;\n return { label: status, tone: 'neutral' };\n};\n\nconst normalizeIssueType = (issueType: CardTicketProps['issueType']): CardTicketIssueType | undefined => {\n if (issueType === null || issueType === undefined) return undefined;\n if (typeof issueType === 'object' && !React.isValidElement(issueType) && 'label' in issueType) return issueType as CardTicketIssueType;\n return { label: issueType, tone: 'neutral' };\n};\n\nexport const CardTicket = ({\n id,\n issueKey,\n title,\n description,\n status,\n issueType,\n assignees = EMPTY_ASSIGNEES,\n priority = 'none',\n labels = EMPTY_LABELS,\n dueDate,\n estimate,\n subtaskProgress,\n selected = false,\n disabled = false,\n onClick,\n className,\n ...rest\n}: CardTicketProps) => {\n const interactive = !!onClick;\n const statusValue = normalizeStatus(status);\n const issueTypeValue = normalizeIssueType(issueType);\n const priorityValue = typeof priority === 'string' ? { level: priority } : priority;\n const priorityLabel = priorityValue.label ?? PRIORITY_LABELS[priorityValue.level];\n const completed = Math.max(0, subtaskProgress?.completed ?? 0);\n const total = Math.max(0, subtaskProgress?.total ?? 0);\n const progress = total > 0 ? Math.min(100, (completed / total) * 100) : 0;\n\n return (\n <article\n {...rest}\n id={id}\n className={cn(\n 'dishui-card-ticket',\n interactive && !disabled && 'dishui-card-ticket--interactive',\n selected && 'dishui-card-ticket--selected',\n disabled && 'dishui-card-ticket--disabled',\n className,\n )}\n role={interactive ? 'button' : undefined}\n tabIndex={interactive && !disabled ? 0 : undefined}\n aria-pressed={interactive ? selected : undefined}\n aria-disabled={disabled || undefined}\n onClick={interactive && !disabled ? onClick : undefined}\n onKeyDown={interactive && !disabled ? event => {\n if (event.target !== event.currentTarget) return;\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n if (!event.repeat) event.currentTarget.click();\n }\n } : undefined}\n >\n <div className=\"dishui-card-ticket__header\">\n {issueTypeValue && (\n <span\n className={cn('dishui-card-ticket__type', `dishui-card-ticket__type--${issueTypeValue.tone ?? 'neutral'}`)}\n title={typeof issueTypeValue.label === 'string' ? issueTypeValue.label : undefined}\n >\n <span className=\"dishui-card-ticket__type-icon\" aria-hidden=\"true\">{issueTypeValue.icon ?? <DefaultIssueIcon />}</span>\n <span className=\"dishui-card-ticket__type-label\">{issueTypeValue.label}</span>\n </span>\n )}\n {issueKey !== null && issueKey !== undefined && <span className=\"dishui-card-ticket__key\">{issueKey}</span>}\n {statusValue && (\n <span className={cn('dishui-card-ticket__status', `dishui-card-ticket__status--${statusValue.tone ?? 'neutral'}`)}>\n {statusValue.label}\n </span>\n )}\n </div>\n\n <h3 className=\"dishui-card-ticket__title\">{title}</h3>\n {description !== null && description !== undefined && <div className=\"dishui-card-ticket__description\">{description}</div>}\n\n {labels.length > 0 && (\n <div className=\"dishui-card-ticket__labels\" aria-label=\"Labels\">\n {labels.map((item, index) => {\n const value = typeof item === 'object' && item !== null && !React.isValidElement(item) && 'label' in item\n ? item as CardTicketLabel\n : { label: item };\n return <span className=\"dishui-card-ticket__label\" key={value.id ?? index}>{value.label}</span>;\n })}\n </div>\n )}\n\n <div className=\"dishui-card-ticket__footer\">\n <span\n className={cn('dishui-card-ticket__priority', `dishui-card-ticket__priority--${priorityValue.level}`)}\n title={typeof priorityLabel === 'string' ? priorityLabel : undefined}\n >\n <span className=\"dishui-card-ticket__priority-bars\" aria-hidden=\"true\"><i /><i /><i /></span>\n <span>{priorityLabel}</span>\n </span>\n\n <div className=\"dishui-card-ticket__metadata\">\n {dueDate !== null && dueDate !== undefined && <span className=\"dishui-card-ticket__meta\"><MetaIcon type=\"calendar\" /><span>{dueDate}</span></span>}\n {estimate !== null && estimate !== undefined && <span className=\"dishui-card-ticket__meta\"><MetaIcon type=\"estimate\" /><span>{estimate}</span></span>}\n {subtaskProgress && (\n <span className=\"dishui-card-ticket__meta dishui-card-ticket__subtasks\" aria-label={typeof subtaskProgress.label === 'string' ? subtaskProgress.label : `${completed} of ${total} subtasks complete`}>\n <MetaIcon type=\"subtask\" />\n <span>{subtaskProgress.label ?? `${completed}/${total}`}</span>\n <span className=\"dishui-card-ticket__progress\" aria-hidden=\"true\"><span style={{ width: `${progress}%` }} /></span>\n </span>\n )}\n </div>\n\n {assignees.length > 0 && (\n <div className=\"dishui-card-ticket__assignees\" aria-label=\"Assignees\">\n {assignees.map((assignee, index) => <TicketAvatar key={assignee.id ?? `${assignee.name}-${index}`} assignee={assignee} />)}\n </div>\n )}\n </div>\n </article>\n );\n};\n"],"mappings":"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"}