@keboola/design 11.0.0 → 11.2.0

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 (670) hide show
  1. package/AGENTS.md +16 -1
  2. package/CHANGELOG.md +2138 -0
  3. package/COMPONENT-API.md +40 -1
  4. package/dist/AIKit-DiS0CVOW.js +1320 -0
  5. package/dist/AIKit-DiS0CVOW.js.map +1 -0
  6. package/dist/Alert-DfZq9kGe.js +133 -0
  7. package/dist/Alert-DfZq9kGe.js.map +1 -0
  8. package/dist/AlertModal-Dp_XuJBW.js +219 -0
  9. package/dist/AlertModal-Dp_XuJBW.js.map +1 -0
  10. package/dist/AppShell-B5GQN6Zs.js +143 -0
  11. package/dist/AppShell-B5GQN6Zs.js.map +1 -0
  12. package/dist/AutoSaveTextarea-BeuWuszr.js +58 -0
  13. package/dist/{chunk-UGT6DKWM.js.map → AutoSaveTextarea-BeuWuszr.js.map} +1 -1
  14. package/dist/Badge-Ch26CXoP.js +195 -0
  15. package/dist/Badge-Ch26CXoP.js.map +1 -0
  16. package/dist/BrandEditor-DyzgfVkl.js +903 -0
  17. package/dist/BrandEditor-DyzgfVkl.js.map +1 -0
  18. package/dist/BrandLogo-CJkRd0F8.js +46 -0
  19. package/dist/BrandLogo-CJkRd0F8.js.map +1 -0
  20. package/dist/Breadcrumb-Frst8MTA.js +330 -0
  21. package/dist/Breadcrumb-Frst8MTA.js.map +1 -0
  22. package/dist/Button-6xBX0nNl.js +391 -0
  23. package/dist/Button-6xBX0nNl.js.map +1 -0
  24. package/dist/Calendar-cG5NIJ4O.js +6768 -0
  25. package/dist/Calendar-cG5NIJ4O.js.map +1 -0
  26. package/dist/Card-BAoZ35CV.js +105 -0
  27. package/dist/Card-BAoZ35CV.js.map +1 -0
  28. package/dist/Checkbox-GJ8-srt4.js +97 -0
  29. package/dist/Checkbox-GJ8-srt4.js.map +1 -0
  30. package/dist/Clipboard-CBJZiviP.js +58 -0
  31. package/dist/Clipboard-CBJZiviP.js.map +1 -0
  32. package/dist/ClipboardButton-ClcluT0C.js +43 -0
  33. package/dist/ClipboardButton-ClcluT0C.js.map +1 -0
  34. package/dist/CodeEditor-DyaN-Ij2.js +1000 -0
  35. package/dist/CodeEditor-DyaN-Ij2.js.map +1 -0
  36. package/dist/Collapsible-BQXWEOBC.js +34 -0
  37. package/dist/Collapsible-BQXWEOBC.js.map +1 -0
  38. package/dist/ColorInput-B8z4j4Y_.js +180 -0
  39. package/dist/ColorInput-B8z4j4Y_.js.map +1 -0
  40. package/dist/ColorModeSwitch-dZFZyqy1.js +77 -0
  41. package/dist/ColorModeSwitch-dZFZyqy1.js.map +1 -0
  42. package/dist/Combobox-Dgm6Z4ib.js +443 -0
  43. package/dist/Combobox-Dgm6Z4ib.js.map +1 -0
  44. package/dist/Command-C0aZfVTq.js +102 -0
  45. package/dist/Command-C0aZfVTq.js.map +1 -0
  46. package/dist/CopyField-BJ96zvXs.js +322 -0
  47. package/dist/CopyField-BJ96zvXs.js.map +1 -0
  48. package/dist/DateInput-B3UdzRfW.js +141 -0
  49. package/dist/DateInput-B3UdzRfW.js.map +1 -0
  50. package/dist/DatePicker-Dw3DpbUh.js +24 -0
  51. package/dist/DatePicker-Dw3DpbUh.js.map +1 -0
  52. package/dist/DateRangeInput-DTuySEiq.js +139 -0
  53. package/dist/DateRangeInput-DTuySEiq.js.map +1 -0
  54. package/dist/DateRangePicker-DCmMHg4s.js +159 -0
  55. package/dist/DateRangePicker-DCmMHg4s.js.map +1 -0
  56. package/dist/DiagramSkeleton-lwBS2YBa.js +11 -0
  57. package/dist/DiagramSkeleton-lwBS2YBa.js.map +1 -0
  58. package/dist/DiffView-ppTIzh2h.js +429 -0
  59. package/dist/DiffView-ppTIzh2h.js.map +1 -0
  60. package/dist/DropdownMenu-t90tVw6l.js +327 -0
  61. package/dist/DropdownMenu-t90tVw6l.js.map +1 -0
  62. package/dist/FieldBox-D7DYtX_m.js +70 -0
  63. package/dist/FieldBox-D7DYtX_m.js.map +1 -0
  64. package/dist/FieldItem-CAPj9lj3.d.ts +111 -0
  65. package/dist/FieldItem-D-h1NeBo.js +108 -0
  66. package/dist/FieldItem-D-h1NeBo.js.map +1 -0
  67. package/dist/FileUpload-BRv0TaZk.js +2527 -0
  68. package/dist/FileUpload-BRv0TaZk.js.map +1 -0
  69. package/dist/Form-DHvcFoEi.js +311 -0
  70. package/dist/Form-DHvcFoEi.js.map +1 -0
  71. package/dist/FormGroup-C41n65cE.js +124 -0
  72. package/dist/FormGroup-C41n65cE.js.map +1 -0
  73. package/dist/FullScreenModal-Cb3PGgh4.js +96 -0
  74. package/dist/FullScreenModal-Cb3PGgh4.js.map +1 -0
  75. package/dist/HoverCard-WfDkLK1s.js +31 -0
  76. package/dist/HoverCard-WfDkLK1s.js.map +1 -0
  77. package/dist/InputGroup-CdTq8H7c.js +292 -0
  78. package/dist/InputGroup-CdTq8H7c.js.map +1 -0
  79. package/dist/Kbd-CxHAo1oo.js +111 -0
  80. package/dist/Kbd-CxHAo1oo.js.map +1 -0
  81. package/dist/MarkedText-Ckbft5mw.js +44 -0
  82. package/dist/MarkedText-Ckbft5mw.js.map +1 -0
  83. package/dist/MermaidDiagram-ChL3WIQT.js +399 -0
  84. package/dist/MermaidDiagram-ChL3WIQT.js.map +1 -0
  85. package/dist/Modal-wqG8nJiK.js +185 -0
  86. package/dist/Modal-wqG8nJiK.js.map +1 -0
  87. package/dist/ModalTitle-C76ke2eo.js +28 -0
  88. package/dist/ModalTitle-C76ke2eo.js.map +1 -0
  89. package/dist/MultiActionButtonGroup-BiIIubiL.js +33 -0
  90. package/dist/MultiActionButtonGroup-BiIIubiL.js.map +1 -0
  91. package/dist/Navbar-BfaPeLUL.js +325 -0
  92. package/dist/Navbar-BfaPeLUL.js.map +1 -0
  93. package/dist/OtpInput-CbbymqYs.js +93 -0
  94. package/dist/OtpInput-CbbymqYs.js.map +1 -0
  95. package/dist/PageHeader-Q3IpCnQd.js +177 -0
  96. package/dist/PageHeader-Q3IpCnQd.js.map +1 -0
  97. package/dist/PageLayout-DSVM-ASz.js +176 -0
  98. package/dist/PageLayout-DSVM-ASz.js.map +1 -0
  99. package/dist/PageToolbar-OQg3mPF-.js +153 -0
  100. package/dist/PageToolbar-OQg3mPF-.js.map +1 -0
  101. package/dist/Pagination-Cjfda8KG.js +70 -0
  102. package/dist/Pagination-Cjfda8KG.js.map +1 -0
  103. package/dist/Popconfirm-D7_vfxFd.js +167 -0
  104. package/dist/Popconfirm-D7_vfxFd.js.map +1 -0
  105. package/dist/Popover-CzeHjvrB.js +85 -0
  106. package/dist/Popover-CzeHjvrB.js.map +1 -0
  107. package/dist/RadioGroup-sIveSsNa.js +233 -0
  108. package/dist/RadioGroup-sIveSsNa.js.map +1 -0
  109. package/dist/Resizable-D3vYToZH.js +52 -0
  110. package/dist/Resizable-D3vYToZH.js.map +1 -0
  111. package/dist/Search-3UiqNZRj.js +184 -0
  112. package/dist/Search-3UiqNZRj.js.map +1 -0
  113. package/dist/SearchInput-C7dF_Ir-.js +102 -0
  114. package/dist/SearchInput-C7dF_Ir-.js.map +1 -0
  115. package/dist/SectionNav-8NoTOKO8.js +276 -0
  116. package/dist/SectionNav-8NoTOKO8.js.map +1 -0
  117. package/dist/Select-Is0VkePH.js +181 -0
  118. package/dist/Select-Is0VkePH.js.map +1 -0
  119. package/dist/Sheet-Dw9BDvjI.js +169 -0
  120. package/dist/Sheet-Dw9BDvjI.js.map +1 -0
  121. package/dist/Sidebar-Dcb4rinA.js +799 -0
  122. package/dist/Sidebar-Dcb4rinA.js.map +1 -0
  123. package/dist/Slider-BOPfMOMm.js +127 -0
  124. package/dist/Slider-BOPfMOMm.js.map +1 -0
  125. package/dist/Stepper-C8sm9ZFM.js +325 -0
  126. package/dist/Stepper-C8sm9ZFM.js.map +1 -0
  127. package/dist/Switch-CX2A0v50.js +201 -0
  128. package/dist/Switch-CX2A0v50.js.map +1 -0
  129. package/dist/Table-CvYuTuNU.js +104 -0
  130. package/dist/Table-CvYuTuNU.js.map +1 -0
  131. package/dist/Tabs-UMQuDoW8.js +74 -0
  132. package/dist/Tabs-UMQuDoW8.js.map +1 -0
  133. package/dist/TextInput-CMuN1WfY.js +110 -0
  134. package/dist/TextInput-CMuN1WfY.js.map +1 -0
  135. package/dist/ThemeProvider-QncUrfJn.js +203 -0
  136. package/dist/ThemeProvider-QncUrfJn.js.map +1 -0
  137. package/dist/TimePicker-D9zktB8A.js +98 -0
  138. package/dist/TimePicker-D9zktB8A.js.map +1 -0
  139. package/dist/Timeline-6btyJl4D.js +154 -0
  140. package/dist/Timeline-6btyJl4D.js.map +1 -0
  141. package/dist/Toast-DQSbs3oA.js +49 -0
  142. package/dist/Toast-DQSbs3oA.js.map +1 -0
  143. package/dist/ToggleGroup-Cy_10Mvu.js +47 -0
  144. package/dist/ToggleGroup-Cy_10Mvu.js.map +1 -0
  145. package/dist/Workbench-BzE-Vvd9.js +293 -0
  146. package/dist/Workbench-BzE-Vvd9.js.map +1 -0
  147. package/dist/ZoomableSvg-CZEu6sAq.js +248 -0
  148. package/dist/ZoomableSvg-CZEu6sAq.js.map +1 -0
  149. package/dist/charts.d.ts +110 -103
  150. package/dist/charts.js +303 -254
  151. package/dist/charts.js.map +1 -1
  152. package/dist/classNames-BzrkDnOD.js +9 -0
  153. package/dist/classNames-BzrkDnOD.js.map +1 -0
  154. package/dist/context-KxxeMHbR.js +62 -0
  155. package/dist/context-KxxeMHbR.js.map +1 -0
  156. package/dist/editors.d.ts +244 -175
  157. package/dist/editors.js +802 -428
  158. package/dist/editors.js.map +1 -1
  159. package/dist/escapeStringRegexp-8MxP2knR.js +6 -0
  160. package/dist/escapeStringRegexp-8MxP2knR.js.map +1 -0
  161. package/dist/icons-Cek151jC.js +640 -0
  162. package/dist/icons-Cek151jC.js.map +1 -0
  163. package/dist/icons.d.ts +2 -41
  164. package/dist/icons.js +2 -9
  165. package/dist/index-m-kQEWiY.d.ts +54 -0
  166. package/dist/index.d.ts +6191 -9891
  167. package/dist/index.js +113 -124
  168. package/dist/internal/blocks/AIKit.js +2 -30
  169. package/dist/internal/blocks/AppShell.js +2 -11
  170. package/dist/internal/blocks/AutoSaveTextarea.js +2 -14
  171. package/dist/internal/blocks/BrandEditor.js +2 -23
  172. package/dist/internal/blocks/ChartPanel.js +45 -9
  173. package/dist/internal/blocks/ChartPanel.js.map +1 -1
  174. package/dist/internal/blocks/ClipboardButton.js +2 -12
  175. package/dist/internal/blocks/ColorInput.js +2 -13
  176. package/dist/internal/blocks/ColorModeSwitch.js +2 -13
  177. package/dist/internal/blocks/Command.js +2 -15
  178. package/dist/internal/blocks/CopyField.js +2 -11
  179. package/dist/internal/blocks/DashboardHero.js +58 -8
  180. package/dist/internal/blocks/DashboardHero.js.map +1 -1
  181. package/dist/internal/blocks/DateInput.js +2 -16
  182. package/dist/internal/blocks/DateRangeInput.js +2 -16
  183. package/dist/internal/blocks/EmptyConfigurationActionCard.js +15 -9
  184. package/dist/internal/blocks/EmptyConfigurationActionCard.js.map +1 -1
  185. package/dist/internal/blocks/EmptyState.js +141 -3
  186. package/dist/internal/blocks/EmptyState.js.map +1 -1
  187. package/dist/internal/blocks/ErrorState.js +178 -4
  188. package/dist/internal/blocks/ErrorState.js.map +1 -1
  189. package/dist/internal/blocks/ExportMenu.js +40 -12
  190. package/dist/internal/blocks/ExportMenu.js.map +1 -1
  191. package/dist/internal/blocks/Form/connectors/MultiComboboxField.js +56 -0
  192. package/dist/internal/blocks/Form/connectors/MultiComboboxField.js.map +1 -0
  193. package/dist/internal/blocks/Form.js +2 -29
  194. package/dist/internal/blocks/FormGroup.js +2 -18
  195. package/dist/internal/blocks/GoogleButton.js +94 -9
  196. package/dist/internal/blocks/GoogleButton.js.map +1 -1
  197. package/dist/internal/blocks/MicrosoftButton.js +63 -9
  198. package/dist/internal/blocks/MicrosoftButton.js.map +1 -1
  199. package/dist/internal/blocks/MultiActionButtonGroup.js +2 -12
  200. package/dist/internal/blocks/MultiCombobox.js +192 -13
  201. package/dist/internal/blocks/MultiCombobox.js.map +1 -1
  202. package/dist/internal/blocks/NumberInput.js +43 -11
  203. package/dist/internal/blocks/NumberInput.js.map +1 -1
  204. package/dist/internal/blocks/OtpInput.js +2 -10
  205. package/dist/internal/blocks/PageHeader.js +2 -9
  206. package/dist/internal/blocks/PageLayout.js +2 -9
  207. package/dist/internal/blocks/PageToolbar.js +2 -13
  208. package/dist/internal/blocks/PasswordInput.js +96 -12
  209. package/dist/internal/blocks/PasswordInput.js.map +1 -1
  210. package/dist/internal/blocks/SearchInput.js +2 -12
  211. package/dist/internal/blocks/SearchInputWithNavigation.js +64 -15
  212. package/dist/internal/blocks/SearchInputWithNavigation.js.map +1 -1
  213. package/dist/internal/blocks/SectionNav.js +2 -15
  214. package/dist/internal/blocks/SplitButton.js +45 -13
  215. package/dist/internal/blocks/SplitButton.js.map +1 -1
  216. package/dist/internal/blocks/StatCard.js +96 -9
  217. package/dist/internal/blocks/StatCard.js.map +1 -1
  218. package/dist/internal/blocks/TextInput.js +2 -13
  219. package/dist/internal/blocks/Textarea.js +31 -12
  220. package/dist/internal/blocks/Textarea.js.map +1 -1
  221. package/dist/internal/blocks/TimeInput.js +76 -16
  222. package/dist/internal/blocks/TimeInput.js.map +1 -1
  223. package/dist/internal/components/Alert.js +2 -11
  224. package/dist/internal/components/AlertModal.js +2 -11
  225. package/dist/internal/components/Avatar.js +52 -8
  226. package/dist/internal/components/Avatar.js.map +1 -1
  227. package/dist/internal/components/Badge.js +2 -9
  228. package/dist/internal/components/BrandLogo.js +2 -11
  229. package/dist/internal/components/Breadcrumb.js +2 -14
  230. package/dist/internal/components/Button.js +2 -10
  231. package/dist/internal/components/ButtonGroup.js +65 -8
  232. package/dist/internal/components/ButtonGroup.js.map +1 -1
  233. package/dist/internal/components/Calendar.js +2 -9
  234. package/dist/internal/components/Card.js +2 -9
  235. package/dist/internal/components/Checkbox.js +2 -11
  236. package/dist/internal/components/Clipboard.js +2 -9
  237. package/dist/internal/components/Collapsible.js +2 -9
  238. package/dist/internal/components/CollapsiblePanel.js +86 -10
  239. package/dist/internal/components/CollapsiblePanel.js.map +1 -1
  240. package/dist/internal/components/Combobox.js +2 -13
  241. package/dist/internal/components/DatePicker.js +2 -11
  242. package/dist/internal/components/DateRangePicker.js +2 -17
  243. package/dist/internal/components/DiffView.js +2 -9
  244. package/dist/internal/components/DotsLoader.js +17 -4
  245. package/dist/internal/components/DotsLoader.js.map +1 -1
  246. package/dist/internal/components/DropdownMenu.js +2 -11
  247. package/dist/internal/components/EmptySearchContent.js +11 -3
  248. package/dist/internal/components/EmptySearchContent.js.map +1 -1
  249. package/dist/internal/components/FileUpload.js +2 -11
  250. package/dist/internal/components/FullScreenModal.js +2 -12
  251. package/dist/internal/components/HelpBlock.js +24 -3
  252. package/dist/internal/components/HelpBlock.js.map +1 -1
  253. package/dist/internal/components/HoverCard.js +2 -9
  254. package/dist/internal/components/InputGroup.js +2 -11
  255. package/dist/internal/components/Kbd.js +2 -9
  256. package/dist/internal/components/Label.js +38 -8
  257. package/dist/internal/components/Label.js.map +1 -1
  258. package/dist/internal/components/Link.js +21 -8
  259. package/dist/internal/components/Link.js.map +1 -1
  260. package/dist/internal/components/MarkedText.js +2 -5
  261. package/dist/internal/components/MergeEditor/ConflictStatus/ConflictStatusIndicator.js +19 -9
  262. package/dist/internal/components/MergeEditor/ConflictStatus/ConflictStatusIndicator.js.map +1 -1
  263. package/dist/internal/components/MergeEditor/PaneHeader.js +12 -3
  264. package/dist/internal/components/MergeEditor/PaneHeader.js.map +1 -1
  265. package/dist/internal/components/MergeEditor/constants.js +17 -3
  266. package/dist/internal/components/MergeEditor/constants.js.map +1 -1
  267. package/dist/internal/components/MergeEditor/useMergeDiff.js +2 -5
  268. package/dist/internal/components/Modal.js +2 -13
  269. package/dist/internal/components/Navbar.js +2 -14
  270. package/dist/internal/components/Pagination.js +2 -11
  271. package/dist/internal/components/PanelWithDetails.js +30 -10
  272. package/dist/internal/components/PanelWithDetails.js.map +1 -1
  273. package/dist/internal/components/Popconfirm.js +2 -12
  274. package/dist/internal/components/Popover.js +2 -9
  275. package/dist/internal/components/Progress.js +46 -8
  276. package/dist/internal/components/Progress.js.map +1 -1
  277. package/dist/internal/components/RadioGroup.js +2 -12
  278. package/dist/internal/components/Resizable.js +2 -9
  279. package/dist/internal/components/ScrollArea.js +41 -8
  280. package/dist/internal/components/ScrollArea.js.map +1 -1
  281. package/dist/internal/components/Search.js +2 -10
  282. package/dist/internal/components/Select.js +2 -12
  283. package/dist/internal/components/Separator.js +83 -8
  284. package/dist/internal/components/Separator.js.map +1 -1
  285. package/dist/internal/components/Sheet.js +2 -12
  286. package/dist/internal/components/Sidebar.js +2 -20
  287. package/dist/internal/components/Skeleton/Skeleton.js +38 -8
  288. package/dist/internal/components/Skeleton/Skeleton.js.map +1 -1
  289. package/dist/internal/components/Skeleton/SkeletonList.js +40 -9
  290. package/dist/internal/components/Skeleton/SkeletonList.js.map +1 -1
  291. package/dist/internal/components/Slider.js +2 -11
  292. package/dist/internal/components/SpotlightBackdrop.js +131 -8
  293. package/dist/internal/components/SpotlightBackdrop.js.map +1 -1
  294. package/dist/internal/components/Stepper.js +2 -10
  295. package/dist/internal/components/Switch.js +2 -10
  296. package/dist/internal/components/Table.js +2 -10
  297. package/dist/internal/components/Tabs.js +2 -12
  298. package/dist/internal/components/ThemeProvider.js +3 -10
  299. package/dist/internal/components/TimePicker.js +2 -12
  300. package/dist/internal/components/Timeline.js +2 -10
  301. package/dist/internal/components/Toast.js +3 -11
  302. package/dist/internal/components/Toggle.js +168 -8
  303. package/dist/internal/components/Toggle.js.map +1 -1
  304. package/dist/internal/components/ToggleGroup.js +2 -9
  305. package/dist/internal/components/Tooltip.js +2 -8
  306. package/dist/internal/components/Truncated.js +44 -8
  307. package/dist/internal/components/Truncated.js.map +1 -1
  308. package/dist/internal/components/Workbench.js +2 -11
  309. package/dist/internal/components/ZoomableSvg.js +2 -13
  310. package/dist/internal/hooks/useAutosizeInput.js +76 -3
  311. package/dist/internal/hooks/useAutosizeInput.js.map +1 -1
  312. package/dist/internal/hooks/useScrollbarPosition.js +44 -4
  313. package/dist/internal/hooks/useScrollbarPosition.js.map +1 -1
  314. package/dist/internal/hooks/useStableCallback.js +28 -3
  315. package/dist/internal/hooks/useStableCallback.js.map +1 -1
  316. package/dist/internal/utils/mergeRefs.js +19 -3
  317. package/dist/internal/utils/mergeRefs.js.map +1 -1
  318. package/dist/internal/utils.js +5 -8
  319. package/dist/markdown-editor.d.ts +72 -72
  320. package/dist/markdown-editor.js +1122 -1207
  321. package/dist/markdown-editor.js.map +1 -1
  322. package/dist/mermaid.d.ts +12 -12
  323. package/dist/mermaid.js +2 -18
  324. package/dist/rjsf.d.ts +45 -34
  325. package/dist/rjsf.js +1601 -1671
  326. package/dist/rjsf.js.map +1 -1
  327. package/dist/rolldown-runtime-Bdc48AWt.js +33 -0
  328. package/dist/styles-DSUP_-9Z.js +158 -0
  329. package/dist/styles-DSUP_-9Z.js.map +1 -0
  330. package/dist/styles.css +1 -1
  331. package/dist/testing.d.ts +8 -7
  332. package/dist/testing.js +36 -21
  333. package/dist/testing.js.map +1 -1
  334. package/dist/themeTokens-BNg98Mu9.js +85 -0
  335. package/dist/themeTokens-BNg98Mu9.js.map +1 -0
  336. package/dist/toast-CjkURw0M.js +184 -0
  337. package/dist/toast-CjkURw0M.js.map +1 -0
  338. package/dist/useColorSchemeState-CYqcUfSH.js +61 -0
  339. package/dist/useColorSchemeState-CYqcUfSH.js.map +1 -0
  340. package/dist/useControllableState-M6494mCT.js +31 -0
  341. package/dist/useControllableState-M6494mCT.js.map +1 -0
  342. package/dist/useElement-DkF6esWL.js +15 -0
  343. package/dist/useElement-DkF6esWL.js.map +1 -0
  344. package/dist/useMergeDiff-CvowEXJ1.js +465 -0
  345. package/dist/useMergeDiff-CvowEXJ1.js.map +1 -0
  346. package/dist/utils-D0c5VAyF.js +308 -0
  347. package/dist/utils-D0c5VAyF.js.map +1 -0
  348. package/package.json +11 -10
  349. package/dist/MermaidDiagram-ZU5KAVRT.js +0 -18
  350. package/dist/MermaidDiagram-ZU5KAVRT.js.map +0 -1
  351. package/dist/chunk-2YYJDKSP.js +0 -51
  352. package/dist/chunk-2YYJDKSP.js.map +0 -1
  353. package/dist/chunk-3P5UUCFI.js +0 -385
  354. package/dist/chunk-3P5UUCFI.js.map +0 -1
  355. package/dist/chunk-3QDFDDWZ.js +0 -99
  356. package/dist/chunk-3QDFDDWZ.js.map +0 -1
  357. package/dist/chunk-3W27OLK5.js +0 -15
  358. package/dist/chunk-3W27OLK5.js.map +0 -1
  359. package/dist/chunk-4FIZZONW.js +0 -40
  360. package/dist/chunk-4FIZZONW.js.map +0 -1
  361. package/dist/chunk-4GIAXOJG.js +0 -133
  362. package/dist/chunk-4GIAXOJG.js.map +0 -1
  363. package/dist/chunk-52NDNMK7.js +0 -99
  364. package/dist/chunk-52NDNMK7.js.map +0 -1
  365. package/dist/chunk-576G5OES.js +0 -201
  366. package/dist/chunk-576G5OES.js.map +0 -1
  367. package/dist/chunk-5AIE6SET.js +0 -659
  368. package/dist/chunk-5AIE6SET.js.map +0 -1
  369. package/dist/chunk-5FTNAZRW.js +0 -327
  370. package/dist/chunk-5FTNAZRW.js.map +0 -1
  371. package/dist/chunk-5IG2S7ZY.js +0 -70
  372. package/dist/chunk-5IG2S7ZY.js.map +0 -1
  373. package/dist/chunk-5QCXHNCW.js +0 -404
  374. package/dist/chunk-5QCXHNCW.js.map +0 -1
  375. package/dist/chunk-6DUMGC7Y.js +0 -105
  376. package/dist/chunk-6DUMGC7Y.js.map +0 -1
  377. package/dist/chunk-6J25CVST.js +0 -174
  378. package/dist/chunk-6J25CVST.js.map +0 -1
  379. package/dist/chunk-6NN35XOP.js +0 -120
  380. package/dist/chunk-6NN35XOP.js.map +0 -1
  381. package/dist/chunk-6NZBVA4T.js +0 -24
  382. package/dist/chunk-6NZBVA4T.js.map +0 -1
  383. package/dist/chunk-6W5BHRCL.js +0 -295
  384. package/dist/chunk-6W5BHRCL.js.map +0 -1
  385. package/dist/chunk-72BKRCEG.js +0 -409
  386. package/dist/chunk-72BKRCEG.js.map +0 -1
  387. package/dist/chunk-7GTI3PPI.js +0 -95
  388. package/dist/chunk-7GTI3PPI.js.map +0 -1
  389. package/dist/chunk-7P6PLZ4B.js +0 -74
  390. package/dist/chunk-7P6PLZ4B.js.map +0 -1
  391. package/dist/chunk-7WZWY5IA.js +0 -46
  392. package/dist/chunk-7WZWY5IA.js.map +0 -1
  393. package/dist/chunk-AIYO2632.js +0 -489
  394. package/dist/chunk-AIYO2632.js.map +0 -1
  395. package/dist/chunk-ANFZWPNE.js +0 -112
  396. package/dist/chunk-ANFZWPNE.js.map +0 -1
  397. package/dist/chunk-ANZTVAJU.js +0 -73
  398. package/dist/chunk-ANZTVAJU.js.map +0 -1
  399. package/dist/chunk-BD5BTJKX.js +0 -166
  400. package/dist/chunk-BD5BTJKX.js.map +0 -1
  401. package/dist/chunk-BHGIDSRJ.js +0 -140
  402. package/dist/chunk-BHGIDSRJ.js.map +0 -1
  403. package/dist/chunk-BSQWZITZ.js +0 -507
  404. package/dist/chunk-BSQWZITZ.js.map +0 -1
  405. package/dist/chunk-D3LAIK62.js +0 -23
  406. package/dist/chunk-D3LAIK62.js.map +0 -1
  407. package/dist/chunk-DODCR43C.js +0 -155
  408. package/dist/chunk-DODCR43C.js.map +0 -1
  409. package/dist/chunk-EEK5NGZF.js +0 -40
  410. package/dist/chunk-EEK5NGZF.js.map +0 -1
  411. package/dist/chunk-ENRG7TXA.js +0 -11
  412. package/dist/chunk-ENRG7TXA.js.map +0 -1
  413. package/dist/chunk-EQRMGIGY.js +0 -239
  414. package/dist/chunk-EQRMGIGY.js.map +0 -1
  415. package/dist/chunk-ERAHK5YQ.js +0 -495
  416. package/dist/chunk-ERAHK5YQ.js.map +0 -1
  417. package/dist/chunk-F3FOFY2P.js +0 -124
  418. package/dist/chunk-F3FOFY2P.js.map +0 -1
  419. package/dist/chunk-F6BTWFOC.js +0 -507
  420. package/dist/chunk-F6BTWFOC.js.map +0 -1
  421. package/dist/chunk-F6J6NNAL.js +0 -34
  422. package/dist/chunk-F6J6NNAL.js.map +0 -1
  423. package/dist/chunk-FCHJ7D5O.js +0 -59
  424. package/dist/chunk-FCHJ7D5O.js.map +0 -1
  425. package/dist/chunk-FFJTEQCC.js +0 -80
  426. package/dist/chunk-FFJTEQCC.js.map +0 -1
  427. package/dist/chunk-FUFMVW7O.js +0 -64
  428. package/dist/chunk-FUFMVW7O.js.map +0 -1
  429. package/dist/chunk-FVPGQ6UE.js +0 -25
  430. package/dist/chunk-FVPGQ6UE.js.map +0 -1
  431. package/dist/chunk-G3PMV62Z.js +0 -33
  432. package/dist/chunk-G3PMV62Z.js.map +0 -1
  433. package/dist/chunk-GACFOW3E.js +0 -51
  434. package/dist/chunk-GACFOW3E.js.map +0 -1
  435. package/dist/chunk-GDT6HQMK.js +0 -42
  436. package/dist/chunk-GDT6HQMK.js.map +0 -1
  437. package/dist/chunk-HLGU22C6.js +0 -2589
  438. package/dist/chunk-HLGU22C6.js.map +0 -1
  439. package/dist/chunk-HPMYYGP7.js +0 -134
  440. package/dist/chunk-HPMYYGP7.js.map +0 -1
  441. package/dist/chunk-I2UCOD45.js +0 -197
  442. package/dist/chunk-I2UCOD45.js.map +0 -1
  443. package/dist/chunk-IEGDZUVM.js +0 -75
  444. package/dist/chunk-IEGDZUVM.js.map +0 -1
  445. package/dist/chunk-IIS7INHF.js +0 -47
  446. package/dist/chunk-IIS7INHF.js.map +0 -1
  447. package/dist/chunk-ITELSEFU.js +0 -256
  448. package/dist/chunk-ITELSEFU.js.map +0 -1
  449. package/dist/chunk-IXAYNBOY.js +0 -407
  450. package/dist/chunk-IXAYNBOY.js.map +0 -1
  451. package/dist/chunk-JUW2ETEI.js +0 -191
  452. package/dist/chunk-JUW2ETEI.js.map +0 -1
  453. package/dist/chunk-K65C7CVE.js +0 -127
  454. package/dist/chunk-K65C7CVE.js.map +0 -1
  455. package/dist/chunk-KDI64MCY.js +0 -189
  456. package/dist/chunk-KDI64MCY.js.map +0 -1
  457. package/dist/chunk-KN4ASMH5.js +0 -160
  458. package/dist/chunk-KN4ASMH5.js.map +0 -1
  459. package/dist/chunk-KQW7QNTU.js +0 -1549
  460. package/dist/chunk-KQW7QNTU.js.map +0 -1
  461. package/dist/chunk-KR7NXXHC.js +0 -66
  462. package/dist/chunk-KR7NXXHC.js.map +0 -1
  463. package/dist/chunk-KRZKIVMA.js +0 -142
  464. package/dist/chunk-KRZKIVMA.js.map +0 -1
  465. package/dist/chunk-KTTLLKGQ.js +0 -185
  466. package/dist/chunk-KTTLLKGQ.js.map +0 -1
  467. package/dist/chunk-KWKSHPDP.js +0 -234
  468. package/dist/chunk-KWKSHPDP.js.map +0 -1
  469. package/dist/chunk-KZVC7OYG.js +0 -57
  470. package/dist/chunk-KZVC7OYG.js.map +0 -1
  471. package/dist/chunk-L5DHUN2V.js +0 -204
  472. package/dist/chunk-L5DHUN2V.js.map +0 -1
  473. package/dist/chunk-LCTGEH57.js +0 -1376
  474. package/dist/chunk-LCTGEH57.js.map +0 -1
  475. package/dist/chunk-LXLIQ2D6.js +0 -12
  476. package/dist/chunk-LXLIQ2D6.js.map +0 -1
  477. package/dist/chunk-M4CTURKX.js +0 -84
  478. package/dist/chunk-M4CTURKX.js.map +0 -1
  479. package/dist/chunk-M6LTUPVP.js +0 -301
  480. package/dist/chunk-M6LTUPVP.js.map +0 -1
  481. package/dist/chunk-MA6RRHDT.js +0 -291
  482. package/dist/chunk-MA6RRHDT.js.map +0 -1
  483. package/dist/chunk-MODE4QIA.js +0 -6
  484. package/dist/chunk-MODE4QIA.js.map +0 -1
  485. package/dist/chunk-MVILMVGG.js +0 -118
  486. package/dist/chunk-MVILMVGG.js.map +0 -1
  487. package/dist/chunk-MWS4VCLV.js +0 -17
  488. package/dist/chunk-MWS4VCLV.js.map +0 -1
  489. package/dist/chunk-NEUX74SO.js +0 -315
  490. package/dist/chunk-NEUX74SO.js.map +0 -1
  491. package/dist/chunk-NFHKYBRD.js +0 -156
  492. package/dist/chunk-NFHKYBRD.js.map +0 -1
  493. package/dist/chunk-NHJNNXD3.js +0 -89
  494. package/dist/chunk-NHJNNXD3.js.map +0 -1
  495. package/dist/chunk-O2BF3HZL.js +0 -33
  496. package/dist/chunk-O2BF3HZL.js.map +0 -1
  497. package/dist/chunk-OANXCZYD.js +0 -212
  498. package/dist/chunk-OANXCZYD.js.map +0 -1
  499. package/dist/chunk-ODJF7YIP.js +0 -230
  500. package/dist/chunk-ODJF7YIP.js.map +0 -1
  501. package/dist/chunk-ON4BJTHI.js +0 -101
  502. package/dist/chunk-ON4BJTHI.js.map +0 -1
  503. package/dist/chunk-OTL5WXIJ.js +0 -16
  504. package/dist/chunk-OTL5WXIJ.js.map +0 -1
  505. package/dist/chunk-PACNBKJV.js +0 -47
  506. package/dist/chunk-PACNBKJV.js.map +0 -1
  507. package/dist/chunk-PROCA7K7.js +0 -23
  508. package/dist/chunk-PROCA7K7.js.map +0 -1
  509. package/dist/chunk-QGMIPA67.js +0 -85
  510. package/dist/chunk-QGMIPA67.js.map +0 -1
  511. package/dist/chunk-QQA37LFB.js +0 -190
  512. package/dist/chunk-QQA37LFB.js.map +0 -1
  513. package/dist/chunk-QZAWRSEB.js +0 -61
  514. package/dist/chunk-QZAWRSEB.js.map +0 -1
  515. package/dist/chunk-R74KGWNS.js +0 -699
  516. package/dist/chunk-R74KGWNS.js.map +0 -1
  517. package/dist/chunk-RFDLHMKL.js +0 -110
  518. package/dist/chunk-RFDLHMKL.js.map +0 -1
  519. package/dist/chunk-RL64HN7S.js +0 -40
  520. package/dist/chunk-RL64HN7S.js.map +0 -1
  521. package/dist/chunk-RMRQKPL7.js +0 -115
  522. package/dist/chunk-RMRQKPL7.js.map +0 -1
  523. package/dist/chunk-RQVK4IYC.js +0 -606
  524. package/dist/chunk-RQVK4IYC.js.map +0 -1
  525. package/dist/chunk-RTW56PWZ.js +0 -59
  526. package/dist/chunk-RTW56PWZ.js.map +0 -1
  527. package/dist/chunk-RUTPQNLR.js +0 -266
  528. package/dist/chunk-RUTPQNLR.js.map +0 -1
  529. package/dist/chunk-S6TAF63G.js +0 -25
  530. package/dist/chunk-S6TAF63G.js.map +0 -1
  531. package/dist/chunk-SBGAUGXY.js +0 -224
  532. package/dist/chunk-SBGAUGXY.js.map +0 -1
  533. package/dist/chunk-SC275NHZ.js +0 -407
  534. package/dist/chunk-SC275NHZ.js.map +0 -1
  535. package/dist/chunk-SCQPU4UE.js +0 -97
  536. package/dist/chunk-SCQPU4UE.js.map +0 -1
  537. package/dist/chunk-SFFF2WQP.js +0 -8
  538. package/dist/chunk-SFFF2WQP.js.map +0 -1
  539. package/dist/chunk-SJYMHZKA.js +0 -36
  540. package/dist/chunk-SJYMHZKA.js.map +0 -1
  541. package/dist/chunk-SLCCUJVN.js +0 -125
  542. package/dist/chunk-SLCCUJVN.js.map +0 -1
  543. package/dist/chunk-SVBSNSD4.js +0 -259
  544. package/dist/chunk-SVBSNSD4.js.map +0 -1
  545. package/dist/chunk-SVPLTL35.js +0 -62
  546. package/dist/chunk-SVPLTL35.js.map +0 -1
  547. package/dist/chunk-SWQFYNYG.js +0 -338
  548. package/dist/chunk-SWQFYNYG.js.map +0 -1
  549. package/dist/chunk-THHB4EWS.js +0 -72
  550. package/dist/chunk-THHB4EWS.js.map +0 -1
  551. package/dist/chunk-TUCDD33E.js +0 -246
  552. package/dist/chunk-TUCDD33E.js.map +0 -1
  553. package/dist/chunk-TV4WAP2R.js +0 -14
  554. package/dist/chunk-TV4WAP2R.js.map +0 -1
  555. package/dist/chunk-U3A6YBTZ.js +0 -134
  556. package/dist/chunk-U3A6YBTZ.js.map +0 -1
  557. package/dist/chunk-UGT6DKWM.js +0 -95
  558. package/dist/chunk-VSERHUWD.js +0 -212
  559. package/dist/chunk-VSERHUWD.js.map +0 -1
  560. package/dist/chunk-VYG7BDXC.js +0 -49
  561. package/dist/chunk-VYG7BDXC.js.map +0 -1
  562. package/dist/chunk-WETKNYZX.js +0 -52
  563. package/dist/chunk-WETKNYZX.js.map +0 -1
  564. package/dist/chunk-WGG4AML3.js +0 -216
  565. package/dist/chunk-WGG4AML3.js.map +0 -1
  566. package/dist/chunk-WKAUEL6I.js +0 -30
  567. package/dist/chunk-WKAUEL6I.js.map +0 -1
  568. package/dist/chunk-WPOLA5CG.js +0 -81
  569. package/dist/chunk-WPOLA5CG.js.map +0 -1
  570. package/dist/chunk-WPVETCGJ.js +0 -254
  571. package/dist/chunk-WPVETCGJ.js.map +0 -1
  572. package/dist/chunk-WTSM3A7E.js +0 -13
  573. package/dist/chunk-WTSM3A7E.js.map +0 -1
  574. package/dist/chunk-WU3F2K3T.js +0 -148
  575. package/dist/chunk-WU3F2K3T.js.map +0 -1
  576. package/dist/chunk-WZZK2DTZ.js +0 -39
  577. package/dist/chunk-WZZK2DTZ.js.map +0 -1
  578. package/dist/chunk-X4IHLKRD.js +0 -42
  579. package/dist/chunk-X4IHLKRD.js.map +0 -1
  580. package/dist/chunk-XAHEXZJC.js +0 -80
  581. package/dist/chunk-XAHEXZJC.js.map +0 -1
  582. package/dist/chunk-XCYGJDUX.js +0 -31
  583. package/dist/chunk-XCYGJDUX.js.map +0 -1
  584. package/dist/chunk-Y4W3JORC.js +0 -104
  585. package/dist/chunk-Y4W3JORC.js.map +0 -1
  586. package/dist/chunk-YFZJ3ZLG.js +0 -1297
  587. package/dist/chunk-YFZJ3ZLG.js.map +0 -1
  588. package/dist/chunk-YI3WLXEN.js +0 -4387
  589. package/dist/chunk-YI3WLXEN.js.map +0 -1
  590. package/dist/chunk-ZBKFSPD3.js +0 -29
  591. package/dist/chunk-ZBKFSPD3.js.map +0 -1
  592. package/dist/chunk-ZOERRQ6A.js +0 -79
  593. package/dist/chunk-ZOERRQ6A.js.map +0 -1
  594. package/dist/chunk-ZSTGUKHU.js +0 -10
  595. package/dist/chunk-ZSTGUKHU.js.map +0 -1
  596. package/dist/chunk-ZUEHDL27.js +0 -65
  597. package/dist/chunk-ZUEHDL27.js.map +0 -1
  598. package/dist/constants-D3gaMY-W.d.ts +0 -39
  599. package/dist/icons.js.map +0 -1
  600. package/dist/index.js.map +0 -1
  601. package/dist/internal/blocks/AIKit.js.map +0 -1
  602. package/dist/internal/blocks/AppShell.js.map +0 -1
  603. package/dist/internal/blocks/AutoSaveTextarea.js.map +0 -1
  604. package/dist/internal/blocks/BrandEditor.js.map +0 -1
  605. package/dist/internal/blocks/ClipboardButton.js.map +0 -1
  606. package/dist/internal/blocks/ColorInput.js.map +0 -1
  607. package/dist/internal/blocks/ColorModeSwitch.js.map +0 -1
  608. package/dist/internal/blocks/Command.js.map +0 -1
  609. package/dist/internal/blocks/CopyField.js.map +0 -1
  610. package/dist/internal/blocks/DateInput.js.map +0 -1
  611. package/dist/internal/blocks/DateRangeInput.js.map +0 -1
  612. package/dist/internal/blocks/Form.js.map +0 -1
  613. package/dist/internal/blocks/FormGroup.js.map +0 -1
  614. package/dist/internal/blocks/MultiActionButtonGroup.js.map +0 -1
  615. package/dist/internal/blocks/OtpInput.js.map +0 -1
  616. package/dist/internal/blocks/PageHeader.js.map +0 -1
  617. package/dist/internal/blocks/PageLayout.js.map +0 -1
  618. package/dist/internal/blocks/PageToolbar.js.map +0 -1
  619. package/dist/internal/blocks/SearchInput.js.map +0 -1
  620. package/dist/internal/blocks/SectionNav.js.map +0 -1
  621. package/dist/internal/blocks/TextInput.js.map +0 -1
  622. package/dist/internal/components/Alert.js.map +0 -1
  623. package/dist/internal/components/AlertModal.js.map +0 -1
  624. package/dist/internal/components/Badge.js.map +0 -1
  625. package/dist/internal/components/BrandLogo.js.map +0 -1
  626. package/dist/internal/components/Breadcrumb.js.map +0 -1
  627. package/dist/internal/components/Button.js.map +0 -1
  628. package/dist/internal/components/Calendar.js.map +0 -1
  629. package/dist/internal/components/Card.js.map +0 -1
  630. package/dist/internal/components/Checkbox.js.map +0 -1
  631. package/dist/internal/components/Clipboard.js.map +0 -1
  632. package/dist/internal/components/Collapsible.js.map +0 -1
  633. package/dist/internal/components/Combobox.js.map +0 -1
  634. package/dist/internal/components/DatePicker.js.map +0 -1
  635. package/dist/internal/components/DateRangePicker.js.map +0 -1
  636. package/dist/internal/components/DiffView.js.map +0 -1
  637. package/dist/internal/components/DropdownMenu.js.map +0 -1
  638. package/dist/internal/components/FileUpload.js.map +0 -1
  639. package/dist/internal/components/FullScreenModal.js.map +0 -1
  640. package/dist/internal/components/HoverCard.js.map +0 -1
  641. package/dist/internal/components/InputGroup.js.map +0 -1
  642. package/dist/internal/components/Kbd.js.map +0 -1
  643. package/dist/internal/components/MarkedText.js.map +0 -1
  644. package/dist/internal/components/MergeEditor/useMergeDiff.js.map +0 -1
  645. package/dist/internal/components/Modal.js.map +0 -1
  646. package/dist/internal/components/Navbar.js.map +0 -1
  647. package/dist/internal/components/Pagination.js.map +0 -1
  648. package/dist/internal/components/Popconfirm.js.map +0 -1
  649. package/dist/internal/components/Popover.js.map +0 -1
  650. package/dist/internal/components/RadioGroup.js.map +0 -1
  651. package/dist/internal/components/Resizable.js.map +0 -1
  652. package/dist/internal/components/Search.js.map +0 -1
  653. package/dist/internal/components/Select.js.map +0 -1
  654. package/dist/internal/components/Sheet.js.map +0 -1
  655. package/dist/internal/components/Sidebar.js.map +0 -1
  656. package/dist/internal/components/Slider.js.map +0 -1
  657. package/dist/internal/components/Stepper.js.map +0 -1
  658. package/dist/internal/components/Switch.js.map +0 -1
  659. package/dist/internal/components/Table.js.map +0 -1
  660. package/dist/internal/components/Tabs.js.map +0 -1
  661. package/dist/internal/components/ThemeProvider.js.map +0 -1
  662. package/dist/internal/components/TimePicker.js.map +0 -1
  663. package/dist/internal/components/Timeline.js.map +0 -1
  664. package/dist/internal/components/Toast.js.map +0 -1
  665. package/dist/internal/components/ToggleGroup.js.map +0 -1
  666. package/dist/internal/components/Tooltip.js.map +0 -1
  667. package/dist/internal/components/Workbench.js.map +0 -1
  668. package/dist/internal/components/ZoomableSvg.js.map +0 -1
  669. package/dist/internal/utils.js.map +0 -1
  670. 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-6xBX0nNl.js";
5
+ import { ButtonGroup } from "./internal/components/ButtonGroup.js";
6
+ import { DropdownMenu } from "./DropdownMenu-t90tVw6l.js";
7
+ import { Label } from "./internal/components/Label.js";
8
+ import { TextInput } from "./TextInput-CMuN1WfY.js";
9
+ import { FormGroup } from "./FormGroup-C41n65cE.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-ChL3WIQT.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