@collabchron/notiq 0.3.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (282) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +230 -39
  3. package/dist/CodeActionMenuPlugin-EINOY4U4.mjs +15 -0
  4. package/dist/DynamicBlockComponent-NRQJ4WW4.mjs +161 -0
  5. package/dist/EquationComponent-CB6DFIHV.mjs +154 -0
  6. package/dist/ExcalidrawComponent-XW6646OH.mjs +528 -0
  7. package/dist/ExcalidrawPlugin-ZFHT62IF.mjs +14 -0
  8. package/dist/ExportPlugin-V2RLM63S.mjs +11 -0
  9. package/dist/FloatingLinkEditorPlugin-TRTCMSP4.mjs +12 -0
  10. package/dist/FloatingTextFormatToolbarPlugin-F2GY6LMI.mjs +30 -0
  11. package/dist/HintComponet-BRL6EAMS.mjs +217 -0
  12. package/dist/InlineImageComponent-UWIUWBHI.mjs +453 -0
  13. package/dist/MobileToolbar-BOOZAMQE.mjs +268 -0
  14. package/dist/SlashCommand-GMT5JI33.mjs +28 -0
  15. package/dist/StoryBuilderComponent-JGDBM5JU.mjs +562 -0
  16. package/{src/components/editor/plugins/TableCellActionMenuPlugin/index.tsx → dist/TableCellActionMenuPlugin-PGK2K3VG.mjs} +667 -759
  17. package/{src/components/editor/plugins/TableHoverActionsPlugin/index.tsx → dist/TableHoverActionsPlugin-GJVE6VRW.mjs} +258 -314
  18. package/dist/TemplatePlugin-ZD3QEVTI.mjs +9 -0
  19. package/dist/ToolbarPlugin-7TOZRD2R.mjs +1547 -0
  20. package/dist/babel-JZ2EV6AX.mjs +7233 -0
  21. package/dist/background-color-XZTYLGO2.mjs +362 -0
  22. package/dist/block-format-YJCV2DIY.mjs +15 -0
  23. package/dist/chunk-2FNEAMSP.mjs +127 -0
  24. package/dist/chunk-3CPBODXA.mjs +84 -0
  25. package/dist/chunk-3G37YKTV.mjs +83 -0
  26. package/dist/chunk-3JVFG7ER.mjs +184 -0
  27. package/dist/chunk-456TN7IM.mjs +110 -0
  28. package/dist/chunk-4EXYCTGJ.mjs +27 -0
  29. package/{src/utils/getSelectedNode.ts → dist/chunk-4HBCVSE6.mjs} +26 -27
  30. package/dist/chunk-4MEDW3T6.mjs +125 -0
  31. package/dist/chunk-4VWFVWYP.mjs +36 -0
  32. package/dist/chunk-5BAKY5KN.mjs +84 -0
  33. package/dist/chunk-5QSNIVIG.mjs +333 -0
  34. package/dist/chunk-64Z3FI7T.mjs +37 -0
  35. package/{src/components/editor/nodes/Stepper/index.tsx → dist/chunk-6RNZQOH2.mjs} +214 -260
  36. package/dist/chunk-77KXU36M.mjs +64 -0
  37. package/dist/chunk-77UA6HYR.mjs +165 -0
  38. package/dist/chunk-7NZAPJ4G.mjs +102 -0
  39. package/dist/chunk-7VUMHWWL.mjs +152 -0
  40. package/dist/chunk-AMMKBSST.mjs +1256 -0
  41. package/dist/chunk-BIU7WTLX.mjs +95 -0
  42. package/dist/chunk-EGMI62PP.mjs +83 -0
  43. package/dist/chunk-EHNQD5KO.mjs +88 -0
  44. package/dist/chunk-FSM26655.mjs +37 -0
  45. package/{src/components/editor/nodes/Hint/index.tsx → dist/chunk-G53GLEAY.mjs} +158 -190
  46. package/dist/chunk-GK35L7UY.mjs +28 -0
  47. package/dist/chunk-GXYD4VZM.mjs +193 -0
  48. package/dist/chunk-GYIOYVCN.mjs +538 -0
  49. package/dist/chunk-GZPNVR7L.mjs +157 -0
  50. package/dist/chunk-JXDPPUJI.mjs +52 -0
  51. package/dist/chunk-K36V4SIW.mjs +141 -0
  52. package/dist/chunk-KJ6AJ44Q.mjs +128 -0
  53. package/dist/chunk-KJV3FAZ7.mjs +142 -0
  54. package/{src/components/editor/plugins/ImagesPlugin/index.tsx → dist/chunk-LGG4IUIA.mjs} +189 -222
  55. package/dist/chunk-LQN3CMKV.mjs +1906 -0
  56. package/dist/chunk-N3WN46VL.mjs +236 -0
  57. package/dist/chunk-PBD6LMLC.mjs +366 -0
  58. package/dist/chunk-POGRR73N.mjs +33 -0
  59. package/{src/components/editor/utils/editorFormatting.ts → dist/chunk-PZSUSXQG.mjs} +238 -282
  60. package/dist/chunk-QEIFVK5M.mjs +29 -0
  61. package/dist/chunk-QHIQKMVN.mjs +427 -0
  62. package/dist/chunk-TCYK7DM7.mjs +36 -0
  63. package/dist/chunk-TTHQCW5F.mjs +47 -0
  64. package/dist/chunk-U47ABU5Z.mjs +53 -0
  65. package/dist/chunk-WDG7J2DY.mjs +116 -0
  66. package/dist/chunk-WJRHXI2C.mjs +733 -0
  67. package/dist/chunk-XLER2DHM.mjs +357 -0
  68. package/dist/chunk-XWC4TK2N.mjs +315 -0
  69. package/dist/chunk-YHPNOWFH.mjs +15 -0
  70. package/dist/chunk-YKC3SO4Z.mjs +32 -0
  71. package/dist/chunk-YMBXLRW5.mjs +374 -0
  72. package/dist/chunk-YPHOEJ46.mjs +64 -0
  73. package/dist/chunk-YUDCJRJM.mjs +25 -0
  74. package/dist/chunk-Z4EWP7BI.mjs +65 -0
  75. package/dist/chunk-ZB5LZQKC.mjs +191 -0
  76. package/dist/chunk-ZJRKATOJ.mjs +65 -0
  77. package/dist/color-BPKOPQKN.mjs +12 -0
  78. package/dist/estree-XC56IUFX.mjs +4414 -0
  79. package/dist/font-FEZ3GKSF.mjs +13 -0
  80. package/dist/font-size-EK775WRH.mjs +15 -0
  81. package/dist/html-S3ACX7NI.mjs +2738 -0
  82. package/dist/image-2PJIAYAT.mjs +993 -0
  83. package/dist/index.d.mts +145 -0
  84. package/dist/index.d.ts +145 -0
  85. package/dist/index.js +57855 -0
  86. package/dist/index.mjs +1790 -0
  87. package/dist/insert-gif-SAIDYURE.mjs +100 -0
  88. package/dist/insert-image-U3RJN3OW.mjs +259 -0
  89. package/dist/insert-node-5P2CRJ7S.mjs +201 -0
  90. package/dist/insert-poll-HCPM7MO6.mjs +33 -0
  91. package/dist/insert-table-24XYUS2W.mjs +66 -0
  92. package/dist/markdown-SNVBOSRA.mjs +3487 -0
  93. package/dist/poll-component-2R4MDLHS.mjs +303 -0
  94. package/dist/postcss-ONF3VDIM.mjs +5051 -0
  95. package/dist/standalone-EOIALU3M.mjs +2373 -0
  96. package/dist/stepper-FSARL6X6.mjs +304 -0
  97. package/dist/styles/notiq.css +1149 -0
  98. package/dist/text-align-VLECWO4H.mjs +118 -0
  99. package/dist/text-format-BG5WOOPZ.mjs +16 -0
  100. package/dist/typescript-AMPI6OVS.mjs +13135 -0
  101. package/package.json +66 -11
  102. package/src/styles/notiq.css +1149 -0
  103. package/src/styles/tailwind-plugin.ts +134 -0
  104. package/components.json +0 -21
  105. package/eslint.config.mjs +0 -16
  106. package/next.config.ts +0 -12
  107. package/postcss.config.mjs +0 -5
  108. package/public/file.svg +0 -1
  109. package/public/globe.svg +0 -1
  110. package/public/images/icons/plus.svg +0 -10
  111. package/public/next.svg +0 -1
  112. package/public/vercel.svg +0 -1
  113. package/public/window.svg +0 -1
  114. package/src/app/actions.ts +0 -2
  115. package/src/app/api/ai/route.ts +0 -175
  116. package/src/app/api/edgestore/[...edgestore]/route.ts +0 -28
  117. package/src/app/favicon.ico +0 -0
  118. package/src/app/globals.css +0 -205
  119. package/src/app/layout.tsx +0 -38
  120. package/src/app/page.tsx +0 -12
  121. package/src/components/editor/Core.tsx +0 -220
  122. package/src/components/editor/hooks/instructions-messages.ts +0 -300
  123. package/src/components/editor/hooks/use-mobile.ts +0 -19
  124. package/src/components/editor/hooks/useReport.ts +0 -67
  125. package/src/components/editor/hooks/useResizeObservert.ts +0 -22
  126. package/src/components/editor/index.tsx +0 -39
  127. package/src/components/editor/lexical-on-change.tsx +0 -28
  128. package/src/components/editor/nodes/CollapsibleNode/CollapsibleContainerNode.ts +0 -92
  129. package/src/components/editor/nodes/CollapsibleNode/CollapsibleContentNode.ts +0 -65
  130. package/src/components/editor/nodes/CollapsibleNode/CollapsibleTitleNode.ts +0 -105
  131. package/src/components/editor/nodes/EquationNode/EquationComponent.tsx +0 -143
  132. package/src/components/editor/nodes/EquationNode/EquationNode.tsx +0 -170
  133. package/src/components/editor/nodes/ExcalidrawNode/ExcalidrawComponent.tsx +0 -228
  134. package/src/components/editor/nodes/ExcalidrawNode/ExcalidrawImage.tsx +0 -137
  135. package/src/components/editor/nodes/ExcalidrawNode/ImageResizer.tsx +0 -317
  136. package/src/components/editor/nodes/ExcalidrawNode/index.tsx +0 -204
  137. package/src/components/editor/nodes/FigmaNode/FigmaNode.tsx +0 -134
  138. package/src/components/editor/nodes/Hint/HintComponet.tsx +0 -221
  139. package/src/components/editor/nodes/ImageNode/index.tsx +0 -328
  140. package/src/components/editor/nodes/InlineImageNode/InlineImageComponent.tsx +0 -383
  141. package/src/components/editor/nodes/InlineImageNode/InlineImageNode.css +0 -94
  142. package/src/components/editor/nodes/InlineImageNode/InlineImageNode.tsx +0 -309
  143. package/src/components/editor/nodes/LayoutNode/LayoutContainerNode.ts +0 -146
  144. package/src/components/editor/nodes/LayoutNode/LayoutItemNode.ts +0 -79
  145. package/src/components/editor/nodes/PollNode/index.tsx +0 -204
  146. package/src/components/editor/nodes/TweetNode/index.tsx +0 -214
  147. package/src/components/editor/nodes/index.ts +0 -81
  148. package/src/components/editor/plugins/AutoEmbedPlugin/index.tsx +0 -350
  149. package/src/components/editor/plugins/AutoLinkPlugin/index.tsx +0 -56
  150. package/src/components/editor/plugins/CodeActionMenuPlugin/components/CopyButton.tsx +0 -70
  151. package/src/components/editor/plugins/CodeActionMenuPlugin/components/PrettierButton.tsx +0 -192
  152. package/src/components/editor/plugins/CodeActionMenuPlugin/index.tsx +0 -217
  153. package/src/components/editor/plugins/CodeActionMenuPlugin/utils.ts +0 -26
  154. package/src/components/editor/plugins/CodeHighlightPlugin/index.ts +0 -21
  155. package/src/components/editor/plugins/CollapsiblePlugin/Collapsible.css +0 -76
  156. package/src/components/editor/plugins/CollapsiblePlugin/index.ts +0 -228
  157. package/src/components/editor/plugins/DragDropPastePlugin/index.tsx +0 -44
  158. package/src/components/editor/plugins/DraggableBlockPlugin/index.tsx +0 -52
  159. package/src/components/editor/plugins/EquationsPlugin/index.tsx +0 -85
  160. package/src/components/editor/plugins/ExcalidrawPlugin/index.tsx +0 -98
  161. package/src/components/editor/plugins/FigmaPlugin/index.tsx +0 -42
  162. package/src/components/editor/plugins/FloatingLinkEditorPlugin/index.tsx +0 -445
  163. package/src/components/editor/plugins/FloatingTextFormatToolbarPlugin/index.tsx +0 -275
  164. package/src/components/editor/plugins/InlineImagePlugin/index.tsx +0 -351
  165. package/src/components/editor/plugins/LayoutPlugin/index.tsx +0 -238
  166. package/src/components/editor/plugins/LinkPlugin/index.tsx +0 -36
  167. package/src/components/editor/plugins/LinkWithMetaData/index.tsx +0 -271
  168. package/src/components/editor/plugins/MarkdownShortcutPlugin/index.tsx +0 -11
  169. package/src/components/editor/plugins/MarkdownTransformers/index.tsx +0 -304
  170. package/src/components/editor/plugins/PollPlugin/index.tsx +0 -49
  171. package/src/components/editor/plugins/ShortcutsPlugin/index.tsx +0 -180
  172. package/src/components/editor/plugins/ShortcutsPlugin/shortcuts.ts +0 -253
  173. package/src/components/editor/plugins/SlashCommand/index.tsx +0 -621
  174. package/src/components/editor/plugins/SpeechToTextPlugin/index.ts +0 -127
  175. package/src/components/editor/plugins/TabFocusPlugin/index.ts +0 -58
  176. package/src/components/editor/plugins/TableCellResizer/index.tsx +0 -438
  177. package/src/components/editor/plugins/TablePlugin/index.tsx +0 -99
  178. package/src/components/editor/plugins/ToolbarPlugin/index.tsx +0 -522
  179. package/src/components/editor/plugins/TwitterPlugin/index.ts +0 -35
  180. package/src/components/editor/plugins/YouTubeNode/index.tsx +0 -179
  181. package/src/components/editor/plugins/YouTubePlugin/index.ts +0 -41
  182. package/src/components/editor/themes/editor-theme.ts +0 -113
  183. package/src/components/editor/themes/theme.css +0 -377
  184. package/src/components/editor/utils/ai.ts +0 -291
  185. package/src/components/editor/utils/canUseDOM.ts +0 -12
  186. package/src/components/editor/utils/environment.ts +0 -50
  187. package/src/components/editor/utils/extract-data.ts +0 -166
  188. package/src/components/editor/utils/getAllLexicalChildren.ts +0 -13
  189. package/src/components/editor/utils/getDOMRangeRect.ts +0 -27
  190. package/src/components/editor/utils/getSelectedNode.ts +0 -27
  191. package/src/components/editor/utils/gif.ts +0 -29
  192. package/src/components/editor/utils/invariant.ts +0 -15
  193. package/src/components/editor/utils/setFloatingElemPosition.ts +0 -51
  194. package/src/components/editor/utils/setFloatingElemPositionForLinkEditor.ts +0 -40
  195. package/src/components/editor/utils/setNodePlaceholderFromSelection/getNodePlaceholder.ts +0 -51
  196. package/src/components/editor/utils/setNodePlaceholderFromSelection/setNodePlaceholderFromSelection.ts +0 -15
  197. package/src/components/editor/utils/setNodePlaceholderFromSelection/setPlaceholderOnSelection.ts +0 -114
  198. package/src/components/editor/utils/setNodePlaceholderFromSelection/styles.css +0 -6
  199. package/src/components/editor/utils/url.ts +0 -109
  200. package/src/components/editor/utils/useLayoutEffect.ts +0 -13
  201. package/src/components/providers/QueryProvider.tsx +0 -15
  202. package/src/components/providers/SharedHistoryContext.tsx +0 -28
  203. package/src/components/providers/ToolbarContext.tsx +0 -123
  204. package/src/components/providers/theme-provider.tsx +0 -11
  205. package/src/components/theme/ModeToggle.tsx +0 -40
  206. package/src/components/ui/FileInput.tsx +0 -40
  207. package/src/components/ui/Input.css +0 -32
  208. package/src/components/ui/Select.css +0 -42
  209. package/src/components/ui/Select.tsx +0 -36
  210. package/src/components/ui/TextInput.tsx +0 -48
  211. package/src/components/ui/ai/ai-button.tsx +0 -574
  212. package/src/components/ui/ai/border.tsx +0 -99
  213. package/src/components/ui/ai/placeholder-input-vanish.tsx +0 -282
  214. package/src/components/ui/button.tsx +0 -89
  215. package/src/components/ui/card.tsx +0 -76
  216. package/src/components/ui/checkbox.tsx +0 -30
  217. package/src/components/ui/command.tsx +0 -153
  218. package/src/components/ui/dialog/Dialog.css +0 -25
  219. package/src/components/ui/dialog/Dialog.tsx +0 -34
  220. package/src/components/ui/dialog.tsx +0 -122
  221. package/src/components/ui/drop-downs/background-color.tsx +0 -183
  222. package/src/components/ui/drop-downs/block-format.tsx +0 -159
  223. package/src/components/ui/drop-downs/code.tsx +0 -42
  224. package/src/components/ui/drop-downs/color.tsx +0 -177
  225. package/src/components/ui/drop-downs/font-size.tsx +0 -138
  226. package/src/components/ui/drop-downs/font.tsx +0 -155
  227. package/src/components/ui/drop-downs/index.tsx +0 -122
  228. package/src/components/ui/drop-downs/insert-node.tsx +0 -213
  229. package/src/components/ui/drop-downs/text-align.tsx +0 -123
  230. package/src/components/ui/drop-downs/text-format.tsx +0 -104
  231. package/src/components/ui/dropdown-menu.tsx +0 -201
  232. package/src/components/ui/equation/EquationEditor.css +0 -38
  233. package/src/components/ui/equation/EquationEditor.tsx +0 -56
  234. package/src/components/ui/equation/KatexEquationAlterer.css +0 -41
  235. package/src/components/ui/equation/KatexEquationAlterer.tsx +0 -83
  236. package/src/components/ui/equation/KatexRenderer.tsx +0 -66
  237. package/src/components/ui/excalidraw/ExcalidrawModal.css +0 -64
  238. package/src/components/ui/excalidraw/ExcalidrawModal.tsx +0 -234
  239. package/src/components/ui/excalidraw/Modal.css +0 -62
  240. package/src/components/ui/excalidraw/Modal.tsx +0 -110
  241. package/src/components/ui/hover-card.tsx +0 -29
  242. package/src/components/ui/image/error-image.tsx +0 -17
  243. package/src/components/ui/image/file-upload.tsx +0 -240
  244. package/src/components/ui/image/image-resizer.tsx +0 -297
  245. package/src/components/ui/image/image-toolbar.tsx +0 -264
  246. package/src/components/ui/image/index.tsx +0 -408
  247. package/src/components/ui/image/lazy-image.tsx +0 -68
  248. package/src/components/ui/image/lazy-video.tsx +0 -71
  249. package/src/components/ui/input.tsx +0 -22
  250. package/src/components/ui/models/custom-dialog.tsx +0 -320
  251. package/src/components/ui/models/insert-gif.tsx +0 -90
  252. package/src/components/ui/models/insert-image.tsx +0 -52
  253. package/src/components/ui/models/insert-poll.tsx +0 -29
  254. package/src/components/ui/models/insert-table.tsx +0 -62
  255. package/src/components/ui/models/use-model.tsx +0 -91
  256. package/src/components/ui/poll/poll-component.tsx +0 -304
  257. package/src/components/ui/popover.tsx +0 -33
  258. package/src/components/ui/progress.tsx +0 -28
  259. package/src/components/ui/scroll-area.tsx +0 -48
  260. package/src/components/ui/separator.tsx +0 -31
  261. package/src/components/ui/skeleton.tsx +0 -15
  262. package/src/components/ui/sonner.tsx +0 -31
  263. package/src/components/ui/stepper/step.tsx +0 -179
  264. package/src/components/ui/stepper/stepper.tsx +0 -89
  265. package/src/components/ui/textarea.tsx +0 -22
  266. package/src/components/ui/toggle.tsx +0 -71
  267. package/src/components/ui/tooltip.tsx +0 -32
  268. package/src/components/ui/write/text-format-floting-toolbar.tsx +0 -346
  269. package/src/lib/edgestore.ts +0 -9
  270. package/src/lib/pinecone-client.ts +0 -0
  271. package/src/lib/utils.ts +0 -6
  272. package/src/utils/docSerialization.ts +0 -77
  273. package/src/utils/emoji-list.ts +0 -16615
  274. package/src/utils/getDOMRangeRect.ts +0 -27
  275. package/src/utils/getThemeSelector.ts +0 -25
  276. package/src/utils/isMobileWidth.ts +0 -7
  277. package/src/utils/joinClasses.ts +0 -13
  278. package/src/utils/setFloatingElemPosition.ts +0 -74
  279. package/src/utils/setFloatingElemPositionForLinkEditor.ts +0 -46
  280. package/src/utils/swipe.ts +0 -127
  281. package/src/utils/url.ts +0 -38
  282. package/tsconfig.json +0 -27
