dishui 0.0.108 → 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 (384) 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.js.map +1 -1
  234. package/dist/components/pro/RichTextEditor/BlockHandle.js.map +1 -1
  235. package/dist/components/pro/RichTextEditor/BubbleToolbar.js.map +1 -1
  236. package/dist/components/pro/RichTextEditor/CommentDialog.js.map +1 -1
  237. package/dist/components/pro/RichTextEditor/CommentPanel.js.map +1 -1
  238. package/dist/components/pro/RichTextEditor/CommentPopover.js.map +1 -1
  239. package/dist/components/pro/RichTextEditor/ContextMenu.js.map +1 -1
  240. package/dist/components/pro/RichTextEditor/RichTextEditor.js.map +1 -1
  241. package/dist/components/pro/RichTextEditor/SlashMenu.js.map +1 -1
  242. package/dist/components/pro/RichTextEditor/Toolbar/ColorPicker.js.map +1 -1
  243. package/dist/components/pro/RichTextEditor/Toolbar/FloatingDialogMenu.js.map +1 -1
  244. package/dist/components/pro/RichTextEditor/Toolbar/MarkdownTemplates.js.map +1 -1
  245. package/dist/components/pro/RichTextEditor/Toolbar/SelectDropdown.js.map +1 -1
  246. package/dist/components/pro/RichTextEditor/Toolbar/TableOpsMenu.js.map +1 -1
  247. package/dist/components/pro/RichTextEditor/Toolbar/Toolbar.js.map +1 -1
  248. package/dist/components/pro/RichTextEditor/Toolbar/ToolbarButton.js.map +1 -1
  249. package/dist/components/pro/RichTextEditor/Toolbar/useAnchoredDropdown.js.map +1 -1
  250. package/dist/components/pro/RichTextEditor/extensions/CodeBlockView.js.map +1 -1
  251. package/dist/components/pro/RichTextEditor/extensions/CommentMark.js.map +1 -1
  252. package/dist/components/pro/RichTextEditor/extensions/FloatingDialog.js.map +1 -1
  253. package/dist/components/pro/RichTextEditor/extensions/FontSize.js.map +1 -1
  254. package/dist/components/pro/RichTextEditor/extensions/MarkdownBlock.js.map +1 -1
  255. package/dist/components/pro/RichTextEditor/extensions/ResizableImage.js.map +1 -1
  256. package/dist/components/pro/RichTextEditor/extensions/legacyMermaid.js.map +1 -1
  257. package/dist/components/pro/RichTextEditor/types.js.map +1 -1
  258. package/dist/components/pro/Sprite/Molly/animations.d.ts +6 -0
  259. package/dist/components/pro/Sprite/Molly/animations.js +52 -0
  260. package/dist/components/pro/Sprite/Molly/animations.js.map +1 -0
  261. package/dist/components/pro/Sprite/Molly/events.d.ts +2 -0
  262. package/dist/components/pro/Sprite/Molly/events.js +46 -0
  263. package/dist/components/pro/Sprite/Molly/events.js.map +1 -0
  264. package/dist/components/pro/Sprite/Molly/index.d.ts +1 -0
  265. package/dist/components/pro/Sprite/Molly/index.js +12 -0
  266. package/dist/components/pro/Sprite/Molly/index.js.map +1 -0
  267. package/dist/components/pro/Sprite/Molly/legFlexion.d.ts +3 -0
  268. package/dist/components/pro/Sprite/Molly/legFlexion.js +48 -0
  269. package/dist/components/pro/Sprite/Molly/legFlexion.js.map +1 -0
  270. package/dist/components/pro/Sprite/Molly/locomotion.d.ts +4 -0
  271. package/dist/components/pro/Sprite/Molly/locomotion.js +51 -0
  272. package/dist/components/pro/Sprite/Molly/locomotion.js.map +1 -0
  273. package/dist/components/pro/Sprite/Molly/model.d.ts +23 -0
  274. package/dist/components/pro/Sprite/Molly/model.js +614 -0
  275. package/dist/components/pro/Sprite/Molly/model.js.map +1 -0
  276. package/dist/components/pro/Sprite/Molly/rig.d.ts +25 -0
  277. package/dist/components/pro/Sprite/Molly/rig.js +102 -0
  278. package/dist/components/pro/Sprite/Molly/rig.js.map +1 -0
  279. package/dist/components/pro/Sprite/Ruby/animations.d.ts +6 -0
  280. package/dist/components/pro/Sprite/Ruby/animations.js +58 -0
  281. package/dist/components/pro/Sprite/Ruby/animations.js.map +1 -0
  282. package/dist/components/pro/Sprite/Ruby/events.d.ts +2 -0
  283. package/dist/components/pro/Sprite/Ruby/events.js +46 -0
  284. package/dist/components/pro/Sprite/Ruby/events.js.map +1 -0
  285. package/dist/components/pro/Sprite/Ruby/index.d.ts +1 -0
  286. package/dist/components/pro/Sprite/Ruby/index.js +12 -0
  287. package/dist/components/pro/Sprite/Ruby/index.js.map +1 -0
  288. package/dist/components/pro/Sprite/Ruby/locomotion.d.ts +4 -0
  289. package/dist/components/pro/Sprite/Ruby/locomotion.js +41 -0
  290. package/dist/components/pro/Sprite/Ruby/locomotion.js.map +1 -0
  291. package/dist/components/pro/Sprite/Ruby/model.d.ts +23 -0
  292. package/dist/components/pro/Sprite/Ruby/model.js +605 -0
  293. package/dist/components/pro/Sprite/Ruby/model.js.map +1 -0
  294. package/dist/components/pro/Sprite/Ruby/rig.d.ts +26 -0
  295. package/dist/components/pro/Sprite/Ruby/rig.js +112 -0
  296. package/dist/components/pro/Sprite/Ruby/rig.js.map +1 -0
  297. package/dist/components/pro/Sprite/Sprite.d.ts +23 -0
  298. package/dist/components/pro/Sprite/Sprite2.js +224 -0
  299. package/dist/components/pro/Sprite/Sprite2.js.map +1 -0
  300. package/dist/components/pro/Sprite/actions.d.ts +3 -0
  301. package/dist/components/pro/Sprite/actions.js +16 -0
  302. package/dist/components/pro/Sprite/actions.js.map +1 -0
  303. package/dist/components/pro/Sprite/createSpriteScene.d.ts +4 -0
  304. package/dist/components/pro/Sprite/createSpriteScene.js +14 -0
  305. package/dist/components/pro/Sprite/createSpriteScene.js.map +1 -0
  306. package/dist/components/pro/Sprite/index.d.ts +4 -0
  307. package/dist/components/pro/Sprite/shared/animation.d.ts +33 -0
  308. package/dist/components/pro/Sprite/shared/animation.js +39 -0
  309. package/dist/components/pro/Sprite/shared/animation.js.map +1 -0
  310. package/dist/components/pro/Sprite/shared/createSpriteStage.d.ts +14 -0
  311. package/dist/components/pro/Sprite/shared/createSpriteStage.js +127 -0
  312. package/dist/components/pro/Sprite/shared/createSpriteStage.js.map +1 -0
  313. package/dist/components/pro/Sprite/shared/events.d.ts +5 -0
  314. package/dist/components/pro/Sprite/shared/events.js +21 -0
  315. package/dist/components/pro/Sprite/shared/events.js.map +1 -0
  316. package/dist/components/pro/Sprite/shared/face.d.ts +15 -0
  317. package/dist/components/pro/Sprite/shared/face.js +33 -0
  318. package/dist/components/pro/Sprite/shared/face.js.map +1 -0
  319. package/dist/components/pro/Sprite/shared/faceSurface.d.ts +6 -0
  320. package/dist/components/pro/Sprite/shared/faceSurface.js +66 -0
  321. package/dist/components/pro/Sprite/shared/faceSurface.js.map +1 -0
  322. package/dist/components/pro/Sprite/shared/gait.d.ts +5 -0
  323. package/dist/components/pro/Sprite/shared/gait.js +19 -0
  324. package/dist/components/pro/Sprite/shared/gait.js.map +1 -0
  325. package/dist/components/pro/Sprite/shared/geometry.d.ts +8 -0
  326. package/dist/components/pro/Sprite/shared/geometry.js +59 -0
  327. package/dist/components/pro/Sprite/shared/geometry.js.map +1 -0
  328. package/dist/components/pro/Sprite/shared/magicEffect.d.ts +27 -0
  329. package/dist/components/pro/Sprite/shared/magicEffect.js +61 -0
  330. package/dist/components/pro/Sprite/shared/magicEffect.js.map +1 -0
  331. package/dist/components/pro/Sprite/shared/playback.d.ts +8 -0
  332. package/dist/components/pro/Sprite/shared/playback.js +74 -0
  333. package/dist/components/pro/Sprite/shared/playback.js.map +1 -0
  334. package/dist/components/pro/Sprite/shared/rig.d.ts +6 -0
  335. package/dist/components/pro/Sprite/shared/rig.js +48 -0
  336. package/dist/components/pro/Sprite/shared/rig.js.map +1 -0
  337. package/dist/components/pro/Sprite/shared/scene.d.ts +9 -0
  338. package/dist/components/pro/Sprite/shared/scene.js +21 -0
  339. package/dist/components/pro/Sprite/shared/scene.js.map +1 -0
  340. package/dist/components/pro/Sprite/shared/sculptor.d.ts +14 -0
  341. package/dist/components/pro/Sprite/shared/sculptor.js +78 -0
  342. package/dist/components/pro/Sprite/shared/sculptor.js.map +1 -0
  343. package/dist/components/pro/Sprite/shared/speechBubble.d.ts +15 -0
  344. package/dist/components/pro/Sprite/shared/speechBubble.js +129 -0
  345. package/dist/components/pro/Sprite/shared/speechBubble.js.map +1 -0
  346. package/dist/components/pro/Sprite/types.d.ts +40 -0
  347. package/dist/contexts/AppContext.js.map +1 -1
  348. package/dist/contexts/authentication.js.map +1 -1
  349. package/dist/data-table.js +3 -3
  350. package/dist/data-table.js.map +1 -1
  351. package/dist/dishui.css +1 -1
  352. package/dist/hooks/useClickOutside.js.map +1 -1
  353. package/dist/hooks/useContainerElement.js.map +1 -1
  354. package/dist/hooks/useControllableState.js.map +1 -1
  355. package/dist/hooks/useCopyToClipboard.js.map +1 -1
  356. package/dist/hooks/useDebounce.js.map +1 -1
  357. package/dist/hooks/useDraggable.js.map +1 -1
  358. package/dist/hooks/useTableColumns.js.map +1 -1
  359. package/dist/hooks/useTableData.js.map +1 -1
  360. package/dist/index-nostyled.d.ts +2 -0
  361. package/dist/index.d.ts +2 -0
  362. package/dist/index.js +116 -115
  363. package/dist/layouts/MainLayout.js.map +1 -1
  364. package/dist/layouts/Navbar.js.map +1 -1
  365. package/dist/layouts/Sidebar.js.map +1 -1
  366. package/dist/layouts/headbar/Headbar.js.map +1 -1
  367. package/dist/layouts/headbar/HeadbarLangSwitcher.js.map +1 -1
  368. package/dist/layouts/headbar/HeadbarSearch.js.map +1 -1
  369. package/dist/layouts/headbar/HeadbarThemeSwitcher.js.map +1 -1
  370. package/dist/layouts/headbar/HeadbarTitle.js.map +1 -1
  371. package/dist/sprite.js +2 -0
  372. package/dist/styles/themeStyles.js.map +1 -1
  373. package/dist/utils/cn.js.map +1 -1
  374. package/dist/utils/flexLayout.js.map +1 -1
  375. package/dist/utils/i18n.js.map +1 -1
  376. package/dist/utils/menu.js.map +1 -1
  377. package/dist/utils/rehype-code-meta.js.map +1 -1
  378. package/dist/utils/remark-code-meta.js.map +1 -1
  379. package/dist/utils/routerBuilder.js.map +1 -1
  380. package/dist/utils/safeStorage.js.map +1 -1
  381. package/dist/utils/selection.js +29 -20
  382. package/dist/utils/selection.js.map +1 -1
  383. package/dist/utils/themes.js.map +1 -1
  384. package/package.json +15 -11
