@keboola/design 11.0.0 → 11.0.1

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 (662) hide show
  1. package/dist/AIKit-Dre37SJr.js +1320 -0
  2. package/dist/AIKit-Dre37SJr.js.map +1 -0
  3. package/dist/Alert-DfZq9kGe.js +133 -0
  4. package/dist/Alert-DfZq9kGe.js.map +1 -0
  5. package/dist/AlertModal-BUC4Es8o.js +222 -0
  6. package/dist/AlertModal-BUC4Es8o.js.map +1 -0
  7. package/dist/AppShell-B5GQN6Zs.js +143 -0
  8. package/dist/AppShell-B5GQN6Zs.js.map +1 -0
  9. package/dist/AutoSaveTextarea-BeuWuszr.js +58 -0
  10. package/dist/{chunk-UGT6DKWM.js.map → AutoSaveTextarea-BeuWuszr.js.map} +1 -1
  11. package/dist/Badge-Ch26CXoP.js +195 -0
  12. package/dist/Badge-Ch26CXoP.js.map +1 -0
  13. package/dist/BrandEditor-B8o9zdZO.js +903 -0
  14. package/dist/BrandEditor-B8o9zdZO.js.map +1 -0
  15. package/dist/BrandLogo-CJkRd0F8.js +46 -0
  16. package/dist/BrandLogo-CJkRd0F8.js.map +1 -0
  17. package/dist/Breadcrumb-DJp7WwSv.js +330 -0
  18. package/dist/Breadcrumb-DJp7WwSv.js.map +1 -0
  19. package/dist/Button-nzmDNS2q.js +391 -0
  20. package/dist/Button-nzmDNS2q.js.map +1 -0
  21. package/dist/Calendar-cG5NIJ4O.js +6768 -0
  22. package/dist/Calendar-cG5NIJ4O.js.map +1 -0
  23. package/dist/Card-BAoZ35CV.js +105 -0
  24. package/dist/Card-BAoZ35CV.js.map +1 -0
  25. package/dist/Checkbox-GJ8-srt4.js +97 -0
  26. package/dist/Checkbox-GJ8-srt4.js.map +1 -0
  27. package/dist/Clipboard-CBJZiviP.js +58 -0
  28. package/dist/Clipboard-CBJZiviP.js.map +1 -0
  29. package/dist/ClipboardButton-ez5V3fkk.js +43 -0
  30. package/dist/ClipboardButton-ez5V3fkk.js.map +1 -0
  31. package/dist/CodeEditor-BfQJfbhL.js +952 -0
  32. package/dist/CodeEditor-BfQJfbhL.js.map +1 -0
  33. package/dist/Collapsible-BQXWEOBC.js +34 -0
  34. package/dist/Collapsible-BQXWEOBC.js.map +1 -0
  35. package/dist/ColorInput-Dx8Dsv7Y.js +180 -0
  36. package/dist/ColorInput-Dx8Dsv7Y.js.map +1 -0
  37. package/dist/ColorModeSwitch-CCqj7tjE.js +77 -0
  38. package/dist/ColorModeSwitch-CCqj7tjE.js.map +1 -0
  39. package/dist/Combobox-c_xBjf0P.js +439 -0
  40. package/dist/Combobox-c_xBjf0P.js.map +1 -0
  41. package/dist/Command-CQ_bQsJp.js +102 -0
  42. package/dist/Command-CQ_bQsJp.js.map +1 -0
  43. package/dist/CopyField-BJ96zvXs.js +322 -0
  44. package/dist/CopyField-BJ96zvXs.js.map +1 -0
  45. package/dist/DateInput-CMD3dY-T.js +141 -0
  46. package/dist/DateInput-CMD3dY-T.js.map +1 -0
  47. package/dist/DatePicker-BbFbmsGl.js +24 -0
  48. package/dist/DatePicker-BbFbmsGl.js.map +1 -0
  49. package/dist/DateRangeInput-D3BhiKyk.js +139 -0
  50. package/dist/DateRangeInput-D3BhiKyk.js.map +1 -0
  51. package/dist/DateRangePicker-BiUgtt_M.js +159 -0
  52. package/dist/DateRangePicker-BiUgtt_M.js.map +1 -0
  53. package/dist/DiagramSkeleton-lwBS2YBa.js +11 -0
  54. package/dist/DiagramSkeleton-lwBS2YBa.js.map +1 -0
  55. package/dist/DiffView-ppTIzh2h.js +429 -0
  56. package/dist/DiffView-ppTIzh2h.js.map +1 -0
  57. package/dist/DropdownMenu-B6ZbYvaM.js +327 -0
  58. package/dist/DropdownMenu-B6ZbYvaM.js.map +1 -0
  59. package/dist/FieldBox-D7DYtX_m.js +70 -0
  60. package/dist/FieldBox-D7DYtX_m.js.map +1 -0
  61. package/dist/FileUpload-sXRv7JiY.js +2527 -0
  62. package/dist/FileUpload-sXRv7JiY.js.map +1 -0
  63. package/dist/Form-BDCef6O9.js +371 -0
  64. package/dist/Form-BDCef6O9.js.map +1 -0
  65. package/dist/FormGroup-S9mPNHKH.js +124 -0
  66. package/dist/FormGroup-S9mPNHKH.js.map +1 -0
  67. package/dist/FullScreenModal-CJa2VkJ2.js +96 -0
  68. package/dist/FullScreenModal-CJa2VkJ2.js.map +1 -0
  69. package/dist/HoverCard-WfDkLK1s.js +31 -0
  70. package/dist/HoverCard-WfDkLK1s.js.map +1 -0
  71. package/dist/InputGroup-BJWsI35s.js +292 -0
  72. package/dist/InputGroup-BJWsI35s.js.map +1 -0
  73. package/dist/Kbd-CxHAo1oo.js +111 -0
  74. package/dist/Kbd-CxHAo1oo.js.map +1 -0
  75. package/dist/MarkedText-Ckbft5mw.js +44 -0
  76. package/dist/MarkedText-Ckbft5mw.js.map +1 -0
  77. package/dist/MermaidDiagram-BB06gymm.js +399 -0
  78. package/dist/MermaidDiagram-BB06gymm.js.map +1 -0
  79. package/dist/Modal-BA5Wc3sx.js +185 -0
  80. package/dist/Modal-BA5Wc3sx.js.map +1 -0
  81. package/dist/ModalTitle-C76ke2eo.js +28 -0
  82. package/dist/ModalTitle-C76ke2eo.js.map +1 -0
  83. package/dist/MultiActionButtonGroup-CiBHxsSk.js +33 -0
  84. package/dist/MultiActionButtonGroup-CiBHxsSk.js.map +1 -0
  85. package/dist/Navbar-t16usFZQ.js +322 -0
  86. package/dist/Navbar-t16usFZQ.js.map +1 -0
  87. package/dist/OtpInput-CbbymqYs.js +93 -0
  88. package/dist/OtpInput-CbbymqYs.js.map +1 -0
  89. package/dist/PageHeader-Q3IpCnQd.js +177 -0
  90. package/dist/PageHeader-Q3IpCnQd.js.map +1 -0
  91. package/dist/PageLayout-DSVM-ASz.js +176 -0
  92. package/dist/PageLayout-DSVM-ASz.js.map +1 -0
  93. package/dist/PageToolbar-0_1OBzaZ.js +153 -0
  94. package/dist/PageToolbar-0_1OBzaZ.js.map +1 -0
  95. package/dist/Pagination-CM_Rszz-.js +70 -0
  96. package/dist/Pagination-CM_Rszz-.js.map +1 -0
  97. package/dist/Popconfirm-BGe1jLov.js +170 -0
  98. package/dist/Popconfirm-BGe1jLov.js.map +1 -0
  99. package/dist/Popover-Ca0V6AD1.js +92 -0
  100. package/dist/Popover-Ca0V6AD1.js.map +1 -0
  101. package/dist/RadioGroup-sIveSsNa.js +233 -0
  102. package/dist/RadioGroup-sIveSsNa.js.map +1 -0
  103. package/dist/Resizable-D3vYToZH.js +52 -0
  104. package/dist/Resizable-D3vYToZH.js.map +1 -0
  105. package/dist/Search-3UiqNZRj.js +184 -0
  106. package/dist/Search-3UiqNZRj.js.map +1 -0
  107. package/dist/SearchInput-D2fcOv7E.js +102 -0
  108. package/dist/SearchInput-D2fcOv7E.js.map +1 -0
  109. package/dist/SectionNav--7bw2b6u.js +276 -0
  110. package/dist/SectionNav--7bw2b6u.js.map +1 -0
  111. package/dist/Select-4YX38G5h.js +181 -0
  112. package/dist/Select-4YX38G5h.js.map +1 -0
  113. package/dist/Sheet-BQrX8-h5.js +169 -0
  114. package/dist/Sheet-BQrX8-h5.js.map +1 -0
  115. package/dist/Sidebar-ROaR_AqC.js +799 -0
  116. package/dist/Sidebar-ROaR_AqC.js.map +1 -0
  117. package/dist/Slider-Da_3mS5v.js +127 -0
  118. package/dist/Slider-Da_3mS5v.js.map +1 -0
  119. package/dist/Stepper-C8sm9ZFM.js +325 -0
  120. package/dist/Stepper-C8sm9ZFM.js.map +1 -0
  121. package/dist/Switch-CX2A0v50.js +201 -0
  122. package/dist/Switch-CX2A0v50.js.map +1 -0
  123. package/dist/Table-CvYuTuNU.js +104 -0
  124. package/dist/Table-CvYuTuNU.js.map +1 -0
  125. package/dist/Tabs-EAihyqCt.js +74 -0
  126. package/dist/Tabs-EAihyqCt.js.map +1 -0
  127. package/dist/TextInput-BGed-V13.js +110 -0
  128. package/dist/TextInput-BGed-V13.js.map +1 -0
  129. package/dist/ThemeProvider-QncUrfJn.js +203 -0
  130. package/dist/ThemeProvider-QncUrfJn.js.map +1 -0
  131. package/dist/TimePicker-B_NegL-7.js +98 -0
  132. package/dist/TimePicker-B_NegL-7.js.map +1 -0
  133. package/dist/Timeline-6btyJl4D.js +154 -0
  134. package/dist/Timeline-6btyJl4D.js.map +1 -0
  135. package/dist/Toast-DQSbs3oA.js +49 -0
  136. package/dist/Toast-DQSbs3oA.js.map +1 -0
  137. package/dist/ToggleGroup-Cy_10Mvu.js +47 -0
  138. package/dist/ToggleGroup-Cy_10Mvu.js.map +1 -0
  139. package/dist/Workbench-BzE-Vvd9.js +293 -0
  140. package/dist/Workbench-BzE-Vvd9.js.map +1 -0
  141. package/dist/ZoomableSvg-DG9PnAm8.js +248 -0
  142. package/dist/ZoomableSvg-DG9PnAm8.js.map +1 -0
  143. package/dist/charts.d.ts +110 -103
  144. package/dist/charts.js +303 -254
  145. package/dist/charts.js.map +1 -1
  146. package/dist/classNames-BzrkDnOD.js +9 -0
  147. package/dist/classNames-BzrkDnOD.js.map +1 -0
  148. package/dist/constants-D6JcsD4_.d.ts +41 -0
  149. package/dist/context-KxxeMHbR.js +62 -0
  150. package/dist/context-KxxeMHbR.js.map +1 -0
  151. package/dist/editors.d.ts +180 -173
  152. package/dist/editors.js +747 -428
  153. package/dist/editors.js.map +1 -1
  154. package/dist/escapeStringRegexp-8MxP2knR.js +6 -0
  155. package/dist/escapeStringRegexp-8MxP2knR.js.map +1 -0
  156. package/dist/icons-Cek151jC.js +640 -0
  157. package/dist/icons-Cek151jC.js.map +1 -0
  158. package/dist/icons.d.ts +2 -41
  159. package/dist/icons.js +2 -9
  160. package/dist/index-m-kQEWiY.d.ts +54 -0
  161. package/dist/index.d.ts +6183 -9885
  162. package/dist/index.js +112 -124
  163. package/dist/internal/blocks/AIKit.js +2 -30
  164. package/dist/internal/blocks/AppShell.js +2 -11
  165. package/dist/internal/blocks/AutoSaveTextarea.js +2 -14
  166. package/dist/internal/blocks/BrandEditor.js +2 -23
  167. package/dist/internal/blocks/ChartPanel.js +45 -9
  168. package/dist/internal/blocks/ChartPanel.js.map +1 -1
  169. package/dist/internal/blocks/ClipboardButton.js +2 -12
  170. package/dist/internal/blocks/ColorInput.js +2 -13
  171. package/dist/internal/blocks/ColorModeSwitch.js +2 -13
  172. package/dist/internal/blocks/Command.js +2 -15
  173. package/dist/internal/blocks/CopyField.js +2 -11
  174. package/dist/internal/blocks/DashboardHero.js +58 -8
  175. package/dist/internal/blocks/DashboardHero.js.map +1 -1
  176. package/dist/internal/blocks/DateInput.js +2 -16
  177. package/dist/internal/blocks/DateRangeInput.js +2 -16
  178. package/dist/internal/blocks/EmptyConfigurationActionCard.js +15 -9
  179. package/dist/internal/blocks/EmptyConfigurationActionCard.js.map +1 -1
  180. package/dist/internal/blocks/EmptyState.js +141 -3
  181. package/dist/internal/blocks/EmptyState.js.map +1 -1
  182. package/dist/internal/blocks/ErrorState.js +178 -4
  183. package/dist/internal/blocks/ErrorState.js.map +1 -1
  184. package/dist/internal/blocks/ExportMenu.js +40 -12
  185. package/dist/internal/blocks/ExportMenu.js.map +1 -1
  186. package/dist/internal/blocks/Form.js +2 -29
  187. package/dist/internal/blocks/FormGroup.js +2 -18
  188. package/dist/internal/blocks/GoogleButton.js +94 -9
  189. package/dist/internal/blocks/GoogleButton.js.map +1 -1
  190. package/dist/internal/blocks/MicrosoftButton.js +63 -9
  191. package/dist/internal/blocks/MicrosoftButton.js.map +1 -1
  192. package/dist/internal/blocks/MultiActionButtonGroup.js +2 -12
  193. package/dist/internal/blocks/MultiCombobox.js +187 -13
  194. package/dist/internal/blocks/MultiCombobox.js.map +1 -1
  195. package/dist/internal/blocks/NumberInput.js +43 -11
  196. package/dist/internal/blocks/NumberInput.js.map +1 -1
  197. package/dist/internal/blocks/OtpInput.js +2 -10
  198. package/dist/internal/blocks/PageHeader.js +2 -9
  199. package/dist/internal/blocks/PageLayout.js +2 -9
  200. package/dist/internal/blocks/PageToolbar.js +2 -13
  201. package/dist/internal/blocks/PasswordInput.js +96 -12
  202. package/dist/internal/blocks/PasswordInput.js.map +1 -1
  203. package/dist/internal/blocks/SearchInput.js +2 -12
  204. package/dist/internal/blocks/SearchInputWithNavigation.js +64 -15
  205. package/dist/internal/blocks/SearchInputWithNavigation.js.map +1 -1
  206. package/dist/internal/blocks/SectionNav.js +2 -15
  207. package/dist/internal/blocks/SplitButton.js +45 -13
  208. package/dist/internal/blocks/SplitButton.js.map +1 -1
  209. package/dist/internal/blocks/StatCard.js +96 -9
  210. package/dist/internal/blocks/StatCard.js.map +1 -1
  211. package/dist/internal/blocks/TextInput.js +2 -13
  212. package/dist/internal/blocks/Textarea.js +31 -12
  213. package/dist/internal/blocks/Textarea.js.map +1 -1
  214. package/dist/internal/blocks/TimeInput.js +76 -16
  215. package/dist/internal/blocks/TimeInput.js.map +1 -1
  216. package/dist/internal/components/Alert.js +2 -11
  217. package/dist/internal/components/AlertModal.js +2 -11
  218. package/dist/internal/components/Avatar.js +52 -8
  219. package/dist/internal/components/Avatar.js.map +1 -1
  220. package/dist/internal/components/Badge.js +2 -9
  221. package/dist/internal/components/BrandLogo.js +2 -11
  222. package/dist/internal/components/Breadcrumb.js +2 -14
  223. package/dist/internal/components/Button.js +2 -10
  224. package/dist/internal/components/ButtonGroup.js +65 -8
  225. package/dist/internal/components/ButtonGroup.js.map +1 -1
  226. package/dist/internal/components/Calendar.js +2 -9
  227. package/dist/internal/components/Card.js +2 -9
  228. package/dist/internal/components/Checkbox.js +2 -11
  229. package/dist/internal/components/Clipboard.js +2 -9
  230. package/dist/internal/components/Collapsible.js +2 -9
  231. package/dist/internal/components/CollapsiblePanel.js +86 -10
  232. package/dist/internal/components/CollapsiblePanel.js.map +1 -1
  233. package/dist/internal/components/Combobox.js +2 -13
  234. package/dist/internal/components/DatePicker.js +2 -11
  235. package/dist/internal/components/DateRangePicker.js +2 -17
  236. package/dist/internal/components/DiffView.js +2 -9
  237. package/dist/internal/components/DotsLoader.js +17 -4
  238. package/dist/internal/components/DotsLoader.js.map +1 -1
  239. package/dist/internal/components/DropdownMenu.js +2 -11
  240. package/dist/internal/components/EmptySearchContent.js +11 -3
  241. package/dist/internal/components/EmptySearchContent.js.map +1 -1
  242. package/dist/internal/components/FileUpload.js +2 -11
  243. package/dist/internal/components/FullScreenModal.js +2 -12
  244. package/dist/internal/components/HelpBlock.js +24 -3
  245. package/dist/internal/components/HelpBlock.js.map +1 -1
  246. package/dist/internal/components/HoverCard.js +2 -9
  247. package/dist/internal/components/InputGroup.js +2 -11
  248. package/dist/internal/components/Kbd.js +2 -9
  249. package/dist/internal/components/Label.js +38 -8
  250. package/dist/internal/components/Label.js.map +1 -1
  251. package/dist/internal/components/Link.js +21 -8
  252. package/dist/internal/components/Link.js.map +1 -1
  253. package/dist/internal/components/MarkedText.js +2 -5
  254. package/dist/internal/components/MergeEditor/ConflictStatus/ConflictStatusIndicator.js +19 -9
  255. package/dist/internal/components/MergeEditor/ConflictStatus/ConflictStatusIndicator.js.map +1 -1
  256. package/dist/internal/components/MergeEditor/PaneHeader.js +12 -3
  257. package/dist/internal/components/MergeEditor/PaneHeader.js.map +1 -1
  258. package/dist/internal/components/MergeEditor/constants.js +17 -3
  259. package/dist/internal/components/MergeEditor/constants.js.map +1 -1
  260. package/dist/internal/components/MergeEditor/useMergeDiff.js +2 -5
  261. package/dist/internal/components/Modal.js +2 -13
  262. package/dist/internal/components/Navbar.js +2 -14
  263. package/dist/internal/components/Pagination.js +2 -11
  264. package/dist/internal/components/PanelWithDetails.js +30 -10
  265. package/dist/internal/components/PanelWithDetails.js.map +1 -1
  266. package/dist/internal/components/Popconfirm.js +2 -12
  267. package/dist/internal/components/Popover.js +2 -9
  268. package/dist/internal/components/Progress.js +46 -8
  269. package/dist/internal/components/Progress.js.map +1 -1
  270. package/dist/internal/components/RadioGroup.js +2 -12
  271. package/dist/internal/components/Resizable.js +2 -9
  272. package/dist/internal/components/ScrollArea.js +41 -8
  273. package/dist/internal/components/ScrollArea.js.map +1 -1
  274. package/dist/internal/components/Search.js +2 -10
  275. package/dist/internal/components/Select.js +2 -12
  276. package/dist/internal/components/Separator.js +83 -8
  277. package/dist/internal/components/Separator.js.map +1 -1
  278. package/dist/internal/components/Sheet.js +2 -12
  279. package/dist/internal/components/Sidebar.js +2 -20
  280. package/dist/internal/components/Skeleton/Skeleton.js +38 -8
  281. package/dist/internal/components/Skeleton/Skeleton.js.map +1 -1
  282. package/dist/internal/components/Skeleton/SkeletonList.js +40 -9
  283. package/dist/internal/components/Skeleton/SkeletonList.js.map +1 -1
  284. package/dist/internal/components/Slider.js +2 -11
  285. package/dist/internal/components/SpotlightBackdrop.js +131 -8
  286. package/dist/internal/components/SpotlightBackdrop.js.map +1 -1
  287. package/dist/internal/components/Stepper.js +2 -10
  288. package/dist/internal/components/Switch.js +2 -10
  289. package/dist/internal/components/Table.js +2 -10
  290. package/dist/internal/components/Tabs.js +2 -12
  291. package/dist/internal/components/ThemeProvider.js +3 -10
  292. package/dist/internal/components/TimePicker.js +2 -12
  293. package/dist/internal/components/Timeline.js +2 -10
  294. package/dist/internal/components/Toast.js +3 -11
  295. package/dist/internal/components/Toggle.js +168 -8
  296. package/dist/internal/components/Toggle.js.map +1 -1
  297. package/dist/internal/components/ToggleGroup.js +2 -9
  298. package/dist/internal/components/Tooltip.js +2 -8
  299. package/dist/internal/components/Truncated.js +44 -8
  300. package/dist/internal/components/Truncated.js.map +1 -1
  301. package/dist/internal/components/Workbench.js +2 -11
  302. package/dist/internal/components/ZoomableSvg.js +2 -13
  303. package/dist/internal/hooks/useAutosizeInput.js +76 -3
  304. package/dist/internal/hooks/useAutosizeInput.js.map +1 -1
  305. package/dist/internal/hooks/useScrollbarPosition.js +44 -4
  306. package/dist/internal/hooks/useScrollbarPosition.js.map +1 -1
  307. package/dist/internal/hooks/useStableCallback.js +28 -3
  308. package/dist/internal/hooks/useStableCallback.js.map +1 -1
  309. package/dist/internal/utils/mergeRefs.js +19 -3
  310. package/dist/internal/utils/mergeRefs.js.map +1 -1
  311. package/dist/internal/utils.js +5 -8
  312. package/dist/markdown-editor.d.ts +72 -72
  313. package/dist/markdown-editor.js +1122 -1207
  314. package/dist/markdown-editor.js.map +1 -1
  315. package/dist/mermaid.d.ts +12 -12
  316. package/dist/mermaid.js +2 -18
  317. package/dist/rjsf.d.ts +33 -34
  318. package/dist/rjsf.js +1541 -1671
  319. package/dist/rjsf.js.map +1 -1
  320. package/dist/rolldown-runtime-Bdc48AWt.js +33 -0
  321. package/dist/styles-DSUP_-9Z.js +158 -0
  322. package/dist/styles-DSUP_-9Z.js.map +1 -0
  323. package/dist/testing.d.ts +8 -7
  324. package/dist/testing.js +36 -21
  325. package/dist/testing.js.map +1 -1
  326. package/dist/themeTokens-BNg98Mu9.js +85 -0
  327. package/dist/themeTokens-BNg98Mu9.js.map +1 -0
  328. package/dist/toast-CjkURw0M.js +184 -0
  329. package/dist/toast-CjkURw0M.js.map +1 -0
  330. package/dist/useColorSchemeState-CYqcUfSH.js +61 -0
  331. package/dist/useColorSchemeState-CYqcUfSH.js.map +1 -0
  332. package/dist/useControllableState-M6494mCT.js +31 -0
  333. package/dist/useControllableState-M6494mCT.js.map +1 -0
  334. package/dist/useElement-DkF6esWL.js +15 -0
  335. package/dist/useElement-DkF6esWL.js.map +1 -0
  336. package/dist/useMergeDiff-CvowEXJ1.js +465 -0
  337. package/dist/useMergeDiff-CvowEXJ1.js.map +1 -0
  338. package/dist/utils-D0c5VAyF.js +308 -0
  339. package/dist/utils-D0c5VAyF.js.map +1 -0
  340. package/package.json +8 -8
  341. package/dist/MermaidDiagram-ZU5KAVRT.js +0 -18
  342. package/dist/MermaidDiagram-ZU5KAVRT.js.map +0 -1
  343. package/dist/chunk-2YYJDKSP.js +0 -51
  344. package/dist/chunk-2YYJDKSP.js.map +0 -1
  345. package/dist/chunk-3P5UUCFI.js +0 -385
  346. package/dist/chunk-3P5UUCFI.js.map +0 -1
  347. package/dist/chunk-3QDFDDWZ.js +0 -99
  348. package/dist/chunk-3QDFDDWZ.js.map +0 -1
  349. package/dist/chunk-3W27OLK5.js +0 -15
  350. package/dist/chunk-3W27OLK5.js.map +0 -1
  351. package/dist/chunk-4FIZZONW.js +0 -40
  352. package/dist/chunk-4FIZZONW.js.map +0 -1
  353. package/dist/chunk-4GIAXOJG.js +0 -133
  354. package/dist/chunk-4GIAXOJG.js.map +0 -1
  355. package/dist/chunk-52NDNMK7.js +0 -99
  356. package/dist/chunk-52NDNMK7.js.map +0 -1
  357. package/dist/chunk-576G5OES.js +0 -201
  358. package/dist/chunk-576G5OES.js.map +0 -1
  359. package/dist/chunk-5AIE6SET.js +0 -659
  360. package/dist/chunk-5AIE6SET.js.map +0 -1
  361. package/dist/chunk-5FTNAZRW.js +0 -327
  362. package/dist/chunk-5FTNAZRW.js.map +0 -1
  363. package/dist/chunk-5IG2S7ZY.js +0 -70
  364. package/dist/chunk-5IG2S7ZY.js.map +0 -1
  365. package/dist/chunk-5QCXHNCW.js +0 -404
  366. package/dist/chunk-5QCXHNCW.js.map +0 -1
  367. package/dist/chunk-6DUMGC7Y.js +0 -105
  368. package/dist/chunk-6DUMGC7Y.js.map +0 -1
  369. package/dist/chunk-6J25CVST.js +0 -174
  370. package/dist/chunk-6J25CVST.js.map +0 -1
  371. package/dist/chunk-6NN35XOP.js +0 -120
  372. package/dist/chunk-6NN35XOP.js.map +0 -1
  373. package/dist/chunk-6NZBVA4T.js +0 -24
  374. package/dist/chunk-6NZBVA4T.js.map +0 -1
  375. package/dist/chunk-6W5BHRCL.js +0 -295
  376. package/dist/chunk-6W5BHRCL.js.map +0 -1
  377. package/dist/chunk-72BKRCEG.js +0 -409
  378. package/dist/chunk-72BKRCEG.js.map +0 -1
  379. package/dist/chunk-7GTI3PPI.js +0 -95
  380. package/dist/chunk-7GTI3PPI.js.map +0 -1
  381. package/dist/chunk-7P6PLZ4B.js +0 -74
  382. package/dist/chunk-7P6PLZ4B.js.map +0 -1
  383. package/dist/chunk-7WZWY5IA.js +0 -46
  384. package/dist/chunk-7WZWY5IA.js.map +0 -1
  385. package/dist/chunk-AIYO2632.js +0 -489
  386. package/dist/chunk-AIYO2632.js.map +0 -1
  387. package/dist/chunk-ANFZWPNE.js +0 -112
  388. package/dist/chunk-ANFZWPNE.js.map +0 -1
  389. package/dist/chunk-ANZTVAJU.js +0 -73
  390. package/dist/chunk-ANZTVAJU.js.map +0 -1
  391. package/dist/chunk-BD5BTJKX.js +0 -166
  392. package/dist/chunk-BD5BTJKX.js.map +0 -1
  393. package/dist/chunk-BHGIDSRJ.js +0 -140
  394. package/dist/chunk-BHGIDSRJ.js.map +0 -1
  395. package/dist/chunk-BSQWZITZ.js +0 -507
  396. package/dist/chunk-BSQWZITZ.js.map +0 -1
  397. package/dist/chunk-D3LAIK62.js +0 -23
  398. package/dist/chunk-D3LAIK62.js.map +0 -1
  399. package/dist/chunk-DODCR43C.js +0 -155
  400. package/dist/chunk-DODCR43C.js.map +0 -1
  401. package/dist/chunk-EEK5NGZF.js +0 -40
  402. package/dist/chunk-EEK5NGZF.js.map +0 -1
  403. package/dist/chunk-ENRG7TXA.js +0 -11
  404. package/dist/chunk-ENRG7TXA.js.map +0 -1
  405. package/dist/chunk-EQRMGIGY.js +0 -239
  406. package/dist/chunk-EQRMGIGY.js.map +0 -1
  407. package/dist/chunk-ERAHK5YQ.js +0 -495
  408. package/dist/chunk-ERAHK5YQ.js.map +0 -1
  409. package/dist/chunk-F3FOFY2P.js +0 -124
  410. package/dist/chunk-F3FOFY2P.js.map +0 -1
  411. package/dist/chunk-F6BTWFOC.js +0 -507
  412. package/dist/chunk-F6BTWFOC.js.map +0 -1
  413. package/dist/chunk-F6J6NNAL.js +0 -34
  414. package/dist/chunk-F6J6NNAL.js.map +0 -1
  415. package/dist/chunk-FCHJ7D5O.js +0 -59
  416. package/dist/chunk-FCHJ7D5O.js.map +0 -1
  417. package/dist/chunk-FFJTEQCC.js +0 -80
  418. package/dist/chunk-FFJTEQCC.js.map +0 -1
  419. package/dist/chunk-FUFMVW7O.js +0 -64
  420. package/dist/chunk-FUFMVW7O.js.map +0 -1
  421. package/dist/chunk-FVPGQ6UE.js +0 -25
  422. package/dist/chunk-FVPGQ6UE.js.map +0 -1
  423. package/dist/chunk-G3PMV62Z.js +0 -33
  424. package/dist/chunk-G3PMV62Z.js.map +0 -1
  425. package/dist/chunk-GACFOW3E.js +0 -51
  426. package/dist/chunk-GACFOW3E.js.map +0 -1
  427. package/dist/chunk-GDT6HQMK.js +0 -42
  428. package/dist/chunk-GDT6HQMK.js.map +0 -1
  429. package/dist/chunk-HLGU22C6.js +0 -2589
  430. package/dist/chunk-HLGU22C6.js.map +0 -1
  431. package/dist/chunk-HPMYYGP7.js +0 -134
  432. package/dist/chunk-HPMYYGP7.js.map +0 -1
  433. package/dist/chunk-I2UCOD45.js +0 -197
  434. package/dist/chunk-I2UCOD45.js.map +0 -1
  435. package/dist/chunk-IEGDZUVM.js +0 -75
  436. package/dist/chunk-IEGDZUVM.js.map +0 -1
  437. package/dist/chunk-IIS7INHF.js +0 -47
  438. package/dist/chunk-IIS7INHF.js.map +0 -1
  439. package/dist/chunk-ITELSEFU.js +0 -256
  440. package/dist/chunk-ITELSEFU.js.map +0 -1
  441. package/dist/chunk-IXAYNBOY.js +0 -407
  442. package/dist/chunk-IXAYNBOY.js.map +0 -1
  443. package/dist/chunk-JUW2ETEI.js +0 -191
  444. package/dist/chunk-JUW2ETEI.js.map +0 -1
  445. package/dist/chunk-K65C7CVE.js +0 -127
  446. package/dist/chunk-K65C7CVE.js.map +0 -1
  447. package/dist/chunk-KDI64MCY.js +0 -189
  448. package/dist/chunk-KDI64MCY.js.map +0 -1
  449. package/dist/chunk-KN4ASMH5.js +0 -160
  450. package/dist/chunk-KN4ASMH5.js.map +0 -1
  451. package/dist/chunk-KQW7QNTU.js +0 -1549
  452. package/dist/chunk-KQW7QNTU.js.map +0 -1
  453. package/dist/chunk-KR7NXXHC.js +0 -66
  454. package/dist/chunk-KR7NXXHC.js.map +0 -1
  455. package/dist/chunk-KRZKIVMA.js +0 -142
  456. package/dist/chunk-KRZKIVMA.js.map +0 -1
  457. package/dist/chunk-KTTLLKGQ.js +0 -185
  458. package/dist/chunk-KTTLLKGQ.js.map +0 -1
  459. package/dist/chunk-KWKSHPDP.js +0 -234
  460. package/dist/chunk-KWKSHPDP.js.map +0 -1
  461. package/dist/chunk-KZVC7OYG.js +0 -57
  462. package/dist/chunk-KZVC7OYG.js.map +0 -1
  463. package/dist/chunk-L5DHUN2V.js +0 -204
  464. package/dist/chunk-L5DHUN2V.js.map +0 -1
  465. package/dist/chunk-LCTGEH57.js +0 -1376
  466. package/dist/chunk-LCTGEH57.js.map +0 -1
  467. package/dist/chunk-LXLIQ2D6.js +0 -12
  468. package/dist/chunk-LXLIQ2D6.js.map +0 -1
  469. package/dist/chunk-M4CTURKX.js +0 -84
  470. package/dist/chunk-M4CTURKX.js.map +0 -1
  471. package/dist/chunk-M6LTUPVP.js +0 -301
  472. package/dist/chunk-M6LTUPVP.js.map +0 -1
  473. package/dist/chunk-MA6RRHDT.js +0 -291
  474. package/dist/chunk-MA6RRHDT.js.map +0 -1
  475. package/dist/chunk-MODE4QIA.js +0 -6
  476. package/dist/chunk-MODE4QIA.js.map +0 -1
  477. package/dist/chunk-MVILMVGG.js +0 -118
  478. package/dist/chunk-MVILMVGG.js.map +0 -1
  479. package/dist/chunk-MWS4VCLV.js +0 -17
  480. package/dist/chunk-MWS4VCLV.js.map +0 -1
  481. package/dist/chunk-NEUX74SO.js +0 -315
  482. package/dist/chunk-NEUX74SO.js.map +0 -1
  483. package/dist/chunk-NFHKYBRD.js +0 -156
  484. package/dist/chunk-NFHKYBRD.js.map +0 -1
  485. package/dist/chunk-NHJNNXD3.js +0 -89
  486. package/dist/chunk-NHJNNXD3.js.map +0 -1
  487. package/dist/chunk-O2BF3HZL.js +0 -33
  488. package/dist/chunk-O2BF3HZL.js.map +0 -1
  489. package/dist/chunk-OANXCZYD.js +0 -212
  490. package/dist/chunk-OANXCZYD.js.map +0 -1
  491. package/dist/chunk-ODJF7YIP.js +0 -230
  492. package/dist/chunk-ODJF7YIP.js.map +0 -1
  493. package/dist/chunk-ON4BJTHI.js +0 -101
  494. package/dist/chunk-ON4BJTHI.js.map +0 -1
  495. package/dist/chunk-OTL5WXIJ.js +0 -16
  496. package/dist/chunk-OTL5WXIJ.js.map +0 -1
  497. package/dist/chunk-PACNBKJV.js +0 -47
  498. package/dist/chunk-PACNBKJV.js.map +0 -1
  499. package/dist/chunk-PROCA7K7.js +0 -23
  500. package/dist/chunk-PROCA7K7.js.map +0 -1
  501. package/dist/chunk-QGMIPA67.js +0 -85
  502. package/dist/chunk-QGMIPA67.js.map +0 -1
  503. package/dist/chunk-QQA37LFB.js +0 -190
  504. package/dist/chunk-QQA37LFB.js.map +0 -1
  505. package/dist/chunk-QZAWRSEB.js +0 -61
  506. package/dist/chunk-QZAWRSEB.js.map +0 -1
  507. package/dist/chunk-R74KGWNS.js +0 -699
  508. package/dist/chunk-R74KGWNS.js.map +0 -1
  509. package/dist/chunk-RFDLHMKL.js +0 -110
  510. package/dist/chunk-RFDLHMKL.js.map +0 -1
  511. package/dist/chunk-RL64HN7S.js +0 -40
  512. package/dist/chunk-RL64HN7S.js.map +0 -1
  513. package/dist/chunk-RMRQKPL7.js +0 -115
  514. package/dist/chunk-RMRQKPL7.js.map +0 -1
  515. package/dist/chunk-RQVK4IYC.js +0 -606
  516. package/dist/chunk-RQVK4IYC.js.map +0 -1
  517. package/dist/chunk-RTW56PWZ.js +0 -59
  518. package/dist/chunk-RTW56PWZ.js.map +0 -1
  519. package/dist/chunk-RUTPQNLR.js +0 -266
  520. package/dist/chunk-RUTPQNLR.js.map +0 -1
  521. package/dist/chunk-S6TAF63G.js +0 -25
  522. package/dist/chunk-S6TAF63G.js.map +0 -1
  523. package/dist/chunk-SBGAUGXY.js +0 -224
  524. package/dist/chunk-SBGAUGXY.js.map +0 -1
  525. package/dist/chunk-SC275NHZ.js +0 -407
  526. package/dist/chunk-SC275NHZ.js.map +0 -1
  527. package/dist/chunk-SCQPU4UE.js +0 -97
  528. package/dist/chunk-SCQPU4UE.js.map +0 -1
  529. package/dist/chunk-SFFF2WQP.js +0 -8
  530. package/dist/chunk-SFFF2WQP.js.map +0 -1
  531. package/dist/chunk-SJYMHZKA.js +0 -36
  532. package/dist/chunk-SJYMHZKA.js.map +0 -1
  533. package/dist/chunk-SLCCUJVN.js +0 -125
  534. package/dist/chunk-SLCCUJVN.js.map +0 -1
  535. package/dist/chunk-SVBSNSD4.js +0 -259
  536. package/dist/chunk-SVBSNSD4.js.map +0 -1
  537. package/dist/chunk-SVPLTL35.js +0 -62
  538. package/dist/chunk-SVPLTL35.js.map +0 -1
  539. package/dist/chunk-SWQFYNYG.js +0 -338
  540. package/dist/chunk-SWQFYNYG.js.map +0 -1
  541. package/dist/chunk-THHB4EWS.js +0 -72
  542. package/dist/chunk-THHB4EWS.js.map +0 -1
  543. package/dist/chunk-TUCDD33E.js +0 -246
  544. package/dist/chunk-TUCDD33E.js.map +0 -1
  545. package/dist/chunk-TV4WAP2R.js +0 -14
  546. package/dist/chunk-TV4WAP2R.js.map +0 -1
  547. package/dist/chunk-U3A6YBTZ.js +0 -134
  548. package/dist/chunk-U3A6YBTZ.js.map +0 -1
  549. package/dist/chunk-UGT6DKWM.js +0 -95
  550. package/dist/chunk-VSERHUWD.js +0 -212
  551. package/dist/chunk-VSERHUWD.js.map +0 -1
  552. package/dist/chunk-VYG7BDXC.js +0 -49
  553. package/dist/chunk-VYG7BDXC.js.map +0 -1
  554. package/dist/chunk-WETKNYZX.js +0 -52
  555. package/dist/chunk-WETKNYZX.js.map +0 -1
  556. package/dist/chunk-WGG4AML3.js +0 -216
  557. package/dist/chunk-WGG4AML3.js.map +0 -1
  558. package/dist/chunk-WKAUEL6I.js +0 -30
  559. package/dist/chunk-WKAUEL6I.js.map +0 -1
  560. package/dist/chunk-WPOLA5CG.js +0 -81
  561. package/dist/chunk-WPOLA5CG.js.map +0 -1
  562. package/dist/chunk-WPVETCGJ.js +0 -254
  563. package/dist/chunk-WPVETCGJ.js.map +0 -1
  564. package/dist/chunk-WTSM3A7E.js +0 -13
  565. package/dist/chunk-WTSM3A7E.js.map +0 -1
  566. package/dist/chunk-WU3F2K3T.js +0 -148
  567. package/dist/chunk-WU3F2K3T.js.map +0 -1
  568. package/dist/chunk-WZZK2DTZ.js +0 -39
  569. package/dist/chunk-WZZK2DTZ.js.map +0 -1
  570. package/dist/chunk-X4IHLKRD.js +0 -42
  571. package/dist/chunk-X4IHLKRD.js.map +0 -1
  572. package/dist/chunk-XAHEXZJC.js +0 -80
  573. package/dist/chunk-XAHEXZJC.js.map +0 -1
  574. package/dist/chunk-XCYGJDUX.js +0 -31
  575. package/dist/chunk-XCYGJDUX.js.map +0 -1
  576. package/dist/chunk-Y4W3JORC.js +0 -104
  577. package/dist/chunk-Y4W3JORC.js.map +0 -1
  578. package/dist/chunk-YFZJ3ZLG.js +0 -1297
  579. package/dist/chunk-YFZJ3ZLG.js.map +0 -1
  580. package/dist/chunk-YI3WLXEN.js +0 -4387
  581. package/dist/chunk-YI3WLXEN.js.map +0 -1
  582. package/dist/chunk-ZBKFSPD3.js +0 -29
  583. package/dist/chunk-ZBKFSPD3.js.map +0 -1
  584. package/dist/chunk-ZOERRQ6A.js +0 -79
  585. package/dist/chunk-ZOERRQ6A.js.map +0 -1
  586. package/dist/chunk-ZSTGUKHU.js +0 -10
  587. package/dist/chunk-ZSTGUKHU.js.map +0 -1
  588. package/dist/chunk-ZUEHDL27.js +0 -65
  589. package/dist/chunk-ZUEHDL27.js.map +0 -1
  590. package/dist/constants-D3gaMY-W.d.ts +0 -39
  591. package/dist/icons.js.map +0 -1
  592. package/dist/index.js.map +0 -1
  593. package/dist/internal/blocks/AIKit.js.map +0 -1
  594. package/dist/internal/blocks/AppShell.js.map +0 -1
  595. package/dist/internal/blocks/AutoSaveTextarea.js.map +0 -1
  596. package/dist/internal/blocks/BrandEditor.js.map +0 -1
  597. package/dist/internal/blocks/ClipboardButton.js.map +0 -1
  598. package/dist/internal/blocks/ColorInput.js.map +0 -1
  599. package/dist/internal/blocks/ColorModeSwitch.js.map +0 -1
  600. package/dist/internal/blocks/Command.js.map +0 -1
  601. package/dist/internal/blocks/CopyField.js.map +0 -1
  602. package/dist/internal/blocks/DateInput.js.map +0 -1
  603. package/dist/internal/blocks/DateRangeInput.js.map +0 -1
  604. package/dist/internal/blocks/Form.js.map +0 -1
  605. package/dist/internal/blocks/FormGroup.js.map +0 -1
  606. package/dist/internal/blocks/MultiActionButtonGroup.js.map +0 -1
  607. package/dist/internal/blocks/OtpInput.js.map +0 -1
  608. package/dist/internal/blocks/PageHeader.js.map +0 -1
  609. package/dist/internal/blocks/PageLayout.js.map +0 -1
  610. package/dist/internal/blocks/PageToolbar.js.map +0 -1
  611. package/dist/internal/blocks/SearchInput.js.map +0 -1
  612. package/dist/internal/blocks/SectionNav.js.map +0 -1
  613. package/dist/internal/blocks/TextInput.js.map +0 -1
  614. package/dist/internal/components/Alert.js.map +0 -1
  615. package/dist/internal/components/AlertModal.js.map +0 -1
  616. package/dist/internal/components/Badge.js.map +0 -1
  617. package/dist/internal/components/BrandLogo.js.map +0 -1
  618. package/dist/internal/components/Breadcrumb.js.map +0 -1
  619. package/dist/internal/components/Button.js.map +0 -1
  620. package/dist/internal/components/Calendar.js.map +0 -1
  621. package/dist/internal/components/Card.js.map +0 -1
  622. package/dist/internal/components/Checkbox.js.map +0 -1
  623. package/dist/internal/components/Clipboard.js.map +0 -1
  624. package/dist/internal/components/Collapsible.js.map +0 -1
  625. package/dist/internal/components/Combobox.js.map +0 -1
  626. package/dist/internal/components/DatePicker.js.map +0 -1
  627. package/dist/internal/components/DateRangePicker.js.map +0 -1
  628. package/dist/internal/components/DiffView.js.map +0 -1
  629. package/dist/internal/components/DropdownMenu.js.map +0 -1
  630. package/dist/internal/components/FileUpload.js.map +0 -1
  631. package/dist/internal/components/FullScreenModal.js.map +0 -1
  632. package/dist/internal/components/HoverCard.js.map +0 -1
  633. package/dist/internal/components/InputGroup.js.map +0 -1
  634. package/dist/internal/components/Kbd.js.map +0 -1
  635. package/dist/internal/components/MarkedText.js.map +0 -1
  636. package/dist/internal/components/MergeEditor/useMergeDiff.js.map +0 -1
  637. package/dist/internal/components/Modal.js.map +0 -1
  638. package/dist/internal/components/Navbar.js.map +0 -1
  639. package/dist/internal/components/Pagination.js.map +0 -1
  640. package/dist/internal/components/Popconfirm.js.map +0 -1
  641. package/dist/internal/components/Popover.js.map +0 -1
  642. package/dist/internal/components/RadioGroup.js.map +0 -1
  643. package/dist/internal/components/Resizable.js.map +0 -1
  644. package/dist/internal/components/Search.js.map +0 -1
  645. package/dist/internal/components/Select.js.map +0 -1
  646. package/dist/internal/components/Sheet.js.map +0 -1
  647. package/dist/internal/components/Sidebar.js.map +0 -1
  648. package/dist/internal/components/Slider.js.map +0 -1
  649. package/dist/internal/components/Stepper.js.map +0 -1
  650. package/dist/internal/components/Switch.js.map +0 -1
  651. package/dist/internal/components/Table.js.map +0 -1
  652. package/dist/internal/components/Tabs.js.map +0 -1
  653. package/dist/internal/components/ThemeProvider.js.map +0 -1
  654. package/dist/internal/components/TimePicker.js.map +0 -1
  655. package/dist/internal/components/Timeline.js.map +0 -1
  656. package/dist/internal/components/Toast.js.map +0 -1
  657. package/dist/internal/components/ToggleGroup.js.map +0 -1
  658. package/dist/internal/components/Tooltip.js.map +0 -1
  659. package/dist/internal/components/Workbench.js.map +0 -1
  660. package/dist/internal/components/ZoomableSvg.js.map +0 -1
  661. package/dist/internal/utils.js.map +0 -1
  662. package/dist/mermaid.js.map +0 -1