package/dist/index.mjs ADDED
@@ -0,0 +1,1790 @@
1
+ import {
2
+ SpeechToTextPlugin_default
3
+ } from "./chunk-77UA6HYR.mjs";
4
+ import {
5
+ CodeHighlightPlugin,
6
+ LexicalAutoLinkPlugin,
7
+ LinkWithMetaDataPlugin,
8
+ nodes_default
9
+ } from "./chunk-XLER2DHM.mjs";
10
+ import {
11
+ Progress,
12
+ UploadProvider,
13
+ useUpload
14
+ } from "./chunk-JXDPPUJI.mjs";
15
+ import {
16
+ DynamicBlockPlugin,
17
+ EquationsPlugin,
18
+ InlineImagePlugin,
19
+ StoryBuilderPlugin
20
+ } from "./chunk-WJRHXI2C.mjs";
21
+ import {
22
+ PollPlugin
23
+ } from "./chunk-U47ABU5Z.mjs";
24
+ import {
25
+ AutoEmbedPlugin,
26
+ CollapsiblePlugin,
27
+ FigmaPlugin,
28
+ LayoutPlugin,
29
+ TwitterPlugin,
30
+ YouTubePlugin
31
+ } from "./chunk-AMMKBSST.mjs";
32
+ import "./chunk-5QSNIVIG.mjs";
33
+ import {
34
+ INSERT_IMAGE_COMMAND,
35
+ ImagesPlugin
36
+ } from "./chunk-LGG4IUIA.mjs";
37
+ import "./chunk-5BAKY5KN.mjs";
38
+ import {
39
+ AIProvider,
40
+ useAI
41
+ } from "./chunk-YUDCJRJM.mjs";
42
+ import {
43
+ StepperPlugin
44
+ } from "./chunk-6RNZQOH2.mjs";
45
+ import "./chunk-GXYD4VZM.mjs";
46
+ import {
47
+ CAN_USE_DOM,
48
+ isCapitalize,
49
+ isCenterAlign,
50
+ isClearFormatting,
51
+ isDecreaseFontSize,
52
+ isFormatBulletList,
53
+ isFormatCheckList,
54
+ isFormatCode,
55
+ isFormatHeading,
56
+ isFormatNumberedList,
57
+ isFormatParagraph,
58
+ isFormatQuote,
59
+ isIncreaseFontSize,
60
+ isIndent,
61
+ isInsertCodeBlock,
62
+ isInsertLink,
63
+ isJustifyAlign,
64
+ isLeftAlign,
65
+ isLowercase,
66
+ isOutdent,
67
+ isRightAlign,
68
+ isStrikeThrough,
69
+ isSubscript,
70
+ isSuperscript,
71
+ isUppercase
72
+ } from "./chunk-ZB5LZQKC.mjs";
73
+ import {
74
+ clearFormatting,
75
+ formatBulletList,
76
+ formatCheckList,
77
+ formatCode,
78
+ formatHeading,
79
+ formatNumberedList,
80
+ formatParagraph,
81
+ formatQuote,
82
+ updateFontSize
83
+ } from "./chunk-PZSUSXQG.mjs";
84
+ import {
85
+ DEFAULT_FONT_SIZE,
86
+ MAX_ALLOWED_FONT_SIZE,
87
+ MIN_ALLOWED_FONT_SIZE,
88
+ ToolbarContext,
89
+ blockTypeToBlockName,
90
+ useToolbarState
91
+ } from "./chunk-7NZAPJ4G.mjs";
92
+ import {
93
+ SharedHistoryContext,
94
+ useSharedHistoryContext
95
+ } from "./chunk-4EXYCTGJ.mjs";
96
+ import "./chunk-N3WN46VL.mjs";
97
+ import {
98
+ Skeleton
99
+ } from "./chunk-QEIFVK5M.mjs";
100
+ import "./chunk-GZPNVR7L.mjs";
101
+ import {
102
+ HintPlugin
103
+ } from "./chunk-G53GLEAY.mjs";
104
+ import "./chunk-YPHOEJ46.mjs";
105
+ import {
106
+ sanitizeUrl
107
+ } from "./chunk-4VWFVWYP.mjs";
108
+ import "./chunk-KJV3FAZ7.mjs";
109
+ import "./chunk-3JVFG7ER.mjs";
110
+ import "./chunk-4MEDW3T6.mjs";
111
+ import {
112
+ Badge
113
+ } from "./chunk-FSM26655.mjs";
114
+ import {
115
+ Card,
116
+ CardContent,
117
+ CardHeader,
118
+ CardTitle
119
+ } from "./chunk-3G37YKTV.mjs";
120
+ import "./chunk-POGRR73N.mjs";
121
+ import {
122
+ Button
123
+ } from "./chunk-BIU7WTLX.mjs";
124
+ import {
125
+ cn
126
+ } from "./chunk-YHPNOWFH.mjs";
127
+ import {
128
+ React,
129
+ __spreadProps,
130
+ __spreadValues,
131
+ init_react_shim
132
+ } from "./chunk-77KXU36M.mjs";
133
+
134
+ // src/index.ts
135
+ init_react_shim();
136
+
137
+ // src/components/editor/index.tsx
138
+ init_react_shim();
139
+ import React3 from "react";
140
+ import { LexicalComposer } from "@lexical/react/LexicalComposer";
141
+
142
+ // src/components/editor/themes/editor-theme.ts
143
+ init_react_shim();
144
+ var theme = {
145
+ code: `
146
+ bg-[#e1e1e1] dark:bg-[#1a1a1a] m-0 text-sm
147
+ overflow-auto relative pl-[52px] p-3 font-mono group
148
+ rounded-sm w-full h-fit block line-code
149
+ `,
150
+ codeHighlight: {
151
+ atrule: "PlaygroundEditorTheme__tokenAttr",
152
+ attr: "PlaygroundEditorTheme__tokenAttr",
153
+ boolean: "PlaygroundEditorTheme__tokenProperty",
154
+ builtin: "PlaygroundEditorTheme__tokenSelector",
155
+ cdata: "PlaygroundEditorTheme__tokenComment",
156
+ char: "PlaygroundEditorTheme__tokenSelector",
157
+ class: "PlaygroundEditorTheme__tokenFunction",
158
+ "class-name": "PlaygroundEditorTheme__tokenFunction",
159
+ comment: "PlaygroundEditorTheme__tokenComment",
160
+ constant: "PlaygroundEditorTheme__tokenProperty",
161
+ deleted: "PlaygroundEditorTheme__tokenProperty",
162
+ doctype: "PlaygroundEditorTheme__tokenComment",
163
+ entity: "PlaygroundEditorTheme__tokenOperator",
164
+ function: "PlaygroundEditorTheme__tokenFunction",
165
+ important: "PlaygroundEditorTheme__tokenVariable",
166
+ inserted: "PlaygroundEditorTheme__tokenSelector",
167
+ keyword: "PlaygroundEditorTheme__tokenAttr",
168
+ namespace: "PlaygroundEditorTheme__tokenVariable",
169
+ number: "PlaygroundEditorTheme__tokenProperty",
170
+ operator: "PlaygroundEditorTheme__tokenOperator",
171
+ prolog: "PlaygroundEditorTheme__tokenComment",
172
+ property: "PlaygroundEditorTheme__tokenProperty",
173
+ punctuation: "PlaygroundEditorTheme__tokenPunctuation",
174
+ regex: "PlaygroundEditorTheme__tokenVariable",
175
+ selector: "PlaygroundEditorTheme__tokenSelector",
176
+ string: "PlaygroundEditorTheme__tokenSelector",
177
+ symbol: "PlaygroundEditorTheme__tokenProperty",
178
+ tag: "PlaygroundEditorTheme__tokenProperty",
179
+ url: "PlaygroundEditorTheme__tokenOperator",
180
+ variable: "PlaygroundEditorTheme__tokenVariable"
181
+ },
182
+ embedBlock: {
183
+ base: "PlaygroundEditorTheme__embedBlock",
184
+ focus: "PlaygroundEditorTheme__embedBlockFocus"
185
+ },
186
+ list: {
187
+ checklist: "PlaygroundEditorTheme__checklist",
188
+ listitem: "PlaygroundEditorTheme__listItem",
189
+ listitemChecked: "PlaygroundEditorTheme__listItemChecked",
190
+ listitemUnchecked: "PlaygroundEditorTheme__listItemUnchecked",
191
+ nested: {
192
+ listitem: "PlaygroundEditorTheme__nestedListItem"
193
+ },
194
+ olDepth: [
195
+ "PlaygroundEditorTheme__ol1 ",
196
+ "PlaygroundEditorTheme__ol2",
197
+ "PlaygroundEditorTheme__ol3",
198
+ "PlaygroundEditorTheme__ol4",
199
+ "PlaygroundEditorTheme__ol5"
200
+ ],
201
+ ulDepth: [
202
+ "PlaygroundEditorTheme__ul1",
203
+ "PlaygroundEditorTheme__ul2",
204
+ "PlaygroundEditorTheme__ul3",
205
+ "PlaygroundEditorTheme__ul4",
206
+ "PlaygroundEditorTheme__ul5"
207
+ ],
208
+ ul: "ul",
209
+ ol: "ol"
210
+ },
211
+ paragraph: "leading-7",
212
+ link: `underline cursor-pointer text-blue-600 after:content-['_\u2197']`,
213
+ hr: "w-full h-1 border-input",
214
+ table: "PlaygroundEditorTheme__table",
215
+ tableCell: "PlaygroundEditorTheme__tableCell",
216
+ tableCellActionButton: "PlaygroundEditorTheme__tableCellActionButton",
217
+ tableCellActionButtonContainer: "PlaygroundEditorTheme__tableCellActionButtonContainer",
218
+ tableCellHeader: "PlaygroundEditorTheme__tableCellHeader",
219
+ tableCellResizer: "PlaygroundEditorTheme__tableCellResizer",
220
+ tableCellSelected: "PlaygroundEditorTheme__tableCellSelected",
221
+ tableRowStriping: "PlaygroundEditorTheme__tableRowStriping",
222
+ tableScrollableWrapper: "PlaygroundEditorTheme__tableScrollableWrapper",
223
+ tableSelected: "PlaygroundEditorTheme__tableSelected",
224
+ tableSelection: "PlaygroundEditorTheme__tableSelection",
225
+ layoutContainer: "grid gap-[10px] my-[10px] ",
226
+ layoutItem: "px-2 py-[16px] border dark:border-zinc-800 dark:bg-zinc-900 dark:text-zinc-50 border border-zinc-200 bg-white/90 shadow-md rounded-sm",
227
+ heading: {
228
+ h1: "scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl",
229
+ h2: "scroll-m-20 border-b pb-2 text-3xl font-semibold tracking-tight first:mt-0",
230
+ h3: "scroll-m-20 text-2xl font-semibold tracking-tight",
231
+ h4: "scroll-m-20 text-xl font-semibold tracking-tight",
232
+ h5: "text-lg font-bold",
233
+ h6: "text-sm font-bold"
234
+ },
235
+ quote: "mt-6 border-l-[4px] pl-6 italic",
236
+ text: {
237
+ bold: "font-bold",
238
+ capitalize: "capitalize",
239
+ code: "inline-flex items-center rounded-sm border border-zinc-200 px-0.1 py-0 h-fit min-h-[20px] transition-colors focus:outline-none focus:ring-2 focus:ring-zinc-950 focus:ring-offset-2 dark:border-zinc-800 dark:focus:ring-zinc-300 border-transparent bg-zinc-100 text-zinc-900 hover:bg-zinc-100/80 dark:bg-zinc-800 dark:text-zinc-50 dark:hover:bg-zinc-800/80",
240
+ italic: "italic ",
241
+ lowercase: "lowercase",
242
+ strikethrough: "line-through",
243
+ underline: "underline",
244
+ underlineStrikethrough: "underline line-through",
245
+ uppercase: "uppercase"
246
+ }
247
+ };
248
+ var editor_theme_default = theme;
249
+
250
+ // src/components/editor/Core.tsx
251
+ init_react_shim();
252
+ import { useCallback as useCallback2, useEffect as useEffect7, useState as useState3 } from "react";
253
+ import { useLexicalEditable as useLexicalEditable2 } from "@lexical/react/useLexicalEditable";
254
+ import { useLexicalComposerContext as useLexicalComposerContext6 } from "@lexical/react/LexicalComposerContext";
255
+ import dynamic from "next/dynamic";
256
+ import { RichTextPlugin } from "@lexical/react/LexicalRichTextPlugin";
257
+ import { ContentEditable } from "@lexical/react/LexicalContentEditable";
258
+ import { LexicalErrorBoundary } from "@lexical/react/LexicalErrorBoundary";
259
+ import { LinkPlugin } from "@lexical/react/LexicalLinkPlugin";
260
+ import { HorizontalRulePlugin } from "@lexical/react/LexicalHorizontalRulePlugin";
261
+ import { HistoryPlugin } from "@lexical/react/LexicalHistoryPlugin";
262
+ import { TablePlugin } from "@lexical/react/LexicalTablePlugin";
263
+ import { AutoFocusPlugin } from "@lexical/react/LexicalAutoFocusPlugin";
264
+ import { ClearEditorPlugin } from "@lexical/react/LexicalClearEditorPlugin";
265
+
266
+ // src/components/editor/plugins/ShortcutsPlugin/index.tsx
267
+ init_react_shim();
268
+ import { TOGGLE_LINK_COMMAND } from "@lexical/link";
269
+ import {
270
+ COMMAND_PRIORITY_NORMAL,
271
+ FORMAT_ELEMENT_COMMAND,
272
+ FORMAT_TEXT_COMMAND,
273
+ INDENT_CONTENT_COMMAND,
274
+ KEY_MODIFIER_COMMAND,
275
+ OUTDENT_CONTENT_COMMAND
276
+ } from "lexical";
277
+ import { useEffect } from "react";
278
+ function ShortcutsPlugin({
279
+ editor,
280
+ setIsLinkEditMode
281
+ }) {
282
+ const { toolbarState } = useToolbarState();
283
+ useEffect(() => {
284
+ const keyboardShortcutsHandler = (payload) => {
285
+ const event = payload;
286
+ if (isFormatParagraph(event)) {
287
+ event.preventDefault();
288
+ formatParagraph(editor);
289
+ } else if (isFormatHeading(event)) {
290
+ event.preventDefault();
291
+ const { code } = event;
292
+ const headingSize = `h${code[code.length - 1]}`;
293
+ formatHeading(editor, toolbarState.blockType, headingSize);
294
+ } else if (isFormatBulletList(event)) {
295
+ event.preventDefault();
296
+ formatBulletList(editor, toolbarState.blockType);
297
+ } else if (isFormatNumberedList(event)) {
298
+ event.preventDefault();
299
+ formatNumberedList(editor, toolbarState.blockType);
300
+ } else if (isFormatCheckList(event)) {
301
+ event.preventDefault();
302
+ formatCheckList(editor, toolbarState.blockType);
303
+ } else if (isFormatCode(event)) {
304
+ event.preventDefault();
305
+ formatCode(editor, toolbarState.blockType);
306
+ } else if (isFormatQuote(event)) {
307
+ event.preventDefault();
308
+ formatQuote(editor, toolbarState.blockType);
309
+ } else if (isStrikeThrough(event)) {
310
+ event.preventDefault();
311
+ editor.dispatchCommand(FORMAT_TEXT_COMMAND, "strikethrough");
312
+ } else if (isLowercase(event)) {
313
+ event.preventDefault();
314
+ editor.dispatchCommand(FORMAT_TEXT_COMMAND, "lowercase");
315
+ } else if (isUppercase(event)) {
316
+ event.preventDefault();
317
+ editor.dispatchCommand(FORMAT_TEXT_COMMAND, "uppercase");
318
+ } else if (isCapitalize(event)) {
319
+ event.preventDefault();
320
+ editor.dispatchCommand(FORMAT_TEXT_COMMAND, "capitalize");
321
+ } else if (isIndent(event)) {
322
+ event.preventDefault();
323
+ editor.dispatchCommand(INDENT_CONTENT_COMMAND, void 0);
324
+ } else if (isOutdent(event)) {
325
+ event.preventDefault();
326
+ editor.dispatchCommand(OUTDENT_CONTENT_COMMAND, void 0);
327
+ } else if (isCenterAlign(event)) {
328
+ event.preventDefault();
329
+ editor.dispatchCommand(FORMAT_ELEMENT_COMMAND, "center");
330
+ } else if (isLeftAlign(event)) {
331
+ event.preventDefault();
332
+ editor.dispatchCommand(FORMAT_ELEMENT_COMMAND, "left");
333
+ } else if (isRightAlign(event)) {
334
+ event.preventDefault();
335
+ editor.dispatchCommand(FORMAT_ELEMENT_COMMAND, "right");
336
+ } else if (isJustifyAlign(event)) {
337
+ event.preventDefault();
338
+ editor.dispatchCommand(FORMAT_ELEMENT_COMMAND, "justify");
339
+ } else if (isSubscript(event)) {
340
+ event.preventDefault();
341
+ editor.dispatchCommand(FORMAT_TEXT_COMMAND, "subscript");
342
+ } else if (isSuperscript(event)) {
343
+ event.preventDefault();
344
+ editor.dispatchCommand(FORMAT_TEXT_COMMAND, "superscript");
345
+ } else if (isInsertCodeBlock(event)) {
346
+ event.preventDefault();
347
+ editor.dispatchCommand(FORMAT_TEXT_COMMAND, "code");
348
+ } else if (isIncreaseFontSize(event)) {
349
+ event.preventDefault();
350
+ updateFontSize(
351
+ editor,
352
+ 1 /* increment */,
353
+ toolbarState.fontSizeInputValue
354
+ );
355
+ } else if (isDecreaseFontSize(event)) {
356
+ event.preventDefault();
357
+ updateFontSize(
358
+ editor,
359
+ 2 /* decrement */,
360
+ toolbarState.fontSizeInputValue
361
+ );
362
+ } else if (isClearFormatting(event)) {
363
+ event.preventDefault();
364
+ clearFormatting(editor);
365
+ } else if (isInsertLink(event)) {
366
+ event.preventDefault();
367
+ const url = toolbarState.isLink ? null : sanitizeUrl("https://");
368
+ setIsLinkEditMode(!toolbarState.isLink);
369
+ editor.dispatchCommand(TOGGLE_LINK_COMMAND, url);
370
+ }
371
+ return false;
372
+ };
373
+ return editor.registerCommand(
374
+ KEY_MODIFIER_COMMAND,
375
+ keyboardShortcutsHandler,
376
+ COMMAND_PRIORITY_NORMAL
377
+ );
378
+ }, [
379
+ editor,
380
+ toolbarState.isLink,
381
+ toolbarState.blockType,
382
+ toolbarState.fontSizeInputValue,
383
+ setIsLinkEditMode
384
+ ]);
385
+ return null;
386
+ }
387
+
388
+ // src/components/editor/plugins/TabFocusPlugin/index.ts
389
+ init_react_shim();
390
+ import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
391
+ import {
392
+ $getSelection,
393
+ $isRangeSelection,
394
+ $setSelection,
395
+ FOCUS_COMMAND
396
+ } from "lexical";
397
+ import { useEffect as useEffect2 } from "react";
398
+ var COMMAND_PRIORITY_LOW = 1;
399
+ var TAB_TO_FOCUS_INTERVAL = 100;
400
+ var lastTabKeyDownTimestamp = 0;
401
+ var hasRegisteredKeyDownListener = false;
402
+ function registerKeyTimeStampTracker() {
403
+ window.addEventListener(
404
+ "keydown",
405
+ (event) => {
406
+ if (event.key === "Tab") {
407
+ lastTabKeyDownTimestamp = event.timeStamp;
408
+ }
409
+ },
410
+ true
411
+ );
412
+ }
413
+ function TabFocusPlugin() {
414
+ const [editor] = useLexicalComposerContext();
415
+ useEffect2(() => {
416
+ if (!hasRegisteredKeyDownListener) {
417
+ registerKeyTimeStampTracker();
418
+ hasRegisteredKeyDownListener = true;
419
+ }
420
+ return editor.registerCommand(
421
+ FOCUS_COMMAND,
422
+ (event) => {
423
+ const selection = $getSelection();
424
+ if ($isRangeSelection(selection)) {
425
+ if (lastTabKeyDownTimestamp + TAB_TO_FOCUS_INTERVAL > event.timeStamp) {
426
+ $setSelection(selection.clone());
427
+ }
428
+ }
429
+ return false;
430
+ },
431
+ COMMAND_PRIORITY_LOW
432
+ );
433
+ }, [editor]);
434
+ return null;
435
+ }
436
+
437
+ // src/components/editor/plugins/TableCellResizer/index.tsx
438
+ init_react_shim();
439
+ import { useLexicalComposerContext as useLexicalComposerContext2 } from "@lexical/react/LexicalComposerContext";
440
+ import { useLexicalEditable } from "@lexical/react/useLexicalEditable";
441
+ import {
442
+ $computeTableMapSkipCellCheck,
443
+ $getTableNodeFromLexicalNodeOrThrow,
444
+ $getTableRowIndexFromTableCellNode,
445
+ $isTableCellNode,
446
+ $isTableRowNode,
447
+ getDOMCellFromTarget,
448
+ getTableElement,
449
+ TableNode
450
+ } from "@lexical/table";
451
+ import { calculateZoomLevel } from "@lexical/utils";
452
+ import { $getNearestNodeFromDOMNode, isHTMLElement } from "lexical";
453
+ import * as React2 from "react";
454
+ import {
455
+ useCallback,
456
+ useEffect as useEffect3,
457
+ useMemo,
458
+ useRef,
459
+ useState
460
+ } from "react";
461
+ import { createPortal } from "react-dom";
462
+ var MIN_ROW_HEIGHT = 33;
463
+ var MIN_COLUMN_WIDTH = 92;
464
+ function TableCellResizer({ editor }) {
465
+ const targetRef = useRef(null);
466
+ const resizerRef = useRef(null);
467
+ const tableRectRef = useRef(null);
468
+ const mouseStartPosRef = useRef(null);
469
+ const [mouseCurrentPos, updateMouseCurrentPos] = useState(null);
470
+ const [activeCell, updateActiveCell] = useState(null);
471
+ const [isMouseDown, updateIsMouseDown] = useState(false);
472
+ const [draggingDirection, updateDraggingDirection] = useState(null);
473
+ const resetState = useCallback(() => {
474
+ updateActiveCell(null);
475
+ targetRef.current = null;
476
+ updateDraggingDirection(null);
477
+ mouseStartPosRef.current = null;
478
+ tableRectRef.current = null;
479
+ }, []);
480
+ const isMouseDownOnEvent = (event) => {
481
+ return (event.buttons & 1) === 1;
482
+ };
483
+ useEffect3(() => {
484
+ return editor.registerNodeTransform(TableNode, (tableNode) => {
485
+ if (tableNode.getColWidths()) {
486
+ return tableNode;
487
+ }
488
+ const numColumns = tableNode.getColumnCount();
489
+ const columnWidth = MIN_COLUMN_WIDTH;
490
+ tableNode.setColWidths(Array(numColumns).fill(columnWidth));
491
+ return tableNode;
492
+ });
493
+ }, [editor]);
494
+ useEffect3(() => {
495
+ const onMouseMove = (event) => {
496
+ const target = event.target;
497
+ if (!isHTMLElement(target)) {
498
+ return;
499
+ }
500
+ if (draggingDirection) {
501
+ updateMouseCurrentPos({
502
+ x: event.clientX,
503
+ y: event.clientY
504
+ });
505
+ return;
506
+ }
507
+ updateIsMouseDown(isMouseDownOnEvent(event));
508
+ if (resizerRef.current && resizerRef.current.contains(target)) {
509
+ return;
510
+ }
511
+ if (targetRef.current !== target) {
512
+ targetRef.current = target;
513
+ const cell = getDOMCellFromTarget(target);
514
+ if (cell && activeCell !== cell) {
515
+ editor.getEditorState().read(
516
+ () => {
517
+ const tableCellNode = $getNearestNodeFromDOMNode(cell.elem);
518
+ if (!tableCellNode) {
519
+ throw new Error("TableCellResizer: Table cell node not found.");
520
+ }
521
+ const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
522
+ const tableElement = getTableElement(
523
+ tableNode,
524
+ editor.getElementByKey(tableNode.getKey())
525
+ );
526
+ if (!tableElement) {
527
+ throw new Error("TableCellResizer: Table element not found.");
528
+ }
529
+ targetRef.current = target;
530
+ tableRectRef.current = tableElement.getBoundingClientRect();
531
+ updateActiveCell(cell);
532
+ },
533
+ { editor }
534
+ );
535
+ } else if (cell == null) {
536
+ resetState();
537
+ }
538
+ }
539
+ };
540
+ const onMouseDown = () => {
541
+ updateIsMouseDown(true);
542
+ };
543
+ const onMouseUp = () => {
544
+ updateIsMouseDown(false);
545
+ };
546
+ const removeRootListener = editor.registerRootListener(
547
+ (rootElement, prevRootElement) => {
548
+ prevRootElement == null ? void 0 : prevRootElement.removeEventListener("mousemove", onMouseMove);
549
+ prevRootElement == null ? void 0 : prevRootElement.removeEventListener("mousedown", onMouseDown);
550
+ prevRootElement == null ? void 0 : prevRootElement.removeEventListener("mouseup", onMouseUp);
551
+ rootElement == null ? void 0 : rootElement.addEventListener("mousemove", onMouseMove);
552
+ rootElement == null ? void 0 : rootElement.addEventListener("mousedown", onMouseDown);
553
+ rootElement == null ? void 0 : rootElement.addEventListener("mouseup", onMouseUp);
554
+ }
555
+ );
556
+ return () => {
557
+ removeRootListener();
558
+ };
559
+ }, [activeCell, draggingDirection, editor, resetState]);
560
+ const isHeightChanging = (direction) => {
561
+ if (direction === "bottom") {
562
+ return true;
563
+ }
564
+ return false;
565
+ };
566
+ const updateRowHeight = useCallback(
567
+ (heightChange) => {
568
+ if (!activeCell) {
569
+ throw new Error("TableCellResizer: Expected active cell.");
570
+ }
571
+ editor.update(
572
+ () => {
573
+ const tableCellNode = $getNearestNodeFromDOMNode(activeCell.elem);
574
+ if (!$isTableCellNode(tableCellNode)) {
575
+ throw new Error("TableCellResizer: Table cell node not found.");
576
+ }
577
+ const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
578
+ const tableRowIndex = $getTableRowIndexFromTableCellNode(tableCellNode) + tableCellNode.getRowSpan() - 1;
579
+ const tableRows = tableNode.getChildren();
580
+ if (tableRowIndex >= tableRows.length || tableRowIndex < 0) {
581
+ throw new Error("Expected table cell to be inside of table row.");
582
+ }
583
+ const tableRow = tableRows[tableRowIndex];
584
+ if (!$isTableRowNode(tableRow)) {
585
+ throw new Error("Expected table row");
586
+ }
587
+ let height = tableRow.getHeight();
588
+ if (height === void 0) {
589
+ const rowCells = tableRow.getChildren();
590
+ height = Math.min(
591
+ ...rowCells.map(
592
+ (cell) => {
593
+ var _a;
594
+ return (_a = getCellNodeHeight(cell, editor)) != null ? _a : Infinity;
595
+ }
596
+ )
597
+ );
598
+ }
599
+ const newHeight = Math.max(height + heightChange, MIN_ROW_HEIGHT);
600
+ tableRow.setHeight(newHeight);
601
+ },
602
+ { tag: "skip-scroll-into-view" }
603
+ );
604
+ },
605
+ [activeCell, editor]
606
+ );
607
+ const getCellNodeHeight = (cell, activeEditor) => {
608
+ const domCellNode = activeEditor.getElementByKey(cell.getKey());
609
+ return domCellNode == null ? void 0 : domCellNode.clientHeight;
610
+ };
611
+ const getCellColumnIndex = (tableCellNode, tableMap) => {
612
+ for (let row = 0; row < tableMap.length; row++) {
613
+ for (let column = 0; column < tableMap[row].length; column++) {
614
+ if (tableMap[row][column].cell === tableCellNode) {
615
+ return column;
616
+ }
617
+ }
618
+ }
619
+ };
620
+ const updateColumnWidth = useCallback(
621
+ (widthChange) => {
622
+ if (!activeCell) {
623
+ throw new Error("TableCellResizer: Expected active cell.");
624
+ }
625
+ editor.update(
626
+ () => {
627
+ const tableCellNode = $getNearestNodeFromDOMNode(activeCell.elem);
628
+ if (!$isTableCellNode(tableCellNode)) {
629
+ throw new Error("TableCellResizer: Table cell node not found.");
630
+ }
631
+ const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
632
+ const [tableMap] = $computeTableMapSkipCellCheck(
633
+ tableNode,
634
+ null,
635
+ null
636
+ );
637
+ const columnIndex = getCellColumnIndex(tableCellNode, tableMap);
638
+ if (columnIndex === void 0) {
639
+ throw new Error("TableCellResizer: Table column not found.");
640
+ }
641
+ const colWidths = tableNode.getColWidths();
642
+ if (!colWidths) {
643
+ return;
644
+ }
645
+ const width = colWidths[columnIndex];
646
+ if (width === void 0) {
647
+ return;
648
+ }
649
+ const newColWidths = [...colWidths];
650
+ const newWidth = Math.max(width + widthChange, MIN_COLUMN_WIDTH);
651
+ newColWidths[columnIndex] = newWidth;
652
+ tableNode.setColWidths(newColWidths);
653
+ },
654
+ { tag: "skip-scroll-into-view" }
655
+ );
656
+ },
657
+ [activeCell, editor]
658
+ );
659
+ const mouseUpHandler = useCallback(
660
+ (direction) => {
661
+ const handler = (event) => {
662
+ event.preventDefault();
663
+ event.stopPropagation();
664
+ if (!activeCell) {
665
+ throw new Error("TableCellResizer: Expected active cell.");
666
+ }
667
+ if (mouseStartPosRef.current) {
668
+ const { x, y } = mouseStartPosRef.current;
669
+ if (activeCell === null) {
670
+ return;
671
+ }
672
+ const zoom = calculateZoomLevel(event.target);
673
+ if (isHeightChanging(direction)) {
674
+ const heightChange = (event.clientY - y) / zoom;
675
+ updateRowHeight(heightChange);
676
+ } else {
677
+ const widthChange = (event.clientX - x) / zoom;
678
+ updateColumnWidth(widthChange);
679
+ }
680
+ resetState();
681
+ document.removeEventListener("mouseup", handler);
682
+ }
683
+ };
684
+ return handler;
685
+ },
686
+ [activeCell, resetState, updateColumnWidth, updateRowHeight]
687
+ );
688
+ const toggleResize = useCallback(
689
+ (direction) => (event) => {
690
+ event.preventDefault();
691
+ event.stopPropagation();
692
+ if (!activeCell) {
693
+ throw new Error("TableCellResizer: Expected active cell.");
694
+ }
695
+ mouseStartPosRef.current = {
696
+ x: event.clientX,
697
+ y: event.clientY
698
+ };
699
+ updateMouseCurrentPos(mouseStartPosRef.current);
700
+ updateDraggingDirection(direction);
701
+ document.addEventListener("mouseup", mouseUpHandler(direction));
702
+ },
703
+ [activeCell, mouseUpHandler]
704
+ );
705
+ const getResizers = useCallback(() => {
706
+ if (activeCell) {
707
+ const { height, width, top, left } = activeCell.elem.getBoundingClientRect();
708
+ const zoom = calculateZoomLevel(activeCell.elem);
709
+ const zoneWidth = 10;
710
+ const styles = {
711
+ bottom: {
712
+ backgroundColor: "none",
713
+ "zIndex": "10",
714
+ cursor: "row-resize",
715
+ height: `${zoneWidth}px`,
716
+ left: `${window.pageXOffset + left}px`,
717
+ top: `${window.pageYOffset + top + height - zoneWidth / 2}px`,
718
+ width: `${width}px`
719
+ },
720
+ right: {
721
+ backgroundColor: "none",
722
+ "zIndex": "10",
723
+ cursor: "col-resize",
724
+ height: `${height}px`,
725
+ left: `${window.pageXOffset + left + width - zoneWidth / 2}px`,
726
+ top: `${window.pageYOffset + top}px`,
727
+ width: `${zoneWidth}px`
728
+ }
729
+ };
730
+ const tableRect = tableRectRef.current;
731
+ if (draggingDirection && mouseCurrentPos && tableRect) {
732
+ if (isHeightChanging(draggingDirection)) {
733
+ styles[draggingDirection].left = `${window.pageXOffset + tableRect.left}px`;
734
+ styles[draggingDirection].top = `${window.pageYOffset + mouseCurrentPos.y / zoom}px`;
735
+ styles[draggingDirection].height = "3px";
736
+ styles[draggingDirection].width = `${tableRect.width}px`;
737
+ } else {
738
+ styles[draggingDirection].top = `${window.pageYOffset + tableRect.top}px`;
739
+ styles[draggingDirection].left = `${window.pageXOffset + mouseCurrentPos.x / zoom}px`;
740
+ styles[draggingDirection].width = "3px";
741
+ styles[draggingDirection].height = `${tableRect.height}px`;
742
+ }
743
+ styles[draggingDirection].backgroundColor = "#adf";
744
+ }
745
+ return styles;
746
+ }
747
+ return {
748
+ bottom: null,
749
+ left: null,
750
+ right: null,
751
+ top: null
752
+ };
753
+ }, [activeCell, draggingDirection, mouseCurrentPos]);
754
+ const resizerStyles = getResizers();
755
+ return /* @__PURE__ */ React2.createElement("div", { ref: resizerRef }, activeCell != null && !isMouseDown && /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(
756
+ "div",
757
+ {
758
+ className: " absolute TableCellResizer__ui",
759
+ style: resizerStyles.right || void 0,
760
+ onMouseDown: toggleResize("right")
761
+ }
762
+ ), /* @__PURE__ */ React2.createElement(
763
+ "div",
764
+ {
765
+ className: "absolute TableCellResizer__ui",
766
+ style: resizerStyles.bottom || void 0,
767
+ onMouseDown: toggleResize("bottom")
768
+ }
769
+ )));
770
+ }
771
+ function TableCellResizerPlugin() {
772
+ const [editor] = useLexicalComposerContext2();
773
+ const isEditable = useLexicalEditable();
774
+ const [mounted, setMounted] = useState(false);
775
+ useEffect3(() => {
776
+ setMounted(true);
777
+ }, []);
778
+ const portal = useMemo(() => {
779
+ if (!mounted || !isEditable) return null;
780
+ return createPortal(/* @__PURE__ */ React2.createElement(TableCellResizer, { editor }), document.body);
781
+ }, [mounted, isEditable, editor]);
782
+ return portal;
783
+ }
784
+
785
+ // src/components/editor/Core.tsx
786
+ import { TabIndentationPlugin } from "@lexical/react/LexicalTabIndentationPlugin";
787
+ import { CheckListPlugin } from "@lexical/react/LexicalCheckListPlugin";
788
+ import { ListPlugin } from "@lexical/react/LexicalListPlugin";
789
+
790
+ // src/components/editor/plugins/DragDropPastePlugin/index.tsx
791
+ init_react_shim();
792
+ import { useLexicalComposerContext as useLexicalComposerContext3 } from "@lexical/react/LexicalComposerContext";
793
+ import { DRAG_DROP_PASTE } from "@lexical/rich-text";
794
+ import { isMimeType, mediaFileReader } from "@lexical/utils";
795
+ import { COMMAND_PRIORITY_LOW as COMMAND_PRIORITY_LOW2 } from "lexical";
796
+ import { useEffect as useEffect4 } from "react";
797
+ var ACCEPTABLE_IMAGE_TYPES = [
798
+ "image/",
799
+ "image/heic",
800
+ "image/heif",
801
+ "image/gif",
802
+ "image/webp"
803
+ ];
804
+ function DragDropPaste() {
805
+ const [editor] = useLexicalComposerContext3();
806
+ useEffect4(() => {
807
+ return editor.registerCommand(
808
+ DRAG_DROP_PASTE,
809
+ (files) => {
810
+ (async () => {
811
+ const filesResult = await mediaFileReader(
812
+ files,
813
+ [ACCEPTABLE_IMAGE_TYPES].flatMap((x) => x)
814
+ );
815
+ for (const { file, result } of filesResult) {
816
+ if (isMimeType(file, ACCEPTABLE_IMAGE_TYPES)) {
817
+ editor.dispatchCommand(INSERT_IMAGE_COMMAND, {
818
+ altText: file.name,
819
+ src: result
820
+ });
821
+ }
822
+ }
823
+ })();
824
+ return true;
825
+ },
826
+ COMMAND_PRIORITY_LOW2
827
+ );
828
+ }, [editor]);
829
+ return null;
830
+ }
831
+
832
+ // src/components/editor/plugins/DraggableBlockPlugin/index.tsx
833
+ init_react_shim();
834
+ import { DraggableBlockPlugin_EXPERIMENTAL } from "@lexical/react/LexicalDraggableBlockPlugin";
835
+ import { useRef as useRef2 } from "react";
836
+ var DRAGGABLE_BLOCK_MENU_CLASSNAME = "draggable-block-menu";
837
+ function DraggableBlockPlugin({
838
+ anchorElem = document.body,
839
+ className
840
+ }) {
841
+ const menuRef = useRef2(null);
842
+ const targetLineRef = useRef2(null);
843
+ const isOnMenu = (element) => {
844
+ return !!element.closest(`.${DRAGGABLE_BLOCK_MENU_CLASSNAME}`);
845
+ };
846
+ return /* @__PURE__ */ React.createElement(
847
+ DraggableBlockPlugin_EXPERIMENTAL,
848
+ {
849
+ anchorElem,
850
+ menuRef,
851
+ targetLineRef,
852
+ menuComponent: /* @__PURE__ */ React.createElement("div", { ref: menuRef, className: cn("draggable-block-menu transition-all z-50 absolute top-0 left-0", className) }, /* @__PURE__ */ React.createElement(
853
+ "svg",
854
+ {
855
+ xmlns: "http://www.w3.org/2000/svg",
856
+ className: "w-4 cursor-move rounded-sm h-4 z-50",
857
+ "data-name": "Layer 1",
858
+ viewBox: "0 0 24 24",
859
+ fill: "currentColor"
860
+ },
861
+ /* @__PURE__ */ React.createElement("path", { stroke: "currentColor", d: "M8.5 10a2 2 0 1 0 2 2 2 2 0 0 0-2-2Zm0 7a2 2 0 1 0 2 2 2 2 0 0 0-2-2Zm7-10a2 2 0 1 0-2-2 2 2 0 0 0 2 2Zm-7-4a2 2 0 1 0 2 2 2 2 0 0 0-2-2Zm7 14a2 2 0 1 0 2 2 2 2 0 0 0-2-2Zm0-7a2 2 0 1 0 2 2 2 2 0 0 0-2-2Z" })
862
+ )),
863
+ targetLineComponent: /* @__PURE__ */ React.createElement(
864
+ "div",
865
+ {
866
+ ref: targetLineRef,
867
+ className: "cursor-none bg-sky-600 h-1 absolute left-0 top-0 opacity-0 will-change-transform"
868
+ }
869
+ ),
870
+ isOnMenu
871
+ }
872
+ );
873
+ }
874
+
875
+ // src/components/editor/Core.tsx
876
+ import { MarkdownShortcutPlugin } from "@lexical/react/LexicalMarkdownShortcutPlugin";
877
+ import { ClickableLinkPlugin } from "@lexical/react/LexicalClickableLinkPlugin";
878
+
879
+ // src/components/editor/lexical-on-change.tsx
880
+ init_react_shim();
881
+ import { useLexicalComposerContext as useLexicalComposerContext4 } from "@lexical/react/LexicalComposerContext";
882
+
883
+ // src/components/editor/utils/useLayoutEffect.ts
884
+ init_react_shim();
885
+ import { useEffect as useEffect5, useLayoutEffect } from "react";
886
+ var useLayoutEffectImpl = CAN_USE_DOM ? useLayoutEffect : useEffect5;
887
+ var useLayoutEffect_default = useLayoutEffectImpl;
888
+
889
+ // src/components/editor/utils/setNodePlaceholderFromSelection/setNodePlaceholderFromSelection.ts
890
+ init_react_shim();
891
+ import { $getSelection as $getSelection2, $isRangeSelection as $isRangeSelection2 } from "lexical";
892
+
893
+ // src/components/editor/utils/setNodePlaceholderFromSelection/setPlaceholderOnSelection.ts
894
+ init_react_shim();
895
+
896
+ // src/components/editor/utils/getAllLexicalChildren.ts
897
+ init_react_shim();
898
+ import { $getNodeByKey, $getRoot } from "lexical";
899
+ var getAllLexicalChildren = (editor) => {
900
+ const childrenKeys = editor.getEditorState().read(() => $getRoot().getChildrenKeys());
901
+ return childrenKeys.map((key) => ({
902
+ key,
903
+ node: $getNodeByKey(key),
904
+ htmlElement: editor.getElementByKey(key)
905
+ }));
906
+ };
907
+
908
+ // src/components/editor/utils/setNodePlaceholderFromSelection/getNodePlaceholder.ts
909
+ init_react_shim();
910
+ import { $isParagraphNode } from "lexical";
911
+ import { $isHeadingNode, $isQuoteNode } from "@lexical/rich-text";
912
+ import { $isListItemNode } from "@lexical/list";
913
+ var getNodePlaceholder = (lexicalNode) => {
914
+ let placeholder;
915
+ if ($isHeadingNode(lexicalNode)) {
916
+ const tag = lexicalNode.getTag();
917
+ placeholder = "Heading";
918
+ switch (tag) {
919
+ case "h1": {
920
+ placeholder += " 1";
921
+ break;
922
+ }
923
+ case "h2": {
924
+ placeholder += " 2";
925
+ break;
926
+ }
927
+ case "h3": {
928
+ placeholder += " 3";
929
+ break;
930
+ }
931
+ case "h4": {
932
+ placeholder += " 4";
933
+ break;
934
+ }
935
+ case "h5": {
936
+ placeholder += "5";
937
+ break;
938
+ }
939
+ case "h6": {
940
+ placeholder += "6";
941
+ break;
942
+ }
943
+ }
944
+ }
945
+ if ($isListItemNode(lexicalNode)) {
946
+ placeholder = "list";
947
+ }
948
+ if ($isQuoteNode(lexicalNode)) {
949
+ placeholder = "Quote";
950
+ }
951
+ if ($isParagraphNode(lexicalNode)) {
952
+ placeholder = "Press '/' for command";
953
+ }
954
+ return placeholder;
955
+ };
956
+
957
+ // src/components/editor/utils/setNodePlaceholderFromSelection/setPlaceholderOnSelection.ts
958
+ var PLACEHOLDER_CLASS_NAME = "node-placeholder";
959
+ var isHtmlHeadingElement = (el) => {
960
+ return el instanceof HTMLHeadingElement;
961
+ };
962
+ var setPlaceholderOnSelection = ({
963
+ selection,
964
+ editor
965
+ }) => {
966
+ const children = getAllLexicalChildren(editor);
967
+ const removePlaceholderClass = (element) => {
968
+ if (!element) return;
969
+ if (element.classList.contains(PLACEHOLDER_CLASS_NAME)) {
970
+ element.classList.remove(PLACEHOLDER_CLASS_NAME);
971
+ element.removeAttribute("data-placeholder");
972
+ }
973
+ Array.from(element.children).forEach((child) => {
974
+ if (child instanceof HTMLElement) {
975
+ removePlaceholderClass(child);
976
+ }
977
+ });
978
+ };
979
+ children.forEach(({ htmlElement, node }) => {
980
+ if (!htmlElement) {
981
+ return;
982
+ }
983
+ if (isHtmlHeadingElement(htmlElement)) {
984
+ return;
985
+ }
986
+ const classList = htmlElement.classList;
987
+ if (node.__type === "collapsible-container") {
988
+ removePlaceholderClass(htmlElement);
989
+ return;
990
+ }
991
+ if (node.__type === "table") {
992
+ removePlaceholderClass(htmlElement);
993
+ return;
994
+ }
995
+ if (node.__type === "layout-container") {
996
+ removePlaceholderClass(htmlElement);
997
+ }
998
+ if (classList.length && classList.contains(PLACEHOLDER_CLASS_NAME)) {
999
+ classList.remove(PLACEHOLDER_CLASS_NAME);
1000
+ htmlElement.removeAttribute("data-placeholder");
1001
+ }
1002
+ });
1003
+ if (children.length === 1 && children[0].htmlElement && !isHtmlHeadingElement(children[0].htmlElement)) {
1004
+ return;
1005
+ }
1006
+ const anchor = selection.anchor;
1007
+ const placeholder = getNodePlaceholder(anchor.getNode());
1008
+ if (placeholder) {
1009
+ const selectedHtmlElement = editor.getElementByKey(anchor.key);
1010
+ selectedHtmlElement == null ? void 0 : selectedHtmlElement.classList.add(PLACEHOLDER_CLASS_NAME);
1011
+ selectedHtmlElement == null ? void 0 : selectedHtmlElement.setAttribute("data-placeholder", placeholder);
1012
+ }
1013
+ };
1014
+
1015
+ // src/components/editor/utils/setNodePlaceholderFromSelection/setNodePlaceholderFromSelection.ts
1016
+ var setNodePlaceholderFromSelection = (editor) => {
1017
+ editor.getEditorState().read(() => {
1018
+ const selection = $getSelection2();
1019
+ if (!$isRangeSelection2(selection)) {
1020
+ return;
1021
+ }
1022
+ setPlaceholderOnSelection({ selection, editor });
1023
+ });
1024
+ };
1025
+
1026
+ // src/components/editor/lexical-on-change.tsx
1027
+ function LexicalOnChangePlugin() {
1028
+ const [editor] = useLexicalComposerContext4();
1029
+ useLayoutEffect_default(() => {
1030
+ const unregisterListener = editor.registerUpdateListener(
1031
+ ({ editorState, dirtyElements, dirtyLeaves, prevEditorState, tags }) => {
1032
+ if (dirtyElements.size === 0 && dirtyLeaves.size === 0 || tags.has("history-merge") || prevEditorState.isEmpty()) {
1033
+ return;
1034
+ }
1035
+ setNodePlaceholderFromSelection(editor);
1036
+ }
1037
+ );
1038
+ return () => {
1039
+ unregisterListener();
1040
+ };
1041
+ }, [editor]);
1042
+ return /* @__PURE__ */ React.createElement(React.Fragment, null);
1043
+ }
1044
+
1045
+ // src/components/editor/Core.tsx
1046
+ import { motion, AnimatePresence } from "framer-motion";
1047
+ import { Sparkles, Lightbulb, Quote } from "lucide-react";
1048
+
1049
+ // src/components/editor/plugins/ContentAnalyticsPlugin/index.tsx
1050
+ init_react_shim();
1051
+ import { useLexicalComposerContext as useLexicalComposerContext5 } from "@lexical/react/LexicalComposerContext";
1052
+ import { $getRoot as $getRoot2 } from "lexical";
1053
+ import { useEffect as useEffect6, useState as useState2 } from "react";
1054
+ import { $isHeadingNode as $isHeadingNode2 } from "@lexical/rich-text";
1055
+ import { $isListNode } from "@lexical/list";
1056
+ import { $isCodeNode } from "@lexical/code";
1057
+ import { Clock, Eye, BarChart3, Target, BookOpen, TrendingUp, Zap, ChevronLeft, ChevronRight } from "lucide-react";
1058
+ function calculateReadabilityScore(avgWordsPerSentence, avgSyllablesPerWord) {
1059
+ const score = 206.835 - 1.015 * avgWordsPerSentence - 84.6 * avgSyllablesPerWord;
1060
+ return Math.max(0, Math.min(100, score));
1061
+ }
1062
+ function calculateEngagementScore(metrics, structure) {
1063
+ let score = 50;
1064
+ if (metrics.wordCount >= 500 && metrics.wordCount <= 2e3) {
1065
+ score += 15;
1066
+ } else if (metrics.wordCount > 2e3) {
1067
+ score += 10;
1068
+ }
1069
+ if (structure.structureScore > 70) score += 10;
1070
+ if (metrics.imageCount > 0) score += 5;
1071
+ if (metrics.listCount > 0) score += 5;
1072
+ if (metrics.codeBlockCount > 0) score += 3;
1073
+ if (metrics.readabilityScore > 60) score += 10;
1074
+ if (metrics.linkCount > 0 && metrics.linkCount <= 10) score += 5;
1075
+ return Math.max(0, Math.min(100, score));
1076
+ }
1077
+ function estimateSyllables(word) {
1078
+ word = word.toLowerCase();
1079
+ if (word.length <= 3) return 1;
1080
+ const vowels = "aeiouy";
1081
+ let syllables = 0;
1082
+ let previousWasVowel = false;
1083
+ for (let i = 0; i < word.length; i++) {
1084
+ const isVowel = vowels.includes(word[i]);
1085
+ if (isVowel && !previousWasVowel) {
1086
+ syllables++;
1087
+ }
1088
+ previousWasVowel = isVowel;
1089
+ }
1090
+ if (word.endsWith("e")) syllables--;
1091
+ return Math.max(1, syllables);
1092
+ }
1093
+ function ContentAnalyticsPlugin() {
1094
+ const [editor] = useLexicalComposerContext5();
1095
+ const [metrics, setMetrics] = useState2({
1096
+ wordCount: 0,
1097
+ readingTime: 0,
1098
+ paragraphCount: 0,
1099
+ headingCount: 0,
1100
+ listCount: 0,
1101
+ codeBlockCount: 0,
1102
+ imageCount: 0,
1103
+ linkCount: 0,
1104
+ sentenceCount: 0,
1105
+ avgWordsPerSentence: 0,
1106
+ readabilityScore: 0,
1107
+ engagementScore: 0
1108
+ });
1109
+ const [structure, setStructure] = useState2({
1110
+ h1Count: 0,
1111
+ h2Count: 0,
1112
+ h3Count: 0,
1113
+ hasIntroduction: false,
1114
+ hasConclusion: false,
1115
+ structureScore: 0
1116
+ });
1117
+ const [isVisible, setIsVisible] = useState2(false);
1118
+ const [isPanelHidden, setIsPanelHidden] = useState2(false);
1119
+ useEffect6(() => {
1120
+ const updateMetrics = () => {
1121
+ editor.read(() => {
1122
+ const root = $getRoot2();
1123
+ const textContent = root.getTextContent();
1124
+ const words = textContent.trim().split(/\s+/).filter((word) => word.length > 0);
1125
+ const wordCount = words.length;
1126
+ const readingTime = Math.ceil(wordCount / 200);
1127
+ let paragraphCount = 0;
1128
+ let headingCount = 0;
1129
+ let listCount = 0;
1130
+ let codeBlockCount = 0;
1131
+ let imageCount = 0;
1132
+ let linkCount = 0;
1133
+ let h1Count = 0;
1134
+ let h2Count = 0;
1135
+ let h3Count = 0;
1136
+ const children = root.getChildren();
1137
+ children.forEach((child) => {
1138
+ if ($isHeadingNode2(child)) {
1139
+ headingCount++;
1140
+ const tag = child.getTag();
1141
+ if (tag === "h1") h1Count++;
1142
+ else if (tag === "h2") h2Count++;
1143
+ else if (tag === "h3") h3Count++;
1144
+ } else if ($isListNode(child)) {
1145
+ listCount++;
1146
+ } else if ($isCodeNode(child)) {
1147
+ codeBlockCount++;
1148
+ } else if (child.getType() === "paragraph") {
1149
+ paragraphCount++;
1150
+ }
1151
+ const countInNode = (node) => {
1152
+ if (node.getType() === "image" || node.getType() === "inline-image") {
1153
+ imageCount++;
1154
+ }
1155
+ if (node.getType() === "link") {
1156
+ linkCount++;
1157
+ }
1158
+ if (node.getChildren) {
1159
+ node.getChildren().forEach(countInNode);
1160
+ }
1161
+ };
1162
+ countInNode(child);
1163
+ });
1164
+ const sentences = textContent.split(/[.!?]+/).filter((s) => s.trim().length > 0);
1165
+ const sentenceCount = sentences.length;
1166
+ const avgWordsPerSentence = sentenceCount > 0 ? wordCount / sentenceCount : 0;
1167
+ const totalSyllables = words.reduce((sum, word) => sum + estimateSyllables(word), 0);
1168
+ const avgSyllablesPerWord = wordCount > 0 ? totalSyllables / wordCount : 0;
1169
+ const readabilityScore = calculateReadabilityScore(avgWordsPerSentence, avgSyllablesPerWord);
1170
+ const hasIntroduction = paragraphCount > 0;
1171
+ const hasConclusion = paragraphCount > 2;
1172
+ let structureScore = 0;
1173
+ if (h1Count === 1) structureScore += 20;
1174
+ if (h2Count >= 2) structureScore += 20;
1175
+ if (hasIntroduction) structureScore += 15;
1176
+ if (hasConclusion) structureScore += 15;
1177
+ if (listCount > 0) structureScore += 10;
1178
+ if (imageCount > 0) structureScore += 10;
1179
+ if (linkCount > 0 && linkCount <= 10) structureScore += 10;
1180
+ const newStructure = {
1181
+ h1Count,
1182
+ h2Count,
1183
+ h3Count,
1184
+ hasIntroduction,
1185
+ hasConclusion,
1186
+ structureScore
1187
+ };
1188
+ const newMetrics = {
1189
+ wordCount,
1190
+ readingTime,
1191
+ paragraphCount,
1192
+ headingCount,
1193
+ listCount,
1194
+ codeBlockCount,
1195
+ imageCount,
1196
+ linkCount,
1197
+ sentenceCount,
1198
+ avgWordsPerSentence,
1199
+ readabilityScore,
1200
+ engagementScore: calculateEngagementScore(
1201
+ {
1202
+ wordCount,
1203
+ readingTime,
1204
+ paragraphCount,
1205
+ headingCount,
1206
+ listCount,
1207
+ codeBlockCount,
1208
+ imageCount,
1209
+ linkCount,
1210
+ sentenceCount,
1211
+ avgWordsPerSentence,
1212
+ readabilityScore,
1213
+ engagementScore: 0
1214
+ },
1215
+ newStructure
1216
+ )
1217
+ };
1218
+ setMetrics(newMetrics);
1219
+ setStructure(newStructure);
1220
+ });
1221
+ };
1222
+ const unregister = editor.registerUpdateListener(() => {
1223
+ updateMetrics();
1224
+ });
1225
+ updateMetrics();
1226
+ return unregister;
1227
+ }, [editor]);
1228
+ useEffect6(() => {
1229
+ setIsVisible(metrics.wordCount > 10);
1230
+ }, [metrics.wordCount]);
1231
+ if (!isVisible) return null;
1232
+ const getReadabilityLabel = (score) => {
1233
+ if (score >= 90) return { label: "Very Easy", color: "bg-green-500" };
1234
+ if (score >= 80) return { label: "Easy", color: "bg-green-400" };
1235
+ if (score >= 70) return { label: "Fairly Easy", color: "bg-yellow-400" };
1236
+ if (score >= 60) return { label: "Standard", color: "bg-yellow-500" };
1237
+ if (score >= 50) return { label: "Fairly Difficult", color: "bg-orange-400" };
1238
+ if (score >= 30) return { label: "Difficult", color: "bg-red-400" };
1239
+ return { label: "Very Difficult", color: "bg-red-500" };
1240
+ };
1241
+ const getEngagementLabel = (score) => {
1242
+ if (score >= 80) return { label: "Excellent", color: "text-green-600" };
1243
+ if (score >= 60) return { label: "Good", color: "text-yellow-600" };
1244
+ if (score >= 40) return { label: "Fair", color: "text-orange-600" };
1245
+ return { label: "Needs Work", color: "text-red-600" };
1246
+ };
1247
+ const readability = getReadabilityLabel(metrics.readabilityScore);
1248
+ const engagement = getEngagementLabel(metrics.engagementScore);
1249
+ return /* @__PURE__ */ React.createElement(
1250
+ "div",
1251
+ {
1252
+ className: cn(
1253
+ "fixed top-20 right-4 z-50 transition-transform duration-300 ease-in-out",
1254
+ isPanelHidden ? "translate-x-full" : "translate-x-0"
1255
+ )
1256
+ },
1257
+ /* @__PURE__ */ React.createElement(
1258
+ Button,
1259
+ {
1260
+ variant: "outline",
1261
+ size: "sm",
1262
+ onClick: () => setIsPanelHidden(!isPanelHidden),
1263
+ className: cn(
1264
+ "absolute top-4 -left-10 z-10 h-8 w-8 p-0 bg-white/95 dark:bg-zinc-900/95 backdrop-blur-sm shadow-lg border border-zinc-200 dark:border-zinc-700 hover:bg-zinc-50 dark:hover:bg-zinc-800",
1265
+ isPanelHidden && "-left-8"
1266
+ )
1267
+ },
1268
+ isPanelHidden ? /* @__PURE__ */ React.createElement(ChevronLeft, { className: "w-4 h-4" }) : /* @__PURE__ */ React.createElement(ChevronRight, { className: "w-4 h-4" })
1269
+ ),
1270
+ /* @__PURE__ */ React.createElement("div", { className: "w-80 space-y-4" }, /* @__PURE__ */ React.createElement(Card, { className: "bg-white/95 dark:bg-zinc-900/95 backdrop-blur-sm shadow-lg border border-zinc-200 dark:border-zinc-700" }, /* @__PURE__ */ React.createElement(CardHeader, { className: "pb-3" }, /* @__PURE__ */ React.createElement(CardTitle, { className: "flex items-center justify-between text-sm font-medium" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React.createElement(BarChart3, { className: "w-4 h-4" }), "Content Analytics"))), /* @__PURE__ */ React.createElement(CardContent, { className: "space-y-4" }, /* @__PURE__ */ React.createElement("div", { className: "grid grid-cols-2 gap-3" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React.createElement(Clock, { className: "w-4 h-4 text-blue-500" }), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "text-lg font-semibold" }, metrics.readingTime, "m"), /* @__PURE__ */ React.createElement("div", { className: "text-xs text-muted-foreground" }, "Reading time"))), /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React.createElement(BookOpen, { className: "w-4 h-4 text-green-500" }), /* @__PURE__ */ React.createElement("div", null, /* @__PURE__ */ React.createElement("div", { className: "text-lg font-semibold" }, metrics.wordCount), /* @__PURE__ */ React.createElement("div", { className: "text-xs text-muted-foreground" }, "Words")))), /* @__PURE__ */ React.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React.createElement(TrendingUp, { className: "w-4 h-4 text-purple-500" }), /* @__PURE__ */ React.createElement("span", { className: "text-sm font-medium" }, "Engagement")), /* @__PURE__ */ React.createElement(Badge, { variant: "outline", className: engagement.color }, engagement.label)), /* @__PURE__ */ React.createElement(Progress, { value: metrics.engagementScore, className: "h-2" }), /* @__PURE__ */ React.createElement("div", { className: "text-xs text-muted-foreground" }, metrics.engagementScore, "/100")), /* @__PURE__ */ React.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ React.createElement(Eye, { className: "w-4 h-4 text-indigo-500" }), /* @__PURE__ */ React.createElement("span", { className: "text-sm font-medium" }, "Readability")), /* @__PURE__ */ React.createElement(Badge, { variant: "outline", className: cn("text-white", readability.color) }, readability.label)), /* @__PURE__ */ React.createElement(Progress, { value: metrics.readabilityScore, className: "h-2" }), /* @__PURE__ */ React.createElement("div", { className: "text-xs text-muted-foreground" }, Math.round(metrics.readabilityScore), "/100 Flesch Score")))), /* @__PURE__ */ React.createElement(Card, { className: "bg-white/95 dark:bg-zinc-900/95 backdrop-blur-sm shadow-lg border border-zinc-200 dark:border-zinc-700" }, /* @__PURE__ */ React.createElement(CardHeader, { className: "pb-3" }, /* @__PURE__ */ React.createElement(CardTitle, { className: "flex items-center gap-2 text-sm font-medium" }, /* @__PURE__ */ React.createElement(Target, { className: "w-4 h-4" }), "Content Structure")), /* @__PURE__ */ React.createElement(CardContent, { className: "space-y-3" }, /* @__PURE__ */ React.createElement("div", { className: "grid grid-cols-2 gap-3 text-xs" }, /* @__PURE__ */ React.createElement("div", { className: "flex justify-between" }, /* @__PURE__ */ React.createElement("span", { className: "text-muted-foreground" }, "H1 Headers:"), /* @__PURE__ */ React.createElement("span", { className: structure.h1Count === 1 ? "text-green-600" : "text-orange-600" }, structure.h1Count)), /* @__PURE__ */ React.createElement("div", { className: "flex justify-between" }, /* @__PURE__ */ React.createElement("span", { className: "text-muted-foreground" }, "H2 Headers:"), /* @__PURE__ */ React.createElement("span", { className: structure.h2Count >= 2 ? "text-green-600" : "text-orange-600" }, structure.h2Count)), /* @__PURE__ */ React.createElement("div", { className: "flex justify-between" }, /* @__PURE__ */ React.createElement("span", { className: "text-muted-foreground" }, "Paragraphs:"), /* @__PURE__ */ React.createElement("span", null, metrics.paragraphCount)), /* @__PURE__ */ React.createElement("div", { className: "flex justify-between" }, /* @__PURE__ */ React.createElement("span", { className: "text-muted-foreground" }, "Lists:"), /* @__PURE__ */ React.createElement("span", null, metrics.listCount)), /* @__PURE__ */ React.createElement("div", { className: "flex justify-between" }, /* @__PURE__ */ React.createElement("span", { className: "text-muted-foreground" }, "Images:"), /* @__PURE__ */ React.createElement("span", null, metrics.imageCount)), /* @__PURE__ */ React.createElement("div", { className: "flex justify-between" }, /* @__PURE__ */ React.createElement("span", { className: "text-muted-foreground" }, "Links:"), /* @__PURE__ */ React.createElement(
1271
+ "span",
1272
+ {
1273
+ className: metrics.linkCount > 0 && metrics.linkCount <= 10 ? "text-green-600" : "text-orange-600"
1274
+ },
1275
+ metrics.linkCount
1276
+ ))), /* @__PURE__ */ React.createElement("div", { className: "space-y-2" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between" }, /* @__PURE__ */ React.createElement("span", { className: "text-sm font-medium" }, "Structure Score"), /* @__PURE__ */ React.createElement("span", { className: "text-sm" }, structure.structureScore, "/100")), /* @__PURE__ */ React.createElement(Progress, { value: structure.structureScore, className: "h-2" })))), metrics.engagementScore < 70 && /* @__PURE__ */ React.createElement(Card, { className: "bg-amber-50/95 dark:bg-amber-900/20 backdrop-blur-sm shadow-lg border border-amber-200 dark:border-amber-800" }, /* @__PURE__ */ React.createElement(CardHeader, { className: "pb-2" }, /* @__PURE__ */ React.createElement(CardTitle, { className: "flex items-center gap-2 text-sm font-medium text-amber-800 dark:text-amber-200" }, /* @__PURE__ */ React.createElement(Zap, { className: "w-4 h-4" }), "Quick Tips")), /* @__PURE__ */ React.createElement(CardContent, { className: "space-y-2" }, /* @__PURE__ */ React.createElement("div", { className: "text-xs text-amber-700 dark:text-amber-300 space-y-1" }, structure.h1Count !== 1 && /* @__PURE__ */ React.createElement("div", null, "\u2022 Use exactly one H1 header for your main title"), structure.h2Count < 2 && /* @__PURE__ */ React.createElement("div", null, "\u2022 Add more H2 headers to break up your content"), metrics.imageCount === 0 && /* @__PURE__ */ React.createElement("div", null, "\u2022 Add images to make your content more engaging"), metrics.listCount === 0 && /* @__PURE__ */ React.createElement("div", null, "\u2022 Use bullet points or numbered lists for better readability"), metrics.wordCount < 300 && /* @__PURE__ */ React.createElement("div", null, "\u2022 Consider expanding your content (aim for 500+ words)"), metrics.readabilityScore < 50 && /* @__PURE__ */ React.createElement("div", null, "\u2022 Try shorter sentences for better readability")))))
1277
+ );
1278
+ }
1279
+
1280
+ // src/components/editor/Core.tsx
1281
+ var SlashCommand = dynamic(() => import("./SlashCommand-GMT5JI33.mjs"), { ssr: false });
1282
+ var ToolbarPlugin = dynamic(() => import("./ToolbarPlugin-7TOZRD2R.mjs"), {
1283
+ ssr: false,
1284
+ loading: () => /* @__PURE__ */ React.createElement("div", { className: "hidden md:block fixed top-14 md:top-20 left-0 right-0 z-50 flex justify-center p-4" }, /* @__PURE__ */ React.createElement(Skeleton, { className: "h-12 w-full max-w-6xl rounded-2xl" }))
1285
+ });
1286
+ var ExportPlugin = dynamic(() => import("./ExportPlugin-V2RLM63S.mjs"), { ssr: false });
1287
+ var TemplatePlugin = dynamic(() => import("./TemplatePlugin-ZD3QEVTI.mjs"), { ssr: false });
1288
+ var ExcalidrawPlugin = dynamic(() => import("./ExcalidrawPlugin-ZFHT62IF.mjs"), {
1289
+ ssr: false
1290
+ });
1291
+ var FloatingLinkEditorPlugin = dynamic(() => import("./FloatingLinkEditorPlugin-TRTCMSP4.mjs"), {
1292
+ ssr: false
1293
+ });
1294
+ var TableCellActionMenuPlugin = dynamic(() => import("./TableCellActionMenuPlugin-PGK2K3VG.mjs"), {
1295
+ ssr: false
1296
+ });
1297
+ var TableHoverActionsPlugin = dynamic(() => import("./TableHoverActionsPlugin-GJVE6VRW.mjs"), {
1298
+ ssr: false
1299
+ });
1300
+ var CodeActionMenuPlugin = dynamic(() => import("./CodeActionMenuPlugin-EINOY4U4.mjs"), { ssr: false });
1301
+ var FloatingTextFormatToolbarPlugin = dynamic(
1302
+ () => import("./FloatingTextFormatToolbarPlugin-F2GY6LMI.mjs"),
1303
+ { ssr: false }
1304
+ );
1305
+ var QUOTES = [
1306
+ { text: "The best way to predict the future is to invent it.", author: "Alan Kay" },
1307
+ { text: "Do not wait to strike till the iron is hot, but make it hot by striking.", author: "William Butler Yeats" },
1308
+ { text: "Creativity is intelligence having fun.", author: "Albert Einstein" },
1309
+ { text: "Start where you are. Use what you have. Do what you can.", author: "Arthur Ashe" },
1310
+ { text: "Your time is limited, so don't waste it living someone else's life.", author: "Steve Jobs" },
1311
+ { text: "The only way to do great work is to love what you do.", author: "Steve Jobs" },
1312
+ { text: "Success is not the key to happiness. Happiness is the key to success.", author: "Albert Schweitzer" },
1313
+ { text: "In the middle of difficulty lies opportunity.", author: "Albert Einstein" },
1314
+ { text: "What we think, we become.", author: "Buddha" },
1315
+ { text: "The journey of a thousand miles begins with one step.", author: "Lao Tzu" },
1316
+ { text: "Believe you can and you're halfway there.", author: "Theodore Roosevelt" },
1317
+ { text: "Innovation distinguishes between a leader and a follower.", author: "Steve Jobs" },
1318
+ { text: "Life is what happens to you while you're busy making other plans.", author: "John Lennon" },
1319
+ { text: "The future belongs to those who believe in the beauty of their dreams.", author: "Eleanor Roosevelt" },
1320
+ { text: "It is during our darkest moments that we must focus to see the light.", author: "Aristotle" }
1321
+ ];
1322
+ function useRotatingQuote() {
1323
+ const [quote, setQuote] = useState3(null);
1324
+ const [isAnimating, setIsAnimating] = useState3(false);
1325
+ const loadNewQuote = useCallback2(() => {
1326
+ setIsAnimating(true);
1327
+ setTimeout(() => {
1328
+ const newQuote = QUOTES[Math.floor(Math.random() * QUOTES.length)];
1329
+ setQuote(newQuote);
1330
+ if (typeof window !== "undefined") {
1331
+ localStorage.setItem(
1332
+ "editorQuote",
1333
+ JSON.stringify(__spreadProps(__spreadValues({}, newQuote), { timestamp: Date.now() }))
1334
+ );
1335
+ }
1336
+ setIsAnimating(false);
1337
+ }, 300);
1338
+ }, []);
1339
+ useEffect7(() => {
1340
+ const loadInitialQuote = () => {
1341
+ if (typeof window !== "undefined") {
1342
+ const stored = localStorage.getItem("editorQuote");
1343
+ if (stored) {
1344
+ try {
1345
+ const parsed = JSON.parse(stored);
1346
+ const isRecent = Date.now() - parsed.timestamp < 3 * 60 * 60 * 1e3;
1347
+ if (isRecent && parsed.text && parsed.author) {
1348
+ setQuote({ text: parsed.text, author: parsed.author });
1349
+ return;
1350
+ }
1351
+ } catch (e) {
1352
+ }
1353
+ }
1354
+ }
1355
+ const newQuote = QUOTES[Math.floor(Math.random() * QUOTES.length)];
1356
+ setQuote(newQuote);
1357
+ };
1358
+ loadInitialQuote();
1359
+ const interval = setInterval(loadNewQuote, 3 * 60 * 60 * 1e3);
1360
+ return () => clearInterval(interval);
1361
+ }, [loadNewQuote]);
1362
+ return { quote, isAnimating, loadNewQuote };
1363
+ }
1364
+ function EnhancedPlaceholder({ quote, isAnimating, onRefresh }) {
1365
+ if (!quote) {
1366
+ return /* @__PURE__ */ React.createElement("div", { className: "absolute inset-0 flex items-center justify-center" }, /* @__PURE__ */ React.createElement(
1367
+ motion.div,
1368
+ {
1369
+ initial: { opacity: 0, scale: 0.9 },
1370
+ animate: { opacity: 1, scale: 1 },
1371
+ className: "flex items-center gap-3 text-gray-400"
1372
+ },
1373
+ /* @__PURE__ */ React.createElement(Sparkles, { className: "h-6 w-6 animate-pulse" }),
1374
+ /* @__PURE__ */ React.createElement("span", { className: "text-lg italic" }, "Loading inspiration...")
1375
+ ));
1376
+ }
1377
+ return /* @__PURE__ */ React.createElement("div", { className: "absolute md:-mt-26 -mt-56 inset-0 pointer-events-none select-none overflow-hidden" }, /* @__PURE__ */ React.createElement(
1378
+ motion.div,
1379
+ {
1380
+ className: "relative h-full w-full",
1381
+ initial: { opacity: 0 },
1382
+ animate: { opacity: 1 },
1383
+ transition: { duration: 0.5 }
1384
+ },
1385
+ /* @__PURE__ */ React.createElement("div", { className: "absolute inset-0 opacity-[0.02] dark:opacity-[0.05]" }, /* @__PURE__ */ React.createElement("div", { className: "absolute top-1/4 left-1/4 w-32 h-32 bg-gradient-to-br from-blue-400 to-purple-600 rounded-full blur-3xl" }), /* @__PURE__ */ React.createElement("div", { className: "absolute top-3/4 right-1/4 w-24 h-24 bg-gradient-to-br from-pink-400 to-orange-600 rounded-full blur-2xl" })),
1386
+ /* @__PURE__ */ React.createElement("div", { className: "relative z-10 h-full flex flex-col justify-center px-4 md:px-12" }, /* @__PURE__ */ React.createElement(AnimatePresence, { mode: "wait" }, !isAnimating && /* @__PURE__ */ React.createElement(
1387
+ motion.div,
1388
+ {
1389
+ key: quote.text,
1390
+ initial: { opacity: 0, y: 20, scale: 0.95 },
1391
+ animate: { opacity: 1, y: 0, scale: 1 },
1392
+ exit: { opacity: 0, y: -20, scale: 0.95 },
1393
+ transition: {
1394
+ duration: 0.6,
1395
+ ease: [0.4, 0, 0.2, 1]
1396
+ },
1397
+ className: "max-w-4xl"
1398
+ },
1399
+ /* @__PURE__ */ React.createElement(
1400
+ motion.div,
1401
+ {
1402
+ className: "flex items-center gap-3 mb-6",
1403
+ initial: { opacity: 0, x: -20 },
1404
+ animate: { opacity: 1, x: 0 },
1405
+ transition: { delay: 0.2 }
1406
+ },
1407
+ /* @__PURE__ */ React.createElement("div", { className: "relative" }, /* @__PURE__ */ React.createElement(Quote, { className: "h-8 w-8 text-blue-400/60 dark:text-blue-300/40" }), /* @__PURE__ */ React.createElement(
1408
+ motion.div,
1409
+ {
1410
+ className: "absolute -top-1 -right-1 h-3 w-3 bg-gradient-to-r from-blue-400 to-purple-500 rounded-full",
1411
+ animate: { scale: [1, 1.2, 1] },
1412
+ transition: { duration: 2, repeat: Infinity, ease: "easeInOut" }
1413
+ }
1414
+ )),
1415
+ /* @__PURE__ */ React.createElement("div", { className: "h-px flex-1 bg-gradient-to-r from-gray-300 to-transparent dark:from-gray-600" })
1416
+ ),
1417
+ /* @__PURE__ */ React.createElement(
1418
+ motion.blockquote,
1419
+ {
1420
+ className: "text-2xl md:text-4xl lg:text-5xl font-light italic leading-relaxed text-gray-400 dark:text-gray-500 mb-6",
1421
+ initial: { opacity: 0 },
1422
+ animate: { opacity: 1 },
1423
+ transition: { delay: 0.3, duration: 0.8 }
1424
+ },
1425
+ '"',
1426
+ quote.text,
1427
+ '"'
1428
+ ),
1429
+ /* @__PURE__ */ React.createElement(
1430
+ motion.div,
1431
+ {
1432
+ className: "flex items-center gap-3",
1433
+ initial: { opacity: 0, x: 20 },
1434
+ animate: { opacity: 1, x: 0 },
1435
+ transition: { delay: 0.5 }
1436
+ },
1437
+ /* @__PURE__ */ React.createElement("div", { className: "h-px flex-1 bg-gradient-to-l from-gray-300 to-transparent dark:from-gray-600" }),
1438
+ /* @__PURE__ */ React.createElement("cite", { className: "text-lg md:text-xl text-gray-500 dark:text-gray-400 font-medium not-italic" }, quote.author),
1439
+ /* @__PURE__ */ React.createElement(Lightbulb, { className: "h-5 w-5 text-amber-400/60 dark:text-amber-300/40" })
1440
+ ),
1441
+ /* @__PURE__ */ React.createElement(
1442
+ motion.button,
1443
+ {
1444
+ onClick: onRefresh,
1445
+ className: "mt-8 pointer-events-auto text-sm text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 transition-colors duration-200 flex items-center hidden md:flex gap-2 group",
1446
+ whileHover: { scale: 1.05 },
1447
+ whileTap: { scale: 0.95 },
1448
+ initial: { opacity: 0 },
1449
+ animate: { opacity: 1 },
1450
+ transition: { delay: 0.8 }
1451
+ },
1452
+ /* @__PURE__ */ React.createElement(Sparkles, { className: "h-4 w-4 group-hover:animate-spin transition-transform" }),
1453
+ /* @__PURE__ */ React.createElement("span", null, "Click for new inspiration")
1454
+ )
1455
+ )), isAnimating && /* @__PURE__ */ React.createElement(
1456
+ motion.div,
1457
+ {
1458
+ initial: { opacity: 0 },
1459
+ animate: { opacity: 1 },
1460
+ exit: { opacity: 0 },
1461
+ className: "flex items-center justify-center"
1462
+ },
1463
+ /* @__PURE__ */ React.createElement(
1464
+ motion.div,
1465
+ {
1466
+ animate: { rotate: 360 },
1467
+ transition: { duration: 1, repeat: Infinity, ease: "linear" }
1468
+ },
1469
+ /* @__PURE__ */ React.createElement(Sparkles, { className: "h-8 w-8 text-blue-400" })
1470
+ ),
1471
+ /* @__PURE__ */ React.createElement("span", { className: "ml-3 text-xl text-gray-400 italic" }, "Finding inspiration...")
1472
+ ))
1473
+ ));
1474
+ }
1475
+ function Core({
1476
+ toolbarConfig
1477
+ }) {
1478
+ const { historyState } = useSharedHistoryContext();
1479
+ const { quote, isAnimating, loadNewQuote } = useRotatingQuote();
1480
+ const isEditable = useLexicalEditable2();
1481
+ const [floatingAnchorElem, setFloatingAnchorElem] = useState3(null);
1482
+ const [editor] = useLexicalComposerContext6();
1483
+ const [activeEditor, setActiveEditor] = useState3(editor);
1484
+ const [isLinkEditMode, setIsLinkEditMode] = useState3(false);
1485
+ const [hasContent, setHasContent] = useState3(false);
1486
+ const onRef = useCallback2((_floatingAnchorElem) => {
1487
+ if (_floatingAnchorElem !== null) {
1488
+ setFloatingAnchorElem(_floatingAnchorElem);
1489
+ }
1490
+ }, []);
1491
+ useEffect7(() => {
1492
+ const unregister = editor.registerTextContentListener((textContent) => {
1493
+ setHasContent(textContent.trim().length > 0);
1494
+ });
1495
+ return unregister;
1496
+ }, [editor]);
1497
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, isEditable && /* @__PURE__ */ React.createElement(
1498
+ ToolbarPlugin,
1499
+ {
1500
+ editor,
1501
+ activeEditor,
1502
+ setActiveEditor,
1503
+ setIsLinkEditMode,
1504
+ toolbarConfig,
1505
+ className: "fixed z-40 md:top-40"
1506
+ }
1507
+ ), isEditable && /* @__PURE__ */ React.createElement(ContentAnalyticsPlugin, null), /* @__PURE__ */ React.createElement("div", { className: cn(
1508
+ "flex justify-center w-full min-h-screen transition-all duration-300",
1509
+ "dark:md:from-gray-900/50 dark:md:to-gray-800/30",
1510
+ "pt-20 md:pt-10"
1511
+ ) }, /* @__PURE__ */ React.createElement(
1512
+ motion.div,
1513
+ {
1514
+ className: cn(
1515
+ "relative w-full max-w-5xl transition-all duration-500",
1516
+ "prose prose-lg dark:prose-invert lg:prose-xl leading-relaxed",
1517
+ "md:rounded-2xl md:shadow-2xl md:shadow-black/5",
1518
+ "md:dark:shadow-black/20",
1519
+ "bg-white dark:bg-gray-900",
1520
+ "md:border md:border-gray-200/50 dark:md:border-gray-800/50"
1521
+ )
1522
+ },
1523
+ /* @__PURE__ */ React.createElement("div", { className: "absolute inset-0 rounded-2xl overflow-hidden pointer-events-none" }, /* @__PURE__ */ React.createElement("div", { className: "absolute inset-0 bg-gradient-to-br from-blue-50/30 via-transparent to-purple-50/30 dark:from-blue-900/10 dark:to-purple-900/10" }), /* @__PURE__ */ React.createElement("div", { className: "absolute top-0 left-0 w-full h-px bg-gradient-to-r from-transparent via-gray-200 to-transparent dark:via-gray-700" })),
1524
+ /* @__PURE__ */ React.createElement(
1525
+ RichTextPlugin,
1526
+ {
1527
+ contentEditable: /* @__PURE__ */ React.createElement("div", { ref: onRef, className: "relative" }, /* @__PURE__ */ React.createElement(
1528
+ ContentEditable,
1529
+ {
1530
+ id: "lexical-editor",
1531
+ autoFocus: true,
1532
+ className: cn(
1533
+ "editor-content relative z-20 outline-none",
1534
+ "px-4 md:px-12 py-8 md:py-16",
1535
+ "min-h-[80vh] md:min-h-[70vh]",
1536
+ "focus:outline-none focus:ring-0",
1537
+ "text-foreground selection:bg-blue-100 dark:selection:bg-blue-900/30",
1538
+ "font-['Inter',_system-ui,_sans-serif] antialiased",
1539
+ "leading-relaxed tracking-wide",
1540
+ "transition-all duration-200 ease-in-out",
1541
+ "rounded-2xl"
1542
+ )
1543
+ }
1544
+ )),
1545
+ placeholder: !hasContent ? /* @__PURE__ */ React.createElement(
1546
+ EnhancedPlaceholder,
1547
+ {
1548
+ quote,
1549
+ isAnimating,
1550
+ onRefresh: loadNewQuote
1551
+ }
1552
+ ) : null,
1553
+ ErrorBoundary: LexicalErrorBoundary
1554
+ }
1555
+ ),
1556
+ /* @__PURE__ */ React.createElement("div", { className: "absolute inset-0 rounded-2xl ring-0 ring-blue-500/0 transition-all duration-300 pointer-events-none focus-within:ring-2 focus-within:ring-blue-500/20 focus-within:ring-offset-2 focus-within:ring-offset-white dark:focus-within:ring-offset-gray-900" }),
1557
+ /* @__PURE__ */ React.createElement(AutoFocusPlugin, { defaultSelection: "rootStart" }),
1558
+ /* @__PURE__ */ React.createElement(ClearEditorPlugin, null),
1559
+ /* @__PURE__ */ React.createElement(ShortcutsPlugin, { editor: activeEditor, setIsLinkEditMode }),
1560
+ /* @__PURE__ */ React.createElement(LexicalOnChangePlugin, null),
1561
+ /* @__PURE__ */ React.createElement(LinkPlugin, null),
1562
+ /* @__PURE__ */ React.createElement(HorizontalRulePlugin, null),
1563
+ /* @__PURE__ */ React.createElement(TabFocusPlugin, null),
1564
+ /* @__PURE__ */ React.createElement(PollPlugin, null),
1565
+ /* @__PURE__ */ React.createElement(ExcalidrawPlugin, null),
1566
+ /* @__PURE__ */ React.createElement(FigmaPlugin, null),
1567
+ /* @__PURE__ */ React.createElement(EquationsPlugin, null),
1568
+ /* @__PURE__ */ React.createElement(SpeechToTextPlugin_default, null),
1569
+ /* @__PURE__ */ React.createElement(TableCellResizerPlugin, null),
1570
+ /* @__PURE__ */ React.createElement(LayoutPlugin, null),
1571
+ /* @__PURE__ */ React.createElement(CollapsiblePlugin, null),
1572
+ /* @__PURE__ */ React.createElement(CodeHighlightPlugin, null),
1573
+ /* @__PURE__ */ React.createElement(DragDropPaste, null),
1574
+ /* @__PURE__ */ React.createElement(TabIndentationPlugin, { maxIndent: 7 }),
1575
+ /* @__PURE__ */ React.createElement(LexicalAutoLinkPlugin, null),
1576
+ /* @__PURE__ */ React.createElement(LinkWithMetaDataPlugin, null),
1577
+ /* @__PURE__ */ React.createElement(ListPlugin, null),
1578
+ /* @__PURE__ */ React.createElement(LinkPlugin, null),
1579
+ /* @__PURE__ */ React.createElement(StepperPlugin, null),
1580
+ /* @__PURE__ */ React.createElement(TwitterPlugin, null),
1581
+ /* @__PURE__ */ React.createElement(CheckListPlugin, null),
1582
+ /* @__PURE__ */ React.createElement(ImagesPlugin, null),
1583
+ /* @__PURE__ */ React.createElement(InlineImagePlugin, null),
1584
+ /* @__PURE__ */ React.createElement(AutoEmbedPlugin, null),
1585
+ /* @__PURE__ */ React.createElement(HintPlugin, null),
1586
+ /* @__PURE__ */ React.createElement(YouTubePlugin, null),
1587
+ /* @__PURE__ */ React.createElement(StoryBuilderPlugin, null),
1588
+ /* @__PURE__ */ React.createElement(DynamicBlockPlugin, null),
1589
+ /* @__PURE__ */ React.createElement(HistoryPlugin, { externalHistoryState: historyState }),
1590
+ /* @__PURE__ */ React.createElement(ExportPlugin, null),
1591
+ /* @__PURE__ */ React.createElement(TemplatePlugin, null),
1592
+ /* @__PURE__ */ React.createElement(MarkdownShortcutPlugin, null),
1593
+ /* @__PURE__ */ React.createElement(ClickableLinkPlugin, { disabled: isEditable }),
1594
+ /* @__PURE__ */ React.createElement(TablePlugin, { hasCellMerge: true, hasCellBackgroundColor: true, hasHorizontalScroll: true }),
1595
+ floatingAnchorElem && isEditable && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(DraggableBlockPlugin, { anchorElem: floatingAnchorElem }), /* @__PURE__ */ React.createElement(
1596
+ FloatingLinkEditorPlugin,
1597
+ {
1598
+ anchorElem: floatingAnchorElem,
1599
+ isLinkEditMode,
1600
+ setIsLinkEditMode
1601
+ }
1602
+ ), /* @__PURE__ */ React.createElement(FloatingTextFormatToolbarPlugin, { setIsLinkEditMode, anchorElem: floatingAnchorElem }), /* @__PURE__ */ React.createElement(TableCellActionMenuPlugin, { anchorElem: floatingAnchorElem, cellMerge: true }), /* @__PURE__ */ React.createElement(CodeActionMenuPlugin, { anchorElem: floatingAnchorElem }), /* @__PURE__ */ React.createElement(TableHoverActionsPlugin, { anchorElem: floatingAnchorElem })),
1603
+ isEditable && /* @__PURE__ */ React.createElement(SlashCommand, null)
1604
+ )));
1605
+ }
1606
+
1607
+ // src/components/editor/index.tsx
1608
+ function Editor({
1609
+ isEditable = false,
1610
+ content,
1611
+ aiConfig,
1612
+ uploadConfig,
1613
+ toolbarConfig
1614
+ }) {
1615
+ const initialConfig = {
1616
+ namespace: "Bloger editor",
1617
+ theme: editor_theme_default,
1618
+ editorState: typeof content === "string" ? content : void 0,
1619
+ // typeof content === "string" ? content : JSON.stringify(content),
1620
+ nodes: [...nodes_default],
1621
+ onError: (error) => {
1622
+ throw error;
1623
+ },
1624
+ editable: isEditable
1625
+ };
1626
+ console.log("Editor content:", content);
1627
+ return /* @__PURE__ */ React3.createElement(LexicalComposer, { initialConfig }, /* @__PURE__ */ React3.createElement(AIProvider, { config: aiConfig }, /* @__PURE__ */ React3.createElement(UploadProvider, { config: uploadConfig }, /* @__PURE__ */ React3.createElement(SharedHistoryContext, null, /* @__PURE__ */ React3.createElement(ToolbarContext, null, /* @__PURE__ */ React3.createElement(Core, { toolbarConfig }))))));
1628
+ }
1629
+
1630
+ // src/styles/tailwind-plugin.ts
1631
+ init_react_shim();
1632
+
1633
+ // node_modules/.pnpm/tailwindcss@4.1.13/node_modules/tailwindcss/dist/plugin.mjs
1634
+ init_react_shim();
1635
+ function g(i, n) {
1636
+ return { handler: i, config: n };
1637
+ }
1638
+ g.withOptions = function(i, n = () => ({})) {
1639
+ function t(o) {
1640
+ return { handler: i(o), config: n(o) };
1641
+ }
1642
+ return t.__isOptionsFunction = true, t;
1643
+ };
1644
+ var u = g;
1645
+
1646
+ // src/styles/tailwind-plugin.ts
1647
+ var notiqPlugin = u(function({ addBase, theme: theme2 }) {
1648
+ addBase({
1649
+ ":root": {
1650
+ "--background": "oklch(1 0 0)",
1651
+ "--foreground": "oklch(0.145 0 0)",
1652
+ "--card": "oklch(1 0 0)",
1653
+ "--card-foreground": "oklch(0.145 0 0)",
1654
+ "--popover": "oklch(1 0 0)",
1655
+ "--popover-foreground": "oklch(0.145 0 0)",
1656
+ "--primary": "oklch(0.205 0 0)",
1657
+ "--primary-foreground": "oklch(0.985 0 0)",
1658
+ "--secondary": "oklch(0.97 0 0)",
1659
+ "--secondary-foreground": "oklch(0.205 0 0)",
1660
+ "--muted": "oklch(0.97 0 0)",
1661
+ "--muted-foreground": "oklch(0.556 0 0)",
1662
+ "--accent": "oklch(0.97 0 0)",
1663
+ "--accent-foreground": "oklch(0.205 0 0)",
1664
+ "--destructive": "oklch(0.577 0.245 27.325)",
1665
+ "--destructive-foreground": "oklch(0.577 0.245 27.325)",
1666
+ "--border": "oklch(0.922 0 0)",
1667
+ "--input": "oklch(0.922 0 0)",
1668
+ "--ring": "oklch(0.708 0 0)",
1669
+ "--radius": "0.625rem",
1670
+ "--font-gray": "#9b9a97",
1671
+ "--font-brown": "#64473a",
1672
+ "--font-orange": "#d9730d",
1673
+ "--font-yellow": "#dfab01",
1674
+ "--font-green": "#0f7b6c",
1675
+ "--font-blue": "#0b6e99",
1676
+ "--font-purple": "#6940a5",
1677
+ "--font-pink": "#ad1a72",
1678
+ "--font-red": "#e03e3e",
1679
+ "--background-gray": "#ebeced",
1680
+ "--background-brown": "#e9e5e3",
1681
+ "--background-orange": "#faebdd",
1682
+ "--background-yellow": "#fbf3db",
1683
+ "--background-green": "#ddedea",
1684
+ "--background-blue": "#ddedea",
1685
+ "--background-purple": "#eae4f2",
1686
+ "--background-pink": "#f4dfeb",
1687
+ "--background-red": "#fbe4e4"
1688
+ },
1689
+ ".dark": {
1690
+ "--background": "oklch(0.145 0 0)",
1691
+ "--foreground": "oklch(0.985 0 0)",
1692
+ "--card": "oklch(0.145 0 0)",
1693
+ "--card-foreground": "oklch(0.985 0 0)",
1694
+ "--popover": "oklch(0.145 0 0)",
1695
+ "--popover-foreground": "oklch(0.985 0 0)",
1696
+ "--primary": "oklch(0.985 0 0)",
1697
+ "--primary-foreground": "oklch(0.205 0 0)",
1698
+ "--secondary": "oklch(0.269 0 0)",
1699
+ "--secondary-foreground": "oklch(0.985 0 0)",
1700
+ "--muted": "oklch(0.269 0 0)",
1701
+ "--muted-foreground": "oklch(0.708 0 0)",
1702
+ "--accent": "oklch(0.269 0 0)",
1703
+ "--accent-foreground:": "oklch(0.985 0 0)",
1704
+ "--destructive": "oklch(0.396 0.141 25.723)",
1705
+ "--destructive-foreground": "oklch(0.637 0.237 25.331)",
1706
+ "--border": "oklch(0.269 0 0)",
1707
+ "--input": "oklch(0.269 0 0)",
1708
+ "--ring": "oklch(0.439 0 0)",
1709
+ "--font-gray": "#9b9a97",
1710
+ "--font-brown": "#937264",
1711
+ "--font-orange": "#ffa344",
1712
+ "--font-yellow": "#ffdc49",
1713
+ "--font-green": "#4dab9a",
1714
+ "--font-blue": "#529cca",
1715
+ "--font-purple": "#9a6dd7",
1716
+ "--font-pink": "#e255a1",
1717
+ "--font-red": "#ff7369",
1718
+ "--background-gray": "#454b4e",
1719
+ "--background-brown": "#434040",
1720
+ "--background-orange": "#594a3a",
1721
+ "--background-yellow": "#59563b",
1722
+ "--background-green": "#354c4b",
1723
+ "--background-blue": "#364954",
1724
+ "--background-purple": "#443f57",
1725
+ "--background-pink": "#533b4c",
1726
+ "--background-red": "#594141"
1727
+ }
1728
+ });
1729
+ }, {
1730
+ theme: {
1731
+ extend: {
1732
+ colors: {
1733
+ background: "var(--background)",
1734
+ foreground: "var(--foreground)",
1735
+ primary: {
1736
+ DEFAULT: "var(--primary)",
1737
+ foreground: "var(--primary-foreground)"
1738
+ },
1739
+ secondary: {
1740
+ DEFAULT: "var(--secondary)",
1741
+ foreground: "var(--secondary-foreground)"
1742
+ },
1743
+ muted: {
1744
+ DEFAULT: "var(--muted)",
1745
+ foreground: "var(--muted-foreground)"
1746
+ },
1747
+ accent: {
1748
+ DEFAULT: "var(--accent)",
1749
+ foreground: "var(--accent-foreground)"
1750
+ },
1751
+ destructive: {
1752
+ DEFAULT: "var(--destructive)",
1753
+ foreground: "var(--destructive-foreground)"
1754
+ },
1755
+ border: "var(--border)",
1756
+ input: "var(--input)",
1757
+ ring: "var(--ring)",
1758
+ card: {
1759
+ DEFAULT: "var(--card)",
1760
+ foreground: "var(--card-foreground)"
1761
+ },
1762
+ popover: {
1763
+ DEFAULT: "var(--popover)",
1764
+ foreground: "var(--popover-foreground)"
1765
+ }
1766
+ },
1767
+ borderRadius: {
1768
+ lg: "var(--radius)",
1769
+ md: "calc(var(--radius) - 2px)",
1770
+ sm: "calc(var(--radius) - 4px)"
1771
+ }
1772
+ }
1773
+ }
1774
+ });
1775
+ export {
1776
+ AIProvider,
1777
+ DEFAULT_FONT_SIZE,
1778
+ Editor,
1779
+ MAX_ALLOWED_FONT_SIZE,
1780
+ MIN_ALLOWED_FONT_SIZE,
1781
+ SharedHistoryContext,
1782
+ ToolbarContext,
1783
+ UploadProvider,
1784
+ blockTypeToBlockName,
1785
+ notiqPlugin,
1786
+ useAI,
1787
+ useSharedHistoryContext,
1788
+ useToolbarState,
1789
+ useUpload
1790
+ };