@@ -1 +1 @@
1
- {"version":3,"file":"themeColor.js","names":[],"sources":["../../../../../src/components/pro/Flow/utils/themeColor.ts"],"sourcesContent":["/**\n * Resolve a CSS color value (including theme custom properties like\n * `var(--color-base-100)` that may use `oklch(...)`) into a concrete sRGB color\n * for the WebGL canvas.\n *\n * PixiJS needs a numeric/hex color and cannot read CSS variables. Resolution:\n * 1. A hidden probe element inherits the themed scope. Its `color` is set to\n * `color-mix(in srgb, <value> 100%, transparent)`, which forces the\n * browser to convert the color into the sRGB space at computed-value\n * time. `getComputedStyle` then serializes it as a plain `rgb(...)` or\n * `color(srgb ...)` string.\n * 2. That string is parsed directly (no canvas). Canvas rasterization is\n * only a last resort: some engines silently reject CSS Color 4 functions\n * (`oklch()`, `lab()`, `color()`) in `fillStyle`, which previously turned\n * every probed theme color black.\n */\n\nlet _rasterCtx: CanvasRenderingContext2D | null = null;\nfunction getRasterCtx(): CanvasRenderingContext2D | null {\n if (_rasterCtx) return _rasterCtx;\n if (typeof document === 'undefined') return null;\n const canvas = document.createElement('canvas');\n canvas.width = 1;\n canvas.height = 1;\n _rasterCtx = canvas.getContext('2d', { willReadFrequently: true });\n return _rasterCtx;\n}\n\n/** Rasterize any CSS color string to concrete sRGB bytes. */\nfunction rasterizeColor(cssColor: string): [number, number, number] | null {\n const ctx = getRasterCtx();\n if (!ctx) return null;\n try {\n ctx.clearRect(0, 0, 1, 1);\n ctx.fillStyle = '#000000';\n ctx.fillStyle = cssColor; // ignored if the browser can't parse it\n ctx.fillRect(0, 0, 1, 1);\n const { data } = ctx.getImageData(0, 0, 1, 1);\n return [data[0], data[1], data[2]];\n } catch {\n return null;\n }\n}\n\nfunction byte(v: number): number {\n return Math.max(0, Math.min(255, Math.round(v)));\n}\n\n/**\n * Parse the sRGB strings a browser serializes a computed color to when the\n * color was forced into the sRGB space: `rgb(...)` / `rgba(...)` (0-255\n * channels) or `color(srgb r g b / a)` (0-1 float channels).\n */\nfunction parseSrgbString(value: string): [number, number, number] | null {\n const rgb = /^rgba?\\(\\s*([\\d.eE+-]+)[\\s,]+([\\d.eE+-]+)[\\s,]+([\\d.eE+-]+)/.exec(value);\n if (rgb) return [byte(+rgb[1]), byte(+rgb[2]), byte(+rgb[3])];\n const fn = /^color\\(\\s*srgb\\s+([\\d.eE+-]+)\\s+([\\d.eE+-]+)\\s+([\\d.eE+-]+)/i.exec(value);\n if (fn) return [byte(+fn[1] * 255), byte(+fn[2] * 255), byte(+fn[3] * 255)];\n return null;\n}\n\n/** Whether the browser computes color-mix() (used to force sRGB output). */\nconst SUPPORTS_COLOR_MIX =\n typeof CSS !== 'undefined' &&\n typeof CSS.supports === 'function' &&\n CSS.supports('color', 'color-mix(in srgb, red, blue)');\n\nfunction parseRgb(host: HTMLElement | null, cssValue: string): [number, number, number] | null {\n if (typeof document === 'undefined') return null;\n try {\n const probe = document.createElement('span');\n // Keep out of layout without `display:none` so `color` still resolves.\n probe.style.position = 'absolute';\n probe.style.width = '0';\n probe.style.height = '0';\n probe.style.overflow = 'hidden';\n probe.style.pointerEvents = 'none';\n (host ?? document.body).appendChild(probe);\n // Bail out when the requested custom property is undefined in this scope:\n // var() would invalidate the declaration and the probe would report its\n // inherited text color instead of the theme color.\n const varMatch = /^var\\(\\s*(--[\\w-]+)\\s*\\)$/.exec(cssValue);\n if (varMatch && !getComputedStyle(probe).getPropertyValue(varMatch[1]).trim()) {\n probe.remove();\n return null;\n }\n // Force the resolved color into the sRGB space at computed-value time, so\n // the serialized result is a plain rgb()/color(srgb) string we can parse\n // ourselves. Do NOT rasterize oklch()/lab() via canvas fillStyle here:\n // some engines (e.g. WebKit) silently reject CSS Color 4 functions in\n // canvas, which used to turn every probed theme color black.\n probe.style.color = SUPPORTS_COLOR_MIX\n ? `color-mix(in srgb, ${cssValue} 100%, transparent)`\n : cssValue;\n const resolved = getComputedStyle(probe).color;\n probe.remove();\n return parseSrgbString(resolved) ?? rasterizeColor(resolved);\n } catch {\n return null;\n }\n}\n\n/** Resolve a CSS color to a 0xRRGGBB number (for PixiJS). */\nexport function cssColorToNumber(host: HTMLElement | null, cssValue: string, fallback: number): number {\n const rgb = parseRgb(host, cssValue);\n if (!rgb) return fallback;\n return (rgb[0] << 16) | (rgb[1] << 8) | rgb[2];\n}\n\n/** Resolve a CSS color to a `#rrggbb` string (for persisted node data). */\nexport function cssColorToHexString(host: HTMLElement | null, cssValue: string, fallback: string): string {\n const rgb = parseRgb(host, cssValue);\n if (!rgb) return fallback;\n return '#' + rgb.map((c) => c.toString(16).padStart(2, '0')).join('');\n}\n\n/**\n * The colors the Flow canvas derives from the active theme:\n * - `background`: the canvas backdrop, follows the theme's muted background.\n * - `gridDot`: grid dots, derived from the theme foreground color.\n * - `nodeFill`: default fill for new shapes, follows the theme base background.\n */\nexport interface FlowThemeColors {\n background: number;\n gridDot: number;\n nodeFill: string;\n nodeText: string;\n}\n\nexport function resolveFlowThemeColors(host: HTMLElement | null): FlowThemeColors {\n return {\n background: cssColorToNumber(host, 'var(--color-base-200)', 0xf8f9fa),\n gridDot: cssColorToNumber(host, 'var(--color-base-content)', 0xd1d5db),\n nodeFill: cssColorToHexString(host, 'var(--color-base-100)', '#ffffff'),\n nodeText: cssColorToHexString(host, 'var(--color-base-content)', '#111827'),\n };\n}\n\n/* ============================================================================\n * Theme color tokens\n *\n * Node/edge colors may be stored either as a literal color (`#rrggbb`,\n * `transparent`, …) or as a THEME TOKEN of the form `theme:<name>` (e.g.\n * `theme:base-100`). Theme tokens are resolved to the live theme color at\n * render time, so shapes that use them re-color automatically whenever the\n * DishUI theme changes. These tokens are the default colors for new shapes.\n * ========================================================================== */\n\nexport const THEME_COLOR_PREFIX = 'theme:';\n\n/** A selectable theme color, shown as a swatch in the inspector. */\nexport interface ThemeColorToken {\n /** Stored value, e.g. `theme:base-100`. */\n token: string;\n /** CSS custom property backing the token. */\n cssVar: string;\n /** Short label for the inspector tooltip. */\n label: string;\n}\n\n/** The theme colors offered as presets/defaults for Flow color fields. */\nexport const THEME_COLOR_TOKENS: ThemeColorToken[] = [\n { token: 'theme:base-100', cssVar: 'var(--color-base-100)', label: 'Base 100' },\n { token: 'theme:base-200', cssVar: 'var(--color-base-200)', label: 'Base 200' },\n { token: 'theme:base-300', cssVar: 'var(--color-base-300)', label: 'Base 300' },\n { token: 'theme:base-content', cssVar: 'var(--color-base-content)', label: 'Base Content' },\n { token: 'theme:primary', cssVar: 'var(--color-primary)', label: 'Primary' },\n { token: 'theme:secondary', cssVar: 'var(--color-secondary)', label: 'Secondary' },\n { token: 'theme:accent', cssVar: 'var(--color-accent)', label: 'Accent' },\n { token: 'theme:neutral', cssVar: 'var(--color-neutral)', label: 'Neutral' },\n { token: 'theme:info', cssVar: 'var(--color-info)', label: 'Info' },\n { token: 'theme:success', cssVar: 'var(--color-success)', label: 'Success' },\n { token: 'theme:warning', cssVar: 'var(--color-warning)', label: 'Warning' },\n { token: 'theme:error', cssVar: 'var(--color-error)', label: 'Error' },\n];\n\nconst TOKEN_TO_CSSVAR = new Map(THEME_COLOR_TOKENS.map((t) => [t.token, t.cssVar]));\nconst TOKEN_TO_LABEL = new Map(THEME_COLOR_TOKENS.map((t) => [t.token, t.label]));\n\n/**\n * The \"follow theme\" default token for each color field type. Each field syncs\n * to a theme role so shapes stay legible against the canvas:\n * - `fill` -> theme background (base-100)\n * - `stroke` -> theme hairline (base-300) — a calm, low-contrast outline\n * - `text` -> theme font color (base-content)\n * - `line` -> theme hairline (base-300) — lines/edges\n */\nexport type ThemeColorFieldKind = 'fill' | 'stroke' | 'text' | 'line';\n\nexport const THEME_SYNC_TOKEN: Record<ThemeColorFieldKind, string> = {\n fill: 'theme:base-100',\n stroke: 'theme:base-300',\n text: 'theme:base-content',\n line: 'theme:base-300',\n};\n\n/** The CSS var backing a given theme token (for live-updating DOM swatches). */\nexport function themeTokenCssVar(token: string): string | undefined {\n return TOKEN_TO_CSSVAR.get(token);\n}\n\n/** Human label for a theme token (for tooltips). */\nexport function themeTokenLabel(token: string): string | undefined {\n return TOKEN_TO_LABEL.get(token);\n}\n\n/**\n * Common named colors offered after the theme-sync swatch: a compact rainbow\n * plus black/white. Order follows 黑白赤橙黄绿青蓝紫粉 (black, white, red,\n * orange, yellow, green, cyan, blue, purple, pink).\n */\nexport interface NamedColor {\n value: string;\n /** Chinese label shown on hover. */\n label: string;\n}\n\nexport const COMMON_COLORS: NamedColor[] = [\n { value: '#000000', label: '黑' },\n { value: '#ffffff', label: '白' },\n { value: '#ef4444', label: '赤' },\n { value: '#f97316', label: '橙' },\n { value: '#eab308', label: '黄' },\n { value: '#22c55e', label: '绿' },\n { value: '#06b6d4', label: '青' },\n { value: '#3b82f6', label: '蓝' },\n { value: '#8b5cf6', label: '紫' },\n { value: '#ec4899', label: '粉' },\n];\n\n/** True when `value` is a `theme:*` token. */\nexport function isThemeToken(value: string | undefined | null): value is string {\n return typeof value === 'string' && value.startsWith(THEME_COLOR_PREFIX);\n}\n\n// Module-level cache of the currently resolved token -> `#rrggbb` mapping. The\n// render loop resolves tokens against this cache (cheap, synchronous) instead\n// of probing the DOM every frame. `refreshThemePalette` rebuilds it whenever\n// the theme changes.\nconst _palette = new Map<string, string>();\n\n/**\n * Re-resolve every theme token against the given host's themed scope and cache\n * the results. Call on init and whenever the active theme changes.\n */\nexport function refreshThemePalette(host: HTMLElement | null): void {\n for (const { token, cssVar } of THEME_COLOR_TOKENS) {\n _palette.set(token, cssColorToHexString(host, cssVar, '#000000'));\n }\n}\n\n/**\n * Resolve a stored color value to a concrete `#rrggbb`/literal color. Theme\n * tokens are looked up in the cached palette; anything else is returned as-is.\n */\nexport function resolveThemeColor(value: string | undefined | null, fallback = '#000000'): string {\n if (!value) return fallback;\n if (isThemeToken(value)) return _palette.get(value) ?? fallback;\n return value;\n}\n\n/**\n * Resolve a stored color to a value usable directly in the DOM. Theme tokens\n * map to their CSS variable so the browser tracks theme changes natively.\n */\nexport function resolveThemeColorCss(value: string | undefined | null, fallback = '#000000'): string {\n if (!value) return fallback;\n if (isThemeToken(value)) return TOKEN_TO_CSSVAR.get(value) ?? fallback;\n return value;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"themeColor.js","names":["_rasterCtx","getRasterCtx","canvas","rasterizeColor","ctx","cssColor","data","byte","v","parseSrgbString","rgb","value","fn","SUPPORTS_COLOR_MIX","parseRgb","probe","host","varMatch","cssValue","resolved","cssColorToNumber","fallback","cssColorToHexString","c","resolveFlowThemeColors","THEME_COLOR_PREFIX","THEME_COLOR_TOKENS","TOKEN_TO_CSSVAR","t","THEME_SYNC_TOKEN","themeTokenCssVar","token","COMMON_COLORS","isThemeToken","_palette","refreshThemePalette","cssVar","resolveThemeColor","resolveThemeColorCss"],"sources":["../../../../../src/components/pro/Flow/utils/themeColor.ts"],"sourcesContent":["/**\n * Resolve a CSS color value (including theme custom properties like\n * `var(--color-base-100)` that may use `oklch(...)`) into a concrete sRGB color\n * for the WebGL canvas.\n *\n * PixiJS needs a numeric/hex color and cannot read CSS variables. Resolution:\n * 1. A hidden probe element inherits the themed scope. Its `color` is set to\n * `color-mix(in srgb, <value> 100%, transparent)`, which forces the\n * browser to convert the color into the sRGB space at computed-value\n * time. `getComputedStyle` then serializes it as a plain `rgb(...)` or\n * `color(srgb ...)` string.\n * 2. That string is parsed directly (no canvas). Canvas rasterization is\n * only a last resort: some engines silently reject CSS Color 4 functions\n * (`oklch()`, `lab()`, `color()`) in `fillStyle`, which previously turned\n * every probed theme color black.\n */\n\nlet _rasterCtx: CanvasRenderingContext2D | null = null;\nfunction getRasterCtx(): CanvasRenderingContext2D | null {\n if (_rasterCtx) return _rasterCtx;\n if (typeof document === 'undefined') return null;\n const canvas = document.createElement('canvas');\n canvas.width = 1;\n canvas.height = 1;\n _rasterCtx = canvas.getContext('2d', { willReadFrequently: true });\n return _rasterCtx;\n}\n\n/** Rasterize any CSS color string to concrete sRGB bytes. */\nfunction rasterizeColor(cssColor: string): [number, number, number] | null {\n const ctx = getRasterCtx();\n if (!ctx) return null;\n try {\n ctx.clearRect(0, 0, 1, 1);\n ctx.fillStyle = '#000000';\n ctx.fillStyle = cssColor; // ignored if the browser can't parse it\n ctx.fillRect(0, 0, 1, 1);\n const { data } = ctx.getImageData(0, 0, 1, 1);\n return [data[0], data[1], data[2]];\n } catch {\n return null;\n }\n}\n\nfunction byte(v: number): number {\n return Math.max(0, Math.min(255, Math.round(v)));\n}\n\n/**\n * Parse the sRGB strings a browser serializes a computed color to when the\n * color was forced into the sRGB space: `rgb(...)` / `rgba(...)` (0-255\n * channels) or `color(srgb r g b / a)` (0-1 float channels).\n */\nfunction parseSrgbString(value: string): [number, number, number] | null {\n const rgb = /^rgba?\\(\\s*([\\d.eE+-]+)[\\s,]+([\\d.eE+-]+)[\\s,]+([\\d.eE+-]+)/.exec(value);\n if (rgb) return [byte(+rgb[1]), byte(+rgb[2]), byte(+rgb[3])];\n const fn = /^color\\(\\s*srgb\\s+([\\d.eE+-]+)\\s+([\\d.eE+-]+)\\s+([\\d.eE+-]+)/i.exec(value);\n if (fn) return [byte(+fn[1] * 255), byte(+fn[2] * 255), byte(+fn[3] * 255)];\n return null;\n}\n\n/** Whether the browser computes color-mix() (used to force sRGB output). */\nconst SUPPORTS_COLOR_MIX =\n typeof CSS !== 'undefined' &&\n typeof CSS.supports === 'function' &&\n CSS.supports('color', 'color-mix(in srgb, red, blue)');\n\nfunction parseRgb(host: HTMLElement | null, cssValue: string): [number, number, number] | null {\n if (typeof document === 'undefined') return null;\n try {\n const probe = document.createElement('span');\n // Keep out of layout without `display:none` so `color` still resolves.\n probe.style.position = 'absolute';\n probe.style.width = '0';\n probe.style.height = '0';\n probe.style.overflow = 'hidden';\n probe.style.pointerEvents = 'none';\n (host ?? document.body).appendChild(probe);\n // Bail out when the requested custom property is undefined in this scope:\n // var() would invalidate the declaration and the probe would report its\n // inherited text color instead of the theme color.\n const varMatch = /^var\\(\\s*(--[\\w-]+)\\s*\\)$/.exec(cssValue);\n if (varMatch && !getComputedStyle(probe).getPropertyValue(varMatch[1]).trim()) {\n probe.remove();\n return null;\n }\n // Force the resolved color into the sRGB space at computed-value time, so\n // the serialized result is a plain rgb()/color(srgb) string we can parse\n // ourselves. Do NOT rasterize oklch()/lab() via canvas fillStyle here:\n // some engines (e.g. WebKit) silently reject CSS Color 4 functions in\n // canvas, which used to turn every probed theme color black.\n probe.style.color = SUPPORTS_COLOR_MIX\n ? `color-mix(in srgb, ${cssValue} 100%, transparent)`\n : cssValue;\n const resolved = getComputedStyle(probe).color;\n probe.remove();\n return parseSrgbString(resolved) ?? rasterizeColor(resolved);\n } catch {\n return null;\n }\n}\n\n/** Resolve a CSS color to a 0xRRGGBB number (for PixiJS). */\nexport function cssColorToNumber(host: HTMLElement | null, cssValue: string, fallback: number): number {\n const rgb = parseRgb(host, cssValue);\n if (!rgb) return fallback;\n return (rgb[0] << 16) | (rgb[1] << 8) | rgb[2];\n}\n\n/** Resolve a CSS color to a `#rrggbb` string (for persisted node data). */\nexport function cssColorToHexString(host: HTMLElement | null, cssValue: string, fallback: string): string {\n const rgb = parseRgb(host, cssValue);\n if (!rgb) return fallback;\n return '#' + rgb.map((c) => c.toString(16).padStart(2, '0')).join('');\n}\n\n/**\n * The colors the Flow canvas derives from the active theme:\n * - `background`: the canvas backdrop, follows the theme's muted background.\n * - `gridDot`: grid dots, derived from the theme foreground color.\n * - `nodeFill`: default fill for new shapes, follows the theme base background.\n */\nexport interface FlowThemeColors {\n background: number;\n gridDot: number;\n nodeFill: string;\n nodeText: string;\n}\n\nexport function resolveFlowThemeColors(host: HTMLElement | null): FlowThemeColors {\n return {\n background: cssColorToNumber(host, 'var(--color-base-200)', 0xf8f9fa),\n gridDot: cssColorToNumber(host, 'var(--color-base-content)', 0xd1d5db),\n nodeFill: cssColorToHexString(host, 'var(--color-base-100)', '#ffffff'),\n nodeText: cssColorToHexString(host, 'var(--color-base-content)', '#111827'),\n };\n}\n\n/* ============================================================================\n * Theme color tokens\n *\n * Node/edge colors may be stored either as a literal color (`#rrggbb`,\n * `transparent`, …) or as a THEME TOKEN of the form `theme:<name>` (e.g.\n * `theme:base-100`). Theme tokens are resolved to the live theme color at\n * render time, so shapes that use them re-color automatically whenever the\n * DishUI theme changes. These tokens are the default colors for new shapes.\n * ========================================================================== */\n\nexport const THEME_COLOR_PREFIX = 'theme:';\n\n/** A selectable theme color, shown as a swatch in the inspector. */\nexport interface ThemeColorToken {\n /** Stored value, e.g. `theme:base-100`. */\n token: string;\n /** CSS custom property backing the token. */\n cssVar: string;\n /** Short label for the inspector tooltip. */\n label: string;\n}\n\n/** The theme colors offered as presets/defaults for Flow color fields. */\nexport const THEME_COLOR_TOKENS: ThemeColorToken[] = [\n { token: 'theme:base-100', cssVar: 'var(--color-base-100)', label: 'Base 100' },\n { token: 'theme:base-200', cssVar: 'var(--color-base-200)', label: 'Base 200' },\n { token: 'theme:base-300', cssVar: 'var(--color-base-300)', label: 'Base 300' },\n { token: 'theme:base-content', cssVar: 'var(--color-base-content)', label: 'Base Content' },\n { token: 'theme:primary', cssVar: 'var(--color-primary)', label: 'Primary' },\n { token: 'theme:secondary', cssVar: 'var(--color-secondary)', label: 'Secondary' },\n { token: 'theme:accent', cssVar: 'var(--color-accent)', label: 'Accent' },\n { token: 'theme:neutral', cssVar: 'var(--color-neutral)', label: 'Neutral' },\n { token: 'theme:info', cssVar: 'var(--color-info)', label: 'Info' },\n { token: 'theme:success', cssVar: 'var(--color-success)', label: 'Success' },\n { token: 'theme:warning', cssVar: 'var(--color-warning)', label: 'Warning' },\n { token: 'theme:error', cssVar: 'var(--color-error)', label: 'Error' },\n];\n\nconst TOKEN_TO_CSSVAR = new Map(THEME_COLOR_TOKENS.map((t) => [t.token, t.cssVar]));\nconst TOKEN_TO_LABEL = new Map(THEME_COLOR_TOKENS.map((t) => [t.token, t.label]));\n\n/**\n * The \"follow theme\" default token for each color field type. Each field syncs\n * to a theme role so shapes stay legible against the canvas:\n * - `fill` -> theme background (base-100)\n * - `stroke` -> theme hairline (base-300) — a calm, low-contrast outline\n * - `text` -> theme font color (base-content)\n * - `line` -> theme hairline (base-300) — lines/edges\n */\nexport type ThemeColorFieldKind = 'fill' | 'stroke' | 'text' | 'line';\n\nexport const THEME_SYNC_TOKEN: Record<ThemeColorFieldKind, string> = {\n fill: 'theme:base-100',\n stroke: 'theme:base-300',\n text: 'theme:base-content',\n line: 'theme:base-300',\n};\n\n/** The CSS var backing a given theme token (for live-updating DOM swatches). */\nexport function themeTokenCssVar(token: string): string | undefined {\n return TOKEN_TO_CSSVAR.get(token);\n}\n\n/** Human label for a theme token (for tooltips). */\nexport function themeTokenLabel(token: string): string | undefined {\n return TOKEN_TO_LABEL.get(token);\n}\n\n/**\n * Common named colors offered after the theme-sync swatch: a compact rainbow\n * plus black/white. Order follows 黑白赤橙黄绿青蓝紫粉 (black, white, red,\n * orange, yellow, green, cyan, blue, purple, pink).\n */\nexport interface NamedColor {\n value: string;\n /** Chinese label shown on hover. */\n label: string;\n}\n\nexport const COMMON_COLORS: NamedColor[] = [\n { value: '#000000', label: '黑' },\n { value: '#ffffff', label: '白' },\n { value: '#ef4444', label: '赤' },\n { value: '#f97316', label: '橙' },\n { value: '#eab308', label: '黄' },\n { value: '#22c55e', label: '绿' },\n { value: '#06b6d4', label: '青' },\n { value: '#3b82f6', label: '蓝' },\n { value: '#8b5cf6', label: '紫' },\n { value: '#ec4899', label: '粉' },\n];\n\n/** True when `value` is a `theme:*` token. */\nexport function isThemeToken(value: string | undefined | null): value is string {\n return typeof value === 'string' && value.startsWith(THEME_COLOR_PREFIX);\n}\n\n// Module-level cache of the currently resolved token -> `#rrggbb` mapping. The\n// render loop resolves tokens against this cache (cheap, synchronous) instead\n// of probing the DOM every frame. `refreshThemePalette` rebuilds it whenever\n// the theme changes.\nconst _palette = new Map<string, string>();\n\n/**\n * Re-resolve every theme token against the given host's themed scope and cache\n * the results. Call on init and whenever the active theme changes.\n */\nexport function refreshThemePalette(host: HTMLElement | null): void {\n for (const { token, cssVar } of THEME_COLOR_TOKENS) {\n _palette.set(token, cssColorToHexString(host, cssVar, '#000000'));\n }\n}\n\n/**\n * Resolve a stored color value to a concrete `#rrggbb`/literal color. Theme\n * tokens are looked up in the cached palette; anything else is returned as-is.\n */\nexport function resolveThemeColor(value: string | undefined | null, fallback = '#000000'): string {\n if (!value) return fallback;\n if (isThemeToken(value)) return _palette.get(value) ?? fallback;\n return value;\n}\n\n/**\n * Resolve a stored color to a value usable directly in the DOM. Theme tokens\n * map to their CSS variable so the browser tracks theme changes natively.\n */\nexport function resolveThemeColorCss(value: string | undefined | null, fallback = '#000000'): string {\n if (!value) return fallback;\n if (isThemeToken(value)) return TOKEN_TO_CSSVAR.get(value) ?? fallback;\n return value;\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"Gantt.js","names":[],"sources":["../../../../src/components/pro/Gantt/Gantt.tsx"],"sourcesContent":["/**\n * DishUI Gantt Chart Component\n */\n\nimport React, {\n forwardRef,\n useImperativeHandle,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type {\n GanttProps,\n GanttHandle,\n GanttNode,\n GanttNodeId,\n GanttScaleLevel,\n FlatGanttNode,\n GanttDependencyLink,\n GanttGridConfig,\n} from \"./types\";\nimport { useGanttState } from \"./hooks/useGanttState\";\nimport { useGanttDrag } from \"./hooks/useGanttDrag\";\nimport {\n isNonWorkingDay,\n isWeekend,\n isSameDay,\n formatDate,\n DEFAULT_SCALE_CONFIGS,\n} from \"./utils\";\nimport \"./styles.css\";\n\n// ─── Helpers ──────────────────────────────────────────────────────\n\n/**\n * Check if a date is a declared holiday entry.\n * Returns true for any date that has an explicit non-working holiday entry,\n * INCLUDING weekends that happen to fall within a holiday period (e.g. Spring Festival).\n * 调休 (compensatory workday entries with isWorkday=true) are NOT holidays.\n */\nfunction isHolidayOnly(date: Date, holidays?: GanttProps[\"holidays\"]): boolean {\n if (!holidays) return false;\n if (holidays.isNonWorkingDay) {\n return holidays.isNonWorkingDay(date);\n }\n const dateStr = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, \"0\")}-${String(date.getDate()).padStart(2, \"0\")}`;\n const entry = holidays.entries?.find((e) => e.date === dateStr);\n if (!entry) return false;\n // 调休 (compensatory workday) is NOT a holiday\n if (entry.isWorkday) return false;\n return true;\n}\n\nconst DEFAULT_GRID: Required<GanttGridConfig> = {\n showCellBorders: true,\n cellBorderColor: \"\",\n weekendColor: \"\",\n holidayColor: \"#fff0f3\",\n todayColor: \"\",\n showRowLines: false,\n};\n\nconst DEFAULT_LABELS = {\n treePanelTitle: \"Tasks\",\n searchPlaceholder: \"Search...\",\n expandAll: \"Expand All\",\n collapseAll: \"Collapse All\",\n today: \"Today\",\n zoomIn: \"Zoom In\",\n zoomOut: \"Zoom Out\",\n noData: \"No data\",\n workingDays: \"Working days\",\n calendarDays: \"Calendar days\",\n weekDays: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"] as [\n string,\n string,\n string,\n string,\n string,\n string,\n string,\n ],\n monthNames: [\n \"Jan\",\n \"Feb\",\n \"Mar\",\n \"Apr\",\n \"May\",\n \"Jun\",\n \"Jul\",\n \"Aug\",\n \"Sep\",\n \"Oct\",\n \"Nov\",\n \"Dec\",\n ] as [\n string,\n string,\n string,\n string,\n string,\n string,\n string,\n string,\n string,\n string,\n string,\n string,\n ],\n add: \"Add\",\n delete: \"Delete\",\n edit: \"Edit\",\n link: \"Open link\",\n};\n\n// ─── Main Component ───────────────────────────────────────────────\n\nconst Gantt = forwardRef<GanttHandle, GanttProps>(function Gantt(props, ref) {\n const {\n data,\n categories = {},\n holidays,\n timeWindow,\n columns,\n defaultScale = \"day\",\n availableScales,\n scaleConfigs,\n treePanelWidth: initialTreeWidth = 300,\n treePanelMinWidth = 200,\n treePanelMaxWidth = 600,\n treePanelResizable = true,\n rowHeight = 36,\n draggable = false,\n resizable = false,\n readOnly = false,\n defaultExpandedIds,\n defaultExpandAll = true,\n todayMarker = { visible: true, autoScroll: true },\n tooltip: tooltipConfig = { enabled: true },\n labels: userLabels,\n showSearch = false,\n highlightNonWorkingDays = true,\n grid: userGrid,\n dependencyLinks = [],\n className,\n width = \"100%\",\n height = \"100%\",\n onBarChange,\n onNodeClick,\n onNodeDoubleClick,\n onContextMenu,\n onNodeToggle,\n onViewChange,\n onScaleChange,\n onNodeLabelEdit,\n onNodeAdd,\n onNodeAddChild,\n onNodeDelete,\n onNodeLinkClick,\n onDependencyCreate,\n onDependencyClick,\n onDependencyDelete,\n renderTreeNode,\n renderToolbar,\n renderTimelineHeader,\n } = props;\n\n const labels = useMemo(\n () => ({ ...DEFAULT_LABELS, ...userLabels }),\n [userLabels],\n );\n const gridCfg = useMemo(() => ({ ...DEFAULT_GRID, ...userGrid }), [userGrid]);\n\n // ─── Core state ─────────────────────────────────────────────\n const state = useGanttState({\n data,\n defaultScale,\n defaultExpandedIds,\n defaultExpandAll,\n scaleConfigs,\n categories,\n holidays,\n timeWindow,\n availableScales,\n onScaleChange,\n onNodeToggle,\n onViewChange,\n });\n const {\n scale,\n setScale,\n scales,\n currentScaleConfig,\n flatNodes,\n dates,\n headerGroups,\n dateRange,\n today,\n todayX,\n totalTimelineWidth,\n selectedNodeId,\n setSelectedNodeId,\n toggleNode,\n expandAll,\n collapseAll,\n scrollToDate,\n scrollToToday,\n scrollToNode,\n treeBodyRef,\n timelineBodyRef,\n timelineHeaderRef,\n syncScrollVertical,\n syncScrollHorizontal,\n } = state;\n\n const drag = useGanttDrag({\n scaleConfig: currentScaleConfig,\n timelineStart: dateRange.start,\n onBarChange: readOnly ? undefined : onBarChange,\n calendar: holidays,\n });\n\n // ─── Tree panel resize ──────────────────────────────────────\n const [treePanelW, setTreePanelW] = useState(initialTreeWidth);\n const resizingRef = useRef(false);\n const resizeStartRef = useRef({ x: 0, width: 0 });\n const handleResizeStart = useCallback(\n (e: React.MouseEvent) => {\n if (!treePanelResizable) return;\n e.preventDefault();\n resizingRef.current = true;\n resizeStartRef.current = { x: e.clientX, width: treePanelW };\n const hm = (ev: MouseEvent) => {\n if (!resizingRef.current) return;\n setTreePanelW(\n Math.max(\n treePanelMinWidth,\n Math.min(\n treePanelMaxWidth,\n resizeStartRef.current.width +\n ev.clientX -\n resizeStartRef.current.x,\n ),\n ),\n );\n };\n const hu = () => {\n resizingRef.current = false;\n window.removeEventListener(\"mousemove\", hm);\n window.removeEventListener(\"mouseup\", hu);\n };\n window.addEventListener(\"mousemove\", hm);\n window.addEventListener(\"mouseup\", hu);\n },\n [treePanelResizable, treePanelW, treePanelMinWidth, treePanelMaxWidth],\n );\n\n // ─── Search ─────────────────────────────────────────────────\n const [searchQuery, setSearchQuery] = useState(\"\");\n const filteredFlatNodes = useMemo(() => {\n if (!searchQuery.trim()) return flatNodes;\n const q = searchQuery.toLowerCase();\n return flatNodes.filter((fn) => fn.node.label.toLowerCase().includes(q));\n }, [flatNodes, searchQuery]);\n\n // ─── Edit dialog ─────────────────────────────────────────\n const [editingLabel, setEditingLabel] = useState(\"\");\n const [editDialogOpen, setEditDialogOpen] = useState(false);\n const [editDialogNode, setEditDialogNode] = useState<GanttNode | null>(null);\n const editInputRef = useRef<HTMLInputElement>(null);\n const startEditing = useCallback(\n (node: GanttNode) => {\n if (readOnly || !onNodeLabelEdit) return;\n setEditDialogNode(node);\n setEditingLabel(node.label);\n setEditDialogOpen(true);\n },\n [readOnly, onNodeLabelEdit],\n );\n const commitEdit = useCallback(() => {\n if (!editDialogNode) return;\n const trimmed = editingLabel.trim();\n if (trimmed && onNodeLabelEdit && trimmed !== editDialogNode.label) {\n onNodeLabelEdit(editDialogNode, trimmed);\n }\n setEditDialogOpen(false);\n setEditDialogNode(null);\n setEditingLabel(\"\");\n }, [editDialogNode, editingLabel, onNodeLabelEdit]);\n const cancelEdit = useCallback(() => {\n setEditDialogOpen(false);\n setEditDialogNode(null);\n setEditingLabel(\"\");\n }, []);\n\n // ─── Dependency connector drag ──────────────────────────────\n const [connDrag, setConnDrag] = useState<{\n fromId: GanttNodeId;\n startX: number;\n startY: number;\n curX: number;\n curY: number;\n } | null>(null);\n const connDragRef = useRef(connDrag);\n connDragRef.current = connDrag;\n const timelinePanelRef = useRef<HTMLDivElement>(null);\n\n const handleConnectorMouseDown = useCallback(\n (e: React.MouseEvent, nodeId: GanttNodeId) => {\n if (readOnly || !onDependencyCreate) return;\n e.preventDefault();\n e.stopPropagation();\n const body = timelineBodyRef.current;\n if (!body) return;\n const rect = body.getBoundingClientRect();\n // Snap start point to the bar's connector edge rather than exact mouse position\n const displayN = showSearch ? filteredFlatNodes : flatNodes;\n const fn = displayN.find((f) => f.node.id === nodeId);\n let x: number;\n let y: number;\n if (fn) {\n // Determine if clicked on left or right connector\n const mouseX = e.clientX - rect.left + body.scrollLeft;\n const barCenter = fn.barLeft + fn.barWidth / 2;\n if (mouseX < barCenter) {\n x = fn.barLeft; // left edge\n } else {\n x = fn.barLeft + fn.barWidth; // right edge\n }\n y = fn.visibleIndex * rowHeight + rowHeight / 2;\n } else {\n x = e.clientX - rect.left + body.scrollLeft;\n y = e.clientY - rect.top + body.scrollTop;\n }\n setConnDrag({ fromId: nodeId, startX: x, startY: y, curX: x, curY: y });\n },\n [\n readOnly,\n onDependencyCreate,\n timelineBodyRef,\n flatNodes,\n filteredFlatNodes,\n showSearch,\n rowHeight,\n ],\n );\n\n useEffect(() => {\n if (!connDrag) return;\n const body = timelineBodyRef.current;\n if (!body) return;\n\n const hm = (e: MouseEvent) => {\n const rect = body.getBoundingClientRect();\n const curX = e.clientX - rect.left + body.scrollLeft;\n const curY = e.clientY - rect.top + body.scrollTop;\n setConnDrag((prev) => (prev ? { ...prev, curX, curY } : null));\n };\n const hu = (e: MouseEvent) => {\n const cur = connDragRef.current;\n if (cur && onDependencyCreate) {\n const rect = body.getBoundingClientRect();\n const y = e.clientY - rect.top + body.scrollTop;\n const rowIdx = Math.floor(y / rowHeight);\n const displayN = showSearch ? filteredFlatNodes : flatNodes;\n const dn = displayN[rowIdx];\n if (dn && dn.node.id !== cur.fromId) {\n onDependencyCreate(cur.fromId, dn.node.id);\n }\n }\n setConnDrag(null);\n };\n window.addEventListener(\"mousemove\", hm);\n window.addEventListener(\"mouseup\", hu);\n return () => {\n window.removeEventListener(\"mousemove\", hm);\n window.removeEventListener(\"mouseup\", hu);\n };\n // Only re-attach listeners when drag starts (fromId changes), not on every cursor move\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [connDrag?.fromId]);\n\n // ─── Auto-scroll ────────────────────────────────────────────\n useEffect(() => {\n if (todayMarker.autoScroll !== false) {\n const t = setTimeout(scrollToToday, 100);\n return () => clearTimeout(t);\n }\n }, []); // eslint-disable-line react-hooks/exhaustive-deps\n\n useImperativeHandle(ref, () => ({\n scrollToDate,\n scrollToToday,\n scrollToNode,\n getVisibleRange: () => ({ start: dateRange.start, end: dateRange.end }),\n setScale,\n expandAll,\n collapseAll,\n toggleNode,\n }));\n\n // ─── Row click → smooth scroll to data start ───────────────\n const handleRowClick = useCallback(\n (node: GanttNode) => {\n setSelectedNodeId(node.id);\n onNodeClick?.(node);\n const flat = flatNodes.find((fn) => fn.node.id === node.id);\n if (flat?.resolvedStartDate && timelineBodyRef.current) {\n const targetX = flat.barLeft - timelineBodyRef.current.clientWidth / 3;\n timelineBodyRef.current.scrollTo({\n left: Math.max(0, targetX),\n behavior: \"smooth\",\n });\n }\n },\n [flatNodes, setSelectedNodeId, onNodeClick, timelineBodyRef],\n );\n\n // ─── Context menu ───────────────────────────────────────────\n const handleTimelineContextMenu = useCallback(\n (e: React.MouseEvent) => {\n if (!onContextMenu) return;\n e.preventDefault();\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();\n const x =\n e.clientX - rect.left + (timelineBodyRef.current?.scrollLeft || 0);\n const date = new Date(dateRange.start);\n date.setDate(\n date.getDate() +\n Math.floor(\n x / (currentScaleConfig.cellWidth * currentScaleConfig.slotsPerDay),\n ),\n );\n onContextMenu({\n node: null,\n position: { x: e.clientX, y: e.clientY },\n date,\n });\n },\n [onContextMenu, dateRange, currentScaleConfig, timelineBodyRef],\n );\n\n const findParent = useCallback(\n (\n targetId: GanttNodeId,\n nodes: GanttNode[],\n parent: GanttNode | null,\n ): GanttNode | null => {\n for (const n of nodes) {\n if (n.id === targetId) return parent;\n if (n.children) {\n const f = findParent(targetId, n.children, n);\n if (f !== undefined) return f;\n }\n }\n return null;\n },\n [],\n );\n\n // ─── Toolbar ────────────────────────────────────────────────\n const defaultToolbar = (\n <div className=\"gantt-toolbar\">\n <div className=\"gantt-toolbar-group\">\n {scales.map((s) => (\n <button\n key={s}\n className={`gantt-scale-btn ${s === scale ? \"gantt-scale-btn--active\" : \"\"}`}\n onClick={() => setScale(s)}\n title={DEFAULT_SCALE_CONFIGS[s].label}\n >\n {DEFAULT_SCALE_CONFIGS[s].label}\n </button>\n ))}\n </div>\n <div className=\"gantt-toolbar-divider\" />\n <button\n className=\"gantt-icon-btn\"\n onClick={scrollToToday}\n title={labels.today}\n >\n ◉\n </button>\n <button\n className=\"gantt-icon-btn\"\n onClick={expandAll}\n title={labels.expandAll}\n >\n ⊞\n </button>\n <button\n className=\"gantt-icon-btn\"\n onClick={collapseAll}\n title={labels.collapseAll}\n >\n ⊟\n </button>\n <div className=\"gantt-toolbar-spacer\" />\n <span style={{ fontSize: 11, color: \"oklch(var(--bc) / 0.4)\" }}>\n {flatNodes.length} items\n </span>\n </div>\n );\n const toolbar = renderToolbar\n ? renderToolbar(defaultToolbar)\n : defaultToolbar;\n\n // ─── Tree Row ───────────────────────────────────────────────\n const renderTreeRow = (flatNode: FlatGanttNode) => {\n const { node, depth, expanded, hasChildren } = flatNode;\n const isSelected = selectedNodeId === node.id;\n\n if (renderTreeNode) {\n return (\n <div\n key={node.id}\n className={`gantt-tree-row ${isSelected ? \"gantt-tree-row--selected\" : \"\"}`}\n style={{ height: rowHeight }}\n onClick={() => handleRowClick(node)}\n onDoubleClick={() => {\n onNodeDoubleClick?.(node);\n startEditing(node);\n }}\n >\n {renderTreeNode(node, depth, expanded, () => toggleNode(node.id))}\n </div>\n );\n }\n\n return (\n <div\n key={node.id}\n className={`gantt-tree-row ${isSelected ? \"gantt-tree-row--selected\" : \"\"}`}\n style={{ height: rowHeight }}\n onClick={() => handleRowClick(node)}\n onDoubleClick={() => {\n onNodeDoubleClick?.(node);\n startEditing(node);\n }}\n >\n <div className=\"gantt-tree-indent\" style={{ width: depth * 20 }} />\n <div\n className={`gantt-tree-toggle ${hasChildren ? (expanded ? \"gantt-tree-toggle--expanded\" : \"\") : \"gantt-tree-toggle--placeholder\"}`}\n onClick={(e) => {\n e.stopPropagation();\n if (hasChildren) toggleNode(node.id);\n }}\n >\n {hasChildren && \"\\u25B6\"}\n </div>\n <div className=\"gantt-tree-label\" title={node.label}>\n {node.label}\n </div>\n {node.link && (\n <button\n className=\"gantt-tree-action-btn\"\n title={labels.link}\n onClick={(e) => {\n e.stopPropagation();\n if (onNodeLinkClick) {\n onNodeLinkClick(node, node.link!);\n } else {\n window.open(node.link!, \"_blank\");\n }\n }}\n >\n <svg\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <path d=\"M10 13a5 5 0 007.54.54l3-3a5 5 0 00-7.07-7.07l-1.72 1.71\" />\n <path d=\"M14 11a5 5 0 00-7.54-.54l-3 3a5 5 0 007.07 7.07l1.71-1.71\" />\n </svg>\n </button>\n )}\n {columns?.map((col) => (\n <div\n key={col.key}\n className=\"gantt-tree-cell\"\n style={{ width: col.width || 80, textAlign: col.align || \"left\" }}\n >\n {col.render ? col.render(node, col) : (node.meta?.[col.key] ?? \"\")}\n </div>\n ))}\n {!readOnly && (onNodeAdd || onNodeAddChild || onNodeDelete) && (\n <div className=\"gantt-tree-actions gantt-tree-actions--pinned\">\n {onNodeAdd && (\n <button\n className=\"gantt-tree-action-btn\"\n title={labels.add}\n onClick={(e) => {\n e.stopPropagation();\n onNodeAdd(findParent(node.id, data, null), node);\n }}\n >\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" />\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </svg>\n </button>\n )}\n {onNodeAddChild && (\n <button\n className=\"gantt-tree-action-btn\"\n title=\"Add child\"\n onClick={(e) => {\n e.stopPropagation();\n onNodeAddChild(node);\n }}\n >\n {\"\\u229E\"}\n </button>\n )}\n {onNodeDelete && (\n <button\n className=\"gantt-tree-action-btn gantt-tree-action-btn--danger\"\n title={labels.delete}\n onClick={(e) => {\n e.stopPropagation();\n onNodeDelete(node);\n }}\n >\n {\"\\u00D7\"}\n </button>\n )}\n </div>\n )}\n </div>\n );\n };\n\n // ─── Timeline Header ───────────────────────────────────────\n const renderDefaultTimelineHeader = () => (\n <div className=\"gantt-timeline-header\" ref={timelineHeaderRef}>\n <div\n className=\"gantt-timeline-header-row\"\n style={{ width: totalTimelineWidth }}\n >\n {headerGroups.map((group, i) => (\n <div\n key={i}\n className=\"gantt-timeline-header-group\"\n style={{\n width:\n group.span *\n currentScaleConfig.cellWidth *\n currentScaleConfig.slotsPerDay,\n }}\n >\n {group.label}\n </div>\n ))}\n </div>\n <div\n className=\"gantt-timeline-header-row\"\n style={{ width: totalTimelineWidth }}\n >\n {scale === \"halfday\"\n ? dates.map((date, i) => {\n const isToday2 = isSameDay(date, today);\n const isWknd = isNonWorkingDay(date, holidays);\n const baseCls = `gantt-timeline-header-cell ${isToday2 ? \"gantt-timeline-header-cell--today\" : \"\"} ${isWknd ? \"gantt-timeline-header-cell--weekend\" : \"\"}`;\n return (\n <React.Fragment key={i}>\n <div\n className={baseCls}\n style={{ width: currentScaleConfig.cellWidth }}\n >\n 上午\n </div>\n <div\n className={baseCls}\n style={{ width: currentScaleConfig.cellWidth }}\n >\n 下午\n </div>\n </React.Fragment>\n );\n })\n : scale === \"hour\"\n ? dates.map((date, i) => {\n const isToday2 = isSameDay(date, today);\n const isWknd = isNonWorkingDay(date, holidays);\n const baseCls = `gantt-timeline-header-cell ${isToday2 ? \"gantt-timeline-header-cell--today\" : \"\"} ${isWknd ? \"gantt-timeline-header-cell--weekend\" : \"\"}`;\n return (\n <React.Fragment key={i}>\n {Array.from({ length: 24 }, (_, h) => (\n <div\n key={h}\n className={baseCls}\n style={{ width: currentScaleConfig.cellWidth }}\n >\n {h}\n </div>\n ))}\n </React.Fragment>\n );\n })\n : dates.map((date, i) => {\n const isToday2 = isSameDay(date, today);\n const isWknd = isNonWorkingDay(date, holidays);\n const cls = `gantt-timeline-header-cell ${isToday2 ? \"gantt-timeline-header-cell--today\" : \"\"} ${isWknd ? \"gantt-timeline-header-cell--weekend\" : \"\"}`;\n return (\n <div\n key={i}\n className={cls}\n style={{\n width:\n currentScaleConfig.cellWidth *\n currentScaleConfig.slotsPerDay,\n }}\n >\n {date.getDate()}\n </div>\n );\n })}\n </div>\n </div>\n );\n\n // ─── Grid Columns ──────────────────────────────────────────\n const renderGridColumns = () => {\n if (scale === \"halfday\" || scale === \"hour\") {\n // Render individual sub-cells for halfday/hour\n const slots = currentScaleConfig.slotsPerDay;\n const cellW = currentScaleConfig.cellWidth;\n const elements: React.ReactNode[] = [];\n dates.forEach((date, dayIdx) => {\n const isToday2 = isSameDay(date, today);\n const isHol = isHolidayOnly(date, holidays);\n const isWknd = isWeekend(date) && holidays?.weekendsOff !== false;\n const showBorder = gridCfg.showCellBorders;\n\n for (let s = 0; s < slots; s++) {\n const globalIdx = dayIdx * slots + s;\n const classes = [\"gantt-timeline-col\"];\n if (showBorder) classes.push(\"gantt-timeline-col--border\");\n if (highlightNonWorkingDays && isWknd)\n classes.push(\"gantt-timeline-col--weekend\");\n if (highlightNonWorkingDays && isHol)\n classes.push(\"gantt-timeline-col--holiday\");\n if (isToday2) classes.push(\"gantt-timeline-col--today\");\n\n const style: React.CSSProperties = {\n left: globalIdx * cellW,\n width: cellW,\n };\n if (gridCfg.cellBorderColor && showBorder)\n style.borderRightColor = gridCfg.cellBorderColor;\n if (isWknd && gridCfg.weekendColor)\n style.background = gridCfg.weekendColor;\n if (isHol && gridCfg.holidayColor)\n style.background = gridCfg.holidayColor;\n if (isToday2 && gridCfg.todayColor)\n style.background = gridCfg.todayColor;\n\n elements.push(\n <div\n key={`${dayIdx}-${s}`}\n className={classes.join(\" \")}\n style={style}\n />,\n );\n }\n });\n return elements;\n }\n\n return dates.map((date, i) => {\n const isToday2 = isSameDay(date, today);\n const isHol = isHolidayOnly(date, holidays);\n const isWknd = isWeekend(date) && holidays?.weekendsOff !== false;\n const showBorder = gridCfg.showCellBorders;\n\n const classes = [\"gantt-timeline-col\"];\n if (showBorder) classes.push(\"gantt-timeline-col--border\");\n if (highlightNonWorkingDays && isWknd)\n classes.push(\"gantt-timeline-col--weekend\");\n if (highlightNonWorkingDays && isHol)\n classes.push(\"gantt-timeline-col--holiday\");\n if (isToday2) classes.push(\"gantt-timeline-col--today\");\n\n // Custom inline colors from gridCfg\n const style: React.CSSProperties = {\n left: i * currentScaleConfig.cellWidth * currentScaleConfig.slotsPerDay,\n width: currentScaleConfig.cellWidth * currentScaleConfig.slotsPerDay,\n };\n if (gridCfg.cellBorderColor && showBorder)\n style.borderRightColor = gridCfg.cellBorderColor;\n if (isWknd && gridCfg.weekendColor)\n style.background = gridCfg.weekendColor;\n if (isHol && gridCfg.holidayColor)\n style.background = gridCfg.holidayColor;\n if (isToday2 && gridCfg.todayColor) style.background = gridCfg.todayColor;\n\n return <div key={i} className={classes.join(\" \")} style={style} />;\n });\n };\n\n // ─── Bar ────────────────────────────────────────────────────\n const renderBar = (flatNode: FlatGanttNode) => {\n const { node, barLeft, barWidth, isRenderable, categoryConfig } = flatNode;\n if (!isRenderable || barWidth <= 0) return null;\n\n const isDraggableBar = !readOnly && (categoryConfig.draggable ?? draggable);\n const isResizableBar = !readOnly && (categoryConfig.resizable ?? resizable);\n const isCurrentlyDragging = drag.draggingNodeId === node.id;\n const isSelected = selectedNodeId === node.id;\n const { left, width: adjustedWidth } = drag.getAdjustedBar(\n node.id,\n barLeft,\n barWidth,\n );\n\n // Per-node color > category color > default\n const barColor = node.barColor || categoryConfig.color || \"#3b82f6\";\n const barBg = node.barColor || categoryConfig.backgroundColor || barColor;\n const barH = rowHeight * (categoryConfig.barHeight || 0.6);\n const barTop = (rowHeight - barH) / 2;\n const borderRadius = categoryConfig.borderRadius ?? 4;\n const renderStyle = categoryConfig.renderStyle || \"bar\";\n const showConnectors = !readOnly && !!onDependencyCreate;\n\n // Connector handles for dependency linking\n const connectorHandles = showConnectors && (\n <>\n <div\n className={`gantt-bar-connector gantt-bar-connector--left ${connDrag?.fromId === node.id ? \"gantt-bar-connector--active\" : \"\"}`}\n onMouseDown={(e) => handleConnectorMouseDown(e, node.id)}\n />\n <div\n className={`gantt-bar-connector gantt-bar-connector--right ${connDrag?.fromId === node.id ? \"gantt-bar-connector--active\" : \"\"}`}\n onMouseDown={(e) => handleConnectorMouseDown(e, node.id)}\n />\n </>\n );\n\n if (renderStyle === \"line\") {\n return (\n <div\n key={node.id}\n className={`gantt-bar gantt-bar--line ${isSelected ? \"gantt-bar--selected\" : \"\"} ${isCurrentlyDragging ? \"gantt-bar--dragging\" : \"\"}`}\n style={{\n left,\n width: adjustedWidth,\n background: barColor,\n top: rowHeight / 2 - 1.5,\n height: 3,\n borderRadius: 1,\n }}\n >\n {connectorHandles}\n </div>\n );\n }\n\n if (node.milestone) {\n return (\n <React.Fragment key={node.id}>\n <div\n className={`gantt-milestone ${isCurrentlyDragging ? \"gantt-bar--dragging\" : \"\"}`}\n style={{\n left: left + adjustedWidth / 2 - 7,\n top: rowHeight / 2 - 7,\n background: barColor,\n transition: isCurrentlyDragging\n ? \"none\"\n : \"left 0.25s cubic-bezier(0.4,0,0.2,1)\",\n }}\n />\n {showConnectors && (\n <div\n style={{\n position: \"absolute\",\n left: left + adjustedWidth / 2 - 7,\n top: rowHeight / 2 - 7,\n width: 14,\n height: 14,\n }}\n >\n <div\n className={`gantt-bar-connector gantt-bar-connector--left ${connDrag?.fromId === node.id ? \"gantt-bar-connector--active\" : \"\"}`}\n style={{ left: -5, top: 2 }}\n onMouseDown={(e) => handleConnectorMouseDown(e, node.id)}\n />\n <div\n className={`gantt-bar-connector gantt-bar-connector--right ${connDrag?.fromId === node.id ? \"gantt-bar-connector--active\" : \"\"}`}\n style={{ right: -5, top: 2 }}\n onMouseDown={(e) => handleConnectorMouseDown(e, node.id)}\n />\n </div>\n )}\n </React.Fragment>\n );\n }\n\n return (\n <div\n key={node.id}\n className={`gantt-bar ${isDraggableBar ? \"gantt-bar--draggable\" : \"\"} ${isCurrentlyDragging ? \"gantt-bar--dragging\" : \"\"} ${isSelected ? \"gantt-bar--selected\" : \"\"}`}\n style={{\n left,\n top: barTop,\n width: adjustedWidth,\n height: barH,\n background: barBg,\n borderRadius,\n }}\n onMouseDown={\n isDraggableBar\n ? (e) => {\n if (\n (e.target as HTMLElement).classList.contains(\n \"gantt-bar-connector\",\n )\n )\n return;\n drag.startDrag(e, node, \"move\", barLeft, barWidth);\n }\n : undefined\n }\n onClick={(e) => {\n e.stopPropagation();\n setSelectedNodeId(node.id);\n onNodeClick?.(node);\n }}\n onContextMenu={(e) => {\n if (onContextMenu) {\n e.preventDefault();\n e.stopPropagation();\n onContextMenu({\n node,\n position: { x: e.clientX, y: e.clientY },\n date: new Date(),\n });\n }\n }}\n >\n {categoryConfig.showProgress && node.progress != null && (\n <div\n className=\"gantt-bar-fill\"\n style={{ width: `${node.progress}%`, background: barColor }}\n />\n )}\n {categoryConfig.renderBar ? (\n categoryConfig.renderBar(node, {\n node,\n width: adjustedWidth,\n height: barH,\n isDragging: isCurrentlyDragging,\n isSelected,\n startDateFormatted: flatNode.resolvedStartDate\n ? formatDate(flatNode.resolvedStartDate)\n : \"\",\n endDateFormatted: flatNode.resolvedEndDate\n ? formatDate(flatNode.resolvedEndDate)\n : \"\",\n durationText: node.workingDays ? `${node.workingDays}d` : \"\",\n })\n ) : (\n <span className=\"gantt-bar-label\">\n {adjustedWidth > 60\n ? node.label\n : node.workingDays\n ? `${node.workingDays}d`\n : \"\"}\n </span>\n )}\n {isResizableBar && (\n <>\n <div\n className=\"gantt-bar-resize-handle gantt-bar-resize-handle--left\"\n onMouseDown={(e) =>\n drag.startDrag(e, node, \"resize-start\", barLeft, barWidth)\n }\n />\n <div\n className=\"gantt-bar-resize-handle gantt-bar-resize-handle--right\"\n onMouseDown={(e) =>\n drag.startDrag(e, node, \"resize-end\", barLeft, barWidth)\n }\n />\n </>\n )}\n {connectorHandles}\n </div>\n );\n };\n\n // ─── Dependency Links SVG ───────────────────────────\n const renderDependencyLinks = () => {\n if (dependencyLinks.length === 0 && !connDrag) return null;\n const displayN = showSearch ? filteredFlatNodes : flatNodes;\n const nodeMap = new Map(displayN.map((fn) => [fn.node.id, fn]));\n const totalH = displayN.length * rowHeight;\n\n return (\n <svg\n className=\"gantt-dependency-svg\"\n style={{ width: totalTimelineWidth, height: totalH }}\n >\n {dependencyLinks.map((link, i) => {\n const from = nodeMap.get(link.fromId);\n const to = nodeMap.get(link.toId);\n if (!from || !to) return null;\n\n const x1 = from.barLeft + from.barWidth;\n const y1 = from.visibleIndex * rowHeight + rowHeight / 2;\n const x2 = to.barLeft;\n const y2 = to.visibleIndex * rowHeight + rowHeight / 2;\n\n const midX = x1 + 12;\n const path = `M${x1},${y1} H${midX} V${y2} H${x2}`;\n const dashClass =\n link.lineStyle === \"dashed\"\n ? \"gantt-dependency-path--dashed\"\n : link.lineStyle === \"dotted\"\n ? \"gantt-dependency-path--dotted\"\n : \"gantt-dependency-path--solid\";\n\n const strokeColor = link.color || undefined;\n const strokeW = link.lineWidth || 1.5;\n const showArr = link.showArrow !== false;\n const showDelete = !readOnly && !!onDependencyDelete;\n\n // Position the delete button at the midpoint of the link\n const delX = midX;\n const delY = (y1 + y2) / 2;\n\n return (\n <g\n key={i}\n className=\"gantt-dependency-group\"\n onClick={() => onDependencyClick?.(link)}\n >\n <path\n className={`gantt-dependency-path ${dashClass}`}\n d={path}\n style={{ stroke: strokeColor, strokeWidth: strokeW }}\n />\n {showArr && (\n <polygon\n className=\"gantt-dependency-arrow\"\n points={`${x2},${y2} ${x2 - 6},${y2 - 4} ${x2 - 6},${y2 + 4}`}\n style={{ fill: strokeColor }}\n />\n )}\n {showDelete && (\n <foreignObject\n x={delX - 8}\n y={delY - 8}\n width={16}\n height={16}\n className=\"gantt-dependency-delete-fo\"\n >\n <button\n className=\"gantt-dependency-delete-btn\"\n onClick={(e) => {\n e.stopPropagation();\n onDependencyDelete(link);\n }}\n title=\"删除连线\"\n >\n ×\n </button>\n </foreignObject>\n )}\n </g>\n );\n })}\n {connDrag &&\n (() => {\n const { startX, startY, curX, curY } = connDrag;\n const dx = curX - startX;\n const cpOffset = Math.min(Math.abs(dx) * 0.5, 60);\n const cp1x = startX + cpOffset;\n const cp2x = curX - cpOffset;\n const d = `M${startX},${startY} C${cp1x},${startY} ${cp2x},${curY} ${curX},${curY}`;\n return <path className=\"gantt-dep-drag-line\" d={d} />;\n })()}\n </svg>\n );\n };\n\n // ─── Today Marker ───────────────────────────────────────────\n const renderTodayMarker = () => {\n if (!todayMarker.visible) return null;\n return (\n <div\n className=\"gantt-today-marker\"\n style={{\n left: todayX,\n ...(todayMarker.color ? { background: todayMarker.color } : {}),\n }}\n />\n );\n };\n\n // ─── Tooltip ────────────────────────────────────────────────\n const [tooltipState, setTooltipState] = useState<{\n node: GanttNode;\n x: number;\n y: number;\n } | null>(null);\n const handleBarMouseEnter = useCallback(\n (e: React.MouseEvent, node: GanttNode) => {\n if (!tooltipConfig.enabled || drag.isDragging) return;\n setTooltipState({ node, x: e.clientX + 12, y: e.clientY + 12 });\n },\n [tooltipConfig.enabled, drag.isDragging],\n );\n const handleBarMouseLeave = useCallback(() => setTooltipState(null), []);\n\n const renderTooltip = () => {\n if (!tooltipState) return null;\n if (tooltipConfig.render)\n return (\n <div\n className=\"gantt-tooltip\"\n style={{ left: tooltipState.x, top: tooltipState.y }}\n >\n {tooltipConfig.render(tooltipState.node)}\n </div>\n );\n const n = tooltipState.node;\n return (\n <div\n className=\"gantt-tooltip\"\n style={{ left: tooltipState.x, top: tooltipState.y }}\n >\n <div className=\"gantt-tooltip-title\">{n.label}</div>\n {n.startDate && (\n <div className=\"gantt-tooltip-row\">\n <span className=\"gantt-tooltip-label\">Start:</span>\n {typeof n.startDate === \"string\"\n ? n.startDate\n : formatDate(n.startDate)}\n </div>\n )}\n {n.endDate && (\n <div className=\"gantt-tooltip-row\">\n <span className=\"gantt-tooltip-label\">End:</span>\n {typeof n.endDate === \"string\" ? n.endDate : formatDate(n.endDate)}\n </div>\n )}\n {n.workingDays != null && (\n <div className=\"gantt-tooltip-row\">\n <span className=\"gantt-tooltip-label\">{labels.workingDays}:</span>\n {n.workingDays}\n </div>\n )}\n {n.assignee && (\n <div className=\"gantt-tooltip-row\">\n <span className=\"gantt-tooltip-label\">Assignee:</span>\n {n.assignee}\n </div>\n )}\n {n.progress != null && (\n <div className=\"gantt-tooltip-row\">\n <span className=\"gantt-tooltip-label\">Progress:</span>\n {n.progress}%\n </div>\n )}\n {n.link && (\n <div className=\"gantt-tooltip-row\">\n <span className=\"gantt-tooltip-label\">Link:</span>\n <span className=\"gantt-tooltip-link\">{n.link}</span>\n </div>\n )}\n </div>\n );\n };\n\n // ─── Main Render ────────────────────────────────────────────\n if (!data || data.length === 0) {\n return (\n <div\n className={`gantt-container ${className || \"\"}`}\n style={{ width, height }}\n >\n {toolbar}\n <div className=\"gantt-empty\">{labels.noData}</div>\n </div>\n );\n }\n\n const displayNodes = showSearch ? filteredFlatNodes : flatNodes;\n const totalRowsHeight = displayNodes.length * rowHeight;\n\n return (\n <div\n className={`gantt-container ${className || \"\"}`}\n style={{ width, height }}\n >\n {toolbar}\n <div className=\"gantt-body\">\n <div className=\"gantt-tree-panel\" style={{ width: treePanelW }}>\n {showSearch && (\n <div className=\"gantt-search\">\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <circle cx=\"11\" cy=\"11\" r=\"8\" />\n <path d=\"m21 21-4.3-4.3\" />\n </svg>\n <input\n className=\"gantt-search-input\"\n placeholder={labels.searchPlaceholder}\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n />\n </div>\n )}\n <div className=\"gantt-tree-header\">\n <div className=\"gantt-tree-header-cell\" style={{ flex: 1 }}>\n {labels.treePanelTitle}\n </div>\n {columns?.map((col) => (\n <div\n key={col.key}\n className=\"gantt-tree-header-cell\"\n style={{\n width: col.width || 80,\n textAlign: col.align || \"left\",\n }}\n >\n {col.title}\n </div>\n ))}\n </div>\n <div\n className=\"gantt-tree-body\"\n ref={treeBodyRef}\n onScroll={() => syncScrollVertical(\"tree\")}\n >\n {displayNodes.map(renderTreeRow)}\n </div>\n </div>\n {treePanelResizable && (\n <div\n className={`gantt-resize-handle ${resizingRef.current ? \"gantt-resize-handle--active\" : \"\"}`}\n onMouseDown={handleResizeStart}\n />\n )}\n <div className=\"gantt-timeline-panel\" ref={timelinePanelRef}>\n {renderTimelineHeader\n ? renderTimelineHeader(dates, scale)\n : renderDefaultTimelineHeader()}\n <div\n className=\"gantt-timeline-body\"\n ref={timelineBodyRef}\n onScroll={() => {\n syncScrollVertical(\"timeline\");\n syncScrollHorizontal();\n }}\n onContextMenu={handleTimelineContextMenu}\n >\n <div\n className=\"gantt-timeline-grid\"\n style={{ width: totalTimelineWidth, height: totalRowsHeight }}\n >\n {renderGridColumns()}\n {renderTodayMarker()}\n </div>\n <div\n className=\"gantt-timeline-rows\"\n style={{ width: totalTimelineWidth, height: totalRowsHeight }}\n >\n {displayNodes.map((fn) => (\n <div\n key={fn.node.id}\n className={`gantt-bar-row ${gridCfg.showRowLines ? \"gantt-bar-row--lined\" : \"\"}`}\n style={{ height: rowHeight }}\n onMouseEnter={(e) => handleBarMouseEnter(e, fn.node)}\n onMouseLeave={handleBarMouseLeave}\n >\n {renderBar(fn)}\n </div>\n ))}\n </div>\n {renderDependencyLinks()}\n </div>\n </div>\n </div>\n {renderTooltip()}\n {/* Edit Dialog */}\n {editDialogOpen && editDialogNode && (\n <div className=\"gantt-edit-dialog-overlay\" onClick={cancelEdit}>\n <div\n className=\"gantt-edit-dialog\"\n onClick={(e) => e.stopPropagation()}\n >\n <div className=\"gantt-edit-dialog__header\">\n <span className=\"gantt-edit-dialog__title\">{labels.edit}</span>\n <button\n type=\"button\"\n className=\"gantt-edit-dialog__close\"\n onClick={cancelEdit}\n >\n \\u00D7\n </button>\n </div>\n <div className=\"gantt-edit-dialog__body\">\n <input\n ref={editInputRef}\n className=\"gantt-edit-dialog__input\"\n value={editingLabel}\n onChange={(e) => setEditingLabel(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") commitEdit();\n if (e.key === \"Escape\") cancelEdit();\n }}\n autoFocus\n />\n </div>\n <div className=\"gantt-edit-dialog__footer\">\n <button\n type=\"button\"\n className=\"gantt-edit-dialog__btn gantt-edit-dialog__btn--cancel\"\n onClick={cancelEdit}\n >\n Cancel\n </button>\n <button\n type=\"button\"\n className=\"gantt-edit-dialog__btn gantt-edit-dialog__btn--submit\"\n onClick={commitEdit}\n disabled={!editingLabel.trim()}\n >\n OK\n </button>\n </div>\n </div>\n </div>\n )}\n </div>\n );\n});\n\nexport default Gantt;\n"],"mappings":"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"}
1
+ {"version":3,"file":"Gantt.js","names":["_Fragment","React","isHolidayOnly","holidays","date","dateStr","entry","DEFAULT_GRID","DEFAULT_LABELS","Gantt","forwardRef","initialTreeWidth","tooltipConfig","userLabels","userGrid","props","labels","useMemo","gridCfg","useGanttState","drag","useGanttDrag","currentScaleConfig","dateRange","readOnly","onBarChange","treePanelW","setTreePanelW","useState","resizingRef","useRef","resizeStartRef","handleResizeStart","useCallback","treePanelResizable","hm","treePanelMinWidth","treePanelMaxWidth","ev","hu","searchQuery","setSearchQuery","filteredFlatNodes","flatNodes","q","fn","editingLabel","setEditingLabel","editDialogOpen","setEditDialogOpen","editDialogNode","setEditDialogNode","editInputRef","startEditing","onNodeLabelEdit","node","commitEdit","trimmed","cancelEdit","connDrag","setConnDrag","connDragRef","timelinePanelRef","handleConnectorMouseDown","onDependencyCreate","body","timelineBodyRef","rect","showSearch","f","nodeId","x","y","rowHeight","useEffect","curX","e","curY","prev","cur","rowIdx","dn","todayMarker","t","scrollToToday","useImperativeHandle","ref","handleRowClick","setSelectedNodeId","onNodeClick","flat","targetX","handleTimelineContextMenu","onContextMenu","findParent","n","nodes","targetId","parent","defaultToolbar","scales","s","scale","setScale","DEFAULT_SCALE_CONFIGS","expandAll","collapseAll","toolbar","renderToolbar","renderTreeRow","flatNode","isSelected","selectedNodeId","renderTreeNode","onNodeDoubleClick","depth","expanded","toggleNode","hasChildren","onNodeLinkClick","columns","col","onNodeAdd","onNodeAddChild","onNodeDelete","data","renderDefaultTimelineHeader","timelineHeaderRef","totalTimelineWidth","headerGroups","group","i","dates","isToday2","isSameDay","today","isWknd","isNonWorkingDay","baseCls","h","renderGridColumns","slots","cellW","elements","isHol","isWeekend","showBorder","globalIdx","dayIdx","classes","highlightNonWorkingDays","style","renderBar","isRenderable","barWidth","isDraggableBar","categoryConfig","draggable","isResizableBar","resizable","isCurrentlyDragging","adjustedWidth","barLeft","barColor","barBg","barH","barTop","borderRadius","renderStyle","showConnectors","connectorHandles","Fragment","left","formatDate","renderDependencyLinks","dependencyLinks","displayN","nodeMap","totalH","from","link","to","x1","y1","x2","y2","midX","path","dashClass","strokeColor","strokeW","showArr","showDelete","onDependencyDelete","delX","delY","onDependencyClick","dx","startX","cpOffset","d","startY","renderTodayMarker","todayX","tooltipState","setTooltipState","handleBarMouseEnter","handleBarMouseLeave","renderTooltip","className","displayNodes","totalRowsHeight","treeBodyRef","syncScrollVertical","renderTimelineHeader","syncScrollHorizontal"],"sources":["../../../../src/components/pro/Gantt/Gantt.tsx"],"sourcesContent":["/**\n * DishUI Gantt Chart Component\n */\n\nimport React, {\n forwardRef,\n useImperativeHandle,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type {\n GanttProps,\n GanttHandle,\n GanttNode,\n GanttNodeId,\n GanttScaleLevel,\n FlatGanttNode,\n GanttDependencyLink,\n GanttGridConfig,\n} from \"./types\";\nimport { useGanttState } from \"./hooks/useGanttState\";\nimport { useGanttDrag } from \"./hooks/useGanttDrag\";\nimport {\n isNonWorkingDay,\n isWeekend,\n isSameDay,\n formatDate,\n DEFAULT_SCALE_CONFIGS,\n} from \"./utils\";\nimport \"./styles.css\";\n\n// ─── Helpers ──────────────────────────────────────────────────────\n\n/**\n * Check if a date is a declared holiday entry.\n * Returns true for any date that has an explicit non-working holiday entry,\n * INCLUDING weekends that happen to fall within a holiday period (e.g. Spring Festival).\n * 调休 (compensatory workday entries with isWorkday=true) are NOT holidays.\n */\nfunction isHolidayOnly(date: Date, holidays?: GanttProps[\"holidays\"]): boolean {\n if (!holidays) return false;\n if (holidays.isNonWorkingDay) {\n return holidays.isNonWorkingDay(date);\n }\n const dateStr = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, \"0\")}-${String(date.getDate()).padStart(2, \"0\")}`;\n const entry = holidays.entries?.find((e) => e.date === dateStr);\n if (!entry) return false;\n // 调休 (compensatory workday) is NOT a holiday\n if (entry.isWorkday) return false;\n return true;\n}\n\nconst DEFAULT_GRID: Required<GanttGridConfig> = {\n showCellBorders: true,\n cellBorderColor: \"\",\n weekendColor: \"\",\n holidayColor: \"#fff0f3\",\n todayColor: \"\",\n showRowLines: false,\n};\n\nconst DEFAULT_LABELS = {\n treePanelTitle: \"Tasks\",\n searchPlaceholder: \"Search...\",\n expandAll: \"Expand All\",\n collapseAll: \"Collapse All\",\n today: \"Today\",\n zoomIn: \"Zoom In\",\n zoomOut: \"Zoom Out\",\n noData: \"No data\",\n workingDays: \"Working days\",\n calendarDays: \"Calendar days\",\n weekDays: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"] as [\n string,\n string,\n string,\n string,\n string,\n string,\n string,\n ],\n monthNames: [\n \"Jan\",\n \"Feb\",\n \"Mar\",\n \"Apr\",\n \"May\",\n \"Jun\",\n \"Jul\",\n \"Aug\",\n \"Sep\",\n \"Oct\",\n \"Nov\",\n \"Dec\",\n ] as [\n string,\n string,\n string,\n string,\n string,\n string,\n string,\n string,\n string,\n string,\n string,\n string,\n ],\n add: \"Add\",\n delete: \"Delete\",\n edit: \"Edit\",\n link: \"Open link\",\n};\n\n// ─── Main Component ───────────────────────────────────────────────\n\nconst Gantt = forwardRef<GanttHandle, GanttProps>(function Gantt(props, ref) {\n const {\n data,\n categories = {},\n holidays,\n timeWindow,\n columns,\n defaultScale = \"day\",\n availableScales,\n scaleConfigs,\n treePanelWidth: initialTreeWidth = 300,\n treePanelMinWidth = 200,\n treePanelMaxWidth = 600,\n treePanelResizable = true,\n rowHeight = 36,\n draggable = false,\n resizable = false,\n readOnly = false,\n defaultExpandedIds,\n defaultExpandAll = true,\n todayMarker = { visible: true, autoScroll: true },\n tooltip: tooltipConfig = { enabled: true },\n labels: userLabels,\n showSearch = false,\n highlightNonWorkingDays = true,\n grid: userGrid,\n dependencyLinks = [],\n className,\n width = \"100%\",\n height = \"100%\",\n onBarChange,\n onNodeClick,\n onNodeDoubleClick,\n onContextMenu,\n onNodeToggle,\n onViewChange,\n onScaleChange,\n onNodeLabelEdit,\n onNodeAdd,\n onNodeAddChild,\n onNodeDelete,\n onNodeLinkClick,\n onDependencyCreate,\n onDependencyClick,\n onDependencyDelete,\n renderTreeNode,\n renderToolbar,\n renderTimelineHeader,\n } = props;\n\n const labels = useMemo(\n () => ({ ...DEFAULT_LABELS, ...userLabels }),\n [userLabels],\n );\n const gridCfg = useMemo(() => ({ ...DEFAULT_GRID, ...userGrid }), [userGrid]);\n\n // ─── Core state ─────────────────────────────────────────────\n const state = useGanttState({\n data,\n defaultScale,\n defaultExpandedIds,\n defaultExpandAll,\n scaleConfigs,\n categories,\n holidays,\n timeWindow,\n availableScales,\n onScaleChange,\n onNodeToggle,\n onViewChange,\n });\n const {\n scale,\n setScale,\n scales,\n currentScaleConfig,\n flatNodes,\n dates,\n headerGroups,\n dateRange,\n today,\n todayX,\n totalTimelineWidth,\n selectedNodeId,\n setSelectedNodeId,\n toggleNode,\n expandAll,\n collapseAll,\n scrollToDate,\n scrollToToday,\n scrollToNode,\n treeBodyRef,\n timelineBodyRef,\n timelineHeaderRef,\n syncScrollVertical,\n syncScrollHorizontal,\n } = state;\n\n const drag = useGanttDrag({\n scaleConfig: currentScaleConfig,\n timelineStart: dateRange.start,\n onBarChange: readOnly ? undefined : onBarChange,\n calendar: holidays,\n });\n\n // ─── Tree panel resize ──────────────────────────────────────\n const [treePanelW, setTreePanelW] = useState(initialTreeWidth);\n const resizingRef = useRef(false);\n const resizeStartRef = useRef({ x: 0, width: 0 });\n const handleResizeStart = useCallback(\n (e: React.MouseEvent) => {\n if (!treePanelResizable) return;\n e.preventDefault();\n resizingRef.current = true;\n resizeStartRef.current = { x: e.clientX, width: treePanelW };\n const hm = (ev: MouseEvent) => {\n if (!resizingRef.current) return;\n setTreePanelW(\n Math.max(\n treePanelMinWidth,\n Math.min(\n treePanelMaxWidth,\n resizeStartRef.current.width +\n ev.clientX -\n resizeStartRef.current.x,\n ),\n ),\n );\n };\n const hu = () => {\n resizingRef.current = false;\n window.removeEventListener(\"mousemove\", hm);\n window.removeEventListener(\"mouseup\", hu);\n };\n window.addEventListener(\"mousemove\", hm);\n window.addEventListener(\"mouseup\", hu);\n },\n [treePanelResizable, treePanelW, treePanelMinWidth, treePanelMaxWidth],\n );\n\n // ─── Search ─────────────────────────────────────────────────\n const [searchQuery, setSearchQuery] = useState(\"\");\n const filteredFlatNodes = useMemo(() => {\n if (!searchQuery.trim()) return flatNodes;\n const q = searchQuery.toLowerCase();\n return flatNodes.filter((fn) => fn.node.label.toLowerCase().includes(q));\n }, [flatNodes, searchQuery]);\n\n // ─── Edit dialog ─────────────────────────────────────────\n const [editingLabel, setEditingLabel] = useState(\"\");\n const [editDialogOpen, setEditDialogOpen] = useState(false);\n const [editDialogNode, setEditDialogNode] = useState<GanttNode | null>(null);\n const editInputRef = useRef<HTMLInputElement>(null);\n const startEditing = useCallback(\n (node: GanttNode) => {\n if (readOnly || !onNodeLabelEdit) return;\n setEditDialogNode(node);\n setEditingLabel(node.label);\n setEditDialogOpen(true);\n },\n [readOnly, onNodeLabelEdit],\n );\n const commitEdit = useCallback(() => {\n if (!editDialogNode) return;\n const trimmed = editingLabel.trim();\n if (trimmed && onNodeLabelEdit && trimmed !== editDialogNode.label) {\n onNodeLabelEdit(editDialogNode, trimmed);\n }\n setEditDialogOpen(false);\n setEditDialogNode(null);\n setEditingLabel(\"\");\n }, [editDialogNode, editingLabel, onNodeLabelEdit]);\n const cancelEdit = useCallback(() => {\n setEditDialogOpen(false);\n setEditDialogNode(null);\n setEditingLabel(\"\");\n }, []);\n\n // ─── Dependency connector drag ──────────────────────────────\n const [connDrag, setConnDrag] = useState<{\n fromId: GanttNodeId;\n startX: number;\n startY: number;\n curX: number;\n curY: number;\n } | null>(null);\n const connDragRef = useRef(connDrag);\n connDragRef.current = connDrag;\n const timelinePanelRef = useRef<HTMLDivElement>(null);\n\n const handleConnectorMouseDown = useCallback(\n (e: React.MouseEvent, nodeId: GanttNodeId) => {\n if (readOnly || !onDependencyCreate) return;\n e.preventDefault();\n e.stopPropagation();\n const body = timelineBodyRef.current;\n if (!body) return;\n const rect = body.getBoundingClientRect();\n // Snap start point to the bar's connector edge rather than exact mouse position\n const displayN = showSearch ? filteredFlatNodes : flatNodes;\n const fn = displayN.find((f) => f.node.id === nodeId);\n let x: number;\n let y: number;\n if (fn) {\n // Determine if clicked on left or right connector\n const mouseX = e.clientX - rect.left + body.scrollLeft;\n const barCenter = fn.barLeft + fn.barWidth / 2;\n if (mouseX < barCenter) {\n x = fn.barLeft; // left edge\n } else {\n x = fn.barLeft + fn.barWidth; // right edge\n }\n y = fn.visibleIndex * rowHeight + rowHeight / 2;\n } else {\n x = e.clientX - rect.left + body.scrollLeft;\n y = e.clientY - rect.top + body.scrollTop;\n }\n setConnDrag({ fromId: nodeId, startX: x, startY: y, curX: x, curY: y });\n },\n [\n readOnly,\n onDependencyCreate,\n timelineBodyRef,\n flatNodes,\n filteredFlatNodes,\n showSearch,\n rowHeight,\n ],\n );\n\n useEffect(() => {\n if (!connDrag) return;\n const body = timelineBodyRef.current;\n if (!body) return;\n\n const hm = (e: MouseEvent) => {\n const rect = body.getBoundingClientRect();\n const curX = e.clientX - rect.left + body.scrollLeft;\n const curY = e.clientY - rect.top + body.scrollTop;\n setConnDrag((prev) => (prev ? { ...prev, curX, curY } : null));\n };\n const hu = (e: MouseEvent) => {\n const cur = connDragRef.current;\n if (cur && onDependencyCreate) {\n const rect = body.getBoundingClientRect();\n const y = e.clientY - rect.top + body.scrollTop;\n const rowIdx = Math.floor(y / rowHeight);\n const displayN = showSearch ? filteredFlatNodes : flatNodes;\n const dn = displayN[rowIdx];\n if (dn && dn.node.id !== cur.fromId) {\n onDependencyCreate(cur.fromId, dn.node.id);\n }\n }\n setConnDrag(null);\n };\n window.addEventListener(\"mousemove\", hm);\n window.addEventListener(\"mouseup\", hu);\n return () => {\n window.removeEventListener(\"mousemove\", hm);\n window.removeEventListener(\"mouseup\", hu);\n };\n // Only re-attach listeners when drag starts (fromId changes), not on every cursor move\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [connDrag?.fromId]);\n\n // ─── Auto-scroll ────────────────────────────────────────────\n useEffect(() => {\n if (todayMarker.autoScroll !== false) {\n const t = setTimeout(scrollToToday, 100);\n return () => clearTimeout(t);\n }\n }, []); // eslint-disable-line react-hooks/exhaustive-deps\n\n useImperativeHandle(ref, () => ({\n scrollToDate,\n scrollToToday,\n scrollToNode,\n getVisibleRange: () => ({ start: dateRange.start, end: dateRange.end }),\n setScale,\n expandAll,\n collapseAll,\n toggleNode,\n }));\n\n // ─── Row click → smooth scroll to data start ───────────────\n const handleRowClick = useCallback(\n (node: GanttNode) => {\n setSelectedNodeId(node.id);\n onNodeClick?.(node);\n const flat = flatNodes.find((fn) => fn.node.id === node.id);\n if (flat?.resolvedStartDate && timelineBodyRef.current) {\n const targetX = flat.barLeft - timelineBodyRef.current.clientWidth / 3;\n timelineBodyRef.current.scrollTo({\n left: Math.max(0, targetX),\n behavior: \"smooth\",\n });\n }\n },\n [flatNodes, setSelectedNodeId, onNodeClick, timelineBodyRef],\n );\n\n // ─── Context menu ───────────────────────────────────────────\n const handleTimelineContextMenu = useCallback(\n (e: React.MouseEvent) => {\n if (!onContextMenu) return;\n e.preventDefault();\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect();\n const x =\n e.clientX - rect.left + (timelineBodyRef.current?.scrollLeft || 0);\n const date = new Date(dateRange.start);\n date.setDate(\n date.getDate() +\n Math.floor(\n x / (currentScaleConfig.cellWidth * currentScaleConfig.slotsPerDay),\n ),\n );\n onContextMenu({\n node: null,\n position: { x: e.clientX, y: e.clientY },\n date,\n });\n },\n [onContextMenu, dateRange, currentScaleConfig, timelineBodyRef],\n );\n\n const findParent = useCallback(\n (\n targetId: GanttNodeId,\n nodes: GanttNode[],\n parent: GanttNode | null,\n ): GanttNode | null => {\n for (const n of nodes) {\n if (n.id === targetId) return parent;\n if (n.children) {\n const f = findParent(targetId, n.children, n);\n if (f !== undefined) return f;\n }\n }\n return null;\n },\n [],\n );\n\n // ─── Toolbar ────────────────────────────────────────────────\n const defaultToolbar = (\n <div className=\"gantt-toolbar\">\n <div className=\"gantt-toolbar-group\">\n {scales.map((s) => (\n <button\n key={s}\n className={`gantt-scale-btn ${s === scale ? \"gantt-scale-btn--active\" : \"\"}`}\n onClick={() => setScale(s)}\n title={DEFAULT_SCALE_CONFIGS[s].label}\n >\n {DEFAULT_SCALE_CONFIGS[s].label}\n </button>\n ))}\n </div>\n <div className=\"gantt-toolbar-divider\" />\n <button\n className=\"gantt-icon-btn\"\n onClick={scrollToToday}\n title={labels.today}\n >\n ◉\n </button>\n <button\n className=\"gantt-icon-btn\"\n onClick={expandAll}\n title={labels.expandAll}\n >\n ⊞\n </button>\n <button\n className=\"gantt-icon-btn\"\n onClick={collapseAll}\n title={labels.collapseAll}\n >\n ⊟\n </button>\n <div className=\"gantt-toolbar-spacer\" />\n <span style={{ fontSize: 11, color: \"oklch(var(--bc) / 0.4)\" }}>\n {flatNodes.length} items\n </span>\n </div>\n );\n const toolbar = renderToolbar\n ? renderToolbar(defaultToolbar)\n : defaultToolbar;\n\n // ─── Tree Row ───────────────────────────────────────────────\n const renderTreeRow = (flatNode: FlatGanttNode) => {\n const { node, depth, expanded, hasChildren } = flatNode;\n const isSelected = selectedNodeId === node.id;\n\n if (renderTreeNode) {\n return (\n <div\n key={node.id}\n className={`gantt-tree-row ${isSelected ? \"gantt-tree-row--selected\" : \"\"}`}\n style={{ height: rowHeight }}\n onClick={() => handleRowClick(node)}\n onDoubleClick={() => {\n onNodeDoubleClick?.(node);\n startEditing(node);\n }}\n >\n {renderTreeNode(node, depth, expanded, () => toggleNode(node.id))}\n </div>\n );\n }\n\n return (\n <div\n key={node.id}\n className={`gantt-tree-row ${isSelected ? \"gantt-tree-row--selected\" : \"\"}`}\n style={{ height: rowHeight }}\n onClick={() => handleRowClick(node)}\n onDoubleClick={() => {\n onNodeDoubleClick?.(node);\n startEditing(node);\n }}\n >\n <div className=\"gantt-tree-indent\" style={{ width: depth * 20 }} />\n <div\n className={`gantt-tree-toggle ${hasChildren ? (expanded ? \"gantt-tree-toggle--expanded\" : \"\") : \"gantt-tree-toggle--placeholder\"}`}\n onClick={(e) => {\n e.stopPropagation();\n if (hasChildren) toggleNode(node.id);\n }}\n >\n {hasChildren && \"\\u25B6\"}\n </div>\n <div className=\"gantt-tree-label\" title={node.label}>\n {node.label}\n </div>\n {node.link && (\n <button\n className=\"gantt-tree-action-btn\"\n title={labels.link}\n onClick={(e) => {\n e.stopPropagation();\n if (onNodeLinkClick) {\n onNodeLinkClick(node, node.link!);\n } else {\n window.open(node.link!, \"_blank\");\n }\n }}\n >\n <svg\n width=\"12\"\n height=\"12\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <path d=\"M10 13a5 5 0 007.54.54l3-3a5 5 0 00-7.07-7.07l-1.72 1.71\" />\n <path d=\"M14 11a5 5 0 00-7.54-.54l-3 3a5 5 0 007.07 7.07l1.71-1.71\" />\n </svg>\n </button>\n )}\n {columns?.map((col) => (\n <div\n key={col.key}\n className=\"gantt-tree-cell\"\n style={{ width: col.width || 80, textAlign: col.align || \"left\" }}\n >\n {col.render ? col.render(node, col) : (node.meta?.[col.key] ?? \"\")}\n </div>\n ))}\n {!readOnly && (onNodeAdd || onNodeAddChild || onNodeDelete) && (\n <div className=\"gantt-tree-actions gantt-tree-actions--pinned\">\n {onNodeAdd && (\n <button\n className=\"gantt-tree-action-btn\"\n title={labels.add}\n onClick={(e) => {\n e.stopPropagation();\n onNodeAdd(findParent(node.id, data, null), node);\n }}\n >\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" />\n <line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" />\n </svg>\n </button>\n )}\n {onNodeAddChild && (\n <button\n className=\"gantt-tree-action-btn\"\n title=\"Add child\"\n onClick={(e) => {\n e.stopPropagation();\n onNodeAddChild(node);\n }}\n >\n {\"\\u229E\"}\n </button>\n )}\n {onNodeDelete && (\n <button\n className=\"gantt-tree-action-btn gantt-tree-action-btn--danger\"\n title={labels.delete}\n onClick={(e) => {\n e.stopPropagation();\n onNodeDelete(node);\n }}\n >\n {\"\\u00D7\"}\n </button>\n )}\n </div>\n )}\n </div>\n );\n };\n\n // ─── Timeline Header ───────────────────────────────────────\n const renderDefaultTimelineHeader = () => (\n <div className=\"gantt-timeline-header\" ref={timelineHeaderRef}>\n <div\n className=\"gantt-timeline-header-row\"\n style={{ width: totalTimelineWidth }}\n >\n {headerGroups.map((group, i) => (\n <div\n key={i}\n className=\"gantt-timeline-header-group\"\n style={{\n width:\n group.span *\n currentScaleConfig.cellWidth *\n currentScaleConfig.slotsPerDay,\n }}\n >\n {group.label}\n </div>\n ))}\n </div>\n <div\n className=\"gantt-timeline-header-row\"\n style={{ width: totalTimelineWidth }}\n >\n {scale === \"halfday\"\n ? dates.map((date, i) => {\n const isToday2 = isSameDay(date, today);\n const isWknd = isNonWorkingDay(date, holidays);\n const baseCls = `gantt-timeline-header-cell ${isToday2 ? \"gantt-timeline-header-cell--today\" : \"\"} ${isWknd ? \"gantt-timeline-header-cell--weekend\" : \"\"}`;\n return (\n <React.Fragment key={i}>\n <div\n className={baseCls}\n style={{ width: currentScaleConfig.cellWidth }}\n >\n 上午\n </div>\n <div\n className={baseCls}\n style={{ width: currentScaleConfig.cellWidth }}\n >\n 下午\n </div>\n </React.Fragment>\n );\n })\n : scale === \"hour\"\n ? dates.map((date, i) => {\n const isToday2 = isSameDay(date, today);\n const isWknd = isNonWorkingDay(date, holidays);\n const baseCls = `gantt-timeline-header-cell ${isToday2 ? \"gantt-timeline-header-cell--today\" : \"\"} ${isWknd ? \"gantt-timeline-header-cell--weekend\" : \"\"}`;\n return (\n <React.Fragment key={i}>\n {Array.from({ length: 24 }, (_, h) => (\n <div\n key={h}\n className={baseCls}\n style={{ width: currentScaleConfig.cellWidth }}\n >\n {h}\n </div>\n ))}\n </React.Fragment>\n );\n })\n : dates.map((date, i) => {\n const isToday2 = isSameDay(date, today);\n const isWknd = isNonWorkingDay(date, holidays);\n const cls = `gantt-timeline-header-cell ${isToday2 ? \"gantt-timeline-header-cell--today\" : \"\"} ${isWknd ? \"gantt-timeline-header-cell--weekend\" : \"\"}`;\n return (\n <div\n key={i}\n className={cls}\n style={{\n width:\n currentScaleConfig.cellWidth *\n currentScaleConfig.slotsPerDay,\n }}\n >\n {date.getDate()}\n </div>\n );\n })}\n </div>\n </div>\n );\n\n // ─── Grid Columns ──────────────────────────────────────────\n const renderGridColumns = () => {\n if (scale === \"halfday\" || scale === \"hour\") {\n // Render individual sub-cells for halfday/hour\n const slots = currentScaleConfig.slotsPerDay;\n const cellW = currentScaleConfig.cellWidth;\n const elements: React.ReactNode[] = [];\n dates.forEach((date, dayIdx) => {\n const isToday2 = isSameDay(date, today);\n const isHol = isHolidayOnly(date, holidays);\n const isWknd = isWeekend(date) && holidays?.weekendsOff !== false;\n const showBorder = gridCfg.showCellBorders;\n\n for (let s = 0; s < slots; s++) {\n const globalIdx = dayIdx * slots + s;\n const classes = [\"gantt-timeline-col\"];\n if (showBorder) classes.push(\"gantt-timeline-col--border\");\n if (highlightNonWorkingDays && isWknd)\n classes.push(\"gantt-timeline-col--weekend\");\n if (highlightNonWorkingDays && isHol)\n classes.push(\"gantt-timeline-col--holiday\");\n if (isToday2) classes.push(\"gantt-timeline-col--today\");\n\n const style: React.CSSProperties = {\n left: globalIdx * cellW,\n width: cellW,\n };\n if (gridCfg.cellBorderColor && showBorder)\n style.borderRightColor = gridCfg.cellBorderColor;\n if (isWknd && gridCfg.weekendColor)\n style.background = gridCfg.weekendColor;\n if (isHol && gridCfg.holidayColor)\n style.background = gridCfg.holidayColor;\n if (isToday2 && gridCfg.todayColor)\n style.background = gridCfg.todayColor;\n\n elements.push(\n <div\n key={`${dayIdx}-${s}`}\n className={classes.join(\" \")}\n style={style}\n />,\n );\n }\n });\n return elements;\n }\n\n return dates.map((date, i) => {\n const isToday2 = isSameDay(date, today);\n const isHol = isHolidayOnly(date, holidays);\n const isWknd = isWeekend(date) && holidays?.weekendsOff !== false;\n const showBorder = gridCfg.showCellBorders;\n\n const classes = [\"gantt-timeline-col\"];\n if (showBorder) classes.push(\"gantt-timeline-col--border\");\n if (highlightNonWorkingDays && isWknd)\n classes.push(\"gantt-timeline-col--weekend\");\n if (highlightNonWorkingDays && isHol)\n classes.push(\"gantt-timeline-col--holiday\");\n if (isToday2) classes.push(\"gantt-timeline-col--today\");\n\n // Custom inline colors from gridCfg\n const style: React.CSSProperties = {\n left: i * currentScaleConfig.cellWidth * currentScaleConfig.slotsPerDay,\n width: currentScaleConfig.cellWidth * currentScaleConfig.slotsPerDay,\n };\n if (gridCfg.cellBorderColor && showBorder)\n style.borderRightColor = gridCfg.cellBorderColor;\n if (isWknd && gridCfg.weekendColor)\n style.background = gridCfg.weekendColor;\n if (isHol && gridCfg.holidayColor)\n style.background = gridCfg.holidayColor;\n if (isToday2 && gridCfg.todayColor) style.background = gridCfg.todayColor;\n\n return <div key={i} className={classes.join(\" \")} style={style} />;\n });\n };\n\n // ─── Bar ────────────────────────────────────────────────────\n const renderBar = (flatNode: FlatGanttNode) => {\n const { node, barLeft, barWidth, isRenderable, categoryConfig } = flatNode;\n if (!isRenderable || barWidth <= 0) return null;\n\n const isDraggableBar = !readOnly && (categoryConfig.draggable ?? draggable);\n const isResizableBar = !readOnly && (categoryConfig.resizable ?? resizable);\n const isCurrentlyDragging = drag.draggingNodeId === node.id;\n const isSelected = selectedNodeId === node.id;\n const { left, width: adjustedWidth } = drag.getAdjustedBar(\n node.id,\n barLeft,\n barWidth,\n );\n\n // Per-node color > category color > default\n const barColor = node.barColor || categoryConfig.color || \"#3b82f6\";\n const barBg = node.barColor || categoryConfig.backgroundColor || barColor;\n const barH = rowHeight * (categoryConfig.barHeight || 0.6);\n const barTop = (rowHeight - barH) / 2;\n const borderRadius = categoryConfig.borderRadius ?? 4;\n const renderStyle = categoryConfig.renderStyle || \"bar\";\n const showConnectors = !readOnly && !!onDependencyCreate;\n\n // Connector handles for dependency linking\n const connectorHandles = showConnectors && (\n <>\n <div\n className={`gantt-bar-connector gantt-bar-connector--left ${connDrag?.fromId === node.id ? \"gantt-bar-connector--active\" : \"\"}`}\n onMouseDown={(e) => handleConnectorMouseDown(e, node.id)}\n />\n <div\n className={`gantt-bar-connector gantt-bar-connector--right ${connDrag?.fromId === node.id ? \"gantt-bar-connector--active\" : \"\"}`}\n onMouseDown={(e) => handleConnectorMouseDown(e, node.id)}\n />\n </>\n );\n\n if (renderStyle === \"line\") {\n return (\n <div\n key={node.id}\n className={`gantt-bar gantt-bar--line ${isSelected ? \"gantt-bar--selected\" : \"\"} ${isCurrentlyDragging ? \"gantt-bar--dragging\" : \"\"}`}\n style={{\n left,\n width: adjustedWidth,\n background: barColor,\n top: rowHeight / 2 - 1.5,\n height: 3,\n borderRadius: 1,\n }}\n >\n {connectorHandles}\n </div>\n );\n }\n\n if (node.milestone) {\n return (\n <React.Fragment key={node.id}>\n <div\n className={`gantt-milestone ${isCurrentlyDragging ? \"gantt-bar--dragging\" : \"\"}`}\n style={{\n left: left + adjustedWidth / 2 - 7,\n top: rowHeight / 2 - 7,\n background: barColor,\n transition: isCurrentlyDragging\n ? \"none\"\n : \"left 0.25s cubic-bezier(0.4,0,0.2,1)\",\n }}\n />\n {showConnectors && (\n <div\n style={{\n position: \"absolute\",\n left: left + adjustedWidth / 2 - 7,\n top: rowHeight / 2 - 7,\n width: 14,\n height: 14,\n }}\n >\n <div\n className={`gantt-bar-connector gantt-bar-connector--left ${connDrag?.fromId === node.id ? \"gantt-bar-connector--active\" : \"\"}`}\n style={{ left: -5, top: 2 }}\n onMouseDown={(e) => handleConnectorMouseDown(e, node.id)}\n />\n <div\n className={`gantt-bar-connector gantt-bar-connector--right ${connDrag?.fromId === node.id ? \"gantt-bar-connector--active\" : \"\"}`}\n style={{ right: -5, top: 2 }}\n onMouseDown={(e) => handleConnectorMouseDown(e, node.id)}\n />\n </div>\n )}\n </React.Fragment>\n );\n }\n\n return (\n <div\n key={node.id}\n className={`gantt-bar ${isDraggableBar ? \"gantt-bar--draggable\" : \"\"} ${isCurrentlyDragging ? \"gantt-bar--dragging\" : \"\"} ${isSelected ? \"gantt-bar--selected\" : \"\"}`}\n style={{\n left,\n top: barTop,\n width: adjustedWidth,\n height: barH,\n background: barBg,\n borderRadius,\n }}\n onMouseDown={\n isDraggableBar\n ? (e) => {\n if (\n (e.target as HTMLElement).classList.contains(\n \"gantt-bar-connector\",\n )\n )\n return;\n drag.startDrag(e, node, \"move\", barLeft, barWidth);\n }\n : undefined\n }\n onClick={(e) => {\n e.stopPropagation();\n setSelectedNodeId(node.id);\n onNodeClick?.(node);\n }}\n onContextMenu={(e) => {\n if (onContextMenu) {\n e.preventDefault();\n e.stopPropagation();\n onContextMenu({\n node,\n position: { x: e.clientX, y: e.clientY },\n date: new Date(),\n });\n }\n }}\n >\n {categoryConfig.showProgress && node.progress != null && (\n <div\n className=\"gantt-bar-fill\"\n style={{ width: `${node.progress}%`, background: barColor }}\n />\n )}\n {categoryConfig.renderBar ? (\n categoryConfig.renderBar(node, {\n node,\n width: adjustedWidth,\n height: barH,\n isDragging: isCurrentlyDragging,\n isSelected,\n startDateFormatted: flatNode.resolvedStartDate\n ? formatDate(flatNode.resolvedStartDate)\n : \"\",\n endDateFormatted: flatNode.resolvedEndDate\n ? formatDate(flatNode.resolvedEndDate)\n : \"\",\n durationText: node.workingDays ? `${node.workingDays}d` : \"\",\n })\n ) : (\n <span className=\"gantt-bar-label\">\n {adjustedWidth > 60\n ? node.label\n : node.workingDays\n ? `${node.workingDays}d`\n : \"\"}\n </span>\n )}\n {isResizableBar && (\n <>\n <div\n className=\"gantt-bar-resize-handle gantt-bar-resize-handle--left\"\n onMouseDown={(e) =>\n drag.startDrag(e, node, \"resize-start\", barLeft, barWidth)\n }\n />\n <div\n className=\"gantt-bar-resize-handle gantt-bar-resize-handle--right\"\n onMouseDown={(e) =>\n drag.startDrag(e, node, \"resize-end\", barLeft, barWidth)\n }\n />\n </>\n )}\n {connectorHandles}\n </div>\n );\n };\n\n // ─── Dependency Links SVG ───────────────────────────\n const renderDependencyLinks = () => {\n if (dependencyLinks.length === 0 && !connDrag) return null;\n const displayN = showSearch ? filteredFlatNodes : flatNodes;\n const nodeMap = new Map(displayN.map((fn) => [fn.node.id, fn]));\n const totalH = displayN.length * rowHeight;\n\n return (\n <svg\n className=\"gantt-dependency-svg\"\n style={{ width: totalTimelineWidth, height: totalH }}\n >\n {dependencyLinks.map((link, i) => {\n const from = nodeMap.get(link.fromId);\n const to = nodeMap.get(link.toId);\n if (!from || !to) return null;\n\n const x1 = from.barLeft + from.barWidth;\n const y1 = from.visibleIndex * rowHeight + rowHeight / 2;\n const x2 = to.barLeft;\n const y2 = to.visibleIndex * rowHeight + rowHeight / 2;\n\n const midX = x1 + 12;\n const path = `M${x1},${y1} H${midX} V${y2} H${x2}`;\n const dashClass =\n link.lineStyle === \"dashed\"\n ? \"gantt-dependency-path--dashed\"\n : link.lineStyle === \"dotted\"\n ? \"gantt-dependency-path--dotted\"\n : \"gantt-dependency-path--solid\";\n\n const strokeColor = link.color || undefined;\n const strokeW = link.lineWidth || 1.5;\n const showArr = link.showArrow !== false;\n const showDelete = !readOnly && !!onDependencyDelete;\n\n // Position the delete button at the midpoint of the link\n const delX = midX;\n const delY = (y1 + y2) / 2;\n\n return (\n <g\n key={i}\n className=\"gantt-dependency-group\"\n onClick={() => onDependencyClick?.(link)}\n >\n <path\n className={`gantt-dependency-path ${dashClass}`}\n d={path}\n style={{ stroke: strokeColor, strokeWidth: strokeW }}\n />\n {showArr && (\n <polygon\n className=\"gantt-dependency-arrow\"\n points={`${x2},${y2} ${x2 - 6},${y2 - 4} ${x2 - 6},${y2 + 4}`}\n style={{ fill: strokeColor }}\n />\n )}\n {showDelete && (\n <foreignObject\n x={delX - 8}\n y={delY - 8}\n width={16}\n height={16}\n className=\"gantt-dependency-delete-fo\"\n >\n <button\n className=\"gantt-dependency-delete-btn\"\n onClick={(e) => {\n e.stopPropagation();\n onDependencyDelete(link);\n }}\n title=\"删除连线\"\n >\n ×\n </button>\n </foreignObject>\n )}\n </g>\n );\n })}\n {connDrag &&\n (() => {\n const { startX, startY, curX, curY } = connDrag;\n const dx = curX - startX;\n const cpOffset = Math.min(Math.abs(dx) * 0.5, 60);\n const cp1x = startX + cpOffset;\n const cp2x = curX - cpOffset;\n const d = `M${startX},${startY} C${cp1x},${startY} ${cp2x},${curY} ${curX},${curY}`;\n return <path className=\"gantt-dep-drag-line\" d={d} />;\n })()}\n </svg>\n );\n };\n\n // ─── Today Marker ───────────────────────────────────────────\n const renderTodayMarker = () => {\n if (!todayMarker.visible) return null;\n return (\n <div\n className=\"gantt-today-marker\"\n style={{\n left: todayX,\n ...(todayMarker.color ? { background: todayMarker.color } : {}),\n }}\n />\n );\n };\n\n // ─── Tooltip ────────────────────────────────────────────────\n const [tooltipState, setTooltipState] = useState<{\n node: GanttNode;\n x: number;\n y: number;\n } | null>(null);\n const handleBarMouseEnter = useCallback(\n (e: React.MouseEvent, node: GanttNode) => {\n if (!tooltipConfig.enabled || drag.isDragging) return;\n setTooltipState({ node, x: e.clientX + 12, y: e.clientY + 12 });\n },\n [tooltipConfig.enabled, drag.isDragging],\n );\n const handleBarMouseLeave = useCallback(() => setTooltipState(null), []);\n\n const renderTooltip = () => {\n if (!tooltipState) return null;\n if (tooltipConfig.render)\n return (\n <div\n className=\"gantt-tooltip\"\n style={{ left: tooltipState.x, top: tooltipState.y }}\n >\n {tooltipConfig.render(tooltipState.node)}\n </div>\n );\n const n = tooltipState.node;\n return (\n <div\n className=\"gantt-tooltip\"\n style={{ left: tooltipState.x, top: tooltipState.y }}\n >\n <div className=\"gantt-tooltip-title\">{n.label}</div>\n {n.startDate && (\n <div className=\"gantt-tooltip-row\">\n <span className=\"gantt-tooltip-label\">Start:</span>\n {typeof n.startDate === \"string\"\n ? n.startDate\n : formatDate(n.startDate)}\n </div>\n )}\n {n.endDate && (\n <div className=\"gantt-tooltip-row\">\n <span className=\"gantt-tooltip-label\">End:</span>\n {typeof n.endDate === \"string\" ? n.endDate : formatDate(n.endDate)}\n </div>\n )}\n {n.workingDays != null && (\n <div className=\"gantt-tooltip-row\">\n <span className=\"gantt-tooltip-label\">{labels.workingDays}:</span>\n {n.workingDays}\n </div>\n )}\n {n.assignee && (\n <div className=\"gantt-tooltip-row\">\n <span className=\"gantt-tooltip-label\">Assignee:</span>\n {n.assignee}\n </div>\n )}\n {n.progress != null && (\n <div className=\"gantt-tooltip-row\">\n <span className=\"gantt-tooltip-label\">Progress:</span>\n {n.progress}%\n </div>\n )}\n {n.link && (\n <div className=\"gantt-tooltip-row\">\n <span className=\"gantt-tooltip-label\">Link:</span>\n <span className=\"gantt-tooltip-link\">{n.link}</span>\n </div>\n )}\n </div>\n );\n };\n\n // ─── Main Render ────────────────────────────────────────────\n if (!data || data.length === 0) {\n return (\n <div\n className={`gantt-container ${className || \"\"}`}\n style={{ width, height }}\n >\n {toolbar}\n <div className=\"gantt-empty\">{labels.noData}</div>\n </div>\n );\n }\n\n const displayNodes = showSearch ? filteredFlatNodes : flatNodes;\n const totalRowsHeight = displayNodes.length * rowHeight;\n\n return (\n <div\n className={`gantt-container ${className || \"\"}`}\n style={{ width, height }}\n >\n {toolbar}\n <div className=\"gantt-body\">\n <div className=\"gantt-tree-panel\" style={{ width: treePanelW }}>\n {showSearch && (\n <div className=\"gantt-search\">\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n >\n <circle cx=\"11\" cy=\"11\" r=\"8\" />\n <path d=\"m21 21-4.3-4.3\" />\n </svg>\n <input\n className=\"gantt-search-input\"\n placeholder={labels.searchPlaceholder}\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n />\n </div>\n )}\n <div className=\"gantt-tree-header\">\n <div className=\"gantt-tree-header-cell\" style={{ flex: 1 }}>\n {labels.treePanelTitle}\n </div>\n {columns?.map((col) => (\n <div\n key={col.key}\n className=\"gantt-tree-header-cell\"\n style={{\n width: col.width || 80,\n textAlign: col.align || \"left\",\n }}\n >\n {col.title}\n </div>\n ))}\n </div>\n <div\n className=\"gantt-tree-body\"\n ref={treeBodyRef}\n onScroll={() => syncScrollVertical(\"tree\")}\n >\n {displayNodes.map(renderTreeRow)}\n </div>\n </div>\n {treePanelResizable && (\n <div\n className={`gantt-resize-handle ${resizingRef.current ? \"gantt-resize-handle--active\" : \"\"}`}\n onMouseDown={handleResizeStart}\n />\n )}\n <div className=\"gantt-timeline-panel\" ref={timelinePanelRef}>\n {renderTimelineHeader\n ? renderTimelineHeader(dates, scale)\n : renderDefaultTimelineHeader()}\n <div\n className=\"gantt-timeline-body\"\n ref={timelineBodyRef}\n onScroll={() => {\n syncScrollVertical(\"timeline\");\n syncScrollHorizontal();\n }}\n onContextMenu={handleTimelineContextMenu}\n >\n <div\n className=\"gantt-timeline-grid\"\n style={{ width: totalTimelineWidth, height: totalRowsHeight }}\n >\n {renderGridColumns()}\n {renderTodayMarker()}\n </div>\n <div\n className=\"gantt-timeline-rows\"\n style={{ width: totalTimelineWidth, height: totalRowsHeight }}\n >\n {displayNodes.map((fn) => (\n <div\n key={fn.node.id}\n className={`gantt-bar-row ${gridCfg.showRowLines ? \"gantt-bar-row--lined\" : \"\"}`}\n style={{ height: rowHeight }}\n onMouseEnter={(e) => handleBarMouseEnter(e, fn.node)}\n onMouseLeave={handleBarMouseLeave}\n >\n {renderBar(fn)}\n </div>\n ))}\n </div>\n {renderDependencyLinks()}\n </div>\n </div>\n </div>\n {renderTooltip()}\n {/* Edit Dialog */}\n {editDialogOpen && editDialogNode && (\n <div className=\"gantt-edit-dialog-overlay\" onClick={cancelEdit}>\n <div\n className=\"gantt-edit-dialog\"\n onClick={(e) => e.stopPropagation()}\n >\n <div className=\"gantt-edit-dialog__header\">\n <span className=\"gantt-edit-dialog__title\">{labels.edit}</span>\n <button\n type=\"button\"\n className=\"gantt-edit-dialog__close\"\n onClick={cancelEdit}\n >\n \\u00D7\n </button>\n </div>\n <div className=\"gantt-edit-dialog__body\">\n <input\n ref={editInputRef}\n className=\"gantt-edit-dialog__input\"\n value={editingLabel}\n onChange={(e) => setEditingLabel(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") commitEdit();\n if (e.key === \"Escape\") cancelEdit();\n }}\n autoFocus\n />\n </div>\n <div className=\"gantt-edit-dialog__footer\">\n <button\n type=\"button\"\n className=\"gantt-edit-dialog__btn gantt-edit-dialog__btn--cancel\"\n onClick={cancelEdit}\n >\n Cancel\n </button>\n <button\n type=\"button\"\n className=\"gantt-edit-dialog__btn gantt-edit-dialog__btn--submit\"\n onClick={commitEdit}\n disabled={!editingLabel.trim()}\n >\n OK\n </button>\n </div>\n </div>\n </div>\n )}\n </div>\n );\n});\n\nexport default Gantt;\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"useGanttDrag.js","names":[],"sources":["../../../../../src/components/pro/Gantt/hooks/useGanttDrag.ts"],"sourcesContent":["/**\n * Drag and resize interaction hook for Gantt bars.\n * Handles move (translate) and resize-start/resize-end operations.\n */\n\nimport { useState, useCallback, useRef, useEffect } from 'react';\nimport type {\n GanttNode,\n GanttScaleConfig,\n GanttBarChangeEvent,\n HolidayCalendar,\n GanttCategoryConfig,\n} from '../types';\nimport {\n xToDate,\n dateToX,\n calculateWorkingDays,\n addWorkingDays,\n startOfDay,\n clamp,\n} from '../utils';\n\nexport type DragMode = 'move' | 'resize-start' | 'resize-end' | null;\n\nexport interface DragState {\n nodeId: string | number;\n mode: DragMode;\n startX: number;\n startBarLeft: number;\n startBarWidth: number;\n originalNode: GanttNode;\n}\n\nexport interface UseGanttDragOptions {\n scaleConfig: GanttScaleConfig;\n timelineStart: Date;\n onBarChange?: (event: GanttBarChangeEvent) => void;\n calendar?: HolidayCalendar;\n minBarWidth?: number;\n}\n\nexport function useGanttDrag(options: UseGanttDragOptions) {\n const { scaleConfig, timelineStart, onBarChange, calendar, minBarWidth = 10 } = options;\n\n const [dragState, setDragState] = useState<DragState | null>(null);\n const [dragDelta, setDragDelta] = useState<{ dx: number }>({ dx: 0 });\n const dragRef = useRef<DragState | null>(null);\n\n const startDrag = useCallback(\n (\n e: React.MouseEvent,\n node: GanttNode,\n mode: DragMode,\n barLeft: number,\n barWidth: number\n ) => {\n if (!mode) return;\n e.preventDefault();\n e.stopPropagation();\n\n const state: DragState = {\n nodeId: node.id,\n mode,\n startX: e.clientX,\n startBarLeft: barLeft,\n startBarWidth: barWidth,\n originalNode: node,\n };\n\n setDragState(state);\n setDragDelta({ dx: 0 });\n dragRef.current = state;\n },\n []\n );\n\n const handleMouseMove = useCallback(\n (e: MouseEvent) => {\n if (!dragRef.current) return;\n const dx = e.clientX - dragRef.current.startX;\n setDragDelta({ dx });\n },\n []\n );\n\n const handleMouseUp = useCallback(\n (e: MouseEvent) => {\n const state = dragRef.current;\n if (!state) return;\n\n const dx = e.clientX - state.startX;\n\n // Compute new position\n let newBarLeft = state.startBarLeft;\n let newBarWidth = state.startBarWidth;\n\n switch (state.mode) {\n case 'move':\n newBarLeft = state.startBarLeft + dx;\n break;\n case 'resize-start':\n newBarLeft = state.startBarLeft + dx;\n newBarWidth = Math.max(minBarWidth, state.startBarWidth - dx);\n break;\n case 'resize-end':\n newBarWidth = Math.max(minBarWidth, state.startBarWidth + dx);\n break;\n }\n\n // Convert pixel positions to dates\n const newStartDate = xToDate(newBarLeft, timelineStart, scaleConfig);\n const newEndDate = xToDate(newBarLeft + newBarWidth, timelineStart, scaleConfig);\n\n // Calculate working days if applicable\n const workingDays = calculateWorkingDays(newStartDate, newEndDate, calendar);\n\n if (onBarChange && (dx !== 0)) {\n onBarChange({\n node: state.originalNode,\n newStartDate: startOfDay(newStartDate),\n newEndDate: startOfDay(newEndDate),\n newWorkingDays: workingDays,\n changeType: state.mode as 'move' | 'resize-start' | 'resize-end',\n originalNode: state.originalNode,\n });\n }\n\n setDragState(null);\n setDragDelta({ dx: 0 });\n dragRef.current = null;\n },\n [timelineStart, scaleConfig, onBarChange, calendar, minBarWidth]\n );\n\n // Attach global mouse listeners during drag\n useEffect(() => {\n if (dragState) {\n window.addEventListener('mousemove', handleMouseMove);\n window.addEventListener('mouseup', handleMouseUp);\n return () => {\n window.removeEventListener('mousemove', handleMouseMove);\n window.removeEventListener('mouseup', handleMouseUp);\n };\n }\n }, [dragState, handleMouseMove, handleMouseUp]);\n\n /**\n * Get the adjusted bar position for a given node during drag\n */\n const getAdjustedBar = useCallback(\n (nodeId: string | number, barLeft: number, barWidth: number) => {\n if (!dragState || dragState.nodeId !== nodeId) {\n return { left: barLeft, width: barWidth };\n }\n\n const dx = dragDelta.dx;\n\n switch (dragState.mode) {\n case 'move':\n return { left: barLeft + dx, width: barWidth };\n case 'resize-start':\n return {\n left: barLeft + dx,\n width: Math.max(minBarWidth, barWidth - dx),\n };\n case 'resize-end':\n return {\n left: barLeft,\n width: Math.max(minBarWidth, barWidth + dx),\n };\n default:\n return { left: barLeft, width: barWidth };\n }\n },\n [dragState, dragDelta, minBarWidth]\n );\n\n const isDragging = dragState !== null;\n const draggingNodeId = dragState?.nodeId ?? null;\n\n return {\n isDragging,\n draggingNodeId,\n dragMode: dragState?.mode ?? null,\n startDrag,\n getAdjustedBar,\n };\n}\n"],"mappings":";;;AAyCA,SAAgB,EAAa,GAA8B;CACzD,IAAM,EAAE,gBAAa,kBAAe,gBAAa,aAAU,iBAAc,OAAO,GAE1E,CAAC,GAAW,KAAgB,EAA2B,IAAI,GAC3D,CAAC,GAAW,KAAgB,EAAyB,EAAE,IAAI,EAAE,CAAC,GAC9D,IAAU,EAAyB,IAAI,GAEvC,IAAY,GAEd,GACA,GACA,GACA,GACA,MACG;EACH,IAAI,CAAC,GAAM;EAEX,AADA,EAAE,eAAe,GACjB,EAAE,gBAAgB;EAElB,IAAM,IAAmB;GACvB,QAAQ,EAAK;GACb;GACA,QAAQ,EAAE;GACV,cAAc;GACd,eAAe;GACf,cAAc;EAChB;EAIA,AAFA,EAAa,CAAK,GAClB,EAAa,EAAE,IAAI,EAAE,CAAC,GACtB,EAAQ,UAAU;CACpB,GACA,CAAC,CACH,GAEM,IAAkB,GACrB,MAAkB;EACjB,IAAI,CAAC,EAAQ,SAAS;EACtB,IAAM,IAAK,EAAE,UAAU,EAAQ,QAAQ;EACvC,EAAa,EAAE,MAAG,CAAC;CACrB,GACA,CAAC,CACH,GAEM,IAAgB,GACnB,MAAkB;EACjB,IAAM,IAAQ,EAAQ;EACtB,IAAI,CAAC,GAAO;EAEZ,IAAM,IAAK,EAAE,UAAU,EAAM,QAGzB,IAAa,EAAM,cACnB,IAAc,EAAM;EAExB,QAAQ,EAAM,MAAd;GACE,KAAK;IACH,IAAa,EAAM,eAAe;IAClC;GACF,KAAK;IAEH,AADA,IAAa,EAAM,eAAe,GAClC,IAAc,KAAK,IAAI,GAAa,EAAM,gBAAgB,CAAE;IAC5D;GACF,KAAK,cACH,IAAc,KAAK,IAAI,GAAa,EAAM,gBAAgB,CAAE;EAEhE;EAGA,IAAM,IAAe,EAAQ,GAAY,GAAe,CAAW,GAC7D,IAAa,EAAQ,IAAa,GAAa,GAAe,CAAW,GAGzE,IAAc,EAAqB,GAAc,GAAY,CAAQ;EAe3E,AAbI,KAAgB,MAAO,KACzB,EAAY;GACV,MAAM,EAAM;GACZ,cAAc,EAAW,CAAY;GACrC,YAAY,EAAW,CAAU;GACjC,gBAAgB;GAChB,YAAY,EAAM;GAClB,cAAc,EAAM;EACtB,CAAC,GAGH,EAAa,IAAI,GACjB,EAAa,EAAE,IAAI,EAAE,CAAC,GACtB,EAAQ,UAAU;CACpB,GACA;EAAC;EAAe;EAAa;EAAa;EAAU;CAAW,CACjE;CAGA,QAAgB;EACd,IAAI,GAGF,OAFA,OAAO,iBAAiB,aAAa,CAAe,GACpD,OAAO,iBAAiB,WAAW,CAAa,SACnC;GAEX,AADA,OAAO,oBAAoB,aAAa,CAAe,GACvD,OAAO,oBAAoB,WAAW,CAAa;EACrD;CAEJ,GAAG;EAAC;EAAW;EAAiB;CAAa,CAAC;CAK9C,IAAM,IAAiB,GACpB,GAAyB,GAAiB,MAAqB;EAC9D,IAAI,CAAC,KAAa,EAAU,WAAW,GACrC,OAAO;GAAE,MAAM;GAAS,OAAO;EAAS;EAG1C,IAAM,IAAK,EAAU;EAErB,QAAQ,EAAU,MAAlB;GACE,KAAK,QACH,OAAO;IAAE,MAAM,IAAU;IAAI,OAAO;GAAS;GAC/C,KAAK,gBACH,OAAO;IACL,MAAM,IAAU;IAChB,OAAO,KAAK,IAAI,GAAa,IAAW,CAAE;GAC5C;GACF,KAAK,cACH,OAAO;IACL,MAAM;IACN,OAAO,KAAK,IAAI,GAAa,IAAW,CAAE;GAC5C;GACF,SACE,OAAO;IAAE,MAAM;IAAS,OAAO;GAAS;EAC5C;CACF,GACA;EAAC;EAAW;EAAW;CAAW,CACpC;CAKA,OAAO;EACL,YAJiB,MAAc;EAK/B,gBAJqB,GAAW,UAAU;EAK1C,UAAU,GAAW,QAAQ;EAC7B;EACA;CACF;AACF"}
1
+ {"version":3,"file":"useGanttDrag.js","names":["useGanttDrag","options","dragState","setDragState","useState","dragDelta","setDragDelta","dragRef","useRef","startDrag","useCallback","mode","state","node","barLeft","barWidth","handleMouseMove","dx","handleMouseUp","e","newBarLeft","newBarWidth","minBarWidth","newStartDate","xToDate","timelineStart","scaleConfig","newEndDate","workingDays","calculateWorkingDays","calendar","onBarChange","startOfDay","getAdjustedBar","nodeId"],"sources":["../../../../../src/components/pro/Gantt/hooks/useGanttDrag.ts"],"sourcesContent":["/**\n * Drag and resize interaction hook for Gantt bars.\n * Handles move (translate) and resize-start/resize-end operations.\n */\n\nimport { useState, useCallback, useRef, useEffect } from 'react';\nimport type {\n GanttNode,\n GanttScaleConfig,\n GanttBarChangeEvent,\n HolidayCalendar,\n GanttCategoryConfig,\n} from '../types';\nimport {\n xToDate,\n dateToX,\n calculateWorkingDays,\n addWorkingDays,\n startOfDay,\n clamp,\n} from '../utils';\n\nexport type DragMode = 'move' | 'resize-start' | 'resize-end' | null;\n\nexport interface DragState {\n nodeId: string | number;\n mode: DragMode;\n startX: number;\n startBarLeft: number;\n startBarWidth: number;\n originalNode: GanttNode;\n}\n\nexport interface UseGanttDragOptions {\n scaleConfig: GanttScaleConfig;\n timelineStart: Date;\n onBarChange?: (event: GanttBarChangeEvent) => void;\n calendar?: HolidayCalendar;\n minBarWidth?: number;\n}\n\nexport function useGanttDrag(options: UseGanttDragOptions) {\n const { scaleConfig, timelineStart, onBarChange, calendar, minBarWidth = 10 } = options;\n\n const [dragState, setDragState] = useState<DragState | null>(null);\n const [dragDelta, setDragDelta] = useState<{ dx: number }>({ dx: 0 });\n const dragRef = useRef<DragState | null>(null);\n\n const startDrag = useCallback(\n (\n e: React.MouseEvent,\n node: GanttNode,\n mode: DragMode,\n barLeft: number,\n barWidth: number\n ) => {\n if (!mode) return;\n e.preventDefault();\n e.stopPropagation();\n\n const state: DragState = {\n nodeId: node.id,\n mode,\n startX: e.clientX,\n startBarLeft: barLeft,\n startBarWidth: barWidth,\n originalNode: node,\n };\n\n setDragState(state);\n setDragDelta({ dx: 0 });\n dragRef.current = state;\n },\n []\n );\n\n const handleMouseMove = useCallback(\n (e: MouseEvent) => {\n if (!dragRef.current) return;\n const dx = e.clientX - dragRef.current.startX;\n setDragDelta({ dx });\n },\n []\n );\n\n const handleMouseUp = useCallback(\n (e: MouseEvent) => {\n const state = dragRef.current;\n if (!state) return;\n\n const dx = e.clientX - state.startX;\n\n // Compute new position\n let newBarLeft = state.startBarLeft;\n let newBarWidth = state.startBarWidth;\n\n switch (state.mode) {\n case 'move':\n newBarLeft = state.startBarLeft + dx;\n break;\n case 'resize-start':\n newBarLeft = state.startBarLeft + dx;\n newBarWidth = Math.max(minBarWidth, state.startBarWidth - dx);\n break;\n case 'resize-end':\n newBarWidth = Math.max(minBarWidth, state.startBarWidth + dx);\n break;\n }\n\n // Convert pixel positions to dates\n const newStartDate = xToDate(newBarLeft, timelineStart, scaleConfig);\n const newEndDate = xToDate(newBarLeft + newBarWidth, timelineStart, scaleConfig);\n\n // Calculate working days if applicable\n const workingDays = calculateWorkingDays(newStartDate, newEndDate, calendar);\n\n if (onBarChange && (dx !== 0)) {\n onBarChange({\n node: state.originalNode,\n newStartDate: startOfDay(newStartDate),\n newEndDate: startOfDay(newEndDate),\n newWorkingDays: workingDays,\n changeType: state.mode as 'move' | 'resize-start' | 'resize-end',\n originalNode: state.originalNode,\n });\n }\n\n setDragState(null);\n setDragDelta({ dx: 0 });\n dragRef.current = null;\n },\n [timelineStart, scaleConfig, onBarChange, calendar, minBarWidth]\n );\n\n // Attach global mouse listeners during drag\n useEffect(() => {\n if (dragState) {\n window.addEventListener('mousemove', handleMouseMove);\n window.addEventListener('mouseup', handleMouseUp);\n return () => {\n window.removeEventListener('mousemove', handleMouseMove);\n window.removeEventListener('mouseup', handleMouseUp);\n };\n }\n }, [dragState, handleMouseMove, handleMouseUp]);\n\n /**\n * Get the adjusted bar position for a given node during drag\n */\n const getAdjustedBar = useCallback(\n (nodeId: string | number, barLeft: number, barWidth: number) => {\n if (!dragState || dragState.nodeId !== nodeId) {\n return { left: barLeft, width: barWidth };\n }\n\n const dx = dragDelta.dx;\n\n switch (dragState.mode) {\n case 'move':\n return { left: barLeft + dx, width: barWidth };\n case 'resize-start':\n return {\n left: barLeft + dx,\n width: Math.max(minBarWidth, barWidth - dx),\n };\n case 'resize-end':\n return {\n left: barLeft,\n width: Math.max(minBarWidth, barWidth + dx),\n };\n default:\n return { left: barLeft, width: barWidth };\n }\n },\n [dragState, dragDelta, minBarWidth]\n );\n\n const isDragging = dragState !== null;\n const draggingNodeId = dragState?.nodeId ?? null;\n\n return {\n isDragging,\n draggingNodeId,\n dragMode: dragState?.mode ?? null,\n startDrag,\n getAdjustedBar,\n };\n}\n"],"mappings":"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"}