@@ -1,1237 +1,1152 @@
1
- import { toast } from './chunk-6W5BHRCL.js';
2
- import { DropdownMenu } from './chunk-ERAHK5YQ.js';
3
- import { ButtonGroup } from './chunk-ANZTVAJU.js';
4
- import { Skeleton } from './chunk-PACNBKJV.js';
5
- import { FormGroup } from './chunk-RTW56PWZ.js';
6
- import './chunk-QZAWRSEB.js';
7
- import './chunk-EEK5NGZF.js';
8
- import './chunk-VSERHUWD.js';
9
- import { TextInput } from './chunk-HPMYYGP7.js';
10
- import './chunk-WKAUEL6I.js';
11
- import './chunk-SC275NHZ.js';
12
- import { Label } from './chunk-S6TAF63G.js';
13
- import './chunk-THHB4EWS.js';
14
- import './chunk-PROCA7K7.js';
15
- import { Button } from './chunk-IXAYNBOY.js';
16
- import { AlignLeft, AlignCenter, AlignRight, AlignJustify, SquareCode, Quote, ListOrdered, List, Heading3, Heading2, Heading1, Type, Bold, Italic, Underline, Strikethrough, Code, ChevronDown, Link } from './chunk-RQVK4IYC.js';
17
- import { Tooltip } from './chunk-SWQFYNYG.js';
18
- import './chunk-3W27OLK5.js';
19
- import './chunk-MODE4QIA.js';
20
- import './chunk-WETKNYZX.js';
21
- import { cn } from './chunk-LXLIQ2D6.js';
22
- import './chunk-G3PMV62Z.js';
23
- import { createContext, lazy, Suspense, use, useState, useRef, useCallback, useEffect } from 'react';
24
- import { CodeNode, $isCodeNode, $createCodeNode } from '@lexical/code';
25
- import { LinkNode, $isLinkNode, TOGGLE_LINK_COMMAND, $createLinkNode } from '@lexical/link';
26
- import { ListNode, ListItemNode, $isListNode, REMOVE_LIST_COMMAND, INSERT_UNORDERED_LIST_COMMAND, INSERT_ORDERED_LIST_COMMAND } from '@lexical/list';
27
- import { CHECK_LIST, TRANSFORMERS, $convertFromMarkdownString, $convertToMarkdownString } from '@lexical/markdown';
28
- import { AutoFocusPlugin } from '@lexical/react/LexicalAutoFocusPlugin';
29
- import { CheckListPlugin } from '@lexical/react/LexicalCheckListPlugin';
30
- import { ClickableLinkPlugin } from '@lexical/react/LexicalClickableLinkPlugin';
31
- import { LexicalComposer } from '@lexical/react/LexicalComposer';
32
- import { ContentEditable } from '@lexical/react/LexicalContentEditable';
33
- import { LexicalErrorBoundary } from '@lexical/react/LexicalErrorBoundary';
34
- import { HistoryPlugin } from '@lexical/react/LexicalHistoryPlugin';
35
- import { HorizontalRuleNode, $createHorizontalRuleNode, $isHorizontalRuleNode } from '@lexical/react/LexicalHorizontalRuleNode';
36
- import { HorizontalRulePlugin } from '@lexical/react/LexicalHorizontalRulePlugin';
37
- import { LinkPlugin } from '@lexical/react/LexicalLinkPlugin';
38
- import { ListPlugin } from '@lexical/react/LexicalListPlugin';
39
- import { MarkdownShortcutPlugin } from '@lexical/react/LexicalMarkdownShortcutPlugin';
40
- import { RichTextPlugin } from '@lexical/react/LexicalRichTextPlugin';
41
- import { TabIndentationPlugin } from '@lexical/react/LexicalTabIndentationPlugin';
42
- import { HeadingNode, QuoteNode, $isHeadingNode, $isQuoteNode, $createQuoteNode, $createHeadingNode } from '@lexical/rich-text';
43
- import { DecoratorNode, $getSelection, $isRangeSelection, FORMAT_TEXT_COMMAND, $createParagraphNode, PASTE_COMMAND, COMMAND_PRIORITY_CRITICAL, DROP_COMMAND, KEY_DOWN_COMMAND, COMMAND_PRIORITY_HIGH, $insertNodes, $getNodeByKey, $setSelection, FORMAT_ELEMENT_COMMAND, $createTextNode } from 'lexical';
44
- import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
45
- import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
46
- import { createPortal } from 'react-dom';
47
- import { $getNearestBlockElementAncestorOrThrow } from '@lexical/utils';
48
-
49
- var ImageRendererContext = createContext(null);
50
- var ImageRendererProvider = ImageRendererContext;
51
- var useImageRenderer = () => use(ImageRendererContext);
52
- var isPlaceholder = (src) => src.startsWith("upload-placeholder-");
53
- var ImageNodeComponent = ({ src, alt }) => {
54
- const renderer = useImageRenderer();
55
- if (isPlaceholder(src)) {
56
- return /* @__PURE__ */ jsx("span", { className: "tw:inline-flex tw:items-center tw:gap-1 tw:rounded tw:bg-neutral-100 tw:px-2 tw:py-1 tw:text-xs tw:text-neutral-400", children: "Uploading image\u2026" });
57
- }
58
- if (renderer) return /* @__PURE__ */ jsx(Fragment, { children: renderer({ src, alt }) });
59
- return /* @__PURE__ */ jsx("img", { src, alt });
1
+ import { cn } from "./classNames-BzrkDnOD.js";
2
+ import { Tooltip } from "./utils-D0c5VAyF.js";
3
+ import { AlignCenter, AlignJustify, AlignLeft, AlignRight, Bold, ChevronDown, Code, Heading1, Heading2, Heading3, Italic, Link, List, ListOrdered, Quote, SquareCode, Strikethrough, Type, Underline } from "./icons-Cek151jC.js";
4
+ import { Button } from "./Button-nzmDNS2q.js";
5
+ import { ButtonGroup } from "./internal/components/ButtonGroup.js";
6
+ import { DropdownMenu } from "./DropdownMenu-B6ZbYvaM.js";
7
+ import { Label } from "./internal/components/Label.js";
8
+ import { TextInput } from "./TextInput-BGed-V13.js";
9
+ import { FormGroup } from "./FormGroup-S9mPNHKH.js";
10
+ import { Skeleton } from "./internal/components/Skeleton/Skeleton.js";
11
+ import { toast } from "./toast-CjkURw0M.js";
12
+ import { Suspense, createContext, lazy, use, useCallback, useEffect, useRef, useState } from "react";
13
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
14
+ import { createPortal } from "react-dom";
15
+ import { $createCodeNode, $isCodeNode, CodeNode } from "@lexical/code";
16
+ import { $createLinkNode, $isLinkNode, LinkNode, TOGGLE_LINK_COMMAND } from "@lexical/link";
17
+ import { $isListNode, INSERT_ORDERED_LIST_COMMAND, INSERT_UNORDERED_LIST_COMMAND, ListItemNode, ListNode, REMOVE_LIST_COMMAND } from "@lexical/list";
18
+ import { $convertFromMarkdownString, $convertToMarkdownString, CHECK_LIST, TRANSFORMERS } from "@lexical/markdown";
19
+ import { AutoFocusPlugin } from "@lexical/react/LexicalAutoFocusPlugin";
20
+ import { CheckListPlugin } from "@lexical/react/LexicalCheckListPlugin";
21
+ import { ClickableLinkPlugin } from "@lexical/react/LexicalClickableLinkPlugin";
22
+ import { LexicalComposer } from "@lexical/react/LexicalComposer";
23
+ import { ContentEditable } from "@lexical/react/LexicalContentEditable";
24
+ import { LexicalErrorBoundary } from "@lexical/react/LexicalErrorBoundary";
25
+ import { HistoryPlugin } from "@lexical/react/LexicalHistoryPlugin";
26
+ import { $createHorizontalRuleNode, $isHorizontalRuleNode, HorizontalRuleNode } from "@lexical/react/LexicalHorizontalRuleNode";
27
+ import { HorizontalRulePlugin } from "@lexical/react/LexicalHorizontalRulePlugin";
28
+ import { LinkPlugin } from "@lexical/react/LexicalLinkPlugin";
29
+ import { ListPlugin } from "@lexical/react/LexicalListPlugin";
30
+ import { MarkdownShortcutPlugin } from "@lexical/react/LexicalMarkdownShortcutPlugin";
31
+ import { RichTextPlugin } from "@lexical/react/LexicalRichTextPlugin";
32
+ import { TabIndentationPlugin } from "@lexical/react/LexicalTabIndentationPlugin";
33
+ import { $createHeadingNode, $createQuoteNode, $isHeadingNode, $isQuoteNode, HeadingNode, QuoteNode } from "@lexical/rich-text";
34
+ import { $createParagraphNode, $createTextNode, $getNodeByKey, $getSelection, $insertNodes, $isRangeSelection, $setSelection, COMMAND_PRIORITY_CRITICAL, COMMAND_PRIORITY_HIGH, DROP_COMMAND, DecoratorNode, FORMAT_ELEMENT_COMMAND, FORMAT_TEXT_COMMAND, KEY_DOWN_COMMAND, PASTE_COMMAND } from "lexical";
35
+ import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
36
+ import { $getNearestBlockElementAncestorOrThrow } from "@lexical/utils";
37
+ //#region src/blocks/MarkdownEditor/context.ts
38
+ const ImageRendererContext = createContext(null);
39
+ const ImageRendererProvider = ImageRendererContext;
40
+ const useImageRenderer = () => use(ImageRendererContext);
41
+ //#endregion
42
+ //#region src/blocks/MarkdownEditor/nodes/ImageNodeComponent.tsx
43
+ const isPlaceholder = (src) => src.startsWith("upload-placeholder-");
44
+ const ImageNodeComponent = ({ src, alt }) => {
45
+ const renderer = useImageRenderer();
46
+ if (isPlaceholder(src)) return /* @__PURE__ */ jsx("span", {
47
+ className: "tw:inline-flex tw:items-center tw:gap-1 tw:rounded tw:bg-neutral-100 tw:px-2 tw:py-1 tw:text-xs tw:text-neutral-400",
48
+ children: "Uploading image…"
49
+ });
50
+ if (renderer) return /* @__PURE__ */ jsx(Fragment$1, { children: renderer({
51
+ src,
52
+ alt
53
+ }) });
54
+ return /* @__PURE__ */ jsx("img", {
55
+ src,
56
+ alt
57
+ });
60
58
  };
61
- var ImageNode = class _ImageNode extends DecoratorNode {
62
- __src;
63
- __altText;
64
- static getType() {
65
- return "image";
66
- }
67
- static clone(node) {
68
- return new _ImageNode(node.__src, node.__altText, node.__key);
69
- }
70
- constructor(src, altText, key) {
71
- super(key);
72
- this.__src = src;
73
- this.__altText = altText;
74
- }
75
- getSrc() {
76
- return this.__src;
77
- }
78
- getAlt() {
79
- return this.__altText;
80
- }
81
- setSrc(src) {
82
- const writable = this.getWritable();
83
- writable.__src = src;
84
- }
85
- setAlt(altText) {
86
- const writable = this.getWritable();
87
- writable.__altText = altText;
88
- }
89
- createDOM(config) {
90
- const span = document.createElement("span");
91
- const className = config.theme.image;
92
- if (typeof className === "string") {
93
- span.className = className;
94
- }
95
- return span;
96
- }
97
- updateDOM() {
98
- return false;
99
- }
100
- decorate() {
101
- return /* @__PURE__ */ jsx(ImageNodeComponent, { src: this.__src, alt: this.__altText });
102
- }
103
- isInline() {
104
- return true;
105
- }
106
- static importJSON(serializedNode) {
107
- return $createImageNode(serializedNode.src, serializedNode.altText);
108
- }
109
- exportJSON() {
110
- return {
111
- type: "image",
112
- version: 1,
113
- src: this.__src,
114
- altText: this.__altText
115
- };
116
- }
117
- exportDOM() {
118
- const element = document.createElement("img");
119
- element.setAttribute("src", this.__src);
120
- element.setAttribute("alt", this.__altText);
121
- return { element };
122
- }
123
- static importDOM() {
124
- return {
125
- img: () => ({
126
- conversion: (domNode) => {
127
- const src = domNode.getAttribute("src") || "";
128
- const alt = domNode.getAttribute("alt") || "";
129
- return { node: $createImageNode(src, alt) };
130
- },
131
- priority: 0
132
- })
133
- };
134
- }
59
+ //#endregion
60
+ //#region src/blocks/MarkdownEditor/nodes/ImageNode.tsx
61
+ var ImageNode = class ImageNode extends DecoratorNode {
62
+ __src;
63
+ __altText;
64
+ static getType() {
65
+ return "image";
66
+ }
67
+ static clone(node) {
68
+ return new ImageNode(node.__src, node.__altText, node.__key);
69
+ }
70
+ constructor(src, altText, key) {
71
+ super(key);
72
+ this.__src = src;
73
+ this.__altText = altText;
74
+ }
75
+ getSrc() {
76
+ return this.__src;
77
+ }
78
+ getAlt() {
79
+ return this.__altText;
80
+ }
81
+ setSrc(src) {
82
+ const writable = this.getWritable();
83
+ writable.__src = src;
84
+ }
85
+ setAlt(altText) {
86
+ const writable = this.getWritable();
87
+ writable.__altText = altText;
88
+ }
89
+ createDOM(config) {
90
+ const span = document.createElement("span");
91
+ const className = config.theme.image;
92
+ if (typeof className === "string") span.className = className;
93
+ return span;
94
+ }
95
+ updateDOM() {
96
+ return false;
97
+ }
98
+ decorate() {
99
+ return /* @__PURE__ */ jsx(ImageNodeComponent, {
100
+ src: this.__src,
101
+ alt: this.__altText
102
+ });
103
+ }
104
+ isInline() {
105
+ return true;
106
+ }
107
+ static importJSON(serializedNode) {
108
+ return $createImageNode(serializedNode.src, serializedNode.altText);
109
+ }
110
+ exportJSON() {
111
+ return {
112
+ type: "image",
113
+ version: 1,
114
+ src: this.__src,
115
+ altText: this.__altText
116
+ };
117
+ }
118
+ exportDOM() {
119
+ const element = document.createElement("img");
120
+ element.setAttribute("src", this.__src);
121
+ element.setAttribute("alt", this.__altText);
122
+ return { element };
123
+ }
124
+ static importDOM() {
125
+ return { img: () => ({
126
+ conversion: (domNode) => {
127
+ const src = domNode.getAttribute("src") || "";
128
+ const alt = domNode.getAttribute("alt") || "";
129
+ return { node: $createImageNode(src, alt) };
130
+ },
131
+ priority: 0
132
+ }) };
133
+ }
135
134
  };
136
- var $createImageNode = (src, altText) => {
137
- return new ImageNode(src, altText);
135
+ const $createImageNode = (src, altText) => {
136
+ return new ImageNode(src, altText);
138
137
  };
139
- var $isImageNode = (node) => {
140
- return node instanceof ImageNode;
138
+ const $isImageNode = (node) => {
139
+ return node instanceof ImageNode;
141
140
  };
142
- var MermaidDiagram = lazy(
143
- () => import('./MermaidDiagram-ZU5KAVRT.js').then(
144
- (m) => ({ default: m.MermaidDiagram }),
145
- (error) => {
146
- console.error("[MarkdownEditor] failed to load MermaidDiagram chunk", error);
147
- return {
148
- default: ({ code }) => /* @__PURE__ */ jsx("pre", { children: /* @__PURE__ */ jsx("code", { children: code }) })
149
- };
150
- }
151
- )
152
- );
153
- var MermaidNodeComponent = ({ code }) => {
154
- return /* @__PURE__ */ jsx(
155
- Suspense,
156
- {
157
- fallback: /* @__PURE__ */ jsx("div", { className: "tw:my-3 tw:overflow-hidden tw:rounded-card tw:border tw:border-neutral-150 tw:bg-neutral-50 tw:p-6", children: /* @__PURE__ */ jsx(Skeleton, { className: "tw:h-40" }) }),
158
- children: /* @__PURE__ */ jsx(MermaidDiagram, { code })
159
- }
160
- );
141
+ //#endregion
142
+ //#region src/blocks/MarkdownEditor/nodes/MermaidNodeComponent.tsx
143
+ const MermaidDiagram = lazy(() => import("./MermaidDiagram-BB06gymm.js").then((n) => n.MermaidDiagram_exports).then((m) => ({ default: m.MermaidDiagram }), (error) => {
144
+ console.error("[MarkdownEditor] failed to load MermaidDiagram chunk", error);
145
+ return { default: ({ code }) => /* @__PURE__ */ jsx("pre", { children: /* @__PURE__ */ jsx("code", { children: code }) }) };
146
+ }));
147
+ const MermaidNodeComponent = ({ code }) => {
148
+ return /* @__PURE__ */ jsx(Suspense, {
149
+ fallback: /* @__PURE__ */ jsx("div", {
150
+ className: "tw:my-3 tw:overflow-hidden tw:rounded-card tw:border tw:border-neutral-150 tw:bg-neutral-50 tw:p-6",
151
+ children: /* @__PURE__ */ jsx(Skeleton, { className: "tw:h-40" })
152
+ }),
153
+ children: /* @__PURE__ */ jsx(MermaidDiagram, { code })
154
+ });
161
155
  };
162
- var MermaidNode = class _MermaidNode extends DecoratorNode {
163
- __code;
164
- static getType() {
165
- return "mermaid";
166
- }
167
- static clone(node) {
168
- return new _MermaidNode(node.__code, node.__key);
169
- }
170
- constructor(code, key) {
171
- super(key);
172
- this.__code = code;
173
- }
174
- getCode() {
175
- return this.__code;
176
- }
177
- setCode(code) {
178
- const writable = this.getWritable();
179
- writable.__code = code;
180
- }
181
- createDOM() {
182
- const div = document.createElement("div");
183
- div.setAttribute("data-lexical-mermaid", "true");
184
- return div;
185
- }
186
- updateDOM() {
187
- return false;
188
- }
189
- decorate() {
190
- return /* @__PURE__ */ jsx(MermaidNodeComponent, { code: this.__code });
191
- }
192
- isInline() {
193
- return false;
194
- }
195
- static importJSON(serializedNode) {
196
- return $createMermaidNode(serializedNode.code);
197
- }
198
- exportJSON() {
199
- return {
200
- type: "mermaid",
201
- version: 1,
202
- code: this.__code
203
- };
204
- }
156
+ //#endregion
157
+ //#region src/blocks/MarkdownEditor/nodes/MermaidNode.tsx
158
+ var MermaidNode = class MermaidNode extends DecoratorNode {
159
+ __code;
160
+ static getType() {
161
+ return "mermaid";
162
+ }
163
+ static clone(node) {
164
+ return new MermaidNode(node.__code, node.__key);
165
+ }
166
+ constructor(code, key) {
167
+ super(key);
168
+ this.__code = code;
169
+ }
170
+ getCode() {
171
+ return this.__code;
172
+ }
173
+ setCode(code) {
174
+ const writable = this.getWritable();
175
+ writable.__code = code;
176
+ }
177
+ createDOM() {
178
+ const div = document.createElement("div");
179
+ div.setAttribute("data-lexical-mermaid", "true");
180
+ return div;
181
+ }
182
+ updateDOM() {
183
+ return false;
184
+ }
185
+ decorate() {
186
+ return /* @__PURE__ */ jsx(MermaidNodeComponent, { code: this.__code });
187
+ }
188
+ isInline() {
189
+ return false;
190
+ }
191
+ static importJSON(serializedNode) {
192
+ return $createMermaidNode(serializedNode.code);
193
+ }
194
+ exportJSON() {
195
+ return {
196
+ type: "mermaid",
197
+ version: 1,
198
+ code: this.__code
199
+ };
200
+ }
205
201
  };
206
- var $createMermaidNode = (code) => {
207
- return new MermaidNode(code);
202
+ const $createMermaidNode = (code) => {
203
+ return new MermaidNode(code);
208
204
  };
209
- var $isMermaidNode = (node) => {
210
- return node instanceof MermaidNode;
205
+ const $isMermaidNode = (node) => {
206
+ return node instanceof MermaidNode;
211
207
  };
212
- var ACCEPTED_IMAGE_TYPES = [
213
- "image/png",
214
- "image/jpeg",
215
- "image/gif",
216
- "image/webp",
217
- "image/svg+xml"
208
+ //#endregion
209
+ //#region src/blocks/MarkdownEditor/plugins/ImagePastePlugin.tsx
210
+ const ACCEPTED_IMAGE_TYPES = [
211
+ "image/png",
212
+ "image/jpeg",
213
+ "image/gif",
214
+ "image/webp",
215
+ "image/svg+xml"
218
216
  ];
219
- var MAX_IMAGE_SIZE = 10 * 1024 * 1024;
220
- var PLACEHOLDER_PREFIX = "upload-placeholder-";
221
- var generatePlaceholderId = () => {
222
- if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
223
- return crypto.randomUUID();
224
- }
225
- return `${Date.now()}-${Math.random().toString(36).slice(2)}`;
226
- };
227
- var isAcceptedImageType = (type) => ACCEPTED_IMAGE_TYPES.includes(type);
228
- var getImageFilesFromDataTransfer = (dataTransfer) => {
229
- if (!dataTransfer) return [];
230
- if (dataTransfer.items.length > 0) {
231
- const files = [];
232
- for (const item of dataTransfer.items) {
233
- if (item.kind === "file" && isAcceptedImageType(item.type)) {
234
- const file = item.getAsFile();
235
- if (file) files.push(file);
236
- }
237
- }
238
- if (files.length > 0) return files;
239
- }
240
- return Array.from(dataTransfer.files).filter((file) => isAcceptedImageType(file.type));
241
- };
242
- var escapeMarkdownAlt = (text) => text.replace(/[[\]()]/g, "");
243
- var ImagePastePlugin = ({ onImageUpload }) => {
244
- const [editor] = useLexicalComposerContext();
245
- const onImageUploadRef = useRef(onImageUpload);
246
- onImageUploadRef.current = onImageUpload;
247
- useEffect(() => {
248
- const uploadFile = (file) => {
249
- const upload = onImageUploadRef.current;
250
- if (!upload) return;
251
- if (file.size > MAX_IMAGE_SIZE) {
252
- toast.error(`Image "${file.name}" is too large. Maximum size is 10 MB.`);
253
- return;
254
- }
255
- let nodeKey = null;
256
- editor.update(() => {
257
- const placeholderNode = $createImageNode(
258
- `${PLACEHOLDER_PREFIX}${generatePlaceholderId()}`,
259
- "Uploading image\u2026"
260
- );
261
- $insertNodes([placeholderNode]);
262
- nodeKey = placeholderNode.getKey();
263
- });
264
- if (!nodeKey) return;
265
- const capturedKey = nodeKey;
266
- upload(file).then(({ url }) => {
267
- editor.update(() => {
268
- const node = $getNodeByKey(capturedKey);
269
- if ($isImageNode(node)) {
270
- const altText = escapeMarkdownAlt(file.name.replace(/\.[^.]+$/, "") || "image");
271
- node.setSrc(url);
272
- node.setAlt(altText);
273
- }
274
- });
275
- }).catch((error) => {
276
- console.error("[MarkdownEditor] image upload failed", error);
277
- toast.error(`Failed to upload "${file.name}". Please try again.`);
278
- editor.update(() => {
279
- const node = $getNodeByKey(capturedKey);
280
- if (node) node.remove();
281
- });
282
- });
283
- };
284
- const removePaste = editor.registerCommand(
285
- PASTE_COMMAND,
286
- (event) => {
287
- if (!onImageUploadRef.current) return false;
288
- if (!(event instanceof ClipboardEvent)) return false;
289
- const files = getImageFilesFromDataTransfer(event.clipboardData);
290
- if (files.length === 0) return false;
291
- event.preventDefault();
292
- Promise.resolve().then(() => files.forEach(uploadFile));
293
- return true;
294
- },
295
- COMMAND_PRIORITY_CRITICAL
296
- );
297
- const removeDrop = editor.registerCommand(
298
- DROP_COMMAND,
299
- (event) => {
300
- if (!onImageUploadRef.current) return false;
301
- const files = getImageFilesFromDataTransfer(event.dataTransfer);
302
- if (files.length === 0) return false;
303
- event.preventDefault();
304
- Promise.resolve().then(() => files.forEach(uploadFile));
305
- return true;
306
- },
307
- COMMAND_PRIORITY_CRITICAL
308
- );
309
- return () => {
310
- removePaste();
311
- removeDrop();
312
- };
313
- }, [editor]);
314
- return null;
217
+ const MAX_IMAGE_SIZE = 10485760;
218
+ const PLACEHOLDER_PREFIX = "upload-placeholder-";
219
+ const generatePlaceholderId = () => {
220
+ if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") return crypto.randomUUID();
221
+ return `${Date.now()}-${Math.random().toString(36).slice(2)}`;
315
222
  };
316
- var KeyboardPlugin = ({
317
- onSave,
318
- onCancel,
319
- singleLine,
320
- blurOnEscape,
321
- skipBlurSaveRef
322
- }) => {
323
- const [editor] = useLexicalComposerContext();
324
- const onSaveRef = useRef(onSave);
325
- onSaveRef.current = onSave;
326
- const onCancelRef = useRef(onCancel);
327
- onCancelRef.current = onCancel;
328
- const singleLineRef = useRef(singleLine);
329
- singleLineRef.current = singleLine;
330
- const blurOnEscapeRef = useRef(blurOnEscape);
331
- blurOnEscapeRef.current = blurOnEscape;
332
- const skipBlurSaveExternalRef = skipBlurSaveRef;
333
- useEffect(() => {
334
- return editor.registerCommand(
335
- KEY_DOWN_COMMAND,
336
- (event) => {
337
- if (event.key === "Enter" && (event.ctrlKey || event.metaKey)) {
338
- event.preventDefault();
339
- onSaveRef.current?.();
340
- return true;
341
- }
342
- if (event.key === "Enter" && !event.shiftKey && !event.altKey && singleLineRef.current) {
343
- event.preventDefault();
344
- editor.getRootElement()?.blur();
345
- return true;
346
- }
347
- if (event.key === "Escape" && blurOnEscapeRef.current) {
348
- if (skipBlurSaveExternalRef) skipBlurSaveExternalRef.current = true;
349
- onCancelRef.current?.();
350
- editor.getRootElement()?.blur();
351
- return true;
352
- }
353
- return false;
354
- },
355
- COMMAND_PRIORITY_HIGH
356
- );
357
- }, [editor, skipBlurSaveExternalRef]);
358
- return null;
223
+ const isAcceptedImageType = (type) => ACCEPTED_IMAGE_TYPES.includes(type);
224
+ const getImageFilesFromDataTransfer = (dataTransfer) => {
225
+ if (!dataTransfer) return [];
226
+ if (dataTransfer.items.length > 0) {
227
+ const files = [];
228
+ for (const item of dataTransfer.items) if (item.kind === "file" && isAcceptedImageType(item.type)) {
229
+ const file = item.getAsFile();
230
+ if (file) files.push(file);
231
+ }
232
+ if (files.length > 0) return files;
233
+ }
234
+ return Array.from(dataTransfer.files).filter((file) => isAcceptedImageType(file.type));
359
235
  };
360
- var IMAGE = {
361
- dependencies: [ImageNode],
362
- export: (node) => {
363
- if (!$isImageNode(node)) return null;
364
- return `![${node.getAlt()}](${node.getSrc()})`;
365
- },
366
- importRegExp: /!\[([^\]]*)\]\(([^)]+)\)/,
367
- regExp: /!\[([^\]]*)\]\(([^)]+)\)$/,
368
- replace: (textNode, match) => {
369
- const [, alt = "", src = ""] = match;
370
- const imageNode = $createImageNode(src, alt);
371
- textNode.replace(imageNode);
372
- },
373
- trigger: ")",
374
- type: "text-match"
236
+ const escapeMarkdownAlt = (text) => text.replace(/[[\]()]/g, "");
237
+ const ImagePastePlugin = ({ onImageUpload }) => {
238
+ const [editor] = useLexicalComposerContext();
239
+ const onImageUploadRef = useRef(onImageUpload);
240
+ onImageUploadRef.current = onImageUpload;
241
+ useEffect(() => {
242
+ const uploadFile = (file) => {
243
+ const upload = onImageUploadRef.current;
244
+ if (!upload) return;
245
+ if (file.size > MAX_IMAGE_SIZE) {
246
+ toast.error(`Image "${file.name}" is too large. Maximum size is 10 MB.`);
247
+ return;
248
+ }
249
+ let nodeKey = null;
250
+ editor.update(() => {
251
+ const placeholderNode = $createImageNode(`${PLACEHOLDER_PREFIX}${generatePlaceholderId()}`, "Uploading image…");
252
+ $insertNodes([placeholderNode]);
253
+ nodeKey = placeholderNode.getKey();
254
+ });
255
+ if (!nodeKey) return;
256
+ const capturedKey = nodeKey;
257
+ upload(file).then(({ url }) => {
258
+ editor.update(() => {
259
+ const node = $getNodeByKey(capturedKey);
260
+ if ($isImageNode(node)) {
261
+ const altText = escapeMarkdownAlt(file.name.replace(/\.[^.]+$/, "") || "image");
262
+ node.setSrc(url);
263
+ node.setAlt(altText);
264
+ }
265
+ });
266
+ }).catch((error) => {
267
+ console.error("[MarkdownEditor] image upload failed", error);
268
+ toast.error(`Failed to upload "${file.name}". Please try again.`);
269
+ editor.update(() => {
270
+ const node = $getNodeByKey(capturedKey);
271
+ if (node) node.remove();
272
+ });
273
+ });
274
+ };
275
+ const removePaste = editor.registerCommand(PASTE_COMMAND, (event) => {
276
+ if (!onImageUploadRef.current) return false;
277
+ if (!(event instanceof ClipboardEvent)) return false;
278
+ const files = getImageFilesFromDataTransfer(event.clipboardData);
279
+ if (files.length === 0) return false;
280
+ event.preventDefault();
281
+ Promise.resolve().then(() => files.forEach(uploadFile));
282
+ return true;
283
+ }, COMMAND_PRIORITY_CRITICAL);
284
+ const removeDrop = editor.registerCommand(DROP_COMMAND, (event) => {
285
+ if (!onImageUploadRef.current) return false;
286
+ const files = getImageFilesFromDataTransfer(event.dataTransfer);
287
+ if (files.length === 0) return false;
288
+ event.preventDefault();
289
+ Promise.resolve().then(() => files.forEach(uploadFile));
290
+ return true;
291
+ }, COMMAND_PRIORITY_CRITICAL);
292
+ return () => {
293
+ removePaste();
294
+ removeDrop();
295
+ };
296
+ }, [editor]);
297
+ return null;
375
298
  };
376
- var HORIZONTAL_RULE = {
377
- dependencies: [HorizontalRuleNode],
378
- export: (node) => {
379
- return $isHorizontalRuleNode(node) ? "---" : null;
380
- },
381
- regExp: /^(---|\*\*\*|___)$/,
382
- replace: (parentNode) => {
383
- const node = $createHorizontalRuleNode();
384
- parentNode.replace(node);
385
- },
386
- type: "element"
299
+ //#endregion
300
+ //#region src/blocks/MarkdownEditor/plugins/KeyboardPlugin.tsx
301
+ const KeyboardPlugin = ({ onSave, onCancel, singleLine, blurOnEscape, skipBlurSaveRef }) => {
302
+ const [editor] = useLexicalComposerContext();
303
+ const onSaveRef = useRef(onSave);
304
+ onSaveRef.current = onSave;
305
+ const onCancelRef = useRef(onCancel);
306
+ onCancelRef.current = onCancel;
307
+ const singleLineRef = useRef(singleLine);
308
+ singleLineRef.current = singleLine;
309
+ const blurOnEscapeRef = useRef(blurOnEscape);
310
+ blurOnEscapeRef.current = blurOnEscape;
311
+ const skipBlurSaveExternalRef = skipBlurSaveRef;
312
+ useEffect(() => {
313
+ return editor.registerCommand(KEY_DOWN_COMMAND, (event) => {
314
+ if (event.key === "Enter" && (event.ctrlKey || event.metaKey)) {
315
+ event.preventDefault();
316
+ onSaveRef.current?.();
317
+ return true;
318
+ }
319
+ if (event.key === "Enter" && !event.shiftKey && !event.altKey && singleLineRef.current) {
320
+ event.preventDefault();
321
+ editor.getRootElement()?.blur();
322
+ return true;
323
+ }
324
+ if (event.key === "Escape" && blurOnEscapeRef.current) {
325
+ if (skipBlurSaveExternalRef) skipBlurSaveExternalRef.current = true;
326
+ onCancelRef.current?.();
327
+ editor.getRootElement()?.blur();
328
+ return true;
329
+ }
330
+ return false;
331
+ }, COMMAND_PRIORITY_HIGH);
332
+ }, [editor, skipBlurSaveExternalRef]);
333
+ return null;
387
334
  };
388
- var MERMAID = {
389
- dependencies: [MermaidNode],
390
- export: (node) => {
391
- if (!$isMermaidNode(node)) return null;
392
- return "```mermaid\n" + node.getCode() + "\n```";
393
- },
394
- regExpStart: /^[ \t]*(`{3,})mermaid(?:\s.*)?$/,
395
- regExpEnd: {
396
- optional: true,
397
- regExp: /^[ \t]*`{3,}$/
398
- },
399
- replace: (rootNode, _children, _startMatch, _endMatch, linesInBetween) => {
400
- if (!linesInBetween) return;
401
- const code = linesInBetween.join("\n").trim();
402
- if (code) {
403
- rootNode.append($createMermaidNode(code));
404
- }
405
- },
406
- handleImportAfterStartMatch: ({
407
- lines,
408
- rootNode,
409
- startLineIndex,
410
- startMatch
411
- }) => {
412
- const fence = startMatch[1];
413
- if (!fence) return [false, startLineIndex];
414
- const fenceLength = fence.trim().length;
415
- const endRegex = new RegExp(`^[ \\t]*\`{${fenceLength},}$`);
416
- for (let i = startLineIndex + 1; i < lines.length; i++) {
417
- if (endRegex.test(lines[i] ?? "")) {
418
- const code2 = lines.slice(startLineIndex + 1, i).join("\n").trim();
419
- if (code2) {
420
- rootNode.append($createMermaidNode(code2));
421
- }
422
- return [true, i];
423
- }
424
- }
425
- const code = lines.slice(startLineIndex + 1).join("\n").trim();
426
- if (code) {
427
- rootNode.append($createMermaidNode(code));
428
- }
429
- return [true, lines.length - 1];
430
- },
431
- type: "multiline-element"
432
- };
433
- var CUSTOM_TRANSFORMERS = [
434
- IMAGE,
435
- HORIZONTAL_RULE,
436
- CHECK_LIST,
437
- MERMAID,
438
- ...TRANSFORMERS
335
+ /**
336
+ * Custom transformers = our additions + built-in Lexical transformers.
337
+ * MERMAID is placed before TRANSFORMERS so it intercepts ` ```mermaid ``` ` before the generic CODE transformer.
338
+ * IMAGE is placed before built-in LINK to prevent `![alt](url)` from being parsed as `!` + link.
339
+ */
340
+ const CUSTOM_TRANSFORMERS = [
341
+ {
342
+ dependencies: [ImageNode],
343
+ export: (node) => {
344
+ if (!$isImageNode(node)) return null;
345
+ return `![${node.getAlt()}](${node.getSrc()})`;
346
+ },
347
+ importRegExp: /!\[([^\]]*)\]\(([^)]+)\)/,
348
+ regExp: /!\[([^\]]*)\]\(([^)]+)\)$/,
349
+ replace: (textNode, match) => {
350
+ const [, alt = "", src = ""] = match;
351
+ const imageNode = $createImageNode(src, alt);
352
+ textNode.replace(imageNode);
353
+ },
354
+ trigger: ")",
355
+ type: "text-match"
356
+ },
357
+ {
358
+ dependencies: [HorizontalRuleNode],
359
+ export: (node) => {
360
+ return $isHorizontalRuleNode(node) ? "---" : null;
361
+ },
362
+ regExp: /^(---|\*\*\*|___)$/,
363
+ replace: (parentNode) => {
364
+ const node = $createHorizontalRuleNode();
365
+ parentNode.replace(node);
366
+ },
367
+ type: "element"
368
+ },
369
+ CHECK_LIST,
370
+ {
371
+ dependencies: [MermaidNode],
372
+ export: (node) => {
373
+ if (!$isMermaidNode(node)) return null;
374
+ return "```mermaid\n" + node.getCode() + "\n```";
375
+ },
376
+ regExpStart: /^[ \t]*(`{3,})mermaid(?:\s.*)?$/,
377
+ regExpEnd: {
378
+ optional: true,
379
+ regExp: /^[ \t]*`{3,}$/
380
+ },
381
+ replace: (rootNode, _children, _startMatch, _endMatch, linesInBetween) => {
382
+ if (!linesInBetween) return;
383
+ const code = linesInBetween.join("\n").trim();
384
+ if (code) rootNode.append($createMermaidNode(code));
385
+ },
386
+ handleImportAfterStartMatch: ({ lines, rootNode, startLineIndex, startMatch }) => {
387
+ const fence = startMatch[1];
388
+ if (!fence) return [false, startLineIndex];
389
+ const fenceLength = fence.trim().length;
390
+ const endRegex = new RegExp(`^[ \\t]*\`{${fenceLength},}$`);
391
+ for (let i = startLineIndex + 1; i < lines.length; i++) if (endRegex.test(lines[i] ?? "")) {
392
+ const code = lines.slice(startLineIndex + 1, i).join("\n").trim();
393
+ if (code) rootNode.append($createMermaidNode(code));
394
+ return [true, i];
395
+ }
396
+ const code = lines.slice(startLineIndex + 1).join("\n").trim();
397
+ if (code) rootNode.append($createMermaidNode(code));
398
+ return [true, lines.length - 1];
399
+ },
400
+ type: "multiline-element"
401
+ },
402
+ ...TRANSFORMERS
439
403
  ];
440
- var SINGLE_LINE_TRANSFORMERS = [];
441
- var TABLE_FENCE_LANG = "__kbc_table__";
442
- var isTableLine = (line) => {
443
- const trimmed = line.trim();
444
- return trimmed.startsWith("|") && trimmed.endsWith("|");
404
+ /**
405
+ * No transformers = plain text. `singleLine` mode edits entity names / titles, which are
406
+ * plain text, not markdown. Parsing inline formatting here corrupts ordinary names: e.g.
407
+ * `staging_chargebee_invoices` would render the `_chargebee_` span as italics, and Lexical
408
+ * escapes the underscores on export (`\_`) to prevent exactly that — but those backslashes
409
+ * then leak into the persisted name. Dropping every transformer keeps `_`, `*`, `` ` ``, `~`
410
+ * literal on both import and export; pair the empty set with `unescapeMarkdownText` on export
411
+ * to strip Lexical's escaping (see MarkdownSyncPlugin).
412
+ */
413
+ const SINGLE_LINE_TRANSFORMERS = [];
414
+ const TABLE_FENCE_LANG = "__kbc_table__";
415
+ const isTableLine = (line) => {
416
+ const trimmed = line.trim();
417
+ return trimmed.startsWith("|") && trimmed.endsWith("|");
445
418
  };
446
- var CODE_FENCE_REGEX = /^[ \t]*`{3,}/;
447
- var preprocessMarkdown = (markdown) => {
448
- const lines = markdown.split("\n");
449
- const result = [];
450
- let tableLines = [];
451
- let insideCodeFence = false;
452
- const flushTable = () => {
453
- if (tableLines.length >= 2) {
454
- result.push(`\`\`\`${TABLE_FENCE_LANG}`);
455
- result.push(...tableLines);
456
- result.push("```");
457
- } else {
458
- result.push(...tableLines);
459
- }
460
- tableLines = [];
461
- };
462
- for (const line of lines) {
463
- if (CODE_FENCE_REGEX.test(line)) {
464
- if (tableLines.length > 0) flushTable();
465
- insideCodeFence = !insideCodeFence;
466
- result.push(line);
467
- continue;
468
- }
469
- if (insideCodeFence) {
470
- result.push(line);
471
- continue;
472
- }
473
- if (isTableLine(line)) {
474
- tableLines.push(line);
475
- } else {
476
- if (tableLines.length > 0) flushTable();
477
- result.push(line);
478
- }
479
- }
480
- if (tableLines.length > 0) flushTable();
481
- return result.join("\n");
419
+ const CODE_FENCE_REGEX = /^[ \t]*`{3,}/;
420
+ /** Wrap GFM tables in code fences so they survive Lexical's markdown round-trip. */
421
+ const preprocessMarkdown = (markdown) => {
422
+ const lines = markdown.split("\n");
423
+ const result = [];
424
+ let tableLines = [];
425
+ let insideCodeFence = false;
426
+ const flushTable = () => {
427
+ if (tableLines.length >= 2) {
428
+ result.push(`\`\`\`${TABLE_FENCE_LANG}`);
429
+ result.push(...tableLines);
430
+ result.push("```");
431
+ } else result.push(...tableLines);
432
+ tableLines = [];
433
+ };
434
+ for (const line of lines) {
435
+ if (CODE_FENCE_REGEX.test(line)) {
436
+ if (tableLines.length > 0) flushTable();
437
+ insideCodeFence = !insideCodeFence;
438
+ result.push(line);
439
+ continue;
440
+ }
441
+ if (insideCodeFence) {
442
+ result.push(line);
443
+ continue;
444
+ }
445
+ if (isTableLine(line)) tableLines.push(line);
446
+ else {
447
+ if (tableLines.length > 0) flushTable();
448
+ result.push(line);
449
+ }
450
+ }
451
+ if (tableLines.length > 0) flushTable();
452
+ return result.join("\n");
482
453
  };
