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":"CommentPopover.js","names":[],"sources":["../../../../src/components/pro/RichTextEditor/CommentPopover.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef, useCallback } from 'react';\nimport { useEditorState, type Editor } from '@tiptap/react';\nimport type { CommentThread, CommentItem } from './extensions/CommentMark';\n\nfunction generateId() {\n return `c_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;\n}\n\nfunction timeAgo(ts: number): string {\n const diff = Date.now() - ts;\n const sec = Math.floor(diff / 1000);\n if (sec < 60) return 'just now';\n const min = Math.floor(sec / 60);\n if (min < 60) return `${min}m ago`;\n const hr = Math.floor(min / 60);\n if (hr < 24) return `${hr}h ago`;\n const d = Math.floor(hr / 24);\n return `${d}d ago`;\n}\n\ninterface CommentPopoverProps {\n editor: Editor;\n threads: CommentThread[];\n onThreadsChange: (threads: CommentThread[]) => void;\n showPanel: boolean;\n onOpenPanel: () => void;\n onScrollToThread: (id: string) => void;\n currentUser?: string;\n editable?: boolean;\n}\n\nconst CommentPopover: React.FC<CommentPopoverProps> = ({\n editor,\n threads,\n onThreadsChange,\n showPanel,\n onOpenPanel,\n onScrollToThread,\n currentUser = 'User',\n editable = true,\n}) => {\n const [activeThreadId, setActiveThreadId] = useState<string | null>(null);\n const activeThread = threads.find((t) => t.id === activeThreadId && !t.resolved);\n const latest = useRef({ editable, threads, activeThreadId });\n latest.current = { editable, threads, activeThreadId };\n const editorEditable = useEditorState({ editor, selector: ({ editor }) => editor.isEditable });\n const canEdit = editable && editorEditable;\n const [pos, setPos] = useState({ x: 0, y: 0 });\n const [replyText, setReplyText] = useState('');\n const popRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n\n useEffect(() => {\n const dom = editor.view.dom;\n const handleClick = (e: Event) => {\n const target = e.target as HTMLElement;\n const commentEl = target.closest('.rte-comment-mark') as HTMLElement | null;\n if (!commentEl) { setActiveThreadId(null); return; }\n\n const commentId = commentEl.getAttribute('data-comment-id');\n const thread = latest.current.threads.find((t) => t.id === commentId);\n if (!commentId || !thread || thread.resolved) { setActiveThreadId(null); return; }\n\n if (showPanel) {\n onScrollToThread(commentId);\n setActiveThreadId(null);\n return;\n }\n\n const wrapperEl = dom.closest('.rte-editor-wrapper');\n if (!wrapperEl) return;\n const wRect = wrapperEl.getBoundingClientRect();\n const elRect = commentEl.getBoundingClientRect();\n\n setPos({\n x: elRect.left - wRect.left + elRect.width / 2,\n y: elRect.bottom - wRect.top + 6,\n });\n setActiveThreadId(thread.id);\n setReplyText('');\n };\n\n dom.addEventListener('click', handleClick);\n return () => dom.removeEventListener('click', handleClick);\n }, [editor, threads, showPanel, onScrollToThread]);\n\n useEffect(() => {\n if (!activeThread) return;\n const handler = (e: MouseEvent) => {\n if (popRef.current && !popRef.current.contains(e.target as Node)) {\n setActiveThreadId(null);\n }\n };\n document.addEventListener('mousedown', handler);\n return () => document.removeEventListener('mousedown', handler);\n }, [activeThread]);\n\n useEffect(() => {\n if (activeThreadId && inputRef.current) inputRef.current.focus();\n }, [activeThreadId, canEdit]);\n\n useEffect(() => {\n if (!activeThread || showPanel) {\n setActiveThreadId(null);\n setReplyText('');\n }\n }, [activeThread, showPanel]);\n\n const toggleResolve = useCallback(() => {\n if (!latest.current.editable || !editor.isEditable) return;\n const thread = latest.current.threads.find((t) => t.id === latest.current.activeThreadId && !t.resolved);\n if (!thread) return;\n const tr = editor.state.tr;\n editor.state.doc.descendants((node, pos) => {\n node.marks.forEach((mark) => {\n if (mark.type.name === 'comment' && mark.attrs.commentId === thread.id) {\n tr.removeMark(pos, pos + node.nodeSize, mark)\n .addMark(pos, pos + node.nodeSize, mark.type.create({ ...mark.attrs, resolved: true }));\n }\n });\n });\n if (tr.docChanged) editor.view.dispatch(tr);\n onThreadsChange(latest.current.threads.map((t) => t.id === thread.id ? { ...t, resolved: true } : t));\n setActiveThreadId(null);\n }, [activeThread, editor, threads, onThreadsChange]);\n\n const addReply = useCallback(() => {\n if (!latest.current.editable || !editor.isEditable || !replyText.trim()) return;\n const thread = latest.current.threads.find((t) => t.id === latest.current.activeThreadId && !t.resolved);\n if (!thread) return;\n const reply: CommentItem = {\n id: generateId(),\n author: currentUser,\n text: replyText.trim(),\n createdAt: Date.now(),\n };\n const updated = latest.current.threads.map((t) =>\n t.id === thread.id ? { ...t, comments: [...t.comments, reply] } : t\n );\n onThreadsChange(updated);\n setReplyText('');\n }, [editor, activeThread, replyText, threads, onThreadsChange, currentUser]);\n\n if (!activeThread || showPanel) return null;\n\n return (\n <div ref={popRef} className=\"rte-comment-popover\" style={{ left: pos.x, top: pos.y }}>\n <div className=\"rte-comment-popover__header\">\n <span className=\"rte-comment-popover__status\">Open</span>\n <div className=\"rte-comment-popover__actions\">\n {canEdit && <button type=\"button\" className=\"rte-comments__icon-btn\" onClick={toggleResolve} title=\"Resolve\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><polyline points=\"20 6 9 17 4 12\" /></svg>\n </button>}\n <button type=\"button\" className=\"rte-comments__icon-btn\" onClick={() => { onOpenPanel(); setActiveThreadId(null); }} title=\"Open panel\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><polyline points=\"15 3 21 3 21 9\" /><polyline points=\"9 21 3 21 3 15\" /><line x1=\"21\" y1=\"3\" x2=\"14\" y2=\"10\" /><line x1=\"3\" y1=\"21\" x2=\"10\" y2=\"14\" /></svg>\n </button>\n <button type=\"button\" className=\"rte-comments__icon-btn\" onClick={() => setActiveThreadId(null)} title=\"Close\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" /><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" /></svg>\n </button>\n </div>\n </div>\n\n {activeThread.comments.map((c) => (\n <div key={c.id} className=\"rte-comment-popover__comment\">\n <div className=\"rte-comments__comment-meta\">\n <span className=\"rte-comments__author\">{c.author}</span>\n <span className=\"rte-comments__time\">{timeAgo(c.createdAt)}</span>\n </div>\n <div className=\"rte-comments__comment-text\">{c.text}</div>\n </div>\n ))}\n\n {canEdit && <div className=\"rte-comment-popover__reply\">\n <input\n ref={inputRef}\n className=\"rte-comments__reply-input\"\n value={replyText}\n onChange={(e) => setReplyText(e.target.value)}\n onKeyDown={(e) => {\n if (e.nativeEvent.isComposing || e.nativeEvent.keyCode === 229) return;\n if (e.key === 'Enter') { e.preventDefault(); addReply(); }\n if (e.key === 'Escape') setActiveThreadId(null);\n }}\n placeholder=\"Reply...\"\n />\n <button type=\"button\" className=\"rte-comments__reply-send\" onClick={addReply} disabled={!replyText.trim()}>\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\" /><polygon points=\"22 2 15 22 11 13 2 9 22 2\" /></svg>\n </button>\n </div>}\n </div>\n );\n};\n\nexport default CommentPopover;\n"],"mappings":"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"}
1
+ {"version":3,"file":"CommentPopover.js","names":["generateId","timeAgo","diff","ts","sec","min","hr","CommentPopover","activeThreadId","setActiveThreadId","useState","activeThread","threads","t","latest","useRef","editorEditable","useEditorState","editor","canEdit","editable","pos","setPos","replyText","setReplyText","popRef","inputRef","useEffect","dom","handleClick","commentEl","e","commentId","thread","showPanel","onScrollToThread","wrapperEl","wRect","elRect","handler","toggleResolve","useCallback","tr","mark","node","onThreadsChange","addReply","reply","currentUser","onOpenPanel","c"],"sources":["../../../../src/components/pro/RichTextEditor/CommentPopover.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef, useCallback } from 'react';\nimport { useEditorState, type Editor } from '@tiptap/react';\nimport type { CommentThread, CommentItem } from './extensions/CommentMark';\n\nfunction generateId() {\n return `c_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;\n}\n\nfunction timeAgo(ts: number): string {\n const diff = Date.now() - ts;\n const sec = Math.floor(diff / 1000);\n if (sec < 60) return 'just now';\n const min = Math.floor(sec / 60);\n if (min < 60) return `${min}m ago`;\n const hr = Math.floor(min / 60);\n if (hr < 24) return `${hr}h ago`;\n const d = Math.floor(hr / 24);\n return `${d}d ago`;\n}\n\ninterface CommentPopoverProps {\n editor: Editor;\n threads: CommentThread[];\n onThreadsChange: (threads: CommentThread[]) => void;\n showPanel: boolean;\n onOpenPanel: () => void;\n onScrollToThread: (id: string) => void;\n currentUser?: string;\n editable?: boolean;\n}\n\nconst CommentPopover: React.FC<CommentPopoverProps> = ({\n editor,\n threads,\n onThreadsChange,\n showPanel,\n onOpenPanel,\n onScrollToThread,\n currentUser = 'User',\n editable = true,\n}) => {\n const [activeThreadId, setActiveThreadId] = useState<string | null>(null);\n const activeThread = threads.find((t) => t.id === activeThreadId && !t.resolved);\n const latest = useRef({ editable, threads, activeThreadId });\n latest.current = { editable, threads, activeThreadId };\n const editorEditable = useEditorState({ editor, selector: ({ editor }) => editor.isEditable });\n const canEdit = editable && editorEditable;\n const [pos, setPos] = useState({ x: 0, y: 0 });\n const [replyText, setReplyText] = useState('');\n const popRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n\n useEffect(() => {\n const dom = editor.view.dom;\n const handleClick = (e: Event) => {\n const target = e.target as HTMLElement;\n const commentEl = target.closest('.rte-comment-mark') as HTMLElement | null;\n if (!commentEl) { setActiveThreadId(null); return; }\n\n const commentId = commentEl.getAttribute('data-comment-id');\n const thread = latest.current.threads.find((t) => t.id === commentId);\n if (!commentId || !thread || thread.resolved) { setActiveThreadId(null); return; }\n\n if (showPanel) {\n onScrollToThread(commentId);\n setActiveThreadId(null);\n return;\n }\n\n const wrapperEl = dom.closest('.rte-editor-wrapper');\n if (!wrapperEl) return;\n const wRect = wrapperEl.getBoundingClientRect();\n const elRect = commentEl.getBoundingClientRect();\n\n setPos({\n x: elRect.left - wRect.left + elRect.width / 2,\n y: elRect.bottom - wRect.top + 6,\n });\n setActiveThreadId(thread.id);\n setReplyText('');\n };\n\n dom.addEventListener('click', handleClick);\n return () => dom.removeEventListener('click', handleClick);\n }, [editor, threads, showPanel, onScrollToThread]);\n\n useEffect(() => {\n if (!activeThread) return;\n const handler = (e: MouseEvent) => {\n if (popRef.current && !popRef.current.contains(e.target as Node)) {\n setActiveThreadId(null);\n }\n };\n document.addEventListener('mousedown', handler);\n return () => document.removeEventListener('mousedown', handler);\n }, [activeThread]);\n\n useEffect(() => {\n if (activeThreadId && inputRef.current) inputRef.current.focus();\n }, [activeThreadId, canEdit]);\n\n useEffect(() => {\n if (!activeThread || showPanel) {\n setActiveThreadId(null);\n setReplyText('');\n }\n }, [activeThread, showPanel]);\n\n const toggleResolve = useCallback(() => {\n if (!latest.current.editable || !editor.isEditable) return;\n const thread = latest.current.threads.find((t) => t.id === latest.current.activeThreadId && !t.resolved);\n if (!thread) return;\n const tr = editor.state.tr;\n editor.state.doc.descendants((node, pos) => {\n node.marks.forEach((mark) => {\n if (mark.type.name === 'comment' && mark.attrs.commentId === thread.id) {\n tr.removeMark(pos, pos + node.nodeSize, mark)\n .addMark(pos, pos + node.nodeSize, mark.type.create({ ...mark.attrs, resolved: true }));\n }\n });\n });\n if (tr.docChanged) editor.view.dispatch(tr);\n onThreadsChange(latest.current.threads.map((t) => t.id === thread.id ? { ...t, resolved: true } : t));\n setActiveThreadId(null);\n }, [activeThread, editor, threads, onThreadsChange]);\n\n const addReply = useCallback(() => {\n if (!latest.current.editable || !editor.isEditable || !replyText.trim()) return;\n const thread = latest.current.threads.find((t) => t.id === latest.current.activeThreadId && !t.resolved);\n if (!thread) return;\n const reply: CommentItem = {\n id: generateId(),\n author: currentUser,\n text: replyText.trim(),\n createdAt: Date.now(),\n };\n const updated = latest.current.threads.map((t) =>\n t.id === thread.id ? { ...t, comments: [...t.comments, reply] } : t\n );\n onThreadsChange(updated);\n setReplyText('');\n }, [editor, activeThread, replyText, threads, onThreadsChange, currentUser]);\n\n if (!activeThread || showPanel) return null;\n\n return (\n <div ref={popRef} className=\"rte-comment-popover\" style={{ left: pos.x, top: pos.y }}>\n <div className=\"rte-comment-popover__header\">\n <span className=\"rte-comment-popover__status\">Open</span>\n <div className=\"rte-comment-popover__actions\">\n {canEdit && <button type=\"button\" className=\"rte-comments__icon-btn\" onClick={toggleResolve} title=\"Resolve\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><polyline points=\"20 6 9 17 4 12\" /></svg>\n </button>}\n <button type=\"button\" className=\"rte-comments__icon-btn\" onClick={() => { onOpenPanel(); setActiveThreadId(null); }} title=\"Open panel\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><polyline points=\"15 3 21 3 21 9\" /><polyline points=\"9 21 3 21 3 15\" /><line x1=\"21\" y1=\"3\" x2=\"14\" y2=\"10\" /><line x1=\"3\" y1=\"21\" x2=\"10\" y2=\"14\" /></svg>\n </button>\n <button type=\"button\" className=\"rte-comments__icon-btn\" onClick={() => setActiveThreadId(null)} title=\"Close\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" /><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" /></svg>\n </button>\n </div>\n </div>\n\n {activeThread.comments.map((c) => (\n <div key={c.id} className=\"rte-comment-popover__comment\">\n <div className=\"rte-comments__comment-meta\">\n <span className=\"rte-comments__author\">{c.author}</span>\n <span className=\"rte-comments__time\">{timeAgo(c.createdAt)}</span>\n </div>\n <div className=\"rte-comments__comment-text\">{c.text}</div>\n </div>\n ))}\n\n {canEdit && <div className=\"rte-comment-popover__reply\">\n <input\n ref={inputRef}\n className=\"rte-comments__reply-input\"\n value={replyText}\n onChange={(e) => setReplyText(e.target.value)}\n onKeyDown={(e) => {\n if (e.nativeEvent.isComposing || e.nativeEvent.keyCode === 229) return;\n if (e.key === 'Enter') { e.preventDefault(); addReply(); }\n if (e.key === 'Escape') setActiveThreadId(null);\n }}\n placeholder=\"Reply...\"\n />\n <button type=\"button\" className=\"rte-comments__reply-send\" onClick={addReply} disabled={!replyText.trim()}>\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\" /><polygon points=\"22 2 15 22 11 13 2 9 22 2\" /></svg>\n </button>\n </div>}\n </div>\n );\n};\n\nexport default CommentPopover;\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ContextMenu.js","names":[],"sources":["../../../../src/components/pro/RichTextEditor/ContextMenu.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef, useCallback } from 'react';\nimport type { Editor } from '@tiptap/react';\nimport type { RichTextEditorLabels } from './types';\nimport { defaultLabels } from './types';\nimport { getNextFloatZIndex } from './extensions/FloatingDialog';\n\ninterface ContextMenuProps {\n editor: Editor;\n labels?: RichTextEditorLabels;\n onAIClick?: () => void;\n}\n\ninterface MenuItem {\n label: string;\n icon?: string;\n action: () => void;\n disabled?: boolean;\n divider?: boolean;\n shortcut?: string;\n}\n\nconst ContextMenu: React.FC<ContextMenuProps> = ({ editor, labels: propsLabels, onAIClick }) => {\n const labels = { ...defaultLabels, ...propsLabels };\n const [visible, setVisible] = useState(false);\n const [pos, setPos] = useState({ x: 0, y: 0 });\n const menuRef = useRef<HTMLDivElement>(null);\n\n const close = useCallback(() => setVisible(false), []);\n\n useEffect(() => {\n const editorEl = editor.view.dom;\n\n const handleContextMenu = (e: Event) => {\n const me = e as MouseEvent;\n me.preventDefault();\n\n const wrapperEl = editorEl.closest('.rte-editor-wrapper');\n if (!wrapperEl) return;\n const rect = wrapperEl.getBoundingClientRect();\n\n setPos({\n x: me.clientX - rect.left,\n y: me.clientY - rect.top,\n });\n setVisible(true);\n };\n\n editorEl.addEventListener('contextmenu', handleContextMenu);\n document.addEventListener('mousedown', (e) => {\n if (menuRef.current && !menuRef.current.contains(e.target as Node)) {\n close();\n }\n });\n document.addEventListener('keydown', (e) => {\n if (e.key === 'Escape') close();\n });\n\n return () => {\n editorEl.removeEventListener('contextmenu', handleContextMenu);\n };\n }, [editor, close]);\n\n useEffect(() => {\n if (!visible || !menuRef.current) return;\n const menu = menuRef.current;\n const wrapper = menu.parentElement;\n if (!wrapper) return;\n\n const wRect = wrapper.getBoundingClientRect();\n const mRect = menu.getBoundingClientRect();\n\n let { x, y } = pos;\n if (x + mRect.width > wRect.width) x = Math.max(0, wRect.width - mRect.width - 4);\n if (y + mRect.height > wRect.height) y = Math.max(0, y - mRect.height);\n if (x !== pos.x || y !== pos.y) setPos({ x, y });\n }, [visible]);\n\n if (!visible) return null;\n\n const hasSelection = editor.state.selection.from !== editor.state.selection.to;\n const isInTable = editor.isActive('table');\n\n const items: (MenuItem | 'divider')[] = [\n { label: 'Cut', shortcut: '⌘X', action: () => { document.execCommand('cut'); close(); }, disabled: !hasSelection },\n { label: 'Copy', shortcut: '⌘C', action: () => { document.execCommand('copy'); close(); }, disabled: !hasSelection },\n { label: 'Paste', shortcut: '⌘V', action: () => { document.execCommand('paste'); close(); } },\n { label: 'Select All', shortcut: '⌘A', action: () => { editor.chain().focus().selectAll().run(); close(); } },\n 'divider',\n { label: labels.bold || 'Bold', shortcut: '⌘B', action: () => { editor.chain().focus().toggleBold().run(); close(); } },\n { label: labels.italic || 'Italic', shortcut: '⌘I', action: () => { editor.chain().focus().toggleItalic().run(); close(); } },\n { label: labels.underline || 'Underline', shortcut: '⌘U', action: () => { editor.chain().focus().toggleUnderline().run(); close(); } },\n { label: labels.strikethrough || 'Strikethrough', action: () => { editor.chain().focus().toggleStrike().run(); close(); } },\n 'divider',\n { label: labels.link || 'Insert Link', action: () => {\n const url = window.prompt(labels.insertLinkUrl || 'Enter URL');\n if (url) editor.chain().focus().setLink({ href: url }).run();\n close();\n }},\n { label: labels.image || 'Insert Image', action: () => {\n const url = window.prompt(labels.insertImageUrl || 'Enter image URL');\n if (url) editor.chain().focus().setImage({ src: url }).run();\n close();\n }},\n { label: labels.codeBlock || 'Code Block', action: () => { editor.chain().focus().toggleNode('codeBlock', 'paragraph').run(); close(); } },\n { label: labels.blockquote || 'Blockquote', action: () => { editor.chain().focus().toggleBlockquote().run(); close(); } },\n { label: labels.horizontalRule || 'Horizontal Rule', action: () => { editor.chain().focus().setHorizontalRule().run(); close(); } },\n { label: `${labels.floatingDialog || 'Floating Dialog'} — ${labels.layoutBlock || 'Block'}`, action: () => {\n editor.chain().focus().insertContent({ type: 'floatingDialog', attrs: { title: 'Note', layout: 'block' }, content: [{ type: 'paragraph' }] }).run();\n close();\n }},\n { label: `${labels.floatingDialog || 'Floating Dialog'} — ${labels.layoutWrapLeft || 'Wrap Left'}`, action: () => {\n editor.chain().focus().insertContent({ type: 'floatingDialog', attrs: { title: 'Note', layout: 'wrap-left', width: 240 }, content: [{ type: 'paragraph' }] }).run();\n close();\n }},\n { label: `${labels.floatingDialog || 'Floating Dialog'} — ${labels.layoutWrapRight || 'Wrap Right'}`, action: () => {\n editor.chain().focus().insertContent({ type: 'floatingDialog', attrs: { title: 'Note', layout: 'wrap-right', width: 240 }, content: [{ type: 'paragraph' }] }).run();\n close();\n }},\n { label: `${labels.floatingDialog || 'Floating Dialog'} — ${labels.layoutFloat || 'Float'}`, action: () => {\n editor.chain().focus().insertContent({ type: 'floatingDialog', attrs: { title: 'Note', layout: 'float', x: 40, y: 40, zIndex: getNextFloatZIndex(editor) }, content: [{ type: 'paragraph' }] }).run();\n close();\n }},\n ];\n\n if (isInTable) {\n items.push('divider');\n items.push({ label: labels.tableAddRowAfter || 'Add Row After', action: () => { editor.chain().focus().addRowAfter().run(); close(); } });\n items.push({ label: labels.tableAddColumnAfter || 'Add Column After', action: () => { editor.chain().focus().addColumnAfter().run(); close(); } });\n items.push({ label: labels.tableDeleteRow || 'Delete Row', action: () => { editor.chain().focus().deleteRow().run(); close(); } });\n items.push({ label: labels.tableDeleteColumn || 'Delete Column', action: () => { editor.chain().focus().deleteColumn().run(); close(); } });\n items.push({ label: labels.tableMergeCells || 'Merge Cells', action: () => { editor.chain().focus().mergeCells().run(); close(); } });\n items.push({ label: labels.tableSplitCell || 'Split Cell', action: () => { editor.chain().focus().splitCell().run(); close(); } });\n }\n\n if (onAIClick) {\n items.push('divider');\n items.push({ label: `✨ ${labels.ai || 'AI Assistant'}`, action: () => { onAIClick(); close(); }, disabled: !hasSelection });\n }\n\n return (\n <div\n ref={menuRef}\n className=\"rte-context-menu\"\n style={{ left: pos.x, top: pos.y }}\n >\n {items.map((item, i) =>\n item === 'divider' ? (\n <div key={`d-${i}`} className=\"rte-context-menu__divider\" />\n ) : (\n <button\n key={i}\n type=\"button\"\n className=\"rte-context-menu__item\"\n onClick={item.action}\n disabled={item.disabled}\n >\n <span className=\"rte-context-menu__label\">{item.label}</span>\n {item.shortcut && <span className=\"rte-context-menu__shortcut\">{item.shortcut}</span>}\n </button>\n )\n )}\n </div>\n );\n};\n\nexport default ContextMenu;\n"],"mappings":"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"}
1
+ {"version":3,"file":"ContextMenu.js","names":["ContextMenu","propsLabels","labels","defaultLabels","visible","setVisible","useState","pos","setPos","menuRef","useRef","close","useCallback","useEffect","editorEl","editor","handleContextMenu","me","e","wrapperEl","rect","menu","wrapper","wRect","mRect","x","y","hasSelection","isInTable","items","url","getNextFloatZIndex","onAIClick","item","i"],"sources":["../../../../src/components/pro/RichTextEditor/ContextMenu.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef, useCallback } from 'react';\nimport type { Editor } from '@tiptap/react';\nimport type { RichTextEditorLabels } from './types';\nimport { defaultLabels } from './types';\nimport { getNextFloatZIndex } from './extensions/FloatingDialog';\n\ninterface ContextMenuProps {\n editor: Editor;\n labels?: RichTextEditorLabels;\n onAIClick?: () => void;\n}\n\ninterface MenuItem {\n label: string;\n icon?: string;\n action: () => void;\n disabled?: boolean;\n divider?: boolean;\n shortcut?: string;\n}\n\nconst ContextMenu: React.FC<ContextMenuProps> = ({ editor, labels: propsLabels, onAIClick }) => {\n const labels = { ...defaultLabels, ...propsLabels };\n const [visible, setVisible] = useState(false);\n const [pos, setPos] = useState({ x: 0, y: 0 });\n const menuRef = useRef<HTMLDivElement>(null);\n\n const close = useCallback(() => setVisible(false), []);\n\n useEffect(() => {\n const editorEl = editor.view.dom;\n\n const handleContextMenu = (e: Event) => {\n const me = e as MouseEvent;\n me.preventDefault();\n\n const wrapperEl = editorEl.closest('.rte-editor-wrapper');\n if (!wrapperEl) return;\n const rect = wrapperEl.getBoundingClientRect();\n\n setPos({\n x: me.clientX - rect.left,\n y: me.clientY - rect.top,\n });\n setVisible(true);\n };\n\n editorEl.addEventListener('contextmenu', handleContextMenu);\n document.addEventListener('mousedown', (e) => {\n if (menuRef.current && !menuRef.current.contains(e.target as Node)) {\n close();\n }\n });\n document.addEventListener('keydown', (e) => {\n if (e.key === 'Escape') close();\n });\n\n return () => {\n editorEl.removeEventListener('contextmenu', handleContextMenu);\n };\n }, [editor, close]);\n\n useEffect(() => {\n if (!visible || !menuRef.current) return;\n const menu = menuRef.current;\n const wrapper = menu.parentElement;\n if (!wrapper) return;\n\n const wRect = wrapper.getBoundingClientRect();\n const mRect = menu.getBoundingClientRect();\n\n let { x, y } = pos;\n if (x + mRect.width > wRect.width) x = Math.max(0, wRect.width - mRect.width - 4);\n if (y + mRect.height > wRect.height) y = Math.max(0, y - mRect.height);\n if (x !== pos.x || y !== pos.y) setPos({ x, y });\n }, [visible]);\n\n if (!visible) return null;\n\n const hasSelection = editor.state.selection.from !== editor.state.selection.to;\n const isInTable = editor.isActive('table');\n\n const items: (MenuItem | 'divider')[] = [\n { label: 'Cut', shortcut: '⌘X', action: () => { document.execCommand('cut'); close(); }, disabled: !hasSelection },\n { label: 'Copy', shortcut: '⌘C', action: () => { document.execCommand('copy'); close(); }, disabled: !hasSelection },\n { label: 'Paste', shortcut: '⌘V', action: () => { document.execCommand('paste'); close(); } },\n { label: 'Select All', shortcut: '⌘A', action: () => { editor.chain().focus().selectAll().run(); close(); } },\n 'divider',\n { label: labels.bold || 'Bold', shortcut: '⌘B', action: () => { editor.chain().focus().toggleBold().run(); close(); } },\n { label: labels.italic || 'Italic', shortcut: '⌘I', action: () => { editor.chain().focus().toggleItalic().run(); close(); } },\n { label: labels.underline || 'Underline', shortcut: '⌘U', action: () => { editor.chain().focus().toggleUnderline().run(); close(); } },\n { label: labels.strikethrough || 'Strikethrough', action: () => { editor.chain().focus().toggleStrike().run(); close(); } },\n 'divider',\n { label: labels.link || 'Insert Link', action: () => {\n const url = window.prompt(labels.insertLinkUrl || 'Enter URL');\n if (url) editor.chain().focus().setLink({ href: url }).run();\n close();\n }},\n { label: labels.image || 'Insert Image', action: () => {\n const url = window.prompt(labels.insertImageUrl || 'Enter image URL');\n if (url) editor.chain().focus().setImage({ src: url }).run();\n close();\n }},\n { label: labels.codeBlock || 'Code Block', action: () => { editor.chain().focus().toggleNode('codeBlock', 'paragraph').run(); close(); } },\n { label: labels.blockquote || 'Blockquote', action: () => { editor.chain().focus().toggleBlockquote().run(); close(); } },\n { label: labels.horizontalRule || 'Horizontal Rule', action: () => { editor.chain().focus().setHorizontalRule().run(); close(); } },\n { label: `${labels.floatingDialog || 'Floating Dialog'} — ${labels.layoutBlock || 'Block'}`, action: () => {\n editor.chain().focus().insertContent({ type: 'floatingDialog', attrs: { title: 'Note', layout: 'block' }, content: [{ type: 'paragraph' }] }).run();\n close();\n }},\n { label: `${labels.floatingDialog || 'Floating Dialog'} — ${labels.layoutWrapLeft || 'Wrap Left'}`, action: () => {\n editor.chain().focus().insertContent({ type: 'floatingDialog', attrs: { title: 'Note', layout: 'wrap-left', width: 240 }, content: [{ type: 'paragraph' }] }).run();\n close();\n }},\n { label: `${labels.floatingDialog || 'Floating Dialog'} — ${labels.layoutWrapRight || 'Wrap Right'}`, action: () => {\n editor.chain().focus().insertContent({ type: 'floatingDialog', attrs: { title: 'Note', layout: 'wrap-right', width: 240 }, content: [{ type: 'paragraph' }] }).run();\n close();\n }},\n { label: `${labels.floatingDialog || 'Floating Dialog'} — ${labels.layoutFloat || 'Float'}`, action: () => {\n editor.chain().focus().insertContent({ type: 'floatingDialog', attrs: { title: 'Note', layout: 'float', x: 40, y: 40, zIndex: getNextFloatZIndex(editor) }, content: [{ type: 'paragraph' }] }).run();\n close();\n }},\n ];\n\n if (isInTable) {\n items.push('divider');\n items.push({ label: labels.tableAddRowAfter || 'Add Row After', action: () => { editor.chain().focus().addRowAfter().run(); close(); } });\n items.push({ label: labels.tableAddColumnAfter || 'Add Column After', action: () => { editor.chain().focus().addColumnAfter().run(); close(); } });\n items.push({ label: labels.tableDeleteRow || 'Delete Row', action: () => { editor.chain().focus().deleteRow().run(); close(); } });\n items.push({ label: labels.tableDeleteColumn || 'Delete Column', action: () => { editor.chain().focus().deleteColumn().run(); close(); } });\n items.push({ label: labels.tableMergeCells || 'Merge Cells', action: () => { editor.chain().focus().mergeCells().run(); close(); } });\n items.push({ label: labels.tableSplitCell || 'Split Cell', action: () => { editor.chain().focus().splitCell().run(); close(); } });\n }\n\n if (onAIClick) {\n items.push('divider');\n items.push({ label: `✨ ${labels.ai || 'AI Assistant'}`, action: () => { onAIClick(); close(); }, disabled: !hasSelection });\n }\n\n return (\n <div\n ref={menuRef}\n className=\"rte-context-menu\"\n style={{ left: pos.x, top: pos.y }}\n >\n {items.map((item, i) =>\n item === 'divider' ? (\n <div key={`d-${i}`} className=\"rte-context-menu__divider\" />\n ) : (\n <button\n key={i}\n type=\"button\"\n className=\"rte-context-menu__item\"\n onClick={item.action}\n disabled={item.disabled}\n >\n <span className=\"rte-context-menu__label\">{item.label}</span>\n {item.shortcut && <span className=\"rte-context-menu__shortcut\">{item.shortcut}</span>}\n </button>\n )\n )}\n </div>\n );\n};\n\nexport default ContextMenu;\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"RichTextEditor.js","names":[],"sources":["../../../../src/components/pro/RichTextEditor/RichTextEditor.tsx"],"sourcesContent":["import React, { useEffect, useCallback, useState, useRef } from 'react';\nimport { cn } from '../../../utils/cn';\nimport { useEditor, EditorContent } from '@tiptap/react';\nimport StarterKit from '@tiptap/starter-kit';\nimport Underline from '@tiptap/extension-underline';\nimport { TextStyle } from '@tiptap/extension-text-style';\nimport Color from '@tiptap/extension-color';\nimport Highlight from '@tiptap/extension-highlight';\nimport TextAlign from '@tiptap/extension-text-align';\nimport Link from '@tiptap/extension-link';\nimport { Table } from '@tiptap/extension-table';\nimport TableRow from '@tiptap/extension-table-row';\nimport TableCell from '@tiptap/extension-table-cell';\nimport TableHeader from '@tiptap/extension-table-header';\nimport Placeholder from '@tiptap/extension-placeholder';\nimport TaskList from '@tiptap/extension-task-list';\nimport TaskItem from '@tiptap/extension-task-item';\nimport Subscript from '@tiptap/extension-subscript';\nimport Superscript from '@tiptap/extension-superscript';\nimport Typography from '@tiptap/extension-typography';\nimport FontFamily from '@tiptap/extension-font-family';\n\nimport Toolbar from './Toolbar';\nimport AIRewrite from './AIRewrite';\nimport ContextMenu from './ContextMenu';\nimport CommentPanel from './CommentPanel';\nimport type { CommentPanelHandle } from './CommentPanel';\nimport CommentDialog from './CommentDialog';\nimport CommentPopover from './CommentPopover';\nimport SlashMenu from './SlashMenu';\nimport BubbleToolbar from './BubbleToolbar';\nimport BlockHandle from './BlockHandle';\nimport { MarkdownBlockExtension } from './extensions/MarkdownBlock';\nimport { CodeBlockExtension } from './extensions/CodeBlockView';\nimport FontSize from './extensions/FontSize';\nimport { ResizableImage } from './extensions/ResizableImage';\nimport { FloatingDialogExtension } from './extensions/FloatingDialog';\nimport { CommentMark } from './extensions/CommentMark';\nimport type { CommentThread } from './extensions/CommentMark';\nimport type { RichTextEditorProps } from './types';\nimport './styles.css';\n\nfunction generateId() {\n return `c_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;\n}\n\nconst RichTextEditor: React.FC<RichTextEditorProps> = ({\n content,\n value,\n onChange,\n onChangeJSON,\n placeholder = 'Start writing...',\n editable = true,\n aiConfig,\n onRequestAIConfig,\n toolbarConfig,\n aiSelectionFollowsEditor = false,\n minHeight = '200px',\n maxHeight,\n className = '',\n autofocus = false,\n labels,\n editorRef,\n showComments: initialShowComments = false,\n commentThreads: externalThreads,\n onCommentThreadsChange,\n currentUser,\n}) => {\n const [formatPainterActive, setFormatPainterActive] = useState(false);\n const [showAIPanel, setShowAIPanel] = useState(false);\n const [aiSelection, setAiSelection] = useState('');\n const [aiSelectionRange, setAiSelectionRange] = useState({ from: 0, to: 0 });\n const [showComments, setShowComments] = useState(initialShowComments);\n const [internalThreads, setInternalThreads] = useState<CommentThread[]>([]);\n const [commentDialogOpen, setCommentDialogOpen] = useState(false);\n const [commentSelectionRange, setCommentSelectionRange] = useState({ from: 0, to: 0 });\n const commentPanelRef = useRef<CommentPanelHandle>(null);\n\n const threads = externalThreads ?? internalThreads;\n const setThreads = onCommentThreadsChange ?? setInternalThreads;\n\n const editor = useEditor({\n extensions: [\n StarterKit.configure({\n codeBlock: false,\n heading: { levels: [1, 2, 3, 4, 5, 6] },\n // v3 StarterKit bundles these; explicit extensions below stay in charge.\n link: false,\n underline: false,\n }),\n Underline,\n TextStyle,\n Color,\n Highlight.configure({ multicolor: true }),\n TextAlign.configure({\n types: ['heading', 'paragraph'],\n }),\n Link.configure({\n openOnClick: false,\n autolink: true,\n HTMLAttributes: { class: 'rte-link' },\n }),\n ResizableImage.configure({ inline: false, allowBase64: true }),\n Table.configure({ resizable: true }),\n TableRow,\n TableCell,\n TableHeader,\n Placeholder.configure({ placeholder }),\n CodeBlockExtension,\n TaskList,\n TaskItem.configure({ nested: true }),\n Subscript,\n Superscript,\n Typography,\n FontFamily,\n FontSize,\n FloatingDialogExtension,\n MarkdownBlockExtension,\n CommentMark,\n ],\n content: value || content || '',\n editable,\n autofocus: autofocus ? 'end' : false,\n onUpdate: ({ editor: e }) => {\n onChange?.(e.getHTML());\n onChangeJSON?.(e.getJSON() as Record<string, unknown>);\n },\n });\n\n useEffect(() => {\n if (editorRef && editor) {\n editorRef.current = editor;\n }\n }, [editor, editorRef]);\n\n useEffect(() => {\n if (editor && value !== undefined) {\n const currentHTML = editor.getHTML();\n if (value !== currentHTML) {\n editor.commands.setContent(value, { emitUpdate: false });\n }\n }\n }, [editor, value]);\n\n useEffect(() => {\n if (editor) {\n editor.setEditable(editable);\n }\n }, [editor, editable]);\n\n const handleAIClick = useCallback(() => {\n if (!editor) return;\n const { from, to } = editor.state.selection;\n const text = from !== to\n ? editor.state.doc.textBetween(from, to, ' ')\n : '';\n setAiSelection(text);\n setAiSelectionRange({ from, to });\n setShowAIPanel(true);\n }, [editor]);\n\n const requestAddComment = useCallback(() => {\n if (!editor) return;\n const { from, to } = editor.state.selection;\n if (from === to) return;\n setCommentSelectionRange({ from, to });\n setCommentDialogOpen(true);\n }, [editor]);\n\n const handleCommentSubmit = useCallback((text: string) => {\n if (!editor) return;\n const id = generateId();\n const thread: CommentThread = {\n id,\n resolved: false,\n comments: [{\n id: generateId(),\n author: currentUser || 'User',\n text,\n createdAt: Date.now(),\n }],\n createdAt: Date.now(),\n };\n editor.chain()\n .focus()\n .setTextSelection(commentSelectionRange)\n .setComment(id)\n .run();\n setThreads([...threads, thread]);\n setCommentDialogOpen(false);\n }, [editor, commentSelectionRange, threads, setThreads, currentUser]);\n\n const handleScrollToThread = useCallback((id: string) => {\n commentPanelRef.current?.scrollToThread(id);\n }, []);\n\n if (!editor) return null;\n\n const minH = typeof minHeight === 'number' ? `${minHeight}px` : minHeight;\n const maxH = maxHeight ? (typeof maxHeight === 'number' ? `${maxHeight}px` : maxHeight) : undefined;\n\n const containerClass = cn(\n 'rte-container',\n formatPainterActive && 'rte-container--format-painter',\n className,\n );\n\n const activeCommentCount = threads.filter((t) => !t.resolved).length;\n\n const showCommentButton = toolbarConfig?.buttons?.comments ?? true;\n const toolbarEnd = showCommentButton ? (\n <div className=\"rte-toolbar__end\">\n <button\n type=\"button\"\n className={`rte-toolbar__btn rte-toolbar__comment-btn ${showComments ? 'rte-toolbar__btn--active' : ''}`}\n onClick={() => setShowComments(!showComments)}\n title=\"Toggle comments\"\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z\" />\n </svg>\n {activeCommentCount > 0 && <span className=\"rte-toolbar__comment-badge\" />}\n </button>\n </div>\n ) : null;\n\n return (\n <div className={containerClass} style={{ minHeight: minH, maxHeight: maxH }}>\n {editable && (\n <Toolbar\n editor={editor}\n config={toolbarConfig}\n labels={labels}\n hasAI={!!aiConfig}\n onAIClick={handleAIClick}\n onRequestAIConfig={onRequestAIConfig}\n onFormatPainterChange={setFormatPainterActive}\n >\n {toolbarEnd}\n </Toolbar>\n )}\n\n\n <div style={{ display: 'flex', flex: 1, overflow: 'hidden' }}>\n <div className=\"rte-editor-wrapper\" style={{ flex: 1 }}>\n <EditorContent editor={editor} className=\"rte-editor-content\" />\n {editable && <ContextMenu editor={editor} labels={labels} onAIClick={aiConfig ? handleAIClick : undefined} />}\n {editable && <SlashMenu editor={editor} />}\n {editable && <BubbleToolbar editor={editor} onAddComment={requestAddComment} />}\n {editable && <BlockHandle editor={editor} persistent />}\n <CommentPopover\n editor={editor}\n threads={threads}\n onThreadsChange={setThreads}\n showPanel={showComments}\n onOpenPanel={() => setShowComments(true)}\n onScrollToThread={handleScrollToThread}\n currentUser={currentUser}\n />\n </div>\n\n {showComments && (\n <CommentPanel\n ref={commentPanelRef}\n editor={editor}\n threads={threads}\n onThreadsChange={setThreads}\n onRequestAddComment={requestAddComment}\n currentUser={currentUser}\n />\n )}\n </div>\n\n {aiConfig && showAIPanel && (\n <AIRewrite\n editor={editor}\n aiConfig={aiConfig}\n labels={labels}\n initialSelection={aiSelection}\n selectionRange={aiSelectionRange}\n followSelection={aiSelectionFollowsEditor}\n onClose={() => setShowAIPanel(false)}\n />\n )}\n\n <CommentDialog\n open={commentDialogOpen}\n onSubmit={handleCommentSubmit}\n onClose={() => setCommentDialogOpen(false)}\n />\n </div>\n );\n};\n\nexport default RichTextEditor;\n"],"mappings":"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"}
1
+ {"version":3,"file":"RichTextEditor.js","names":["Toolbar","AIRewrite","ContextMenu","CommentPanel","CommentDialog","CommentPopover","SlashMenu","BubbleToolbar","BlockHandle","FontSize","StarterKit","Underline","Color","Highlight","TextAlign","Link","TableRow","TableCell","TableHeader","Placeholder","TaskList","TaskItem","Subscript","Superscript","Typography","FontFamily","generateId","RichTextEditor","initialShowComments","externalThreads","formatPainterActive","setFormatPainterActive","useState","showAIPanel","setShowAIPanel","aiSelection","setAiSelection","aiSelectionRange","setAiSelectionRange","showComments","setShowComments","internalThreads","setInternalThreads","commentDialogOpen","setCommentDialogOpen","commentSelectionRange","setCommentSelectionRange","commentPanelRef","useRef","threads","setThreads","onCommentThreadsChange","editor","useEditor","TextStyle","ResizableImage","Table","CodeBlockExtension","FloatingDialogExtension","MarkdownBlockExtension","CommentMark","value","content","autofocus","onChange","onChangeJSON","useEffect","editorRef","editable","handleAIClick","useCallback","text","from","to","requestAddComment","handleCommentSubmit","id","thread","currentUser","handleScrollToThread","minH","minHeight","maxH","maxHeight","containerClass","cn","className","activeCommentCount","t","toolbarEnd","toolbarConfig","aiConfig","EditorContent","aiSelectionFollowsEditor"],"sources":["../../../../src/components/pro/RichTextEditor/RichTextEditor.tsx"],"sourcesContent":["import React, { useEffect, useCallback, useState, useRef } from 'react';\nimport { cn } from '../../../utils/cn';\nimport { useEditor, EditorContent } from '@tiptap/react';\nimport StarterKit from '@tiptap/starter-kit';\nimport Underline from '@tiptap/extension-underline';\nimport { TextStyle } from '@tiptap/extension-text-style';\nimport Color from '@tiptap/extension-color';\nimport Highlight from '@tiptap/extension-highlight';\nimport TextAlign from '@tiptap/extension-text-align';\nimport Link from '@tiptap/extension-link';\nimport { Table } from '@tiptap/extension-table';\nimport TableRow from '@tiptap/extension-table-row';\nimport TableCell from '@tiptap/extension-table-cell';\nimport TableHeader from '@tiptap/extension-table-header';\nimport Placeholder from '@tiptap/extension-placeholder';\nimport TaskList from '@tiptap/extension-task-list';\nimport TaskItem from '@tiptap/extension-task-item';\nimport Subscript from '@tiptap/extension-subscript';\nimport Superscript from '@tiptap/extension-superscript';\nimport Typography from '@tiptap/extension-typography';\nimport FontFamily from '@tiptap/extension-font-family';\n\nimport Toolbar from './Toolbar';\nimport AIRewrite from './AIRewrite';\nimport ContextMenu from './ContextMenu';\nimport CommentPanel from './CommentPanel';\nimport type { CommentPanelHandle } from './CommentPanel';\nimport CommentDialog from './CommentDialog';\nimport CommentPopover from './CommentPopover';\nimport SlashMenu from './SlashMenu';\nimport BubbleToolbar from './BubbleToolbar';\nimport BlockHandle from './BlockHandle';\nimport { MarkdownBlockExtension } from './extensions/MarkdownBlock';\nimport { CodeBlockExtension } from './extensions/CodeBlockView';\nimport FontSize from './extensions/FontSize';\nimport { ResizableImage } from './extensions/ResizableImage';\nimport { FloatingDialogExtension } from './extensions/FloatingDialog';\nimport { CommentMark } from './extensions/CommentMark';\nimport type { CommentThread } from './extensions/CommentMark';\nimport type { RichTextEditorProps } from './types';\nimport './styles.css';\n\nfunction generateId() {\n return `c_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;\n}\n\nconst RichTextEditor: React.FC<RichTextEditorProps> = ({\n content,\n value,\n onChange,\n onChangeJSON,\n placeholder = 'Start writing...',\n editable = true,\n aiConfig,\n onRequestAIConfig,\n toolbarConfig,\n aiSelectionFollowsEditor = false,\n minHeight = '200px',\n maxHeight,\n className = '',\n autofocus = false,\n labels,\n editorRef,\n showComments: initialShowComments = false,\n commentThreads: externalThreads,\n onCommentThreadsChange,\n currentUser,\n}) => {\n const [formatPainterActive, setFormatPainterActive] = useState(false);\n const [showAIPanel, setShowAIPanel] = useState(false);\n const [aiSelection, setAiSelection] = useState('');\n const [aiSelectionRange, setAiSelectionRange] = useState({ from: 0, to: 0 });\n const [showComments, setShowComments] = useState(initialShowComments);\n const [internalThreads, setInternalThreads] = useState<CommentThread[]>([]);\n const [commentDialogOpen, setCommentDialogOpen] = useState(false);\n const [commentSelectionRange, setCommentSelectionRange] = useState({ from: 0, to: 0 });\n const commentPanelRef = useRef<CommentPanelHandle>(null);\n\n const threads = externalThreads ?? internalThreads;\n const setThreads = onCommentThreadsChange ?? setInternalThreads;\n\n const editor = useEditor({\n extensions: [\n StarterKit.configure({\n codeBlock: false,\n heading: { levels: [1, 2, 3, 4, 5, 6] },\n // v3 StarterKit bundles these; explicit extensions below stay in charge.\n link: false,\n underline: false,\n }),\n Underline,\n TextStyle,\n Color,\n Highlight.configure({ multicolor: true }),\n TextAlign.configure({\n types: ['heading', 'paragraph'],\n }),\n Link.configure({\n openOnClick: false,\n autolink: true,\n HTMLAttributes: { class: 'rte-link' },\n }),\n ResizableImage.configure({ inline: false, allowBase64: true }),\n Table.configure({ resizable: true }),\n TableRow,\n TableCell,\n TableHeader,\n Placeholder.configure({ placeholder }),\n CodeBlockExtension,\n TaskList,\n TaskItem.configure({ nested: true }),\n Subscript,\n Superscript,\n Typography,\n FontFamily,\n FontSize,\n FloatingDialogExtension,\n MarkdownBlockExtension,\n CommentMark,\n ],\n content: value || content || '',\n editable,\n autofocus: autofocus ? 'end' : false,\n onUpdate: ({ editor: e }) => {\n onChange?.(e.getHTML());\n onChangeJSON?.(e.getJSON() as Record<string, unknown>);\n },\n });\n\n useEffect(() => {\n if (editorRef && editor) {\n editorRef.current = editor;\n }\n }, [editor, editorRef]);\n\n useEffect(() => {\n if (editor && value !== undefined) {\n const currentHTML = editor.getHTML();\n if (value !== currentHTML) {\n editor.commands.setContent(value, { emitUpdate: false });\n }\n }\n }, [editor, value]);\n\n useEffect(() => {\n if (editor) {\n editor.setEditable(editable);\n }\n }, [editor, editable]);\n\n const handleAIClick = useCallback(() => {\n if (!editor) return;\n const { from, to } = editor.state.selection;\n const text = from !== to\n ? editor.state.doc.textBetween(from, to, ' ')\n : '';\n setAiSelection(text);\n setAiSelectionRange({ from, to });\n setShowAIPanel(true);\n }, [editor]);\n\n const requestAddComment = useCallback(() => {\n if (!editor) return;\n const { from, to } = editor.state.selection;\n if (from === to) return;\n setCommentSelectionRange({ from, to });\n setCommentDialogOpen(true);\n }, [editor]);\n\n const handleCommentSubmit = useCallback((text: string) => {\n if (!editor) return;\n const id = generateId();\n const thread: CommentThread = {\n id,\n resolved: false,\n comments: [{\n id: generateId(),\n author: currentUser || 'User',\n text,\n createdAt: Date.now(),\n }],\n createdAt: Date.now(),\n };\n editor.chain()\n .focus()\n .setTextSelection(commentSelectionRange)\n .setComment(id)\n .run();\n setThreads([...threads, thread]);\n setCommentDialogOpen(false);\n }, [editor, commentSelectionRange, threads, setThreads, currentUser]);\n\n const handleScrollToThread = useCallback((id: string) => {\n commentPanelRef.current?.scrollToThread(id);\n }, []);\n\n if (!editor) return null;\n\n const minH = typeof minHeight === 'number' ? `${minHeight}px` : minHeight;\n const maxH = maxHeight ? (typeof maxHeight === 'number' ? `${maxHeight}px` : maxHeight) : undefined;\n\n const containerClass = cn(\n 'rte-container',\n formatPainterActive && 'rte-container--format-painter',\n className,\n );\n\n const activeCommentCount = threads.filter((t) => !t.resolved).length;\n\n const showCommentButton = toolbarConfig?.buttons?.comments ?? true;\n const toolbarEnd = showCommentButton ? (\n <div className=\"rte-toolbar__end\">\n <button\n type=\"button\"\n className={`rte-toolbar__btn rte-toolbar__comment-btn ${showComments ? 'rte-toolbar__btn--active' : ''}`}\n onClick={() => setShowComments(!showComments)}\n title=\"Toggle comments\"\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z\" />\n </svg>\n {activeCommentCount > 0 && <span className=\"rte-toolbar__comment-badge\" />}\n </button>\n </div>\n ) : null;\n\n return (\n <div className={containerClass} style={{ minHeight: minH, maxHeight: maxH }}>\n {editable && (\n <Toolbar\n editor={editor}\n config={toolbarConfig}\n labels={labels}\n hasAI={!!aiConfig}\n onAIClick={handleAIClick}\n onRequestAIConfig={onRequestAIConfig}\n onFormatPainterChange={setFormatPainterActive}\n >\n {toolbarEnd}\n </Toolbar>\n )}\n\n\n <div style={{ display: 'flex', flex: 1, overflow: 'hidden' }}>\n <div className=\"rte-editor-wrapper\" style={{ flex: 1 }}>\n <EditorContent editor={editor} className=\"rte-editor-content\" />\n {editable && <ContextMenu editor={editor} labels={labels} onAIClick={aiConfig ? handleAIClick : undefined} />}\n {editable && <SlashMenu editor={editor} />}\n {editable && <BubbleToolbar editor={editor} onAddComment={requestAddComment} />}\n {editable && <BlockHandle editor={editor} persistent />}\n <CommentPopover\n editor={editor}\n threads={threads}\n onThreadsChange={setThreads}\n showPanel={showComments}\n onOpenPanel={() => setShowComments(true)}\n onScrollToThread={handleScrollToThread}\n currentUser={currentUser}\n />\n </div>\n\n {showComments && (\n <CommentPanel\n ref={commentPanelRef}\n editor={editor}\n threads={threads}\n onThreadsChange={setThreads}\n onRequestAddComment={requestAddComment}\n currentUser={currentUser}\n />\n )}\n </div>\n\n {aiConfig && showAIPanel && (\n <AIRewrite\n editor={editor}\n aiConfig={aiConfig}\n labels={labels}\n initialSelection={aiSelection}\n selectionRange={aiSelectionRange}\n followSelection={aiSelectionFollowsEditor}\n onClose={() => setShowAIPanel(false)}\n />\n )}\n\n <CommentDialog\n open={commentDialogOpen}\n onSubmit={handleCommentSubmit}\n onClose={() => setCommentDialogOpen(false)}\n />\n </div>\n );\n};\n\nexport default RichTextEditor;\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"SlashMenu.js","names":[],"sources":["../../../../src/components/pro/RichTextEditor/SlashMenu.tsx"],"sourcesContent":["import React, { useState, useEffect, useLayoutEffect, useRef, useCallback } from 'react';\nimport type { Editor } from '@tiptap/react';\nimport type { ChainedCommands } from '@tiptap/core';\nimport { TextSelection } from '@tiptap/pm/state';\n\ninterface SlashMenuItem {\n label: string;\n icon: string;\n description: string;\n action: (chain: ChainedCommands) => ChainedCommands;\n keywords?: string[];\n}\n\nconst SLASH_ITEMS: SlashMenuItem[] = [\n { label: 'Text', icon: 'Aa', description: 'Plain text', keywords: ['paragraph', 'text', 'plain'],\n action: (e) => e.setParagraph() },\n { label: 'Heading 1', icon: 'H1', description: 'Large heading', keywords: ['h1', 'title'],\n action: (e) => e.setHeading({ level: 1 }) },\n { label: 'Heading 2', icon: 'H2', description: 'Medium heading', keywords: ['h2', 'subtitle'],\n action: (e) => e.setHeading({ level: 2 }) },\n { label: 'Heading 3', icon: 'H3', description: 'Small heading', keywords: ['h3'],\n action: (e) => e.setHeading({ level: 3 }) },\n { label: 'Bullet List', icon: '•', description: 'Unordered list', keywords: ['ul', 'bullet', 'unordered'],\n action: (e) => e.toggleBulletList() },\n { label: 'Numbered List', icon: '1.', description: 'Ordered list', keywords: ['ol', 'ordered', 'number'],\n action: (e) => e.toggleOrderedList() },\n { label: 'Task List', icon: '☑', description: 'To-do list', keywords: ['todo', 'checkbox', 'task'],\n action: (e) => e.toggleTaskList() },\n { label: 'Blockquote', icon: '\"', description: 'Quote block', keywords: ['quote', 'blockquote'],\n action: (e) => e.toggleBlockquote() },\n { label: 'Code Block', icon: '</>', description: 'Code snippet', keywords: ['code', 'pre', 'snippet'],\n action: (e) => e.setNode('codeBlock') },\n { label: 'Divider', icon: '—', description: 'Horizontal rule', keywords: ['hr', 'divider', 'separator', 'line'],\n action: (e) => e.setHorizontalRule() },\n { label: 'Table', icon: '⊞', description: 'Insert 3×3 table', keywords: ['table', 'grid'],\n action: (e) => e.insertTable({ rows: 3, cols: 3, withHeaderRow: true }) },\n { label: 'Image', icon: '🖼', description: 'Insert image by URL', keywords: ['image', 'picture', 'photo'],\n action: (e) => e},\n];\n\ninterface SlashRange {\n from: number;\n to: number;\n query: string;\n}\n\ninterface SlashMenuProps {\n editor: Editor;\n}\n\nconst SlashMenu: React.FC<SlashMenuProps> = ({ editor }) => {\n const [visible, setVisible] = useState(false);\n const [renderedRange, setRenderedRange] = useState<SlashRange | null>(null);\n const query = renderedRange?.query ?? '';\n const [pos, setPos] = useState({ x: 0, y: 0 });\n const [selected, setSelected] = useState(0);\n const menuRef = useRef<HTMLDivElement>(null);\n const activeRange = useRef<SlashRange | null>(null);\n const dismissed = useRef<string | null>(null);\n const composing = useRef(false);\n\n const getRange = useCallback(() => {\n if (editor.isDestroyed || !editor.isEditable || editor.view.composing || composing.current) return null;\n const selection = editor.state.selection;\n if (!(selection instanceof TextSelection) || !selection.empty || selection.$from.parent.type.spec.code || selection.$from.marks().some((mark) => mark.type.spec.code)) return null;\n const { $from } = selection;\n // textContent drops inline atoms and hard breaks, so its offsets are not document offsets.\n const text = $from.parent.textBetween(0, $from.parentOffset, '\\n', (node) => node.type.name === 'hardBreak' ? '\\n' : '\\ufffc');\n const match = /(?:^|\\s)\\/([^\\s/]*)$/.exec(text);\n if (!match) return null;\n return { from: $from.pos - match[1].length - 1, to: $from.pos, query: match[1] };\n }, [editor]);\n\n const filtered = query\n ? SLASH_ITEMS.filter((item) => {\n const q = query.toLowerCase();\n return item.label.toLowerCase().includes(q)\n || item.description.toLowerCase().includes(q)\n || item.keywords?.some((k) => k.includes(q));\n })\n : SLASH_ITEMS;\n\n const close = useCallback(() => {\n setVisible(false);\n setRenderedRange(null);\n const range = activeRange.current;\n if (range) dismissed.current = `${range.from}:${range.to}:${range.query}`;\n activeRange.current = null;\n setSelected(0);\n }, []);\n\n const executeItem = useCallback((item: SlashMenuItem) => {\n const range = getRange();\n const active = activeRange.current;\n // Transactions update the ref before React commits the new menu. An old\n // rendered action must not operate on that newer trigger/selection.\n if (!range || !active || !renderedRange\n || range.from !== renderedRange.from || range.to !== renderedRange.to || range.query !== renderedRange.query\n || range.from !== active.from || range.to !== active.to || range.query !== active.query) {\n close();\n return;\n }\n const url = item.label === 'Image' ? window.prompt('Image URL:')?.trim() : undefined;\n if (item.label === 'Image' && !url) { close(); return; }\n close();\n // Delete the trigger and insert/convert in one transaction (one undo step).\n const chain = editor.chain().focus().deleteRange(range);\n (url ? chain.setImage({ src: url }) : item.action(chain)).run();\n }, [editor, getRange, close, renderedRange]);\n\n useEffect(() => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const handleUpdate = () => {\n const range = editor.isFocused ? getRange() : null;\n if (!range) {\n activeRange.current = null;\n dismissed.current = null;\n setVisible(false);\n return;\n }\n if (dismissed.current === `${range.from}:${range.to}:${range.query}`) return;\n if (activeRange.current?.query !== range.query || activeRange.current?.from !== range.from) setSelected(0);\n activeRange.current = range;\n setRenderedRange(range);\n setVisible(true);\n };\n const start = () => { composing.current = true; close(); };\n const end = () => {\n composing.current = false;\n dismissed.current = null;\n timer = setTimeout(handleUpdate, 0);\n };\n const dom = editor.view.dom;\n editor.on('transaction', handleUpdate);\n editor.on('blur', close);\n dom.addEventListener('compositionstart', start);\n dom.addEventListener('compositionend', end);\n return () => {\n clearTimeout(timer);\n editor.off('transaction', handleUpdate);\n editor.off('blur', close);\n dom.removeEventListener('compositionstart', start);\n dom.removeEventListener('compositionend', end);\n };\n }, [editor, getRange, close]);\n\n useLayoutEffect(() => {\n if (!visible || !filtered.length) return;\n const wrapper = editor.view.dom.closest('.rte-editor-wrapper') as HTMLElement | null;\n const menu = menuRef.current;\n if (!wrapper || !menu) return;\n const place = () => {\n const range = getRange();\n if (!range) { close(); return; }\n const coords = editor.view.coordsAtPos(range.to);\n const rect = wrapper.getBoundingClientRect();\n const left = Math.max(8, rect.left + wrapper.clientLeft);\n const right = Math.min(window.innerWidth - 8, rect.right);\n const top = Math.max(8, rect.top + wrapper.clientTop);\n const bottom = Math.min(window.innerHeight - 8, rect.bottom);\n // Keep partially visible edge anchors usable, but never leave an\n // offscreen menu intercepting the editor's Enter/arrow keys.\n if (right <= left || bottom <= top || coords.bottom < top || coords.top > bottom) {\n close();\n return;\n }\n const anchorTop = Math.min(Math.max(coords.top, top), bottom);\n const anchorBottom = Math.min(Math.max(coords.bottom, top), bottom);\n menu.style.boxSizing = 'border-box';\n menu.style.minWidth = '0';\n menu.style.width = `${Math.min(280, right - left)}px`;\n const below = bottom - anchorBottom - 4;\n const above = anchorTop - top - 4;\n const flip = below < Math.min(300, menu.scrollHeight) && above > below;\n const availableHeight = flip ? above : below;\n if (availableHeight <= 0) { close(); return; }\n menu.style.maxHeight = `${Math.min(300, availableHeight)}px`;\n const x = Math.max(left, Math.min(coords.left, right - menu.offsetWidth));\n const y = flip ? anchorTop - menu.offsetHeight - 4 : anchorBottom + 4;\n setPos({ x: x - rect.left - wrapper.clientLeft + wrapper.scrollLeft,\n y: y - rect.top - wrapper.clientTop + wrapper.scrollTop });\n };\n place();\n window.addEventListener('scroll', place, true);\n window.addEventListener('resize', place);\n editor.on('transaction', place);\n return () => {\n window.removeEventListener('scroll', place, true);\n window.removeEventListener('resize', place);\n editor.off('transaction', place);\n };\n }, [editor, visible, filtered.length, getRange, close]);\n\n useEffect(() => {\n if (!visible) return;\n const menu = menuRef.current;\n const item = menu?.children[selected] as HTMLElement | undefined;\n if (!menu || !item) return;\n if (item.offsetTop < menu.scrollTop) menu.scrollTop = item.offsetTop;\n else if (item.offsetTop + item.offsetHeight > menu.scrollTop + menu.clientHeight) {\n menu.scrollTop = item.offsetTop + item.offsetHeight - menu.clientHeight;\n }\n }, [selected, visible]);\n\n useEffect(() => {\n if (!visible) return;\n const handleKeyDown = (e: KeyboardEvent) => {\n if (!editor.view.dom.contains(e.target as Node) || !editor.isFocused || e.isComposing || e.keyCode === 229 || editor.view.composing || composing.current || e.ctrlKey || e.metaKey || e.altKey || e.shiftKey) return;\n if (!filtered.length && e.key !== 'Escape') return;\n if (['ArrowDown', 'ArrowUp', 'Enter', 'Escape'].includes(e.key)) e.stopImmediatePropagation();\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n setSelected((s) => (s + 1) % filtered.length);\n } else if (e.key === 'ArrowUp') {\n e.preventDefault();\n setSelected((s) => (s - 1 + filtered.length) % filtered.length);\n } else if (e.key === 'Enter') {\n e.preventDefault();\n if (filtered[selected]) executeItem(filtered[selected]);\n } else if (e.key === 'Escape') {\n e.preventDefault();\n close();\n }\n };\n document.addEventListener('keydown', handleKeyDown, true);\n return () => document.removeEventListener('keydown', handleKeyDown, true);\n }, [editor, visible, filtered, selected, executeItem, close]);\n\n useEffect(() => {\n if (!visible) return;\n const handler = (e: MouseEvent) => {\n if (menuRef.current && !menuRef.current.contains(e.target as Node)) close();\n };\n document.addEventListener('mousedown', handler);\n return () => document.removeEventListener('mousedown', handler);\n }, [visible, close]);\n\n if (!visible || filtered.length === 0) return null;\n\n return (\n <div ref={menuRef} className=\"rte-slash-menu\" role=\"menu\" aria-label=\"Insert block\" style={{ left: pos.x, top: pos.y }} onMouseDown={(e) => e.preventDefault()}>\n {filtered.map((item, i) => (\n <button\n key={item.label}\n type=\"button\"\n role=\"menuitem\"\n tabIndex={-1}\n className={`rte-slash-menu__item ${i === selected ? 'rte-slash-menu__item--active' : ''}`}\n onClick={() => executeItem(item)}\n onMouseEnter={() => setSelected(i)}\n >\n <span className=\"rte-slash-menu__icon\">{item.icon}</span>\n <div className=\"rte-slash-menu__text\">\n <span className=\"rte-slash-menu__label\">{item.label}</span>\n <span className=\"rte-slash-menu__desc\">{item.description}</span>\n </div>\n </button>\n ))}\n </div>\n );\n};\n\nexport default SlashMenu;\n"],"mappings":"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"}
1
+ {"version":3,"file":"SlashMenu.js","names":["SLASH_ITEMS","SlashMenu","visible","setVisible","useState","renderedRange","setRenderedRange","query","pos","setPos","selected","setSelected","menuRef","useRef","activeRange","dismissed","composing","getRange","useCallback","editor","selection","TextSelection","mark","text","$from","node","match","filtered","q","item","k","close","range","executeItem","active","url","chain","useEffect","timer","handleUpdate","start","end","dom","useLayoutEffect","wrapper","menu","place","coords","rect","left","right","top","bottom","anchorTop","anchorBottom","below","above","flip","availableHeight","x","y","handleKeyDown","s","handler","i"],"sources":["../../../../src/components/pro/RichTextEditor/SlashMenu.tsx"],"sourcesContent":["import React, { useState, useEffect, useLayoutEffect, useRef, useCallback } from 'react';\nimport type { Editor } from '@tiptap/react';\nimport type { ChainedCommands } from '@tiptap/core';\nimport { TextSelection } from '@tiptap/pm/state';\n\ninterface SlashMenuItem {\n label: string;\n icon: string;\n description: string;\n action: (chain: ChainedCommands) => ChainedCommands;\n keywords?: string[];\n}\n\nconst SLASH_ITEMS: SlashMenuItem[] = [\n { label: 'Text', icon: 'Aa', description: 'Plain text', keywords: ['paragraph', 'text', 'plain'],\n action: (e) => e.setParagraph() },\n { label: 'Heading 1', icon: 'H1', description: 'Large heading', keywords: ['h1', 'title'],\n action: (e) => e.setHeading({ level: 1 }) },\n { label: 'Heading 2', icon: 'H2', description: 'Medium heading', keywords: ['h2', 'subtitle'],\n action: (e) => e.setHeading({ level: 2 }) },\n { label: 'Heading 3', icon: 'H3', description: 'Small heading', keywords: ['h3'],\n action: (e) => e.setHeading({ level: 3 }) },\n { label: 'Bullet List', icon: '•', description: 'Unordered list', keywords: ['ul', 'bullet', 'unordered'],\n action: (e) => e.toggleBulletList() },\n { label: 'Numbered List', icon: '1.', description: 'Ordered list', keywords: ['ol', 'ordered', 'number'],\n action: (e) => e.toggleOrderedList() },\n { label: 'Task List', icon: '☑', description: 'To-do list', keywords: ['todo', 'checkbox', 'task'],\n action: (e) => e.toggleTaskList() },\n { label: 'Blockquote', icon: '\"', description: 'Quote block', keywords: ['quote', 'blockquote'],\n action: (e) => e.toggleBlockquote() },\n { label: 'Code Block', icon: '</>', description: 'Code snippet', keywords: ['code', 'pre', 'snippet'],\n action: (e) => e.setNode('codeBlock') },\n { label: 'Divider', icon: '—', description: 'Horizontal rule', keywords: ['hr', 'divider', 'separator', 'line'],\n action: (e) => e.setHorizontalRule() },\n { label: 'Table', icon: '⊞', description: 'Insert 3×3 table', keywords: ['table', 'grid'],\n action: (e) => e.insertTable({ rows: 3, cols: 3, withHeaderRow: true }) },\n { label: 'Image', icon: '🖼', description: 'Insert image by URL', keywords: ['image', 'picture', 'photo'],\n action: (e) => e},\n];\n\ninterface SlashRange {\n from: number;\n to: number;\n query: string;\n}\n\ninterface SlashMenuProps {\n editor: Editor;\n}\n\nconst SlashMenu: React.FC<SlashMenuProps> = ({ editor }) => {\n const [visible, setVisible] = useState(false);\n const [renderedRange, setRenderedRange] = useState<SlashRange | null>(null);\n const query = renderedRange?.query ?? '';\n const [pos, setPos] = useState({ x: 0, y: 0 });\n const [selected, setSelected] = useState(0);\n const menuRef = useRef<HTMLDivElement>(null);\n const activeRange = useRef<SlashRange | null>(null);\n const dismissed = useRef<string | null>(null);\n const composing = useRef(false);\n\n const getRange = useCallback(() => {\n if (editor.isDestroyed || !editor.isEditable || editor.view.composing || composing.current) return null;\n const selection = editor.state.selection;\n if (!(selection instanceof TextSelection) || !selection.empty || selection.$from.parent.type.spec.code || selection.$from.marks().some((mark) => mark.type.spec.code)) return null;\n const { $from } = selection;\n // textContent drops inline atoms and hard breaks, so its offsets are not document offsets.\n const text = $from.parent.textBetween(0, $from.parentOffset, '\\n', (node) => node.type.name === 'hardBreak' ? '\\n' : '\\ufffc');\n const match = /(?:^|\\s)\\/([^\\s/]*)$/.exec(text);\n if (!match) return null;\n return { from: $from.pos - match[1].length - 1, to: $from.pos, query: match[1] };\n }, [editor]);\n\n const filtered = query\n ? SLASH_ITEMS.filter((item) => {\n const q = query.toLowerCase();\n return item.label.toLowerCase().includes(q)\n || item.description.toLowerCase().includes(q)\n || item.keywords?.some((k) => k.includes(q));\n })\n : SLASH_ITEMS;\n\n const close = useCallback(() => {\n setVisible(false);\n setRenderedRange(null);\n const range = activeRange.current;\n if (range) dismissed.current = `${range.from}:${range.to}:${range.query}`;\n activeRange.current = null;\n setSelected(0);\n }, []);\n\n const executeItem = useCallback((item: SlashMenuItem) => {\n const range = getRange();\n const active = activeRange.current;\n // Transactions update the ref before React commits the new menu. An old\n // rendered action must not operate on that newer trigger/selection.\n if (!range || !active || !renderedRange\n || range.from !== renderedRange.from || range.to !== renderedRange.to || range.query !== renderedRange.query\n || range.from !== active.from || range.to !== active.to || range.query !== active.query) {\n close();\n return;\n }\n const url = item.label === 'Image' ? window.prompt('Image URL:')?.trim() : undefined;\n if (item.label === 'Image' && !url) { close(); return; }\n close();\n // Delete the trigger and insert/convert in one transaction (one undo step).\n const chain = editor.chain().focus().deleteRange(range);\n (url ? chain.setImage({ src: url }) : item.action(chain)).run();\n }, [editor, getRange, close, renderedRange]);\n\n useEffect(() => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const handleUpdate = () => {\n const range = editor.isFocused ? getRange() : null;\n if (!range) {\n activeRange.current = null;\n dismissed.current = null;\n setVisible(false);\n return;\n }\n if (dismissed.current === `${range.from}:${range.to}:${range.query}`) return;\n if (activeRange.current?.query !== range.query || activeRange.current?.from !== range.from) setSelected(0);\n activeRange.current = range;\n setRenderedRange(range);\n setVisible(true);\n };\n const start = () => { composing.current = true; close(); };\n const end = () => {\n composing.current = false;\n dismissed.current = null;\n timer = setTimeout(handleUpdate, 0);\n };\n const dom = editor.view.dom;\n editor.on('transaction', handleUpdate);\n editor.on('blur', close);\n dom.addEventListener('compositionstart', start);\n dom.addEventListener('compositionend', end);\n return () => {\n clearTimeout(timer);\n editor.off('transaction', handleUpdate);\n editor.off('blur', close);\n dom.removeEventListener('compositionstart', start);\n dom.removeEventListener('compositionend', end);\n };\n }, [editor, getRange, close]);\n\n useLayoutEffect(() => {\n if (!visible || !filtered.length) return;\n const wrapper = editor.view.dom.closest('.rte-editor-wrapper') as HTMLElement | null;\n const menu = menuRef.current;\n if (!wrapper || !menu) return;\n const place = () => {\n const range = getRange();\n if (!range) { close(); return; }\n const coords = editor.view.coordsAtPos(range.to);\n const rect = wrapper.getBoundingClientRect();\n const left = Math.max(8, rect.left + wrapper.clientLeft);\n const right = Math.min(window.innerWidth - 8, rect.right);\n const top = Math.max(8, rect.top + wrapper.clientTop);\n const bottom = Math.min(window.innerHeight - 8, rect.bottom);\n // Keep partially visible edge anchors usable, but never leave an\n // offscreen menu intercepting the editor's Enter/arrow keys.\n if (right <= left || bottom <= top || coords.bottom < top || coords.top > bottom) {\n close();\n return;\n }\n const anchorTop = Math.min(Math.max(coords.top, top), bottom);\n const anchorBottom = Math.min(Math.max(coords.bottom, top), bottom);\n menu.style.boxSizing = 'border-box';\n menu.style.minWidth = '0';\n menu.style.width = `${Math.min(280, right - left)}px`;\n const below = bottom - anchorBottom - 4;\n const above = anchorTop - top - 4;\n const flip = below < Math.min(300, menu.scrollHeight) && above > below;\n const availableHeight = flip ? above : below;\n if (availableHeight <= 0) { close(); return; }\n menu.style.maxHeight = `${Math.min(300, availableHeight)}px`;\n const x = Math.max(left, Math.min(coords.left, right - menu.offsetWidth));\n const y = flip ? anchorTop - menu.offsetHeight - 4 : anchorBottom + 4;\n setPos({ x: x - rect.left - wrapper.clientLeft + wrapper.scrollLeft,\n y: y - rect.top - wrapper.clientTop + wrapper.scrollTop });\n };\n place();\n window.addEventListener('scroll', place, true);\n window.addEventListener('resize', place);\n editor.on('transaction', place);\n return () => {\n window.removeEventListener('scroll', place, true);\n window.removeEventListener('resize', place);\n editor.off('transaction', place);\n };\n }, [editor, visible, filtered.length, getRange, close]);\n\n useEffect(() => {\n if (!visible) return;\n const menu = menuRef.current;\n const item = menu?.children[selected] as HTMLElement | undefined;\n if (!menu || !item) return;\n if (item.offsetTop < menu.scrollTop) menu.scrollTop = item.offsetTop;\n else if (item.offsetTop + item.offsetHeight > menu.scrollTop + menu.clientHeight) {\n menu.scrollTop = item.offsetTop + item.offsetHeight - menu.clientHeight;\n }\n }, [selected, visible]);\n\n useEffect(() => {\n if (!visible) return;\n const handleKeyDown = (e: KeyboardEvent) => {\n if (!editor.view.dom.contains(e.target as Node) || !editor.isFocused || e.isComposing || e.keyCode === 229 || editor.view.composing || composing.current || e.ctrlKey || e.metaKey || e.altKey || e.shiftKey) return;\n if (!filtered.length && e.key !== 'Escape') return;\n if (['ArrowDown', 'ArrowUp', 'Enter', 'Escape'].includes(e.key)) e.stopImmediatePropagation();\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n setSelected((s) => (s + 1) % filtered.length);\n } else if (e.key === 'ArrowUp') {\n e.preventDefault();\n setSelected((s) => (s - 1 + filtered.length) % filtered.length);\n } else if (e.key === 'Enter') {\n e.preventDefault();\n if (filtered[selected]) executeItem(filtered[selected]);\n } else if (e.key === 'Escape') {\n e.preventDefault();\n close();\n }\n };\n document.addEventListener('keydown', handleKeyDown, true);\n return () => document.removeEventListener('keydown', handleKeyDown, true);\n }, [editor, visible, filtered, selected, executeItem, close]);\n\n useEffect(() => {\n if (!visible) return;\n const handler = (e: MouseEvent) => {\n if (menuRef.current && !menuRef.current.contains(e.target as Node)) close();\n };\n document.addEventListener('mousedown', handler);\n return () => document.removeEventListener('mousedown', handler);\n }, [visible, close]);\n\n if (!visible || filtered.length === 0) return null;\n\n return (\n <div ref={menuRef} className=\"rte-slash-menu\" role=\"menu\" aria-label=\"Insert block\" style={{ left: pos.x, top: pos.y }} onMouseDown={(e) => e.preventDefault()}>\n {filtered.map((item, i) => (\n <button\n key={item.label}\n type=\"button\"\n role=\"menuitem\"\n tabIndex={-1}\n className={`rte-slash-menu__item ${i === selected ? 'rte-slash-menu__item--active' : ''}`}\n onClick={() => executeItem(item)}\n onMouseEnter={() => setSelected(i)}\n >\n <span className=\"rte-slash-menu__icon\">{item.icon}</span>\n <div className=\"rte-slash-menu__text\">\n <span className=\"rte-slash-menu__label\">{item.label}</span>\n <span className=\"rte-slash-menu__desc\">{item.description}</span>\n </div>\n </button>\n ))}\n </div>\n );\n};\n\nexport default SlashMenu;\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ColorPicker.js","names":[],"sources":["../../../../../src/components/pro/RichTextEditor/Toolbar/ColorPicker.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect, useId } from 'react';\nimport { createPortal } from 'react-dom';\nimport { useAnchoredDropdown } from './useAnchoredDropdown';\n\ninterface ColorPickerProps {\n value: string;\n onChange: (color: string) => void;\n title?: string;\n icon?: React.ReactNode;\n kind?: 'text' | 'highlight';\n /** Button class; defaults to the classic toolbar button. Bubble toolbar passes its own. */\n buttonClassName?: string;\n /** Portals the palette outside scroll-clipped bubble toolbars. */\n portalOwner?: string;\n}\n\nconst COLORS = [\n '#000000', '#434343', '#666666', '#999999', '#cccccc', '#eeeeee', '#ffffff',\n '#ff0000', '#ff4500', '#ff8c00', '#ffd700', '#32cd32', '#00bfff', '#8a2be2',\n '#ff69b4', '#dc143c', '#ff6347', '#ffa500', '#9acd32', '#20b2aa', '#4169e1',\n '#9370db', '#db7093', '#b22222', '#d2691e', '#daa520', '#228b22', '#008b8b',\n '#191970', '#4b0082',\n];\n\nexport const ColorPicker: React.FC<ColorPickerProps> = ({ value, onChange, title, icon, kind = 'text', buttonClassName = 'rte-toolbar__btn', portalOwner }) => {\n const [isOpen, setIsOpen] = useState(false);\n const [paletteTheme, setPaletteTheme] = useState<React.CSSProperties>({});\n const ref = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLButtonElement>(null);\n const paletteRef = useRef<HTMLDivElement>(null);\n const paletteId = useId();\n const dropdownStyle = useAnchoredDropdown(isOpen, triggerRef, paletteRef);\n const label = title || (kind === 'text' ? 'Text color' : 'Highlight color');\n const description = `${label}: ${value || (kind === 'text' ? 'Default' : 'None')}`;\n\n useEffect(() => {\n const handler = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node) && !paletteRef.current?.contains(e.target as Node)) {\n setIsOpen(false);\n }\n };\n document.addEventListener('mousedown', handler);\n return () => document.removeEventListener('mousedown', handler);\n }, [ref, paletteRef]);\n\n const palette = isOpen && (\n <div ref={paletteRef} id={paletteId} data-rte-palette-owner={portalOwner}\n className=\"rte-toolbar__color-dropdown\" role=\"group\" aria-label={label}\n style={{ ...dropdownStyle, ...paletteTheme }}>\n {COLORS.map((color) => (\n <button key={color} type=\"button\"\n className={`rte-toolbar__color-swatch ${color === value ? 'rte-toolbar__color-swatch--active' : ''}`}\n style={{ backgroundColor: color }}\n onMouseDown={portalOwner ? event => event.preventDefault() : undefined}\n onClick={() => { onChange(color); setIsOpen(false); }}\n title={`${label}: ${color}`} aria-label={`${label}: ${color}`}\n aria-pressed={color.toLowerCase() === value.toLowerCase()} />\n ))}\n <button type=\"button\" className=\"rte-toolbar__color-clear\"\n onMouseDown={portalOwner ? event => event.preventDefault() : undefined}\n onClick={() => { onChange(''); setIsOpen(false); }}\n title={`Clear ${label}`} aria-label={`Clear ${label}`} aria-pressed={!value}>Clear</button>\n </div>\n );\n\n return (\n <div ref={ref} className=\"rte-toolbar__color-picker\"\n onBlur={(event) => {\n if (!event.currentTarget.contains(event.relatedTarget) && !paletteRef.current?.contains(event.relatedTarget)) setIsOpen(false);\n }}\n onKeyDown={(event) => {\n if (event.key === 'Escape' && isOpen) {\n event.preventDefault();\n event.stopPropagation();\n setIsOpen(false);\n triggerRef.current?.focus();\n }\n }}>\n <button\n type=\"button\"\n ref={triggerRef}\n className={`${buttonClassName} rte-toolbar__color-trigger`}\n onMouseDown={portalOwner ? event => event.preventDefault() : undefined}\n onClick={event => {\n if (portalOwner && !isOpen) {\n const computed = getComputedStyle(event.currentTarget);\n const variables: Record<string, string> = {};\n for (const name of ['--rte-bg', '--rte-text', '--rte-border', '--rte-placeholder', '--rte-active-color', '--rte-toolbar-btn-hover']) {\n variables[name] = computed.getPropertyValue(name);\n }\n setPaletteTheme(variables);\n }\n setIsOpen(!isOpen);\n }}\n title={description}\n aria-label={description}\n aria-expanded={isOpen}\n aria-controls={isOpen ? paletteId : undefined}\n >\n <span className={`rte-toolbar__color-icon rte-toolbar__color-icon--${kind}`} aria-hidden=\"true\">\n {icon || (kind === 'text' ? <span className=\"rte-toolbar__color-letter\">A</span> : (\n <svg width=\"18\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"m14 3 7 7-9 9-7-7zM5 12l-2 7 2 2 7-2M14 7l3 3M3 21h6\" />\n </svg>\n ))}\n <span\n className={`rte-toolbar__color-indicator${value ? '' : ' rte-toolbar__color-indicator--empty'}`}\n style={{ backgroundColor: value || undefined }}\n />\n </span>\n </button>\n {portalOwner && typeof document !== 'undefined' ? createPortal(palette, document.body) : palette}\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"ColorPicker.js","names":["COLORS","ColorPicker","isOpen","setIsOpen","useState","paletteTheme","setPaletteTheme","ref","useRef","triggerRef","paletteRef","paletteId","useId","dropdownStyle","useAnchoredDropdown","label","title","kind","description","value","handler","palette","portalOwner","color","event","onChange","buttonClassName","computed","variables","name","icon","createPortal"],"sources":["../../../../../src/components/pro/RichTextEditor/Toolbar/ColorPicker.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect, useId } from 'react';\nimport { createPortal } from 'react-dom';\nimport { useAnchoredDropdown } from './useAnchoredDropdown';\n\ninterface ColorPickerProps {\n value: string;\n onChange: (color: string) => void;\n title?: string;\n icon?: React.ReactNode;\n kind?: 'text' | 'highlight';\n /** Button class; defaults to the classic toolbar button. Bubble toolbar passes its own. */\n buttonClassName?: string;\n /** Portals the palette outside scroll-clipped bubble toolbars. */\n portalOwner?: string;\n}\n\nconst COLORS = [\n '#000000', '#434343', '#666666', '#999999', '#cccccc', '#eeeeee', '#ffffff',\n '#ff0000', '#ff4500', '#ff8c00', '#ffd700', '#32cd32', '#00bfff', '#8a2be2',\n '#ff69b4', '#dc143c', '#ff6347', '#ffa500', '#9acd32', '#20b2aa', '#4169e1',\n '#9370db', '#db7093', '#b22222', '#d2691e', '#daa520', '#228b22', '#008b8b',\n '#191970', '#4b0082',\n];\n\nexport const ColorPicker: React.FC<ColorPickerProps> = ({ value, onChange, title, icon, kind = 'text', buttonClassName = 'rte-toolbar__btn', portalOwner }) => {\n const [isOpen, setIsOpen] = useState(false);\n const [paletteTheme, setPaletteTheme] = useState<React.CSSProperties>({});\n const ref = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLButtonElement>(null);\n const paletteRef = useRef<HTMLDivElement>(null);\n const paletteId = useId();\n const dropdownStyle = useAnchoredDropdown(isOpen, triggerRef, paletteRef);\n const label = title || (kind === 'text' ? 'Text color' : 'Highlight color');\n const description = `${label}: ${value || (kind === 'text' ? 'Default' : 'None')}`;\n\n useEffect(() => {\n const handler = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node) && !paletteRef.current?.contains(e.target as Node)) {\n setIsOpen(false);\n }\n };\n document.addEventListener('mousedown', handler);\n return () => document.removeEventListener('mousedown', handler);\n }, [ref, paletteRef]);\n\n const palette = isOpen && (\n <div ref={paletteRef} id={paletteId} data-rte-palette-owner={portalOwner}\n className=\"rte-toolbar__color-dropdown\" role=\"group\" aria-label={label}\n style={{ ...dropdownStyle, ...paletteTheme }}>\n {COLORS.map((color) => (\n <button key={color} type=\"button\"\n className={`rte-toolbar__color-swatch ${color === value ? 'rte-toolbar__color-swatch--active' : ''}`}\n style={{ backgroundColor: color }}\n onMouseDown={portalOwner ? event => event.preventDefault() : undefined}\n onClick={() => { onChange(color); setIsOpen(false); }}\n title={`${label}: ${color}`} aria-label={`${label}: ${color}`}\n aria-pressed={color.toLowerCase() === value.toLowerCase()} />\n ))}\n <button type=\"button\" className=\"rte-toolbar__color-clear\"\n onMouseDown={portalOwner ? event => event.preventDefault() : undefined}\n onClick={() => { onChange(''); setIsOpen(false); }}\n title={`Clear ${label}`} aria-label={`Clear ${label}`} aria-pressed={!value}>Clear</button>\n </div>\n );\n\n return (\n <div ref={ref} className=\"rte-toolbar__color-picker\"\n onBlur={(event) => {\n if (!event.currentTarget.contains(event.relatedTarget) && !paletteRef.current?.contains(event.relatedTarget)) setIsOpen(false);\n }}\n onKeyDown={(event) => {\n if (event.key === 'Escape' && isOpen) {\n event.preventDefault();\n event.stopPropagation();\n setIsOpen(false);\n triggerRef.current?.focus();\n }\n }}>\n <button\n type=\"button\"\n ref={triggerRef}\n className={`${buttonClassName} rte-toolbar__color-trigger`}\n onMouseDown={portalOwner ? event => event.preventDefault() : undefined}\n onClick={event => {\n if (portalOwner && !isOpen) {\n const computed = getComputedStyle(event.currentTarget);\n const variables: Record<string, string> = {};\n for (const name of ['--rte-bg', '--rte-text', '--rte-border', '--rte-placeholder', '--rte-active-color', '--rte-toolbar-btn-hover']) {\n variables[name] = computed.getPropertyValue(name);\n }\n setPaletteTheme(variables);\n }\n setIsOpen(!isOpen);\n }}\n title={description}\n aria-label={description}\n aria-expanded={isOpen}\n aria-controls={isOpen ? paletteId : undefined}\n >\n <span className={`rte-toolbar__color-icon rte-toolbar__color-icon--${kind}`} aria-hidden=\"true\">\n {icon || (kind === 'text' ? <span className=\"rte-toolbar__color-letter\">A</span> : (\n <svg width=\"18\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"m14 3 7 7-9 9-7-7zM5 12l-2 7 2 2 7-2M14 7l3 3M3 21h6\" />\n </svg>\n ))}\n <span\n className={`rte-toolbar__color-indicator${value ? '' : ' rte-toolbar__color-indicator--empty'}`}\n style={{ backgroundColor: value || undefined }}\n />\n </span>\n </button>\n {portalOwner && typeof document !== 'undefined' ? createPortal(palette, document.body) : palette}\n </div>\n );\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"FloatingDialogMenu.js","names":[],"sources":["../../../../../src/components/pro/RichTextEditor/Toolbar/FloatingDialogMenu.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect } from 'react';\nimport { flushSync } from 'react-dom';\nimport type { RichTextEditorLabels } from '../types';\nimport { useAnchoredDropdown } from './useAnchoredDropdown';\n\ninterface FloatingDialogMenuProps {\n labels: RichTextEditorLabels;\n onInsert: (layout: 'block' | 'wrap-left' | 'wrap-right' | 'float', focusEditor?: boolean) => void;\n}\n\nconst DIALOG_LAYOUT_OPTIONS: { key: 'block' | 'wrap-left' | 'wrap-right' | 'float'; labelKey: keyof RichTextEditorLabels; icon: React.ReactNode }[] = [\n {\n key: 'block', labelKey: 'layoutBlock',\n icon: <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\" /><line x1=\"3\" y1=\"3\" x2=\"21\" y2=\"3\" /><line x1=\"3\" y1=\"21\" x2=\"21\" y2=\"21\" /></svg>,\n },\n {\n key: 'wrap-left', labelKey: 'layoutWrapLeft',\n icon: <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><rect x=\"2\" y=\"4\" width=\"10\" height=\"8\" rx=\"1\" /><line x1=\"15\" y1=\"5\" x2=\"22\" y2=\"5\" /><line x1=\"15\" y1=\"8\" x2=\"22\" y2=\"8\" /><line x1=\"15\" y1=\"11\" x2=\"22\" y2=\"11\" /><line x1=\"2\" y1=\"15\" x2=\"22\" y2=\"15\" /><line x1=\"2\" y1=\"18\" x2=\"22\" y2=\"18\" /></svg>,\n },\n {\n key: 'wrap-right', labelKey: 'layoutWrapRight',\n icon: <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><rect x=\"12\" y=\"4\" width=\"10\" height=\"8\" rx=\"1\" /><line x1=\"2\" y1=\"5\" x2=\"9\" y2=\"5\" /><line x1=\"2\" y1=\"8\" x2=\"9\" y2=\"8\" /><line x1=\"2\" y1=\"11\" x2=\"9\" y2=\"11\" /><line x1=\"2\" y1=\"15\" x2=\"22\" y2=\"15\" /><line x1=\"2\" y1=\"18\" x2=\"22\" y2=\"18\" /></svg>,\n },\n {\n key: 'float', labelKey: 'layoutFloat',\n icon: <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><rect x=\"6\" y=\"6\" width=\"12\" height=\"12\" rx=\"2\" /><path d=\"M2 2h4M18 2h4M2 22h4M18 22h4\" strokeDasharray=\"2 2\" /><line x1=\"2\" y1=\"12\" x2=\"6\" y2=\"12\" strokeDasharray=\"2 2\" /><line x1=\"18\" y1=\"12\" x2=\"22\" y2=\"12\" strokeDasharray=\"2 2\" /></svg>,\n },\n];\n\nexport const FloatingDialogMenu: React.FC<FloatingDialogMenuProps> = ({ labels, onInsert }) => {\n const [isOpen, setIsOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLButtonElement>(null);\n const dropdownRef = useRef<HTMLDivElement>(null);\n const dropdownStyle = useAnchoredDropdown(isOpen, triggerRef, dropdownRef);\n const pointerType = useRef('');\n\n useEffect(() => {\n const handler = (e: PointerEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) setIsOpen(false);\n };\n document.addEventListener('pointerdown', handler);\n return () => document.removeEventListener('pointerdown', handler);\n }, []);\n\n return (\n <div ref={ref} className=\"rte-toolbar__template-menu\" onPointerDown={(event) => { pointerType.current = event.pointerType; }}>\n <button\n type=\"button\"\n ref={triggerRef}\n className={`rte-toolbar__btn ${isOpen ? 'rte-toolbar__btn--active' : ''}`}\n aria-expanded={isOpen}\n onClick={() => setIsOpen(!isOpen)}\n title={labels.floatingDialog || 'Floating Dialog'}\n style={{ width: 'auto', padding: '0 6px', gap: '2px', display: 'inline-flex', alignItems: 'center' }}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <rect x=\"2\" y=\"4\" width=\"13\" height=\"10\" rx=\"2\" />\n <path d=\"M9 10h11a2 2 0 012 2v6a2 2 0 01-2 2H9a2 2 0 01-2-2v-2\" />\n <line x1=\"7\" y1=\"14\" x2=\"13\" y2=\"14\" />\n </svg>\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\">\n <polyline points=\"6 9 12 15 18 9\" />\n </svg>\n </button>\n {isOpen && (\n <div ref={dropdownRef} className=\"rte-toolbar__template-dropdown\" style={{ ...dropdownStyle, minWidth: 140 }}>\n {DIALOG_LAYOUT_OPTIONS.map((opt) => (\n <button\n key={opt.key}\n type=\"button\"\n className=\"rte-toolbar__template-item\"\n onClick={(event) => {\n const focusEditor = event.detail === 0 || pointerType.current !== 'touch';\n flushSync(() => setIsOpen(false));\n onInsert(opt.key, focusEditor);\n }}\n >\n <span className=\"rte-toolbar__template-icon\" style={{ display: 'flex', alignItems: 'center' }}>{opt.icon}</span>\n <span>{labels[opt.labelKey] || opt.labelKey}</span>\n </button>\n ))}\n </div>\n )}\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"FloatingDialogMenu.js","names":["DIALOG_LAYOUT_OPTIONS","FloatingDialogMenu","isOpen","setIsOpen","useState","ref","useRef","triggerRef","dropdownRef","dropdownStyle","useAnchoredDropdown","pointerType","useEffect","handler","event","labels","focusEditor","flushSync","onInsert","opt"],"sources":["../../../../../src/components/pro/RichTextEditor/Toolbar/FloatingDialogMenu.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect } from 'react';\nimport { flushSync } from 'react-dom';\nimport type { RichTextEditorLabels } from '../types';\nimport { useAnchoredDropdown } from './useAnchoredDropdown';\n\ninterface FloatingDialogMenuProps {\n labels: RichTextEditorLabels;\n onInsert: (layout: 'block' | 'wrap-left' | 'wrap-right' | 'float', focusEditor?: boolean) => void;\n}\n\nconst DIALOG_LAYOUT_OPTIONS: { key: 'block' | 'wrap-left' | 'wrap-right' | 'float'; labelKey: keyof RichTextEditorLabels; icon: React.ReactNode }[] = [\n {\n key: 'block', labelKey: 'layoutBlock',\n icon: <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\" /><line x1=\"3\" y1=\"3\" x2=\"21\" y2=\"3\" /><line x1=\"3\" y1=\"21\" x2=\"21\" y2=\"21\" /></svg>,\n },\n {\n key: 'wrap-left', labelKey: 'layoutWrapLeft',\n icon: <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><rect x=\"2\" y=\"4\" width=\"10\" height=\"8\" rx=\"1\" /><line x1=\"15\" y1=\"5\" x2=\"22\" y2=\"5\" /><line x1=\"15\" y1=\"8\" x2=\"22\" y2=\"8\" /><line x1=\"15\" y1=\"11\" x2=\"22\" y2=\"11\" /><line x1=\"2\" y1=\"15\" x2=\"22\" y2=\"15\" /><line x1=\"2\" y1=\"18\" x2=\"22\" y2=\"18\" /></svg>,\n },\n {\n key: 'wrap-right', labelKey: 'layoutWrapRight',\n icon: <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><rect x=\"12\" y=\"4\" width=\"10\" height=\"8\" rx=\"1\" /><line x1=\"2\" y1=\"5\" x2=\"9\" y2=\"5\" /><line x1=\"2\" y1=\"8\" x2=\"9\" y2=\"8\" /><line x1=\"2\" y1=\"11\" x2=\"9\" y2=\"11\" /><line x1=\"2\" y1=\"15\" x2=\"22\" y2=\"15\" /><line x1=\"2\" y1=\"18\" x2=\"22\" y2=\"18\" /></svg>,\n },\n {\n key: 'float', labelKey: 'layoutFloat',\n icon: <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><rect x=\"6\" y=\"6\" width=\"12\" height=\"12\" rx=\"2\" /><path d=\"M2 2h4M18 2h4M2 22h4M18 22h4\" strokeDasharray=\"2 2\" /><line x1=\"2\" y1=\"12\" x2=\"6\" y2=\"12\" strokeDasharray=\"2 2\" /><line x1=\"18\" y1=\"12\" x2=\"22\" y2=\"12\" strokeDasharray=\"2 2\" /></svg>,\n },\n];\n\nexport const FloatingDialogMenu: React.FC<FloatingDialogMenuProps> = ({ labels, onInsert }) => {\n const [isOpen, setIsOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLButtonElement>(null);\n const dropdownRef = useRef<HTMLDivElement>(null);\n const dropdownStyle = useAnchoredDropdown(isOpen, triggerRef, dropdownRef);\n const pointerType = useRef('');\n\n useEffect(() => {\n const handler = (e: PointerEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) setIsOpen(false);\n };\n document.addEventListener('pointerdown', handler);\n return () => document.removeEventListener('pointerdown', handler);\n }, []);\n\n return (\n <div ref={ref} className=\"rte-toolbar__template-menu\" onPointerDown={(event) => { pointerType.current = event.pointerType; }}>\n <button\n type=\"button\"\n ref={triggerRef}\n className={`rte-toolbar__btn ${isOpen ? 'rte-toolbar__btn--active' : ''}`}\n aria-expanded={isOpen}\n onClick={() => setIsOpen(!isOpen)}\n title={labels.floatingDialog || 'Floating Dialog'}\n style={{ width: 'auto', padding: '0 6px', gap: '2px', display: 'inline-flex', alignItems: 'center' }}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <rect x=\"2\" y=\"4\" width=\"13\" height=\"10\" rx=\"2\" />\n <path d=\"M9 10h11a2 2 0 012 2v6a2 2 0 01-2 2H9a2 2 0 01-2-2v-2\" />\n <line x1=\"7\" y1=\"14\" x2=\"13\" y2=\"14\" />\n </svg>\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\">\n <polyline points=\"6 9 12 15 18 9\" />\n </svg>\n </button>\n {isOpen && (\n <div ref={dropdownRef} className=\"rte-toolbar__template-dropdown\" style={{ ...dropdownStyle, minWidth: 140 }}>\n {DIALOG_LAYOUT_OPTIONS.map((opt) => (\n <button\n key={opt.key}\n type=\"button\"\n className=\"rte-toolbar__template-item\"\n onClick={(event) => {\n const focusEditor = event.detail === 0 || pointerType.current !== 'touch';\n flushSync(() => setIsOpen(false));\n onInsert(opt.key, focusEditor);\n }}\n >\n <span className=\"rte-toolbar__template-icon\" style={{ display: 'flex', alignItems: 'center' }}>{opt.icon}</span>\n <span>{labels[opt.labelKey] || opt.labelKey}</span>\n </button>\n ))}\n </div>\n )}\n </div>\n );\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"MarkdownTemplates.js","names":[],"sources":["../../../../../src/components/pro/RichTextEditor/Toolbar/MarkdownTemplates.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect } from 'react';\nimport { flushSync } from 'react-dom';\nimport type { RichTextEditorLabels } from '../types';\nimport { useAnchoredDropdown } from './useAnchoredDropdown';\n\nexport const MD_TEMPLATES: { key: string; labelKey: keyof RichTextEditorLabels; icon: string; content: string }[] = [\n {\n key: 'flowchart', labelKey: 'mdTplFlowchart', icon: '🔀',\n content: `## Flowchart\n\n\\`\\`\\`mermaid\ngraph TD\n A[Start] --> B{Is it valid?}\n B -->|Yes| C[Process Data]\n B -->|No| D[Show Error]\n C --> E[Save to DB]\n E --> F[Send Response]\n D --> G[Log Warning]\n G --> A\n F --> H[End]\n\\`\\`\\`\n`,\n },\n {\n key: 'sequence', labelKey: 'mdTplSequence', icon: '🔄',\n content: `## Sequence Diagram\n\n\\`\\`\\`mermaid\nsequenceDiagram\n participant Browser\n participant Server\n participant Database\n participant Cache\n\n Browser->>Server: POST /api/login\n Server->>Database: Query user\n Database-->>Server: User record\n Server->>Cache: Store session\n Cache-->>Server: OK\n Server-->>Browser: 200 JWT Token\n Browser->>Server: GET /api/data (Bearer token)\n Server->>Cache: Validate session\n Cache-->>Server: Valid\n Server->>Database: Fetch data\n Database-->>Server: Result set\n Server-->>Browser: 200 JSON data\n\\`\\`\\`\n`,\n },\n {\n key: 'pie', labelKey: 'mdTplPieChart', icon: '🥧',\n content: `## Pie Chart\n\n\\`\\`\\`mermaid\npie title Tech Stack Usage 2025\n \"TypeScript\" : 35\n \"Python\" : 25\n \"Rust\" : 15\n \"Go\" : 12\n \"Java\" : 8\n \"Others\" : 5\n\\`\\`\\`\n`,\n },\n {\n key: 'gantt', labelKey: 'mdTplGantt', icon: '📊',\n content: `## Gantt Chart\n\n\\`\\`\\`mermaid\ngantt\n title Project Development Timeline\n dateFormat YYYY-MM-DD\n section Design\n UI/UX Design :a1, 2025-01-01, 20d\n API Design :a2, after a1, 10d\n section Frontend\n Component Library :b1, after a2, 25d\n Page Integration :b2, after b1, 15d\n Testing & Bug Fix :b3, after b2, 10d\n section Backend\n Core API Development :c1, after a2, 30d\n Database Optimization :c2, after c1, 10d\n section Deployment\n Staging Deploy :d1, after b3, 5d\n Production Release :milestone, after d1, 0d\n\\`\\`\\`\n`,\n },\n {\n key: 'xychart', labelKey: 'mdTplBarChart', icon: '📈',\n content: `## Bar Chart (xychart)\n\n\\`\\`\\`mermaid\nxychart-beta\n title \"Monthly Revenue (in thousands)\"\n x-axis [Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec]\n y-axis \"Revenue (USD)\" 0 --> 120\n bar [52, 48, 61, 55, 72, 68, 85, 90, 78, 95, 102, 110]\n line [52, 48, 61, 55, 72, 68, 85, 90, 78, 95, 102, 110]\n\\`\\`\\`\n`,\n },\n {\n key: 'python', labelKey: 'mdTplPython', icon: '🐍',\n content: `## Python Example\n\n\\`\\`\\`python\nimport asyncio\nfrom dataclasses import dataclass, field\nfrom typing import AsyncIterator\n\n\n@dataclass\nclass DataPipeline:\n \"\"\"Async data processing pipeline.\"\"\"\n name: str\n buffer_size: int = 100\n _queue: asyncio.Queue = field(init=False)\n\n def __post_init__(self):\n self._queue = asyncio.Queue(maxsize=self.buffer_size)\n\n async def produce(self, items: list[int]) -> None:\n for item in items:\n transformed = item ** 2 + 2 * item + 1\n await self._queue.put(transformed)\n await self._queue.put(None) # sentinel\n\n async def consume(self) -> AsyncIterator[int]:\n while True:\n item = await self._queue.get()\n if item is None:\n break\n yield item\n\n async def run(self, data: list[int]) -> list[int]:\n results: list[int] = []\n producer = asyncio.create_task(self.produce(data))\n async for value in self.consume():\n results.append(value)\n await producer\n return results\n\n\nasync def main():\n pipeline = DataPipeline(name=\"squares\", buffer_size=50)\n data = list(range(1, 21))\n results = await pipeline.run(data)\n print(f\"Processed {len(results)} items: {results[:5]}...\")\n\n\nif __name__ == \"__main__\":\n asyncio.run(main())\n\\`\\`\\`\n`,\n },\n {\n key: 'typescript', labelKey: 'mdTplTypeScript', icon: '🟦',\n content: `## TypeScript Example\n\n\\`\\`\\`typescript\ninterface APIResponse<T> {\n data: T;\n status: number;\n message: string;\n timestamp: Date;\n}\n\ntype HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';\n\nclass TypedFetcher {\n private baseUrl: string;\n private headers: Record<string, string>;\n\n constructor(baseUrl: string, token?: string) {\n this.baseUrl = baseUrl;\n this.headers = {\n 'Content-Type': 'application/json',\n ...(token ? { Authorization: \\\\\\`Bearer \\\\\\${token}\\\\\\` } : {}),\n };\n }\n\n async request<T>(\n method: HttpMethod,\n path: string,\n body?: unknown,\n ): Promise<APIResponse<T>> {\n const response = await fetch(\\\\\\`\\\\\\${this.baseUrl}\\\\\\${path}\\\\\\`, {\n method,\n headers: this.headers,\n body: body ? JSON.stringify(body) : undefined,\n });\n\n if (!response.ok) {\n throw new Error(\\\\\\`HTTP \\\\\\${response.status}: \\\\\\${response.statusText}\\\\\\`);\n }\n\n return response.json() as Promise<APIResponse<T>>;\n }\n\n get<T>(path: string) { return this.request<T>('GET', path); }\n post<T>(path: string, body: unknown) { return this.request<T>('POST', path, body); }\n put<T>(path: string, body: unknown) { return this.request<T>('PUT', path, body); }\n delete<T>(path: string) { return this.request<T>('DELETE', path); }\n}\n\n// Usage\ninterface User {\n id: number;\n name: string;\n email: string;\n}\n\nconst api = new TypedFetcher('https://api.example.com', 'my-token');\nconst users = await api.get<User[]>('/users');\nconsole.log(users.data);\n\\`\\`\\`\n`,\n },\n {\n key: 'rust', labelKey: 'mdTplRust', icon: '🦀',\n content: `## Rust Example\n\n\\`\\`\\`rust\nuse std::collections::HashMap;\nuse std::sync::Arc;\nuse tokio::sync::RwLock;\n\n#[derive(Debug, Clone)]\nstruct CacheEntry<V: Clone> {\n value: V,\n expires_at: std::time::Instant,\n}\n\n#[derive(Clone)]\nstruct AsyncCache<V: Clone + Send + Sync + 'static> {\n store: Arc<RwLock<HashMap<String, CacheEntry<V>>>>,\n ttl: std::time::Duration,\n}\n\nimpl<V: Clone + Send + Sync + 'static> AsyncCache<V> {\n fn new(ttl_secs: u64) -> Self {\n Self {\n store: Arc::new(RwLock::new(HashMap::new())),\n ttl: std::time::Duration::from_secs(ttl_secs),\n }\n }\n\n async fn get(&self, key: &str) -> Option<V> {\n let store = self.store.read().await;\n store.get(key).and_then(|entry| {\n if entry.expires_at > std::time::Instant::now() {\n Some(entry.value.clone())\n } else {\n None\n }\n })\n }\n\n async fn set(&self, key: String, value: V) {\n let mut store = self.store.write().await;\n store.insert(key, CacheEntry {\n value,\n expires_at: std::time::Instant::now() + self.ttl,\n });\n }\n\n async fn cleanup(&self) -> usize {\n let mut store = self.store.write().await;\n let now = std::time::Instant::now();\n let before = store.len();\n store.retain(|_, entry| entry.expires_at > now);\n before - store.len()\n }\n}\n\n#[tokio::main]\nasync fn main() {\n let cache = AsyncCache::<String>::new(60);\n cache.set(\"hello\".into(), \"world\".into()).await;\n\n if let Some(val) = cache.get(\"hello\").await {\n println!(\"Got: {val}\");\n }\n}\n\\`\\`\\`\n`,\n },\n {\n key: 'math', labelKey: 'mdTplMath', icon: '🔢',\n content: `## Math Formulas (TeX)\n\n### Euler's Identity\n\n$$\ne^{i\\\\pi} + 1 = 0\n$$\n\n### Quadratic Formula\n\n$$\nx = \\\\frac{-b \\\\pm \\\\sqrt{b^2 - 4ac}}{2a}\n$$\n\n### Gaussian Integral\n\n$$\n\\\\int_{-\\\\infty}^{\\\\infty} e^{-x^2} \\\\, dx = \\\\sqrt{\\\\pi}\n$$\n\n### Maxwell's Equations\n\n$$\n\\\\nabla \\\\cdot \\\\mathbf{E} = \\\\frac{\\\\rho}{\\\\epsilon_0}\n$$\n\n$$\n\\\\nabla \\\\cdot \\\\mathbf{B} = 0\n$$\n\n$$\n\\\\nabla \\\\times \\\\mathbf{E} = -\\\\frac{\\\\partial \\\\mathbf{B}}{\\\\partial t}\n$$\n\n$$\n\\\\nabla \\\\times \\\\mathbf{B} = \\\\mu_0 \\\\mathbf{J} + \\\\mu_0 \\\\epsilon_0 \\\\frac{\\\\partial \\\\mathbf{E}}{\\\\partial t}\n$$\n\n### Taylor Series Expansion\n\n$$\nf(x) = \\\\sum_{n=0}^{\\\\infty} \\\\frac{f^{(n)}(a)}{n!}(x-a)^n\n$$\n\n### Matrix Notation\n\n$$\n\\\\mathbf{A} = \\\\begin{pmatrix} a_{11} & a_{12} & \\\\cdots & a_{1n} \\\\\\\\ a_{21} & a_{22} & \\\\cdots & a_{2n} \\\\\\\\ \\\\vdots & \\\\vdots & \\\\ddots & \\\\vdots \\\\\\\\ a_{m1} & a_{m2} & \\\\cdots & a_{mn} \\\\end{pmatrix}\n$$\n\n### Inline math: The identity $e^{i\\\\theta} = \\\\cos\\\\theta + i\\\\sin\\\\theta$ is known as Euler's formula.\n`,\n },\n {\n key: 'mixed', labelKey: 'mdTplMixed', icon: '🎨',\n content: `## Mixed Content Example\n\n### Architecture Overview\n\n\\`\\`\\`mermaid\ngraph LR\n Client[Client App] --> Gateway[API Gateway]\n Gateway --> Auth[Auth Service]\n Gateway --> Core[Core Service]\n Core --> DB[(PostgreSQL)]\n Core --> Cache[(Redis)]\n Auth --> DB\n\\`\\`\\`\n\n### Performance Formula\n\nThe response time $T$ is calculated as:\n\n$$\nT = T_{network} + T_{processing} + T_{db}\n$$\n\nwhere $T_{db} = O(\\\\log n)$ with proper indexing.\n\n### Implementation\n\n\\`\\`\\`python\nfrom fastapi import FastAPI, Depends\nfrom functools import lru_cache\n\napp = FastAPI()\n\n@lru_cache(maxsize=256)\ndef compute_heavy(n: int) -> float:\n \"\"\"Cached computation: O(log n) amortized.\"\"\"\n return sum(1.0 / i for i in range(1, n + 1))\n\n@app.get(\"/api/harmonic/{n}\")\nasync def harmonic(n: int):\n result = compute_heavy(n)\n return {\"n\": n, \"H_n\": round(result, 6)}\n\\`\\`\\`\n\n### Project Status\n\n\\`\\`\\`mermaid\npie title Sprint Progress\n \"Completed\" : 65\n \"In Progress\" : 20\n \"Blocked\" : 10\n \"Not Started\" : 5\n\\`\\`\\`\n`,\n },\n];\n\ninterface MarkdownTemplateMenuProps {\n labels: RichTextEditorLabels;\n onSelect: (content: string, focusEditor?: boolean) => void;\n}\n\nexport const MarkdownTemplateMenu: React.FC<MarkdownTemplateMenuProps> = ({ labels, onSelect }) => {\n const [isOpen, setIsOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLButtonElement>(null);\n const dropdownRef = useRef<HTMLDivElement>(null);\n const dropdownStyle = useAnchoredDropdown(isOpen, triggerRef, dropdownRef);\n const pointerType = useRef('');\n const select = (event: React.MouseEvent, content: string) => {\n // Touch insertion must not enter Android's native editing/IME focus path.\n const focusEditor = event.detail === 0 || pointerType.current !== 'touch';\n flushSync(() => setIsOpen(false));\n onSelect(content, focusEditor);\n };\n\n useEffect(() => {\n const handler = (e: PointerEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) {\n setIsOpen(false);\n }\n };\n document.addEventListener('pointerdown', handler);\n return () => document.removeEventListener('pointerdown', handler);\n }, []);\n\n return (\n <div ref={ref} className=\"rte-toolbar__template-menu\" onPointerDown={(event) => { pointerType.current = event.pointerType; }}>\n <button\n type=\"button\"\n ref={triggerRef}\n className={`rte-toolbar__btn ${isOpen ? 'rte-toolbar__btn--active' : ''}`}\n aria-expanded={isOpen}\n onClick={() => setIsOpen(!isOpen)}\n title={labels.mdTemplates || 'Markdown Templates'}\n style={{ width: 'auto', padding: '0 6px', gap: '2px', display: 'inline-flex', alignItems: 'center' }}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <rect x=\"3\" y=\"3\" width=\"8\" height=\"8\" rx=\"1.5\" />\n <rect x=\"13\" y=\"3\" width=\"8\" height=\"8\" rx=\"1.5\" />\n <rect x=\"3\" y=\"13\" width=\"8\" height=\"8\" rx=\"1.5\" />\n <path d=\"M17 14v6M14 17h6\" />\n </svg>\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\">\n <polyline points=\"6 9 12 15 18 9\" />\n </svg>\n </button>\n {isOpen && (\n <div ref={dropdownRef} className=\"rte-toolbar__template-dropdown\" style={dropdownStyle}>\n <div className=\"rte-toolbar__template-group-label\">Mermaid</div>\n {MD_TEMPLATES.filter(t => ['flowchart', 'sequence', 'pie', 'gantt', 'xychart'].includes(t.key)).map(t => (\n <button\n key={t.key}\n type=\"button\"\n className=\"rte-toolbar__template-item\"\n onClick={(event) => select(event, t.content)}\n >\n <span className=\"rte-toolbar__template-icon\">{t.icon}</span>\n <span>{labels[t.labelKey] || t.labelKey}</span>\n </button>\n ))}\n <div className=\"rte-toolbar__template-group-label\">Code</div>\n {MD_TEMPLATES.filter(t => ['python', 'typescript', 'rust'].includes(t.key)).map(t => (\n <button\n key={t.key}\n type=\"button\"\n className=\"rte-toolbar__template-item\"\n onClick={(event) => select(event, t.content)}\n >\n <span className=\"rte-toolbar__template-icon\">{t.icon}</span>\n <span>{labels[t.labelKey] || t.labelKey}</span>\n </button>\n ))}\n <div className=\"rte-toolbar__template-group-label\">Math / Mixed</div>\n {MD_TEMPLATES.filter(t => ['math', 'mixed'].includes(t.key)).map(t => (\n <button\n key={t.key}\n type=\"button\"\n className=\"rte-toolbar__template-item\"\n onClick={(event) => select(event, t.content)}\n >\n <span className=\"rte-toolbar__template-icon\">{t.icon}</span>\n <span>{labels[t.labelKey] || t.labelKey}</span>\n </button>\n ))}\n </div>\n )}\n </div>\n );\n};\n"],"mappings":";;;;;AAKA,IAAa,IAAuG;CAClH;EACE,KAAK;EAAa,UAAU;EAAkB,MAAM;EACpD,SAAS;CAcX;CACA;EACE,KAAK;EAAY,UAAU;EAAiB,MAAM;EAClD,SAAS;CAuBX;CACA;EACE,KAAK;EAAO,UAAU;EAAiB,MAAM;EAC7C,SAAS;CAYX;CACA;EACE,KAAK;EAAS,UAAU;EAAc,MAAM;EAC5C,SAAS;CAqBX;CACA;EACE,KAAK;EAAW,UAAU;EAAiB,MAAM;EACjD,SAAS;CAWX;CACA;EACE,KAAK;EAAU,UAAU;EAAe,MAAM;EAC9C,SAAS;CAmDX;CACA;EACE,KAAK;EAAc,UAAU;EAAmB,MAAM;EACtD,SAAS;CA4DX;CACA;EACE,KAAK;EAAQ,UAAU;EAAa,MAAM;EAC1C,SAAS;CAkEX;CACA;EACE,KAAK;EAAQ,UAAU;EAAa,MAAM;EAC1C,SAAS;CAoDX;CACA;EACE,KAAK;EAAS,UAAU;EAAc,MAAM;EAC5C,SAAS;CAqDX;AACF,GAOa,KAA6D,EAAE,WAAQ,kBAAe;CACjG,IAAM,CAAC,GAAQ,KAAa,EAAS,EAAK,GACpC,IAAM,EAAuB,IAAI,GACjC,IAAa,EAA0B,IAAI,GAC3C,IAAc,EAAuB,IAAI,GACzC,IAAgB,EAAoB,GAAQ,GAAY,CAAW,GACnE,IAAc,EAAO,EAAE,GACvB,KAAU,GAAyB,MAAoB;EAE3D,IAAM,IAAc,EAAM,WAAW,KAAK,EAAY,YAAY;EAElE,AADA,QAAgB,EAAU,EAAK,CAAC,GAChC,EAAS,GAAS,CAAW;CAC/B;CAYA,OAVA,QAAgB;EACd,IAAM,KAAW,MAAoB;GACnC,AAAI,EAAI,WAAW,CAAC,EAAI,QAAQ,SAAS,EAAE,MAAc,KACvD,EAAU,EAAK;EAEnB;EAEA,OADA,SAAS,iBAAiB,eAAe,CAAO,SACnC,SAAS,oBAAoB,eAAe,CAAO;CAClE,GAAG,CAAC,CAAC,GAGH,kBAAC,OAAD;EAAU;EAAK,WAAU;EAA6B,gBAAgB,MAAU;GAAE,EAAY,UAAU,EAAM;EAAa;EAA3H,UAAA,CACE,kBAAC,UAAD;GACE,MAAK;GACL,KAAK;GACL,WAAW,oBAAoB,IAAS,6BAA6B;GACrE,iBAAe;GACf,eAAe,EAAU,CAAC,CAAM;GAChC,OAAO,EAAO,eAAe;GAC7B,OAAO;IAAE,OAAO;IAAQ,SAAS;IAAS,KAAK;IAAO,SAAS;IAAe,YAAY;GAAS;GAPrG,UAAA,CASE,kBAAC,OAAD;IAAK,OAAM;IAAK,QAAO;IAAK,SAAQ;IAAY,MAAK;IAAO,QAAO;IAAe,aAAY;IAAI,eAAc;IAAQ,gBAAe;IAAvI,UAAA;KACE,kBAAC,QAAD;MAAM,GAAE;MAAI,GAAE;MAAI,OAAM;MAAI,QAAO;MAAI,IAAG;KAAO,CAAA;KACjD,kBAAC,QAAD;MAAM,GAAE;MAAK,GAAE;MAAI,OAAM;MAAI,QAAO;MAAI,IAAG;KAAO,CAAA;KAClD,kBAAC,QAAD;MAAM,GAAE;MAAI,GAAE;MAAK,OAAM;MAAI,QAAO;MAAI,IAAG;KAAO,CAAA;KAClD,kBAAC,QAAD,EAAM,GAAE,mBAAoB,CAAA;IACzB;GACL,CAAA,GAAA,kBAAC,OAAD;IAAK,OAAM;IAAK,QAAO;IAAK,SAAQ;IAAY,MAAK;IAAO,QAAO;IAAe,aAAY;IAC5F,UAAA,kBAAC,YAAD,EAAU,QAAO,iBAAkB,CAAA;GAChC,CAAA,CACC;EACP,CAAA,GAAA,KACC,kBAAC,OAAD;GAAK,KAAK;GAAa,WAAU;GAAiC,OAAO;GAAzE,UAAA;IACE,kBAAC,OAAD;KAAK,WAAU;KAAoC,UAAA;IAAY,CAAA;IAC9D,EAAa,QAAO,MAAK;KAAC;KAAa;KAAY;KAAO;KAAS;IAAS,CAAC,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC,KAAI,MAClG,kBAAC,UAAD;KAEE,MAAK;KACL,WAAU;KACV,UAAU,MAAU,EAAO,GAAO,EAAE,OAAO;KAJ7C,UAAA,CAME,kBAAC,QAAD;MAAM,WAAU;MAA8B,UAAA,EAAE;KAAW,CAAA,GAC3D,kBAAC,QAAD,EAAA,UAAO,EAAO,EAAE,aAAa,EAAE,SAAe,CAAA,CACxC;IAPD,GAAA,EAAE,GAOD,CACT;IACD,kBAAC,OAAD;KAAK,WAAU;KAAoC,UAAA;IAAS,CAAA;IAC3D,EAAa,QAAO,MAAK;KAAC;KAAU;KAAc;IAAM,CAAC,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC,KAAI,MAC9E,kBAAC,UAAD;KAEE,MAAK;KACL,WAAU;KACV,UAAU,MAAU,EAAO,GAAO,EAAE,OAAO;KAJ7C,UAAA,CAME,kBAAC,QAAD;MAAM,WAAU;MAA8B,UAAA,EAAE;KAAW,CAAA,GAC3D,kBAAC,QAAD,EAAA,UAAO,EAAO,EAAE,aAAa,EAAE,SAAe,CAAA,CACxC;IAPD,GAAA,EAAE,GAOD,CACT;IACD,kBAAC,OAAD;KAAK,WAAU;KAAoC,UAAA;IAAiB,CAAA;IACnE,EAAa,QAAO,MAAK,CAAC,QAAQ,OAAO,CAAC,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC,KAAI,MAC/D,kBAAC,UAAD;KAEE,MAAK;KACL,WAAU;KACV,UAAU,MAAU,EAAO,GAAO,EAAE,OAAO;KAJ7C,UAAA,CAME,kBAAC,QAAD;MAAM,WAAU;MAA8B,UAAA,EAAE;KAAW,CAAA,GAC3D,kBAAC,QAAD,EAAA,UAAO,EAAO,EAAE,aAAa,EAAE,SAAe,CAAA,CACxC;IAPD,GAAA,EAAE,GAOD,CACT;GACE;EAEJ,CAAA,CAAA;;AAET"}
1
+ {"version":3,"file":"MarkdownTemplates.js","names":["MD_TEMPLATES","MarkdownTemplateMenu","isOpen","setIsOpen","useState","ref","useRef","triggerRef","dropdownRef","dropdownStyle","useAnchoredDropdown","pointerType","select","focusEditor","event","flushSync","onSelect","content","useEffect","handler","labels","t"],"sources":["../../../../../src/components/pro/RichTextEditor/Toolbar/MarkdownTemplates.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect } from 'react';\nimport { flushSync } from 'react-dom';\nimport type { RichTextEditorLabels } from '../types';\nimport { useAnchoredDropdown } from './useAnchoredDropdown';\n\nexport const MD_TEMPLATES: { key: string; labelKey: keyof RichTextEditorLabels; icon: string; content: string }[] = [\n {\n key: 'flowchart', labelKey: 'mdTplFlowchart', icon: '🔀',\n content: `## Flowchart\n\n\\`\\`\\`mermaid\ngraph TD\n A[Start] --> B{Is it valid?}\n B -->|Yes| C[Process Data]\n B -->|No| D[Show Error]\n C --> E[Save to DB]\n E --> F[Send Response]\n D --> G[Log Warning]\n G --> A\n F --> H[End]\n\\`\\`\\`\n`,\n },\n {\n key: 'sequence', labelKey: 'mdTplSequence', icon: '🔄',\n content: `## Sequence Diagram\n\n\\`\\`\\`mermaid\nsequenceDiagram\n participant Browser\n participant Server\n participant Database\n participant Cache\n\n Browser->>Server: POST /api/login\n Server->>Database: Query user\n Database-->>Server: User record\n Server->>Cache: Store session\n Cache-->>Server: OK\n Server-->>Browser: 200 JWT Token\n Browser->>Server: GET /api/data (Bearer token)\n Server->>Cache: Validate session\n Cache-->>Server: Valid\n Server->>Database: Fetch data\n Database-->>Server: Result set\n Server-->>Browser: 200 JSON data\n\\`\\`\\`\n`,\n },\n {\n key: 'pie', labelKey: 'mdTplPieChart', icon: '🥧',\n content: `## Pie Chart\n\n\\`\\`\\`mermaid\npie title Tech Stack Usage 2025\n \"TypeScript\" : 35\n \"Python\" : 25\n \"Rust\" : 15\n \"Go\" : 12\n \"Java\" : 8\n \"Others\" : 5\n\\`\\`\\`\n`,\n },\n {\n key: 'gantt', labelKey: 'mdTplGantt', icon: '📊',\n content: `## Gantt Chart\n\n\\`\\`\\`mermaid\ngantt\n title Project Development Timeline\n dateFormat YYYY-MM-DD\n section Design\n UI/UX Design :a1, 2025-01-01, 20d\n API Design :a2, after a1, 10d\n section Frontend\n Component Library :b1, after a2, 25d\n Page Integration :b2, after b1, 15d\n Testing & Bug Fix :b3, after b2, 10d\n section Backend\n Core API Development :c1, after a2, 30d\n Database Optimization :c2, after c1, 10d\n section Deployment\n Staging Deploy :d1, after b3, 5d\n Production Release :milestone, after d1, 0d\n\\`\\`\\`\n`,\n },\n {\n key: 'xychart', labelKey: 'mdTplBarChart', icon: '📈',\n content: `## Bar Chart (xychart)\n\n\\`\\`\\`mermaid\nxychart-beta\n title \"Monthly Revenue (in thousands)\"\n x-axis [Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec]\n y-axis \"Revenue (USD)\" 0 --> 120\n bar [52, 48, 61, 55, 72, 68, 85, 90, 78, 95, 102, 110]\n line [52, 48, 61, 55, 72, 68, 85, 90, 78, 95, 102, 110]\n\\`\\`\\`\n`,\n },\n {\n key: 'python', labelKey: 'mdTplPython', icon: '🐍',\n content: `## Python Example\n\n\\`\\`\\`python\nimport asyncio\nfrom dataclasses import dataclass, field\nfrom typing import AsyncIterator\n\n\n@dataclass\nclass DataPipeline:\n \"\"\"Async data processing pipeline.\"\"\"\n name: str\n buffer_size: int = 100\n _queue: asyncio.Queue = field(init=False)\n\n def __post_init__(self):\n self._queue = asyncio.Queue(maxsize=self.buffer_size)\n\n async def produce(self, items: list[int]) -> None:\n for item in items:\n transformed = item ** 2 + 2 * item + 1\n await self._queue.put(transformed)\n await self._queue.put(None) # sentinel\n\n async def consume(self) -> AsyncIterator[int]:\n while True:\n item = await self._queue.get()\n if item is None:\n break\n yield item\n\n async def run(self, data: list[int]) -> list[int]:\n results: list[int] = []\n producer = asyncio.create_task(self.produce(data))\n async for value in self.consume():\n results.append(value)\n await producer\n return results\n\n\nasync def main():\n pipeline = DataPipeline(name=\"squares\", buffer_size=50)\n data = list(range(1, 21))\n results = await pipeline.run(data)\n print(f\"Processed {len(results)} items: {results[:5]}...\")\n\n\nif __name__ == \"__main__\":\n asyncio.run(main())\n\\`\\`\\`\n`,\n },\n {\n key: 'typescript', labelKey: 'mdTplTypeScript', icon: '🟦',\n content: `## TypeScript Example\n\n\\`\\`\\`typescript\ninterface APIResponse<T> {\n data: T;\n status: number;\n message: string;\n timestamp: Date;\n}\n\ntype HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE';\n\nclass TypedFetcher {\n private baseUrl: string;\n private headers: Record<string, string>;\n\n constructor(baseUrl: string, token?: string) {\n this.baseUrl = baseUrl;\n this.headers = {\n 'Content-Type': 'application/json',\n ...(token ? { Authorization: \\\\\\`Bearer \\\\\\${token}\\\\\\` } : {}),\n };\n }\n\n async request<T>(\n method: HttpMethod,\n path: string,\n body?: unknown,\n ): Promise<APIResponse<T>> {\n const response = await fetch(\\\\\\`\\\\\\${this.baseUrl}\\\\\\${path}\\\\\\`, {\n method,\n headers: this.headers,\n body: body ? JSON.stringify(body) : undefined,\n });\n\n if (!response.ok) {\n throw new Error(\\\\\\`HTTP \\\\\\${response.status}: \\\\\\${response.statusText}\\\\\\`);\n }\n\n return response.json() as Promise<APIResponse<T>>;\n }\n\n get<T>(path: string) { return this.request<T>('GET', path); }\n post<T>(path: string, body: unknown) { return this.request<T>('POST', path, body); }\n put<T>(path: string, body: unknown) { return this.request<T>('PUT', path, body); }\n delete<T>(path: string) { return this.request<T>('DELETE', path); }\n}\n\n// Usage\ninterface User {\n id: number;\n name: string;\n email: string;\n}\n\nconst api = new TypedFetcher('https://api.example.com', 'my-token');\nconst users = await api.get<User[]>('/users');\nconsole.log(users.data);\n\\`\\`\\`\n`,\n },\n {\n key: 'rust', labelKey: 'mdTplRust', icon: '🦀',\n content: `## Rust Example\n\n\\`\\`\\`rust\nuse std::collections::HashMap;\nuse std::sync::Arc;\nuse tokio::sync::RwLock;\n\n#[derive(Debug, Clone)]\nstruct CacheEntry<V: Clone> {\n value: V,\n expires_at: std::time::Instant,\n}\n\n#[derive(Clone)]\nstruct AsyncCache<V: Clone + Send + Sync + 'static> {\n store: Arc<RwLock<HashMap<String, CacheEntry<V>>>>,\n ttl: std::time::Duration,\n}\n\nimpl<V: Clone + Send + Sync + 'static> AsyncCache<V> {\n fn new(ttl_secs: u64) -> Self {\n Self {\n store: Arc::new(RwLock::new(HashMap::new())),\n ttl: std::time::Duration::from_secs(ttl_secs),\n }\n }\n\n async fn get(&self, key: &str) -> Option<V> {\n let store = self.store.read().await;\n store.get(key).and_then(|entry| {\n if entry.expires_at > std::time::Instant::now() {\n Some(entry.value.clone())\n } else {\n None\n }\n })\n }\n\n async fn set(&self, key: String, value: V) {\n let mut store = self.store.write().await;\n store.insert(key, CacheEntry {\n value,\n expires_at: std::time::Instant::now() + self.ttl,\n });\n }\n\n async fn cleanup(&self) -> usize {\n let mut store = self.store.write().await;\n let now = std::time::Instant::now();\n let before = store.len();\n store.retain(|_, entry| entry.expires_at > now);\n before - store.len()\n }\n}\n\n#[tokio::main]\nasync fn main() {\n let cache = AsyncCache::<String>::new(60);\n cache.set(\"hello\".into(), \"world\".into()).await;\n\n if let Some(val) = cache.get(\"hello\").await {\n println!(\"Got: {val}\");\n }\n}\n\\`\\`\\`\n`,\n },\n {\n key: 'math', labelKey: 'mdTplMath', icon: '🔢',\n content: `## Math Formulas (TeX)\n\n### Euler's Identity\n\n$$\ne^{i\\\\pi} + 1 = 0\n$$\n\n### Quadratic Formula\n\n$$\nx = \\\\frac{-b \\\\pm \\\\sqrt{b^2 - 4ac}}{2a}\n$$\n\n### Gaussian Integral\n\n$$\n\\\\int_{-\\\\infty}^{\\\\infty} e^{-x^2} \\\\, dx = \\\\sqrt{\\\\pi}\n$$\n\n### Maxwell's Equations\n\n$$\n\\\\nabla \\\\cdot \\\\mathbf{E} = \\\\frac{\\\\rho}{\\\\epsilon_0}\n$$\n\n$$\n\\\\nabla \\\\cdot \\\\mathbf{B} = 0\n$$\n\n$$\n\\\\nabla \\\\times \\\\mathbf{E} = -\\\\frac{\\\\partial \\\\mathbf{B}}{\\\\partial t}\n$$\n\n$$\n\\\\nabla \\\\times \\\\mathbf{B} = \\\\mu_0 \\\\mathbf{J} + \\\\mu_0 \\\\epsilon_0 \\\\frac{\\\\partial \\\\mathbf{E}}{\\\\partial t}\n$$\n\n### Taylor Series Expansion\n\n$$\nf(x) = \\\\sum_{n=0}^{\\\\infty} \\\\frac{f^{(n)}(a)}{n!}(x-a)^n\n$$\n\n### Matrix Notation\n\n$$\n\\\\mathbf{A} = \\\\begin{pmatrix} a_{11} & a_{12} & \\\\cdots & a_{1n} \\\\\\\\ a_{21} & a_{22} & \\\\cdots & a_{2n} \\\\\\\\ \\\\vdots & \\\\vdots & \\\\ddots & \\\\vdots \\\\\\\\ a_{m1} & a_{m2} & \\\\cdots & a_{mn} \\\\end{pmatrix}\n$$\n\n### Inline math: The identity $e^{i\\\\theta} = \\\\cos\\\\theta + i\\\\sin\\\\theta$ is known as Euler's formula.\n`,\n },\n {\n key: 'mixed', labelKey: 'mdTplMixed', icon: '🎨',\n content: `## Mixed Content Example\n\n### Architecture Overview\n\n\\`\\`\\`mermaid\ngraph LR\n Client[Client App] --> Gateway[API Gateway]\n Gateway --> Auth[Auth Service]\n Gateway --> Core[Core Service]\n Core --> DB[(PostgreSQL)]\n Core --> Cache[(Redis)]\n Auth --> DB\n\\`\\`\\`\n\n### Performance Formula\n\nThe response time $T$ is calculated as:\n\n$$\nT = T_{network} + T_{processing} + T_{db}\n$$\n\nwhere $T_{db} = O(\\\\log n)$ with proper indexing.\n\n### Implementation\n\n\\`\\`\\`python\nfrom fastapi import FastAPI, Depends\nfrom functools import lru_cache\n\napp = FastAPI()\n\n@lru_cache(maxsize=256)\ndef compute_heavy(n: int) -> float:\n \"\"\"Cached computation: O(log n) amortized.\"\"\"\n return sum(1.0 / i for i in range(1, n + 1))\n\n@app.get(\"/api/harmonic/{n}\")\nasync def harmonic(n: int):\n result = compute_heavy(n)\n return {\"n\": n, \"H_n\": round(result, 6)}\n\\`\\`\\`\n\n### Project Status\n\n\\`\\`\\`mermaid\npie title Sprint Progress\n \"Completed\" : 65\n \"In Progress\" : 20\n \"Blocked\" : 10\n \"Not Started\" : 5\n\\`\\`\\`\n`,\n },\n];\n\ninterface MarkdownTemplateMenuProps {\n labels: RichTextEditorLabels;\n onSelect: (content: string, focusEditor?: boolean) => void;\n}\n\nexport const MarkdownTemplateMenu: React.FC<MarkdownTemplateMenuProps> = ({ labels, onSelect }) => {\n const [isOpen, setIsOpen] = useState(false);\n const ref = useRef<HTMLDivElement>(null);\n const triggerRef = useRef<HTMLButtonElement>(null);\n const dropdownRef = useRef<HTMLDivElement>(null);\n const dropdownStyle = useAnchoredDropdown(isOpen, triggerRef, dropdownRef);\n const pointerType = useRef('');\n const select = (event: React.MouseEvent, content: string) => {\n // Touch insertion must not enter Android's native editing/IME focus path.\n const focusEditor = event.detail === 0 || pointerType.current !== 'touch';\n flushSync(() => setIsOpen(false));\n onSelect(content, focusEditor);\n };\n\n useEffect(() => {\n const handler = (e: PointerEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) {\n setIsOpen(false);\n }\n };\n document.addEventListener('pointerdown', handler);\n return () => document.removeEventListener('pointerdown', handler);\n }, []);\n\n return (\n <div ref={ref} className=\"rte-toolbar__template-menu\" onPointerDown={(event) => { pointerType.current = event.pointerType; }}>\n <button\n type=\"button\"\n ref={triggerRef}\n className={`rte-toolbar__btn ${isOpen ? 'rte-toolbar__btn--active' : ''}`}\n aria-expanded={isOpen}\n onClick={() => setIsOpen(!isOpen)}\n title={labels.mdTemplates || 'Markdown Templates'}\n style={{ width: 'auto', padding: '0 6px', gap: '2px', display: 'inline-flex', alignItems: 'center' }}\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <rect x=\"3\" y=\"3\" width=\"8\" height=\"8\" rx=\"1.5\" />\n <rect x=\"13\" y=\"3\" width=\"8\" height=\"8\" rx=\"1.5\" />\n <rect x=\"3\" y=\"13\" width=\"8\" height=\"8\" rx=\"1.5\" />\n <path d=\"M17 14v6M14 17h6\" />\n </svg>\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2.5\">\n <polyline points=\"6 9 12 15 18 9\" />\n </svg>\n </button>\n {isOpen && (\n <div ref={dropdownRef} className=\"rte-toolbar__template-dropdown\" style={dropdownStyle}>\n <div className=\"rte-toolbar__template-group-label\">Mermaid</div>\n {MD_TEMPLATES.filter(t => ['flowchart', 'sequence', 'pie', 'gantt', 'xychart'].includes(t.key)).map(t => (\n <button\n key={t.key}\n type=\"button\"\n className=\"rte-toolbar__template-item\"\n onClick={(event) => select(event, t.content)}\n >\n <span className=\"rte-toolbar__template-icon\">{t.icon}</span>\n <span>{labels[t.labelKey] || t.labelKey}</span>\n </button>\n ))}\n <div className=\"rte-toolbar__template-group-label\">Code</div>\n {MD_TEMPLATES.filter(t => ['python', 'typescript', 'rust'].includes(t.key)).map(t => (\n <button\n key={t.key}\n type=\"button\"\n className=\"rte-toolbar__template-item\"\n onClick={(event) => select(event, t.content)}\n >\n <span className=\"rte-toolbar__template-icon\">{t.icon}</span>\n <span>{labels[t.labelKey] || t.labelKey}</span>\n </button>\n ))}\n <div className=\"rte-toolbar__template-group-label\">Math / Mixed</div>\n {MD_TEMPLATES.filter(t => ['math', 'mixed'].includes(t.key)).map(t => (\n <button\n key={t.key}\n type=\"button\"\n className=\"rte-toolbar__template-item\"\n onClick={(event) => select(event, t.content)}\n >\n <span className=\"rte-toolbar__template-icon\">{t.icon}</span>\n <span>{labels[t.labelKey] || t.labelKey}</span>\n </button>\n ))}\n </div>\n )}\n </div>\n );\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"SelectDropdown.js","names":[],"sources":["../../../../../src/components/pro/RichTextEditor/Toolbar/SelectDropdown.tsx"],"sourcesContent":["import React from 'react';\nimport Select from '../../../Select';\n\nexport const FONT_FAMILIES = [\n { label: 'Default', value: '' },\n { label: 'Arial', value: 'Arial, sans-serif' },\n { label: 'Helvetica', value: 'Helvetica, sans-serif' },\n { label: 'Georgia', value: 'Georgia, serif' },\n { label: 'Times New Roman', value: 'Times New Roman, serif' },\n { label: 'Courier New', value: 'Courier New, monospace' },\n { label: 'Verdana', value: 'Verdana, sans-serif' },\n { label: 'Trebuchet MS', value: 'Trebuchet MS, sans-serif' },\n { label: 'Impact', value: 'Impact, sans-serif' },\n { label: 'Comic Sans MS', value: 'Comic Sans MS, cursive' },\n];\n\nexport const FONT_SIZES = [\n { label: 'Default', value: '' },\n { label: '10px', value: '10px' },\n { label: '12px', value: '12px' },\n { label: '14px', value: '14px' },\n { label: '16px', value: '16px' },\n { label: '18px', value: '18px' },\n { label: '20px', value: '20px' },\n { label: '24px', value: '24px' },\n { label: '28px', value: '28px' },\n { label: '32px', value: '32px' },\n { label: '36px', value: '36px' },\n { label: '48px', value: '48px' },\n { label: '64px', value: '64px' },\n { label: '72px', value: '72px' },\n];\n\ninterface SelectDropdownProps {\n value: string;\n options: { label: string; value: string }[];\n onChange: (value: string) => void;\n title?: string;\n width?: number;\n className?: string;\n}\n\nexport const SelectDropdown: React.FC<SelectDropdownProps> = ({ value, options, onChange, title, width = 110, className = 'rte-toolbar__select' }) => (\n <Select\n className={className}\n style={{ width }}\n options={options}\n value={value}\n onChange={(next) => onChange(String(next))}\n aria-label={title ?? 'Formatting option'}\n />\n);\n"],"mappings":";;;;AAGA,IAAa,IAAgB;CAC3B;EAAE,OAAO;EAAW,OAAO;CAAG;CAC9B;EAAE,OAAO;EAAS,OAAO;CAAoB;CAC7C;EAAE,OAAO;EAAa,OAAO;CAAwB;CACrD;EAAE,OAAO;EAAW,OAAO;CAAiB;CAC5C;EAAE,OAAO;EAAmB,OAAO;CAAyB;CAC5D;EAAE,OAAO;EAAe,OAAO;CAAyB;CACxD;EAAE,OAAO;EAAW,OAAO;CAAsB;CACjD;EAAE,OAAO;EAAgB,OAAO;CAA2B;CAC3D;EAAE,OAAO;EAAU,OAAO;CAAqB;CAC/C;EAAE,OAAO;EAAiB,OAAO;CAAyB;AAC5D,GAEa,IAAa;CACxB;EAAE,OAAO;EAAW,OAAO;CAAG;CAC9B;EAAE,OAAO;EAAQ,OAAO;CAAO;CAC/B;EAAE,OAAO;EAAQ,OAAO;CAAO;CAC/B;EAAE,OAAO;EAAQ,OAAO;CAAO;CAC/B;EAAE,OAAO;EAAQ,OAAO;CAAO;CAC/B;EAAE,OAAO;EAAQ,OAAO;CAAO;CAC/B;EAAE,OAAO;EAAQ,OAAO;CAAO;CAC/B;EAAE,OAAO;EAAQ,OAAO;CAAO;CAC/B;EAAE,OAAO;EAAQ,OAAO;CAAO;CAC/B;EAAE,OAAO;EAAQ,OAAO;CAAO;CAC/B;EAAE,OAAO;EAAQ,OAAO;CAAO;CAC/B;EAAE,OAAO;EAAQ,OAAO;CAAO;CAC/B;EAAE,OAAO;EAAQ,OAAO;CAAO;CAC/B;EAAE,OAAO;EAAQ,OAAO;CAAO;AACjC,GAWa,KAAiD,EAAE,UAAO,YAAS,aAAU,UAAO,WAAQ,KAAK,eAAY,4BACxH,kBAAC,GAAD;CACa;CACX,OAAO,EAAE,SAAM;CACN;CACF;CACP,WAAW,MAAS,EAAS,OAAO,CAAI,CAAC;CACzC,cAAY,KAAS;AACtB,CAAA"}
1
+ {"version":3,"file":"SelectDropdown.js","names":["Select","FONT_FAMILIES","FONT_SIZES","SelectDropdown","onChange","next","title"],"sources":["../../../../../src/components/pro/RichTextEditor/Toolbar/SelectDropdown.tsx"],"sourcesContent":["import React from 'react';\nimport Select from '../../../Select';\n\nexport const FONT_FAMILIES = [\n { label: 'Default', value: '' },\n { label: 'Arial', value: 'Arial, sans-serif' },\n { label: 'Helvetica', value: 'Helvetica, sans-serif' },\n { label: 'Georgia', value: 'Georgia, serif' },\n { label: 'Times New Roman', value: 'Times New Roman, serif' },\n { label: 'Courier New', value: 'Courier New, monospace' },\n { label: 'Verdana', value: 'Verdana, sans-serif' },\n { label: 'Trebuchet MS', value: 'Trebuchet MS, sans-serif' },\n { label: 'Impact', value: 'Impact, sans-serif' },\n { label: 'Comic Sans MS', value: 'Comic Sans MS, cursive' },\n];\n\nexport const FONT_SIZES = [\n { label: 'Default', value: '' },\n { label: '10px', value: '10px' },\n { label: '12px', value: '12px' },\n { label: '14px', value: '14px' },\n { label: '16px', value: '16px' },\n { label: '18px', value: '18px' },\n { label: '20px', value: '20px' },\n { label: '24px', value: '24px' },\n { label: '28px', value: '28px' },\n { label: '32px', value: '32px' },\n { label: '36px', value: '36px' },\n { label: '48px', value: '48px' },\n { label: '64px', value: '64px' },\n { label: '72px', value: '72px' },\n];\n\ninterface SelectDropdownProps {\n value: string;\n options: { label: string; value: string }[];\n onChange: (value: string) => void;\n title?: string;\n width?: number;\n className?: string;\n}\n\nexport const SelectDropdown: React.FC<SelectDropdownProps> = ({ value, options, onChange, title, width = 110, className = 'rte-toolbar__select' }) => (\n <Select\n className={className}\n style={{ width }}\n options={options}\n value={value}\n onChange={(next) => onChange(String(next))}\n aria-label={title ?? 'Formatting option'}\n />\n);\n"],"mappings":";;;;AAGA,IAAaC,IAAgB;CAC3B;EAAE,OAAO;EAAW,OAAO;CAAG;CAC9B;EAAE,OAAO;EAAS,OAAO;CAAoB;CAC7C;EAAE,OAAO;EAAa,OAAO;CAAwB;CACrD;EAAE,OAAO;EAAW,OAAO;CAAiB;CAC5C;EAAE,OAAO;EAAmB,OAAO;CAAyB;CAC5D;EAAE,OAAO;EAAe,OAAO;CAAyB;CACxD;EAAE,OAAO;EAAW,OAAO;CAAsB;CACjD;EAAE,OAAO;EAAgB,OAAO;CAA2B;CAC3D;EAAE,OAAO;EAAU,OAAO;CAAqB;CAC/C;EAAE,OAAO;EAAiB,OAAO;CAAyB;AAC5D,GAEaC,IAAa;CACxB;EAAE,OAAO;EAAW,OAAO;CAAG;CAC9B;EAAE,OAAO;EAAQ,OAAO;CAAO;CAC/B;EAAE,OAAO;EAAQ,OAAO;CAAO;CAC/B;EAAE,OAAO;EAAQ,OAAO;CAAO;CAC/B;EAAE,OAAO;EAAQ,OAAO;CAAO;CAC/B;EAAE,OAAO;EAAQ,OAAO;CAAO;CAC/B;EAAE,OAAO;EAAQ,OAAO;CAAO;CAC/B;EAAE,OAAO;EAAQ,OAAO;CAAO;CAC/B;EAAE,OAAO;EAAQ,OAAO;CAAO;CAC/B;EAAE,OAAO;EAAQ,OAAO;CAAO;CAC/B;EAAE,OAAO;EAAQ,OAAO;CAAO;CAC/B;EAAE,OAAO;EAAQ,OAAO;CAAO;CAC/B;EAAE,OAAO;EAAQ,OAAO;CAAO;CAC/B;EAAE,OAAO;EAAQ,OAAO;CAAO;AACjC,GAWaC,KAAiD,EAAE,UAAO,YAAS,aAAU,UAAO,WAAQ,KAAK,eAAY,4BACxH,kBAACH,GAAD;CACa;CACX,OAAO,EAAE,SAAM;CACN;CACF;CACP,WAAW,MAASI,EAAS,OAAOC,CAAI,CAAC;CACzC,cAAYC,KAAS;AACtB,CAAA"}