@kopexa/tiptap 17.6.18 → 17.7.2

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 (428) hide show
  1. package/dist/index.d.mts +691 -24
  2. package/dist/index.d.ts +691 -24
  3. package/dist/index.js +1478 -786
  4. package/dist/index.mjs +7987 -112
  5. package/package.json +57 -52
  6. package/dist/chunk-2SI7MRAE.mjs +0 -64
  7. package/dist/chunk-2U5CQUZH.mjs +0 -91
  8. package/dist/chunk-2UDCL55K.mjs +0 -55
  9. package/dist/chunk-2V6VOAPI.mjs +0 -139
  10. package/dist/chunk-2Z2QVW67.mjs +0 -1
  11. package/dist/chunk-32SUXCAQ.mjs +0 -115
  12. package/dist/chunk-33QD5PYJ.mjs +0 -63
  13. package/dist/chunk-3VRQUYYW.mjs +0 -169
  14. package/dist/chunk-42HKGCOO.mjs +0 -129
  15. package/dist/chunk-4ALV4UA5.mjs +0 -1
  16. package/dist/chunk-4CDZ547I.mjs +0 -185
  17. package/dist/chunk-4HO7BWDC.mjs +0 -89
  18. package/dist/chunk-4JRYQZ4A.mjs +0 -174
  19. package/dist/chunk-552JLRNB.mjs +0 -35
  20. package/dist/chunk-5SMDMQDF.mjs +0 -34
  21. package/dist/chunk-6552DQWB.mjs +0 -416
  22. package/dist/chunk-7FDDRVUE.mjs +0 -143
  23. package/dist/chunk-7VGROP26.mjs +0 -262
  24. package/dist/chunk-7VW67NVL.mjs +0 -80
  25. package/dist/chunk-AAV7ZNBP.mjs +0 -83
  26. package/dist/chunk-ATRHILCH.mjs +0 -1
  27. package/dist/chunk-B7WJOQ3X.mjs +0 -103
  28. package/dist/chunk-BEV5U2DK.mjs +0 -131
  29. package/dist/chunk-BXHPO3T7.mjs +0 -152
  30. package/dist/chunk-BXJYNSWQ.mjs +0 -30
  31. package/dist/chunk-C5RQWJKE.mjs +0 -155
  32. package/dist/chunk-CNVACBGT.mjs +0 -51
  33. package/dist/chunk-DQK6PA4U.mjs +0 -276
  34. package/dist/chunk-DSBJFMHK.mjs +0 -38
  35. package/dist/chunk-DT7ML2P4.mjs +0 -42
  36. package/dist/chunk-DZLGLP7R.mjs +0 -99
  37. package/dist/chunk-EAAQE5ZV.mjs +0 -283
  38. package/dist/chunk-EHY2NAW7.mjs +0 -120
  39. package/dist/chunk-EIIWU5FR.mjs +0 -61
  40. package/dist/chunk-ERPGWXFK.mjs +0 -163
  41. package/dist/chunk-F73FCUD5.mjs +0 -1
  42. package/dist/chunk-FRJX2F4T.mjs +0 -55
  43. package/dist/chunk-GYIYX2JH.mjs +0 -73
  44. package/dist/chunk-H6LC4LDQ.mjs +0 -63
  45. package/dist/chunk-H7MS2UMO.mjs +0 -168
  46. package/dist/chunk-HLLA2HRV.mjs +0 -1
  47. package/dist/chunk-HTJ2RXOG.mjs +0 -32
  48. package/dist/chunk-IFXRPGIJ.mjs +0 -98
  49. package/dist/chunk-IOB3REX6.mjs +0 -173
  50. package/dist/chunk-IQERE7KP.mjs +0 -115
  51. package/dist/chunk-JCV5SEKN.mjs +0 -65
  52. package/dist/chunk-JVSH5T4B.mjs +0 -72
  53. package/dist/chunk-KK4K43WM.mjs +0 -59
  54. package/dist/chunk-KR42JAVB.mjs +0 -60
  55. package/dist/chunk-KYLBKQ2E.mjs +0 -203
  56. package/dist/chunk-L5RDMV3H.mjs +0 -216
  57. package/dist/chunk-LNVWG34E.mjs +0 -165
  58. package/dist/chunk-LVNUU67N.mjs +0 -1
  59. package/dist/chunk-MNTOOEHA.mjs +0 -1
  60. package/dist/chunk-N3JE67CS.mjs +0 -81
  61. package/dist/chunk-N4CT5RNC.mjs +0 -123
  62. package/dist/chunk-OEVR5N7X.mjs +0 -65
  63. package/dist/chunk-P55PLOHR.mjs +0 -34
  64. package/dist/chunk-Q5FK7SFY.mjs +0 -75
  65. package/dist/chunk-Q7DFJ5NI.mjs +0 -153
  66. package/dist/chunk-QIELBKP3.mjs +0 -104
  67. package/dist/chunk-R2GM4A3T.mjs +0 -71
  68. package/dist/chunk-REJEJXOZ.mjs +0 -10
  69. package/dist/chunk-RFWNKE7D.mjs +0 -238
  70. package/dist/chunk-TAM3VMJT.mjs +0 -80
  71. package/dist/chunk-TDFS3DCZ.mjs +0 -79
  72. package/dist/chunk-TLM5ALHZ.mjs +0 -1
  73. package/dist/chunk-TZQQ6C2Q.mjs +0 -101
  74. package/dist/chunk-U5XAL46P.mjs +0 -39
  75. package/dist/chunk-UJ4BNZ63.mjs +0 -178
  76. package/dist/chunk-UVHVCION.mjs +0 -168
  77. package/dist/chunk-V6TAZMQN.mjs +0 -105
  78. package/dist/chunk-VF3G2URZ.mjs +0 -83
  79. package/dist/chunk-VRQ6OSAZ.mjs +0 -76
  80. package/dist/chunk-VTKJPVNM.mjs +0 -148
  81. package/dist/chunk-VX3HSJ76.mjs +0 -73
  82. package/dist/chunk-W2FLOOJ6.mjs +0 -75
  83. package/dist/chunk-XGAABDMW.mjs +0 -159
  84. package/dist/chunk-Y2KSWMG5.mjs +0 -1
  85. package/dist/chunk-YJAHZXLG.mjs +0 -92
  86. package/dist/chunk-Z365KVQY.mjs +0 -34
  87. package/dist/chunk-ZVTJ6XD7.mjs +0 -88
  88. package/dist/chunk-ZZ4OU46C.mjs +0 -131
  89. package/dist/context/editor-context.d.mts +0 -10
  90. package/dist/context/editor-context.d.ts +0 -10
  91. package/dist/context/editor-context.js +0 -34
  92. package/dist/context/editor-context.mjs +0 -9
  93. package/dist/context/editor-file-context.d.mts +0 -70
  94. package/dist/context/editor-file-context.d.ts +0 -70
  95. package/dist/context/editor-file-context.js +0 -96
  96. package/dist/context/editor-file-context.mjs +0 -12
  97. package/dist/extensions/callout/callout-settings.d.mts +0 -13
  98. package/dist/extensions/callout/callout-settings.d.ts +0 -13
  99. package/dist/extensions/callout/callout-settings.js +0 -206
  100. package/dist/extensions/callout/callout-settings.mjs +0 -9
  101. package/dist/extensions/callout/callout-view.d.mts +0 -12
  102. package/dist/extensions/callout/callout-view.d.ts +0 -12
  103. package/dist/extensions/callout/callout-view.js +0 -273
  104. package/dist/extensions/callout/callout-view.mjs +0 -12
  105. package/dist/extensions/callout/index.d.mts +0 -44
  106. package/dist/extensions/callout/index.d.ts +0 -44
  107. package/dist/extensions/callout/index.js +0 -380
  108. package/dist/extensions/callout/index.mjs +0 -13
  109. package/dist/extensions/callout/messages.d.mts +0 -59
  110. package/dist/extensions/callout/messages.d.ts +0 -59
  111. package/dist/extensions/callout/messages.js +0 -88
  112. package/dist/extensions/callout/messages.mjs +0 -7
  113. package/dist/extensions/image/image-view.d.mts +0 -15
  114. package/dist/extensions/image/image-view.d.ts +0 -15
  115. package/dist/extensions/image/image-view.js +0 -255
  116. package/dist/extensions/image/image-view.mjs +0 -12
  117. package/dist/extensions/image/index.d.mts +0 -29
  118. package/dist/extensions/image/index.d.ts +0 -29
  119. package/dist/extensions/image/index.js +0 -282
  120. package/dist/extensions/image/index.mjs +0 -16
  121. package/dist/extensions/image/messages.d.mts +0 -28
  122. package/dist/extensions/image/messages.d.ts +0 -28
  123. package/dist/extensions/image/messages.js +0 -57
  124. package/dist/extensions/image/messages.mjs +0 -7
  125. package/dist/extensions/image-upload/image-upload-view.d.mts +0 -12
  126. package/dist/extensions/image-upload/image-upload-view.d.ts +0 -12
  127. package/dist/extensions/image-upload/image-upload-view.js +0 -338
  128. package/dist/extensions/image-upload/image-upload-view.mjs +0 -12
  129. package/dist/extensions/image-upload/index.d.mts +0 -46
  130. package/dist/extensions/image-upload/index.d.ts +0 -46
  131. package/dist/extensions/image-upload/index.js +0 -414
  132. package/dist/extensions/image-upload/index.mjs +0 -16
  133. package/dist/extensions/image-upload/messages.d.mts +0 -32
  134. package/dist/extensions/image-upload/messages.d.ts +0 -32
  135. package/dist/extensions/image-upload/messages.js +0 -61
  136. package/dist/extensions/image-upload/messages.mjs +0 -7
  137. package/dist/extensions/link/index.d.mts +0 -6
  138. package/dist/extensions/link/index.d.ts +0 -6
  139. package/dist/extensions/link/index.js +0 -94
  140. package/dist/extensions/link/index.mjs +0 -7
  141. package/dist/extensions/math/index.d.mts +0 -38
  142. package/dist/extensions/math/index.d.ts +0 -38
  143. package/dist/extensions/math/index.js +0 -544
  144. package/dist/extensions/math/index.mjs +0 -17
  145. package/dist/extensions/math/inline-math-view.d.mts +0 -12
  146. package/dist/extensions/math/inline-math-view.d.ts +0 -12
  147. package/dist/extensions/math/inline-math-view.js +0 -232
  148. package/dist/extensions/math/inline-math-view.mjs +0 -11
  149. package/dist/extensions/math/inline-math.d.mts +0 -32
  150. package/dist/extensions/math/inline-math.d.ts +0 -32
  151. package/dist/extensions/math/inline-math.js +0 -304
  152. package/dist/extensions/math/inline-math.mjs +0 -12
  153. package/dist/extensions/math/math-block-view.d.mts +0 -11
  154. package/dist/extensions/math/math-block-view.d.ts +0 -11
  155. package/dist/extensions/math/math-block-view.js +0 -248
  156. package/dist/extensions/math/math-block-view.mjs +0 -11
  157. package/dist/extensions/math/messages.d.mts +0 -49
  158. package/dist/extensions/math/messages.d.ts +0 -49
  159. package/dist/extensions/math/messages.js +0 -78
  160. package/dist/extensions/math/messages.mjs +0 -7
  161. package/dist/extensions/selection/index.d.mts +0 -5
  162. package/dist/extensions/selection/index.d.ts +0 -5
  163. package/dist/extensions/selection/index.js +0 -62
  164. package/dist/extensions/selection/index.mjs +0 -7
  165. package/dist/extensions/toc/index.d.mts +0 -53
  166. package/dist/extensions/toc/index.d.ts +0 -53
  167. package/dist/extensions/toc/index.js +0 -501
  168. package/dist/extensions/toc/index.mjs +0 -13
  169. package/dist/extensions/toc/messages.d.mts +0 -74
  170. package/dist/extensions/toc/messages.d.ts +0 -74
  171. package/dist/extensions/toc/messages.js +0 -103
  172. package/dist/extensions/toc/messages.mjs +0 -7
  173. package/dist/extensions/toc/toc-settings.d.mts +0 -13
  174. package/dist/extensions/toc/toc-settings.d.ts +0 -13
  175. package/dist/extensions/toc/toc-settings.js +0 -283
  176. package/dist/extensions/toc/toc-settings.mjs +0 -9
  177. package/dist/extensions/toc/toc-view.d.mts +0 -12
  178. package/dist/extensions/toc/toc-view.d.ts +0 -12
  179. package/dist/extensions/toc/toc-view.js +0 -411
  180. package/dist/extensions/toc/toc-view.mjs +0 -12
  181. package/dist/extensions/trailing-node/index.d.mts +0 -9
  182. package/dist/extensions/trailing-node/index.d.ts +0 -9
  183. package/dist/extensions/trailing-node/index.js +0 -86
  184. package/dist/extensions/trailing-node/index.mjs +0 -7
  185. package/dist/extensions/ui-state/index.d.mts +0 -34
  186. package/dist/extensions/ui-state/index.d.ts +0 -34
  187. package/dist/extensions/ui-state/index.js +0 -84
  188. package/dist/extensions/ui-state/index.mjs +0 -9
  189. package/dist/extensions/variable/extract-variables.d.mts +0 -16
  190. package/dist/extensions/variable/extract-variables.d.ts +0 -16
  191. package/dist/extensions/variable/extract-variables.js +0 -58
  192. package/dist/extensions/variable/extract-variables.mjs +0 -7
  193. package/dist/extensions/variable/index.d.mts +0 -38
  194. package/dist/extensions/variable/index.d.ts +0 -38
  195. package/dist/extensions/variable/index.js +0 -190
  196. package/dist/extensions/variable/index.mjs +0 -11
  197. package/dist/extensions/variable/messages.d.mts +0 -69
  198. package/dist/extensions/variable/messages.d.ts +0 -69
  199. package/dist/extensions/variable/messages.js +0 -98
  200. package/dist/extensions/variable/messages.mjs +0 -7
  201. package/dist/extensions/variable/variable-context.d.mts +0 -56
  202. package/dist/extensions/variable/variable-context.d.ts +0 -56
  203. package/dist/extensions/variable/variable-context.js +0 -70
  204. package/dist/extensions/variable/variable-context.mjs +0 -12
  205. package/dist/extensions/variable/variable-filler-dialog.d.mts +0 -43
  206. package/dist/extensions/variable/variable-filler-dialog.d.ts +0 -43
  207. package/dist/extensions/variable/variable-filler-dialog.js +0 -207
  208. package/dist/extensions/variable/variable-filler-dialog.mjs +0 -9
  209. package/dist/extensions/variable/variable-suggestion.d.mts +0 -31
  210. package/dist/extensions/variable/variable-suggestion.d.ts +0 -31
  211. package/dist/extensions/variable/variable-suggestion.js +0 -615
  212. package/dist/extensions/variable/variable-suggestion.mjs +0 -14
  213. package/dist/extensions/variable/variable-view.d.mts +0 -13
  214. package/dist/extensions/variable/variable-view.d.ts +0 -13
  215. package/dist/extensions/variable/variable-view.js +0 -110
  216. package/dist/extensions/variable/variable-view.mjs +0 -11
  217. package/dist/hooks/use-create-editor.d.mts +0 -46
  218. package/dist/hooks/use-create-editor.d.ts +0 -46
  219. package/dist/hooks/use-create-editor.js +0 -2726
  220. package/dist/hooks/use-create-editor.mjs +0 -37
  221. package/dist/hooks/use-cursor-visibility.d.mts +0 -37
  222. package/dist/hooks/use-cursor-visibility.d.ts +0 -37
  223. package/dist/hooks/use-cursor-visibility.js +0 -140
  224. package/dist/hooks/use-cursor-visibility.mjs +0 -8
  225. package/dist/hooks/use-floating-element.d.mts +0 -43
  226. package/dist/hooks/use-floating-element.d.ts +0 -43
  227. package/dist/hooks/use-floating-element.js +0 -88
  228. package/dist/hooks/use-floating-element.mjs +0 -8
  229. package/dist/hooks/use-floating-toolbar-visibility.d.mts +0 -32
  230. package/dist/hooks/use-floating-toolbar-visibility.d.ts +0 -32
  231. package/dist/hooks/use-floating-toolbar-visibility.js +0 -115
  232. package/dist/hooks/use-floating-toolbar-visibility.mjs +0 -13
  233. package/dist/hooks/use-menu-navigation.d.mts +0 -55
  234. package/dist/hooks/use-menu-navigation.d.ts +0 -55
  235. package/dist/hooks/use-menu-navigation.js +0 -163
  236. package/dist/hooks/use-menu-navigation.mjs +0 -8
  237. package/dist/hooks/use-tiptap-editor.d.mts +0 -20
  238. package/dist/hooks/use-tiptap-editor.d.ts +0 -20
  239. package/dist/hooks/use-tiptap-editor.js +0 -58
  240. package/dist/hooks/use-tiptap-editor.mjs +0 -8
  241. package/dist/hooks/use-ui-editor-state.d.mts +0 -7
  242. package/dist/hooks/use-ui-editor-state.d.ts +0 -7
  243. package/dist/hooks/use-ui-editor-state.js +0 -107
  244. package/dist/hooks/use-ui-editor-state.mjs +0 -11
  245. package/dist/hooks/use-window-size.d.mts +0 -12
  246. package/dist/hooks/use-window-size.d.ts +0 -12
  247. package/dist/hooks/use-window-size.js +0 -75
  248. package/dist/hooks/use-window-size.mjs +0 -7
  249. package/dist/presets/basic/editor-header.d.mts +0 -23
  250. package/dist/presets/basic/editor-header.d.ts +0 -23
  251. package/dist/presets/basic/editor-header.js +0 -2750
  252. package/dist/presets/basic/editor-header.mjs +0 -43
  253. package/dist/presets/basic/index.d.mts +0 -38
  254. package/dist/presets/basic/index.d.ts +0 -38
  255. package/dist/presets/basic/index.js +0 -6891
  256. package/dist/presets/basic/index.mjs +0 -85
  257. package/dist/ui/blockquote-button/blockquote-button.d.mts +0 -20
  258. package/dist/ui/blockquote-button/blockquote-button.d.ts +0 -20
  259. package/dist/ui/blockquote-button/blockquote-button.js +0 -247
  260. package/dist/ui/blockquote-button/blockquote-button.mjs +0 -9
  261. package/dist/ui/blockquote-button/index.d.mts +0 -6
  262. package/dist/ui/blockquote-button/index.d.ts +0 -6
  263. package/dist/ui/blockquote-button/index.js +0 -259
  264. package/dist/ui/blockquote-button/index.mjs +0 -21
  265. package/dist/ui/blockquote-button/use-blockquote.d.mts +0 -85
  266. package/dist/ui/blockquote-button/use-blockquote.d.ts +0 -85
  267. package/dist/ui/blockquote-button/use-blockquote.js +0 -192
  268. package/dist/ui/blockquote-button/use-blockquote.mjs +0 -17
  269. package/dist/ui/bubble-menu/index.d.mts +0 -13
  270. package/dist/ui/bubble-menu/index.d.ts +0 -13
  271. package/dist/ui/bubble-menu/index.js +0 -673
  272. package/dist/ui/bubble-menu/index.mjs +0 -16
  273. package/dist/ui/codeblock-button/code-block-button.d.mts +0 -20
  274. package/dist/ui/codeblock-button/code-block-button.d.ts +0 -20
  275. package/dist/ui/codeblock-button/code-block-button.js +0 -237
  276. package/dist/ui/codeblock-button/code-block-button.mjs +0 -9
  277. package/dist/ui/codeblock-button/index.d.mts +0 -6
  278. package/dist/ui/codeblock-button/index.d.ts +0 -6
  279. package/dist/ui/codeblock-button/index.js +0 -249
  280. package/dist/ui/codeblock-button/index.mjs +0 -21
  281. package/dist/ui/codeblock-button/use-code-block.d.mts +0 -92
  282. package/dist/ui/codeblock-button/use-code-block.d.ts +0 -92
  283. package/dist/ui/codeblock-button/use-code-block.js +0 -192
  284. package/dist/ui/codeblock-button/use-code-block.mjs +0 -17
  285. package/dist/ui/color-highlight-button/color-highlight-button.d.mts +0 -25
  286. package/dist/ui/color-highlight-button/color-highlight-button.d.ts +0 -25
  287. package/dist/ui/color-highlight-button/color-highlight-button.js +0 -266
  288. package/dist/ui/color-highlight-button/color-highlight-button.mjs +0 -9
  289. package/dist/ui/color-highlight-button/index.d.mts +0 -6
  290. package/dist/ui/color-highlight-button/index.d.ts +0 -6
  291. package/dist/ui/color-highlight-button/index.js +0 -342
  292. package/dist/ui/color-highlight-button/index.mjs +0 -27
  293. package/dist/ui/color-highlight-button/use-color-highlight.d.mts +0 -64
  294. package/dist/ui/color-highlight-button/use-color-highlight.d.ts +0 -64
  295. package/dist/ui/color-highlight-button/use-color-highlight.js +0 -247
  296. package/dist/ui/color-highlight-button/use-color-highlight.mjs +0 -23
  297. package/dist/ui/color-highlight-popover/color-highlight-popover.d.mts +0 -29
  298. package/dist/ui/color-highlight-popover/color-highlight-popover.d.ts +0 -29
  299. package/dist/ui/color-highlight-popover/color-highlight-popover.js +0 -590
  300. package/dist/ui/color-highlight-popover/color-highlight-popover.mjs +0 -17
  301. package/dist/ui/color-highlight-popover/index.d.mts +0 -6
  302. package/dist/ui/color-highlight-popover/index.d.ts +0 -6
  303. package/dist/ui/color-highlight-popover/index.js +0 -591
  304. package/dist/ui/color-highlight-popover/index.mjs +0 -17
  305. package/dist/ui/copy-anchor-link-button/use-scroll-to-hash.d.mts +0 -30
  306. package/dist/ui/copy-anchor-link-button/use-scroll-to-hash.d.ts +0 -30
  307. package/dist/ui/copy-anchor-link-button/use-scroll-to-hash.js +0 -171
  308. package/dist/ui/copy-anchor-link-button/use-scroll-to-hash.mjs +0 -10
  309. package/dist/ui/heading-button/index.d.mts +0 -45
  310. package/dist/ui/heading-button/index.d.ts +0 -45
  311. package/dist/ui/heading-button/index.js +0 -222
  312. package/dist/ui/heading-button/index.mjs +0 -16
  313. package/dist/ui/heading-button/utils.d.mts +0 -17
  314. package/dist/ui/heading-button/utils.d.ts +0 -17
  315. package/dist/ui/heading-button/utils.js +0 -92
  316. package/dist/ui/heading-button/utils.mjs +0 -19
  317. package/dist/ui/heading-dropdown-menu/index.d.mts +0 -14
  318. package/dist/ui/heading-dropdown-menu/index.d.ts +0 -14
  319. package/dist/ui/heading-dropdown-menu/index.js +0 -308
  320. package/dist/ui/heading-dropdown-menu/index.mjs +0 -10
  321. package/dist/ui/link-bubble/index.d.mts +0 -13
  322. package/dist/ui/link-bubble/index.d.ts +0 -13
  323. package/dist/ui/link-bubble/index.js +0 -183
  324. package/dist/ui/link-bubble/index.mjs +0 -10
  325. package/dist/ui/link-popover/index.d.mts +0 -7
  326. package/dist/ui/link-popover/index.d.ts +0 -7
  327. package/dist/ui/link-popover/index.js +0 -512
  328. package/dist/ui/link-popover/index.mjs +0 -30
  329. package/dist/ui/link-popover/link-popover.d.mts +0 -85
  330. package/dist/ui/link-popover/link-popover.d.ts +0 -85
  331. package/dist/ui/link-popover/link-popover.js +0 -498
  332. package/dist/ui/link-popover/link-popover.mjs +0 -16
  333. package/dist/ui/link-popover/use-link-popover.d.mts +0 -123
  334. package/dist/ui/link-popover/use-link-popover.d.ts +0 -123
  335. package/dist/ui/link-popover/use-link-popover.js +0 -259
  336. package/dist/ui/link-popover/use-link-popover.mjs +0 -20
  337. package/dist/ui/list-button/index.d.mts +0 -50
  338. package/dist/ui/list-button/index.d.ts +0 -50
  339. package/dist/ui/list-button/index.js +0 -232
  340. package/dist/ui/list-button/index.mjs +0 -24
  341. package/dist/ui/list-dropdown-menu/index.d.mts +0 -45
  342. package/dist/ui/list-dropdown-menu/index.d.ts +0 -45
  343. package/dist/ui/list-dropdown-menu/index.js +0 -361
  344. package/dist/ui/list-dropdown-menu/index.mjs +0 -21
  345. package/dist/ui/mark-button/index.d.mts +0 -59
  346. package/dist/ui/mark-button/index.d.ts +0 -59
  347. package/dist/ui/mark-button/index.js +0 -217
  348. package/dist/ui/mark-button/index.mjs +0 -26
  349. package/dist/ui/reset-all-formatting-button/index.d.mts +0 -7
  350. package/dist/ui/reset-all-formatting-button/index.d.ts +0 -7
  351. package/dist/ui/reset-all-formatting-button/index.js +0 -286
  352. package/dist/ui/reset-all-formatting-button/index.mjs +0 -26
  353. package/dist/ui/reset-all-formatting-button/reset-all-formatting-button.d.mts +0 -30
  354. package/dist/ui/reset-all-formatting-button/reset-all-formatting-button.d.ts +0 -30
  355. package/dist/ui/reset-all-formatting-button/reset-all-formatting-button.js +0 -271
  356. package/dist/ui/reset-all-formatting-button/reset-all-formatting-button.mjs +0 -12
  357. package/dist/ui/reset-all-formatting-button/use-reset-all-formatting.d.mts +0 -103
  358. package/dist/ui/reset-all-formatting-button/use-reset-all-formatting.d.ts +0 -103
  359. package/dist/ui/reset-all-formatting-button/use-reset-all-formatting.js +0 -211
  360. package/dist/ui/reset-all-formatting-button/use-reset-all-formatting.mjs +0 -21
  361. package/dist/ui/slash-dropdown-menu/index.d.mts +0 -10
  362. package/dist/ui/slash-dropdown-menu/index.d.ts +0 -10
  363. package/dist/ui/slash-dropdown-menu/index.js +0 -1056
  364. package/dist/ui/slash-dropdown-menu/index.mjs +0 -19
  365. package/dist/ui/slash-dropdown-menu/slash-dropdown-menu.d.mts +0 -16
  366. package/dist/ui/slash-dropdown-menu/slash-dropdown-menu.d.ts +0 -16
  367. package/dist/ui/slash-dropdown-menu/slash-dropdown-menu.js +0 -1053
  368. package/dist/ui/slash-dropdown-menu/slash-dropdown-menu.mjs +0 -16
  369. package/dist/ui/slash-dropdown-menu/use-slash-dropdown-menu.d.mts +0 -162
  370. package/dist/ui/slash-dropdown-menu/use-slash-dropdown-menu.d.ts +0 -162
  371. package/dist/ui/slash-dropdown-menu/use-slash-dropdown-menu.js +0 -457
  372. package/dist/ui/slash-dropdown-menu/use-slash-dropdown-menu.mjs +0 -10
  373. package/dist/ui/suggestion-menu/index.d.mts +0 -10
  374. package/dist/ui/suggestion-menu/index.d.ts +0 -10
  375. package/dist/ui/suggestion-menu/index.js +0 -489
  376. package/dist/ui/suggestion-menu/index.mjs +0 -17
  377. package/dist/ui/suggestion-menu/suggestion-menu-types.d.mts +0 -89
  378. package/dist/ui/suggestion-menu/suggestion-menu-types.d.ts +0 -89
  379. package/dist/ui/suggestion-menu/suggestion-menu-types.js +0 -19
  380. package/dist/ui/suggestion-menu/suggestion-menu-types.mjs +0 -1
  381. package/dist/ui/suggestion-menu/suggestion-menu-utils.d.mts +0 -27
  382. package/dist/ui/suggestion-menu/suggestion-menu-utils.d.ts +0 -27
  383. package/dist/ui/suggestion-menu/suggestion-menu-utils.js +0 -75
  384. package/dist/ui/suggestion-menu/suggestion-menu-utils.mjs +0 -9
  385. package/dist/ui/suggestion-menu/suggestion-menu.d.mts +0 -15
  386. package/dist/ui/suggestion-menu/suggestion-menu.d.ts +0 -15
  387. package/dist/ui/suggestion-menu/suggestion-menu.js +0 -453
  388. package/dist/ui/suggestion-menu/suggestion-menu.mjs +0 -12
  389. package/dist/ui/table-button/index.d.mts +0 -15
  390. package/dist/ui/table-button/index.d.ts +0 -15
  391. package/dist/ui/table-button/index.js +0 -202
  392. package/dist/ui/table-button/index.mjs +0 -9
  393. package/dist/ui/table-button/use-table.d.mts +0 -51
  394. package/dist/ui/table-button/use-table.d.ts +0 -51
  395. package/dist/ui/table-button/use-table.js +0 -146
  396. package/dist/ui/table-button/use-table.mjs +0 -14
  397. package/dist/ui/text-align-button/index.d.mts +0 -6
  398. package/dist/ui/text-align-button/index.d.ts +0 -6
  399. package/dist/ui/text-align-button/index.js +0 -235
  400. package/dist/ui/text-align-button/index.mjs +0 -29
  401. package/dist/ui/text-align-button/text-align-button.d.mts +0 -20
  402. package/dist/ui/text-align-button/text-align-button.d.ts +0 -20
  403. package/dist/ui/text-align-button/text-align-button.js +0 -215
  404. package/dist/ui/text-align-button/text-align-button.mjs +0 -9
  405. package/dist/ui/text-align-button/use-text-align.d.mts +0 -106
  406. package/dist/ui/text-align-button/use-text-align.d.ts +0 -106
  407. package/dist/ui/text-align-button/use-text-align.js +0 -169
  408. package/dist/ui/text-align-button/use-text-align.mjs +0 -24
  409. package/dist/ui/undo-redo-button/index.d.mts +0 -6
  410. package/dist/ui/undo-redo-button/index.d.ts +0 -6
  411. package/dist/ui/undo-redo-button/index.js +0 -202
  412. package/dist/ui/undo-redo-button/index.mjs +0 -25
  413. package/dist/ui/undo-redo-button/undo-redo-button.d.mts +0 -23
  414. package/dist/ui/undo-redo-button/undo-redo-button.d.ts +0 -23
  415. package/dist/ui/undo-redo-button/undo-redo-button.js +0 -187
  416. package/dist/ui/undo-redo-button/undo-redo-button.mjs +0 -10
  417. package/dist/ui/undo-redo-button/use-undo-redo.d.mts +0 -95
  418. package/dist/ui/undo-redo-button/use-undo-redo.d.ts +0 -95
  419. package/dist/ui/undo-redo-button/use-undo-redo.js +0 -146
  420. package/dist/ui/undo-redo-button/use-undo-redo.mjs +0 -21
  421. package/dist/utils/index.d.mts +0 -38
  422. package/dist/utils/index.d.ts +0 -38
  423. package/dist/utils/index.js +0 -128
  424. package/dist/utils/index.mjs +0 -15
  425. package/dist/utils/safe-parse.d.mts +0 -14
  426. package/dist/utils/safe-parse.d.ts +0 -14
  427. package/dist/utils/safe-parse.js +0 -203
  428. package/dist/utils/safe-parse.mjs +0 -8