483
- var postprocessMarkdown = (markdown) => {
484
- const regex = new RegExp(`\`\`\`${TABLE_FENCE_LANG}\\n([\\s\\S]*?)\\n\`\`\``, "g");
485
- return markdown.replace(regex, "$1");
454
+ /** Unwrap code-fenced tables back to raw GFM table markdown. */
455
+ const postprocessMarkdown = (markdown) => {
456
+ const regex = new RegExp(`\`\`\`${TABLE_FENCE_LANG}\\n([\\s\\S]*?)\\n\`\`\``, "g");
457
+ return markdown.replace(regex, "$1");
486
458
  };
487
- var unescapeMarkdownText = (markdown) => markdown.replace(/\\([*_`~\\])/g, "$1");
488
-
489
- // src/blocks/MarkdownEditor/plugins/MarkdownSyncPlugin.tsx
490
- var IMPORT_TAG = "markdown-import";
491
- var MarkdownSyncPlugin = ({
492
- value,
493
- editable,
494
- onChange,
495
- transformers = CUSTOM_TRANSFORMERS,
496
- singleLine = false
497
- }) => {
498
- const [editor] = useLexicalComposerContext();
499
- const lastExportedRef = useRef(value);
500
- const onChangeRef = useRef(onChange);
501
- onChangeRef.current = onChange;
502
- const transformersRef = useRef(transformers);
503
- transformersRef.current = transformers;
504
- const singleLineRef = useRef(singleLine);
505
- singleLineRef.current = singleLine;
506
- useEffect(() => {
507
- editor.setEditable(editable);
508
- }, [editor, editable]);
509
- useEffect(() => {
510
- if (value === lastExportedRef.current) return;
511
- lastExportedRef.current = value;
512
- editor.update(
513
- () => {
514
- $convertFromMarkdownString(preprocessMarkdown(value), transformersRef.current);
515
- },
516
- { tag: IMPORT_TAG }
517
- );
518
- }, [editor, value]);
519
- useEffect(() => {
520
- return editor.registerUpdateListener(({ tags }) => {
521
- if (tags.has(IMPORT_TAG)) return;
522
- editor.getEditorState().read(() => {
523
- const raw = $convertToMarkdownString(transformersRef.current);
524
- const markdown = singleLineRef.current ? unescapeMarkdownText(raw) : postprocessMarkdown(raw);
525
- if (markdown !== lastExportedRef.current) {
526
- lastExportedRef.current = markdown;
527
- onChangeRef.current?.(markdown);
528
- }
529
- });
530
- });
531
- }, [editor]);
532
- return null;
459
+ /**
460
+ * Reverses the backslash-escaping Lexical applies to markdown punctuation (`* _ ` ~ \`) when
461
+ * exporting text nodes. Used for `singleLine` (plain-text) mode, where the export value is a
462
+ * bare entity name — the escaping would otherwise persist as literal backslashes in the name.
463
+ */
464
+ const unescapeMarkdownText = (markdown) => markdown.replace(/\\([*_`~\\])/g, "$1");
465
+ //#endregion
466
+ //#region src/blocks/MarkdownEditor/plugins/MarkdownSyncPlugin.tsx
467
+ const IMPORT_TAG = "markdown-import";
468
+ const MarkdownSyncPlugin = ({ value, editable, onChange, transformers = CUSTOM_TRANSFORMERS, singleLine = false }) => {
469
+ const [editor] = useLexicalComposerContext();
470
+ const lastExportedRef = useRef(value);
471
+ const onChangeRef = useRef(onChange);
472
+ onChangeRef.current = onChange;
473
+ const transformersRef = useRef(transformers);
474
+ transformersRef.current = transformers;
475
+ const singleLineRef = useRef(singleLine);
476
+ singleLineRef.current = singleLine;
477
+ useEffect(() => {
478
+ editor.setEditable(editable);
479
+ }, [editor, editable]);
480
+ useEffect(() => {
481
+ if (value === lastExportedRef.current) return;
482
+ lastExportedRef.current = value;
483
+ editor.update(() => {
484
+ $convertFromMarkdownString(preprocessMarkdown(value), transformersRef.current);
485
+ }, { tag: IMPORT_TAG });
486
+ }, [editor, value]);
487
+ useEffect(() => {
488
+ return editor.registerUpdateListener(({ tags }) => {
489
+ if (tags.has(IMPORT_TAG)) return;
490
+ editor.getEditorState().read(() => {
491
+ const raw = $convertToMarkdownString(transformersRef.current);
492
+ const markdown = singleLineRef.current ? unescapeMarkdownText(raw) : postprocessMarkdown(raw);
493
+ if (markdown !== lastExportedRef.current) {
494
+ lastExportedRef.current = markdown;
495
+ onChangeRef.current?.(markdown);
496
+ }
497
+ });
498
+ });
499
+ }, [editor]);
500
+ return null;
533
501
  };
534
- var ALIGNMENT_OPTIONS = [
535
- { value: "left", label: "Left", icon: AlignLeft },
536
- { value: "center", label: "Center", icon: AlignCenter },
537
- { value: "right", label: "Right", icon: AlignRight },
538
- { value: "justify", label: "Justify", icon: AlignJustify }
502
+ //#endregion
503
+ //#region src/blocks/MarkdownEditor/plugins/toolbar/AlignmentDropdown.tsx
504
+ const ALIGNMENT_OPTIONS = [
505
+ {
506
+ value: "left",
507
+ label: "Left",
508
+ icon: AlignLeft
509
+ },
510
+ {
511
+ value: "center",
512
+ label: "Center",
513
+ icon: AlignCenter
514
+ },
515
+ {
516
+ value: "right",
517
+ label: "Right",
518
+ icon: AlignRight
519
+ },
520
+ {
521
+ value: "justify",
522
+ label: "Justify",
523
+ icon: AlignJustify
524
+ }
539
525
  ];
540
- var ALIGNMENT_ICONS = Object.fromEntries(
541
- ALIGNMENT_OPTIONS.map(({ value, icon }) => [value, icon])
542
- );
543
- var AlignmentDropdown = ({
544
- editor,
545
- alignment
546
- }) => {
547
- const savedSelectionRef = useRef(null);
548
- const handleOpenChange = (open) => {
549
- if (open) {
550
- editor.getEditorState().read(() => {
551
- const selection = $getSelection();
552
- savedSelectionRef.current = selection ? selection.clone() : null;
553
- });
554
- }
555
- };
556
- const handleSelect = (align) => {
557
- editor.update(() => {
558
- if (savedSelectionRef.current) {
559
- $setSelection(savedSelectionRef.current);
560
- }
561
- editor.dispatchCommand(FORMAT_ELEMENT_COMMAND, align);
562
- });
563
- };
564
- const CurrentAlignmentIcon = ALIGNMENT_ICONS[alignment] ?? AlignLeft;
565
- return /* @__PURE__ */ jsxs(DropdownMenu, { onOpenChange: handleOpenChange, children: [
566
- /* @__PURE__ */ jsx(Tooltip, { tooltip: "Text alignment", placement: "top", triggerAsChild: true, children: /* @__PURE__ */ jsx(DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
567
- "button",
568
- {
569
- type: "button",
570
- className: cn(
571
- "tw:flex tw:h-7 tw:cursor-pointer tw:items-center tw:gap-1 tw:rounded tw:border-0 tw:bg-transparent tw:px-1.5 tw:text-xs tw:text-muted-foreground",
572
- "tw:hover:bg-accent"
573
- ),
574
- children: [
575
- /* @__PURE__ */ jsx(CurrentAlignmentIcon, { className: "tw:size-4" }),
576
- /* @__PURE__ */ jsx(ChevronDown, { className: "tw:size-3" })
577
- ]
578
- }
579
- ) }) }),
580
- /* @__PURE__ */ jsx(DropdownMenu.Content, { align: "start", className: "tw:min-w-32", children: ALIGNMENT_OPTIONS.map(({ value, label, icon: IconComp }) => /* @__PURE__ */ jsxs(
581
- DropdownMenu.Item,
582
- {
583
- onSelect: () => handleSelect(value),
584
- className: cn(
585
- "tw:flex tw:items-center tw:gap-2",
586
- alignment === value && "tw:bg-secondary-50 tw:text-secondary-500"
587
- ),
588
- children: [
589
- /* @__PURE__ */ jsx(IconComp, { className: "tw:size-4" }),
590
- label
591
- ]
592
- },
593
- value
594
- )) })
595
- ] });
526
+ const ALIGNMENT_ICONS = Object.fromEntries(ALIGNMENT_OPTIONS.map(({ value, icon }) => [value, icon]));
527
+ const AlignmentDropdown = ({ editor, alignment }) => {
528
+ const savedSelectionRef = useRef(null);
529
+ const handleOpenChange = (open) => {
530
+ if (open) editor.getEditorState().read(() => {
531
+ const selection = $getSelection();
532
+ savedSelectionRef.current = selection ? selection.clone() : null;
533
+ });
534
+ };
535
+ const handleSelect = (align) => {
536
+ editor.update(() => {
537
+ if (savedSelectionRef.current) $setSelection(savedSelectionRef.current);
538
+ editor.dispatchCommand(FORMAT_ELEMENT_COMMAND, align);
539
+ });
540
+ };
541
+ const CurrentAlignmentIcon = ALIGNMENT_ICONS[alignment] ?? AlignLeft;
542
+ return /* @__PURE__ */ jsxs(DropdownMenu, {
543
+ onOpenChange: handleOpenChange,
544
+ children: [/* @__PURE__ */ jsx(Tooltip, {
545
+ tooltip: "Text alignment",
546
+ placement: "top",
547
+ triggerAsChild: true,
548
+ children: /* @__PURE__ */ jsx(DropdownMenu.Trigger, {
549
+ asChild: true,
550
+ children: /* @__PURE__ */ jsxs("button", {
551
+ type: "button",
552
+ className: cn("tw:flex tw:h-7 tw:cursor-pointer tw:items-center tw:gap-1 tw:rounded tw:border-0 tw:bg-transparent tw:px-1.5 tw:text-xs tw:text-muted-foreground", "tw:hover:bg-accent"),
553
+ children: [/* @__PURE__ */ jsx(CurrentAlignmentIcon, { className: "tw:size-4" }), /* @__PURE__ */ jsx(ChevronDown, { className: "tw:size-3" })]
554
+ })
555
+ })
556
+ }), /* @__PURE__ */ jsx(DropdownMenu.Content, {
557
+ align: "start",
558
+ className: "tw:min-w-32",
559
+ children: ALIGNMENT_OPTIONS.map(({ value, label, icon: IconComp }) => /* @__PURE__ */ jsxs(DropdownMenu.Item, {
560
+ onSelect: () => handleSelect(value),
561
+ className: cn("tw:flex tw:items-center tw:gap-2", alignment === value && "tw:bg-secondary-50 tw:text-secondary-500"),
562
+ children: [/* @__PURE__ */ jsx(IconComp, { className: "tw:size-4" }), label]
563
+ }, value))
564
+ })]
565
+ });
596
566
  };
597
- var BLOCK_TYPE_META = {
598
- paragraph: { label: "Normal", icon: Type, selectable: true },
599
- h1: { label: "Heading 1", icon: Heading1, selectable: true },
600
- h2: { label: "Heading 2", icon: Heading2, selectable: true },
601
- h3: { label: "Heading 3", icon: Heading3, selectable: true },
602
- bullet: { label: "Bullet List", icon: List, selectable: false },
603
- number: { label: "Numbered List", icon: ListOrdered, selectable: false },
604
- quote: { label: "Quote", icon: Quote, selectable: false },
605
- code: { label: "Code Block", icon: SquareCode, selectable: false }
567
+ //#endregion
568
+ //#region src/blocks/MarkdownEditor/plugins/toolbar/BlockTypeDropdown.tsx
569
+ const BLOCK_TYPE_META = {
570
+ paragraph: {
571
+ label: "Normal",
572
+ icon: Type,
573
+ selectable: true
574
+ },
575
+ h1: {
576
+ label: "Heading 1",
577
+ icon: Heading1,
578
+ selectable: true
579
+ },
580
+ h2: {
581
+ label: "Heading 2",
582
+ icon: Heading2,
583
+ selectable: true
584
+ },
585
+ h3: {
586
+ label: "Heading 3",
587
+ icon: Heading3,
588
+ selectable: true
589
+ },
590
+ bullet: {
591
+ label: "Bullet List",
592
+ icon: List,
593
+ selectable: false
594
+ },
595
+ number: {
596
+ label: "Numbered List",
597
+ icon: ListOrdered,
598
+ selectable: false
599
+ },
600
+ quote: {
601
+ label: "Quote",
602
+ icon: Quote,
603
+ selectable: false
604
+ },
605
+ code: {
606
+ label: "Code Block",
607
+ icon: SquareCode,
608
+ selectable: false
609
+ }
606
610
  };
607
- var BLOCK_TYPE_OPTIONS = Object.entries(BLOCK_TYPE_META).filter(([, meta]) => meta.selectable).map(([value, { label, icon }]) => ({ value, label, icon }));
608
- var isBlockType = (value) => Object.prototype.hasOwnProperty.call(BLOCK_TYPE_META, value);
609
- var BlockTypeDropdown = ({
610
- editor,
611
- blockType
612
- }) => {
613
- const savedSelectionRef = useRef(null);
614
- const currentMeta = isBlockType(blockType) ? BLOCK_TYPE_META[blockType] : null;
615
- const CurrentBlockIcon = currentMeta?.icon ?? Type;
616
- const handleOpenChange = (open) => {
617
- if (open) {
618
- editor.getEditorState().read(() => {
619
- const selection = $getSelection();
620
- savedSelectionRef.current = selection ? selection.clone() : null;
621
- });
622
- }
623
- };
624
- const handleSelect = (type) => {
625
- editor.update(() => {
626
- if (savedSelectionRef.current) {
627
- $setSelection(savedSelectionRef.current);
628
- }
629
- const selection = $getSelection();
630
- if (!$isRangeSelection(selection)) return;
631
- if (type === "bullet") {
632
- editor.dispatchCommand(INSERT_UNORDERED_LIST_COMMAND, void 0);
633
- return;
634
- }
635
- if (type === "number") {
636
- editor.dispatchCommand(INSERT_ORDERED_LIST_COMMAND, void 0);
637
- return;
638
- }
639
- const anchorNode = selection.anchor.getNode();
640
- const element = $getNearestBlockElementAncestorOrThrow(anchorNode);
641
- const newNode = type === "h1" || type === "h2" || type === "h3" ? $createHeadingNode(type) : type === "quote" ? $createQuoteNode() : type === "code" ? $createCodeNode() : $createParagraphNode();
642
- element.getChildren().forEach((child) => newNode.append(child));
643
- element.replace(newNode);
644
- });
645
- };
646
- return /* @__PURE__ */ jsxs(DropdownMenu, { onOpenChange: handleOpenChange, children: [
647
- /* @__PURE__ */ jsx(Tooltip, { tooltip: "Change block type", placement: "top", triggerAsChild: true, children: /* @__PURE__ */ jsx(DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
648
- "button",
649
- {
650
- type: "button",
651
- className: cn(
652
- "tw:flex tw:h-7 tw:cursor-pointer tw:items-center tw:gap-1.5 tw:rounded tw:border-0 tw:bg-transparent tw:px-1.5 tw:text-xs tw:text-muted-foreground",
653
- "tw:hover:bg-accent"
654
- ),
655
- children: [
656
- /* @__PURE__ */ jsx(CurrentBlockIcon, { className: "tw:size-4" }),
657
- currentMeta?.label ?? "Normal",
658
- /* @__PURE__ */ jsx(ChevronDown, { className: "tw:size-3" })
659
- ]
660
- }
661
- ) }) }),
662
- /* @__PURE__ */ jsx(DropdownMenu.Content, { align: "start", className: "tw:min-w-40", children: BLOCK_TYPE_OPTIONS.map(({ value, label, icon: IconComp }) => /* @__PURE__ */ jsxs(
663
- DropdownMenu.Item,
664
- {
665
- onSelect: () => handleSelect(value),
666
- className: cn(
667
- "tw:flex tw:items-center tw:gap-2",
668
- blockType === value && "tw:bg-secondary-50 tw:text-secondary-500"
669
- ),
670
- children: [
671
- /* @__PURE__ */ jsx(IconComp, { className: "tw:size-4" }),
672
- label
673
- ]
674
- },
675
- value
676
- )) })
677
- ] });
611
+ const BLOCK_TYPE_OPTIONS = Object.entries(BLOCK_TYPE_META).filter(([, meta]) => meta.selectable).map(([value, { label, icon }]) => ({
612
+ value,
613
+ label,
614
+ icon
615
+ }));
616
+ const isBlockType = (value) => Object.prototype.hasOwnProperty.call(BLOCK_TYPE_META, value);
617
+ const BlockTypeDropdown = ({ editor, blockType }) => {
618
+ const savedSelectionRef = useRef(null);
619
+ const currentMeta = isBlockType(blockType) ? BLOCK_TYPE_META[blockType] : null;
620
+ const CurrentBlockIcon = currentMeta?.icon ?? Type;
621
+ const handleOpenChange = (open) => {
622
+ if (open) editor.getEditorState().read(() => {
623
+ const selection = $getSelection();
624
+ savedSelectionRef.current = selection ? selection.clone() : null;
625
+ });
626
+ };
627
+ const handleSelect = (type) => {
628
+ editor.update(() => {
629
+ if (savedSelectionRef.current) $setSelection(savedSelectionRef.current);
630
+ const selection = $getSelection();
631
+ if (!$isRangeSelection(selection)) return;
632
+ if (type === "bullet") {
633
+ editor.dispatchCommand(INSERT_UNORDERED_LIST_COMMAND, void 0);
634
+ return;
635
+ }
636
+ if (type === "number") {
637
+ editor.dispatchCommand(INSERT_ORDERED_LIST_COMMAND, void 0);
638
+ return;
639
+ }
640
+ const anchorNode = selection.anchor.getNode();
641
+ const element = $getNearestBlockElementAncestorOrThrow(anchorNode);
642
+ const newNode = type === "h1" || type === "h2" || type === "h3" ? $createHeadingNode(type) : type === "quote" ? $createQuoteNode() : type === "code" ? $createCodeNode() : $createParagraphNode();
643
+ element.getChildren().forEach((child) => newNode.append(child));
644
+ element.replace(newNode);
645
+ });
646
+ };
647
+ return /* @__PURE__ */ jsxs(DropdownMenu, {
648
+ onOpenChange: handleOpenChange,
649
+ children: [/* @__PURE__ */ jsx(Tooltip, {
650
+ tooltip: "Change block type",
651
+ placement: "top",
652
+ triggerAsChild: true,
653
+ children: /* @__PURE__ */ jsx(DropdownMenu.Trigger, {
654
+ asChild: true,
655
+ children: /* @__PURE__ */ jsxs("button", {
656
+ type: "button",
657
+ className: cn("tw:flex tw:h-7 tw:cursor-pointer tw:items-center tw:gap-1.5 tw:rounded tw:border-0 tw:bg-transparent tw:px-1.5 tw:text-xs tw:text-muted-foreground", "tw:hover:bg-accent"),
658
+ children: [
659
+ /* @__PURE__ */ jsx(CurrentBlockIcon, { className: "tw:size-4" }),
660
+ currentMeta?.label ?? "Normal",
661
+ /* @__PURE__ */ jsx(ChevronDown, { className: "tw:size-3" })
662
+ ]
663
+ })
664
+ })
665
+ }), /* @__PURE__ */ jsx(DropdownMenu.Content, {
666
+ align: "start",
667
+ className: "tw:min-w-40",
668
+ children: BLOCK_TYPE_OPTIONS.map(({ value, label, icon: IconComp }) => /* @__PURE__ */ jsxs(DropdownMenu.Item, {
669
+ onSelect: () => handleSelect(value),
670
+ className: cn("tw:flex tw:items-center tw:gap-2", blockType === value && "tw:bg-secondary-50 tw:text-secondary-500"),
671
+ children: [/* @__PURE__ */ jsx(IconComp, { className: "tw:size-4" }), label]
672
+ }, value))
673
+ })]
674
+ });
678
675
  };
679
- var ToolbarButton = ({
680
- active,
681
- disabled,
682
- onClick,
683
- tooltip,
684
- children,
685
- className: extraClassName
686
- }) => /* @__PURE__ */ jsx(Tooltip, { tooltip, placement: "top", triggerAsChild: true, children: /* @__PURE__ */ jsx(
687
- "button",
688
- {
689
- type: "button",
690
- disabled,
691
- onClick,
692
- className: cn(
693
- "tw:flex tw:h-7 tw:min-w-7 tw:cursor-pointer tw:items-center tw:justify-center tw:rounded tw:border-0 tw:bg-transparent tw:px-1 tw:text-xs tw:text-muted-foreground",
694
- "tw:hover:bg-accent tw:disabled:cursor-not-allowed tw:disabled:opacity-30",
695
- active && "tw:bg-secondary-100 tw:text-secondary-500",
696
- extraClassName
697
- ),
698
- children
699
- }
700
- ) });
701
- var insertLink = (editor, url, label, savedSelection) => {
702
- editor.update(() => {
703
- $setSelection(savedSelection);
704
- const selection = $getSelection();
705
- if ($isRangeSelection(selection)) {
706
- const selectedText = selection.getTextContent();
707
- if (selectedText && label === selectedText) {
708
- editor.dispatchCommand(TOGGLE_LINK_COMMAND, url);
709
- return;
710
- }
711
- }
712
- const linkNode = $createLinkNode(url);
713
- const textNode = $createTextNode(label || url);
714
- linkNode.append(textNode);
715
- if ($isRangeSelection(selection)) {
716
- selection.insertNodes([linkNode]);
717
- }
718
- });
676
+ //#endregion
677
+ //#region src/blocks/MarkdownEditor/plugins/toolbar/ToolbarButton.tsx
678
+ const ToolbarButton = ({ active, disabled, onClick, tooltip, children, className: extraClassName }) => /* @__PURE__ */ jsx(Tooltip, {
679
+ tooltip,
680
+ placement: "top",
681
+ triggerAsChild: true,
682
+ children: /* @__PURE__ */ jsx("button", {
683
+ type: "button",
684
+ disabled,
685
+ onClick,
686
+ className: cn("tw:flex tw:h-7 tw:min-w-7 tw:cursor-pointer tw:items-center tw:justify-center tw:rounded tw:border-0 tw:bg-transparent tw:px-1 tw:text-xs tw:text-muted-foreground", "tw:hover:bg-accent tw:disabled:cursor-not-allowed tw:disabled:opacity-30", active && "tw:bg-secondary-100 tw:text-secondary-500", extraClassName),
687
+ children
688
+ })
689
+ });
690
+ //#endregion
691
+ //#region src/blocks/MarkdownEditor/plugins/toolbar/LinkPanel.tsx
692
+ const insertLink = (editor, url, label, savedSelection) => {
693
+ editor.update(() => {
694
+ $setSelection(savedSelection);
695
+ const selection = $getSelection();
696
+ if ($isRangeSelection(selection)) {
697
+ const selectedText = selection.getTextContent();
698
+ if (selectedText && label === selectedText) {
699
+ editor.dispatchCommand(TOGGLE_LINK_COMMAND, url);
700
+ return;
701
+ }
702
+ }
703
+ const linkNode = $createLinkNode(url);
704
+ const textNode = $createTextNode(label || url);
705
+ linkNode.append(textNode);
706
+ if ($isRangeSelection(selection)) selection.insertNodes([linkNode]);
707
+ });
719
708
  };
720
- var LinkPanel = ({ editor, isLink }) => {
721
- const [open, setOpen] = useState(false);
722
- const [url, setUrl] = useState("");
723
- const [label, setLabel] = useState("");
724
- const savedSelectionRef = useRef(null);
725
- const panelRef = useRef(null);
726
- const handleOpen = () => {
727
- editor.getEditorState().read(() => {
728
- const selection = $getSelection();
729
- savedSelectionRef.current = selection ? selection.clone() : null;
730
- if ($isRangeSelection(selection)) {
731
- const text = selection.getTextContent();
732
- if (text) setLabel(text);
733
- }
734
- });
735
- setOpen(true);
736
- };
737
- const handleClose = () => {
738
- setOpen(false);
739
- setUrl("");
740
- setLabel("");
741
- savedSelectionRef.current = null;
742
- editor.focus();
743
- };
744
- const handleSubmit = () => {
745
- const trimmedUrl = url.trim();
746
- if (!trimmedUrl) return;
747
- insertLink(editor, trimmedUrl, label.trim(), savedSelectionRef.current);
748
- handleClose();
749
- };
750
- const handleKeyDown = (e) => {
751
- if (e.key === "Enter") {
752
- e.preventDefault();
753
- handleSubmit();
754
- }
755
- if (e.key === "Escape") {
756
- e.preventDefault();
757
- handleClose();
758
- }
759
- };
760
- if (isLink) {
761
- return /* @__PURE__ */ jsx(
762
- ToolbarButton,
763
- {
764
- active: true,
765
- onClick: () => editor.dispatchCommand(TOGGLE_LINK_COMMAND, null),
766
- tooltip: "Remove Link",
767
- children: /* @__PURE__ */ jsx(Link, { className: "tw:size-4" })
768
- }
769
- );
770
- }
771
- return /* @__PURE__ */ jsxs("div", { className: "tw:relative", children: [
772
- /* @__PURE__ */ jsx(ToolbarButton, { active: open, onClick: handleOpen, tooltip: "Insert Link", children: /* @__PURE__ */ jsx(Link, { className: "tw:size-4" }) }),
773
- open && /* @__PURE__ */ jsx(
774
- "div",
775
- {
776
- ref: panelRef,
777
- className: "tw:absolute tw:left-0 tw:top-full tw:z-50 tw:mt-1 tw:w-80 tw:rounded-md tw:border tw:border-border tw:bg-popover tw:p-3 tw:text-popover-foreground tw:shadow-lg",
778
- children: /* @__PURE__ */ jsxs("div", { className: "tw:flex tw:flex-col tw:gap-2", children: [
779
- /* @__PURE__ */ jsxs(FormGroup, { children: [
780
- /* @__PURE__ */ jsx(Label, { htmlFor: "link-label", className: "tw:mb-1 tw:text-xs", children: "Label" }),
781
- /* @__PURE__ */ jsx(
782
- TextInput,
783
- {
784
- id: "link-label",
785
- autoFocus: true,
786
- placeholder: "Link text",
787
- value: label,
788
- onValueChange: setLabel,
789
- onKeyDown: handleKeyDown,
790
- variant: "secondary"
791
- }
792
- )
793
- ] }),
794
- /* @__PURE__ */ jsxs(FormGroup, { children: [
795
- /* @__PURE__ */ jsx(Label, { htmlFor: "link-url", className: "tw:mb-1 tw:text-xs", children: "URL" }),
796
- /* @__PURE__ */ jsx(
797
- TextInput,
798
- {
799
- id: "link-url",
800
- placeholder: "https://\u2026",
801
- value: url,
802
- onValueChange: setUrl,
803
- onKeyDown: handleKeyDown,
804
- variant: "secondary"
805
- }
806
- )
807
- ] }),
808
- /* @__PURE__ */ jsxs(ButtonGroup, { children: [
809
- /* @__PURE__ */ jsx(Button, { size: "small", variant: "outline", onClick: handleClose, children: "Cancel" }),
810
- /* @__PURE__ */ jsx(Button, { size: "small", onClick: handleSubmit, disabled: !url.trim(), children: "Add link" })
811
- ] })
812
- ] })
813
- }
814
- )
815
- ] });
709
+ const LinkPanel = ({ editor, isLink }) => {
710
+ const [open, setOpen] = useState(false);
711
+ const [url, setUrl] = useState("");
712
+ const [label, setLabel] = useState("");
713
+ const savedSelectionRef = useRef(null);
714
+ const panelRef = useRef(null);
715
+ const handleOpen = () => {
716
+ editor.getEditorState().read(() => {
717
+ const selection = $getSelection();
718
+ savedSelectionRef.current = selection ? selection.clone() : null;
719
+ if ($isRangeSelection(selection)) {
720
+ const text = selection.getTextContent();
721
+ if (text) setLabel(text);
722
+ }
723
+ });
724
+ setOpen(true);
725
+ };
726
+ const handleClose = () => {
727
+ setOpen(false);
728
+ setUrl("");
729
+ setLabel("");
730
+ savedSelectionRef.current = null;
731
+ editor.focus();
732
+ };
733
+ const handleSubmit = () => {
734
+ const trimmedUrl = url.trim();
735
+ if (!trimmedUrl) return;
736
+ insertLink(editor, trimmedUrl, label.trim(), savedSelectionRef.current);
737
+ handleClose();
738
+ };
739
+ const handleKeyDown = (e) => {
740
+ if (e.key === "Enter") {
741
+ e.preventDefault();
742
+ handleSubmit();
743
+ }
744
+ if (e.key === "Escape") {
745
+ e.preventDefault();
746
+ handleClose();
747
+ }
748
+ };
749
+ if (isLink) return /* @__PURE__ */ jsx(ToolbarButton, {
750
+ active: true,
751
+ onClick: () => editor.dispatchCommand(TOGGLE_LINK_COMMAND, null),
752
+ tooltip: "Remove Link",
753
+ children: /* @__PURE__ */ jsx(Link, { className: "tw:size-4" })
754
+ });
755
+ return /* @__PURE__ */ jsxs("div", {
756
+ className: "tw:relative",
757
+ children: [/* @__PURE__ */ jsx(ToolbarButton, {
758
+ active: open,
759
+ onClick: handleOpen,
760
+ tooltip: "Insert Link",
761
+ children: /* @__PURE__ */ jsx(Link, { className: "tw:size-4" })
762
+ }), open && /* @__PURE__ */ jsx("div", {
763
+ ref: panelRef,
764
+ className: "tw:absolute tw:left-0 tw:top-full tw:z-50 tw:mt-1 tw:w-80 tw:rounded-md tw:border tw:border-border tw:bg-popover tw:p-3 tw:text-popover-foreground tw:shadow-lg",
765
+ children: /* @__PURE__ */ jsxs("div", {
766
+ className: "tw:flex tw:flex-col tw:gap-2",
767
+ children: [
768
+ /* @__PURE__ */ jsxs(FormGroup, { children: [/* @__PURE__ */ jsx(Label, {
769
+ htmlFor: "link-label",
770
+ className: "tw:mb-1 tw:text-xs",
771
+ children: "Label"
772
+ }), /* @__PURE__ */ jsx(TextInput, {
773
+ id: "link-label",
774
+ autoFocus: true,
775
+ placeholder: "Link text",
776
+ value: label,
777
+ onValueChange: setLabel,
778
+ onKeyDown: handleKeyDown,
779
+ variant: "secondary"
780
+ })] }),
781
+ /* @__PURE__ */ jsxs(FormGroup, { children: [/* @__PURE__ */ jsx(Label, {
782
+ htmlFor: "link-url",
783
+ className: "tw:mb-1 tw:text-xs",
784
+ children: "URL"
785
+ }), /* @__PURE__ */ jsx(TextInput, {
786
+ id: "link-url",
787
+ placeholder: "https://…",
788
+ value: url,
789
+ onValueChange: setUrl,
790
+ onKeyDown: handleKeyDown,
791
+ variant: "secondary"
792
+ })] }),
793
+ /* @__PURE__ */ jsxs(ButtonGroup, { children: [/* @__PURE__ */ jsx(Button, {
794
+ size: "small",
795
+ variant: "outline",
796
+ onClick: handleClose,
797
+ children: "Cancel"
798
+ }), /* @__PURE__ */ jsx(Button, {
799
+ size: "small",
800
+ onClick: handleSubmit,
801
+ disabled: !url.trim(),
802
+ children: "Add link"
803
+ })] })
804
+ ]
805
+ })
806
+ })]
807
+ });
816
808
  };
817
- var ToolbarDivider = () => /* @__PURE__ */ jsx("div", { className: "tw:mx-0.5 tw:h-5 tw:w-px tw:bg-border" });
818
- var ELEMENT_FORMAT_TYPES = ["left", "center", "right", "justify", "start", "end", ""];
819
- var isElementFormatType = (value) => ELEMENT_FORMAT_TYPES.includes(value);
820
- var toElementFormatType = (value) => isElementFormatType(value) ? value : "left";
821
- var ToolbarPlugin = () => {
822
- const [editor] = useLexicalComposerContext();
823
- const [isBold, setIsBold] = useState(false);
824
- const [isItalic, setIsItalic] = useState(false);
825
- const [isUnderline, setIsUnderline] = useState(false);
826
- const [isStrikethrough, setIsStrikethrough] = useState(false);
827
- const [isCode, setIsCode] = useState(false);
828
- const [isLink, setIsLink] = useState(false);
829
- const [blockType, setBlockType] = useState("paragraph");
830
- const [alignment, setAlignment] = useState("left");
831
- const [isVisible, setIsVisible] = useState(false);
832
- const [position, setPosition] = useState(null);
833
- const toolbarRef = useRef(null);
834
- const isMouseDownRef = useRef(false);
835
- const hasSelectionRef = useRef(false);
836
- const updatePosition = useCallback(() => {
837
- const nativeSelection = window.getSelection();
838
- if (!nativeSelection || nativeSelection.rangeCount === 0) return;
839
- const range = nativeSelection.getRangeAt(0);
840
- const rect = range.getBoundingClientRect();
841
- if (rect.width > 0) {
842
- const toolbarWidth = toolbarRef.current?.offsetWidth ?? 300;
843
- setPosition({
844
- top: rect.top + window.scrollY - 8,
845
- left: Math.max(8, rect.left + window.scrollX + rect.width / 2 - toolbarWidth / 2)
846
- });
847
- }
848
- }, []);
849
- useEffect(() => {
850
- const handleMouseDown = () => {
851
- isMouseDownRef.current = true;
852
- };
853
- const handleMouseUp = () => {
854
- isMouseDownRef.current = false;
855
- if (hasSelectionRef.current) {
856
- setIsVisible(true);
857
- }
858
- };
859
- document.addEventListener("mousedown", handleMouseDown);
860
- document.addEventListener("mouseup", handleMouseUp);
861
- return () => {
862
- document.removeEventListener("mousedown", handleMouseDown);
863
- document.removeEventListener("mouseup", handleMouseUp);
864
- };
865
- }, []);
866
- const updateToolbar = useCallback(() => {
867
- const selection = $getSelection();
868
- if (!$isRangeSelection(selection)) {
869
- hasSelectionRef.current = false;
870
- setIsVisible(false);
871
- return;
872
- }
873
- const hasSelection = !selection.isCollapsed() && selection.getTextContent().length > 0;
874
- hasSelectionRef.current = hasSelection;
875
- if (!hasSelection) {
876
- setIsVisible(false);
877
- } else if (!isMouseDownRef.current) {
878
- setIsVisible(true);
879
- }
880
- if (hasSelection) {
881
- updatePosition();
882
- }
883
- setIsBold(selection.hasFormat("bold"));
884
- setIsItalic(selection.hasFormat("italic"));
885
- setIsUnderline(selection.hasFormat("underline"));
886
- setIsStrikethrough(selection.hasFormat("strikethrough"));
887
- setIsCode(selection.hasFormat("code"));
888
- const node = selection.anchor.getNode();
889
- const parent = node.getParent();
890
- setIsLink($isLinkNode(parent) || $isLinkNode(node));
891
- const blockElement = $getNearestBlockElementAncestorOrThrow(node);
892
- if ($isListNode(blockElement)) {
893
- const listType = blockElement.getListType();
894
- setBlockType(listType === "number" ? "number" : "bullet");
895
- } else if ($isHeadingNode(blockElement)) {
896
- setBlockType(blockElement.getTag());
897
- } else if ($isCodeNode(blockElement)) {
898
- setBlockType("code");
899
- } else if ($isQuoteNode(blockElement)) {
900
- setBlockType("quote");
901
- } else {
902
- setBlockType("paragraph");
903
- }
904
- setAlignment(toElementFormatType(blockElement.getFormatType()));
905
- }, [updatePosition]);
906
- useEffect(() => {
907
- const unregisterUpdate = editor.registerUpdateListener(({ editorState }) => {
908
- editorState.read(() => {
909
- updateToolbar();
910
- });
911
- });
912
- return () => {
913
- unregisterUpdate();
914
- };
915
- }, [editor, updateToolbar]);
916
- if (!isVisible || !position) return null;
917
- return createPortal(
918
- /* @__PURE__ */ jsxs(
919
- "div",
920
- {
921
- ref: toolbarRef,
922
- role: "toolbar",
923
- "aria-label": "Formatting options",
924
- onMouseDown: (e) => e.preventDefault(),
925
- style: { top: position.top, left: position.left },
926
- className: "tw:absolute tw:z-[1060] tw:flex tw:-translate-y-full tw:items-center tw:gap-0.5 tw:rounded-lg tw:border tw:border-border tw:bg-popover tw:px-1.5 tw:py-1 tw:text-popover-foreground tw:shadow-lg",
927
- children: [
928
- /* @__PURE__ */ jsx(BlockTypeDropdown, { editor, blockType }),
929
- /* @__PURE__ */ jsx(ToolbarDivider, {}),
930
- /* @__PURE__ */ jsx(
931
- ToolbarButton,
932
- {
933
- active: isBold,
934
- onClick: () => editor.dispatchCommand(FORMAT_TEXT_COMMAND, "bold"),
935
- tooltip: "Bold (Ctrl+B)",
936
- children: /* @__PURE__ */ jsx(Bold, { className: "tw:size-4" })
937
- }
938
- ),
939
- /* @__PURE__ */ jsx(
940
- ToolbarButton,
941
- {
942
- active: isItalic,
943
- onClick: () => editor.dispatchCommand(FORMAT_TEXT_COMMAND, "italic"),
944
- tooltip: "Italic (Ctrl+I)",
945
- children: /* @__PURE__ */ jsx(Italic, { className: "tw:size-4" })
946
- }
947
- ),
948
- /* @__PURE__ */ jsx(
949
- ToolbarButton,
950
- {
951
- active: isUnderline,
952
- onClick: () => editor.dispatchCommand(FORMAT_TEXT_COMMAND, "underline"),
953
- tooltip: "Underline (Ctrl+U)",
954
- children: /* @__PURE__ */ jsx(Underline, { className: "tw:size-4" })
955
- }
956
- ),
957
- /* @__PURE__ */ jsx(
958
- ToolbarButton,
959
- {
960
- active: isStrikethrough,
961
- onClick: () => editor.dispatchCommand(FORMAT_TEXT_COMMAND, "strikethrough"),
962
- tooltip: "Strikethrough",
963
- children: /* @__PURE__ */ jsx(Strikethrough, { className: "tw:size-4" })
964
- }
965
- ),
966
- /* @__PURE__ */ jsx(
967
- ToolbarButton,
968
- {
969
- active: isCode,
970
- onClick: () => editor.dispatchCommand(FORMAT_TEXT_COMMAND, "code"),
971
- tooltip: "Inline Code",
972
- children: /* @__PURE__ */ jsx(Code, { className: "tw:size-4" })
973
- }
974
- ),
975
- /* @__PURE__ */ jsx(ToolbarDivider, {}),
976
- /* @__PURE__ */ jsx(LinkPanel, { editor, isLink }),
977
- /* @__PURE__ */ jsx(ToolbarDivider, {}),
978
- /* @__PURE__ */ jsx(
979
- ToolbarButton,
980
- {
981
- active: blockType === "bullet",
982
- onClick: () => {
983
- if (blockType === "bullet") {
984
- editor.dispatchCommand(REMOVE_LIST_COMMAND, void 0);
985
- } else {
986
- editor.dispatchCommand(INSERT_UNORDERED_LIST_COMMAND, void 0);
987
- }
988
- },
989
- tooltip: "Bullet List",
990
- children: /* @__PURE__ */ jsx(List, { className: "tw:size-4" })
991
- }
992
- ),
993
- /* @__PURE__ */ jsx(
994
- ToolbarButton,
995
- {
996
- active: blockType === "number",
997
- onClick: () => {
998
- if (blockType === "number") {
999
- editor.dispatchCommand(REMOVE_LIST_COMMAND, void 0);
1000
- } else {
1001
- editor.dispatchCommand(INSERT_ORDERED_LIST_COMMAND, void 0);
1002
- }
1003
- },
1004
- tooltip: "Numbered List",
1005
- children: /* @__PURE__ */ jsx(ListOrdered, { className: "tw:size-4" })
1006
- }
1007
- ),
1008
- /* @__PURE__ */ jsx(ToolbarDivider, {}),
1009
- /* @__PURE__ */ jsx(AlignmentDropdown, { editor, alignment }),
1010
- /* @__PURE__ */ jsx(ToolbarDivider, {}),
1011
- /* @__PURE__ */ jsx(
1012
- ToolbarButton,
1013
- {
1014
- active: blockType === "quote",
1015
- onClick: () => {
1016
- editor.update(() => {
1017
- const selection = $getSelection();
1018
- if (!$isRangeSelection(selection)) return;
1019
- const anchorNode = selection.anchor.getNode();
1020
- const element = $getNearestBlockElementAncestorOrThrow(anchorNode);
1021
- const newNode = blockType === "quote" ? $createParagraphNode() : $createQuoteNode();
1022
- element.getChildren().forEach((child) => newNode.append(child));
1023
- element.replace(newNode);
1024
- });
1025
- },
1026
- tooltip: "Quote",
1027
- children: /* @__PURE__ */ jsx(Quote, { className: "tw:size-4" })
1028
- }
1029
- ),
1030
- /* @__PURE__ */ jsx(
1031
- ToolbarButton,
1032
- {
1033
- active: blockType === "code",
1034
- onClick: () => {
1035
- editor.update(() => {
1036
- const selection = $getSelection();
1037
- if (!$isRangeSelection(selection)) return;
1038
- const anchorNode = selection.anchor.getNode();
1039
- const element = $getNearestBlockElementAncestorOrThrow(anchorNode);
1040
- const newNode = blockType === "code" ? $createParagraphNode() : $createCodeNode();
1041
- element.getChildren().forEach((child) => newNode.append(child));
1042
- element.replace(newNode);
1043
- });
1044
- },
1045
- tooltip: "Code Block",
1046
- children: /* @__PURE__ */ jsx(SquareCode, { className: "tw:size-4" })
1047
- }
1048
- )
1049
- ]
1050
- }
1051
- ),
1052
- document.body
1053
- );
809
+ //#endregion
810
+ //#region src/blocks/MarkdownEditor/plugins/toolbar/ToolbarDivider.tsx
811
+ const ToolbarDivider = () => /* @__PURE__ */ jsx("div", { className: "tw:mx-0.5 tw:h-5 tw:w-px tw:bg-border" });
812
+ //#endregion
813
+ //#region src/blocks/MarkdownEditor/plugins/ToolbarPlugin.tsx
814
+ const ELEMENT_FORMAT_TYPES = [
815
+ "left",
816
+ "center",
817
+ "right",
818
+ "justify",
819
+ "start",
820
+ "end",
821
+ ""
822
+ ];
823
+ const isElementFormatType = (value) => ELEMENT_FORMAT_TYPES.includes(value);
824
+ const toElementFormatType = (value) => isElementFormatType(value) ? value : "left";
825
+ const ToolbarPlugin = () => {
826
+ const [editor] = useLexicalComposerContext();
827
+ const [isBold, setIsBold] = useState(false);
828
+ const [isItalic, setIsItalic] = useState(false);
829
+ const [isUnderline, setIsUnderline] = useState(false);
830
+ const [isStrikethrough, setIsStrikethrough] = useState(false);
831
+ const [isCode, setIsCode] = useState(false);
832
+ const [isLink, setIsLink] = useState(false);
833
+ const [blockType, setBlockType] = useState("paragraph");
834
+ const [alignment, setAlignment] = useState("left");
835
+ const [isVisible, setIsVisible] = useState(false);
836
+ const [position, setPosition] = useState(null);
837
+ const toolbarRef = useRef(null);
838
+ const isMouseDownRef = useRef(false);
839
+ const hasSelectionRef = useRef(false);
840
+ const updatePosition = useCallback(() => {
841
+ const nativeSelection = window.getSelection();
842
+ if (!nativeSelection || nativeSelection.rangeCount === 0) return;
843
+ const rect = nativeSelection.getRangeAt(0).getBoundingClientRect();
844
+ if (rect.width > 0) {
845
+ const toolbarWidth = toolbarRef.current?.offsetWidth ?? 300;
846
+ setPosition({
847
+ top: rect.top + window.scrollY - 8,
848
+ left: Math.max(8, rect.left + window.scrollX + rect.width / 2 - toolbarWidth / 2)
849
+ });
850
+ }
851
+ }, []);
852
+ useEffect(() => {
853
+ const handleMouseDown = () => {
854
+ isMouseDownRef.current = true;
855
+ };
856
+ const handleMouseUp = () => {
857
+ isMouseDownRef.current = false;
858
+ if (hasSelectionRef.current) setIsVisible(true);
859
+ };
860
+ document.addEventListener("mousedown", handleMouseDown);
861
+ document.addEventListener("mouseup", handleMouseUp);
862
+ return () => {
863
+ document.removeEventListener("mousedown", handleMouseDown);
864
+ document.removeEventListener("mouseup", handleMouseUp);
865
+ };
866
+ }, []);
867
+ const updateToolbar = useCallback(() => {
868
+ const selection = $getSelection();
869
+ if (!$isRangeSelection(selection)) {
870
+ hasSelectionRef.current = false;
871
+ setIsVisible(false);
872
+ return;
873
+ }
874
+ const hasSelection = !selection.isCollapsed() && selection.getTextContent().length > 0;
875
+ hasSelectionRef.current = hasSelection;
876
+ if (!hasSelection) setIsVisible(false);
877
+ else if (!isMouseDownRef.current) setIsVisible(true);
878
+ if (hasSelection) updatePosition();
879
+ setIsBold(selection.hasFormat("bold"));
880
+ setIsItalic(selection.hasFormat("italic"));
881
+ setIsUnderline(selection.hasFormat("underline"));
882
+ setIsStrikethrough(selection.hasFormat("strikethrough"));
883
+ setIsCode(selection.hasFormat("code"));
884
+ const node = selection.anchor.getNode();
885
+ const parent = node.getParent();
886
+ setIsLink($isLinkNode(parent) || $isLinkNode(node));
887
+ const blockElement = $getNearestBlockElementAncestorOrThrow(node);
888
+ if ($isListNode(blockElement)) {
889
+ const listType = blockElement.getListType();
890
+ setBlockType(listType === "number" ? "number" : "bullet");
891
+ } else if ($isHeadingNode(blockElement)) setBlockType(blockElement.getTag());
892
+ else if ($isCodeNode(blockElement)) setBlockType("code");
893
+ else if ($isQuoteNode(blockElement)) setBlockType("quote");
894
+ else setBlockType("paragraph");
895
+ setAlignment(toElementFormatType(blockElement.getFormatType()));
896
+ }, [updatePosition]);
897
+ useEffect(() => {
898
+ const unregisterUpdate = editor.registerUpdateListener(({ editorState }) => {
899
+ editorState.read(() => {
900
+ updateToolbar();
901
+ });
902
+ });
903
+ return () => {
904
+ unregisterUpdate();
905
+ };
906
+ }, [editor, updateToolbar]);
907
+ if (!isVisible || !position) return null;
908
+ return createPortal(/* @__PURE__ */ jsxs("div", {
909
+ ref: toolbarRef,
910
+ role: "toolbar",
911
+ "aria-label": "Formatting options",
912
+ onMouseDown: (e) => e.preventDefault(),
913
+ style: {
914
+ top: position.top,
915
+ left: position.left
916
+ },
917
+ className: "tw:absolute tw:z-[1060] tw:flex tw:-translate-y-full tw:items-center tw:gap-0.5 tw:rounded-lg tw:border tw:border-border tw:bg-popover tw:px-1.5 tw:py-1 tw:text-popover-foreground tw:shadow-lg",
918
+ children: [
919
+ /* @__PURE__ */ jsx(BlockTypeDropdown, {
920
+ editor,
921
+ blockType
922
+ }),
923
+ /* @__PURE__ */ jsx(ToolbarDivider, {}),
924
+ /* @__PURE__ */ jsx(ToolbarButton, {
925
+ active: isBold,
926
+ onClick: () => editor.dispatchCommand(FORMAT_TEXT_COMMAND, "bold"),
927
+ tooltip: "Bold (Ctrl+B)",
928
+ children: /* @__PURE__ */ jsx(Bold, { className: "tw:size-4" })
929
+ }),
930
+ /* @__PURE__ */ jsx(ToolbarButton, {
931
+ active: isItalic,
932
+ onClick: () => editor.dispatchCommand(FORMAT_TEXT_COMMAND, "italic"),
933
+ tooltip: "Italic (Ctrl+I)",
934
+ children: /* @__PURE__ */ jsx(Italic, { className: "tw:size-4" })
935
+ }),
936
+ /* @__PURE__ */ jsx(ToolbarButton, {
937
+ active: isUnderline,
938
+ onClick: () => editor.dispatchCommand(FORMAT_TEXT_COMMAND, "underline"),
939
+ tooltip: "Underline (Ctrl+U)",
940
+ children: /* @__PURE__ */ jsx(Underline, { className: "tw:size-4" })
941
+ }),
942
+ /* @__PURE__ */ jsx(ToolbarButton, {
943
+ active: isStrikethrough,
944
+ onClick: () => editor.dispatchCommand(FORMAT_TEXT_COMMAND, "strikethrough"),
945
+ tooltip: "Strikethrough",
946
+ children: /* @__PURE__ */ jsx(Strikethrough, { className: "tw:size-4" })
947
+ }),
948
+ /* @__PURE__ */ jsx(ToolbarButton, {
949
+ active: isCode,
950
+ onClick: () => editor.dispatchCommand(FORMAT_TEXT_COMMAND, "code"),
951
+ tooltip: "Inline Code",
952
+ children: /* @__PURE__ */ jsx(Code, { className: "tw:size-4" })
953
+ }),
954
+ /* @__PURE__ */ jsx(ToolbarDivider, {}),
955
+ /* @__PURE__ */ jsx(LinkPanel, {
956
+ editor,
957
+ isLink
958
+ }),
959
+ /* @__PURE__ */ jsx(ToolbarDivider, {}),
960
+ /* @__PURE__ */ jsx(ToolbarButton, {
961
+ active: blockType === "bullet",
962
+ onClick: () => {
963
+ if (blockType === "bullet") editor.dispatchCommand(REMOVE_LIST_COMMAND, void 0);
964
+ else editor.dispatchCommand(INSERT_UNORDERED_LIST_COMMAND, void 0);
965
+ },
966
+ tooltip: "Bullet List",
967
+ children: /* @__PURE__ */ jsx(List, { className: "tw:size-4" })
968
+ }),
969
+ /* @__PURE__ */ jsx(ToolbarButton, {
970
+ active: blockType === "number",
971
+ onClick: () => {
972
+ if (blockType === "number") editor.dispatchCommand(REMOVE_LIST_COMMAND, void 0);
973
+ else editor.dispatchCommand(INSERT_ORDERED_LIST_COMMAND, void 0);
974
+ },
975
+ tooltip: "Numbered List",
976
+ children: /* @__PURE__ */ jsx(ListOrdered, { className: "tw:size-4" })
977
+ }),
978
+ /* @__PURE__ */ jsx(ToolbarDivider, {}),
979
+ /* @__PURE__ */ jsx(AlignmentDropdown, {
980
+ editor,
981
+ alignment
982
+ }),
983
+ /* @__PURE__ */ jsx(ToolbarDivider, {}),
984
+ /* @__PURE__ */ jsx(ToolbarButton, {
985
+ active: blockType === "quote",
986
+ onClick: () => {
987
+ editor.update(() => {
988
+ const selection = $getSelection();
989
+ if (!$isRangeSelection(selection)) return;
990
+ const anchorNode = selection.anchor.getNode();
991
+ const element = $getNearestBlockElementAncestorOrThrow(anchorNode);
992
+ const newNode = blockType === "quote" ? $createParagraphNode() : $createQuoteNode();
993
+ element.getChildren().forEach((child) => newNode.append(child));
994
+ element.replace(newNode);
995
+ });
996
+ },
997
+ tooltip: "Quote",
998
+ children: /* @__PURE__ */ jsx(Quote, { className: "tw:size-4" })
999
+ }),
1000
+ /* @__PURE__ */ jsx(ToolbarButton, {
1001
+ active: blockType === "code",
1002
+ onClick: () => {
1003
+ editor.update(() => {
1004
+ const selection = $getSelection();
1005
+ if (!$isRangeSelection(selection)) return;
1006
+ const anchorNode = selection.anchor.getNode();
1007
+ const element = $getNearestBlockElementAncestorOrThrow(anchorNode);
1008
+ const newNode = blockType === "code" ? $createParagraphNode() : $createCodeNode();
1009
+ element.getChildren().forEach((child) => newNode.append(child));
1010
+ element.replace(newNode);
1011
+ });
1012
+ },
1013
+ tooltip: "Code Block",
1014
+ children: /* @__PURE__ */ jsx(SquareCode, { className: "tw:size-4" })
1015
+ })
1016
+ ]
1017
+ }), document.body);
1054
1018
  };
1055
-
1056
- // src/blocks/MarkdownEditor/theme.ts
1057
- var editorTheme = {
1058
- link: "tw:cursor-pointer tw:!text-primary tw:underline",
1059
- text: {
1060
- bold: "tw:font-bold",
1061
- italic: "tw:italic",
1062
- strikethrough: "tw:line-through",
1063
- underline: "tw:underline",
1064
- code: "tw:rounded tw:bg-muted tw:px-1 tw:py-0.5 tw:font-mono tw:text-[0.85em]"
1065
- },
1066
- list: {
1067
- ol: "tw:!list-decimal",
1068
- ul: "tw:!list-disc",
1069
- checklist: "tw:!list-none tw:!pl-0",
1070
- listitemChecked: [
1071
- "tw:relative tw:!pl-6 tw:list-none tw:outline-hidden tw:line-through tw:text-muted-foreground",
1072
- 'tw:before:content-[""] tw:before:absolute tw:before:left-0 tw:before:top-[3px]',
1073
- "tw:before:size-4 tw:before:rounded tw:before:border tw:before:border-solid",
1074
- "tw:before:bg-primary tw:before:border-primary tw:before:cursor-pointer",
1075
- 'tw:after:content-[""] tw:after:absolute tw:after:left-[5.5px] tw:after:top-[5.5px]',
1076
- "tw:after:w-1 tw:after:h-2 tw:after:border-primary-foreground tw:after:border-solid",
1077
- "tw:after:border-r-[1.5px] tw:after:border-b-[1.5px] tw:after:border-t-0 tw:after:border-l-0",
1078
- "tw:after:rotate-45"
1079
- ].join(" "),
1080
- listitemUnchecked: [
1081
- "tw:relative tw:!pl-6 tw:list-none tw:outline-hidden",
1082
- 'tw:before:content-[""] tw:before:absolute tw:before:left-0 tw:before:top-[3px]',
1083
- "tw:before:size-4 tw:before:rounded tw:before:border tw:before:border-solid",
1084
- "tw:before:border-input tw:before:bg-background tw:before:cursor-pointer"
1085
- ].join(" ")
1086
- }
1019
+ //#endregion
1020
+ //#region src/blocks/MarkdownEditor/theme.ts
1021
+ /**
1022
+ * Lexical editor theme — maps node types to CSS classes.
1023
+ * The editor container uses `tw:prose` so semantic elements (headings, lists, blockquotes, etc.)
1024
+ * are styled by Tailwind Typography. We only need explicit classes for text formatting
1025
+ * (bold, italic, etc.) because Lexical renders those as `<span>` elements.
1026
+ */
1027
+ const editorTheme = {
1028
+ link: "tw:cursor-pointer tw:!text-primary tw:underline",
1029
+ text: {
1030
+ bold: "tw:font-bold",
1031
+ italic: "tw:italic",
1032
+ strikethrough: "tw:line-through",
1033
+ underline: "tw:underline",
1034
+ code: "tw:rounded tw:bg-muted tw:px-1 tw:py-0.5 tw:font-mono tw:text-[0.85em]"
1035
+ },
1036
+ list: {
1037
+ ol: "tw:!list-decimal",
1038
+ ul: "tw:!list-disc",
1039
+ checklist: "tw:!list-none tw:!pl-0",
1040
+ listitemChecked: [
1041
+ "tw:relative tw:!pl-6 tw:list-none tw:outline-hidden tw:line-through tw:text-muted-foreground",
1042
+ "tw:before:content-[\"\"] tw:before:absolute tw:before:left-0 tw:before:top-[3px]",
1043
+ "tw:before:size-4 tw:before:rounded tw:before:border tw:before:border-solid",
1044
+ "tw:before:bg-primary tw:before:border-primary tw:before:cursor-pointer",
1045
+ "tw:after:content-[\"\"] tw:after:absolute tw:after:left-[5.5px] tw:after:top-[5.5px]",
1046
+ "tw:after:w-1 tw:after:h-2 tw:after:border-primary-foreground tw:after:border-solid",
1047
+ "tw:after:border-r-[1.5px] tw:after:border-b-[1.5px] tw:after:border-t-0 tw:after:border-l-0",
1048
+ "tw:after:rotate-45"
1049
+ ].join(" "),
1050
+ listitemUnchecked: [
1051
+ "tw:relative tw:!pl-6 tw:list-none tw:outline-hidden",
1052
+ "tw:before:content-[\"\"] tw:before:absolute tw:before:left-0 tw:before:top-[3px]",
1053
+ "tw:before:size-4 tw:before:rounded tw:before:border tw:before:border-solid",
1054
+ "tw:before:border-input tw:before:bg-background tw:before:cursor-pointer"
1055
+ ].join(" ")
1056
+ }
1087
1057
  };
1088
- var EDITOR_NODES = [
1089
- ImageNode,
1090
- MermaidNode,
1091
- HeadingNode,
1092
- QuoteNode,
1093
- ListNode,
1094
- ListItemNode,
1095
- CodeNode,
1096
- LinkNode,
1097
- HorizontalRuleNode
1058
+ //#endregion
1059
+ //#region src/blocks/MarkdownEditor/MarkdownEditor.tsx
1060
+ const EDITOR_NODES = [
1061
+ ImageNode,
1062
+ MermaidNode,
1063
+ HeadingNode,
1064
+ QuoteNode,
1065
+ ListNode,
1066
+ ListItemNode,
1067
+ CodeNode,
1068
+ LinkNode,
1069
+ HorizontalRuleNode
1098
1070
  ];
1099
- var MarkdownEditor = ({
1100
- value,
1101
- onChange,
1102
- readOnly = false,
1103
- placeholder,
1104
- autoFocus = false,
1105
- disabled = false,
1106
- onSave,
1107
- onCancel,
1108
- onImageUpload,
1109
- className,
1110
- imageRenderer,
1111
- showToolbar = false,
1112
- compact = false,
1113
- saveOnBlur = false,
1114
- singleLine = false,
1115
- clampDisplay = false,
1116
- minRows
1117
- }) => {
1118
- const editable = !readOnly && !disabled;
1119
- const transformers = singleLine ? SINGLE_LINE_TRANSFORMERS : CUSTOM_TRANSFORMERS;
1120
- const useDefaultMinHeight = !compact && minRows === void 0;
1121
- const customMinHeight = !compact && minRows !== void 0 ? { minHeight: `${minRows * 1.75}em` } : void 0;
1122
- const [initialConfig] = useState(() => ({
1123
- namespace: "MarkdownEditor",
1124
- theme: editorTheme,
1125
- nodes: EDITOR_NODES,
1126
- onError: (error) => {
1127
- console.error("[MarkdownEditor] uncaught editor error", error);
1128
- },
1129
- editable,
1130
- editorState: () => {
1131
- $convertFromMarkdownString(preprocessMarkdown(value), transformers);
1132
- }
1133
- }));
1134
- const skipBlurSaveRef = useRef(false);
1135
- const handleBlur = saveOnBlur && onSave ? (event) => {
1136
- if (skipBlurSaveRef.current) {
1137
- skipBlurSaveRef.current = false;
1138
- return;
1139
- }
1140
- if (!event.currentTarget.contains(event.relatedTarget)) {
1141
- onSave();
1142
- }
1143
- } : void 0;
1144
- return /* @__PURE__ */ jsx(LexicalComposer, { initialConfig, children: /* @__PURE__ */ jsx(ImageRendererProvider, { value: imageRenderer ?? null, children: /* @__PURE__ */ jsxs(
1145
- "div",
1146
- {
1147
- className: cn(
1148
- !compact && "tw:prose",
1149
- // Compact mode drops `tw:prose`, so Lexical's <p> wrappers fall back to the browser
1150
- // default `margin: 1em 0` — visually huge at heading sizes. Zero them, and use the
1151
- // adjacent-sibling selector for paragraph spacing so single-paragraph blocks (titles,
1152
- // short descriptions) stay tight while multi-paragraph blocks still breathe.
1153
- compact && "tw:[&_p]:m-0 tw:[&_p+p]:mt-2",
1154
- // Display-state clamp: 2 lines, dropped in focus-within so editing expands to full
1155
- // height. line-clamp is self-gating (no effect below 3 lines), so short/empty content
1156
- // renders clean; a CSS fade can't gate on overflow without JS, so it's omitted.
1157
- clampDisplay && "tw:[&:not(:focus-within)]:line-clamp-2",
1158
- className
1159
- ),
1160
- onBlur: handleBlur,
1161
- children: [
1162
- showToolbar && editable && /* @__PURE__ */ jsx(ToolbarPlugin, {}),
1163
- /* @__PURE__ */ jsx(
1164
- "div",
1165
- {
1166
- className: cn(
1167
- "tw:relative tw:rounded-md tw:transition-colors",
1168
- // In compact mode the padding lets the hover bg / focus ring extend past the text,
1169
- // but a matching negative margin shifts the wrapper outward so the text itself stays
1170
- // aligned with the parent's content edge (i.e. with where static text would render).
1171
- compact ? "tw:px-1.5 tw:py-0.5 tw:-mx-1.5 tw:-my-0.5" : "tw:p-2",
1172
- editable && "tw:cursor-text tw:hover:bg-muted tw:focus-within:ring-2 tw:focus-within:ring-ring/40"
1173
- ),
1174
- children: /* @__PURE__ */ jsx(
1175
- RichTextPlugin,
1176
- {
1177
- contentEditable: /* @__PURE__ */ jsx(
1178
- ContentEditable,
1179
- {
1180
- className: cn("tw:outline-hidden", useDefaultMinHeight && "tw:min-h-[100px]"),
1181
- style: customMinHeight,
1182
- "aria-placeholder": placeholder ?? "",
1183
- placeholder: placeholder ? /* @__PURE__ */ jsx(
1184
- "div",
1185
- {
1186
- className: cn(
1187
- "tw:pointer-events-none tw:absolute tw:select-none tw:text-muted-foreground",
1188
- compact ? "tw:left-1.5 tw:top-0.5" : "tw:left-2 tw:top-[calc(0.5rem+0.35em)]"
1189
- ),
1190
- children: placeholder
1191
- }
1192
- ) : /* @__PURE__ */ jsx("div", {})
1193
- }
1194
- ),
1195
- ErrorBoundary: LexicalErrorBoundary
1196
- }
1197
- )
1198
- }
1199
- ),
1200
- /* @__PURE__ */ jsx(HistoryPlugin, {}),
1201
- /* @__PURE__ */ jsx(LinkPlugin, {}),
1202
- /* @__PURE__ */ jsx(ClickableLinkPlugin, { newTab: true }),
1203
- !singleLine && /* @__PURE__ */ jsx(ListPlugin, {}),
1204
- !singleLine && /* @__PURE__ */ jsx(CheckListPlugin, {}),
1205
- !singleLine && /* @__PURE__ */ jsx(HorizontalRulePlugin, {}),
1206
- /* @__PURE__ */ jsx(TabIndentationPlugin, {}),
1207
- /* @__PURE__ */ jsx(MarkdownShortcutPlugin, { transformers }),
1208
- /* @__PURE__ */ jsx(
1209
- MarkdownSyncPlugin,
1210
- {
1211
- value,
1212
- editable,
1213
- onChange,
1214
- transformers,
1215
- singleLine
1216
- }
1217
- ),
1218
- /* @__PURE__ */ jsx(ImagePastePlugin, { onImageUpload }),
1219
- /* @__PURE__ */ jsx(
1220
- KeyboardPlugin,
1221
- {
1222
- onSave,
1223
- onCancel,
1224
- singleLine,
1225
- blurOnEscape: singleLine || saveOnBlur,
1226
- skipBlurSaveRef
1227
- }
1228
- ),
1229
- autoFocus && /* @__PURE__ */ jsx(AutoFocusPlugin, {})
1230
- ]
1231
- }
1232
- ) }) });
1071
+ const MarkdownEditor = ({ value, onChange, readOnly = false, placeholder, autoFocus = false, disabled = false, onSave, onCancel, onImageUpload, className, imageRenderer, showToolbar = false, compact = false, saveOnBlur = false, singleLine = false, clampDisplay = false, minRows }) => {
1072
+ const editable = !readOnly && !disabled;
1073
+ const transformers = singleLine ? SINGLE_LINE_TRANSFORMERS : CUSTOM_TRANSFORMERS;
1074
+ const useDefaultMinHeight = !compact && minRows === void 0;
1075
+ const customMinHeight = !compact && minRows !== void 0 ? { minHeight: `${minRows * 1.75}em` } : void 0;
1076
+ const [initialConfig] = useState(() => ({
1077
+ namespace: "MarkdownEditor",
1078
+ theme: editorTheme,
1079
+ nodes: EDITOR_NODES,
1080
+ onError: (error) => {
1081
+ console.error("[MarkdownEditor] uncaught editor error", error);
1082
+ },
1083
+ editable,
1084
+ editorState: () => {
1085
+ $convertFromMarkdownString(preprocessMarkdown(value), transformers);
1086
+ }
1087
+ }));
1088
+ const skipBlurSaveRef = useRef(false);
1089
+ const handleBlur = saveOnBlur && onSave ? (event) => {
1090
+ if (skipBlurSaveRef.current) {
1091
+ skipBlurSaveRef.current = false;
1092
+ return;
1093
+ }
1094
+ if (!event.currentTarget.contains(event.relatedTarget)) onSave();
1095
+ } : void 0;
1096
+ return /* @__PURE__ */ jsx(LexicalComposer, {
1097
+ initialConfig,
1098
+ children: /* @__PURE__ */ jsx(ImageRendererProvider, {
1099
+ value: imageRenderer ?? null,
1100
+ children: /* @__PURE__ */ jsxs("div", {
1101
+ className: cn(!compact && "tw:prose", compact && "tw:[&_p]:m-0 tw:[&_p+p]:mt-2", clampDisplay && "tw:[&:not(:focus-within)]:line-clamp-2", className),
1102
+ onBlur: handleBlur,
1103
+ children: [
1104
+ showToolbar && editable && /* @__PURE__ */ jsx(ToolbarPlugin, {}),
1105
+ /* @__PURE__ */ jsx("div", {
1106
+ className: cn("tw:relative tw:rounded-md tw:transition-colors", compact ? "tw:px-1.5 tw:py-0.5 tw:-mx-1.5 tw:-my-0.5" : "tw:p-2", editable && "tw:cursor-text tw:hover:bg-muted tw:focus-within:ring-2 tw:focus-within:ring-ring/40"),
1107
+ children: /* @__PURE__ */ jsx(RichTextPlugin, {
1108
+ contentEditable: /* @__PURE__ */ jsx(ContentEditable, {
1109
+ className: cn("tw:outline-hidden", useDefaultMinHeight && "tw:min-h-[100px]"),
1110
+ style: customMinHeight,
1111
+ "aria-placeholder": placeholder ?? "",
1112
+ placeholder: placeholder ? /* @__PURE__ */ jsx("div", {
1113
+ className: cn("tw:pointer-events-none tw:absolute tw:select-none tw:text-muted-foreground", compact ? "tw:left-1.5 tw:top-0.5" : "tw:left-2 tw:top-[calc(0.5rem+0.35em)]"),
1114
+ children: placeholder
1115
+ }) : /* @__PURE__ */ jsx("div", {})
1116
+ }),
1117
+ ErrorBoundary: LexicalErrorBoundary
1118
+ })
1119
+ }),
1120
+ /* @__PURE__ */ jsx(HistoryPlugin, {}),
1121
+ /* @__PURE__ */ jsx(LinkPlugin, {}),
1122
+ /* @__PURE__ */ jsx(ClickableLinkPlugin, { newTab: true }),
1123
+ !singleLine && /* @__PURE__ */ jsx(ListPlugin, {}),
1124
+ !singleLine && /* @__PURE__ */ jsx(CheckListPlugin, {}),
1125
+ !singleLine && /* @__PURE__ */ jsx(HorizontalRulePlugin, {}),
1126
+ /* @__PURE__ */ jsx(TabIndentationPlugin, {}),
1127
+ /* @__PURE__ */ jsx(MarkdownShortcutPlugin, { transformers }),
1128
+ /* @__PURE__ */ jsx(MarkdownSyncPlugin, {
1129
+ value,
1130
+ editable,
1131
+ onChange,
1132
+ transformers,
1133
+ singleLine
1134
+ }),
1135
+ /* @__PURE__ */ jsx(ImagePastePlugin, { onImageUpload }),
1136
+ /* @__PURE__ */ jsx(KeyboardPlugin, {
1137
+ onSave,
1138
+ onCancel,
1139
+ singleLine,
1140
+ blurOnEscape: singleLine || saveOnBlur,
1141
+ skipBlurSaveRef
1142
+ }),
1143
+ autoFocus && /* @__PURE__ */ jsx(AutoFocusPlugin, {})
1144
+ ]
1145
+ })
1146
+ })
1147
+ });
1233
1148
  };
1234
-
1149
+ //#endregion
1235
1150
  export { MarkdownEditor };
1236
- //# sourceMappingURL=markdown-editor.js.map
1151
+
1237
1152
  //# sourceMappingURL=markdown-editor.js.map