dishui 0.0.64 → 0.0.65

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 (177) hide show
  1. package/dist/components/Badge/index.js +12 -9
  2. package/dist/components/Badge/index.js.map +1 -1
  3. package/dist/components/Button/index.js +43 -40
  4. package/dist/components/Button/index.js.map +1 -1
  5. package/dist/components/Card/index.d.ts +11 -0
  6. package/dist/components/Card/index.js +62 -37
  7. package/dist/components/Card/index.js.map +1 -1
  8. package/dist/components/Chart/Chart.js.map +1 -1
  9. package/dist/components/Checkbox/index.js +32 -30
  10. package/dist/components/Checkbox/index.js.map +1 -1
  11. package/dist/components/Demo/index.js.map +1 -1
  12. package/dist/components/EmptyState/index.d.ts +4 -1
  13. package/dist/components/EmptyState/index.js +3 -3
  14. package/dist/components/EmptyState/index.js.map +1 -1
  15. package/dist/components/FileUploader/DropZone.js.map +1 -1
  16. package/dist/components/FileUploader/FileItem.js.map +1 -1
  17. package/dist/components/FileUploader/FileUploader.js.map +1 -1
  18. package/dist/components/FileUploader/UploadQueue.js.map +1 -1
  19. package/dist/components/Input/index.js +30 -30
  20. package/dist/components/Input/index.js.map +1 -1
  21. package/dist/components/Label/index.js +41 -40
  22. package/dist/components/Label/index.js.map +1 -1
  23. package/dist/components/List/index.js +47 -32
  24. package/dist/components/List/index.js.map +1 -1
  25. package/dist/components/Markdown/Markdown.js +61 -57
  26. package/dist/components/Markdown/Markdown.js.map +1 -1
  27. package/dist/components/Markdown/markdownComponents.js +49 -49
  28. package/dist/components/Markdown/markdownComponents.js.map +1 -1
  29. package/dist/components/Modal/index.d.ts +7 -3
  30. package/dist/components/Modal/index.js +77 -65
  31. package/dist/components/Modal/index.js.map +1 -1
  32. package/dist/components/Page/index.d.ts +58 -0
  33. package/dist/components/Page/index.js +74 -0
  34. package/dist/components/Page/index.js.map +1 -0
  35. package/dist/components/PageHeader/index.js.map +1 -1
  36. package/dist/components/Select/index.js +0 -3
  37. package/dist/components/Select/index.js.map +1 -1
  38. package/dist/components/SidebarToggleButton/index.js.map +1 -1
  39. package/dist/components/StatCard/index.d.ts +3 -1
  40. package/dist/components/StatCard/index.js +39 -11
  41. package/dist/components/StatCard/index.js.map +1 -1
  42. package/dist/components/Table/index.js +103 -85
  43. package/dist/components/Table/index.js.map +1 -1
  44. package/dist/components/Tabs/index.d.ts +19 -5
  45. package/dist/components/Tabs/index.js +32 -13
  46. package/dist/components/Tabs/index.js.map +1 -1
  47. package/dist/components/Tree/Tree.js.map +1 -1
  48. package/dist/components/pro/ArticleContextMenu/index.js.map +1 -1
  49. package/dist/components/pro/ArticleControl/ArticleControl2.js.map +1 -1
  50. package/dist/components/pro/CodeEditor/editors/CodeEditor.js +141 -134
  51. package/dist/components/pro/CodeEditor/editors/CodeEditor.js.map +1 -1
  52. package/dist/components/pro/CodeEditor/editors/MarkdownEditor.js +81 -78
  53. package/dist/components/pro/CodeEditor/editors/MarkdownEditor.js.map +1 -1
  54. package/dist/components/pro/CodeEditor/panels/FootnotePanel.js.map +1 -1
  55. package/dist/components/pro/CodeEditor/panels/HistoryPanel.js.map +1 -1
  56. package/dist/components/pro/CodeEditor/panels/OutlinePanel.js.map +1 -1
  57. package/dist/components/pro/CodeEditor/panels/TableOfContentsPanel.js.map +1 -1
  58. package/dist/components/pro/CodeEditor/panels/VariablePanel.js.map +1 -1
  59. package/dist/components/pro/CodeEditor/themes.js +59 -59
  60. package/dist/components/pro/CodeEditor/themes.js.map +1 -1
  61. package/dist/components/pro/DataTable/DataTable.js +49 -48
  62. package/dist/components/pro/DataTable/DataTable.js.map +1 -1
  63. package/dist/components/pro/DataTable/Filters.js +42 -42
  64. package/dist/components/pro/DataTable/Filters.js.map +1 -1
  65. package/dist/components/pro/DataTable/PivotPanel.js.map +1 -1
  66. package/dist/components/pro/DataTable/PivotView.js +35 -32
  67. package/dist/components/pro/DataTable/PivotView.js.map +1 -1
  68. package/dist/components/pro/DataTable/components/BulkActions.js.map +1 -1
  69. package/dist/components/pro/DataTable/components/ColumnSelector.js.map +1 -1
  70. package/dist/components/pro/DataTable/components/FilterBar.js.map +1 -1
  71. package/dist/components/pro/DataTable/components/TableBody.js.map +1 -1
  72. package/dist/components/pro/DataTable/components/TableHeader.js.map +1 -1
  73. package/dist/components/pro/DataTable/components/TablePagination.js.map +1 -1
  74. package/dist/components/pro/DataTable/components/TableToolbar.js.map +1 -1
  75. package/dist/components/pro/DataTable/pivotExtension.js.map +1 -1
  76. package/dist/components/pro/DataTable/rowDetailExtension.js.map +1 -1
  77. package/dist/components/pro/DataTable/tanstack-table.js +37 -37
  78. package/dist/components/pro/DataTable/tanstack-table.js.map +1 -1
  79. package/dist/components/pro/FileExplorer/Breadcrumb.js +53 -53
  80. package/dist/components/pro/FileExplorer/Breadcrumb.js.map +1 -1
  81. package/dist/components/pro/FileExplorer/CreateDialog.js.map +1 -1
  82. package/dist/components/pro/FileExplorer/FileExplorer.js.map +1 -1
  83. package/dist/components/pro/FileExplorer/FileIcon.js +22 -22
  84. package/dist/components/pro/FileExplorer/FileIcon.js.map +1 -1
  85. package/dist/components/pro/FileExplorer/GridView.js.map +1 -1
  86. package/dist/components/pro/FileExplorer/ListView.js.map +1 -1
  87. package/dist/components/pro/FileExplorer/Toolbar.js.map +1 -1
  88. package/dist/components/pro/Flow/Flow.js +496 -494
  89. package/dist/components/pro/Flow/Flow.js.map +1 -1
  90. package/dist/components/pro/Flow/FlowCanvas.js +916 -917
  91. package/dist/components/pro/Flow/FlowCanvas.js.map +1 -1
  92. package/dist/components/pro/Flow/context/FlowUIContext.js.map +1 -1
  93. package/dist/components/pro/Flow/edges/EdgeRenderer.js +59 -59
  94. package/dist/components/pro/Flow/edges/EdgeRenderer.js.map +1 -1
  95. package/dist/components/pro/Flow/hooks/useClipboard.js.map +1 -1
  96. package/dist/components/pro/Flow/hooks/useDeleteSelection.js.map +1 -1
  97. package/dist/components/pro/Flow/hooks/useEdgeMutations.js.map +1 -1
  98. package/dist/components/pro/Flow/hooks/useLayoutActions.js +9 -11
  99. package/dist/components/pro/Flow/hooks/useLayoutActions.js.map +1 -1
  100. package/dist/components/pro/Flow/hooks/useLineMutations.js.map +1 -1
  101. package/dist/components/pro/Flow/hooks/useMindMap.js.map +1 -1
  102. package/dist/components/pro/Flow/hooks/useNodeMutations.js.map +1 -1
  103. package/dist/components/pro/Flow/lines/FreehandTool.js +9 -9
  104. package/dist/components/pro/Flow/lines/FreehandTool.js.map +1 -1
  105. package/dist/components/pro/Flow/lines/LineRenderer.js +5 -5
  106. package/dist/components/pro/Flow/lines/LineRenderer.js.map +1 -1
  107. package/dist/components/pro/Flow/nodes/DataNodeView.js +113 -93
  108. package/dist/components/pro/Flow/nodes/DataNodeView.js.map +1 -1
  109. package/dist/components/pro/Flow/nodes/MediaContent.js.map +1 -1
  110. package/dist/components/pro/Flow/nodes/MediaOverlay.js.map +1 -1
  111. package/dist/components/pro/Flow/nodes/Model3DView.js +1 -1
  112. package/dist/components/pro/Flow/nodes/Model3DView.js.map +1 -1
  113. package/dist/components/pro/Flow/nodes/NodeRenderer.js +118 -118
  114. package/dist/components/pro/Flow/nodes/NodeRenderer.js.map +1 -1
  115. package/dist/components/pro/Flow/nodes/dataUtils.js.map +1 -1
  116. package/dist/components/pro/Flow/nodes/shapes.js +1 -3
  117. package/dist/components/pro/Flow/nodes/shapes.js.map +1 -1
  118. package/dist/components/pro/Flow/panels/AIPanel.js.map +1 -1
  119. package/dist/components/pro/Flow/panels/Breadcrumb.js.map +1 -1
  120. package/dist/components/pro/Flow/panels/ContextMenu.js.map +1 -1
  121. package/dist/components/pro/Flow/panels/DataInspectorSection.js.map +1 -1
  122. package/dist/components/pro/Flow/panels/ExpandableTextarea.js.map +1 -1
  123. package/dist/components/pro/Flow/panels/FlowPanelGroup.js.map +1 -1
  124. package/dist/components/pro/Flow/panels/FlowToolbar.js +97 -97
  125. package/dist/components/pro/Flow/panels/FlowToolbar.js.map +1 -1
  126. package/dist/components/pro/Flow/panels/InspectorPanel.js +57 -57
  127. package/dist/components/pro/Flow/panels/InspectorPanel.js.map +1 -1
  128. package/dist/components/pro/Flow/panels/OutlinePanel.js +26 -22
  129. package/dist/components/pro/Flow/panels/OutlinePanel.js.map +1 -1
  130. package/dist/components/pro/Flow/panels/PresentationMode.js +18 -16
  131. package/dist/components/pro/Flow/panels/PresentationMode.js.map +1 -1
  132. package/dist/components/pro/Flow/panels/ProjectTitle.js.map +1 -1
  133. package/dist/components/pro/Flow/panels/ShapePalette.js +109 -104
  134. package/dist/components/pro/Flow/panels/ShapePalette.js.map +1 -1
  135. package/dist/components/pro/Flow/panels/toolbarIcons.js.map +1 -1
  136. package/dist/components/pro/RichTextEditor/AIRewrite.js.map +1 -1
  137. package/dist/components/pro/RichTextEditor/BlockHandle.js.map +1 -1
  138. package/dist/components/pro/RichTextEditor/BubbleToolbar.js.map +1 -1
  139. package/dist/components/pro/RichTextEditor/CommentDialog.js.map +1 -1
  140. package/dist/components/pro/RichTextEditor/CommentPanel.js.map +1 -1
  141. package/dist/components/pro/RichTextEditor/CommentPopover.js.map +1 -1
  142. package/dist/components/pro/RichTextEditor/ContextMenu.js.map +1 -1
  143. package/dist/components/pro/RichTextEditor/RichTextEditor.js.map +1 -1
  144. package/dist/components/pro/RichTextEditor/SlashMenu.js.map +1 -1
  145. package/dist/components/pro/RichTextEditor/Toolbar/ColorPicker.js.map +1 -1
  146. package/dist/components/pro/RichTextEditor/Toolbar/FloatingDialogMenu.js.map +1 -1
  147. package/dist/components/pro/RichTextEditor/Toolbar/MarkdownTemplates.js.map +1 -1
  148. package/dist/components/pro/RichTextEditor/Toolbar/SelectDropdown.js.map +1 -1
  149. package/dist/components/pro/RichTextEditor/Toolbar/TableOpsMenu.js.map +1 -1
  150. package/dist/components/pro/RichTextEditor/Toolbar/Toolbar.js.map +1 -1
  151. package/dist/components/pro/RichTextEditor/extensions/CodeBlockView.js.map +1 -1
  152. package/dist/components/pro/RichTextEditor/extensions/FloatingDialog.js.map +1 -1
  153. package/dist/components/pro/RichTextEditor/extensions/MarkdownBlock.js.map +1 -1
  154. package/dist/contexts/AppContext.js.map +1 -1
  155. package/dist/dishui.css +1 -1
  156. package/dist/hooks/useTableColumns.js +7 -8
  157. package/dist/hooks/useTableColumns.js.map +1 -1
  158. package/dist/index.d.ts +2 -0
  159. package/dist/index.js +227 -221
  160. package/dist/layouts/MainLayout.js +22 -22
  161. package/dist/layouts/MainLayout.js.map +1 -1
  162. package/dist/layouts/Navbar.js.map +1 -1
  163. package/dist/layouts/Sidebar.js +94 -73
  164. package/dist/layouts/Sidebar.js.map +1 -1
  165. package/dist/layouts/headbar/Headbar.js.map +1 -1
  166. package/dist/layouts/headbar/HeadbarLangSwitcher.js.map +1 -1
  167. package/dist/layouts/headbar/HeadbarSearch.js.map +1 -1
  168. package/dist/layouts/headbar/HeadbarThemeSwitcher.js +11 -11
  169. package/dist/layouts/headbar/HeadbarThemeSwitcher.js.map +1 -1
  170. package/dist/layouts/headbar/HeadbarTitle.js.map +1 -1
  171. package/dist/utils/i18n.js +10 -10
  172. package/dist/utils/i18n.js.map +1 -1
  173. package/dist/utils/menu.js.map +1 -1
  174. package/dist/utils/routerBuilder.js +17 -15
  175. package/dist/utils/routerBuilder.js.map +1 -1
  176. package/dist/utils/themes.js.map +1 -1
  177. package/package.json +7 -7