@@ -1,2726 +0,0 @@
1
- "use client";
2
- "use strict";
3
- var __create = Object.create;
4
- var __defProp = Object.defineProperty;
5
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
- var __getOwnPropNames = Object.getOwnPropertyNames;
7
- var __getProtoOf = Object.getPrototypeOf;
8
- var __hasOwnProp = Object.prototype.hasOwnProperty;
9
- var __export = (target, all) => {
10
- for (var name in all)
11
- __defProp(target, name, { get: all[name], enumerable: true });
12
- };
13
- var __copyProps = (to, from, except, desc) => {
14
- if (from && typeof from === "object" || typeof from === "function") {
15
- for (let key of __getOwnPropNames(from))
16
- if (!__hasOwnProp.call(to, key) && key !== except)
17
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
18
- }
19
- return to;
20
- };
21
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
- // If the importer is in node compatibility mode or this is not an ESM
23
- // file that has been converted to a CommonJS file using a Babel-
24
- // compatible transform (i.e. "__esModule" has not been set), then set
25
- // "default" to the CommonJS "module.exports" for node compatibility.
26
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
- mod
28
- ));
29
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
30
-
31
- // src/hooks/use-create-editor.ts
32
- var use_create_editor_exports = {};
33
- __export(use_create_editor_exports, {
34
- getExtensions: () => getExtensions,
35
- useCreateEditor: () => useCreateEditor
36
- });
37
- module.exports = __toCommonJS(use_create_editor_exports);
38
- var import_extension_code = require("@kopexa/extension-code");
39
- var import_extension_controlref = require("@kopexa/extension-controlref");
40
- var import_extension_table = require("@kopexa/extension-table");
41
- var import_extension_file_handler = require("@tiptap/extension-file-handler");
42
- var import_extension_highlight = require("@tiptap/extension-highlight");
43
- var import_extension_invisible_characters = __toESM(require("@tiptap/extension-invisible-characters"));
44
- var import_extension_list = require("@tiptap/extension-list");
45
- var import_extension_subscript = require("@tiptap/extension-subscript");
46
- var import_extension_superscript = require("@tiptap/extension-superscript");
47
- var import_extension_table_of_contents = require("@tiptap/extension-table-of-contents");
48
- var import_extension_text_align = require("@tiptap/extension-text-align");
49
- var import_extension_text_style = require("@tiptap/extension-text-style");
50
- var import_extension_typography = require("@tiptap/extension-typography");
51
- var import_extension_unique_id = require("@tiptap/extension-unique-id");
52
- var import_extensions = require("@tiptap/extensions");
53
- var import_react27 = require("@tiptap/react");
54
- var import_starter_kit = require("@tiptap/starter-kit");
55
- var import_react28 = require("react");
56
-
57
- // src/context/editor-file-context.tsx
58
- var import_react = require("react");
59
- var import_jsx_runtime = require("react/jsx-runtime");
60
- var EditorFileContext = (0, import_react.createContext)(null);
61
- var DEFAULT_CACHE_BUFFER = 2 * 60 * 1e3;
62
- var DEFAULT_CACHE_TTL = 10 * 60 * 1e3;
63
- function useEditorFile() {
64
- return (0, import_react.useContext)(EditorFileContext);
65
- }
66
-
67
- // src/extensions/callout/index.ts
68
- var import_core = require("@tiptap/core");
69
- var import_react5 = require("@tiptap/react");
70
-
71
- // src/extensions/callout/callout-view.tsx
72
- var import_icons2 = require("@kopexa/icons");
73
- var import_theme = require("@kopexa/theme");
74
- var import_react3 = require("@tiptap/react");
75
- var import_react4 = require("react");
76
-
77
- // src/extensions/callout/callout-settings.tsx
78
- var import_button = require("@kopexa/button");
79
- var import_dialog = require("@kopexa/dialog");
80
- var import_icons = require("@kopexa/icons");
81
- var import_input = require("@kopexa/input");
82
- var import_label = require("@kopexa/label");
83
- var import_select = require("@kopexa/select");
84
- var import_react2 = require("react");
85
- var import_react_intl2 = require("react-intl");
86
-
87
- // src/extensions/callout/messages.ts
88
- var import_react_intl = require("react-intl");
89
- var messages = (0, import_react_intl.defineMessages)({
90
- settings: {
91
- id: "editor.callout.settings",
92
- defaultMessage: "Settings",
93
- description: "Settings button label"
94
- },
95
- variant: {
96
- id: "editor.callout.variant",
97
- defaultMessage: "Variant",
98
- description: "Variant setting label"
99
- },
100
- variant_default: {
101
- id: "editor.callout.variant_default",
102
- defaultMessage: "Default",
103
- description: "Default variant option"
104
- },
105
- variant_info: {
106
- id: "editor.callout.variant_info",
107
- defaultMessage: "Info",
108
- description: "Info variant option"
109
- },
110
- variant_success: {
111
- id: "editor.callout.variant_success",
112
- defaultMessage: "Success",
113
- description: "Success variant option"
114
- },
115
- variant_warning: {
116
- id: "editor.callout.variant_warning",
117
- defaultMessage: "Warning",
118
- description: "Warning variant option"
119
- },
120
- variant_destructive: {
121
- id: "editor.callout.variant_destructive",
122
- defaultMessage: "Error",
123
- description: "Destructive/Error variant option"
124
- },
125
- title: {
126
- id: "editor.callout.title",
127
- defaultMessage: "Title",
128
- description: "Title input label"
129
- },
130
- title_placeholder: {
131
- id: "editor.callout.title_placeholder",
132
- defaultMessage: "Optional title...",
133
- description: "Title input placeholder"
134
- },
135
- save: {
136
- id: "editor.callout.save",
137
- defaultMessage: "Save",
138
- description: "Save button label"
139
- },
140
- cancel: {
141
- id: "editor.callout.cancel",
142
- defaultMessage: "Cancel",
143
- description: "Cancel button label"
144
- }
145
- });
146
-
147
- // src/extensions/callout/callout-settings.tsx
148
- var import_jsx_runtime2 = require("react/jsx-runtime");
149
- var VARIANTS = [
150
- { value: "default", messageKey: "variant_default" },
151
- { value: "info", messageKey: "variant_info" },
152
- { value: "success", messageKey: "variant_success" },
153
- { value: "warning", messageKey: "variant_warning" },
154
- { value: "destructive", messageKey: "variant_destructive" }
155
- ];
156
- function CalloutSettings({
157
- editor,
158
- attrs,
159
- getPos
160
- }) {
161
- const intl = (0, import_react_intl2.useIntl)();
162
- const [isOpen, setIsOpen] = (0, import_react2.useState)(false);
163
- const [localAttrs, setLocalAttrs] = (0, import_react2.useState)(attrs);
164
- (0, import_react2.useEffect)(() => {
165
- if (isOpen) {
166
- setLocalAttrs(attrs);
167
- }
168
- }, [isOpen, attrs]);
169
- const handleSave = (0, import_react2.useCallback)(() => {
170
- const pos = getPos();
171
- if (pos === void 0) return;
172
- editor.view.dispatch(
173
- editor.state.tr.setNodeMarkup(pos, void 0, localAttrs)
174
- );
175
- setIsOpen(false);
176
- }, [editor, localAttrs, getPos]);
177
- const handleCancel = (0, import_react2.useCallback)(() => {
178
- setLocalAttrs(attrs);
179
- setIsOpen(false);
180
- }, [attrs]);
181
- const handleVariantChange = (0, import_react2.useCallback)((value) => {
182
- setLocalAttrs((prev) => ({
183
- ...prev,
184
- variant: String(value)
185
- }));
186
- }, []);
187
- const handleTitleChange = (0, import_react2.useCallback)(
188
- (e) => {
189
- const value = e.target.value;
190
- setLocalAttrs((prev) => ({
191
- ...prev,
192
- title: value || null
193
- }));
194
- },
195
- []
196
- );
197
- if (!editor.isEditable) {
198
- return null;
199
- }
200
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
201
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
202
- import_button.IconButton,
203
- {
204
- size: "sm",
205
- variant: "ghost",
206
- "aria-label": intl.formatMessage(messages.settings),
207
- onClick: (e) => {
208
- e.stopPropagation();
209
- e.preventDefault();
210
- setIsOpen(true);
211
- },
212
- children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_icons.SettingsIcon, { className: "size-3.5" })
213
- }
214
- ),
215
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dialog.Dialog.Root, { open: isOpen, onOpenChange: setIsOpen, size: "sm", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_dialog.Dialog.Content, { children: [
216
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dialog.Dialog.Header, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dialog.Dialog.Title, { children: intl.formatMessage(messages.settings) }) }),
217
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_dialog.Dialog.Body, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "space-y-4", children: [
218
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "space-y-1.5", children: [
219
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_label.Label, { className: "text-sm", children: intl.formatMessage(messages.variant) }),
220
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
221
- import_select.Select,
222
- {
223
- size: "sm",
224
- value: localAttrs.variant,
225
- onValueChange: handleVariantChange,
226
- children: [
227
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_select.Select.Trigger, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_select.Select.Value, {}) }),
228
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_select.Select.Content, { children: VARIANTS.map((v) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_select.Select.Item, { value: v.value, children: intl.formatMessage(messages[v.messageKey]) }, v.value)) })
229
- ]
230
- }
231
- )
232
- ] }),
233
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "space-y-1.5", children: [
234
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_label.Label, { className: "text-sm", children: intl.formatMessage(messages.title) }),
235
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
236
- import_input.Input,
237
- {
238
- size: "sm",
239
- value: localAttrs.title || "",
240
- onChange: handleTitleChange,
241
- placeholder: intl.formatMessage(messages.title_placeholder)
242
- }
243
- )
244
- ] })
245
- ] }) }),
246
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_dialog.Dialog.Footer, { children: [
247
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_button.Button, { variant: "ghost", onClick: handleCancel, children: intl.formatMessage(messages.cancel) }),
248
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_button.Button, { onClick: handleSave, children: intl.formatMessage(messages.save) })
249
- ] })
250
- ] }) })
251
- ] });
252
- }
253
-
254
- // src/extensions/callout/callout-view.tsx
255
- var import_jsx_runtime3 = require("react/jsx-runtime");
256
- function getVariantIcon(variant, iconClass) {
257
- switch (variant) {
258
- case "info":
259
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_icons2.InfoIcon, { className: iconClass });
260
- case "success":
261
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_icons2.CheckCirleIcon, { className: iconClass });
262
- case "warning":
263
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_icons2.AlertIcon, { className: iconClass });
264
- case "destructive":
265
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_icons2.AlertCircleIcon, { className: iconClass });
266
- default:
267
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_icons2.ShellIcon, { className: iconClass });
268
- }
269
- }
270
- function CalloutNodeView({ editor, node, getPos }) {
271
- const attrs = node.attrs;
272
- const { variant = "info", title } = attrs;
273
- const isEditable = (0, import_react3.useEditorState)({
274
- editor,
275
- selector: ({ editor: e }) => {
276
- var _a;
277
- return (_a = e == null ? void 0 : e.isEditable) != null ? _a : false;
278
- }
279
- });
280
- const styles = (0, import_react4.useMemo)(
281
- () => (0, import_theme.callout)({
282
- variant,
283
- radius: "md",
284
- size: "md"
285
- }),
286
- [variant]
287
- );
288
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
289
- import_react3.NodeViewWrapper,
290
- {
291
- className: styles.root(),
292
- "data-type": "callout",
293
- "data-variant": variant,
294
- children: [
295
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: styles.iconContainer(), children: getVariantIcon(variant, styles.icon()) }),
296
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: styles.content(), children: [
297
- title && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: styles.title(), children: title }),
298
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react3.NodeViewContent, { className: "callout-content" })
299
- ] }),
300
- isEditable && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "absolute top-2 right-2", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
301
- CalloutSettings,
302
- {
303
- editor,
304
- attrs,
305
- getPos
306
- }
307
- ) })
308
- ]
309
- }
310
- );
311
- }
312
-
313
- // src/extensions/callout/index.ts
314
- var CalloutNode = import_core.Node.create({
315
- name: "calloutNode",
316
- group: "block",
317
- content: "block+",
318
- defining: true,
319
- draggable: true,
320
- addOptions() {
321
- return {
322
- HTMLAttributes: {}
323
- };
324
- },
325
- addAttributes() {
326
- return {
327
- variant: {
328
- default: "info",
329
- parseHTML: (element) => element.getAttribute("data-variant") || "info",
330
- renderHTML: (attributes) => ({
331
- "data-variant": attributes.variant
332
- })
333
- },
334
- title: {
335
- default: null,
336
- parseHTML: (element) => element.getAttribute("data-title") || null,
337
- renderHTML: (attributes) => {
338
- if (!attributes.title) return {};
339
- return {
340
- "data-title": attributes.title
341
- };
342
- }
343
- }
344
- };
345
- },
346
- parseHTML() {
347
- return [
348
- {
349
- tag: 'div[data-type="callout"]'
350
- }
351
- ];
352
- },
353
- renderHTML({ HTMLAttributes }) {
354
- return [
355
- "div",
356
- (0, import_core.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes, {
357
- "data-type": "callout"
358
- }),
359
- 0
360
- ];
361
- },
362
- addNodeView() {
363
- return (0, import_react5.ReactNodeViewRenderer)(CalloutNodeView);
364
- },
365
- addCommands() {
366
- return {
367
- insertCallout: (variant = "info") => ({ commands }) => {
368
- return commands.insertContent({
369
- type: this.name,
370
- attrs: { variant },
371
- content: [
372
- {
373
- type: "paragraph"
374
- }
375
- ]
376
- });
377
- },
378
- updateCalloutSettings: (attrs) => ({ tr, state, dispatch }) => {
379
- const { selection } = state;
380
- const node = state.doc.nodeAt(selection.from);
381
- if ((node == null ? void 0 : node.type.name) !== this.name) {
382
- return false;
383
- }
384
- if (dispatch) {
385
- tr.setNodeMarkup(selection.from, void 0, {
386
- ...node.attrs,
387
- ...attrs
388
- });
389
- }
390
- return true;
391
- }
392
- };
393
- },
394
- addKeyboardShortcuts() {
395
- return {
396
- // Allow backspace at start to lift content out of callout
397
- Backspace: ({ editor }) => {
398
- var _a;
399
- const { state } = editor;
400
- const { selection } = state;
401
- const { $from } = selection;
402
- if ($from.parent.type.name === "paragraph" && $from.parentOffset === 0) {
403
- const calloutNode = $from.node(-1);
404
- if ((calloutNode == null ? void 0 : calloutNode.type.name) === this.name) {
405
- if (calloutNode.childCount === 1 && ((_a = calloutNode.firstChild) == null ? void 0 : _a.textContent) === "") {
406
- return editor.commands.deleteNode(this.name);
407
- }
408
- }
409
- }
410
- return false;
411
- }
412
- };
413
- }
414
- });
415
-
416
- // src/extensions/image/index.ts
417
- var import_extension_image = require("@tiptap/extension-image");
418
- var import_react8 = require("@tiptap/react");
419
-
420
- // src/extensions/image/image-view.tsx
421
- var import_button2 = require("@kopexa/button");
422
- var import_icons3 = require("@kopexa/icons");
423
- var import_theme2 = require("@kopexa/theme");
424
- var import_react6 = require("@tiptap/react");
425
- var import_react7 = require("react");
426
- var import_react_intl4 = require("react-intl");
427
-
428
- // src/extensions/image/messages.ts
429
- var import_react_intl3 = require("react-intl");
430
- var messages2 = (0, import_react_intl3.defineMessages)({
431
- loading: {
432
- id: "editor.image.loading",
433
- defaultMessage: "Loading image..."
434
- },
435
- uploading: {
436
- id: "editor.image.uploading",
437
- defaultMessage: "Uploading..."
438
- },
439
- error: {
440
- id: "editor.image.error",
441
- defaultMessage: "Failed to load image"
442
- },
443
- upload_error: {
444
- id: "editor.image.upload_error",
445
- defaultMessage: "Failed to upload image"
446
- },
447
- retry: {
448
- id: "editor.image.retry",
449
- defaultMessage: "Retry"
450
- },
451
- remove: {
452
- id: "editor.image.remove",
453
- defaultMessage: "Remove"
454
- }
455
- });
456
-
457
- // src/extensions/image/image-view.tsx
458
- var import_jsx_runtime4 = require("react/jsx-runtime");
459
- function ImageNodeView({ editor, node, getPos }) {
460
- var _a;
461
- const intl = (0, import_react_intl4.useIntl)();
462
- const fileHandler = useEditorFile();
463
- const { src, alt, title, uploadState, uploadProgress } = node.attrs;
464
- const isEditable = (0, import_react6.useEditorState)({
465
- editor,
466
- selector: ({ editor: e }) => {
467
- var _a2;
468
- return (_a2 = e == null ? void 0 : e.isEditable) != null ? _a2 : false;
469
- }
470
- });
471
- const [resolvedUrl, setResolvedUrl] = (0, import_react7.useState)(null);
472
- const [resolveState, setResolveState] = (0, import_react7.useState)("idle");
473
- const needsResolve = (_a = fileHandler == null ? void 0 : fileHandler.isReference(src)) != null ? _a : false;
474
- const resolveImage = (0, import_react7.useCallback)(async () => {
475
- if (!src) return;
476
- if (!needsResolve) {
477
- setResolvedUrl(src);
478
- setResolveState("resolved");
479
- return;
480
- }
481
- if (!fileHandler) {
482
- setResolvedUrl(src);
483
- setResolveState("resolved");
484
- return;
485
- }
486
- setResolveState("loading");
487
- try {
488
- const url = await fileHandler.resolve(src);
489
- setResolvedUrl(url);
490
- setResolveState("resolved");
491
- } catch {
492
- setResolveState("error");
493
- }
494
- }, [src, needsResolve, fileHandler]);
495
- (0, import_react7.useEffect)(() => {
496
- resolveImage();
497
- }, [resolveImage]);
498
- const handleRetry = (0, import_react7.useCallback)(() => {
499
- resolveImage();
500
- }, [resolveImage]);
501
- const handleRemove = (0, import_react7.useCallback)(() => {
502
- const pos = getPos();
503
- if (pos === void 0) return;
504
- editor.commands.deleteRange({
505
- from: pos,
506
- to: pos + node.nodeSize
507
- });
508
- }, [editor, getPos, node.nodeSize]);
509
- const errorStyles = (0, import_react7.useMemo)(
510
- () => (0, import_theme2.imagePlaceholder)({ size: "md", variant: "error" }),
511
- []
512
- );
513
- const loadingStyles = (0, import_react7.useMemo)(
514
- () => (0, import_theme2.imagePlaceholder)({ size: "md", variant: "uploading" }),
515
- []
516
- );
517
- if (uploadState === "uploading") {
518
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react6.NodeViewWrapper, { className: "my-4", "data-type": "image", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: loadingStyles.root(), children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: loadingStyles.content(), children: [
519
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "relative size-12", children: [
520
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
521
- "svg",
522
- {
523
- className: "size-12 -rotate-90",
524
- viewBox: "0 0 36 36",
525
- "aria-hidden": "true",
526
- children: [
527
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
528
- "circle",
529
- {
530
- cx: "18",
531
- cy: "18",
532
- r: "16",
533
- fill: "none",
534
- className: "stroke-muted",
535
- strokeWidth: "2"
536
- }
537
- ),
538
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
539
- "circle",
540
- {
541
- cx: "18",
542
- cy: "18",
543
- r: "16",
544
- fill: "none",
545
- className: "stroke-primary",
546
- strokeWidth: "2",
547
- strokeDasharray: 100,
548
- strokeDashoffset: 100 - (uploadProgress != null ? uploadProgress : 0),
549
- strokeLinecap: "round"
550
- }
551
- )
552
- ]
553
- }
554
- ),
555
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "absolute inset-0 flex items-center justify-center text-xs font-medium", children: [
556
- uploadProgress != null ? uploadProgress : 0,
557
- "%"
558
- ] })
559
- ] }),
560
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: loadingStyles.text(), children: intl.formatMessage(messages2.uploading) })
561
- ] }) }) });
562
- }
563
- if (uploadState === "error") {
564
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react6.NodeViewWrapper, { className: "my-4", "data-type": "image", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: errorStyles.root(), children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: errorStyles.content(), children: [
565
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_icons3.AlertCircleIcon, { className: errorStyles.icon() }),
566
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: errorStyles.text(), children: intl.formatMessage(messages2.upload_error) }),
567
- isEditable && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
568
- import_button2.IconButton,
569
- {
570
- size: "sm",
571
- variant: "ghost",
572
- onClick: handleRemove,
573
- "aria-label": intl.formatMessage(messages2.remove),
574
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_icons3.TrashIcon, { className: "size-4" })
575
- }
576
- )
577
- ] }) }) });
578
- }
579
- if (resolveState === "loading") {
580
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react6.NodeViewWrapper, { className: "my-4", "data-type": "image", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: `${loadingStyles.root()} animate-pulse`, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: loadingStyles.text(), children: intl.formatMessage(messages2.loading) }) }) });
581
- }
582
- if (resolveState === "error") {
583
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react6.NodeViewWrapper, { className: "my-4", "data-type": "image", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: errorStyles.root(), children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: errorStyles.content(), children: [
584
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_icons3.AlertCircleIcon, { className: errorStyles.icon() }),
585
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: errorStyles.text(), children: intl.formatMessage(messages2.error) }),
586
- isEditable && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex gap-2", children: [
587
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
588
- import_button2.IconButton,
589
- {
590
- size: "sm",
591
- variant: "outline",
592
- onClick: handleRetry,
593
- "aria-label": intl.formatMessage(messages2.retry),
594
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_icons3.ArrowCounterClockwiseIcon, { className: "size-4" })
595
- }
596
- ),
597
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
598
- import_button2.IconButton,
599
- {
600
- size: "sm",
601
- variant: "ghost",
602
- onClick: handleRemove,
603
- "aria-label": intl.formatMessage(messages2.remove),
604
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_icons3.TrashIcon, { className: "size-4" })
605
- }
606
- )
607
- ] })
608
- ] }) }) });
609
- }
610
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react6.NodeViewWrapper, { className: "my-4 relative group", "data-type": "image", children: [
611
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
612
- "img",
613
- {
614
- src: resolvedUrl != null ? resolvedUrl : src,
615
- alt: alt != null ? alt : "",
616
- title: title != null ? title : void 0,
617
- className: "max-w-full h-auto rounded-lg",
618
- draggable: false
619
- }
620
- ),
621
- isEditable && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "absolute top-2 right-2 opacity-0 group-hover:opacity-100 transition-opacity flex gap-1", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
622
- import_button2.IconButton,
623
- {
624
- size: "sm",
625
- variant: "outline",
626
- onClick: handleRemove,
627
- "aria-label": intl.formatMessage(messages2.remove),
628
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_icons3.TrashIcon, { className: "size-3.5" })
629
- }
630
- ) })
631
- ] });
632
- }
633
-
634
- // src/extensions/image/index.ts
635
- var ImageNode = import_extension_image.Image.extend({
636
- addAttributes() {
637
- var _a;
638
- return {
639
- ...(_a = this.parent) == null ? void 0 : _a.call(this),
640
- // Upload state for drag & drop / paste uploads
641
- uploadState: {
642
- default: null,
643
- rendered: false
644
- },
645
- uploadProgress: {
646
- default: null,
647
- rendered: false
648
- }
649
- };
650
- },
651
- addNodeView() {
652
- return (0, import_react8.ReactNodeViewRenderer)(ImageNodeView);
653
- }
654
- });
655
-
656
- // src/extensions/image-upload/index.ts
657
- var import_core2 = require("@tiptap/core");
658
- var import_react11 = require("@tiptap/react");
659
-
660
- // src/extensions/image-upload/image-upload-view.tsx
661
- var import_button3 = require("@kopexa/button");
662
- var import_icons4 = require("@kopexa/icons");
663
- var import_theme3 = require("@kopexa/theme");
664
- var import_react9 = require("@tiptap/react");
665
- var import_react10 = require("react");
666
- var import_react_intl6 = require("react-intl");
667
-
668
- // src/extensions/image-upload/messages.ts
669
- var import_react_intl5 = require("react-intl");
670
- var messages3 = (0, import_react_intl5.defineMessages)({
671
- upload_error: {
672
- id: "editor.image.upload_error",
673
- defaultMessage: "Failed to upload image"
674
- },
675
- uploading: {
676
- id: "editor.image.uploading",
677
- defaultMessage: "Uploading..."
678
- },
679
- upload_placeholder: {
680
- id: "editor.image.upload_placeholder",
681
- defaultMessage: "Click to upload or drag & drop"
682
- },
683
- upload_hint: {
684
- id: "editor.image.upload_hint",
685
- defaultMessage: "PNG, JPG, GIF, WebP, SVG"
686
- },
687
- click_to_retry: {
688
- id: "editor.image.click_to_retry",
689
- defaultMessage: "Click to try again"
690
- },
691
- files_not_supported: {
692
- id: "editor.image.files_not_supported",
693
- defaultMessage: "File upload is not configured"
694
- },
695
- remove: {
696
- id: "editor.image.remove",
697
- defaultMessage: "Remove"
698
- }
699
- });
700
-
701
- // src/extensions/image-upload/image-upload-view.tsx
702
- var import_jsx_runtime5 = require("react/jsx-runtime");
703
- function ImageUploadNodeView({ editor, node, getPos }) {
704
- const intl = (0, import_react_intl6.useIntl)();
705
- const fileHandler = useEditorFile();
706
- const isEditable = (0, import_react9.useEditorState)({
707
- editor,
708
- selector: ({ editor: e }) => {
709
- var _a;
710
- return (_a = e == null ? void 0 : e.isEditable) != null ? _a : false;
711
- }
712
- });
713
- const [uploadState, setUploadState] = (0, import_react10.useState)("idle");
714
- const [uploadProgress, setUploadProgress] = (0, import_react10.useState)(0);
715
- const [isDragOver, setIsDragOver] = (0, import_react10.useState)(false);
716
- const fileInputRef = (0, import_react10.useRef)(null);
717
- const handleRemove = (0, import_react10.useCallback)(() => {
718
- const pos = getPos();
719
- if (pos === void 0) return;
720
- editor.commands.deleteRange({
721
- from: pos,
722
- to: pos + node.nodeSize
723
- });
724
- }, [editor, getPos, node.nodeSize]);
725
- const handleFileSelect = (0, import_react10.useCallback)(
726
- async (file) => {
727
- if (!fileHandler) return;
728
- const pos = getPos();
729
- if (pos === void 0) return;
730
- setUploadState("uploading");
731
- setUploadProgress(0);
732
- try {
733
- const ref = await fileHandler.upload(file, (percent) => {
734
- setUploadProgress(percent);
735
- });
736
- const currentPos = getPos();
737
- if (currentPos === void 0) return;
738
- editor.chain().focus().deleteRange({ from: currentPos, to: currentPos + node.nodeSize }).insertContentAt(currentPos, {
739
- type: "image",
740
- attrs: {
741
- src: ref,
742
- alt: file.name.replace(/\.[^/.]+$/, ""),
743
- title: file.name.replace(/\.[^/.]+$/, "")
744
- }
745
- }).run();
746
- } catch (error) {
747
- console.error("[ImageUpload] Upload failed:", error);
748
- setUploadState("error");
749
- setUploadProgress(0);
750
- }
751
- },
752
- [fileHandler, editor, getPos, node.nodeSize]
753
- );
754
- const handleInputChange = (0, import_react10.useCallback)(
755
- (e) => {
756
- var _a;
757
- const file = (_a = e.target.files) == null ? void 0 : _a[0];
758
- if (file) {
759
- handleFileSelect(file);
760
- }
761
- e.target.value = "";
762
- },
763
- [handleFileSelect]
764
- );
765
- const handleDrop = (0, import_react10.useCallback)(
766
- (e) => {
767
- e.preventDefault();
768
- e.stopPropagation();
769
- setIsDragOver(false);
770
- const file = e.dataTransfer.files[0];
771
- if (file == null ? void 0 : file.type.startsWith("image/")) {
772
- handleFileSelect(file);
773
- }
774
- },
775
- [handleFileSelect]
776
- );
777
- const handleDragOver = (0, import_react10.useCallback)((e) => {
778
- e.preventDefault();
779
- e.stopPropagation();
780
- }, []);
781
- const handleDragEnter = (0, import_react10.useCallback)((e) => {
782
- e.preventDefault();
783
- e.stopPropagation();
784
- setIsDragOver(true);
785
- }, []);
786
- const handleDragLeave = (0, import_react10.useCallback)((e) => {
787
- e.preventDefault();
788
- e.stopPropagation();
789
- if (!e.currentTarget.contains(e.relatedTarget)) {
790
- setIsDragOver(false);
791
- }
792
- }, []);
793
- const handleClick = (0, import_react10.useCallback)(() => {
794
- var _a;
795
- if (uploadState === "idle" || uploadState === "error") {
796
- (_a = fileInputRef.current) == null ? void 0 : _a.click();
797
- }
798
- }, [uploadState]);
799
- const styles = (0, import_react10.useMemo)(
800
- () => (0, import_theme3.imagePlaceholder)({
801
- size: "md",
802
- variant: isDragOver ? "default" : void 0
803
- }),
804
- [isDragOver]
805
- );
806
- const errorStyles = (0, import_react10.useMemo)(
807
- () => (0, import_theme3.imagePlaceholder)({ size: "md", variant: "error" }),
808
- []
809
- );
810
- const uploadingStyles = (0, import_react10.useMemo)(
811
- () => (0, import_theme3.imagePlaceholder)({ size: "md", variant: "uploading" }),
812
- []
813
- );
814
- const disabledStyles = (0, import_react10.useMemo)(
815
- () => (0, import_theme3.imagePlaceholder)({ size: "md", variant: "disabled" }),
816
- []
817
- );
818
- if (!fileHandler) {
819
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react9.NodeViewWrapper, { className: "my-4", "data-type": "image-upload", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: disabledStyles.root(), children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: disabledStyles.content(), children: [
820
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_icons4.ImageIcon, { className: disabledStyles.icon() }),
821
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: disabledStyles.text(), children: intl.formatMessage(messages3.files_not_supported) }),
822
- isEditable && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
823
- import_button3.IconButton,
824
- {
825
- size: "sm",
826
- variant: "ghost",
827
- onClick: handleRemove,
828
- "aria-label": intl.formatMessage(messages3.remove),
829
- children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_icons4.TrashIcon, { className: "size-4" })
830
- }
831
- )
832
- ] }) }) });
833
- }
834
- if (uploadState === "uploading") {
835
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react9.NodeViewWrapper, { className: "my-4", "data-type": "image-upload", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: uploadingStyles.root(), children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: uploadingStyles.content(), children: [
836
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "relative size-12", children: [
837
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
838
- "svg",
839
- {
840
- className: "size-12 -rotate-90",
841
- viewBox: "0 0 36 36",
842
- "aria-hidden": "true",
843
- children: [
844
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
845
- "circle",
846
- {
847
- cx: "18",
848
- cy: "18",
849
- r: "16",
850
- fill: "none",
851
- className: "stroke-muted",
852
- strokeWidth: "2"
853
- }
854
- ),
855
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
856
- "circle",
857
- {
858
- cx: "18",
859
- cy: "18",
860
- r: "16",
861
- fill: "none",
862
- className: "stroke-primary",
863
- strokeWidth: "2",
864
- strokeDasharray: 100,
865
- strokeDashoffset: 100 - uploadProgress,
866
- strokeLinecap: "round"
867
- }
868
- )
869
- ]
870
- }
871
- ),
872
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "absolute inset-0 flex items-center justify-center text-xs font-medium", children: [
873
- uploadProgress,
874
- "%"
875
- ] })
876
- ] }),
877
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: uploadingStyles.text(), children: intl.formatMessage(messages3.uploading) })
878
- ] }) }) });
879
- }
880
- if (uploadState === "error") {
881
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react9.NodeViewWrapper, { className: "my-4", "data-type": "image-upload", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: errorStyles.root(), onClick: handleClick, children: [
882
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: errorStyles.content(), children: [
883
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_icons4.AlertCircleIcon, { className: errorStyles.icon() }),
884
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: errorStyles.text(), children: intl.formatMessage(messages3.upload_error) }),
885
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: errorStyles.hint(), children: intl.formatMessage(messages3.click_to_retry) })
886
- ] }),
887
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
888
- "input",
889
- {
890
- ref: fileInputRef,
891
- type: "file",
892
- accept: "image/*",
893
- className: "hidden",
894
- onChange: handleInputChange
895
- }
896
- ),
897
- isEditable && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
898
- import_button3.IconButton,
899
- {
900
- size: "sm",
901
- variant: "ghost",
902
- className: errorStyles.removeButton(),
903
- onClick: (e) => {
904
- e.stopPropagation();
905
- handleRemove();
906
- },
907
- "aria-label": intl.formatMessage(messages3.remove),
908
- children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_icons4.TrashIcon, { className: "size-3.5" })
909
- }
910
- )
911
- ] }) });
912
- }
913
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react9.NodeViewWrapper, { className: "my-4", "data-type": "image-upload", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
914
- "div",
915
- {
916
- className: `${styles.root()} ${isDragOver ? "border-primary bg-primary/10" : ""}`,
917
- onClick: handleClick,
918
- onDrop: handleDrop,
919
- onDragOver: handleDragOver,
920
- onDragEnter: handleDragEnter,
921
- onDragLeave: handleDragLeave,
922
- children: [
923
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: styles.content(), children: [
924
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_icons4.UploadIcon, { className: styles.icon() }),
925
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: styles.text(), children: intl.formatMessage(messages3.upload_placeholder) }),
926
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: styles.hint(), children: intl.formatMessage(messages3.upload_hint) })
927
- ] }),
928
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
929
- "input",
930
- {
931
- ref: fileInputRef,
932
- type: "file",
933
- accept: "image/*",
934
- className: "hidden",
935
- onChange: handleInputChange
936
- }
937
- ),
938
- isEditable && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
939
- import_button3.IconButton,
940
- {
941
- size: "sm",
942
- variant: "ghost",
943
- className: styles.removeButton(),
944
- onClick: (e) => {
945
- e.stopPropagation();
946
- handleRemove();
947
- },
948
- "aria-label": intl.formatMessage(messages3.remove),
949
- children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_icons4.TrashIcon, { className: "size-3.5" })
950
- }
951
- )
952
- ]
953
- }
954
- ) });
955
- }
956
-
957
- // src/extensions/image-upload/index.ts
958
- var ImageUploadNode = import_core2.Node.create({
959
- name: "imageUpload",
960
- group: "block",
961
- atom: true,
962
- draggable: true,
963
- selectable: true,
964
- addOptions() {
965
- return {
966
- accept: "image/*",
967
- maxSize: 0,
968
- HTMLAttributes: {}
969
- };
970
- },
971
- addAttributes() {
972
- return {
973
- // Upload state tracking
974
- uploadState: {
975
- default: null,
976
- rendered: false
977
- },
978
- uploadProgress: {
979
- default: null,
980
- rendered: false
981
- }
982
- };
983
- },
984
- parseHTML() {
985
- return [
986
- {
987
- tag: 'div[data-type="image-upload"]'
988
- }
989
- ];
990
- },
991
- renderHTML({ HTMLAttributes }) {
992
- return ["div", { ...HTMLAttributes, "data-type": "image-upload" }];
993
- },
994
- addNodeView() {
995
- return (0, import_react11.ReactNodeViewRenderer)(ImageUploadNodeView);
996
- },
997
- addCommands() {
998
- return {
999
- setImageUpload: () => ({ commands }) => {
1000
- return commands.insertContent({
1001
- type: this.name
1002
- });
1003
- }
1004
- };
1005
- },
1006
- addKeyboardShortcuts() {
1007
- return {
1008
- Enter: ({ editor }) => {
1009
- const { selection } = editor.state;
1010
- const { $from } = selection;
1011
- const node = $from.nodeAfter;
1012
- if ((node == null ? void 0 : node.type.name) === "imageUpload" && editor.isActive("imageUpload")) {
1013
- const nodeEl = editor.view.nodeDOM($from.pos);
1014
- if (nodeEl instanceof HTMLElement) {
1015
- const input = nodeEl.querySelector('input[type="file"]');
1016
- if (input instanceof HTMLElement) {
1017
- input.click();
1018
- return true;
1019
- }
1020
- }
1021
- }
1022
- return false;
1023
- }
1024
- };
1025
- }
1026
- });
1027
-
1028
- // src/extensions/link/index.ts
1029
- var import_extension_link = __toESM(require("@tiptap/extension-link"));
1030
- var import_state = require("@tiptap/pm/state");
1031
- var import_react12 = require("@tiptap/react");
1032
- var Link = import_extension_link.default.extend({
1033
- inclusive: false,
1034
- parseHTML() {
1035
- return [
1036
- {
1037
- tag: 'a[href]:not([data-type="button"]):not([href *= "javascript:" i])'
1038
- }
1039
- ];
1040
- },
1041
- addProseMirrorPlugins() {
1042
- var _a;
1043
- const { editor } = this;
1044
- return [
1045
- ...((_a = this.parent) == null ? void 0 : _a.call(this)) || [],
1046
- new import_state.Plugin({
1047
- key: new import_state.PluginKey("linkKeyHandler"),
1048
- props: {
1049
- handleKeyDown: (_, event) => {
1050
- const { selection } = editor.state;
1051
- if (event.key === "Escape" && selection.empty !== true) {
1052
- editor.commands.focus(selection.to, { scrollIntoView: false });
1053
- }
1054
- return false;
1055
- },
1056
- handleClick(view, pos) {
1057
- const { schema, doc, tr } = view.state;
1058
- let range;
1059
- if (schema.marks.link) {
1060
- range = (0, import_react12.getMarkRange)(doc.resolve(pos), schema.marks.link);
1061
- }
1062
- if (!range) {
1063
- return;
1064
- }
1065
- const { from, to } = range;
1066
- const start = Math.min(from, to);
1067
- const end = Math.max(from, to);
1068
- if (pos < start || pos > end) {
1069
- return;
1070
- }
1071
- const $start = doc.resolve(start);
1072
- const $end = doc.resolve(end);
1073
- const transaction = tr.setSelection(
1074
- new import_state.TextSelection($start, $end)
1075
- );
1076
- view.dispatch(transaction);
1077
- }
1078
- }
1079
- })
1080
- ];
1081
- }
1082
- });
1083
-
1084
- // src/extensions/math/index.ts
1085
- var import_core4 = require("@tiptap/core");
1086
- var import_react18 = require("@tiptap/react");
1087
-
1088
- // src/extensions/math/math-block-view.tsx
1089
- var import_button4 = require("@kopexa/button");
1090
- var import_dialog2 = require("@kopexa/dialog");
1091
- var import_icons5 = require("@kopexa/icons");
1092
- var import_label2 = require("@kopexa/label");
1093
- var import_react13 = require("@tiptap/react");
1094
- var import_katex = __toESM(require("katex"));
1095
- var import_katex_min = require("katex/dist/katex.min.css");
1096
- var import_react14 = require("react");
1097
- var import_react_intl8 = require("react-intl");
1098
-
1099
- // src/extensions/math/messages.ts
1100
- var import_react_intl7 = require("react-intl");
1101
- var messages4 = (0, import_react_intl7.defineMessages)({
1102
- title: {
1103
- id: "editor.math.title",
1104
- defaultMessage: "Formula",
1105
- description: "Math block title"
1106
- },
1107
- edit: {
1108
- id: "editor.math.edit",
1109
- defaultMessage: "Edit",
1110
- description: "Edit button label"
1111
- },
1112
- preview: {
1113
- id: "editor.math.preview",
1114
- defaultMessage: "Preview",
1115
- description: "Preview section label"
1116
- },
1117
- latex_input: {
1118
- id: "editor.math.latex_input",
1119
- defaultMessage: "LaTeX",
1120
- description: "LaTeX input label"
1121
- },
1122
- latex_placeholder: {
1123
- id: "editor.math.latex_placeholder",
1124
- defaultMessage: "Enter LaTeX formula...",
1125
- description: "LaTeX input placeholder"
1126
- },
1127
- invalid_latex: {
1128
- id: "editor.math.invalid_latex",
1129
- defaultMessage: "Invalid LaTeX syntax",
1130
- description: "Error message for invalid LaTeX"
1131
- },
1132
- empty_formula: {
1133
- id: "editor.math.empty_formula",
1134
- defaultMessage: "Click to add formula",
1135
- description: "Placeholder for empty formula"
1136
- },
1137
- save: {
1138
- id: "editor.math.save",
1139
- defaultMessage: "Save",
1140
- description: "Save button label"
1141
- },
1142
- cancel: {
1143
- id: "editor.math.cancel",
1144
- defaultMessage: "Cancel",
1145
- description: "Cancel button label"
1146
- }
1147
- });
1148
-
1149
- // src/extensions/math/math-block-view.tsx
1150
- var import_jsx_runtime6 = require("react/jsx-runtime");
1151
- function MathBlockView({ editor, node, getPos }) {
1152
- const intl = (0, import_react_intl8.useIntl)();
1153
- const attrs = node.attrs;
1154
- const { latex = "" } = attrs;
1155
- const isEditable = (0, import_react13.useEditorState)({
1156
- editor,
1157
- selector: ({ editor: e }) => {
1158
- var _a;
1159
- return (_a = e == null ? void 0 : e.isEditable) != null ? _a : false;
1160
- }
1161
- });
1162
- const [isOpen, setIsOpen] = (0, import_react14.useState)(false);
1163
- const [localLatex, setLocalLatex] = (0, import_react14.useState)(latex);
1164
- const [error, setError] = (0, import_react14.useState)(null);
1165
- (0, import_react14.useEffect)(() => {
1166
- if (isOpen) {
1167
- setLocalLatex(latex);
1168
- setError(null);
1169
- }
1170
- }, [isOpen, latex]);
1171
- const renderedHtml = (0, import_react14.useMemo)(() => {
1172
- if (!latex) return null;
1173
- try {
1174
- return import_katex.default.renderToString(latex, {
1175
- throwOnError: false,
1176
- displayMode: true,
1177
- output: "html"
1178
- });
1179
- } catch {
1180
- return null;
1181
- }
1182
- }, [latex]);
1183
- const previewHtml = (0, import_react14.useMemo)(() => {
1184
- if (!localLatex) return null;
1185
- try {
1186
- setError(null);
1187
- return import_katex.default.renderToString(localLatex, {
1188
- throwOnError: true,
1189
- displayMode: true,
1190
- output: "html"
1191
- });
1192
- } catch (_e) {
1193
- setError(intl.formatMessage(messages4.invalid_latex));
1194
- return null;
1195
- }
1196
- }, [localLatex, intl]);
1197
- const handleSave = (0, import_react14.useCallback)(() => {
1198
- const pos = getPos();
1199
- if (pos === void 0) return;
1200
- editor.view.dispatch(
1201
- editor.state.tr.setNodeMarkup(pos, void 0, { latex: localLatex })
1202
- );
1203
- setIsOpen(false);
1204
- }, [editor, localLatex, getPos]);
1205
- const handleCancel = (0, import_react14.useCallback)(() => {
1206
- setLocalLatex(latex);
1207
- setError(null);
1208
- setIsOpen(false);
1209
- }, [latex]);
1210
- const handleOpenEditor = (0, import_react14.useCallback)(
1211
- (e) => {
1212
- e.stopPropagation();
1213
- e.preventDefault();
1214
- if (isEditable) {
1215
- setIsOpen(true);
1216
- }
1217
- },
1218
- [isEditable]
1219
- );
1220
- const isEmpty = !latex;
1221
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1222
- import_react13.NodeViewWrapper,
1223
- {
1224
- className: "my-4 relative group",
1225
- "data-type": "math-block",
1226
- "data-latex": latex,
1227
- children: [
1228
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1229
- "button",
1230
- {
1231
- type: "button",
1232
- className: "w-full flex items-center justify-center min-h-16 p-4 rounded-md border border-border bg-muted/30 cursor-pointer hover:bg-muted/50 transition-colors",
1233
- onClick: handleOpenEditor,
1234
- children: isEmpty ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex items-center gap-2 text-muted-foreground", children: [
1235
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "text-lg font-serif", children: "\u2211" }),
1236
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "text-sm", children: intl.formatMessage(messages4.empty_formula) })
1237
- ] }) : renderedHtml ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1238
- "div",
1239
- {
1240
- className: "katex-display",
1241
- dangerouslySetInnerHTML: { __html: renderedHtml }
1242
- }
1243
- ) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "text-destructive text-sm", children: intl.formatMessage(messages4.invalid_latex) })
1244
- }
1245
- ),
1246
- isEditable && !isEmpty && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1247
- import_button4.IconButton,
1248
- {
1249
- size: "sm",
1250
- variant: "ghost",
1251
- className: "absolute top-2 right-2 opacity-0 group-hover:opacity-100 transition-opacity",
1252
- "aria-label": intl.formatMessage(messages4.edit),
1253
- onClick: handleOpenEditor,
1254
- children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_icons5.EditIcon, { className: "size-3.5" })
1255
- }
1256
- ),
1257
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_dialog2.Dialog.Root, { open: isOpen, onOpenChange: setIsOpen, size: "md", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_dialog2.Dialog.Content, { children: [
1258
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_dialog2.Dialog.Header, { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_dialog2.Dialog.Title, { children: intl.formatMessage(messages4.title) }) }),
1259
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_dialog2.Dialog.Body, { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "space-y-4", children: [
1260
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "space-y-1.5", children: [
1261
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_label2.Label, { className: "text-sm", children: intl.formatMessage(messages4.latex_input) }),
1262
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1263
- "textarea",
1264
- {
1265
- className: "w-full min-h-24 p-3 rounded-md border border-input bg-background font-mono text-sm resize-y focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
1266
- value: localLatex,
1267
- onChange: (e) => setLocalLatex(e.target.value),
1268
- placeholder: intl.formatMessage(messages4.latex_placeholder),
1269
- spellCheck: false
1270
- }
1271
- ),
1272
- error && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "text-xs text-destructive", children: error })
1273
- ] }),
1274
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "space-y-1.5", children: [
1275
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_label2.Label, { className: "text-sm", children: intl.formatMessage(messages4.preview) }),
1276
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "min-h-16 p-4 rounded-md border border-border bg-muted/30 flex items-center justify-center", children: previewHtml ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1277
- "div",
1278
- {
1279
- className: "katex-display",
1280
- dangerouslySetInnerHTML: { __html: previewHtml }
1281
- }
1282
- ) : localLatex ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "text-muted-foreground text-sm", children: intl.formatMessage(messages4.invalid_latex) }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "text-muted-foreground text-sm", children: intl.formatMessage(messages4.latex_placeholder) }) })
1283
- ] })
1284
- ] }) }),
1285
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_dialog2.Dialog.Footer, { children: [
1286
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_button4.Button, { variant: "ghost", onClick: handleCancel, children: intl.formatMessage(messages4.cancel) }),
1287
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_button4.Button, { onClick: handleSave, disabled: !!error && !!localLatex, children: intl.formatMessage(messages4.save) })
1288
- ] })
1289
- ] }) })
1290
- ]
1291
- }
1292
- );
1293
- }
1294
-
1295
- // src/extensions/math/inline-math.ts
1296
- var import_core3 = require("@tiptap/core");
1297
- var import_react17 = require("@tiptap/react");
1298
-
1299
- // src/extensions/math/inline-math-view.tsx
1300
- var import_button5 = require("@kopexa/button");
1301
- var import_dialog3 = require("@kopexa/dialog");
1302
- var import_label3 = require("@kopexa/label");
1303
- var import_react15 = require("@tiptap/react");
1304
- var import_katex2 = __toESM(require("katex"));
1305
- var import_katex_min2 = require("katex/dist/katex.min.css");
1306
- var import_react16 = require("react");
1307
- var import_react_intl9 = require("react-intl");
1308
- var import_jsx_runtime7 = require("react/jsx-runtime");
1309
- function InlineMathView({ editor, node, getPos }) {
1310
- const intl = (0, import_react_intl9.useIntl)();
1311
- const attrs = node.attrs;
1312
- const { latex = "" } = attrs;
1313
- const isEditable = (0, import_react15.useEditorState)({
1314
- editor,
1315
- selector: ({ editor: e }) => {
1316
- var _a;
1317
- return (_a = e == null ? void 0 : e.isEditable) != null ? _a : false;
1318
- }
1319
- });
1320
- const [isOpen, setIsOpen] = (0, import_react16.useState)(false);
1321
- const [localLatex, setLocalLatex] = (0, import_react16.useState)(latex);
1322
- const [error, setError] = (0, import_react16.useState)(null);
1323
- (0, import_react16.useEffect)(() => {
1324
- if (isOpen) {
1325
- setLocalLatex(latex);
1326
- setError(null);
1327
- }
1328
- }, [isOpen, latex]);
1329
- const renderedHtml = (0, import_react16.useMemo)(() => {
1330
- if (!latex) return null;
1331
- try {
1332
- return import_katex2.default.renderToString(latex, {
1333
- throwOnError: false,
1334
- displayMode: false,
1335
- output: "html"
1336
- });
1337
- } catch {
1338
- return null;
1339
- }
1340
- }, [latex]);
1341
- const previewHtml = (0, import_react16.useMemo)(() => {
1342
- if (!localLatex) return null;
1343
- try {
1344
- setError(null);
1345
- return import_katex2.default.renderToString(localLatex, {
1346
- throwOnError: true,
1347
- displayMode: false,
1348
- output: "html"
1349
- });
1350
- } catch (_e) {
1351
- setError(intl.formatMessage(messages4.invalid_latex));
1352
- return null;
1353
- }
1354
- }, [localLatex, intl]);
1355
- const handleSave = (0, import_react16.useCallback)(() => {
1356
- const pos = getPos();
1357
- if (pos === void 0) return;
1358
- editor.view.dispatch(
1359
- editor.state.tr.setNodeMarkup(pos, void 0, { latex: localLatex })
1360
- );
1361
- setIsOpen(false);
1362
- }, [editor, localLatex, getPos]);
1363
- const handleCancel = (0, import_react16.useCallback)(() => {
1364
- setLocalLatex(latex);
1365
- setError(null);
1366
- setIsOpen(false);
1367
- }, [latex]);
1368
- const handleClick = (0, import_react16.useCallback)(
1369
- (e) => {
1370
- e.stopPropagation();
1371
- e.preventDefault();
1372
- if (isEditable) {
1373
- setIsOpen(true);
1374
- }
1375
- },
1376
- [isEditable]
1377
- );
1378
- const isEmpty = !latex;
1379
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1380
- import_react15.NodeViewWrapper,
1381
- {
1382
- as: "span",
1383
- className: "inline-math-wrapper",
1384
- "data-type": "inline-math",
1385
- "data-latex": latex,
1386
- children: [
1387
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1388
- "span",
1389
- {
1390
- className: `inline-math cursor-pointer rounded px-0.5 transition-colors ${isEditable ? "hover:bg-primary/10 hover:ring-1 hover:ring-primary/20" : ""} ${isEmpty ? "text-muted-foreground italic" : ""}`,
1391
- onClick: handleClick,
1392
- children: isEmpty ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "text-xs", children: "$?$" }) : renderedHtml ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1393
- "span",
1394
- {
1395
- dangerouslySetInnerHTML: { __html: renderedHtml }
1396
- }
1397
- ) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "text-destructive text-xs", children: latex })
1398
- }
1399
- ),
1400
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_dialog3.Dialog.Root, { open: isOpen, onOpenChange: setIsOpen, size: "sm", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_dialog3.Dialog.Content, { children: [
1401
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_dialog3.Dialog.Header, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_dialog3.Dialog.Title, { children: intl.formatMessage(messages4.title) }) }),
1402
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_dialog3.Dialog.Body, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "space-y-4", children: [
1403
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "space-y-1.5", children: [
1404
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_label3.Label, { className: "text-sm", children: intl.formatMessage(messages4.latex_input) }),
1405
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1406
- "input",
1407
- {
1408
- type: "text",
1409
- className: "w-full p-2 rounded-md border border-input bg-background font-mono text-sm focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
1410
- value: localLatex,
1411
- onChange: (e) => setLocalLatex(e.target.value),
1412
- placeholder: intl.formatMessage(messages4.latex_placeholder),
1413
- spellCheck: false
1414
- }
1415
- ),
1416
- error && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "text-xs text-destructive", children: error })
1417
- ] }),
1418
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "space-y-1.5", children: [
1419
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_label3.Label, { className: "text-sm", children: intl.formatMessage(messages4.preview) }),
1420
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "min-h-10 p-3 rounded-md border border-border bg-muted/30 flex items-center justify-center", children: previewHtml ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1421
- "span",
1422
- {
1423
- dangerouslySetInnerHTML: { __html: previewHtml }
1424
- }
1425
- ) : localLatex ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "text-muted-foreground text-sm", children: intl.formatMessage(messages4.invalid_latex) }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "text-muted-foreground text-sm", children: "$...$" }) })
1426
- ] })
1427
- ] }) }),
1428
- /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_dialog3.Dialog.Footer, { children: [
1429
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_button5.Button, { variant: "ghost", onClick: handleCancel, children: intl.formatMessage(messages4.cancel) }),
1430
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_button5.Button, { onClick: handleSave, disabled: !!error && !!localLatex, children: intl.formatMessage(messages4.save) })
1431
- ] })
1432
- ] }) })
1433
- ]
1434
- }
1435
- );
1436
- }
1437
-
1438
- // src/extensions/math/inline-math.ts
1439
- var InlineMath = import_core3.Node.create({
1440
- name: "inlineMath",
1441
- group: "inline",
1442
- inline: true,
1443
- atom: true,
1444
- addOptions() {
1445
- return {
1446
- HTMLAttributes: {}
1447
- };
1448
- },
1449
- addAttributes() {
1450
- return {
1451
- latex: {
1452
- default: "",
1453
- parseHTML: (element) => element.getAttribute("data-latex") || "",
1454
- renderHTML: (attributes) => ({
1455
- "data-latex": attributes.latex
1456
- })
1457
- }
1458
- };
1459
- },
1460
- parseHTML() {
1461
- return [
1462
- {
1463
- tag: 'span[data-type="inline-math"]'
1464
- }
1465
- ];
1466
- },
1467
- renderHTML({ HTMLAttributes }) {
1468
- return [
1469
- "span",
1470
- (0, import_core3.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes, {
1471
- "data-type": "inline-math"
1472
- })
1473
- ];
1474
- },
1475
- addNodeView() {
1476
- return (0, import_react17.ReactNodeViewRenderer)(InlineMathView, {
1477
- as: "span"
1478
- });
1479
- },
1480
- addCommands() {
1481
- return {
1482
- insertInlineMath: (latex = "") => ({ commands }) => {
1483
- return commands.insertContent({
1484
- type: this.name,
1485
- attrs: { latex }
1486
- });
1487
- }
1488
- };
1489
- },
1490
- addInputRules() {
1491
- return [
1492
- // Inline math with $...$
1493
- new import_core3.InputRule({
1494
- // Match $...$ but not $$...$$
1495
- find: /(?<!\$)\$([^$]+)\$(?!\$)/,
1496
- handler: ({ state, range, match }) => {
1497
- const latex = match[1];
1498
- const { tr } = state;
1499
- tr.replaceWith(range.from, range.to, this.type.create({ latex }));
1500
- }
1501
- })
1502
- ];
1503
- }
1504
- });
1505
-
1506
- // src/extensions/math/index.ts
1507
- var MathBlock = import_core4.Node.create({
1508
- name: "mathBlock",
1509
- group: "block",
1510
- atom: true,
1511
- draggable: true,
1512
- addOptions() {
1513
- return {
1514
- HTMLAttributes: {}
1515
- };
1516
- },
1517
- addAttributes() {
1518
- return {
1519
- latex: {
1520
- default: "",
1521
- parseHTML: (element) => element.getAttribute("data-latex") || "",
1522
- renderHTML: (attributes) => ({
1523
- "data-latex": attributes.latex
1524
- })
1525
- }
1526
- };
1527
- },
1528
- parseHTML() {
1529
- return [
1530
- {
1531
- tag: 'div[data-type="math-block"]'
1532
- }
1533
- ];
1534
- },
1535
- renderHTML({ HTMLAttributes }) {
1536
- return [
1537
- "div",
1538
- (0, import_core4.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes, {
1539
- "data-type": "math-block"
1540
- })
1541
- ];
1542
- },
1543
- addNodeView() {
1544
- return (0, import_react18.ReactNodeViewRenderer)(MathBlockView);
1545
- },
1546
- addCommands() {
1547
- return {
1548
- insertMathBlock: (latex = "") => ({ commands }) => {
1549
- return commands.insertContent({
1550
- type: this.name,
1551
- attrs: { latex }
1552
- });
1553
- },
1554
- updateMathBlock: (latex) => ({ tr, state, dispatch }) => {
1555
- const { selection } = state;
1556
- const node = state.doc.nodeAt(selection.from);
1557
- if ((node == null ? void 0 : node.type.name) !== this.name) {
1558
- return false;
1559
- }
1560
- if (dispatch) {
1561
- tr.setNodeMarkup(selection.from, void 0, {
1562
- ...node.attrs,
1563
- latex
1564
- });
1565
- }
1566
- return true;
1567
- }
1568
- };
1569
- },
1570
- addInputRules() {
1571
- return [
1572
- // Block math with $$...$$
1573
- new import_core4.InputRule({
1574
- find: /^\$\$(.+)\$\$$/,
1575
- handler: ({ state, range, match }) => {
1576
- const latex = match[1];
1577
- const { tr } = state;
1578
- tr.replaceWith(range.from, range.to, this.type.create({ latex }));
1579
- }
1580
- })
1581
- ];
1582
- }
1583
- });
1584
-
1585
- // src/extensions/selection/index.ts
1586
- var import_state2 = require("@tiptap/pm/state");
1587
- var import_view = require("@tiptap/pm/view");
1588
- var import_react19 = require("@tiptap/react");
1589
- var Selection = import_react19.Extension.create({
1590
- name: "selection",
1591
- addProseMirrorPlugins() {
1592
- const { editor } = this;
1593
- return [
1594
- new import_state2.Plugin({
1595
- key: new import_state2.PluginKey("selection"),
1596
- props: {
1597
- decorations(state) {
1598
- if (state.selection.empty) {
1599
- return null;
1600
- }
1601
- if (editor.isFocused === true || !editor.isEditable) {
1602
- return null;
1603
- }
1604
- if ((0, import_react19.isNodeSelection)(state.selection)) {
1605
- return null;
1606
- }
1607
- return import_view.DecorationSet.create(state.doc, [
1608
- import_view.Decoration.inline(state.selection.from, state.selection.to, {
1609
- class: "selection"
1610
- })
1611
- ]);
1612
- }
1613
- }
1614
- })
1615
- ];
1616
- }
1617
- });
1618
-
1619
- // src/extensions/toc/index.ts
1620
- var import_core5 = require("@tiptap/core");
1621
- var import_react23 = require("@tiptap/react");
1622
-
1623
- // src/extensions/toc/toc-view.tsx
1624
- var import_icons7 = require("@kopexa/icons");
1625
- var import_theme4 = require("@kopexa/theme");
1626
- var import_react21 = require("@tiptap/react");
1627
- var import_react22 = require("react");
1628
- var import_react_intl12 = require("react-intl");
1629
-
1630
- // src/extensions/toc/messages.ts
1631
- var import_react_intl10 = require("react-intl");
1632
- var messages5 = (0, import_react_intl10.defineMessages)({
1633
- title: {
1634
- id: "editor.toc.title",
1635
- defaultMessage: "Table of Contents",
1636
- description: "Title of the table of contents"
1637
- },
1638
- save: {
1639
- id: "editor.toc.save",
1640
- defaultMessage: "Save",
1641
- description: "Save button label"
1642
- },
1643
- cancel: {
1644
- id: "editor.toc.cancel",
1645
- defaultMessage: "Cancel",
1646
- description: "Cancel button label"
1647
- },
1648
- empty_state: {
1649
- id: "editor.toc.empty_state",
1650
- defaultMessage: "No headings found. Add headings (H1-H6) to populate the table of contents.",
1651
- description: "Empty state when no headings are present"
1652
- },
1653
- empty_heading: {
1654
- id: "editor.toc.empty_heading",
1655
- defaultMessage: "(Empty heading)",
1656
- description: "Placeholder for empty heading text"
1657
- },
1658
- settings: {
1659
- id: "editor.toc.settings",
1660
- defaultMessage: "Settings",
1661
- description: "Settings button label"
1662
- },
1663
- min_level: {
1664
- id: "editor.toc.min_level",
1665
- defaultMessage: "Minimum level",
1666
- description: "Minimum heading level setting"
1667
- },
1668
- max_level: {
1669
- id: "editor.toc.max_level",
1670
- defaultMessage: "Maximum level",
1671
- description: "Maximum heading level setting"
1672
- },
1673
- numbered: {
1674
- id: "editor.toc.numbered",
1675
- defaultMessage: "Numbering",
1676
- description: "Numbering toggle label"
1677
- },
1678
- numbered_hint: {
1679
- id: "editor.toc.numbered_hint",
1680
- defaultMessage: "Show hierarchical numbering (1, 1.1, 1.1.1)",
1681
- description: "Hint for numbering toggle"
1682
- },
1683
- style: {
1684
- id: "editor.toc.style",
1685
- defaultMessage: "Style",
1686
- description: "Style setting label"
1687
- },
1688
- style_default: {
1689
- id: "editor.toc.style_default",
1690
- defaultMessage: "Default",
1691
- description: "Default style option"
1692
- },
1693
- style_flat: {
1694
- id: "editor.toc.style_flat",
1695
- defaultMessage: "Flat",
1696
- description: "Flat style option"
1697
- },
1698
- style_compact: {
1699
- id: "editor.toc.style_compact",
1700
- defaultMessage: "Compact",
1701
- description: "Compact style option"
1702
- }
1703
- });
1704
-
1705
- // src/extensions/toc/toc-settings.tsx
1706
- var import_button6 = require("@kopexa/button");
1707
- var import_dialog4 = require("@kopexa/dialog");
1708
- var import_icons6 = require("@kopexa/icons");
1709
- var import_label4 = require("@kopexa/label");
1710
- var import_select2 = require("@kopexa/select");
1711
- var import_switch = require("@kopexa/switch");
1712
- var import_react20 = require("react");
1713
- var import_react_intl11 = require("react-intl");
1714
- var import_jsx_runtime8 = require("react/jsx-runtime");
1715
- var HEADING_LEVELS = [
1716
- { value: "1", label: "H1" },
1717
- { value: "2", label: "H2" },
1718
- { value: "3", label: "H3" },
1719
- { value: "4", label: "H4" },
1720
- { value: "5", label: "H5" },
1721
- { value: "6", label: "H6" }
1722
- ];
1723
- function TocSettings({ editor, attrs, getPos }) {
1724
- const intl = (0, import_react_intl11.useIntl)();
1725
- const [isOpen, setIsOpen] = (0, import_react20.useState)(false);
1726
- const [localAttrs, setLocalAttrs] = (0, import_react20.useState)(attrs);
1727
- (0, import_react20.useEffect)(() => {
1728
- if (isOpen) {
1729
- setLocalAttrs(attrs);
1730
- }
1731
- }, [isOpen, attrs]);
1732
- const handleSave = (0, import_react20.useCallback)(() => {
1733
- const pos = getPos();
1734
- if (pos === void 0) return;
1735
- editor.view.dispatch(
1736
- editor.state.tr.setNodeMarkup(pos, void 0, localAttrs)
1737
- );
1738
- setIsOpen(false);
1739
- }, [editor, localAttrs, getPos]);
1740
- const handleCancel = (0, import_react20.useCallback)(() => {
1741
- setLocalAttrs(attrs);
1742
- setIsOpen(false);
1743
- }, [attrs]);
1744
- const handleMinLevelChange = (0, import_react20.useCallback)((value) => {
1745
- const minLevel = Number.parseInt(String(value), 10);
1746
- setLocalAttrs((prev) => ({
1747
- ...prev,
1748
- minLevel,
1749
- // Ensure maxLevel is not less than minLevel
1750
- maxLevel: Math.max(prev.maxLevel, minLevel)
1751
- }));
1752
- }, []);
1753
- const handleMaxLevelChange = (0, import_react20.useCallback)((value) => {
1754
- const maxLevel = Number.parseInt(String(value), 10);
1755
- setLocalAttrs((prev) => ({
1756
- ...prev,
1757
- maxLevel,
1758
- // Ensure minLevel is not greater than maxLevel
1759
- minLevel: Math.min(prev.minLevel, maxLevel)
1760
- }));
1761
- }, []);
1762
- const handleNumberedChange = (0, import_react20.useCallback)((checked) => {
1763
- setLocalAttrs((prev) => ({ ...prev, numbered: checked }));
1764
- }, []);
1765
- const handleStyleChange = (0, import_react20.useCallback)((value) => {
1766
- setLocalAttrs((prev) => ({
1767
- ...prev,
1768
- style: String(value)
1769
- }));
1770
- }, []);
1771
- if (!editor.isEditable) {
1772
- return null;
1773
- }
1774
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_jsx_runtime8.Fragment, { children: [
1775
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1776
- import_button6.IconButton,
1777
- {
1778
- size: "sm",
1779
- variant: "ghost",
1780
- "aria-label": intl.formatMessage(messages5.settings),
1781
- onClick: (e) => {
1782
- e.stopPropagation();
1783
- e.preventDefault();
1784
- setIsOpen(true);
1785
- },
1786
- children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_icons6.SettingsIcon, { className: "size-3.5" })
1787
- }
1788
- ),
1789
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_dialog4.Dialog.Root, { open: isOpen, onOpenChange: setIsOpen, size: "sm", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_dialog4.Dialog.Content, { children: [
1790
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_dialog4.Dialog.Header, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_dialog4.Dialog.Title, { children: intl.formatMessage(messages5.settings) }) }),
1791
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_dialog4.Dialog.Body, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "space-y-4", children: [
1792
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "grid grid-cols-2 gap-3", children: [
1793
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "space-y-1.5", children: [
1794
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_label4.Label, { className: "text-sm", children: intl.formatMessage(messages5.min_level) }),
1795
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1796
- import_select2.Select,
1797
- {
1798
- size: "sm",
1799
- value: String(localAttrs.minLevel),
1800
- onValueChange: handleMinLevelChange,
1801
- children: [
1802
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_select2.Select.Trigger, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_select2.Select.Value, {}) }),
1803
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_select2.Select.Content, { children: HEADING_LEVELS.map((level) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1804
- import_select2.Select.Item,
1805
- {
1806
- value: level.value,
1807
- disabled: Number.parseInt(level.value, 10) > localAttrs.maxLevel,
1808
- children: level.label
1809
- },
1810
- level.value
1811
- )) })
1812
- ]
1813
- }
1814
- )
1815
- ] }),
1816
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "space-y-1.5", children: [
1817
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_label4.Label, { className: "text-sm", children: intl.formatMessage(messages5.max_level) }),
1818
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1819
- import_select2.Select,
1820
- {
1821
- size: "sm",
1822
- value: String(localAttrs.maxLevel),
1823
- onValueChange: handleMaxLevelChange,
1824
- children: [
1825
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_select2.Select.Trigger, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_select2.Select.Value, {}) }),
1826
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_select2.Select.Content, { children: HEADING_LEVELS.map((level) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1827
- import_select2.Select.Item,
1828
- {
1829
- value: level.value,
1830
- disabled: Number.parseInt(level.value, 10) < localAttrs.minLevel,
1831
- children: level.label
1832
- },
1833
- level.value
1834
- )) })
1835
- ]
1836
- }
1837
- )
1838
- ] })
1839
- ] }),
1840
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "flex items-center justify-between gap-2", children: [
1841
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "space-y-0.5", children: [
1842
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_label4.Label, { className: "text-sm", children: intl.formatMessage(messages5.numbered) }),
1843
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "text-xs text-muted-foreground", children: intl.formatMessage(messages5.numbered_hint) })
1844
- ] }),
1845
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1846
- import_switch.Switch,
1847
- {
1848
- size: "sm",
1849
- checked: localAttrs.numbered,
1850
- onCheckedChange: handleNumberedChange
1851
- }
1852
- )
1853
- ] }),
1854
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "space-y-1.5", children: [
1855
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_label4.Label, { className: "text-sm", children: intl.formatMessage(messages5.style) }),
1856
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1857
- import_select2.Select,
1858
- {
1859
- size: "sm",
1860
- value: localAttrs.style,
1861
- onValueChange: handleStyleChange,
1862
- children: [
1863
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_select2.Select.Trigger, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_select2.Select.Value, {}) }),
1864
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_select2.Select.Content, { children: [
1865
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_select2.Select.Item, { value: "default", children: intl.formatMessage(messages5.style_default) }),
1866
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_select2.Select.Item, { value: "flat", children: intl.formatMessage(messages5.style_flat) }),
1867
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_select2.Select.Item, { value: "compact", children: intl.formatMessage(messages5.style_compact) })
1868
- ] })
1869
- ]
1870
- }
1871
- )
1872
- ] })
1873
- ] }) }),
1874
- /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_dialog4.Dialog.Footer, { children: [
1875
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_button6.Button, { variant: "ghost", onClick: handleCancel, children: intl.formatMessage(messages5.cancel) }),
1876
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_button6.Button, { onClick: handleSave, children: intl.formatMessage(messages5.save) })
1877
- ] })
1878
- ] }) })
1879
- ] });
1880
- }
1881
-
1882
- // src/extensions/toc/toc-view.tsx
1883
- var import_jsx_runtime9 = require("react/jsx-runtime");
1884
- function generateHeadingNumbers(headings, minLevel) {
1885
- const counters = [0, 0, 0, 0, 0, 0];
1886
- return headings.map((heading) => {
1887
- const levelIndex = heading.level - 1;
1888
- counters[levelIndex]++;
1889
- for (let i = levelIndex + 1; i < 6; i++) {
1890
- counters[i] = 0;
1891
- }
1892
- const numberParts = [];
1893
- for (let i = minLevel - 1; i <= levelIndex; i++) {
1894
- if (counters[i] > 0) {
1895
- numberParts.push(counters[i]);
1896
- }
1897
- }
1898
- return {
1899
- ...heading,
1900
- number: numberParts.join(".")
1901
- };
1902
- });
1903
- }
1904
- function TocNodeView({ editor, node, getPos }) {
1905
- const [headings, setHeadings] = (0, import_react22.useState)([]);
1906
- const intl = (0, import_react_intl12.useIntl)();
1907
- const attrs = node.attrs;
1908
- const {
1909
- minLevel = 1,
1910
- maxLevel = 6,
1911
- numbered = false,
1912
- style = "default"
1913
- } = attrs;
1914
- const styles = (0, import_react22.useMemo)(() => (0, import_theme4.toc)({ style }), [style]);
1915
- const updateHeadings = (0, import_react22.useCallback)(() => {
1916
- const items = [];
1917
- const { doc } = editor.state;
1918
- doc.descendants((docNode, pos) => {
1919
- if (docNode.type.name === "heading") {
1920
- const level = docNode.attrs.level;
1921
- if (level >= minLevel && level <= maxLevel) {
1922
- const id = docNode.attrs.id || `heading-${pos}`;
1923
- items.push({
1924
- id,
1925
- level,
1926
- text: docNode.textContent,
1927
- pos
1928
- });
1929
- }
1930
- }
1931
- });
1932
- const numberedHeadings = generateHeadingNumbers(items, minLevel);
1933
- setHeadings(numberedHeadings);
1934
- }, [editor, minLevel, maxLevel]);
1935
- (0, import_react22.useEffect)(() => {
1936
- updateHeadings();
1937
- editor.on("update", updateHeadings);
1938
- return () => {
1939
- editor.off("update", updateHeadings);
1940
- };
1941
- }, [editor, updateHeadings]);
1942
- const handleClick = (0, import_react22.useCallback)(
1943
- (pos, id) => {
1944
- var _a;
1945
- editor.chain().focus().setTextSelection(pos).run();
1946
- let element = document.querySelector(`[data-id="${id}"]`);
1947
- if (!element) {
1948
- const { view } = editor;
1949
- const coords = view.coordsAtPos(pos);
1950
- const domNode = document.elementFromPoint(coords.left, coords.top);
1951
- element = (_a = domNode == null ? void 0 : domNode.closest("h1, h2, h3, h4, h5, h6")) != null ? _a : null;
1952
- }
1953
- if (element) {
1954
- element.scrollIntoView({ behavior: "smooth", block: "start" });
1955
- }
1956
- },
1957
- [editor]
1958
- );
1959
- const isEmpty = headings.length === 0;
1960
- const getIndent = (level) => {
1961
- return (level - minLevel) * 16;
1962
- };
1963
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react21.NodeViewWrapper, { className: styles.root(), "data-type": "toc", children: [
1964
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: styles.header(), children: [
1965
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: styles.headerContent(), children: [
1966
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_icons7.ListIcon, { className: styles.headerIcon() }),
1967
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: styles.headerTitle(), children: intl.formatMessage(messages5.title) })
1968
- ] }),
1969
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: styles.headerActions(), children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1970
- TocSettings,
1971
- {
1972
- editor,
1973
- attrs,
1974
- getPos
1975
- }
1976
- ) })
1977
- ] }),
1978
- isEmpty ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: styles.emptyState(), children: intl.formatMessage(messages5.empty_state) }) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("nav", { className: styles.nav(), children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("ul", { className: styles.list(), children: headings.map((heading) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1979
- "li",
1980
- {
1981
- className: styles.item(),
1982
- style: {
1983
- paddingLeft: `${getIndent(heading.level)}px`
1984
- },
1985
- children: [
1986
- numbered && heading.number && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: styles.itemNumber(), children: heading.number }),
1987
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1988
- "button",
1989
- {
1990
- type: "button",
1991
- onClick: () => handleClick(heading.pos, heading.id),
1992
- className: styles.itemButton(),
1993
- children: heading.text || intl.formatMessage(messages5.empty_heading)
1994
- }
1995
- )
1996
- ]
1997
- },
1998
- heading.id
1999
- )) }) })
2000
- ] });
2001
- }
2002
-
2003
- // src/extensions/toc/index.ts
2004
- var TocNode = import_core5.Node.create({
2005
- name: "tableOfContentsNode",
2006
- group: "block",
2007
- atom: true,
2008
- draggable: true,
2009
- addOptions() {
2010
- return {
2011
- HTMLAttributes: {}
2012
- };
2013
- },
2014
- addAttributes() {
2015
- return {
2016
- minLevel: {
2017
- default: 1,
2018
- parseHTML: (element) => Number.parseInt(element.getAttribute("data-min-level") || "1", 10),
2019
- renderHTML: (attributes) => ({
2020
- "data-min-level": attributes.minLevel
2021
- })
2022
- },
2023
- maxLevel: {
2024
- default: 6,
2025
- parseHTML: (element) => Number.parseInt(element.getAttribute("data-max-level") || "6", 10),
2026
- renderHTML: (attributes) => ({
2027
- "data-max-level": attributes.maxLevel
2028
- })
2029
- },
2030
- numbered: {
2031
- default: false,
2032
- parseHTML: (element) => element.getAttribute("data-numbered") === "true",
2033
- renderHTML: (attributes) => ({
2034
- "data-numbered": attributes.numbered ? "true" : "false"
2035
- })
2036
- },
2037
- style: {
2038
- default: "default",
2039
- parseHTML: (element) => element.getAttribute("data-style") || "default",
2040
- renderHTML: (attributes) => ({
2041
- "data-style": attributes.style
2042
- })
2043
- }
2044
- };
2045
- },
2046
- parseHTML() {
2047
- return [
2048
- {
2049
- tag: 'div[data-type="toc"]'
2050
- }
2051
- ];
2052
- },
2053
- renderHTML({ HTMLAttributes }) {
2054
- return [
2055
- "div",
2056
- (0, import_core5.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes, {
2057
- "data-type": "toc"
2058
- })
2059
- ];
2060
- },
2061
- addNodeView() {
2062
- return (0, import_react23.ReactNodeViewRenderer)(TocNodeView);
2063
- },
2064
- addCommands() {
2065
- return {
2066
- insertTableOfContents: () => ({ commands }) => {
2067
- return commands.insertContent({
2068
- type: this.name
2069
- });
2070
- },
2071
- updateTocSettings: (attrs) => ({ tr, state, dispatch }) => {
2072
- const { selection } = state;
2073
- const node = state.doc.nodeAt(selection.from);
2074
- if ((node == null ? void 0 : node.type.name) !== this.name) {
2075
- return false;
2076
- }
2077
- if (dispatch) {
2078
- tr.setNodeMarkup(selection.from, void 0, {
2079
- ...node.attrs,
2080
- ...attrs
2081
- });
2082
- }
2083
- return true;
2084
- }
2085
- };
2086
- }
2087
- });
2088
-
2089
- // src/extensions/trailing-node/index.ts
2090
- var import_state3 = require("@tiptap/pm/state");
2091
- var import_react24 = require("@tiptap/react");
2092
- function nodeEqualsType({
2093
- types,
2094
- node
2095
- }) {
2096
- if (!node) return false;
2097
- if (Array.isArray(types)) {
2098
- return types.includes(node.type);
2099
- }
2100
- return node.type === types;
2101
- }
2102
- var TrailingNode = import_react24.Extension.create({
2103
- name: "trailingNode",
2104
- addOptions() {
2105
- return {
2106
- node: "paragraph",
2107
- notAfter: ["paragraph"]
2108
- };
2109
- },
2110
- addProseMirrorPlugins() {
2111
- const plugin = new import_state3.PluginKey(this.name);
2112
- const disabledNodes = Object.entries(this.editor.schema.nodes).map(([, value]) => value).filter((node) => this.options.notAfter.includes(node.name));
2113
- return [
2114
- new import_state3.Plugin({
2115
- key: plugin,
2116
- appendTransaction: (_, __, state) => {
2117
- const { doc, tr, schema } = state;
2118
- const shouldInsertNodeAtEnd = plugin.getState(state);
2119
- const endPosition = doc.content.size;
2120
- const type = schema.nodes[this.options.node];
2121
- if (!shouldInsertNodeAtEnd) {
2122
- return null;
2123
- }
2124
- if (type) {
2125
- return tr.insert(endPosition, type.create());
2126
- }
2127
- return null;
2128
- },
2129
- state: {
2130
- init: (_, state) => {
2131
- const lastNode = state.tr.doc.lastChild;
2132
- return !nodeEqualsType({ node: lastNode, types: disabledNodes });
2133
- },
2134
- apply: (tr, value) => {
2135
- if (!tr.docChanged) {
2136
- return value;
2137
- }
2138
- const lastNode = tr.doc.lastChild;
2139
- return !nodeEqualsType({ node: lastNode, types: disabledNodes });
2140
- }
2141
- }
2142
- })
2143
- ];
2144
- }
2145
- });
2146
-
2147
- // src/extensions/ui-state/index.ts
2148
- var import_core6 = require("@tiptap/core");
2149
- var defaultUiState = {
2150
- aiGenerationIsSelection: false,
2151
- aiGenerationIsLoading: false,
2152
- aiGenerationActive: false,
2153
- aiGenerationHasMessage: false,
2154
- commentInputVisible: false,
2155
- lockDragHandle: false,
2156
- isDragging: false
2157
- };
2158
- var UiState = import_core6.Extension.create({
2159
- name: "uiState",
2160
- addStorage() {
2161
- return {
2162
- uiState: { ...defaultUiState }
2163
- };
2164
- },
2165
- addCommands() {
2166
- const createBooleanSetter = (key) => (value) => () => {
2167
- this.storage[key] = value;
2168
- return true;
2169
- };
2170
- const createToggle = (key, value) => () => () => {
2171
- this.storage[key] = value;
2172
- return true;
2173
- };
2174
- return {
2175
- // AI Generation commands
2176
- aiGenerationSetIsSelection: createBooleanSetter(
2177
- "aiGenerationIsSelection"
2178
- ),
2179
- aiGenerationSetIsLoading: createBooleanSetter("aiGenerationIsLoading"),
2180
- aiGenerationHasMessage: createBooleanSetter("aiGenerationHasMessage"),
2181
- aiGenerationShow: createToggle("aiGenerationActive", true),
2182
- aiGenerationHide: createToggle("aiGenerationActive", false),
2183
- // Comment input commands
2184
- commentInputShow: createToggle("commentInputVisible", true),
2185
- commentInputHide: createToggle("commentInputVisible", false),
2186
- // Drag handle commands
2187
- setLockDragHandle: createBooleanSetter("lockDragHandle"),
2188
- setIsDragging: createBooleanSetter("isDragging"),
2189
- // Reset command
2190
- resetUiState: () => () => {
2191
- Object.assign(this.storage, { ...defaultUiState });
2192
- return true;
2193
- }
2194
- };
2195
- },
2196
- onCreate() {
2197
- this.storage = { ...defaultUiState };
2198
- }
2199
- });
2200
-
2201
- // src/extensions/variable/index.ts
2202
- var import_core7 = require("@tiptap/core");
2203
- var import_react26 = require("@tiptap/react");
2204
-
2205
- // src/extensions/variable/variable-view.tsx
2206
- var import_theme5 = require("@kopexa/theme");
2207
- var import_react25 = require("@tiptap/react");
2208
-
2209
- // src/extensions/variable/variable-context.tsx
2210
- var React = __toESM(require("react"));
2211
- var import_jsx_runtime10 = require("react/jsx-runtime");
2212
- var VariableContext = React.createContext(null);
2213
- function useVariables() {
2214
- return React.useContext(VariableContext);
2215
- }
2216
-
2217
- // src/extensions/variable/variable-view.tsx
2218
- var import_jsx_runtime11 = require("react/jsx-runtime");
2219
- function VariableNodeView({ node, editor }) {
2220
- var _a;
2221
- const attrs = node.attrs;
2222
- const { name, fallback, category } = attrs;
2223
- const context = useVariables();
2224
- const isEditable = (0, import_react25.useEditorState)({
2225
- editor,
2226
- selector: ({ editor: e }) => {
2227
- var _a2;
2228
- return (_a2 = e == null ? void 0 : e.isEditable) != null ? _a2 : true;
2229
- }
2230
- });
2231
- const resolvedValue = (_a = context == null ? void 0 : context.resolveVariable) == null ? void 0 : _a.call(context, name);
2232
- const hasValue = resolvedValue !== void 0 && resolvedValue !== "";
2233
- const displayValue = resolvedValue || fallback;
2234
- const styles = (0, import_theme5.variableNode)({ resolved: hasValue });
2235
- if (!isEditable && hasValue) {
2236
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2237
- import_react25.NodeViewWrapper,
2238
- {
2239
- as: "span",
2240
- "data-type": "variable",
2241
- "data-name": name,
2242
- style: { userSelect: "text" },
2243
- children: displayValue
2244
- }
2245
- );
2246
- }
2247
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2248
- import_react25.NodeViewWrapper,
2249
- {
2250
- as: "span",
2251
- className: styles.wrapper(),
2252
- "data-type": "variable",
2253
- "data-name": name,
2254
- "data-category": category,
2255
- "data-resolved": hasValue ? "true" : "false",
2256
- children: hasValue ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: styles.chip(), title: `{{${name}}}`, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: styles.value(), children: displayValue }) }) : /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
2257
- "span",
2258
- {
2259
- className: styles.chip(),
2260
- title: fallback ? `Fallback: ${fallback}` : void 0,
2261
- children: [
2262
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: styles.bracket(), children: "{" }),
2263
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: styles.bracket(), children: "{" }),
2264
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: styles.name(), children: name }),
2265
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: styles.bracket(), children: "}" }),
2266
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: styles.bracket(), children: "}" })
2267
- ]
2268
- }
2269
- )
2270
- }
2271
- );
2272
- }
2273
-
2274
- // src/extensions/variable/index.ts
2275
- var VariableNode = import_core7.Node.create({
2276
- name: "variable",
2277
- group: "inline",
2278
- inline: true,
2279
- atom: true,
2280
- selectable: true,
2281
- draggable: true,
2282
- addOptions() {
2283
- return {
2284
- HTMLAttributes: {}
2285
- };
2286
- },
2287
- addAttributes() {
2288
- return {
2289
- name: {
2290
- default: "",
2291
- parseHTML: (element) => element.getAttribute("data-name"),
2292
- renderHTML: (attributes) => ({
2293
- "data-name": attributes.name
2294
- })
2295
- },
2296
- fallback: {
2297
- default: void 0,
2298
- parseHTML: (element) => element.getAttribute("data-fallback"),
2299
- renderHTML: (attributes) => {
2300
- if (!attributes.fallback) return {};
2301
- return {
2302
- "data-fallback": attributes.fallback
2303
- };
2304
- }
2305
- },
2306
- category: {
2307
- default: void 0,
2308
- parseHTML: (element) => element.getAttribute("data-category"),
2309
- renderHTML: (attributes) => {
2310
- if (!attributes.category) return {};
2311
- return {
2312
- "data-category": attributes.category
2313
- };
2314
- }
2315
- }
2316
- };
2317
- },
2318
- parseHTML() {
2319
- return [
2320
- {
2321
- tag: 'span[data-type="variable"]'
2322
- }
2323
- ];
2324
- },
2325
- renderHTML({ node, HTMLAttributes }) {
2326
- const attrs = node.attrs;
2327
- return [
2328
- "span",
2329
- (0, import_core7.mergeAttributes)(this.options.HTMLAttributes, HTMLAttributes, {
2330
- "data-type": "variable",
2331
- class: "variable-node"
2332
- }),
2333
- `{{${attrs.name}}}`
2334
- ];
2335
- },
2336
- addNodeView() {
2337
- return (0, import_react26.ReactNodeViewRenderer)(VariableNodeView);
2338
- },
2339
- addCommands() {
2340
- return {
2341
- insertVariable: (attrs) => ({ commands }) => {
2342
- return commands.insertContent({
2343
- type: this.name,
2344
- attrs
2345
- });
2346
- }
2347
- };
2348
- }
2349
- });
2350
-
2351
- // src/utils/safe-parse.ts
2352
- var import_dompurify = __toESM(require("dompurify"));
2353
- var import_markdown_it = __toESM(require("markdown-it"));
2354
- var md = new import_markdown_it.default({
2355
- html: false,
2356
- // keep it safe
2357
- linkify: true,
2358
- typographer: true
2359
- });
2360
- var DOMPURIFY_CONFIG = {
2361
- // Allowed tags (safe subset for rich text)
2362
- ALLOWED_TAGS: [
2363
- "p",
2364
- "br",
2365
- "span",
2366
- "div",
2367
- "h1",
2368
- "h2",
2369
- "h3",
2370
- "h4",
2371
- "h5",
2372
- "h6",
2373
- "strong",
2374
- "b",
2375
- "em",
2376
- "i",
2377
- "u",
2378
- "s",
2379
- "strike",
2380
- "del",
2381
- "ul",
2382
- "ol",
2383
- "li",
2384
- "blockquote",
2385
- "pre",
2386
- "code",
2387
- "a",
2388
- "img",
2389
- "table",
2390
- "thead",
2391
- "tbody",
2392
- "tr",
2393
- "th",
2394
- "td",
2395
- "hr",
2396
- "sub",
2397
- "sup",
2398
- "mark"
2399
- ],
2400
- // Allowed attributes
2401
- ALLOWED_ATTR: [
2402
- "href",
2403
- "src",
2404
- "alt",
2405
- "title",
2406
- "class",
2407
- "id",
2408
- "target",
2409
- "rel",
2410
- "colspan",
2411
- "rowspan",
2412
- "width",
2413
- "height"
2414
- ],
2415
- // Allow all data-* attributes (needed for Tiptap extensions like controlBlock)
2416
- ALLOW_DATA_ATTR: true,
2417
- // Forbid all event handlers and javascript: URLs
2418
- FORBID_ATTR: [
2419
- "onerror",
2420
- "onload",
2421
- "onclick",
2422
- "onmouseover",
2423
- "onmouseout",
2424
- "onfocus",
2425
- "onblur",
2426
- "onchange",
2427
- "onsubmit",
2428
- "onkeydown",
2429
- "onkeyup",
2430
- "onkeypress",
2431
- "ondblclick",
2432
- "oncontextmenu"
2433
- ],
2434
- // Forbid dangerous tags completely
2435
- FORBID_TAGS: [
2436
- "script",
2437
- "style",
2438
- "iframe",
2439
- "object",
2440
- "embed",
2441
- "form",
2442
- "input",
2443
- "button",
2444
- "textarea",
2445
- "select"
2446
- ],
2447
- // Block javascript: and data: URLs
2448
- ALLOWED_URI_REGEXP: /^(?:(?:https?|mailto|tel):|[^a-z]|[a-z+.-]+(?:[^a-z+.\-:]|$))/i
2449
- };
2450
- function sanitizeHtml(html) {
2451
- if (typeof window === "undefined") {
2452
- return html;
2453
- }
2454
- return import_dompurify.default.sanitize(html, DOMPURIFY_CONFIG);
2455
- }
2456
- function toPlainTextDoc(s) {
2457
- return {
2458
- type: "doc",
2459
- content: [
2460
- {
2461
- type: "paragraph",
2462
- content: s ? [{ type: "text", text: s }] : []
2463
- }
2464
- ]
2465
- };
2466
- }
2467
- function safeParseContent(content) {
2468
- if (!content || content === "") return { type: "doc", content: [] };
2469
- if (typeof content === "object") {
2470
- return content;
2471
- }
2472
- if (typeof content === "string") {
2473
- const trimmed = content.trim();
2474
- if (looksLikeJsonString(trimmed)) {
2475
- try {
2476
- const parsed = JSON.parse(trimmed);
2477
- if (isTiptapDoc(parsed)) return parsed;
2478
- } catch {
2479
- }
2480
- }
2481
- if (looksLikeHtml(trimmed)) {
2482
- return sanitizeHtml(trimmed);
2483
- }
2484
- const raw = normalizeNewlines(trimmed);
2485
- try {
2486
- const html = md.render(raw);
2487
- return sanitizeHtml(html);
2488
- } catch {
2489
- }
2490
- return toPlainTextDoc(raw);
2491
- }
2492
- return { type: "doc", content: [] };
2493
- }
2494
- function looksLikeJsonString(s) {
2495
- const c = s.trim().charCodeAt(0);
2496
- return c === 123 || c === 91;
2497
- }
2498
- function looksLikeHtml(s) {
2499
- const trimmed = s.trim();
2500
- if (trimmed.charCodeAt(0) !== 60) return false;
2501
- const secondChar = trimmed.charCodeAt(1);
2502
- return secondChar >= 65 && secondChar <= 90 || // A-Z
2503
- secondChar >= 97 && secondChar <= 122 || // a-z
2504
- secondChar === 33;
2505
- }
2506
- function isTiptapDoc(value) {
2507
- return Boolean(
2508
- value && typeof value === "object" && value.type === "doc" && Array.isArray(value.content)
2509
- );
2510
- }
2511
- function normalizeNewlines(raw) {
2512
- return raw.replace(/\r\n?/g, "\n").replace(/\\n/g, "\n");
2513
- }
2514
-
2515
- // src/hooks/use-create-editor.ts
2516
- var useCreateEditor = ({
2517
- content,
2518
- editable = true,
2519
- placeholder = "Write, type '/' for commands\u2026",
2520
- onChange,
2521
- enableControls = false,
2522
- controlResolver,
2523
- fileHandler: fileHandlerProp,
2524
- enableVariables = false,
2525
- ...options
2526
- }) => {
2527
- const fileHandlerFromContext = useEditorFile();
2528
- const fileHandler = fileHandlerProp != null ? fileHandlerProp : fileHandlerFromContext;
2529
- const [extensions] = (0, import_react28.useState)(
2530
- () => getExtensions({
2531
- editable,
2532
- placeholder,
2533
- enableControls,
2534
- controlResolver,
2535
- fileHandler,
2536
- enableVariables
2537
- })
2538
- );
2539
- const editor = (0, import_react27.useEditor)({
2540
- editorProps: {
2541
- attributes: {
2542
- autocomplete: "off",
2543
- autocorrect: "off",
2544
- autocapitalize: "off",
2545
- "aria-label": "Main content area, start typing to enter text."
2546
- }
2547
- },
2548
- immediatelyRender: false,
2549
- shouldRerenderOnTransaction: false,
2550
- extensions,
2551
- editable,
2552
- onUpdate: ({ editor: editor2 }) => {
2553
- onChange == null ? void 0 : onChange(editor2.getJSON());
2554
- },
2555
- content: safeParseContent(content),
2556
- ...options
2557
- });
2558
- (0, import_react28.useEffect)(() => {
2559
- if (editor && editor.isEditable !== editable) {
2560
- editor.setEditable(editable);
2561
- }
2562
- }, [editor, editable]);
2563
- return editor;
2564
- };
2565
- function getExtensions({
2566
- editable,
2567
- placeholder,
2568
- enableControls = false,
2569
- controlResolver,
2570
- fileHandler,
2571
- enableVariables = false
2572
- }) {
2573
- const extensions = [
2574
- import_starter_kit.StarterKit.configure({
2575
- trailingNode: false,
2576
- // we use our custom trailing node extension
2577
- link: false,
2578
- // we use our custom link extension
2579
- code: false,
2580
- // we use our own
2581
- codeBlock: false
2582
- // we use our own
2583
- // undoRedo should be dynamic based on collaboration, later.^
2584
- }),
2585
- import_extension_text_align.TextAlign.configure({ types: ["heading", "paragraph"] }),
2586
- import_extension_list.TaskList,
2587
- import_extension_list.TaskItem.configure({ nested: true }),
2588
- import_extension_invisible_characters.default.configure({
2589
- visible: false
2590
- }),
2591
- import_extension_table_of_contents.TableOfContents.configure({
2592
- getIndex: import_extension_table_of_contents.getHierarchicalIndexes
2593
- }),
2594
- Selection,
2595
- Link.configure({ openOnClick: !editable }),
2596
- // disable link click when editing
2597
- import_extension_text_style.TextStyleKit,
2598
- import_extension_highlight.Highlight.configure({ multicolor: true }),
2599
- import_extensions.CharacterCount,
2600
- import_extension_typography.Typography,
2601
- import_extension_superscript.Superscript,
2602
- import_extension_subscript.Subscript,
2603
- import_extension_code.CodeKit,
2604
- TrailingNode,
2605
- import_extension_unique_id.UniqueID.configure({
2606
- types: [
2607
- "paragraph",
2608
- "bulletList",
2609
- "orderedList",
2610
- "taskList",
2611
- "heading",
2612
- "blockquote",
2613
- "codeBlock"
2614
- ]
2615
- // filterTransaction: (transaction) => !isChangeOrigin(transaction),
2616
- }),
2617
- UiState,
2618
- import_extension_table.TableKit,
2619
- TocNode,
2620
- CalloutNode,
2621
- MathBlock,
2622
- InlineMath,
2623
- // Image support - extended with file reference resolution
2624
- ImageNode.configure({
2625
- allowBase64: true
2626
- }),
2627
- // Image upload placeholder
2628
- ImageUploadNode,
2629
- import_extensions.Placeholder.configure({
2630
- placeholder,
2631
- emptyNodeClass: "is-empty with-slash"
2632
- })
2633
- ];
2634
- if (enableControls) {
2635
- extensions.push(import_extension_controlref.ControlKit.configure({ resolver: controlResolver }));
2636
- }
2637
- if (enableVariables) {
2638
- extensions.push(VariableNode);
2639
- }
2640
- if (fileHandler) {
2641
- extensions.push(
2642
- import_extension_file_handler.FileHandler.configure({
2643
- allowedMimeTypes: [
2644
- "image/jpeg",
2645
- "image/png",
2646
- "image/gif",
2647
- "image/webp",
2648
- "image/svg+xml"
2649
- ],
2650
- onDrop: (editor, files, pos) => {
2651
- for (const file of files) {
2652
- handleFileUpload(editor, file, fileHandler, pos);
2653
- }
2654
- },
2655
- onPaste: (editor, files) => {
2656
- for (const file of files) {
2657
- handleFileUpload(editor, file, fileHandler);
2658
- }
2659
- }
2660
- })
2661
- );
2662
- }
2663
- return extensions;
2664
- }
2665
- async function handleFileUpload(editor, file, fileHandler, pos) {
2666
- if (!editor) return;
2667
- const tempId = `uploading-${Date.now()}-${Math.random().toString(36).slice(2)}`;
2668
- const insertPos = pos != null ? pos : editor.state.selection.anchor;
2669
- editor.chain().focus().insertContentAt(insertPos, {
2670
- type: "image",
2671
- attrs: {
2672
- src: tempId,
2673
- uploadState: "uploading",
2674
- uploadProgress: 0
2675
- }
2676
- }).run();
2677
- try {
2678
- const ref = await fileHandler.upload(file, (percent) => {
2679
- editor.state.doc.descendants((node, nodePos) => {
2680
- if (node.type.name === "image" && node.attrs.src === tempId) {
2681
- editor.view.dispatch(
2682
- editor.state.tr.setNodeMarkup(nodePos, void 0, {
2683
- ...node.attrs,
2684
- uploadProgress: percent
2685
- })
2686
- );
2687
- return false;
2688
- }
2689
- return true;
2690
- });
2691
- });
2692
- editor.state.doc.descendants((node, nodePos) => {
2693
- if (node.type.name === "image" && node.attrs.src === tempId) {
2694
- editor.view.dispatch(
2695
- editor.state.tr.setNodeMarkup(nodePos, void 0, {
2696
- src: ref,
2697
- uploadState: null,
2698
- uploadProgress: null
2699
- })
2700
- );
2701
- return false;
2702
- }
2703
- return true;
2704
- });
2705
- } catch (error) {
2706
- editor.state.doc.descendants((node, nodePos) => {
2707
- if (node.type.name === "image" && node.attrs.src === tempId) {
2708
- editor.view.dispatch(
2709
- editor.state.tr.setNodeMarkup(nodePos, void 0, {
2710
- ...node.attrs,
2711
- uploadState: "error",
2712
- uploadProgress: null
2713
- })
2714
- );
2715
- return false;
2716
- }
2717
- return true;
2718
- });
2719
- console.error("[FileHandler] Upload failed:", error);
2720
- }
2721
- }
2722
- // Annotate the CommonJS export names for ESM import in node:
2723
- 0 && (module.exports = {
2724
- getExtensions,
2725
- useCreateEditor
2726
- });