@@ -1 +1 @@
1
- {"version":3,"file":"toolbarIcons.js","names":[],"sources":["../../../../../src/components/pro/Flow/panels/toolbarIcons.tsx"],"sourcesContent":["import React from 'react';\n\n/**\n * Toolbar icon set for the Flow editor.\n * Compact 20x20 stroke icons that inherit `currentColor`, so they follow the\n * button's variant (primary/ghost) automatically.\n */\n\nconst base = {\n width: 18,\n height: 18,\n viewBox: '0 0 24 24',\n fill: 'none',\n stroke: 'currentColor',\n strokeWidth: 2,\n strokeLinecap: 'round' as const,\n strokeLinejoin: 'round' as const,\n};\n\nexport const IconSelect: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <path d=\"M4 3l7 17 2.5-6.5L20 11 4 3z\" />\n </svg>\n);\n\n\nexport const IconAutoFocus: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <circle cx=\"12\" cy=\"12\" r=\"6\" />\n <circle cx=\"12\" cy=\"12\" r=\"2\" />\n <path d=\"M4 12H2M22 12h-2M12 4V2M12 22v-2\" />\n <path d=\"M17.5 5.5l1-1M5.5 17.5l-1 1\" />\n </svg>\n);\n\nexport const IconBack: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <path d=\"M19 12H5\" />\n <path d=\"M11 18l-6-6 6-6\" />\n </svg>\n);\n\nexport const IconUndo: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <path d=\"M9 14L4 9l5-5\" />\n <path d=\"M4 9h11a5 5 0 0 1 0 10h-4\" />\n </svg>\n);\n\nexport const IconRedo: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <path d=\"M15 14l5-5-5-5\" />\n <path d=\"M20 9H9a5 5 0 0 0 0 10h4\" />\n </svg>\n);\n\nexport const IconGroup: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <rect x=\"3\" y=\"3\" width=\"8\" height=\"8\" rx=\"1\" />\n <rect x=\"13\" y=\"13\" width=\"8\" height=\"8\" rx=\"1\" />\n <path d=\"M13 6h4a1 1 0 0 1 1 1v4\" strokeDasharray=\"2 2\" />\n </svg>\n);\n\nexport const IconGeoGroup: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" strokeDasharray=\"3 3\" />\n <rect x=\"7\" y=\"7\" width=\"4\" height=\"4\" rx=\"0.5\" />\n <rect x=\"13\" y=\"13\" width=\"4\" height=\"4\" rx=\"0.5\" />\n </svg>\n);\n\nexport const IconUngroup: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <rect x=\"3\" y=\"3\" width=\"7\" height=\"7\" rx=\"1\" />\n <rect x=\"14\" y=\"14\" width=\"7\" height=\"7\" rx=\"1\" />\n <path d=\"M14 5h5M17 3v4\" />\n </svg>\n);\n\nexport type AlignIconKind = 'left' | 'center-h' | 'right' | 'top' | 'center-v' | 'bottom' | 'distribute-h' | 'distribute-v';\n\nexport const IconAlign: React.FC<{ kind: AlignIconKind }> = ({ kind }) => {\n const vertical = kind === 'left' || kind === 'center-h' || kind === 'right';\n if (vertical) {\n const x = kind === 'left' ? 5 : kind === 'right' ? 19 : 12;\n return (\n <svg {...base} aria-hidden=\"true\">\n <path d={`M${x} 3v18`} />\n <rect x={kind === 'left' ? 5 : kind === 'right' ? 10 : 7} y=\"5\" width=\"9\" height=\"4\" rx=\"0.5\" />\n <rect x={kind === 'left' ? 5 : kind === 'right' ? 5 : 4} y=\"14\" width=\"14\" height=\"4\" rx=\"0.5\" />\n </svg>\n );\n }\n if (kind === 'top' || kind === 'center-v' || kind === 'bottom') {\n const y = kind === 'top' ? 5 : kind === 'bottom' ? 19 : 12;\n return (\n <svg {...base} aria-hidden=\"true\">\n <path d={`M3 ${y}h18`} />\n <rect x=\"5\" y={kind === 'top' ? 5 : kind === 'bottom' ? 10 : 7} width=\"4\" height=\"9\" rx=\"0.5\" />\n <rect x=\"14\" y={kind === 'top' ? 5 : kind === 'bottom' ? 5 : 4} width=\"4\" height=\"14\" rx=\"0.5\" />\n </svg>\n );\n }\n return (\n <svg {...base} aria-hidden=\"true\">\n {kind === 'distribute-h' ? (\n <><path d=\"M3 3v18M21 3v18\" /><rect x=\"6\" y=\"7\" width=\"4\" height=\"10\" /><rect x=\"14\" y=\"7\" width=\"4\" height=\"10\" /></>\n ) : (\n <><path d=\"M3 3h18M3 21h18\" /><rect x=\"7\" y=\"6\" width=\"10\" height=\"4\" /><rect x=\"7\" y=\"14\" width=\"10\" height=\"4\" /></>\n )}\n </svg>\n );\n};\n\nexport const IconZoomOut: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <circle cx=\"11\" cy=\"11\" r=\"7\" />\n <path d=\"M21 21l-4.3-4.3M8 11h6\" />\n </svg>\n);\n\nexport const IconZoomIn: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <circle cx=\"11\" cy=\"11\" r=\"7\" />\n <path d=\"M21 21l-4.3-4.3M11 8v6M8 11h6\" />\n </svg>\n);\n\nexport const IconFitView: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <path d=\"M4 9V5a1 1 0 0 1 1-1h4M15 4h4a1 1 0 0 1 1 1v4M20 15v4a1 1 0 0 1-1 1h-4M9 20H5a1 1 0 0 1-1-1v-4\" />\n <rect x=\"9\" y=\"9\" width=\"6\" height=\"6\" rx=\"1\" />\n </svg>\n);\n\nexport const IconShapes: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <rect x=\"3\" y=\"13\" width=\"8\" height=\"8\" rx=\"1\" />\n <circle cx=\"17\" cy=\"7\" r=\"4\" />\n <path d=\"M13 21l4-7 4 7z\" />\n </svg>\n);\n\nexport const IconInspector: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n <path d=\"M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z\" />\n </svg>\n);\n\nexport const IconOutline: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <path d=\"M8 6h13M8 12h13M8 18h13M3 6h.01M3 12h.01M3 18h.01\" />\n </svg>\n);\n\nexport const IconJson: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <path d=\"M8 4H7a2 2 0 0 0-2 2v3a2 2 0 0 1-2 2 2 2 0 0 1 2 2v3a2 2 0 0 0 2 2h1\" />\n <path d=\"M16 4h1a2 2 0 0 1 2 2v3a2 2 0 0 0 2 2 2 2 0 0 0-2 2v3a2 2 0 0 1-2 2h-1\" />\n </svg>\n);\n\nexport const IconAI: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <path d=\"M12 3l1.9 4.6L18.5 9.5 13.9 11.4 12 16l-1.9-4.6L5.5 9.5l4.6-1.9L12 3z\" />\n <path d=\"M18 15l.9 2.1L21 18l-2.1.9L18 21l-.9-2.1L15 18l2.1-.9L18 15z\" />\n </svg>\n);\n\nexport const IconGrid: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" />\n <path d=\"M9 3v18M15 3v18M3 9h18M3 15h18\" />\n </svg>\n);\n\n/** Placement magnet (snap stamps to the canvas grid). */\nexport const IconMagnet: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <path d=\"M4 12V6a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v6a2 2 0 0 0 4 0V6a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v6a7 7 0 0 1-14 0\" />\n <path d=\"M4 9.5h6M14 9.5h6\" />\n </svg>\n);\n\nexport const IconMiniMap: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <rect x=\"3\" y=\"4\" width=\"18\" height=\"16\" rx=\"2\" />\n <rect x=\"13\" y=\"12\" width=\"6\" height=\"6\" rx=\"1\" />\n </svg>\n);\n\nexport const IconImport: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <path d=\"M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8z\" />\n <path d=\"M14 3v5h5\" />\n <path d=\"M12 18v-6\" />\n <path d=\"M9.5 14.5 12 12l2.5 2.5\" />\n </svg>\n);\n\nexport const IconExport: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <path d=\"M12 15V3\" />\n <path d=\"M8 7l4-4 4 4\" />\n <path d=\"M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2\" />\n </svg>\n);\n\nexport const IconPublish: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <path d=\"M22 2 11 13\" />\n <path d=\"M22 2 15 22l-4-9-9-4 20-7z\" />\n </svg>\n);\n\nexport const IconExportImage: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <rect x=\"3\" y=\"4\" width=\"18\" height=\"16\" rx=\"2\" />\n <circle cx=\"9\" cy=\"9\" r=\"1.5\" />\n <path d=\"M4 17l5-5 3 3 2-2 6 6\" />\n <path d=\"M16 3v7m-3-3 3 3 3-3\" />\n </svg>\n);\n\n/** Export PNG: an image frame with a download arrow into a tray. */\nexport const IconExportPng: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <rect x=\"3\" y=\"3\" width=\"12\" height=\"10\" rx=\"1.5\" />\n <circle cx=\"6.5\" cy=\"6.5\" r=\"1\" />\n <path d=\"M3 11l3.5-3 3 2.5\" />\n <path d=\"M19 12v6M16.5 15.5 19 18l2.5-2.5\" />\n <path d=\"M14 21h10\" opacity=\"0.5\" />\n </svg>\n);\n\n/** Export PDF: a document marked \"PDF\" with a download arrow. */\nexport const IconExportPdf: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <path d=\"M13 3H7a2 2 0 0 0-2 2v6\" />\n <path d=\"M13 3l5 5v3\" />\n <path d=\"M4.5 14h1.6a1.4 1.4 0 0 1 0 2.8H4.5V14v5\" />\n <path d=\"M17 14v6M14.5 17.5 17 20l2.5-2.5\" />\n <path d=\"M10 14v5h1a1.4 1.4 0 0 0 1.4-1.4v-2.2A1.4 1.4 0 0 0 11 14z\" />\n </svg>\n);\n\nexport const IconExportMarkdown: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\" />\n <path d=\"M6 15V9l3 3 3-3v6\" />\n <path d=\"M17 9v4m0 0 2-2m-2 2-2-2\" />\n </svg>\n);\n\n/** Export JSON: braces with a download arrow into a tray. */\nexport const IconExportJson: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <path d=\"M9 4c-1.5 0-2 .6-2 2s.4 2-1 2c1.4 0 1 1 1 2s.5 2 2 2\" />\n <path d=\"M15 4c1.5 0 2 .6 2 2s-.4 2 1 2c-1.4 0-1 1-1 2s-.5 2-2 2\" />\n <path d=\"M12 13v6M9 16l3 3 3-3\" />\n <path d=\"M4 20h16\" opacity=\"0.5\" />\n </svg>\n);\n\n/** Layer / z-order controls: to-front, forward, backward, to-back. */\nexport type LayerIconKind = 'front' | 'up' | 'down' | 'back';\n\nexport const IconLayer: React.FC<{ kind: LayerIconKind }> = ({ kind }) => {\n // Metaphor: a stack of layers with the *moving* layer drawn solid and an\n // arrow showing the z-order direction. Front/back push all the way; up/down\n // shift by one. Each variant is visually distinct.\n switch (kind) {\n case 'front':\n // Solid square on top of two outlined layers + up arrow.\n return (\n <svg {...base} aria-hidden=\"true\">\n <rect x=\"7\" y=\"7\" width=\"10\" height=\"10\" rx=\"1.5\" fill=\"currentColor\" stroke=\"none\" />\n <path d=\"M4 15.5l3 1.7M20 15.5l-3 1.7\" opacity=\"0.5\" />\n <path d=\"M4 18.5l8 4.5 8-4.5\" opacity=\"0.5\" />\n <path d=\"M12 5V1M9.5 3 12 .8 14.5 3\" transform=\"translate(0 1)\" />\n </svg>\n );\n case 'up':\n // Solid layer with a single up arrow.\n return (\n <svg {...base} aria-hidden=\"true\">\n <rect x=\"3\" y=\"12\" width=\"11\" height=\"8\" rx=\"1.5\" fill=\"currentColor\" stroke=\"none\" opacity=\"0.4\" />\n <rect x=\"9\" y=\"8\" width=\"11\" height=\"8\" rx=\"1.5\" fill=\"currentColor\" stroke=\"none\" />\n <path d=\"M14.5 5.5V1M12 3l2.5-2.5L17 3\" />\n </svg>\n );\n case 'down':\n // Solid layer with a single down arrow.\n return (\n <svg {...base} aria-hidden=\"true\">\n <rect x=\"9\" y=\"8\" width=\"11\" height=\"8\" rx=\"1.5\" fill=\"currentColor\" stroke=\"none\" opacity=\"0.4\" />\n <rect x=\"3\" y=\"12\" width=\"11\" height=\"8\" rx=\"1.5\" fill=\"currentColor\" stroke=\"none\" />\n <path d=\"M14.5 18.5V23M12 20.5l2.5 2.5 2.5-2.5\" />\n </svg>\n );\n case 'back':\n default:\n // Outlined top layers over a solid bottom layer + down arrow.\n return (\n <svg {...base} aria-hidden=\"true\">\n <path d=\"M4 8.5l8-4.5 8 4.5\" opacity=\"0.5\" />\n <path d=\"M4 8.5l3 1.7M20 8.5l-3 1.7\" opacity=\"0.5\" />\n <rect x=\"7\" y=\"9\" width=\"10\" height=\"10\" rx=\"1.5\" fill=\"currentColor\" stroke=\"none\" />\n <path d=\"M12 21v4M9.5 23 12 25.2 14.5 23\" transform=\"translate(0 -1)\" />\n </svg>\n );\n }\n};\n\nexport const IconAnchorVisible: React.FC<{ visible?: boolean }> = ({ visible = true }) => (\n <svg {...base} aria-hidden=\"true\">\n <rect x=\"4\" y=\"5\" width=\"16\" height=\"14\" rx=\"2\" strokeDasharray=\"3 2\" />\n <circle cx=\"4\" cy=\"5\" r=\"2\" fill=\"currentColor\" stroke=\"none\" />\n {visible ? (\n <path d=\"M2 12s3.5-5 10-5 10 5 10 5-3.5 5-10 5S2 12 2 12zM12 10a2 2 0 1 0 0 4 2 2 0 0 0 0-4z\" />\n ) : (\n <path d=\"M3 3l18 18\" />\n )}\n </svg>\n);\n\nexport const IconPresent: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <rect x=\"2\" y=\"4\" width=\"20\" height=\"13\" rx=\"2\" />\n <path d=\"M10 8.5l4.5 2.5L10 13.5z\" fill=\"currentColor\" stroke=\"none\" />\n <path d=\"M12 17v3M8 20h8\" />\n </svg>\n);\n\nexport const IconArchify: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <rect x=\"3\" y=\"5\" width=\"8\" height=\"6\" rx=\"1.5\" />\n <rect x=\"13\" y=\"5\" width=\"8\" height=\"6\" rx=\"1.5\" />\n <rect x=\"8\" y=\"14\" width=\"8\" height=\"6\" rx=\"1.5\" />\n <path d=\"M7 11v1.5M17 11v1.5M12 12.5V14\" />\n </svg>\n);\n"],"mappings":"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"}
1
+ {"version":3,"file":"toolbarIcons.js","names":[],"sources":["../../../../../src/components/pro/Flow/panels/toolbarIcons.tsx"],"sourcesContent":["import React from 'react';\n\n/**\n * Toolbar icon set for the Flow editor.\n * Compact 20x20 stroke icons that inherit `currentColor`, so they follow the\n * button's variant (primary/ghost) automatically.\n */\n\nconst base = {\n width: 18,\n height: 18,\n viewBox: '0 0 24 24',\n fill: 'none',\n stroke: 'currentColor',\n strokeWidth: 2,\n strokeLinecap: 'round' as const,\n strokeLinejoin: 'round' as const,\n};\n\nexport const IconSelect: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <path d=\"M4 3l7 17 2.5-6.5L20 11 4 3z\" />\n </svg>\n);\n\n\nexport const IconAutoFocus: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <circle cx=\"12\" cy=\"12\" r=\"6\" />\n <circle cx=\"12\" cy=\"12\" r=\"2\" />\n <path d=\"M4 12H2M22 12h-2M12 4V2M12 22v-2\" />\n <path d=\"M17.5 5.5l1-1M5.5 17.5l-1 1\" />\n </svg>\n);\n\nexport const IconBack: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <path d=\"M19 12H5\" />\n <path d=\"M11 18l-6-6 6-6\" />\n </svg>\n);\n\nexport const IconUndo: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <path d=\"M9 14L4 9l5-5\" />\n <path d=\"M4 9h11a5 5 0 0 1 0 10h-4\" />\n </svg>\n);\n\nexport const IconRedo: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <path d=\"M15 14l5-5-5-5\" />\n <path d=\"M20 9H9a5 5 0 0 0 0 10h4\" />\n </svg>\n);\n\nexport const IconGroup: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <rect x=\"3\" y=\"3\" width=\"8\" height=\"8\" rx=\"1\" />\n <rect x=\"13\" y=\"13\" width=\"8\" height=\"8\" rx=\"1\" />\n <path d=\"M13 6h4a1 1 0 0 1 1 1v4\" strokeDasharray=\"2 2\" />\n </svg>\n);\n\nexport const IconGeoGroup: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" strokeDasharray=\"3 3\" />\n <rect x=\"7\" y=\"7\" width=\"4\" height=\"4\" rx=\"0.5\" />\n <rect x=\"13\" y=\"13\" width=\"4\" height=\"4\" rx=\"0.5\" />\n </svg>\n);\n\nexport const IconUngroup: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <rect x=\"3\" y=\"3\" width=\"7\" height=\"7\" rx=\"1\" />\n <rect x=\"14\" y=\"14\" width=\"7\" height=\"7\" rx=\"1\" />\n <path d=\"M14 5h5M17 3v4\" />\n </svg>\n);\n\nexport type AlignIconKind = 'left' | 'center-h' | 'right' | 'top' | 'center-v' | 'bottom' | 'distribute-h' | 'distribute-v';\n\nexport const IconAlign: React.FC<{ kind: AlignIconKind }> = ({ kind }) => {\n const vertical = kind === 'left' || kind === 'center-h' || kind === 'right';\n if (vertical) {\n const x = kind === 'left' ? 5 : kind === 'right' ? 19 : 12;\n return (\n <svg {...base} aria-hidden=\"true\">\n <path d={`M${x} 3v18`} />\n <rect x={kind === 'left' ? 5 : kind === 'right' ? 10 : 7} y=\"5\" width=\"9\" height=\"4\" rx=\"0.5\" />\n <rect x={kind === 'left' ? 5 : kind === 'right' ? 5 : 4} y=\"14\" width=\"14\" height=\"4\" rx=\"0.5\" />\n </svg>\n );\n }\n if (kind === 'top' || kind === 'center-v' || kind === 'bottom') {\n const y = kind === 'top' ? 5 : kind === 'bottom' ? 19 : 12;\n return (\n <svg {...base} aria-hidden=\"true\">\n <path d={`M3 ${y}h18`} />\n <rect x=\"5\" y={kind === 'top' ? 5 : kind === 'bottom' ? 10 : 7} width=\"4\" height=\"9\" rx=\"0.5\" />\n <rect x=\"14\" y={kind === 'top' ? 5 : kind === 'bottom' ? 5 : 4} width=\"4\" height=\"14\" rx=\"0.5\" />\n </svg>\n );\n }\n return (\n <svg {...base} aria-hidden=\"true\">\n {kind === 'distribute-h' ? (\n <><path d=\"M3 3v18M21 3v18\" /><rect x=\"6\" y=\"7\" width=\"4\" height=\"10\" /><rect x=\"14\" y=\"7\" width=\"4\" height=\"10\" /></>\n ) : (\n <><path d=\"M3 3h18M3 21h18\" /><rect x=\"7\" y=\"6\" width=\"10\" height=\"4\" /><rect x=\"7\" y=\"14\" width=\"10\" height=\"4\" /></>\n )}\n </svg>\n );\n};\n\nexport const IconZoomOut: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <circle cx=\"11\" cy=\"11\" r=\"7\" />\n <path d=\"M21 21l-4.3-4.3M8 11h6\" />\n </svg>\n);\n\nexport const IconZoomIn: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <circle cx=\"11\" cy=\"11\" r=\"7\" />\n <path d=\"M21 21l-4.3-4.3M11 8v6M8 11h6\" />\n </svg>\n);\n\nexport const IconFitView: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <path d=\"M4 9V5a1 1 0 0 1 1-1h4M15 4h4a1 1 0 0 1 1 1v4M20 15v4a1 1 0 0 1-1 1h-4M9 20H5a1 1 0 0 1-1-1v-4\" />\n <rect x=\"9\" y=\"9\" width=\"6\" height=\"6\" rx=\"1\" />\n </svg>\n);\n\nexport const IconShapes: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <rect x=\"3\" y=\"13\" width=\"8\" height=\"8\" rx=\"1\" />\n <circle cx=\"17\" cy=\"7\" r=\"4\" />\n <path d=\"M13 21l4-7 4 7z\" />\n </svg>\n);\n\nexport const IconInspector: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <circle cx=\"12\" cy=\"12\" r=\"3\" />\n <path d=\"M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z\" />\n </svg>\n);\n\nexport const IconOutline: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <path d=\"M8 6h13M8 12h13M8 18h13M3 6h.01M3 12h.01M3 18h.01\" />\n </svg>\n);\n\nexport const IconJson: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <path d=\"M8 4H7a2 2 0 0 0-2 2v3a2 2 0 0 1-2 2 2 2 0 0 1 2 2v3a2 2 0 0 0 2 2h1\" />\n <path d=\"M16 4h1a2 2 0 0 1 2 2v3a2 2 0 0 0 2 2 2 2 0 0 0-2 2v3a2 2 0 0 1-2 2h-1\" />\n </svg>\n);\n\nexport const IconAI: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <path d=\"M12 3l1.9 4.6L18.5 9.5 13.9 11.4 12 16l-1.9-4.6L5.5 9.5l4.6-1.9L12 3z\" />\n <path d=\"M18 15l.9 2.1L21 18l-2.1.9L18 21l-.9-2.1L15 18l2.1-.9L18 15z\" />\n </svg>\n);\n\nexport const IconGrid: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" />\n <path d=\"M9 3v18M15 3v18M3 9h18M3 15h18\" />\n </svg>\n);\n\n/** Placement magnet (snap stamps to the canvas grid). */\nexport const IconMagnet: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <path d=\"M4 12V6a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v6a2 2 0 0 0 4 0V6a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v6a7 7 0 0 1-14 0\" />\n <path d=\"M4 9.5h6M14 9.5h6\" />\n </svg>\n);\n\nexport const IconMiniMap: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <rect x=\"3\" y=\"4\" width=\"18\" height=\"16\" rx=\"2\" />\n <rect x=\"13\" y=\"12\" width=\"6\" height=\"6\" rx=\"1\" />\n </svg>\n);\n\nexport const IconImport: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <path d=\"M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8z\" />\n <path d=\"M14 3v5h5\" />\n <path d=\"M12 18v-6\" />\n <path d=\"M9.5 14.5 12 12l2.5 2.5\" />\n </svg>\n);\n\nexport const IconExport: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <path d=\"M12 15V3\" />\n <path d=\"M8 7l4-4 4 4\" />\n <path d=\"M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2\" />\n </svg>\n);\n\nexport const IconPublish: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <path d=\"M22 2 11 13\" />\n <path d=\"M22 2 15 22l-4-9-9-4 20-7z\" />\n </svg>\n);\n\nexport const IconExportImage: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <rect x=\"3\" y=\"4\" width=\"18\" height=\"16\" rx=\"2\" />\n <circle cx=\"9\" cy=\"9\" r=\"1.5\" />\n <path d=\"M4 17l5-5 3 3 2-2 6 6\" />\n <path d=\"M16 3v7m-3-3 3 3 3-3\" />\n </svg>\n);\n\n/** Export PNG: an image frame with a download arrow into a tray. */\nexport const IconExportPng: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <rect x=\"3\" y=\"3\" width=\"12\" height=\"10\" rx=\"1.5\" />\n <circle cx=\"6.5\" cy=\"6.5\" r=\"1\" />\n <path d=\"M3 11l3.5-3 3 2.5\" />\n <path d=\"M19 12v6M16.5 15.5 19 18l2.5-2.5\" />\n <path d=\"M14 21h10\" opacity=\"0.5\" />\n </svg>\n);\n\n/** Export PDF: a document marked \"PDF\" with a download arrow. */\nexport const IconExportPdf: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <path d=\"M13 3H7a2 2 0 0 0-2 2v6\" />\n <path d=\"M13 3l5 5v3\" />\n <path d=\"M4.5 14h1.6a1.4 1.4 0 0 1 0 2.8H4.5V14v5\" />\n <path d=\"M17 14v6M14.5 17.5 17 20l2.5-2.5\" />\n <path d=\"M10 14v5h1a1.4 1.4 0 0 0 1.4-1.4v-2.2A1.4 1.4 0 0 0 11 14z\" />\n </svg>\n);\n\nexport const IconExportMarkdown: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\" />\n <path d=\"M6 15V9l3 3 3-3v6\" />\n <path d=\"M17 9v4m0 0 2-2m-2 2-2-2\" />\n </svg>\n);\n\n/** Export JSON: braces with a download arrow into a tray. */\nexport const IconExportJson: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <path d=\"M9 4c-1.5 0-2 .6-2 2s.4 2-1 2c1.4 0 1 1 1 2s.5 2 2 2\" />\n <path d=\"M15 4c1.5 0 2 .6 2 2s-.4 2 1 2c-1.4 0-1 1-1 2s-.5 2-2 2\" />\n <path d=\"M12 13v6M9 16l3 3 3-3\" />\n <path d=\"M4 20h16\" opacity=\"0.5\" />\n </svg>\n);\n\n/** Layer / z-order controls: to-front, forward, backward, to-back. */\nexport type LayerIconKind = 'front' | 'up' | 'down' | 'back';\n\nexport const IconLayer: React.FC<{ kind: LayerIconKind }> = ({ kind }) => {\n // Metaphor: a stack of layers with the *moving* layer drawn solid and an\n // arrow showing the z-order direction. Front/back push all the way; up/down\n // shift by one. Each variant is visually distinct.\n switch (kind) {\n case 'front':\n // Solid square on top of two outlined layers + up arrow.\n return (\n <svg {...base} aria-hidden=\"true\">\n <rect x=\"7\" y=\"7\" width=\"10\" height=\"10\" rx=\"1.5\" fill=\"currentColor\" stroke=\"none\" />\n <path d=\"M4 15.5l3 1.7M20 15.5l-3 1.7\" opacity=\"0.5\" />\n <path d=\"M4 18.5l8 4.5 8-4.5\" opacity=\"0.5\" />\n <path d=\"M12 5V1M9.5 3 12 .8 14.5 3\" transform=\"translate(0 1)\" />\n </svg>\n );\n case 'up':\n // Solid layer with a single up arrow.\n return (\n <svg {...base} aria-hidden=\"true\">\n <rect x=\"3\" y=\"12\" width=\"11\" height=\"8\" rx=\"1.5\" fill=\"currentColor\" stroke=\"none\" opacity=\"0.4\" />\n <rect x=\"9\" y=\"8\" width=\"11\" height=\"8\" rx=\"1.5\" fill=\"currentColor\" stroke=\"none\" />\n <path d=\"M14.5 5.5V1M12 3l2.5-2.5L17 3\" />\n </svg>\n );\n case 'down':\n // Solid layer with a single down arrow.\n return (\n <svg {...base} aria-hidden=\"true\">\n <rect x=\"9\" y=\"8\" width=\"11\" height=\"8\" rx=\"1.5\" fill=\"currentColor\" stroke=\"none\" opacity=\"0.4\" />\n <rect x=\"3\" y=\"12\" width=\"11\" height=\"8\" rx=\"1.5\" fill=\"currentColor\" stroke=\"none\" />\n <path d=\"M14.5 18.5V23M12 20.5l2.5 2.5 2.5-2.5\" />\n </svg>\n );\n case 'back':\n default:\n // Outlined top layers over a solid bottom layer + down arrow.\n return (\n <svg {...base} aria-hidden=\"true\">\n <path d=\"M4 8.5l8-4.5 8 4.5\" opacity=\"0.5\" />\n <path d=\"M4 8.5l3 1.7M20 8.5l-3 1.7\" opacity=\"0.5\" />\n <rect x=\"7\" y=\"9\" width=\"10\" height=\"10\" rx=\"1.5\" fill=\"currentColor\" stroke=\"none\" />\n <path d=\"M12 21v4M9.5 23 12 25.2 14.5 23\" transform=\"translate(0 -1)\" />\n </svg>\n );\n }\n};\n\nexport const IconAnchorVisible: React.FC<{ visible?: boolean }> = ({ visible = true }) => (\n <svg {...base} aria-hidden=\"true\">\n <rect x=\"4\" y=\"5\" width=\"16\" height=\"14\" rx=\"2\" strokeDasharray=\"3 2\" />\n <circle cx=\"4\" cy=\"5\" r=\"2\" fill=\"currentColor\" stroke=\"none\" />\n {visible ? (\n <path d=\"M2 12s3.5-5 10-5 10 5 10 5-3.5 5-10 5S2 12 2 12zM12 10a2 2 0 1 0 0 4 2 2 0 0 0 0-4z\" />\n ) : (\n <path d=\"M3 3l18 18\" />\n )}\n </svg>\n);\n\nexport const IconPresent: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <rect x=\"2\" y=\"4\" width=\"20\" height=\"13\" rx=\"2\" />\n <path d=\"M10 8.5l4.5 2.5L10 13.5z\" fill=\"currentColor\" stroke=\"none\" />\n <path d=\"M12 17v3M8 20h8\" />\n </svg>\n);\n\nexport const IconArchify: React.FC = () => (\n <svg {...base} aria-hidden=\"true\">\n <rect x=\"3\" y=\"5\" width=\"8\" height=\"6\" rx=\"1.5\" />\n <rect x=\"13\" y=\"5\" width=\"8\" height=\"6\" rx=\"1.5\" />\n <rect x=\"8\" y=\"14\" width=\"8\" height=\"6\" rx=\"1.5\" />\n <path d=\"M7 11v1.5M17 11v1.5M12 12.5V14\" />\n </svg>\n);\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"AIRewrite.js","names":[],"sources":["../../../../src/components/pro/RichTextEditor/AIRewrite.tsx"],"sourcesContent":["import React, { useState, useRef, useCallback, useEffect } from 'react';\nimport type { Editor } from '@tiptap/react';\nimport type { AIConfig, AIAction, RichTextEditorLabels } from './types';\nimport { defaultLabels } from './types';\n\ninterface AIRewriteProps {\n editor: Editor;\n aiConfig: AIConfig;\n labels?: RichTextEditorLabels;\n initialSelection: string;\n selectionRange: { from: number; to: number };\n onClose: () => void;\n}\n\nconst QUICK_ACTIONS: { key: AIAction; labelKey: keyof RichTextEditorLabels; icon: string }[] = [\n { key: 'rewrite', labelKey: 'aiRewrite', icon: '✏' },\n { key: 'shorten', labelKey: 'aiShorten', icon: '📝' },\n { key: 'expand', labelKey: 'aiExpand', icon: '📄' },\n { key: 'fix_grammar', labelKey: 'aiFixGrammar', icon: '✓' },\n { key: 'translate_en', labelKey: 'aiTranslateEn', icon: 'EN' },\n { key: 'translate_zh', labelKey: 'aiTranslateZh', icon: '中' },\n { key: 'professional', labelKey: 'aiProfessional', icon: '💼' },\n { key: 'casual', labelKey: 'aiCasual', icon: '💬' },\n];\n\nfunction getSystemPrompt(action: AIAction | 'custom', customPrompt?: string): string {\n if (action === 'custom') return customPrompt || 'Follow the user instructions.';\n const prompts: Record<AIAction, string> = {\n rewrite: 'Rewrite the following text to improve clarity and readability. Keep the same meaning and tone. Return only the rewritten text.',\n shorten: 'Shorten the following text while preserving its key meaning. Be concise. Return only the shortened text.',\n expand: 'Expand the following text with more details and examples while keeping the same tone. Return only the expanded text.',\n fix_grammar: 'Fix any grammar, spelling, and punctuation errors in the following text. Return only the corrected text.',\n translate_en: 'Translate the following text to English. Return only the translated text.',\n translate_zh: 'Translate the following text to Chinese. Return only the translated text.',\n professional: 'Rewrite the following text in a professional, formal tone. Return only the rewritten text.',\n casual: 'Rewrite the following text in a casual, friendly tone. Return only the rewritten text.',\n };\n return customPrompt || prompts[action];\n}\n\nasync function* streamOpenAI(\n config: AIConfig,\n text: string,\n systemPrompt: string,\n signal: AbortSignal,\n): AsyncGenerator<string> {\n const body = JSON.stringify({\n model: config.model,\n messages: [\n { role: 'system', content: systemPrompt },\n { role: 'user', content: text },\n ],\n stream: true,\n });\n\n const response = await fetch(config.gateway, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(config.apiKey ? { Authorization: `Bearer ${config.apiKey}` } : {}),\n ...config.headers,\n },\n body,\n signal,\n });\n\n if (!response.ok) throw new Error(`AI API error: ${response.status} ${response.statusText}`);\n const reader = response.body?.getReader();\n if (!reader) throw new Error('No response body');\n\n const decoder = new TextDecoder();\n let buffer = '';\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() || '';\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed || trimmed === 'data: [DONE]' || !trimmed.startsWith('data: ')) continue;\n try {\n const data = JSON.parse(trimmed.slice(6));\n const content = data.choices?.[0]?.delta?.content;\n if (content) yield content;\n } catch { /* skip */ }\n }\n }\n}\n\nasync function* streamAnthropic(\n config: AIConfig,\n text: string,\n systemPrompt: string,\n signal: AbortSignal,\n): AsyncGenerator<string> {\n const body = JSON.stringify({\n model: config.model,\n max_tokens: 4096,\n system: systemPrompt,\n messages: [{ role: 'user', content: text }],\n stream: true,\n });\n\n const response = await fetch(config.gateway, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(config.apiKey ? { 'x-api-key': config.apiKey } : {}),\n 'anthropic-version': '2023-06-01',\n ...config.headers,\n },\n body,\n signal,\n });\n\n if (!response.ok) throw new Error(`AI API error: ${response.status} ${response.statusText}`);\n const reader = response.body?.getReader();\n if (!reader) throw new Error('No response body');\n\n const decoder = new TextDecoder();\n let buffer = '';\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() || '';\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed.startsWith('data: ')) continue;\n try {\n const data = JSON.parse(trimmed.slice(6));\n if (data.type === 'content_block_delta' && data.delta?.text) yield data.delta.text;\n } catch { /* skip */ }\n }\n }\n}\n\nfunction getStream(\n config: AIConfig,\n text: string,\n systemPrompt: string,\n action: AIAction | 'custom',\n signal: AbortSignal,\n): AsyncIterable<string> {\n if (config.protocol === 'custom' && config.customHandler) {\n return config.customHandler({ text, action: action === 'custom' ? 'rewrite' : action, signal });\n }\n if (config.protocol === 'anthropic') return streamAnthropic(config, text, systemPrompt, signal);\n return streamOpenAI(config, text, systemPrompt, signal);\n}\n\nconst AIRewrite: React.FC<AIRewriteProps> = ({ editor, aiConfig, labels: propsLabels, initialSelection, selectionRange, onClose }) => {\n const labels = { ...defaultLabels, ...propsLabels };\n const [prompt, setPrompt] = useState('');\n const [isProcessing, setIsProcessing] = useState(false);\n const [streamedText, setStreamedText] = useState('');\n const [error, setError] = useState<string | null>(null);\n const abortRef = useRef<AbortController | null>(null);\n const promptRef = useRef<HTMLTextAreaElement>(null);\n\n const selectedText = initialSelection;\n\n useEffect(() => {\n if (promptRef.current) promptRef.current.focus();\n }, []);\n\n const handleGenerate = useCallback(async (action: AIAction | 'custom' = 'custom', customPromptOverride?: string) => {\n const text = selectedText || editor.state.doc.textContent;\n if (!text.trim() && !prompt.trim()) return;\n\n const systemPrompt = action === 'custom'\n ? (prompt || 'Improve the following text. Return only the improved text.')\n : getSystemPrompt(action, customPromptOverride);\n\n const userText = action === 'custom' && prompt\n ? `Instructions: ${prompt}\\n\\nText:\\n${text}`\n : text;\n\n setIsProcessing(true);\n setStreamedText('');\n setError(null);\n\n const abort = new AbortController();\n abortRef.current = abort;\n\n try {\n let result = '';\n for await (const chunk of getStream(aiConfig, userText, systemPrompt, action, abort.signal)) {\n if (abort.signal.aborted) break;\n result += chunk;\n setStreamedText(result);\n }\n } catch (err: unknown) {\n if (err instanceof DOMException && err.name === 'AbortError') return;\n setError(String(err instanceof Error ? err.message : err));\n } finally {\n setIsProcessing(false);\n }\n }, [editor, aiConfig, selectedText, prompt]);\n\n const handleAccept = useCallback(() => {\n if (!streamedText) return;\n const { from, to } = selectionRange;\n if (from !== to) {\n editor.chain().focus().deleteRange({ from, to }).insertContentAt(from, streamedText).run();\n } else {\n editor.chain().focus().insertContent(streamedText).run();\n }\n setStreamedText('');\n setPrompt('');\n onClose();\n }, [editor, streamedText, selectionRange, onClose]);\n\n const handleReject = useCallback(() => {\n abortRef.current?.abort();\n setStreamedText('');\n setIsProcessing(false);\n setError(null);\n }, []);\n\n const handleKeyDown = useCallback((e: React.KeyboardEvent) => {\n if (e.key === 'Enter' && (e.metaKey || e.ctrlKey)) {\n e.preventDefault();\n handleGenerate();\n }\n }, [handleGenerate]);\n\n return (\n <div className=\"rte-ai-panel-v2\">\n <div className=\"rte-ai-panel-v2__header\">\n <span className=\"rte-ai-panel-v2__title\">✨ {labels.ai || 'AI Assistant'}</span>\n <button type=\"button\" className=\"rte-ai-panel-v2__close-btn\" onClick={onClose} title=\"Close\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" /><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n </button>\n </div>\n {/* Prompt input */}\n <div className=\"rte-ai-panel-v2__prompt-section\">\n <label className=\"rte-ai-panel-v2__label\">Prompt</label>\n <textarea\n ref={promptRef}\n className=\"rte-ai-panel-v2__prompt-input\"\n value={prompt}\n onChange={(e) => setPrompt(e.target.value)}\n onKeyDown={handleKeyDown}\n placeholder=\"Describe what AI should do... (Ctrl+Enter to generate)\"\n rows={3}\n disabled={isProcessing}\n />\n </div>\n\n {/* Selected text display */}\n <div className=\"rte-ai-panel-v2__selection-section\">\n <label className=\"rte-ai-panel-v2__label\">Selected Text</label>\n <div className=\"rte-ai-panel-v2__selection-box\">\n {selectedText ? (\n <span>{selectedText.length > 300 ? selectedText.slice(0, 300) + '...' : selectedText}</span>\n ) : (\n <span className=\"rte-ai-panel-v2__empty\">No text selected (will use all content)</span>\n )}\n </div>\n </div>\n\n {/* Quick actions */}\n <div className=\"rte-ai-panel-v2__quick-actions\">\n {QUICK_ACTIONS.map(({ key, labelKey, icon }) => (\n <button\n key={key}\n type=\"button\"\n className=\"rte-ai-panel-v2__quick-btn\"\n onClick={() => handleGenerate(key)}\n disabled={isProcessing}\n title={labels[labelKey]}\n >\n <span>{icon}</span>\n <span>{labels[labelKey]}</span>\n </button>\n ))}\n </div>\n\n {/* Generate button */}\n <div className=\"rte-ai-panel-v2__actions\">\n <button\n type=\"button\"\n className=\"rte-ai-panel-v2__generate-btn\"\n onClick={() => handleGenerate()}\n disabled={isProcessing || (!prompt.trim() && !selectedText.trim())}\n >\n {isProcessing ? (\n <><div className=\"rte-ai-panel__spinner\" /> {labels.aiProcessing}</>\n ) : (\n '✨ Generate'\n )}\n </button>\n {isProcessing && (\n <button type=\"button\" className=\"rte-ai-panel-v2__cancel-btn\" onClick={handleReject}>\n Cancel\n </button>\n )}\n </div>\n\n {/* Streaming result */}\n {streamedText && (\n <div className=\"rte-ai-panel-v2__result\">\n <label className=\"rte-ai-panel-v2__label\">Result</label>\n <div className=\"rte-ai-panel-v2__result-text\">{streamedText}</div>\n <div className=\"rte-ai-panel-v2__result-actions\">\n <button type=\"button\" className=\"rte-ai-panel-v2__accept-btn\" onClick={handleAccept}>\n {labels.aiAccept}\n </button>\n <button type=\"button\" className=\"rte-ai-panel-v2__reject-btn\" onClick={handleReject}>\n {labels.aiReject}\n </button>\n </div>\n </div>\n )}\n\n {/* Error */}\n {error && (\n <div className=\"rte-ai-panel-v2__error\">\n <span>{error}</span>\n <button type=\"button\" onClick={() => setError(null)}>Dismiss</button>\n </div>\n )}\n </div>\n );\n};\n\nexport default AIRewrite;\n"],"mappings":"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"}
1
+ {"version":3,"file":"AIRewrite.js","names":[],"sources":["../../../../src/components/pro/RichTextEditor/AIRewrite.tsx"],"sourcesContent":["import React, { useState, useRef, useCallback, useEffect } from 'react';\nimport type { Editor } from '@tiptap/react';\nimport type { AIConfig, AIAction, RichTextEditorLabels } from './types';\nimport { defaultLabels } from './types';\n\ninterface AIRewriteProps {\n editor: Editor;\n aiConfig: AIConfig;\n labels?: RichTextEditorLabels;\n initialSelection: string;\n selectionRange: { from: number; to: number };\n onClose: () => void;\n}\n\nconst QUICK_ACTIONS: { key: AIAction; labelKey: keyof RichTextEditorLabels; icon: string }[] = [\n { key: 'rewrite', labelKey: 'aiRewrite', icon: '✏' },\n { key: 'shorten', labelKey: 'aiShorten', icon: '📝' },\n { key: 'expand', labelKey: 'aiExpand', icon: '📄' },\n { key: 'fix_grammar', labelKey: 'aiFixGrammar', icon: '✓' },\n { key: 'translate_en', labelKey: 'aiTranslateEn', icon: 'EN' },\n { key: 'translate_zh', labelKey: 'aiTranslateZh', icon: '中' },\n { key: 'professional', labelKey: 'aiProfessional', icon: '💼' },\n { key: 'casual', labelKey: 'aiCasual', icon: '💬' },\n];\n\nfunction getSystemPrompt(action: AIAction | 'custom', customPrompt?: string): string {\n if (action === 'custom') return customPrompt || 'Follow the user instructions.';\n const prompts: Record<AIAction, string> = {\n rewrite: 'Rewrite the following text to improve clarity and readability. Keep the same meaning and tone. Return only the rewritten text.',\n shorten: 'Shorten the following text while preserving its key meaning. Be concise. Return only the shortened text.',\n expand: 'Expand the following text with more details and examples while keeping the same tone. Return only the expanded text.',\n fix_grammar: 'Fix any grammar, spelling, and punctuation errors in the following text. Return only the corrected text.',\n translate_en: 'Translate the following text to English. Return only the translated text.',\n translate_zh: 'Translate the following text to Chinese. Return only the translated text.',\n professional: 'Rewrite the following text in a professional, formal tone. Return only the rewritten text.',\n casual: 'Rewrite the following text in a casual, friendly tone. Return only the rewritten text.',\n };\n return customPrompt || prompts[action];\n}\n\nasync function* streamOpenAI(\n config: AIConfig,\n text: string,\n systemPrompt: string,\n signal: AbortSignal,\n): AsyncGenerator<string> {\n const body = JSON.stringify({\n model: config.model,\n messages: [\n { role: 'system', content: systemPrompt },\n { role: 'user', content: text },\n ],\n stream: true,\n });\n\n const response = await fetch(config.gateway, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(config.apiKey ? { Authorization: `Bearer ${config.apiKey}` } : {}),\n ...config.headers,\n },\n body,\n signal,\n });\n\n if (!response.ok) throw new Error(`AI API error: ${response.status} ${response.statusText}`);\n const reader = response.body?.getReader();\n if (!reader) throw new Error('No response body');\n\n const decoder = new TextDecoder();\n let buffer = '';\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() || '';\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed || trimmed === 'data: [DONE]' || !trimmed.startsWith('data: ')) continue;\n try {\n const data = JSON.parse(trimmed.slice(6));\n const content = data.choices?.[0]?.delta?.content;\n if (content) yield content;\n } catch { /* skip */ }\n }\n }\n}\n\nasync function* streamAnthropic(\n config: AIConfig,\n text: string,\n systemPrompt: string,\n signal: AbortSignal,\n): AsyncGenerator<string> {\n const body = JSON.stringify({\n model: config.model,\n max_tokens: 4096,\n system: systemPrompt,\n messages: [{ role: 'user', content: text }],\n stream: true,\n });\n\n const response = await fetch(config.gateway, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(config.apiKey ? { 'x-api-key': config.apiKey } : {}),\n 'anthropic-version': '2023-06-01',\n ...config.headers,\n },\n body,\n signal,\n });\n\n if (!response.ok) throw new Error(`AI API error: ${response.status} ${response.statusText}`);\n const reader = response.body?.getReader();\n if (!reader) throw new Error('No response body');\n\n const decoder = new TextDecoder();\n let buffer = '';\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() || '';\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed.startsWith('data: ')) continue;\n try {\n const data = JSON.parse(trimmed.slice(6));\n if (data.type === 'content_block_delta' && data.delta?.text) yield data.delta.text;\n } catch { /* skip */ }\n }\n }\n}\n\nfunction getStream(\n config: AIConfig,\n text: string,\n systemPrompt: string,\n action: AIAction | 'custom',\n signal: AbortSignal,\n): AsyncIterable<string> {\n if (config.protocol === 'custom' && config.customHandler) {\n return config.customHandler({ text, action: action === 'custom' ? 'rewrite' : action, signal });\n }\n if (config.protocol === 'anthropic') return streamAnthropic(config, text, systemPrompt, signal);\n return streamOpenAI(config, text, systemPrompt, signal);\n}\n\nconst AIRewrite: React.FC<AIRewriteProps> = ({ editor, aiConfig, labels: propsLabels, initialSelection, selectionRange, onClose }) => {\n const labels = { ...defaultLabels, ...propsLabels };\n const [prompt, setPrompt] = useState('');\n const [isProcessing, setIsProcessing] = useState(false);\n const [streamedText, setStreamedText] = useState('');\n const [error, setError] = useState<string | null>(null);\n const abortRef = useRef<AbortController | null>(null);\n const promptRef = useRef<HTMLTextAreaElement>(null);\n\n const selectedText = initialSelection;\n\n useEffect(() => {\n if (promptRef.current) promptRef.current.focus();\n }, []);\n\n const handleGenerate = useCallback(async (action: AIAction | 'custom' = 'custom', customPromptOverride?: string) => {\n const text = selectedText || editor.state.doc.textContent;\n if (!text.trim() && !prompt.trim()) return;\n\n const systemPrompt = action === 'custom'\n ? (prompt || 'Improve the following text. Return only the improved text.')\n : getSystemPrompt(action, customPromptOverride);\n\n const userText = action === 'custom' && prompt\n ? `Instructions: ${prompt}\\n\\nText:\\n${text}`\n : text;\n\n setIsProcessing(true);\n setStreamedText('');\n setError(null);\n\n const abort = new AbortController();\n abortRef.current = abort;\n\n try {\n let result = '';\n for await (const chunk of getStream(aiConfig, userText, systemPrompt, action, abort.signal)) {\n if (abort.signal.aborted) break;\n result += chunk;\n setStreamedText(result);\n }\n } catch (err: unknown) {\n if (err instanceof DOMException && err.name === 'AbortError') return;\n setError(String(err instanceof Error ? err.message : err));\n } finally {\n setIsProcessing(false);\n }\n }, [editor, aiConfig, selectedText, prompt]);\n\n const handleAccept = useCallback(() => {\n if (!streamedText) return;\n const { from, to } = selectionRange;\n if (from !== to) {\n editor.chain().focus().deleteRange({ from, to }).insertContentAt(from, streamedText).run();\n } else {\n editor.chain().focus().insertContent(streamedText).run();\n }\n setStreamedText('');\n setPrompt('');\n onClose();\n }, [editor, streamedText, selectionRange, onClose]);\n\n const handleReject = useCallback(() => {\n abortRef.current?.abort();\n setStreamedText('');\n setIsProcessing(false);\n setError(null);\n }, []);\n\n const handleKeyDown = useCallback((e: React.KeyboardEvent) => {\n if (e.key === 'Enter' && (e.metaKey || e.ctrlKey)) {\n e.preventDefault();\n handleGenerate();\n }\n }, [handleGenerate]);\n\n return (\n <div className=\"rte-ai-panel-v2\">\n <div className=\"rte-ai-panel-v2__header\">\n <span className=\"rte-ai-panel-v2__title\">✨ {labels.ai || 'AI Assistant'}</span>\n <button type=\"button\" className=\"rte-ai-panel-v2__close-btn\" onClick={onClose} title=\"Close\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" /><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n </button>\n </div>\n {/* Prompt input */}\n <div className=\"rte-ai-panel-v2__prompt-section\">\n <label className=\"rte-ai-panel-v2__label\">Prompt</label>\n <textarea\n ref={promptRef}\n className=\"rte-ai-panel-v2__prompt-input\"\n value={prompt}\n onChange={(e) => setPrompt(e.target.value)}\n onKeyDown={handleKeyDown}\n placeholder=\"Describe what AI should do... (Ctrl+Enter to generate)\"\n rows={3}\n disabled={isProcessing}\n />\n </div>\n\n {/* Selected text display */}\n <div className=\"rte-ai-panel-v2__selection-section\">\n <label className=\"rte-ai-panel-v2__label\">Selected Text</label>\n <div className=\"rte-ai-panel-v2__selection-box\">\n {selectedText ? (\n <span>{selectedText.length > 300 ? selectedText.slice(0, 300) + '...' : selectedText}</span>\n ) : (\n <span className=\"rte-ai-panel-v2__empty\">No text selected (will use all content)</span>\n )}\n </div>\n </div>\n\n {/* Quick actions */}\n <div className=\"rte-ai-panel-v2__quick-actions\">\n {QUICK_ACTIONS.map(({ key, labelKey, icon }) => (\n <button\n key={key}\n type=\"button\"\n className=\"rte-ai-panel-v2__quick-btn\"\n onClick={() => handleGenerate(key)}\n disabled={isProcessing}\n title={labels[labelKey]}\n >\n <span>{icon}</span>\n <span>{labels[labelKey]}</span>\n </button>\n ))}\n </div>\n\n {/* Generate button */}\n <div className=\"rte-ai-panel-v2__actions\">\n <button\n type=\"button\"\n className=\"rte-ai-panel-v2__generate-btn\"\n onClick={() => handleGenerate()}\n disabled={isProcessing || (!prompt.trim() && !selectedText.trim())}\n >\n {isProcessing ? (\n <><div className=\"rte-ai-panel__spinner\" /> {labels.aiProcessing}</>\n ) : (\n '✨ Generate'\n )}\n </button>\n {isProcessing && (\n <button type=\"button\" className=\"rte-ai-panel-v2__cancel-btn\" onClick={handleReject}>\n Cancel\n </button>\n )}\n </div>\n\n {/* Streaming result */}\n {streamedText && (\n <div className=\"rte-ai-panel-v2__result\">\n <label className=\"rte-ai-panel-v2__label\">Result</label>\n <div className=\"rte-ai-panel-v2__result-text\">{streamedText}</div>\n <div className=\"rte-ai-panel-v2__result-actions\">\n <button type=\"button\" className=\"rte-ai-panel-v2__accept-btn\" onClick={handleAccept}>\n {labels.aiAccept}\n </button>\n <button type=\"button\" className=\"rte-ai-panel-v2__reject-btn\" onClick={handleReject}>\n {labels.aiReject}\n </button>\n </div>\n </div>\n )}\n\n {/* Error */}\n {error && (\n <div className=\"rte-ai-panel-v2__error\">\n <span>{error}</span>\n <button type=\"button\" onClick={() => setError(null)}>Dismiss</button>\n </div>\n )}\n </div>\n );\n};\n\nexport default AIRewrite;\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"BlockHandle.js","names":[],"sources":["../../../../src/components/pro/RichTextEditor/BlockHandle.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef, useCallback } from 'react';\nimport type { Editor } from '@tiptap/react';\n\ninterface BlockHandleProps {\n editor: Editor;\n}\n\ninterface BlockInfo {\n pos: number;\n size: number;\n domTop: number;\n domBottom: number;\n}\n\nconst BlockHandle: React.FC<BlockHandleProps> = ({ editor }) => {\n const [visible, setVisible] = useState(false);\n const [handleTop, setHandleTop] = useState(0);\n const [showMenu, setShowMenu] = useState(false);\n const [currentBlockIndex, setCurrentBlockIndex] = useState(-1);\n const [isDragging, setIsDragging] = useState(false);\n const [dropIndicator, setDropIndicator] = useState<{ top: number } | null>(null);\n const menuRef = useRef<HTMLDivElement>(null);\n const handleRef = useRef<HTMLDivElement>(null);\n const hideTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n const hoveringHandle = useRef(false);\n\n const cancelHide = useCallback(() => {\n if (hideTimer.current) {\n clearTimeout(hideTimer.current);\n hideTimer.current = null;\n }\n }, []);\n\n const scheduleHide = useCallback(() => {\n cancelHide();\n hideTimer.current = setTimeout(() => {\n if (!hoveringHandle.current && !showMenu && !isDragging) {\n setVisible(false);\n }\n }, 200);\n }, [cancelHide, showMenu, isDragging]);\n\n const getBlocks = useCallback((): BlockInfo[] => {\n const wrapperEl = editor.view.dom.closest('.rte-editor-wrapper') as HTMLElement | null;\n if (!wrapperEl) return [];\n const wrapperRect = wrapperEl.getBoundingClientRect();\n const scrollTop = wrapperEl.scrollTop;\n const blocks: BlockInfo[] = [];\n\n editor.state.doc.forEach((node, offset) => {\n const domNode = editor.view.nodeDOM(offset) as HTMLElement | null;\n if (domNode) {\n const rect = domNode.getBoundingClientRect();\n blocks.push({\n pos: offset,\n size: node.nodeSize,\n domTop: rect.top - wrapperRect.top + scrollTop,\n domBottom: rect.bottom - wrapperRect.top + scrollTop,\n });\n }\n });\n return blocks;\n }, [editor]);\n\n const findBlockByClientY = useCallback((clientY: number): number => {\n const wrapperEl = editor.view.dom.closest('.rte-editor-wrapper') as HTMLElement | null;\n if (!wrapperEl) return -1;\n const wrapperRect = wrapperEl.getBoundingClientRect();\n const y = clientY - wrapperRect.top + wrapperEl.scrollTop;\n\n const blocks = getBlocks();\n for (let i = 0; i < blocks.length; i++) {\n const mid = (blocks[i].domTop + blocks[i].domBottom) / 2;\n if (y < mid) return i;\n }\n return blocks.length - 1;\n }, [editor, getBlocks]);\n\n const findDropSlot = useCallback((clientY: number): { slotIndex: number; indicatorTop: number } | null => {\n const wrapperEl = editor.view.dom.closest('.rte-editor-wrapper') as HTMLElement | null;\n if (!wrapperEl) return null;\n const wrapperRect = wrapperEl.getBoundingClientRect();\n const y = clientY - wrapperRect.top + wrapperEl.scrollTop;\n\n const blocks = getBlocks();\n if (blocks.length === 0) return null;\n\n let bestSlot = 0;\n let bestDist = Infinity;\n let bestTop = blocks[0].domTop;\n\n for (let i = 0; i <= blocks.length; i++) {\n const edgeY = i < blocks.length ? blocks[i].domTop : blocks[blocks.length - 1].domBottom;\n const dist = Math.abs(y - edgeY);\n if (dist < bestDist) {\n bestDist = dist;\n bestSlot = i;\n bestTop = edgeY;\n }\n }\n\n return { slotIndex: bestSlot, indicatorTop: bestTop };\n }, [getBlocks]);\n\n useEffect(() => {\n const wrapperEl = editor.view.dom.closest('.rte-editor-wrapper') as HTMLElement | null;\n if (!wrapperEl) return;\n\n const handleMouseMove = (e: MouseEvent) => {\n if (isDragging) return;\n\n const idx = findBlockByClientY(e.clientY);\n if (idx < 0) return;\n\n const blocks = getBlocks();\n if (idx >= blocks.length) return;\n\n setHandleTop(blocks[idx].domTop);\n setCurrentBlockIndex(idx);\n cancelHide();\n setVisible(true);\n };\n\n const handleMouseLeave = () => {\n if (!isDragging) scheduleHide();\n };\n\n wrapperEl.addEventListener('mousemove', handleMouseMove);\n wrapperEl.addEventListener('mouseleave', handleMouseLeave);\n return () => {\n wrapperEl.removeEventListener('mousemove', handleMouseMove);\n wrapperEl.removeEventListener('mouseleave', handleMouseLeave);\n cancelHide();\n };\n }, [editor, cancelHide, scheduleHide, isDragging, findBlockByClientY, getBlocks]);\n\n useEffect(() => {\n if (!showMenu) return;\n const handler = (e: MouseEvent) => {\n if (menuRef.current && !menuRef.current.contains(e.target as Node)) {\n setShowMenu(false);\n }\n };\n document.addEventListener('mousedown', handler);\n return () => document.removeEventListener('mousedown', handler);\n }, [showMenu]);\n\n const addBlockBelow = useCallback(() => {\n const blocks = getBlocks();\n if (currentBlockIndex < 0 || currentBlockIndex >= blocks.length) return;\n const block = blocks[currentBlockIndex];\n const insertPos = block.pos + block.size;\n try {\n editor.chain().focus().insertContentAt(insertPos, { type: 'paragraph' }).run();\n editor.commands.focus(insertPos + 1);\n } catch { /* noop */ }\n setShowMenu(false);\n }, [editor, currentBlockIndex, getBlocks]);\n\n const handleDragStart = useCallback((e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n\n const dragIdx = currentBlockIndex;\n const blocks = getBlocks();\n if (dragIdx < 0 || dragIdx >= blocks.length) return;\n\n setIsDragging(true);\n\n const handleDragMove = (ev: MouseEvent) => {\n const slot = findDropSlot(ev.clientY);\n if (slot) {\n setDropIndicator({ top: slot.indicatorTop });\n }\n };\n\n const handleDragEnd = (ev: MouseEvent) => {\n document.removeEventListener('mousemove', handleDragMove);\n document.removeEventListener('mouseup', handleDragEnd);\n setIsDragging(false);\n setDropIndicator(null);\n\n const freshBlocks = getBlocks();\n if (dragIdx >= freshBlocks.length) return;\n\n const slot = findDropSlot(ev.clientY);\n if (!slot) return;\n\n let targetSlot = slot.slotIndex;\n\n // No-op: dropping at the same position or one below (no actual move)\n if (targetSlot === dragIdx || targetSlot === dragIdx + 1) return;\n\n const sourceBlock = freshBlocks[dragIdx];\n const sourceNode = editor.state.doc.nodeAt(sourceBlock.pos);\n if (!sourceNode) return;\n\n // Compute the insert position (before which block, or at end)\n let insertBefore: number;\n if (targetSlot < freshBlocks.length) {\n insertBefore = freshBlocks[targetSlot].pos;\n } else {\n const last = freshBlocks[freshBlocks.length - 1];\n insertBefore = last.pos + last.size;\n }\n\n const sourceFrom = sourceBlock.pos;\n const sourceTo = sourceBlock.pos + sourceBlock.size;\n const content = editor.state.doc.slice(sourceFrom, sourceTo).content;\n\n const { tr } = editor.state;\n\n if (targetSlot <= dragIdx) {\n // Moving up: delete source first (it's after target), then insert\n tr.delete(sourceFrom, sourceTo);\n const mapped = tr.mapping.map(insertBefore);\n tr.insert(mapped, content);\n } else {\n // Moving down: insert first (target is after source), then delete\n tr.insert(insertBefore, content);\n tr.delete(\n tr.mapping.map(sourceFrom),\n tr.mapping.map(sourceTo)\n );\n }\n\n editor.view.dispatch(tr);\n };\n\n document.addEventListener('mousemove', handleDragMove);\n document.addEventListener('mouseup', handleDragEnd);\n }, [editor, currentBlockIndex, getBlocks, findDropSlot]);\n\n const menuItems = [\n { label: 'Text', action: () => { addBlockBelow(); } },\n { label: 'Heading 1', action: () => { addBlockBelow(); editor.chain().focus().toggleHeading({ level: 1 }).run(); } },\n { label: 'Heading 2', action: () => { addBlockBelow(); editor.chain().focus().toggleHeading({ level: 2 }).run(); } },\n { label: 'Heading 3', action: () => { addBlockBelow(); editor.chain().focus().toggleHeading({ level: 3 }).run(); } },\n { label: 'Bullet List', action: () => { addBlockBelow(); editor.chain().focus().toggleBulletList().run(); } },\n { label: 'Numbered List', action: () => { addBlockBelow(); editor.chain().focus().toggleOrderedList().run(); } },\n { label: 'Task List', action: () => { addBlockBelow(); editor.chain().focus().toggleTaskList().run(); } },\n { label: 'Blockquote', action: () => { addBlockBelow(); editor.chain().focus().toggleBlockquote().run(); } },\n { label: 'Code Block', action: () => { addBlockBelow(); editor.chain().focus().toggleNode('codeBlock', 'paragraph').run(); } },\n { label: 'Divider', action: () => { addBlockBelow(); editor.chain().focus().setHorizontalRule().run(); } },\n { label: 'Table 3×3', action: () => { addBlockBelow(); editor.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run(); } },\n ];\n\n if (!visible && !showMenu && !isDragging) return null;\n\n return (\n <>\n <div\n ref={handleRef}\n className=\"rte-block-handle\"\n style={{ top: handleTop }}\n onMouseEnter={() => { hoveringHandle.current = true; cancelHide(); }}\n onMouseLeave={() => { hoveringHandle.current = false; if (!isDragging) scheduleHide(); }}\n onMouseDown={(e) => { e.stopPropagation(); e.preventDefault(); }}\n >\n <button\n type=\"button\"\n className=\"rte-block-handle__btn rte-block-handle__btn--add\"\n onMouseDown={(e) => { e.stopPropagation(); e.preventDefault(); }}\n onClick={(e) => { e.stopPropagation(); setShowMenu(!showMenu); }}\n title=\"Add block\"\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" /><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" /></svg>\n </button>\n <button\n type=\"button\"\n className={`rte-block-handle__btn rte-block-handle__btn--drag ${isDragging ? 'rte-block-handle__btn--dragging' : ''}`}\n title=\"Drag to reorder\"\n onMouseDown={handleDragStart}\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <circle cx=\"9\" cy=\"6\" r=\"1.5\" /><circle cx=\"15\" cy=\"6\" r=\"1.5\" />\n <circle cx=\"9\" cy=\"12\" r=\"1.5\" /><circle cx=\"15\" cy=\"12\" r=\"1.5\" />\n <circle cx=\"9\" cy=\"18\" r=\"1.5\" /><circle cx=\"15\" cy=\"18\" r=\"1.5\" />\n </svg>\n </button>\n </div>\n\n {showMenu && (\n <div\n ref={menuRef}\n className=\"rte-block-handle__menu\"\n style={{ top: handleTop + 28 }}\n onMouseDown={(e) => e.stopPropagation()}\n >\n {menuItems.map((item) => (\n <button\n key={item.label}\n type=\"button\"\n className=\"rte-block-handle__menu-item\"\n onMouseDown={(e) => e.stopPropagation()}\n onClick={(e) => { e.stopPropagation(); item.action(); setShowMenu(false); }}\n >\n {item.label}\n </button>\n ))}\n </div>\n )}\n\n {isDragging && dropIndicator && (\n <div className=\"rte-block-handle__drop-indicator\" style={{ top: dropIndicator.top }} />\n )}\n </>\n );\n};\n\nexport default BlockHandle;\n"],"mappings":";;AAcA,IAAM,IAAA,CAA2C,EAAE,QAAA,EAAA,MAAa;AAC9D,QAAM,CAAC,GAAS,CAAA,IAAc,EAAS,EAAK,GACtC,CAAC,GAAW,CAAA,IAAgB,EAAS,CAAC,GACtC,CAAC,GAAU,CAAA,IAAe,EAAS,EAAK,GACxC,CAAC,GAAmB,CAAA,IAAwB,EAAS,EAAE,GACvD,CAAC,GAAY,CAAA,IAAiB,EAAS,EAAK,GAC5C,CAAC,GAAe,CAAA,IAAoB,EAAiC,IAAI,GACzE,IAAU,EAAuB,IAAI,GACrC,IAAY,EAAuB,IAAI,GACvC,IAAY,EAA6C,IAAI,GAC7D,IAAiB,EAAO,EAAK,GAE7B,IAAa,EAAA,MAAkB;AACnC,IAAI,EAAU,YACZ,aAAa,EAAU,OAAO,GAC9B,EAAU,UAAU;AAAA,EAExB,GAAG,CAAC,CAAC,GAEC,IAAe,EAAA,MAAkB;AACrC,IAAA,EAAW,GACX,EAAU,UAAU,WAAA,MAAiB;AACnC,MAAI,CAAC,EAAe,WAAW,CAAC,KAAY,CAAC,KAC3C,EAAW,EAAK;AAAA,IAEpB,GAAG,GAAG;AAAA,EACR,GAAG;AAAA,IAAC;AAAA,IAAY;AAAA,IAAU;AAAA,EAAU,CAAC,GAE/B,IAAY,EAAA,MAA+B;AAC/C,UAAM,IAAY,EAAO,KAAK,IAAI,QAAQ,qBAAqB;AAC/D,QAAI,CAAC,EAAW,QAAO,CAAC;AACxB,UAAM,IAAc,EAAU,sBAAsB,GAC9C,IAAY,EAAU,WACtB,IAAsB,CAAC;AAE7B,WAAA,EAAO,MAAM,IAAI,QAAA,CAAS,GAAM,MAAW;AACzC,YAAM,IAAU,EAAO,KAAK,QAAQ,CAAM;AAC1C,UAAI,GAAS;AACX,cAAM,IAAO,EAAQ,sBAAsB;AAC3C,QAAA,EAAO,KAAK;AAAA,UACV,KAAK;AAAA,UACL,MAAM,EAAK;AAAA,UACX,QAAQ,EAAK,MAAM,EAAY,MAAM;AAAA,UACrC,WAAW,EAAK,SAAS,EAAY,MAAM;AAAA,QAC7C,CAAC;AAAA,MACH;AAAA,IACF,CAAC,GACM;AAAA,EACT,GAAG,CAAC,CAAM,CAAC,GAEL,IAAqB,EAAA,CAAa,MAA4B;AAClE,UAAM,IAAY,EAAO,KAAK,IAAI,QAAQ,qBAAqB;AAC/D,QAAI,CAAC,EAAW,QAAO;AAEvB,UAAM,IAAI,IADU,EAAU,sBACV,EAAY,MAAM,EAAU,WAE1C,IAAS,EAAU;AACzB,aAAS,IAAI,GAAG,IAAI,EAAO,QAAQ,IAEjC,KAAI,KADS,EAAO,CAAA,EAAG,SAAS,EAAO,CAAA,EAAG,aAAa,EAC1C,QAAO;AAEtB,WAAO,EAAO,SAAS;AAAA,EACzB,GAAG,CAAC,GAAQ,CAAS,CAAC,GAEhB,IAAe,EAAA,CAAa,MAAwE;AACxG,UAAM,IAAY,EAAO,KAAK,IAAI,QAAQ,qBAAqB;AAC/D,QAAI,CAAC,EAAW,QAAO;AAEvB,UAAM,IAAI,IADU,EAAU,sBACV,EAAY,MAAM,EAAU,WAE1C,IAAS,EAAU;AACzB,QAAI,EAAO,WAAW,EAAG,QAAO;AAEhC,QAAI,IAAW,GACX,IAAW,OACX,IAAU,EAAO,CAAA,EAAG;AAExB,aAAS,IAAI,GAAG,KAAK,EAAO,QAAQ,KAAK;AACvC,YAAM,IAAQ,IAAI,EAAO,SAAS,EAAO,CAAA,EAAG,SAAS,EAAO,EAAO,SAAS,CAAA,EAAG,WACzE,IAAO,KAAK,IAAI,IAAI,CAAK;AAC/B,MAAI,IAAO,MACT,IAAW,GACX,IAAW,GACX,IAAU;AAAA,IAEd;AAEA,WAAO;AAAA,MAAE,WAAW;AAAA,MAAU,cAAc;AAAA,IAAQ;AAAA,EACtD,GAAG,CAAC,CAAS,CAAC;AAEd,EAAA,EAAA,MAAgB;AACd,UAAM,IAAY,EAAO,KAAK,IAAI,QAAQ,qBAAqB;AAC/D,QAAI,CAAC,EAAW;AAEhB,UAAM,IAAA,CAAmB,MAAkB;AACzC,UAAI,EAAY;AAEhB,YAAM,IAAM,EAAmB,EAAE,OAAO;AACxC,UAAI,IAAM,EAAG;AAEb,YAAM,IAAS,EAAU;AACzB,MAAI,KAAO,EAAO,WAElB,EAAa,EAAO,CAAA,EAAK,MAAM,GAC/B,EAAqB,CAAG,GACxB,EAAW,GACX,EAAW,EAAI;AAAA,IACjB,GAEM,IAAA,MAAyB;AAC7B,MAAK,KAAY,EAAa;AAAA,IAChC;AAEA,WAAA,EAAU,iBAAiB,aAAa,CAAe,GACvD,EAAU,iBAAiB,cAAc,CAAgB,GACzD,MAAa;AACX,MAAA,EAAU,oBAAoB,aAAa,CAAe,GAC1D,EAAU,oBAAoB,cAAc,CAAgB,GAC5D,EAAW;AAAA,IACb;AAAA,EACF,GAAG;AAAA,IAAC;AAAA,IAAQ;AAAA,IAAY;AAAA,IAAc;AAAA,IAAY;AAAA,IAAoB;AAAA,EAAS,CAAC,GAEhF,EAAA,MAAgB;AACd,QAAI,CAAC,EAAU;AACf,UAAM,IAAA,CAAW,MAAkB;AACjC,MAAI,EAAQ,WAAW,CAAC,EAAQ,QAAQ,SAAS,EAAE,MAAc,KAC/D,EAAY,EAAK;AAAA,IAErB;AACA,oBAAS,iBAAiB,aAAa,CAAO,GAC9C,MAAa,SAAS,oBAAoB,aAAa,CAAO;AAAA,EAChE,GAAG,CAAC,CAAQ,CAAC;AAEb,QAAM,IAAgB,EAAA,MAAkB;AACtC,UAAM,IAAS,EAAU;AACzB,QAAI,IAAoB,KAAK,KAAqB,EAAO,OAAQ;AACjE,UAAM,IAAQ,EAAO,CAAA,GACf,IAAY,EAAM,MAAM,EAAM;AACpC,QAAI;AACF,MAAA,EAAO,MAAM,EAAE,MAAM,EAAE,gBAAgB,GAAW,EAAE,MAAM,YAAY,CAAC,EAAE,IAAI,GAC7E,EAAO,SAAS,MAAM,IAAY,CAAC;AAAA,IACrC,QAAQ;AAAA,IAAa;AACrB,IAAA,EAAY,EAAK;AAAA,EACnB,GAAG;AAAA,IAAC;AAAA,IAAQ;AAAA,IAAmB;AAAA,EAAS,CAAC,GAEnC,IAAkB,EAAA,CAAa,MAAwB;AAC3D,MAAE,eAAe,GACjB,EAAE,gBAAgB;AAElB,UAAM,IAAU,GACV,IAAS,EAAU;AACzB,QAAI,IAAU,KAAK,KAAW,EAAO,OAAQ;AAE7C,IAAA,EAAc,EAAI;AAElB,UAAM,IAAA,CAAkB,MAAmB;AACzC,YAAM,IAAO,EAAa,EAAG,OAAO;AACpC,MAAI,KACF,EAAiB,EAAE,KAAK,EAAK,aAAa,CAAC;AAAA,IAE/C,GAEM,IAAA,CAAiB,MAAmB;AACxC,eAAS,oBAAoB,aAAa,CAAc,GACxD,SAAS,oBAAoB,WAAW,CAAa,GACrD,EAAc,EAAK,GACnB,EAAiB,IAAI;AAErB,YAAM,IAAc,EAAU;AAC9B,UAAI,KAAW,EAAY,OAAQ;AAEnC,YAAM,IAAO,EAAa,EAAG,OAAO;AACpC,UAAI,CAAC,EAAM;AAEX,UAAI,IAAa,EAAK;AAGtB,UAAI,MAAe,KAAW,MAAe,IAAU,EAAG;AAE1D,YAAM,IAAc,EAAY,CAAA;AAEhC,UAAI,CADe,EAAO,MAAM,IAAI,OAAO,EAAY,GAClD,EAAY;AAGjB,UAAI;AACJ,UAAI,IAAa,EAAY,OAC3B,CAAA,IAAe,EAAY,CAAA,EAAY;AAAA,WAClC;AACL,cAAM,IAAO,EAAY,EAAY,SAAS,CAAA;AAC9C,QAAA,IAAe,EAAK,MAAM,EAAK;AAAA,MACjC;AAEA,YAAM,IAAa,EAAY,KACzB,IAAW,EAAY,MAAM,EAAY,MACzC,IAAU,EAAO,MAAM,IAAI,MAAM,GAAY,CAAQ,EAAE,SAEvD,EAAE,IAAA,EAAA,IAAO,EAAO;AAEtB,UAAI,KAAc,GAAS;AAEzB,QAAA,EAAG,OAAO,GAAY,CAAQ;AAC9B,cAAM,IAAS,EAAG,QAAQ,IAAI,CAAY;AAC1C,QAAA,EAAG,OAAO,GAAQ,CAAO;AAAA,MAC3B;AAEE,QAAA,EAAG,OAAO,GAAc,CAAO,GAC/B,EAAG,OACD,EAAG,QAAQ,IAAI,CAAU,GACzB,EAAG,QAAQ,IAAI,CAAQ,CACzB;AAGF,MAAA,EAAO,KAAK,SAAS,CAAE;AAAA,IACzB;AAEA,aAAS,iBAAiB,aAAa,CAAc,GACrD,SAAS,iBAAiB,WAAW,CAAa;AAAA,EACpD,GAAG;AAAA,IAAC;AAAA,IAAQ;AAAA,IAAmB;AAAA,IAAW;AAAA,EAAY,CAAC,GAEjD,IAAY;AAAA,IAChB;AAAA,MAAE,OAAO;AAAA,MAAQ,QAAA,MAAc;AAAE,QAAA,EAAc;AAAA,MAAG;AAAA,IAAE;AAAA,IACpD;AAAA,MAAE,OAAO;AAAA,MAAa,QAAA,MAAc;AAAE,QAAA,EAAc,GAAG,EAAO,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI;AAAA,MAAG;AAAA,IAAE;AAAA,IACnH;AAAA,MAAE,OAAO;AAAA,MAAa,QAAA,MAAc;AAAE,QAAA,EAAc,GAAG,EAAO,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI;AAAA,MAAG;AAAA,IAAE;AAAA,IACnH;AAAA,MAAE,OAAO;AAAA,MAAa,QAAA,MAAc;AAAE,QAAA,EAAc,GAAG,EAAO,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI;AAAA,MAAG;AAAA,IAAE;AAAA,IACnH;AAAA,MAAE,OAAO;AAAA,MAAe,QAAA,MAAc;AAAE,QAAA,EAAc,GAAG,EAAO,MAAM,EAAE,MAAM,EAAE,iBAAiB,EAAE,IAAI;AAAA,MAAG;AAAA,IAAE;AAAA,IAC5G;AAAA,MAAE,OAAO;AAAA,MAAiB,QAAA,MAAc;AAAE,QAAA,EAAc,GAAG,EAAO,MAAM,EAAE,MAAM,EAAE,kBAAkB,EAAE,IAAI;AAAA,MAAG;AAAA,IAAE;AAAA,IAC/G;AAAA,MAAE,OAAO;AAAA,MAAa,QAAA,MAAc;AAAE,QAAA,EAAc,GAAG,EAAO,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,IAAI;AAAA,MAAG;AAAA,IAAE;AAAA,IACxG;AAAA,MAAE,OAAO;AAAA,MAAc,QAAA,MAAc;AAAE,QAAA,EAAc,GAAG,EAAO,MAAM,EAAE,MAAM,EAAE,iBAAiB,EAAE,IAAI;AAAA,MAAG;AAAA,IAAE;AAAA,IAC3G;AAAA,MAAE,OAAO;AAAA,MAAc,QAAA,MAAc;AAAE,QAAA,EAAc,GAAG,EAAO,MAAM,EAAE,MAAM,EAAE,WAAW,aAAa,WAAW,EAAE,IAAI;AAAA,MAAG;AAAA,IAAE;AAAA,IAC7H;AAAA,MAAE,OAAO;AAAA,MAAW,QAAA,MAAc;AAAE,QAAA,EAAc,GAAG,EAAO,MAAM,EAAE,MAAM,EAAE,kBAAkB,EAAE,IAAI;AAAA,MAAG;AAAA,IAAE;AAAA,IACzG;AAAA,MAAE,OAAO;AAAA,MAAa,QAAA,MAAc;AAAE,QAAA,EAAc,GAAG,EAAO,MAAM,EAAE,MAAM,EAAE,YAAY;AAAA,UAAE,MAAM;AAAA,UAAG,MAAM;AAAA,UAAG,eAAe;AAAA,QAAK,CAAC,EAAE,IAAI;AAAA,MAAG;AAAA,IAAE;AAAA,EAChJ;AAEA,SAAI,CAAC,KAAW,CAAC,KAAY,CAAC,IAAmB,OAG/C,gBAAA,EAAA,GAAA,EAAA,UAAA;AAAA,IACE,gBAAA,EAAC,OAAD;AAAA,MACE,KAAK;AAAA,MACL,WAAU;AAAA,MACV,OAAO,EAAE,KAAK,EAAU;AAAA,MACxB,cAAA,MAAoB;AAAE,QAAA,EAAe,UAAU,IAAM,EAAW;AAAA,MAAG;AAAA,MACnE,cAAA,MAAoB;AAAE,QAAA,EAAe,UAAU,IAAY,KAAY,EAAa;AAAA,MAAG;AAAA,MACvF,aAAA,CAAc,MAAM;AAAE,UAAE,gBAAgB,GAAG,EAAE,eAAe;AAAA,MAAG;AAAA,gBANjE,CAQE,gBAAA,EAAC,UAAD;AAAA,QACE,MAAK;AAAA,QACL,WAAU;AAAA,QACV,aAAA,CAAc,MAAM;AAAE,YAAE,gBAAgB,GAAG,EAAE,eAAe;AAAA,QAAG;AAAA,QAC/D,SAAA,CAAU,MAAM;AAAE,YAAE,gBAAgB,GAAG,EAAY,CAAC,CAAQ;AAAA,QAAG;AAAA,QAC/D,OAAM;AAAA,kBAEN,gBAAA,EAAC,OAAD;AAAA,UAAK,OAAM;AAAA,UAAK,QAAO;AAAA,UAAK,SAAQ;AAAA,UAAY,MAAK;AAAA,UAAO,QAAO;AAAA,UAAe,aAAY;AAAA,oBAA9F,CAAkG,gBAAA,EAAC,QAAD;AAAA,YAAM,IAAG;AAAA,YAAK,IAAG;AAAA,YAAI,IAAG;AAAA,YAAK,IAAG;AAAA,UAAM,CAAA,GAAC,gBAAA,EAAC,QAAD;AAAA,YAAM,IAAG;AAAA,YAAI,IAAG;AAAA,YAAK,IAAG;AAAA,YAAK,IAAG;AAAA,UAAM,CAAA,CAAM;AAAA;MAC/K,CAAA,GACR,gBAAA,EAAC,UAAD;AAAA,QACE,MAAK;AAAA,QACL,WAAW,qDAAqD,IAAa,oCAAoC,EAAA;AAAA,QACjH,OAAM;AAAA,QACN,aAAa;AAAA,kBAEb,gBAAA,EAAC,OAAD;AAAA,UAAK,OAAM;AAAA,UAAK,QAAO;AAAA,UAAK,SAAQ;AAAA,UAAY,MAAK;AAAA,UAAO,QAAO;AAAA,UAAe,aAAY;AAAA,oBAA9F;AAAA,YACE,gBAAA,EAAC,UAAD;AAAA,cAAQ,IAAG;AAAA,cAAI,IAAG;AAAA,cAAI,GAAE;AAAA,YAAO,CAAA;AAAA,YAAC,gBAAA,EAAC,UAAD;AAAA,cAAQ,IAAG;AAAA,cAAK,IAAG;AAAA,cAAI,GAAE;AAAA,YAAO,CAAA;AAAA,YAChE,gBAAA,EAAC,UAAD;AAAA,cAAQ,IAAG;AAAA,cAAI,IAAG;AAAA,cAAK,GAAE;AAAA,YAAO,CAAA;AAAA,YAAC,gBAAA,EAAC,UAAD;AAAA,cAAQ,IAAG;AAAA,cAAK,IAAG;AAAA,cAAK,GAAE;AAAA,YAAO,CAAA;AAAA,YAClE,gBAAA,EAAC,UAAD;AAAA,cAAQ,IAAG;AAAA,cAAI,IAAG;AAAA,cAAK,GAAE;AAAA,YAAO,CAAA;AAAA,YAAC,gBAAA,EAAC,UAAD;AAAA,cAAQ,IAAG;AAAA,cAAK,IAAG;AAAA,cAAK,GAAE;AAAA,YAAO,CAAA;AAAA,UAC/D;AAAA;MACC,CAAA,CACL;AAAA;IAEJ,KACC,gBAAA,EAAC,OAAD;AAAA,MACE,KAAK;AAAA,MACL,WAAU;AAAA,MACV,OAAO,EAAE,KAAK,IAAY,GAAG;AAAA,MAC7B,aAAA,CAAc,MAAM,EAAE,gBAAgB;AAAA,gBAErC,EAAU,IAAA,CAAK,MACd,gBAAA,EAAC,UAAD;AAAA,QAEE,MAAK;AAAA,QACL,WAAU;AAAA,QACV,aAAA,CAAc,MAAM,EAAE,gBAAgB;AAAA,QACtC,SAAA,CAAU,MAAM;AAAE,UAAA,EAAE,gBAAgB,GAAG,EAAK,OAAO,GAAG,EAAY,EAAK;AAAA,QAAG;AAAA,kBAEzE,EAAK;AAAA,MACA,GAPD,EAAK,KAOJ,CACT;AAAA,IACE,CAAA;AAAA,IAGN,KAAc,KACb,gBAAA,EAAC,OAAD;AAAA,MAAK,WAAU;AAAA,MAAmC,OAAO,EAAE,KAAK,EAAc,IAAI;AAAA,IAAI,CAAA;AAAA,EAExF,EAAA,CAAA;AAEN"}
1
+ {"version":3,"file":"BlockHandle.js","names":[],"sources":["../../../../src/components/pro/RichTextEditor/BlockHandle.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef, useCallback } from 'react';\nimport type { Editor } from '@tiptap/react';\n\ninterface BlockHandleProps {\n editor: Editor;\n}\n\ninterface BlockInfo {\n pos: number;\n size: number;\n domTop: number;\n domBottom: number;\n}\n\nconst BlockHandle: React.FC<BlockHandleProps> = ({ editor }) => {\n const [visible, setVisible] = useState(false);\n const [handleTop, setHandleTop] = useState(0);\n const [showMenu, setShowMenu] = useState(false);\n const [currentBlockIndex, setCurrentBlockIndex] = useState(-1);\n const [isDragging, setIsDragging] = useState(false);\n const [dropIndicator, setDropIndicator] = useState<{ top: number } | null>(null);\n const menuRef = useRef<HTMLDivElement>(null);\n const handleRef = useRef<HTMLDivElement>(null);\n const hideTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n const hoveringHandle = useRef(false);\n\n const cancelHide = useCallback(() => {\n if (hideTimer.current) {\n clearTimeout(hideTimer.current);\n hideTimer.current = null;\n }\n }, []);\n\n const scheduleHide = useCallback(() => {\n cancelHide();\n hideTimer.current = setTimeout(() => {\n if (!hoveringHandle.current && !showMenu && !isDragging) {\n setVisible(false);\n }\n }, 200);\n }, [cancelHide, showMenu, isDragging]);\n\n const getBlocks = useCallback((): BlockInfo[] => {\n const wrapperEl = editor.view.dom.closest('.rte-editor-wrapper') as HTMLElement | null;\n if (!wrapperEl) return [];\n const wrapperRect = wrapperEl.getBoundingClientRect();\n const scrollTop = wrapperEl.scrollTop;\n const blocks: BlockInfo[] = [];\n\n editor.state.doc.forEach((node, offset) => {\n const domNode = editor.view.nodeDOM(offset) as HTMLElement | null;\n if (domNode) {\n const rect = domNode.getBoundingClientRect();\n blocks.push({\n pos: offset,\n size: node.nodeSize,\n domTop: rect.top - wrapperRect.top + scrollTop,\n domBottom: rect.bottom - wrapperRect.top + scrollTop,\n });\n }\n });\n return blocks;\n }, [editor]);\n\n const findBlockByClientY = useCallback((clientY: number): number => {\n const wrapperEl = editor.view.dom.closest('.rte-editor-wrapper') as HTMLElement | null;\n if (!wrapperEl) return -1;\n const wrapperRect = wrapperEl.getBoundingClientRect();\n const y = clientY - wrapperRect.top + wrapperEl.scrollTop;\n\n const blocks = getBlocks();\n for (let i = 0; i < blocks.length; i++) {\n const mid = (blocks[i].domTop + blocks[i].domBottom) / 2;\n if (y < mid) return i;\n }\n return blocks.length - 1;\n }, [editor, getBlocks]);\n\n const findDropSlot = useCallback((clientY: number): { slotIndex: number; indicatorTop: number } | null => {\n const wrapperEl = editor.view.dom.closest('.rte-editor-wrapper') as HTMLElement | null;\n if (!wrapperEl) return null;\n const wrapperRect = wrapperEl.getBoundingClientRect();\n const y = clientY - wrapperRect.top + wrapperEl.scrollTop;\n\n const blocks = getBlocks();\n if (blocks.length === 0) return null;\n\n let bestSlot = 0;\n let bestDist = Infinity;\n let bestTop = blocks[0].domTop;\n\n for (let i = 0; i <= blocks.length; i++) {\n const edgeY = i < blocks.length ? blocks[i].domTop : blocks[blocks.length - 1].domBottom;\n const dist = Math.abs(y - edgeY);\n if (dist < bestDist) {\n bestDist = dist;\n bestSlot = i;\n bestTop = edgeY;\n }\n }\n\n return { slotIndex: bestSlot, indicatorTop: bestTop };\n }, [getBlocks]);\n\n useEffect(() => {\n const wrapperEl = editor.view.dom.closest('.rte-editor-wrapper') as HTMLElement | null;\n if (!wrapperEl) return;\n\n const handleMouseMove = (e: MouseEvent) => {\n if (isDragging) return;\n\n const idx = findBlockByClientY(e.clientY);\n if (idx < 0) return;\n\n const blocks = getBlocks();\n if (idx >= blocks.length) return;\n\n setHandleTop(blocks[idx].domTop);\n setCurrentBlockIndex(idx);\n cancelHide();\n setVisible(true);\n };\n\n const handleMouseLeave = () => {\n if (!isDragging) scheduleHide();\n };\n\n wrapperEl.addEventListener('mousemove', handleMouseMove);\n wrapperEl.addEventListener('mouseleave', handleMouseLeave);\n return () => {\n wrapperEl.removeEventListener('mousemove', handleMouseMove);\n wrapperEl.removeEventListener('mouseleave', handleMouseLeave);\n cancelHide();\n };\n }, [editor, cancelHide, scheduleHide, isDragging, findBlockByClientY, getBlocks]);\n\n useEffect(() => {\n if (!showMenu) return;\n const handler = (e: MouseEvent) => {\n if (menuRef.current && !menuRef.current.contains(e.target as Node)) {\n setShowMenu(false);\n }\n };\n document.addEventListener('mousedown', handler);\n return () => document.removeEventListener('mousedown', handler);\n }, [showMenu]);\n\n const addBlockBelow = useCallback(() => {\n const blocks = getBlocks();\n if (currentBlockIndex < 0 || currentBlockIndex >= blocks.length) return;\n const block = blocks[currentBlockIndex];\n const insertPos = block.pos + block.size;\n try {\n editor.chain().focus().insertContentAt(insertPos, { type: 'paragraph' }).run();\n editor.commands.focus(insertPos + 1);\n } catch { /* noop */ }\n setShowMenu(false);\n }, [editor, currentBlockIndex, getBlocks]);\n\n const handleDragStart = useCallback((e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n\n const dragIdx = currentBlockIndex;\n const blocks = getBlocks();\n if (dragIdx < 0 || dragIdx >= blocks.length) return;\n\n setIsDragging(true);\n\n const handleDragMove = (ev: MouseEvent) => {\n const slot = findDropSlot(ev.clientY);\n if (slot) {\n setDropIndicator({ top: slot.indicatorTop });\n }\n };\n\n const handleDragEnd = (ev: MouseEvent) => {\n document.removeEventListener('mousemove', handleDragMove);\n document.removeEventListener('mouseup', handleDragEnd);\n setIsDragging(false);\n setDropIndicator(null);\n\n const freshBlocks = getBlocks();\n if (dragIdx >= freshBlocks.length) return;\n\n const slot = findDropSlot(ev.clientY);\n if (!slot) return;\n\n let targetSlot = slot.slotIndex;\n\n // No-op: dropping at the same position or one below (no actual move)\n if (targetSlot === dragIdx || targetSlot === dragIdx + 1) return;\n\n const sourceBlock = freshBlocks[dragIdx];\n const sourceNode = editor.state.doc.nodeAt(sourceBlock.pos);\n if (!sourceNode) return;\n\n // Compute the insert position (before which block, or at end)\n let insertBefore: number;\n if (targetSlot < freshBlocks.length) {\n insertBefore = freshBlocks[targetSlot].pos;\n } else {\n const last = freshBlocks[freshBlocks.length - 1];\n insertBefore = last.pos + last.size;\n }\n\n const sourceFrom = sourceBlock.pos;\n const sourceTo = sourceBlock.pos + sourceBlock.size;\n const content = editor.state.doc.slice(sourceFrom, sourceTo).content;\n\n const { tr } = editor.state;\n\n if (targetSlot <= dragIdx) {\n // Moving up: delete source first (it's after target), then insert\n tr.delete(sourceFrom, sourceTo);\n const mapped = tr.mapping.map(insertBefore);\n tr.insert(mapped, content);\n } else {\n // Moving down: insert first (target is after source), then delete\n tr.insert(insertBefore, content);\n tr.delete(\n tr.mapping.map(sourceFrom),\n tr.mapping.map(sourceTo)\n );\n }\n\n editor.view.dispatch(tr);\n };\n\n document.addEventListener('mousemove', handleDragMove);\n document.addEventListener('mouseup', handleDragEnd);\n }, [editor, currentBlockIndex, getBlocks, findDropSlot]);\n\n const menuItems = [\n { label: 'Text', action: () => { addBlockBelow(); } },\n { label: 'Heading 1', action: () => { addBlockBelow(); editor.chain().focus().toggleHeading({ level: 1 }).run(); } },\n { label: 'Heading 2', action: () => { addBlockBelow(); editor.chain().focus().toggleHeading({ level: 2 }).run(); } },\n { label: 'Heading 3', action: () => { addBlockBelow(); editor.chain().focus().toggleHeading({ level: 3 }).run(); } },\n { label: 'Bullet List', action: () => { addBlockBelow(); editor.chain().focus().toggleBulletList().run(); } },\n { label: 'Numbered List', action: () => { addBlockBelow(); editor.chain().focus().toggleOrderedList().run(); } },\n { label: 'Task List', action: () => { addBlockBelow(); editor.chain().focus().toggleTaskList().run(); } },\n { label: 'Blockquote', action: () => { addBlockBelow(); editor.chain().focus().toggleBlockquote().run(); } },\n { label: 'Code Block', action: () => { addBlockBelow(); editor.chain().focus().toggleNode('codeBlock', 'paragraph').run(); } },\n { label: 'Divider', action: () => { addBlockBelow(); editor.chain().focus().setHorizontalRule().run(); } },\n { label: 'Table 3×3', action: () => { addBlockBelow(); editor.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run(); } },\n ];\n\n if (!visible && !showMenu && !isDragging) return null;\n\n return (\n <>\n <div\n ref={handleRef}\n className=\"rte-block-handle\"\n style={{ top: handleTop }}\n onMouseEnter={() => { hoveringHandle.current = true; cancelHide(); }}\n onMouseLeave={() => { hoveringHandle.current = false; if (!isDragging) scheduleHide(); }}\n onMouseDown={(e) => { e.stopPropagation(); e.preventDefault(); }}\n >\n <button\n type=\"button\"\n className=\"rte-block-handle__btn rte-block-handle__btn--add\"\n onMouseDown={(e) => { e.stopPropagation(); e.preventDefault(); }}\n onClick={(e) => { e.stopPropagation(); setShowMenu(!showMenu); }}\n title=\"Add block\"\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" /><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" /></svg>\n </button>\n <button\n type=\"button\"\n className={`rte-block-handle__btn rte-block-handle__btn--drag ${isDragging ? 'rte-block-handle__btn--dragging' : ''}`}\n title=\"Drag to reorder\"\n onMouseDown={handleDragStart}\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <circle cx=\"9\" cy=\"6\" r=\"1.5\" /><circle cx=\"15\" cy=\"6\" r=\"1.5\" />\n <circle cx=\"9\" cy=\"12\" r=\"1.5\" /><circle cx=\"15\" cy=\"12\" r=\"1.5\" />\n <circle cx=\"9\" cy=\"18\" r=\"1.5\" /><circle cx=\"15\" cy=\"18\" r=\"1.5\" />\n </svg>\n </button>\n </div>\n\n {showMenu && (\n <div\n ref={menuRef}\n className=\"rte-block-handle__menu\"\n style={{ top: handleTop + 28 }}\n onMouseDown={(e) => e.stopPropagation()}\n >\n {menuItems.map((item) => (\n <button\n key={item.label}\n type=\"button\"\n className=\"rte-block-handle__menu-item\"\n onMouseDown={(e) => e.stopPropagation()}\n onClick={(e) => { e.stopPropagation(); item.action(); setShowMenu(false); }}\n >\n {item.label}\n </button>\n ))}\n </div>\n )}\n\n {isDragging && dropIndicator && (\n <div className=\"rte-block-handle__drop-indicator\" style={{ top: dropIndicator.top }} />\n )}\n </>\n );\n};\n\nexport default BlockHandle;\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"BubbleToolbar.js","names":[],"sources":["../../../../src/components/pro/RichTextEditor/BubbleToolbar.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef } from 'react';\nimport type { Editor } from '@tiptap/react';\n\ninterface BubbleToolbarProps {\n editor: Editor;\n onAddComment?: () => void;\n}\n\nconst BubbleToolbar: React.FC<BubbleToolbarProps> = ({ editor, onAddComment }) => {\n const [visible, setVisible] = useState(false);\n const [pos, setPos] = useState({ x: 0, y: 0 });\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const update = () => {\n const { from, to } = editor.state.selection;\n if (from === to || !editor.isFocused) {\n setVisible(false);\n return;\n }\n const coords = editor.view.coordsAtPos(from);\n const endCoords = editor.view.coordsAtPos(to);\n const wrapperEl = editor.view.dom.closest('.rte-editor-wrapper');\n if (!wrapperEl) return;\n const rect = wrapperEl.getBoundingClientRect();\n\n const centerX = (coords.left + endCoords.left) / 2 - rect.left;\n const topY = Math.min(coords.top, endCoords.top) - rect.top - 44;\n\n setPos({ x: centerX, y: topY });\n setVisible(true);\n };\n\n editor.on('selectionUpdate', update);\n editor.on('blur', () => setVisible(false));\n return () => {\n editor.off('selectionUpdate', update);\n };\n }, [editor]);\n\n if (!visible) return null;\n\n const btn = (onClick: () => void, title: string, isActive: boolean, children: React.ReactNode) => (\n <button\n type=\"button\"\n className={`rte-bubble__btn ${isActive ? 'rte-bubble__btn--active' : ''}`}\n onClick={onClick}\n title={title}\n onMouseDown={(e) => e.preventDefault()}\n >\n {children}\n </button>\n );\n\n return (\n <div ref={ref} className=\"rte-bubble\" style={{ left: pos.x, top: pos.y }}>\n {btn(() => editor.chain().focus().toggleBold().run(), 'Bold', editor.isActive('bold'),\n <strong style={{ fontSize: 13 }}>B</strong>)}\n {btn(() => editor.chain().focus().toggleItalic().run(), 'Italic', editor.isActive('italic'),\n <em style={{ fontSize: 13 }}>I</em>)}\n {btn(() => editor.chain().focus().toggleUnderline().run(), 'Underline', editor.isActive('underline'),\n <span style={{ fontSize: 13, textDecoration: 'underline' }}>U</span>)}\n {btn(() => editor.chain().focus().toggleStrike().run(), 'Strike', editor.isActive('strike'),\n <span style={{ fontSize: 13, textDecoration: 'line-through' }}>S</span>)}\n {btn(() => editor.chain().focus().toggleCode().run(), 'Code', editor.isActive('code'),\n <span style={{ fontSize: 11, fontFamily: 'monospace' }}>&lt;/&gt;</span>)}\n {btn(() => {\n const url = window.prompt('URL:');\n if (url) editor.chain().focus().setLink({ href: url }).run();\n }, 'Link', editor.isActive('link'),\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><path d=\"M10 13a5 5 0 007.54.54l3-3a5 5 0 00-7.07-7.07l-1.72 1.71\" /><path d=\"M14 11a5 5 0 00-7.54-.54l-3 3a5 5 0 007.07 7.07l1.71-1.71\" /></svg>)}\n {onAddComment && (\n <>\n <div className=\"rte-bubble__divider\" />\n {btn(onAddComment, 'Comment', false,\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><path d=\"M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z\" /></svg>)}\n </>\n )}\n </div>\n );\n};\n\nexport default BubbleToolbar;\n"],"mappings":"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"}
1
+ {"version":3,"file":"BubbleToolbar.js","names":[],"sources":["../../../../src/components/pro/RichTextEditor/BubbleToolbar.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef } from 'react';\nimport type { Editor } from '@tiptap/react';\n\ninterface BubbleToolbarProps {\n editor: Editor;\n onAddComment?: () => void;\n}\n\nconst BubbleToolbar: React.FC<BubbleToolbarProps> = ({ editor, onAddComment }) => {\n const [visible, setVisible] = useState(false);\n const [pos, setPos] = useState({ x: 0, y: 0 });\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const update = () => {\n const { from, to } = editor.state.selection;\n if (from === to || !editor.isFocused) {\n setVisible(false);\n return;\n }\n const coords = editor.view.coordsAtPos(from);\n const endCoords = editor.view.coordsAtPos(to);\n const wrapperEl = editor.view.dom.closest('.rte-editor-wrapper');\n if (!wrapperEl) return;\n const rect = wrapperEl.getBoundingClientRect();\n\n const centerX = (coords.left + endCoords.left) / 2 - rect.left;\n const topY = Math.min(coords.top, endCoords.top) - rect.top - 44;\n\n setPos({ x: centerX, y: topY });\n setVisible(true);\n };\n\n editor.on('selectionUpdate', update);\n editor.on('blur', () => setVisible(false));\n return () => {\n editor.off('selectionUpdate', update);\n };\n }, [editor]);\n\n if (!visible) return null;\n\n const btn = (onClick: () => void, title: string, isActive: boolean, children: React.ReactNode) => (\n <button\n type=\"button\"\n className={`rte-bubble__btn ${isActive ? 'rte-bubble__btn--active' : ''}`}\n onClick={onClick}\n title={title}\n onMouseDown={(e) => e.preventDefault()}\n >\n {children}\n </button>\n );\n\n return (\n <div ref={ref} className=\"rte-bubble\" style={{ left: pos.x, top: pos.y }}>\n {btn(() => editor.chain().focus().toggleBold().run(), 'Bold', editor.isActive('bold'),\n <strong style={{ fontSize: 13 }}>B</strong>)}\n {btn(() => editor.chain().focus().toggleItalic().run(), 'Italic', editor.isActive('italic'),\n <em style={{ fontSize: 13 }}>I</em>)}\n {btn(() => editor.chain().focus().toggleUnderline().run(), 'Underline', editor.isActive('underline'),\n <span style={{ fontSize: 13, textDecoration: 'underline' }}>U</span>)}\n {btn(() => editor.chain().focus().toggleStrike().run(), 'Strike', editor.isActive('strike'),\n <span style={{ fontSize: 13, textDecoration: 'line-through' }}>S</span>)}\n {btn(() => editor.chain().focus().toggleCode().run(), 'Code', editor.isActive('code'),\n <span style={{ fontSize: 11, fontFamily: 'monospace' }}>&lt;/&gt;</span>)}\n {btn(() => {\n const url = window.prompt('URL:');\n if (url) editor.chain().focus().setLink({ href: url }).run();\n }, 'Link', editor.isActive('link'),\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><path d=\"M10 13a5 5 0 007.54.54l3-3a5 5 0 00-7.07-7.07l-1.72 1.71\" /><path d=\"M14 11a5 5 0 00-7.54-.54l-3 3a5 5 0 007.07 7.07l1.71-1.71\" /></svg>)}\n {onAddComment && (\n <>\n <div className=\"rte-bubble__divider\" />\n {btn(onAddComment, 'Comment', false,\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><path d=\"M21 15a2 2 0 01-2 2H7l-4 4V5a2 2 0 012-2h14a2 2 0 012 2z\" /></svg>)}\n </>\n )}\n </div>\n );\n};\n\nexport default BubbleToolbar;\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"CommentDialog.js","names":[],"sources":["../../../../src/components/pro/RichTextEditor/CommentDialog.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect } from 'react';\n\ninterface CommentDialogProps {\n open: boolean;\n onSubmit: (text: string) => void;\n onClose: () => void;\n}\n\nconst CommentDialog: React.FC<CommentDialogProps> = ({ open, onSubmit, onClose }) => {\n const [text, setText] = useState('');\n const inputRef = useRef<HTMLTextAreaElement>(null);\n\n useEffect(() => {\n if (open) {\n setText('');\n setTimeout(() => inputRef.current?.focus(), 50);\n }\n }, [open]);\n\n useEffect(() => {\n if (!open) return;\n const handleKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') onClose();\n };\n document.addEventListener('keydown', handleKey);\n return () => document.removeEventListener('keydown', handleKey);\n }, [open, onClose]);\n\n if (!open) return null;\n\n const handleSubmit = () => {\n if (text.trim()) {\n onSubmit(text.trim());\n setText('');\n }\n };\n\n return (\n <div className=\"rte-dialog-overlay\" onClick={onClose}>\n <div className=\"rte-dialog\" onClick={(e) => e.stopPropagation()}>\n <div className=\"rte-dialog__header\">\n <span className=\"rte-dialog__title\">Add Comment</span>\n <button type=\"button\" className=\"rte-dialog__close\" onClick={onClose}>\n <svg width=\"16\" height=\"16\" 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 className=\"rte-dialog__body\">\n <textarea\n ref={inputRef}\n className=\"rte-dialog__textarea\"\n value={text}\n onChange={(e) => setText(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); handleSubmit(); }\n }}\n placeholder=\"Write your comment...\"\n rows={3}\n />\n </div>\n <div className=\"rte-dialog__footer\">\n <button type=\"button\" className=\"rte-dialog__btn rte-dialog__btn--cancel\" onClick={onClose}>Cancel</button>\n <button type=\"button\" className=\"rte-dialog__btn rte-dialog__btn--submit\" onClick={handleSubmit} disabled={!text.trim()}>Add Comment</button>\n </div>\n </div>\n </div>\n );\n};\n\nexport default CommentDialog;\n"],"mappings":";;AAQA,IAAM,IAAA,CAA+C,EAAE,MAAA,GAAM,UAAA,GAAU,SAAA,EAAA,MAAc;AACnF,QAAM,CAAC,GAAM,CAAA,IAAW,EAAS,EAAE,GAC7B,IAAW,EAA4B,IAAI;AAkBjD,MAhBA,EAAA,MAAgB;AACd,IAAI,MACF,EAAQ,EAAE,GACV,WAAA,MAAiB,EAAS,SAAS,MAAM,GAAG,EAAE;AAAA,EAElD,GAAG,CAAC,CAAI,CAAC,GAET,EAAA,MAAgB;AACd,QAAI,CAAC,EAAM;AACX,UAAM,IAAA,CAAa,MAAqB;AACtC,MAAI,EAAE,QAAQ,YAAU,EAAQ;AAAA,IAClC;AACA,oBAAS,iBAAiB,WAAW,CAAS,GAC9C,MAAa,SAAS,oBAAoB,WAAW,CAAS;AAAA,EAChE,GAAG,CAAC,GAAM,CAAO,CAAC,GAEd,CAAC,EAAM,QAAO;AAElB,QAAM,IAAA,MAAqB;AACzB,IAAI,EAAK,KAAK,MACZ,EAAS,EAAK,KAAK,CAAC,GACpB,EAAQ,EAAE;AAAA,EAEd;AAEA,SACE,gBAAA,EAAC,OAAD;AAAA,IAAK,WAAU;AAAA,IAAqB,SAAS;AAAA,cAC3C,gBAAA,EAAC,OAAD;AAAA,MAAK,WAAU;AAAA,MAAa,SAAA,CAAU,MAAM,EAAE,gBAAgB;AAAA,gBAA9D;AAAA,QACE,gBAAA,EAAC,OAAD;AAAA,UAAK,WAAU;AAAA,oBAAf,CACE,gBAAA,EAAC,QAAD;AAAA,YAAM,WAAU;AAAA,sBAAoB;AAAA,UAAiB,CAAA,GACrD,gBAAA,EAAC,UAAD;AAAA,YAAQ,MAAK;AAAA,YAAS,WAAU;AAAA,YAAoB,SAAS;AAAA,sBAC3D,gBAAA,EAAC,OAAD;AAAA,cAAK,OAAM;AAAA,cAAK,QAAO;AAAA,cAAK,SAAQ;AAAA,cAAY,MAAK;AAAA,cAAO,QAAO;AAAA,cAAe,aAAY;AAAA,wBAA9F,CAAkG,gBAAA,EAAC,QAAD;AAAA,gBAAM,IAAG;AAAA,gBAAK,IAAG;AAAA,gBAAI,IAAG;AAAA,gBAAI,IAAG;AAAA,cAAM,CAAA,GAAC,gBAAA,EAAC,QAAD;AAAA,gBAAM,IAAG;AAAA,gBAAI,IAAG;AAAA,gBAAI,IAAG;AAAA,gBAAK,IAAG;AAAA,cAAM,CAAA,CAAM;AAAA;UAC7K,CAAA,CACL;AAAA;QACL,gBAAA,EAAC,OAAD;AAAA,UAAK,WAAU;AAAA,oBACb,gBAAA,EAAC,YAAD;AAAA,YACE,KAAK;AAAA,YACL,WAAU;AAAA,YACV,OAAO;AAAA,YACP,UAAA,CAAW,MAAM,EAAQ,EAAE,OAAO,KAAK;AAAA,YACvC,WAAA,CAAY,MAAM;AAChB,cAAI,EAAE,QAAQ,WAAW,CAAC,EAAE,aAAY,EAAE,eAAe,GAAG,EAAa;AAAA,YAC3E;AAAA,YACA,aAAY;AAAA,YACZ,MAAM;AAAA,UACP,CAAA;AAAA,QACE,CAAA;AAAA,QACL,gBAAA,EAAC,OAAD;AAAA,UAAK,WAAU;AAAA,oBAAf,CACE,gBAAA,EAAC,UAAD;AAAA,YAAQ,MAAK;AAAA,YAAS,WAAU;AAAA,YAA0C,SAAS;AAAA,sBAAS;AAAA,UAAc,CAAA,GAC1G,gBAAA,EAAC,UAAD;AAAA,YAAQ,MAAK;AAAA,YAAS,WAAU;AAAA,YAA0C,SAAS;AAAA,YAAc,UAAU,CAAC,EAAK,KAAK;AAAA,sBAAG;AAAA,UAAmB,CAAA,CACzI;AAAA;MACF;AAAA;EACF,CAAA;AAET"}
1
+ {"version":3,"file":"CommentDialog.js","names":[],"sources":["../../../../src/components/pro/RichTextEditor/CommentDialog.tsx"],"sourcesContent":["import React, { useState, useRef, useEffect } from 'react';\n\ninterface CommentDialogProps {\n open: boolean;\n onSubmit: (text: string) => void;\n onClose: () => void;\n}\n\nconst CommentDialog: React.FC<CommentDialogProps> = ({ open, onSubmit, onClose }) => {\n const [text, setText] = useState('');\n const inputRef = useRef<HTMLTextAreaElement>(null);\n\n useEffect(() => {\n if (open) {\n setText('');\n setTimeout(() => inputRef.current?.focus(), 50);\n }\n }, [open]);\n\n useEffect(() => {\n if (!open) return;\n const handleKey = (e: KeyboardEvent) => {\n if (e.key === 'Escape') onClose();\n };\n document.addEventListener('keydown', handleKey);\n return () => document.removeEventListener('keydown', handleKey);\n }, [open, onClose]);\n\n if (!open) return null;\n\n const handleSubmit = () => {\n if (text.trim()) {\n onSubmit(text.trim());\n setText('');\n }\n };\n\n return (\n <div className=\"rte-dialog-overlay\" onClick={onClose}>\n <div className=\"rte-dialog\" onClick={(e) => e.stopPropagation()}>\n <div className=\"rte-dialog__header\">\n <span className=\"rte-dialog__title\">Add Comment</span>\n <button type=\"button\" className=\"rte-dialog__close\" onClick={onClose}>\n <svg width=\"16\" height=\"16\" 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 className=\"rte-dialog__body\">\n <textarea\n ref={inputRef}\n className=\"rte-dialog__textarea\"\n value={text}\n onChange={(e) => setText(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); handleSubmit(); }\n }}\n placeholder=\"Write your comment...\"\n rows={3}\n />\n </div>\n <div className=\"rte-dialog__footer\">\n <button type=\"button\" className=\"rte-dialog__btn rte-dialog__btn--cancel\" onClick={onClose}>Cancel</button>\n <button type=\"button\" className=\"rte-dialog__btn rte-dialog__btn--submit\" onClick={handleSubmit} disabled={!text.trim()}>Add Comment</button>\n </div>\n </div>\n </div>\n );\n};\n\nexport default CommentDialog;\n"],"mappings":";;AAQA,IAAM,IAAA,CAA+C,EAAE,MAAA,GAAM,UAAA,GAAU,SAAA,EAAA,MAAc;AACnF,QAAM,CAAC,GAAM,CAAA,IAAW,EAAS,EAAE,GAC7B,IAAW,EAA4B,IAAI;AAkBjD,MAhBA,EAAA,MAAgB;AACd,IAAI,MACF,EAAQ,EAAE,GACV,WAAA,MAAiB,EAAS,SAAS,MAAM,GAAG,EAAE;AAAA,EAElD,GAAG,CAAC,CAAI,CAAC,GAET,EAAA,MAAgB;AACd,QAAI,CAAC,EAAM;AACX,UAAM,IAAA,CAAa,MAAqB;AACtC,MAAI,EAAE,QAAQ,YAAU,EAAQ;AAAA,IAClC;AACA,oBAAS,iBAAiB,WAAW,CAAS,GAC9C,MAAa,SAAS,oBAAoB,WAAW,CAAS;AAAA,EAChE,GAAG,CAAC,GAAM,CAAO,CAAC,GAEd,CAAC,EAAM,QAAO;AAElB,QAAM,IAAA,MAAqB;AACzB,IAAI,EAAK,KAAK,MACZ,EAAS,EAAK,KAAK,CAAC,GACpB,EAAQ,EAAE;AAAA,EAEd;AAEA,SACE,gBAAA,EAAC,OAAD;AAAA,IAAK,WAAU;AAAA,IAAqB,SAAS;AAAA,IAC3C,UAAA,gBAAA,EAAC,OAAD;AAAA,MAAK,WAAU;AAAA,MAAa,SAAA,CAAU,MAAM,EAAE,gBAAgB;AAAA,MAA9D,UAAA;AAAA,QACE,gBAAA,EAAC,OAAD;AAAA,UAAK,WAAU;AAAA,UAAf,UAAA,CACE,gBAAA,EAAC,QAAD;AAAA,YAAM,WAAU;AAAA,YAAoB,UAAA;AAAA,UAAiB,CAAA,GACrD,gBAAA,EAAC,UAAD;AAAA,YAAQ,MAAK;AAAA,YAAS,WAAU;AAAA,YAAoB,SAAS;AAAA,YAC3D,UAAA,gBAAA,EAAC,OAAD;AAAA,cAAK,OAAM;AAAA,cAAK,QAAO;AAAA,cAAK,SAAQ;AAAA,cAAY,MAAK;AAAA,cAAO,QAAO;AAAA,cAAe,aAAY;AAAA,cAA9F,UAAA,CAAkG,gBAAA,EAAC,QAAD;AAAA,gBAAM,IAAG;AAAA,gBAAK,IAAG;AAAA,gBAAI,IAAG;AAAA,gBAAI,IAAG;AAAA,cAAM,CAAA,GAAC,gBAAA,EAAC,QAAD;AAAA,gBAAM,IAAG;AAAA,gBAAI,IAAG;AAAA,gBAAI,IAAG;AAAA,gBAAK,IAAG;AAAA,cAAM,CAAA,CAAM;AAAA;UAC7K,CAAA,CACL;AAAA;QACL,gBAAA,EAAC,OAAD;AAAA,UAAK,WAAU;AAAA,UACb,UAAA,gBAAA,EAAC,YAAD;AAAA,YACE,KAAK;AAAA,YACL,WAAU;AAAA,YACV,OAAO;AAAA,YACP,UAAA,CAAW,MAAM,EAAQ,EAAE,OAAO,KAAK;AAAA,YACvC,WAAA,CAAY,MAAM;AAChB,cAAI,EAAE,QAAQ,WAAW,CAAC,EAAE,aAAY,EAAE,eAAe,GAAG,EAAa;AAAA,YAC3E;AAAA,YACA,aAAY;AAAA,YACZ,MAAM;AAAA,UACP,CAAA;AAAA,QACE,CAAA;AAAA,QACL,gBAAA,EAAC,OAAD;AAAA,UAAK,WAAU;AAAA,UAAf,UAAA,CACE,gBAAA,EAAC,UAAD;AAAA,YAAQ,MAAK;AAAA,YAAS,WAAU;AAAA,YAA0C,SAAS;AAAA,YAAS,UAAA;AAAA,UAAc,CAAA,GAC1G,gBAAA,EAAC,UAAD;AAAA,YAAQ,MAAK;AAAA,YAAS,WAAU;AAAA,YAA0C,SAAS;AAAA,YAAc,UAAU,CAAC,EAAK,KAAK;AAAA,YAAG,UAAA;AAAA,UAAmB,CAAA,CACzI;AAAA;MACF;AAAA;EACF,CAAA;AAET"}
@@ -1 +1 @@
1
- {"version":3,"file":"CommentPanel.js","names":[],"sources":["../../../../src/components/pro/RichTextEditor/CommentPanel.tsx"],"sourcesContent":["import React, { useState, useCallback, useRef, useEffect, useImperativeHandle, forwardRef } from 'react';\nimport type { Editor } from '@tiptap/react';\nimport type { CommentThread, CommentItem } from './extensions/CommentMark';\n\nexport interface CommentPanelHandle {\n scrollToThread: (id: string) => void;\n}\n\ninterface CommentPanelProps {\n editor: Editor;\n threads: CommentThread[];\n onThreadsChange: (threads: CommentThread[]) => void;\n onRequestAddComment: () => void;\n currentUser?: string;\n}\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\nconst CommentPanel = forwardRef<CommentPanelHandle, CommentPanelProps>(({\n editor,\n threads,\n onThreadsChange,\n onRequestAddComment,\n currentUser = 'User',\n}, ref) => {\n const [replyingTo, setReplyingTo] = useState<string | null>(null);\n const [replyText, setReplyText] = useState('');\n const replyInputRef = useRef<HTMLInputElement>(null);\n const threadRefs = useRef<Map<string, HTMLDivElement>>(new Map());\n const listRef = useRef<HTMLDivElement>(null);\n\n useImperativeHandle(ref, () => ({\n scrollToThread: (id: string) => {\n const el = threadRefs.current.get(id);\n if (el) {\n el.scrollIntoView({ behavior: 'smooth', block: 'center' });\n el.classList.add('rte-comments__thread--highlight');\n setTimeout(() => el.classList.remove('rte-comments__thread--highlight'), 1500);\n }\n },\n }));\n\n useEffect(() => {\n if (replyingTo && replyInputRef.current) {\n replyInputRef.current.focus();\n }\n }, [replyingTo]);\n\n const toggleResolve = useCallback((threadId: string) => {\n const updated = threads.map((t) => {\n if (t.id !== threadId) return t;\n const newResolved = !t.resolved;\n editor.state.doc.descendants((node, pos) => {\n node.marks.forEach((mark) => {\n if (mark.type.name === 'comment' && mark.attrs.commentId === threadId) {\n editor.view.dispatch(\n editor.state.tr\n .removeMark(pos, pos + node.nodeSize, mark)\n .addMark(pos, pos + node.nodeSize, mark.type.create({ ...mark.attrs, resolved: newResolved }))\n );\n }\n });\n });\n return { ...t, resolved: newResolved };\n });\n onThreadsChange(updated);\n }, [editor, threads, onThreadsChange]);\n\n const addReply = useCallback((threadId: string) => {\n if (!replyText.trim()) return;\n const reply: CommentItem = {\n id: generateId(),\n author: currentUser,\n text: replyText.trim(),\n createdAt: Date.now(),\n };\n const updated = threads.map((t) =>\n t.id === threadId ? { ...t, comments: [...t.comments, reply] } : t\n );\n onThreadsChange(updated);\n setReplyText('');\n setReplyingTo(null);\n }, [replyText, threads, onThreadsChange, currentUser]);\n\n const deleteThread = useCallback((threadId: string) => {\n editor.state.doc.descendants((node, pos) => {\n node.marks.forEach((mark) => {\n if (mark.type.name === 'comment' && mark.attrs.commentId === threadId) {\n editor.view.dispatch(\n editor.state.tr.removeMark(pos, pos + node.nodeSize, mark)\n );\n }\n });\n });\n onThreadsChange(threads.filter((t) => t.id !== threadId));\n }, [editor, threads, onThreadsChange]);\n\n const activeThreads = threads.filter((t) => !t.resolved);\n const resolvedThreads = threads.filter((t) => t.resolved);\n\n const renderThread = (thread: CommentThread) => (\n <div\n key={thread.id}\n ref={(el) => { if (el) threadRefs.current.set(thread.id, el); else threadRefs.current.delete(thread.id); }}\n className={`rte-comments__thread ${thread.resolved ? 'rte-comments__thread--resolved' : ''}`}\n >\n <div className=\"rte-comments__thread-header\">\n <span className={`rte-comments__status ${thread.resolved ? 'rte-comments__status--resolved' : ''}`}>\n {thread.resolved ? '✓ Resolved' : 'Open'}\n </span>\n <div className=\"rte-comments__thread-actions\">\n <button\n type=\"button\"\n className=\"rte-comments__icon-btn\"\n onClick={() => toggleResolve(thread.id)}\n title={thread.resolved ? 'Unresolve' : 'Resolve'}\n >\n {thread.resolved ? (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><path d=\"M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-4 0h4\" /></svg>\n ) : (\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 )}\n </button>\n <button\n type=\"button\"\n className=\"rte-comments__icon-btn rte-comments__icon-btn--danger\"\n onClick={() => deleteThread(thread.id)}\n title=\"Delete thread\"\n >\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 {thread.comments.map((c) => (\n <div key={c.id} className=\"rte-comments__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 {replyingTo === thread.id ? (\n <div className=\"rte-comments__reply-form\">\n <input\n ref={replyInputRef}\n className=\"rte-comments__reply-input\"\n value={replyText}\n onChange={(e) => setReplyText(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') addReply(thread.id);\n if (e.key === 'Escape') { setReplyingTo(null); setReplyText(''); }\n }}\n placeholder=\"Reply...\"\n />\n <button type=\"button\" className=\"rte-comments__reply-send\" onClick={() => addReply(thread.id)}>\n <svg width=\"14\" height=\"14\" 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 ) : (\n <button\n type=\"button\"\n className=\"rte-comments__reply-trigger\"\n onClick={() => setReplyingTo(thread.id)}\n >\n Reply...\n </button>\n )}\n </div>\n );\n\n return (\n <div className=\"rte-comments\">\n <div className=\"rte-comments__header\">\n <span className=\"rte-comments__title\">\n Comments\n {activeThreads.length > 0 && <span className=\"rte-comments__badge\">{activeThreads.length}</span>}\n </span>\n <button\n type=\"button\"\n className=\"rte-comments__add-btn\"\n onClick={onRequestAddComment}\n title=\"Add comment to selection\"\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" /><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" /></svg>\n </button>\n </div>\n\n <div ref={listRef} className=\"rte-comments__list\">\n {threads.length === 0 ? (\n <div className=\"rte-comments__empty\">Select text and click + to add a comment</div>\n ) : (\n <>\n {activeThreads.map(renderThread)}\n {resolvedThreads.length > 0 && (\n <>\n <div className=\"rte-comments__section-label\">Resolved ({resolvedThreads.length})</div>\n {resolvedThreads.map(renderThread)}\n </>\n )}\n </>\n )}\n </div>\n </div>\n );\n});\n\nCommentPanel.displayName = 'CommentPanel';\n\nexport default CommentPanel;\n"],"mappings":"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"}
1
+ {"version":3,"file":"CommentPanel.js","names":[],"sources":["../../../../src/components/pro/RichTextEditor/CommentPanel.tsx"],"sourcesContent":["import React, { useState, useCallback, useRef, useEffect, useImperativeHandle, forwardRef } from 'react';\nimport type { Editor } from '@tiptap/react';\nimport type { CommentThread, CommentItem } from './extensions/CommentMark';\n\nexport interface CommentPanelHandle {\n scrollToThread: (id: string) => void;\n}\n\ninterface CommentPanelProps {\n editor: Editor;\n threads: CommentThread[];\n onThreadsChange: (threads: CommentThread[]) => void;\n onRequestAddComment: () => void;\n currentUser?: string;\n}\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\nconst CommentPanel = forwardRef<CommentPanelHandle, CommentPanelProps>(({\n editor,\n threads,\n onThreadsChange,\n onRequestAddComment,\n currentUser = 'User',\n}, ref) => {\n const [replyingTo, setReplyingTo] = useState<string | null>(null);\n const [replyText, setReplyText] = useState('');\n const replyInputRef = useRef<HTMLInputElement>(null);\n const threadRefs = useRef<Map<string, HTMLDivElement>>(new Map());\n const listRef = useRef<HTMLDivElement>(null);\n\n useImperativeHandle(ref, () => ({\n scrollToThread: (id: string) => {\n const el = threadRefs.current.get(id);\n if (el) {\n el.scrollIntoView({ behavior: 'smooth', block: 'center' });\n el.classList.add('rte-comments__thread--highlight');\n setTimeout(() => el.classList.remove('rte-comments__thread--highlight'), 1500);\n }\n },\n }));\n\n useEffect(() => {\n if (replyingTo && replyInputRef.current) {\n replyInputRef.current.focus();\n }\n }, [replyingTo]);\n\n const toggleResolve = useCallback((threadId: string) => {\n const updated = threads.map((t) => {\n if (t.id !== threadId) return t;\n const newResolved = !t.resolved;\n editor.state.doc.descendants((node, pos) => {\n node.marks.forEach((mark) => {\n if (mark.type.name === 'comment' && mark.attrs.commentId === threadId) {\n editor.view.dispatch(\n editor.state.tr\n .removeMark(pos, pos + node.nodeSize, mark)\n .addMark(pos, pos + node.nodeSize, mark.type.create({ ...mark.attrs, resolved: newResolved }))\n );\n }\n });\n });\n return { ...t, resolved: newResolved };\n });\n onThreadsChange(updated);\n }, [editor, threads, onThreadsChange]);\n\n const addReply = useCallback((threadId: string) => {\n if (!replyText.trim()) return;\n const reply: CommentItem = {\n id: generateId(),\n author: currentUser,\n text: replyText.trim(),\n createdAt: Date.now(),\n };\n const updated = threads.map((t) =>\n t.id === threadId ? { ...t, comments: [...t.comments, reply] } : t\n );\n onThreadsChange(updated);\n setReplyText('');\n setReplyingTo(null);\n }, [replyText, threads, onThreadsChange, currentUser]);\n\n const deleteThread = useCallback((threadId: string) => {\n editor.state.doc.descendants((node, pos) => {\n node.marks.forEach((mark) => {\n if (mark.type.name === 'comment' && mark.attrs.commentId === threadId) {\n editor.view.dispatch(\n editor.state.tr.removeMark(pos, pos + node.nodeSize, mark)\n );\n }\n });\n });\n onThreadsChange(threads.filter((t) => t.id !== threadId));\n }, [editor, threads, onThreadsChange]);\n\n const activeThreads = threads.filter((t) => !t.resolved);\n const resolvedThreads = threads.filter((t) => t.resolved);\n\n const renderThread = (thread: CommentThread) => (\n <div\n key={thread.id}\n ref={(el) => { if (el) threadRefs.current.set(thread.id, el); else threadRefs.current.delete(thread.id); }}\n className={`rte-comments__thread ${thread.resolved ? 'rte-comments__thread--resolved' : ''}`}\n >\n <div className=\"rte-comments__thread-header\">\n <span className={`rte-comments__status ${thread.resolved ? 'rte-comments__status--resolved' : ''}`}>\n {thread.resolved ? '✓ Resolved' : 'Open'}\n </span>\n <div className=\"rte-comments__thread-actions\">\n <button\n type=\"button\"\n className=\"rte-comments__icon-btn\"\n onClick={() => toggleResolve(thread.id)}\n title={thread.resolved ? 'Unresolve' : 'Resolve'}\n >\n {thread.resolved ? (\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><path d=\"M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-4 0h4\" /></svg>\n ) : (\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 )}\n </button>\n <button\n type=\"button\"\n className=\"rte-comments__icon-btn rte-comments__icon-btn--danger\"\n onClick={() => deleteThread(thread.id)}\n title=\"Delete thread\"\n >\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 {thread.comments.map((c) => (\n <div key={c.id} className=\"rte-comments__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 {replyingTo === thread.id ? (\n <div className=\"rte-comments__reply-form\">\n <input\n ref={replyInputRef}\n className=\"rte-comments__reply-input\"\n value={replyText}\n onChange={(e) => setReplyText(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') addReply(thread.id);\n if (e.key === 'Escape') { setReplyingTo(null); setReplyText(''); }\n }}\n placeholder=\"Reply...\"\n />\n <button type=\"button\" className=\"rte-comments__reply-send\" onClick={() => addReply(thread.id)}>\n <svg width=\"14\" height=\"14\" 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 ) : (\n <button\n type=\"button\"\n className=\"rte-comments__reply-trigger\"\n onClick={() => setReplyingTo(thread.id)}\n >\n Reply...\n </button>\n )}\n </div>\n );\n\n return (\n <div className=\"rte-comments\">\n <div className=\"rte-comments__header\">\n <span className=\"rte-comments__title\">\n Comments\n {activeThreads.length > 0 && <span className=\"rte-comments__badge\">{activeThreads.length}</span>}\n </span>\n <button\n type=\"button\"\n className=\"rte-comments__add-btn\"\n onClick={onRequestAddComment}\n title=\"Add comment to selection\"\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\"><line x1=\"12\" y1=\"5\" x2=\"12\" y2=\"19\" /><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\" /></svg>\n </button>\n </div>\n\n <div ref={listRef} className=\"rte-comments__list\">\n {threads.length === 0 ? (\n <div className=\"rte-comments__empty\">Select text and click + to add a comment</div>\n ) : (\n <>\n {activeThreads.map(renderThread)}\n {resolvedThreads.length > 0 && (\n <>\n <div className=\"rte-comments__section-label\">Resolved ({resolvedThreads.length})</div>\n {resolvedThreads.map(renderThread)}\n </>\n )}\n </>\n )}\n </div>\n </div>\n );\n});\n\nCommentPanel.displayName = 'CommentPanel';\n\nexport default CommentPanel;\n"],"mappings":"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"}
@@ -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 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}\n\nconst CommentPopover: React.FC<CommentPopoverProps> = ({\n editor,\n threads,\n onThreadsChange,\n showPanel,\n onOpenPanel,\n onScrollToThread,\n currentUser = 'User',\n}) => {\n const [activeThread, setActiveThread] = useState<CommentThread | null>(null);\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) { setActiveThread(null); return; }\n\n const commentId = commentEl.getAttribute('data-comment-id');\n if (!commentId) return;\n\n const thread = threads.find((t) => t.id === commentId);\n if (!thread || thread.resolved) return;\n\n if (showPanel) {\n onScrollToThread(commentId);\n setActiveThread(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 setActiveThread(thread);\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 setActiveThread(null);\n }\n };\n document.addEventListener('mousedown', handler);\n return () => document.removeEventListener('mousedown', handler);\n }, [activeThread]);\n\n useEffect(() => {\n if (activeThread && inputRef.current) inputRef.current.focus();\n }, [activeThread]);\n\n const toggleResolve = useCallback(() => {\n if (!activeThread) return;\n const updated = threads.map((t) => {\n if (t.id !== activeThread.id) return t;\n editor.state.doc.descendants((node, pos) => {\n node.marks.forEach((mark) => {\n if (mark.type.name === 'comment' && mark.attrs.commentId === activeThread.id) {\n editor.view.dispatch(\n editor.state.tr\n .removeMark(pos, pos + node.nodeSize, mark)\n .addMark(pos, pos + node.nodeSize, mark.type.create({ ...mark.attrs, resolved: true }))\n );\n }\n });\n });\n return { ...t, resolved: true };\n });\n onThreadsChange(updated);\n setActiveThread(null);\n }, [activeThread, editor, threads, onThreadsChange]);\n\n const addReply = useCallback(() => {\n if (!activeThread || !replyText.trim()) return;\n const reply: CommentItem = {\n id: generateId(),\n author: currentUser,\n text: replyText.trim(),\n createdAt: Date.now(),\n };\n const updated = threads.map((t) =>\n t.id === activeThread.id ? { ...t, comments: [...t.comments, reply] } : t\n );\n onThreadsChange(updated);\n setActiveThread(updated.find((t) => t.id === activeThread.id) || null);\n setReplyText('');\n }, [activeThread, replyText, threads, onThreadsChange, currentUser]);\n\n if (!activeThread) 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 <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(); setActiveThread(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={() => setActiveThread(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 <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.key === 'Enter') addReply();\n if (e.key === 'Escape') setActiveThread(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":[],"sources":["../../../../src/components/pro/RichTextEditor/CommentPopover.tsx"],"sourcesContent":["import React, { useState, useEffect, useRef, useCallback } from 'react';\nimport 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}\n\nconst CommentPopover: React.FC<CommentPopoverProps> = ({\n editor,\n threads,\n onThreadsChange,\n showPanel,\n onOpenPanel,\n onScrollToThread,\n currentUser = 'User',\n}) => {\n const [activeThread, setActiveThread] = useState<CommentThread | null>(null);\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) { setActiveThread(null); return; }\n\n const commentId = commentEl.getAttribute('data-comment-id');\n if (!commentId) return;\n\n const thread = threads.find((t) => t.id === commentId);\n if (!thread || thread.resolved) return;\n\n if (showPanel) {\n onScrollToThread(commentId);\n setActiveThread(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 setActiveThread(thread);\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 setActiveThread(null);\n }\n };\n document.addEventListener('mousedown', handler);\n return () => document.removeEventListener('mousedown', handler);\n }, [activeThread]);\n\n useEffect(() => {\n if (activeThread && inputRef.current) inputRef.current.focus();\n }, [activeThread]);\n\n const toggleResolve = useCallback(() => {\n if (!activeThread) return;\n const updated = threads.map((t) => {\n if (t.id !== activeThread.id) return t;\n editor.state.doc.descendants((node, pos) => {\n node.marks.forEach((mark) => {\n if (mark.type.name === 'comment' && mark.attrs.commentId === activeThread.id) {\n editor.view.dispatch(\n editor.state.tr\n .removeMark(pos, pos + node.nodeSize, mark)\n .addMark(pos, pos + node.nodeSize, mark.type.create({ ...mark.attrs, resolved: true }))\n );\n }\n });\n });\n return { ...t, resolved: true };\n });\n onThreadsChange(updated);\n setActiveThread(null);\n }, [activeThread, editor, threads, onThreadsChange]);\n\n const addReply = useCallback(() => {\n if (!activeThread || !replyText.trim()) return;\n const reply: CommentItem = {\n id: generateId(),\n author: currentUser,\n text: replyText.trim(),\n createdAt: Date.now(),\n };\n const updated = threads.map((t) =>\n t.id === activeThread.id ? { ...t, comments: [...t.comments, reply] } : t\n );\n onThreadsChange(updated);\n setActiveThread(updated.find((t) => t.id === activeThread.id) || null);\n setReplyText('');\n }, [activeThread, replyText, threads, onThreadsChange, currentUser]);\n\n if (!activeThread) 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 <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(); setActiveThread(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={() => setActiveThread(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 <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.key === 'Enter') addReply();\n if (e.key === 'Escape') setActiveThread(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":";;AAIA,SAAS,IAAa;AACpB,SAAO,KAAK,KAAK,IAAI,CAAA,IAAK,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,CAAC,CAAA;AACjE;AAEA,SAAS,EAAQ,GAAoB;AACnC,QAAM,IAAO,KAAK,IAAI,IAAI,GACpB,IAAM,KAAK,MAAM,IAAO,GAAI;AAClC,MAAI,IAAM,GAAI,QAAO;AACrB,QAAM,IAAM,KAAK,MAAM,IAAM,EAAE;AAC/B,MAAI,IAAM,GAAI,QAAO,GAAG,CAAA;AACxB,QAAM,IAAK,KAAK,MAAM,IAAM,EAAE;AAC9B,SAAI,IAAK,KAAW,GAAG,CAAA,UAEhB,GADG,KAAK,MAAM,IAAK,EAChB,CAAA;AACZ;AAYA,IAAM,IAAA,CAAiD,EACrD,QAAA,GACA,SAAA,GACA,iBAAA,GACA,WAAA,GACA,aAAA,GACA,kBAAA,GACA,aAAA,IAAc,OAAA,MACV;AACJ,QAAM,CAAC,GAAc,CAAA,IAAmB,EAA+B,IAAI,GACrE,CAAC,GAAK,CAAA,IAAU,EAAS;AAAA,IAAE,GAAG;AAAA,IAAG,GAAG;AAAA,EAAE,CAAC,GACvC,CAAC,GAAW,CAAA,IAAgB,EAAS,EAAE,GACvC,IAAS,EAAuB,IAAI,GACpC,IAAW,EAAyB,IAAI;AAE9C,EAAA,EAAA,MAAgB;AACd,UAAM,IAAM,EAAO,KAAK,KAClB,IAAA,CAAe,MAAa;AAEhC,YAAM,IADS,EAAE,OACQ,QAAQ,mBAAmB;AACpD,UAAI,CAAC,GAAW;AAAE,QAAA,EAAgB,IAAI;AAAG;AAAA,MAAQ;AAEjD,YAAM,IAAY,EAAU,aAAa,iBAAiB;AAC1D,UAAI,CAAC,EAAW;AAEhB,YAAM,IAAS,EAAQ,KAAA,CAAM,MAAM,EAAE,OAAO,CAAS;AACrD,UAAI,CAAC,KAAU,EAAO,SAAU;AAEhC,UAAI,GAAW;AACb,QAAA,EAAiB,CAAS,GAC1B,EAAgB,IAAI;AACpB;AAAA,MACF;AAEA,YAAM,IAAY,EAAI,QAAQ,qBAAqB;AACnD,UAAI,CAAC,EAAW;AAChB,YAAM,IAAQ,EAAU,sBAAsB,GACxC,IAAS,EAAU,sBAAsB;AAE/C,MAAA,EAAO;AAAA,QACL,GAAG,EAAO,OAAO,EAAM,OAAO,EAAO,QAAQ;AAAA,QAC7C,GAAG,EAAO,SAAS,EAAM,MAAM;AAAA,MACjC,CAAC,GACD,EAAgB,CAAM,GACtB,EAAa,EAAE;AAAA,IACjB;AAEA,WAAA,EAAI,iBAAiB,SAAS,CAAW,GACzC,MAAa,EAAI,oBAAoB,SAAS,CAAW;AAAA,EAC3D,GAAG;AAAA,IAAC;AAAA,IAAQ;AAAA,IAAS;AAAA,IAAW;AAAA,EAAgB,CAAC,GAEjD,EAAA,MAAgB;AACd,QAAI,CAAC,EAAc;AACnB,UAAM,IAAA,CAAW,MAAkB;AACjC,MAAI,EAAO,WAAW,CAAC,EAAO,QAAQ,SAAS,EAAE,MAAc,KAC7D,EAAgB,IAAI;AAAA,IAExB;AACA,oBAAS,iBAAiB,aAAa,CAAO,GAC9C,MAAa,SAAS,oBAAoB,aAAa,CAAO;AAAA,EAChE,GAAG,CAAC,CAAY,CAAC,GAEjB,EAAA,MAAgB;AACd,IAAI,KAAgB,EAAS,WAAS,EAAS,QAAQ,MAAM;AAAA,EAC/D,GAAG,CAAC,CAAY,CAAC;AAEjB,QAAM,IAAgB,EAAA,MAAkB;AACtC,IAAK,MAgBL,EAfgB,EAAQ,IAAA,CAAK,MACvB,EAAE,OAAO,EAAa,KAAW,KACrC,EAAO,MAAM,IAAI,YAAA,CAAa,GAAM,MAAQ;AAC1C,MAAA,EAAK,MAAM,QAAA,CAAS,MAAS;AAC3B,QAAI,EAAK,KAAK,SAAS,aAAa,EAAK,MAAM,cAAc,EAAa,MACxE,EAAO,KAAK,SACV,EAAO,MAAM,GACV,WAAW,GAAK,IAAM,EAAK,UAAU,CAAI,EACzC,QAAQ,GAAK,IAAM,EAAK,UAAU,EAAK,KAAK,OAAO;AAAA,UAAE,GAAG,EAAK;AAAA,UAAO,UAAU;AAAA,QAAK,CAAC,CAAC,CAC1F;AAAA,MAEJ,CAAC;AAAA,IACH,CAAC,GACM;AAAA,MAAE,GAAG;AAAA,MAAG,UAAU;AAAA,IAAK,EAEhB,CAAO,GACvB,EAAgB,IAAI;AAAA,EACtB,GAAG;AAAA,IAAC;AAAA,IAAc;AAAA,IAAQ;AAAA,IAAS;AAAA,EAAe,CAAC,GAE7C,IAAW,EAAA,MAAkB;AACjC,QAAI,CAAC,KAAgB,CAAC,EAAU,KAAK,EAAG;AACxC,UAAM,IAAqB;AAAA,MACzB,IAAI,EAAW;AAAA,MACf,QAAQ;AAAA,MACR,MAAM,EAAU,KAAK;AAAA,MACrB,WAAW,KAAK,IAAI;AAAA,IACtB,GACM,IAAU,EAAQ,IAAA,CAAK,MAC3B,EAAE,OAAO,EAAa,KAAK;AAAA,MAAE,GAAG;AAAA,MAAG,UAAU,CAAC,GAAG,EAAE,UAAU,CAAK;AAAA,IAAE,IAAI,CAC1E;AACA,IAAA,EAAgB,CAAO,GACvB,EAAgB,EAAQ,KAAA,CAAM,MAAM,EAAE,OAAO,EAAa,EAAE,KAAK,IAAI,GACrE,EAAa,EAAE;AAAA,EACjB,GAAG;AAAA,IAAC;AAAA,IAAc;AAAA,IAAW;AAAA,IAAS;AAAA,IAAiB;AAAA,EAAW,CAAC;AAEnE,SAAK,IAGH,gBAAA,EAAC,OAAD;AAAA,IAAK,KAAK;AAAA,IAAQ,WAAU;AAAA,IAAsB,OAAO;AAAA,MAAE,MAAM,EAAI;AAAA,MAAG,KAAK,EAAI;AAAA,IAAE;AAAA,IAAnF,UAAA;AAAA,MACE,gBAAA,EAAC,OAAD;AAAA,QAAK,WAAU;AAAA,QAAf,UAAA,CACE,gBAAA,EAAC,QAAD;AAAA,UAAM,WAAU;AAAA,UAA8B,UAAA;AAAA,QAAU,CAAA,GACxD,gBAAA,EAAC,OAAD;AAAA,UAAK,WAAU;AAAA,UAAf,UAAA;AAAA,YACE,gBAAA,EAAC,UAAD;AAAA,cAAQ,MAAK;AAAA,cAAS,WAAU;AAAA,cAAyB,SAAS;AAAA,cAAe,OAAM;AAAA,cACrF,UAAA,gBAAA,EAAC,OAAD;AAAA,gBAAK,OAAM;AAAA,gBAAK,QAAO;AAAA,gBAAK,SAAQ;AAAA,gBAAY,MAAK;AAAA,gBAAO,QAAO;AAAA,gBAAe,aAAY;AAAA,gBAAI,UAAA,gBAAA,EAAC,YAAD,EAAU,QAAO,iBAAkB,CAAA;AAAA,cAAM,CAAA;AAAA,YACrI,CAAA;AAAA,YACR,gBAAA,EAAC,UAAD;AAAA,cAAQ,MAAK;AAAA,cAAS,WAAU;AAAA,cAAyB,SAAA,MAAe;AAAE,gBAAA,EAAY,GAAG,EAAgB,IAAI;AAAA,cAAG;AAAA,cAAG,OAAM;AAAA,cACvH,UAAA,gBAAA,EAAC,OAAD;AAAA,gBAAK,OAAM;AAAA,gBAAK,QAAO;AAAA,gBAAK,SAAQ;AAAA,gBAAY,MAAK;AAAA,gBAAO,QAAO;AAAA,gBAAe,aAAY;AAAA,gBAA9F,UAAA;AAAA,kBAAkG,gBAAA,EAAC,YAAD,EAAU,QAAO,iBAAkB,CAAA;AAAA,kBAAC,gBAAA,EAAC,YAAD,EAAU,QAAO,iBAAkB,CAAA;AAAA,kBAAC,gBAAA,EAAC,QAAD;AAAA,oBAAM,IAAG;AAAA,oBAAK,IAAG;AAAA,oBAAI,IAAG;AAAA,oBAAK,IAAG;AAAA,kBAAM,CAAA;AAAA,kBAAC,gBAAA,EAAC,QAAD;AAAA,oBAAM,IAAG;AAAA,oBAAI,IAAG;AAAA,oBAAK,IAAG;AAAA,oBAAK,IAAG;AAAA,kBAAM,CAAA;AAAA,gBAAM;AAAA;YACvP,CAAA;AAAA,YACR,gBAAA,EAAC,UAAD;AAAA,cAAQ,MAAK;AAAA,cAAS,WAAU;AAAA,cAAyB,SAAA,MAAe,EAAgB,IAAI;AAAA,cAAG,OAAM;AAAA,cACnG,UAAA,gBAAA,EAAC,OAAD;AAAA,gBAAK,OAAM;AAAA,gBAAK,QAAO;AAAA,gBAAK,SAAQ;AAAA,gBAAY,MAAK;AAAA,gBAAO,QAAO;AAAA,gBAAe,aAAY;AAAA,gBAA9F,UAAA,CAAkG,gBAAA,EAAC,QAAD;AAAA,kBAAM,IAAG;AAAA,kBAAK,IAAG;AAAA,kBAAI,IAAG;AAAA,kBAAI,IAAG;AAAA,gBAAM,CAAA,GAAC,gBAAA,EAAC,QAAD;AAAA,kBAAM,IAAG;AAAA,kBAAI,IAAG;AAAA,kBAAI,IAAG;AAAA,kBAAK,IAAG;AAAA,gBAAM,CAAA,CAAM;AAAA;YAC7K,CAAA;AAAA,UACL;AAAA,QACF,CAAA,CAAA;AAAA;MAEJ,EAAa,SAAS,IAAA,CAAK,MAC1B,gBAAA,EAAC,OAAD;AAAA,QAAgB,WAAU;AAAA,QAA1B,UAAA,CACE,gBAAA,EAAC,OAAD;AAAA,UAAK,WAAU;AAAA,UAAf,UAAA,CACE,gBAAA,EAAC,QAAD;AAAA,YAAM,WAAU;AAAA,YAAwB,UAAA,EAAE;AAAA,UAAa,CAAA,GACvD,gBAAA,EAAC,QAAD;AAAA,YAAM,WAAU;AAAA,YAAsB,UAAA,EAAQ,EAAE,SAAS;AAAA,UAAQ,CAAA,CAC9D;AAAA,QACL,CAAA,GAAA,gBAAA,EAAC,OAAD;AAAA,UAAK,WAAU;AAAA,UAA8B,UAAA,EAAE;AAAA,QAAU,CAAA,CACtD;AAAA,MANK,GAAA,EAAE,EAMP,CACN;AAAA,MAED,gBAAA,EAAC,OAAD;AAAA,QAAK,WAAU;AAAA,QAAf,UAAA,CACE,gBAAA,EAAC,SAAD;AAAA,UACE,KAAK;AAAA,UACL,WAAU;AAAA,UACV,OAAO;AAAA,UACP,UAAA,CAAW,MAAM,EAAa,EAAE,OAAO,KAAK;AAAA,UAC5C,WAAA,CAAY,MAAM;AAChB,YAAI,EAAE,QAAQ,WAAS,EAAS,GAC5B,EAAE,QAAQ,YAAU,EAAgB,IAAI;AAAA,UAC9C;AAAA,UACA,aAAY;AAAA,QACb,CAAA,GACD,gBAAA,EAAC,UAAD;AAAA,UAAQ,MAAK;AAAA,UAAS,WAAU;AAAA,UAA2B,SAAS;AAAA,UAAU,UAAU,CAAC,EAAU,KAAK;AAAA,UACtG,UAAA,gBAAA,EAAC,OAAD;AAAA,YAAK,OAAM;AAAA,YAAK,QAAO;AAAA,YAAK,SAAQ;AAAA,YAAY,MAAK;AAAA,YAAO,QAAO;AAAA,YAAe,aAAY;AAAA,YAA9F,UAAA,CAAkG,gBAAA,EAAC,QAAD;AAAA,cAAM,IAAG;AAAA,cAAK,IAAG;AAAA,cAAI,IAAG;AAAA,cAAK,IAAG;AAAA,YAAM,CAAA,GAAC,gBAAA,EAAC,WAAD,EAAS,QAAO,4BAA6B,CAAA,CAAM;AAAA;QACtL,CAAA,CACL;AAAA;IACF;AAAA,OA7CmB;AA+C5B"}