@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
@@ -0,0 +1,1906 @@
1
+ import {
2
+ Toggle
3
+ } from "./chunk-Z4EWP7BI.mjs";
4
+ import {
5
+ getSelectedNode
6
+ } from "./chunk-4HBCVSE6.mjs";
7
+ import {
8
+ BlockFormatDropDown
9
+ } from "./chunk-K36V4SIW.mjs";
10
+ import {
11
+ Color
12
+ } from "./chunk-YMBXLRW5.mjs";
13
+ import {
14
+ TextFormat
15
+ } from "./chunk-456TN7IM.mjs";
16
+ import {
17
+ Font
18
+ } from "./chunk-7VUMHWWL.mjs";
19
+ import {
20
+ Command,
21
+ CommandEmpty,
22
+ CommandGroup,
23
+ CommandInput,
24
+ CommandItem,
25
+ CommandList,
26
+ CommandSeparator
27
+ } from "./chunk-KJ6AJ44Q.mjs";
28
+ import {
29
+ Popover,
30
+ PopoverContent,
31
+ PopoverTrigger
32
+ } from "./chunk-64Z3FI7T.mjs";
33
+ import {
34
+ FontSize
35
+ } from "./chunk-2FNEAMSP.mjs";
36
+ import {
37
+ useAI
38
+ } from "./chunk-YUDCJRJM.mjs";
39
+ import {
40
+ $createStepperNode
41
+ } from "./chunk-6RNZQOH2.mjs";
42
+ import {
43
+ CollapsibleContainerNode,
44
+ CollapsibleTitleNode
45
+ } from "./chunk-GXYD4VZM.mjs";
46
+ import {
47
+ SHORTCUTS
48
+ } from "./chunk-ZB5LZQKC.mjs";
49
+ import {
50
+ Separator
51
+ } from "./chunk-TCYK7DM7.mjs";
52
+ import {
53
+ sanitizeUrl
54
+ } from "./chunk-4VWFVWYP.mjs";
55
+ import {
56
+ cn
57
+ } from "./chunk-YHPNOWFH.mjs";
58
+ import {
59
+ React,
60
+ __objRest,
61
+ __spreadProps,
62
+ __spreadValues,
63
+ init_react_shim
64
+ } from "./chunk-77KXU36M.mjs";
65
+
66
+ // src/components/editor/plugins/FloatingTextFormatToolbarPlugin/index.tsx
67
+ init_react_shim();
68
+ import { $isCodeHighlightNode } from "@lexical/code";
69
+ import { $isLinkNode } from "@lexical/link";
70
+ import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
71
+ import {
72
+ $findMatchingParent,
73
+ $getNearestNodeOfType,
74
+ mergeRegister as mergeRegister2
75
+ } from "@lexical/utils";
76
+ import {
77
+ $getSelection as $getSelection3,
78
+ $isParagraphNode,
79
+ $isRangeSelection as $isRangeSelection2,
80
+ $isRootOrShadowRoot,
81
+ $isTextNode as $isTextNode2,
82
+ getDOMSelection as getDOMSelection2
83
+ } from "lexical";
84
+ import { useCallback as useCallback3, useEffect as useEffect5, useState as useState5 } from "react";
85
+ import * as React6 from "react";
86
+ import { createPortal } from "react-dom";
87
+ import {
88
+ $getSelectionStyleValueForProperty
89
+ } from "@lexical/selection";
90
+ import { useRef as useRef4 } from "react";
91
+ import { $isTableNode } from "@lexical/table";
92
+ import { $isListNode, ListNode as ListNode2 } from "@lexical/list";
93
+ import { $isHeadingNode } from "@lexical/rich-text";
94
+
95
+ // src/components/ui/write/text-format-floting-toolbar.tsx
96
+ init_react_shim();
97
+ import {
98
+ $getSelection as $getSelection2,
99
+ COMMAND_PRIORITY_LOW,
100
+ FORMAT_TEXT_COMMAND,
101
+ getDOMSelection,
102
+ SELECTION_CHANGE_COMMAND
103
+ } from "lexical";
104
+ import { useCallback as useCallback2, useEffect as useEffect4, useRef as useRef3 } from "react";
105
+ import { TOGGLE_LINK_COMMAND } from "@lexical/link";
106
+
107
+ // src/components/editor/utils/getDOMRangeRect.ts
108
+ init_react_shim();
109
+ function getDOMRangeRect(nativeSelection, rootElement) {
110
+ const domRange = nativeSelection.getRangeAt(0);
111
+ let rect;
112
+ if (nativeSelection.anchorNode === rootElement) {
113
+ let inner = rootElement;
114
+ while (inner.firstElementChild != null) {
115
+ inner = inner.firstElementChild;
116
+ }
117
+ rect = inner.getBoundingClientRect();
118
+ } else {
119
+ rect = domRange.getBoundingClientRect();
120
+ }
121
+ return rect;
122
+ }
123
+
124
+ // src/components/editor/utils/setFloatingElemPosition.ts
125
+ init_react_shim();
126
+ var VERTICAL_GAP = 10;
127
+ var HORIZONTAL_OFFSET = 5;
128
+ function isKeyboardOpen() {
129
+ if (typeof window === "undefined") return false;
130
+ const isMobile = window.innerWidth < 768;
131
+ if (!isMobile) return false;
132
+ const activeElement = document.activeElement;
133
+ const isInputFocused = activeElement && (activeElement.tagName === "INPUT" || activeElement.tagName === "TEXTAREA" || activeElement instanceof HTMLElement && activeElement.contentEditable === "true" || activeElement.getAttribute("contenteditable") === "true");
134
+ return !!isInputFocused;
135
+ }
136
+ function getKeyboardHeight() {
137
+ if (typeof window === "undefined") return 0;
138
+ const isMobile = window.innerWidth < 768;
139
+ if (!isMobile) return 0;
140
+ return 280;
141
+ }
142
+ function setFloatingElemPosition(targetRect, floatingElem, anchorElem, verticalGap = VERTICAL_GAP, horizontalOffset = HORIZONTAL_OFFSET) {
143
+ const scrollerElem = anchorElem.parentElement;
144
+ if (targetRect === null || !scrollerElem) {
145
+ floatingElem.style.opacity = "0";
146
+ floatingElem.style.transform = "translate(-10000px, -10000px)";
147
+ return;
148
+ }
149
+ const floatingElemRect = floatingElem.getBoundingClientRect();
150
+ const anchorElementRect = anchorElem.getBoundingClientRect();
151
+ const editorScrollerRect = scrollerElem.getBoundingClientRect();
152
+ const isMobile = window.innerWidth < 768;
153
+ const keyboardOpen = isKeyboardOpen();
154
+ const keyboardHeight = keyboardOpen ? getKeyboardHeight() : 0;
155
+ let top = targetRect.bottom + verticalGap;
156
+ let left = targetRect.left + horizontalOffset;
157
+ if (isMobile && keyboardOpen) {
158
+ const viewportHeight = window.innerHeight;
159
+ const toolbarHeight = floatingElemRect.height;
160
+ const keyboardTop = viewportHeight - keyboardHeight;
161
+ top = keyboardTop - toolbarHeight - 20;
162
+ left = (window.innerWidth - floatingElemRect.width) / 2;
163
+ top -= anchorElementRect.top;
164
+ left -= anchorElementRect.left;
165
+ } else {
166
+ if (top + floatingElemRect.height > editorScrollerRect.bottom) {
167
+ top = targetRect.top - floatingElemRect.height - verticalGap;
168
+ }
169
+ if (left + floatingElemRect.width > editorScrollerRect.right) {
170
+ left = editorScrollerRect.right - floatingElemRect.width - horizontalOffset;
171
+ }
172
+ if (left < editorScrollerRect.left) {
173
+ left = editorScrollerRect.left + horizontalOffset;
174
+ }
175
+ top -= anchorElementRect.top;
176
+ left -= anchorElementRect.left;
177
+ }
178
+ floatingElem.style.transition = "transform 0.2s ease-in-out, opacity 0.2s ease-in-out";
179
+ floatingElem.style.opacity = "1";
180
+ floatingElem.style.transform = `translate(${left}px, ${top}px)`;
181
+ }
182
+
183
+ // src/components/ui/write/text-format-floting-toolbar.tsx
184
+ import { mergeRegister } from "@lexical/utils";
185
+
186
+ // src/hooks/use-mobile.ts
187
+ init_react_shim();
188
+ import * as React2 from "react";
189
+ var MOBILE_BREAKPOINT = 768;
190
+ function useIsMobile() {
191
+ const [isMobile, setIsMobile] = React2.useState(void 0);
192
+ React2.useEffect(() => {
193
+ const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
194
+ const onChange = () => {
195
+ setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
196
+ };
197
+ mql.addEventListener("change", onChange);
198
+ setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
199
+ return () => mql.removeEventListener("change", onChange);
200
+ }, []);
201
+ return !!isMobile;
202
+ }
203
+
204
+ // src/components/ui/write/text-format-floting-toolbar.tsx
205
+ import { Bold, Code, Italic, Link, UnderlineIcon } from "lucide-react";
206
+
207
+ // src/components/ui/ai/ai-button.tsx
208
+ init_react_shim();
209
+ import { Loader2, RotateCcw, StarsIcon, WandSparkles } from "lucide-react";
210
+ import React5, { useMemo, useState as useState4 } from "react";
211
+
212
+ // src/components/ui/hover-card.tsx
213
+ init_react_shim();
214
+ import * as React3 from "react";
215
+ import * as HoverCardPrimitive from "@radix-ui/react-hover-card";
216
+ var HoverCard = HoverCardPrimitive.Root;
217
+ var HoverCardTrigger = HoverCardPrimitive.Trigger;
218
+ var HoverCardContent = React3.forwardRef((_a, ref) => {
219
+ var _b = _a, { className, align = "center", sideOffset = 4 } = _b, props = __objRest(_b, ["className", "align", "sideOffset"]);
220
+ return /* @__PURE__ */ React3.createElement(
221
+ HoverCardPrimitive.Content,
222
+ __spreadValues({
223
+ ref,
224
+ align,
225
+ sideOffset,
226
+ className: cn(
227
+ "z-50 w-64 rounded-md border bg-popover p-4 text-popover-foreground shadow-md outline-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
228
+ className
229
+ )
230
+ }, props)
231
+ );
232
+ });
233
+ HoverCardContent.displayName = HoverCardPrimitive.Content.displayName;
234
+
235
+ // src/components/ui/ai/border.tsx
236
+ init_react_shim();
237
+ import React4, { useState as useState2, useEffect as useEffect2 } from "react";
238
+ import { motion } from "framer-motion";
239
+ function HoverBorderGradient(_a) {
240
+ var _b = _a, {
241
+ children,
242
+ containerClassName,
243
+ className,
244
+ as: Tag = "button",
245
+ duration = 1,
246
+ clockwise = true
247
+ } = _b, props = __objRest(_b, [
248
+ "children",
249
+ "containerClassName",
250
+ "className",
251
+ "as",
252
+ "duration",
253
+ "clockwise"
254
+ ]);
255
+ const [hovered, setHovered] = useState2(false);
256
+ const [direction, setDirection] = useState2("TOP");
257
+ const rotateDirection = (currentDirection) => {
258
+ const directions = ["TOP", "LEFT", "BOTTOM", "RIGHT"];
259
+ const currentIndex = directions.indexOf(currentDirection);
260
+ const nextIndex = clockwise ? (currentIndex - 1 + directions.length) % directions.length : (currentIndex + 1) % directions.length;
261
+ return directions[nextIndex];
262
+ };
263
+ const movingMap = {
264
+ TOP: "radial-gradient(20.7% 50% at 50% 0%, hsl(0, 0%, 100%) 0%, rgba(255, 255, 255, 0) 100%)",
265
+ LEFT: "radial-gradient(16.6% 43.1% at 0% 50%, hsl(0, 0%, 100%) 0%, rgba(255, 255, 255, 0) 100%)",
266
+ BOTTOM: "radial-gradient(20.7% 50% at 50% 100%, hsl(0, 0%, 100%) 0%, rgba(255, 255, 255, 0) 100%)",
267
+ RIGHT: "radial-gradient(16.2% 41.199999999999996% at 100% 50%, hsl(0, 0%, 100%) 0%, rgba(255, 255, 255, 0) 100%)"
268
+ };
269
+ const highlight = "radial-gradient(75% 181.15942028985506% at 50% 50%, #3275F8 0%, rgba(255, 255, 255, 0) 100%)";
270
+ useEffect2(() => {
271
+ if (!hovered) {
272
+ const interval = setInterval(() => {
273
+ setDirection((prevState) => rotateDirection(prevState));
274
+ }, duration * 1e3);
275
+ return () => clearInterval(interval);
276
+ }
277
+ }, [hovered]);
278
+ return /* @__PURE__ */ React4.createElement(
279
+ Tag,
280
+ __spreadValues({
281
+ onMouseEnter: (event) => {
282
+ setHovered(true);
283
+ },
284
+ onMouseLeave: () => setHovered(false),
285
+ className: cn(
286
+ "relative flex rounded-full border content-center bg-black/20 hover:bg-black/10 transition duration-500 dark:bg-white/20 items-center flex-col flex-nowrap justify-center overflow-visible p-px decoration-clone w-fit",
287
+ containerClassName
288
+ )
289
+ }, props),
290
+ /* @__PURE__ */ React4.createElement(
291
+ "div",
292
+ {
293
+ className: cn(
294
+ "w-auto text-white z-10 bg-black rounded-[inherit]",
295
+ className
296
+ )
297
+ },
298
+ children
299
+ ),
300
+ /* @__PURE__ */ React4.createElement(
301
+ motion.div,
302
+ {
303
+ className: cn(
304
+ "flex-none inset-0 overflow-hidden absolute z-0 rounded-[inherit]"
305
+ ),
306
+ style: {
307
+ filter: "blur(2px)",
308
+ position: "absolute",
309
+ width: "100%",
310
+ height: "100%"
311
+ },
312
+ initial: { background: movingMap[direction] },
313
+ animate: {
314
+ background: hovered ? [movingMap[direction], highlight] : movingMap[direction]
315
+ },
316
+ transition: { ease: "linear", duration: duration != null ? duration : 1 }
317
+ }
318
+ ),
319
+ /* @__PURE__ */ React4.createElement("div", { className: "bg-black absolute z-1 flex-none inset-[2px] rounded-[100px]" })
320
+ );
321
+ }
322
+
323
+ // src/components/ui/ai/placeholder-input-vanish.tsx
324
+ init_react_shim();
325
+ import { AnimatePresence, motion as motion2 } from "framer-motion";
326
+ import { useCallback, useEffect as useEffect3, useRef as useRef2, useState as useState3 } from "react";
327
+ function PlaceholdersAndVanishInput({
328
+ placeholders: placeholders2,
329
+ onChange,
330
+ onSubmit,
331
+ disabled
332
+ }) {
333
+ const [currentPlaceholder, setCurrentPlaceholder] = useState3(0);
334
+ const intervalRef = useRef2(null);
335
+ const startAnimation = () => {
336
+ intervalRef.current = setInterval(() => {
337
+ setCurrentPlaceholder((prev) => (prev + 1) % placeholders2.length);
338
+ }, 3e3);
339
+ };
340
+ const handleVisibilityChange = () => {
341
+ if (document.visibilityState !== "visible" && intervalRef.current) {
342
+ clearInterval(intervalRef.current);
343
+ intervalRef.current = null;
344
+ } else if (document.visibilityState === "visible") {
345
+ startAnimation();
346
+ }
347
+ };
348
+ useEffect3(() => {
349
+ startAnimation();
350
+ document.addEventListener("visibilitychange", handleVisibilityChange);
351
+ return () => {
352
+ if (intervalRef.current) {
353
+ clearInterval(intervalRef.current);
354
+ }
355
+ document.removeEventListener("visibilitychange", handleVisibilityChange);
356
+ };
357
+ }, [placeholders2]);
358
+ const canvasRef = useRef2(null);
359
+ const newDataRef = useRef2([]);
360
+ const inputRef = useRef2(null);
361
+ const [value, setValue] = useState3("");
362
+ const [animating, setAnimating] = useState3(false);
363
+ const draw = useCallback(() => {
364
+ if (!inputRef.current) return;
365
+ const canvas = canvasRef.current;
366
+ if (!canvas) return;
367
+ const ctx = canvas.getContext("2d");
368
+ if (!ctx) return;
369
+ canvas.width = 800;
370
+ canvas.height = 800;
371
+ ctx.clearRect(0, 0, 800, 800);
372
+ const computedStyles = getComputedStyle(inputRef.current);
373
+ const fontSize = parseFloat(computedStyles.getPropertyValue("font-size"));
374
+ ctx.font = `${fontSize * 2}px ${computedStyles.fontFamily}`;
375
+ ctx.fillStyle = "#FFF";
376
+ ctx.fillText(value, 16, 40);
377
+ const imageData = ctx.getImageData(0, 0, 800, 800);
378
+ const pixelData = imageData.data;
379
+ const newData = [];
380
+ for (let t = 0; t < 800; t++) {
381
+ let i = 4 * t * 800;
382
+ for (let n = 0; n < 800; n++) {
383
+ let e = i + 4 * n;
384
+ if (pixelData[e] !== 0 && pixelData[e + 1] !== 0 && pixelData[e + 2] !== 0) {
385
+ newData.push({
386
+ x: n,
387
+ y: t,
388
+ color: [
389
+ pixelData[e],
390
+ pixelData[e + 1],
391
+ pixelData[e + 2],
392
+ pixelData[e + 3]
393
+ ]
394
+ });
395
+ }
396
+ }
397
+ }
398
+ newDataRef.current = newData.map(({ x, y, color }) => ({
399
+ x,
400
+ y,
401
+ r: 1,
402
+ color: `rgba(${color[0]}, ${color[1]}, ${color[2]}, ${color[3]})`
403
+ }));
404
+ }, [value]);
405
+ useEffect3(() => {
406
+ draw();
407
+ }, [value, draw]);
408
+ const animate = (start) => {
409
+ const animateFrame = (pos = 0) => {
410
+ requestAnimationFrame(() => {
411
+ var _a;
412
+ const newArr = [];
413
+ for (let i = 0; i < newDataRef.current.length; i++) {
414
+ const current = newDataRef.current[i];
415
+ if (current.x < pos) {
416
+ newArr.push(current);
417
+ } else {
418
+ if (current.r <= 0) {
419
+ current.r = 0;
420
+ continue;
421
+ }
422
+ current.x += Math.random() > 0.5 ? 1 : -1;
423
+ current.y += Math.random() > 0.5 ? 1 : -1;
424
+ current.r -= 0.05 * Math.random();
425
+ newArr.push(current);
426
+ }
427
+ }
428
+ newDataRef.current = newArr;
429
+ const ctx = (_a = canvasRef.current) == null ? void 0 : _a.getContext("2d");
430
+ if (ctx) {
431
+ ctx.clearRect(pos, 0, 800, 800);
432
+ newDataRef.current.forEach((t) => {
433
+ const { x: n, y: i, r: s, color } = t;
434
+ if (n > pos) {
435
+ ctx.beginPath();
436
+ ctx.rect(n, i, s, s);
437
+ ctx.fillStyle = color;
438
+ ctx.strokeStyle = color;
439
+ ctx.stroke();
440
+ }
441
+ });
442
+ }
443
+ if (newDataRef.current.length > 0) {
444
+ animateFrame(pos - 8);
445
+ } else {
446
+ setValue("");
447
+ setAnimating(false);
448
+ }
449
+ });
450
+ };
451
+ animateFrame(start);
452
+ };
453
+ const handleKeyDown = (e) => {
454
+ if (e.key === "Enter" && !animating) {
455
+ vanishAndSubmit();
456
+ }
457
+ };
458
+ const vanishAndSubmit = () => {
459
+ var _a;
460
+ setAnimating(true);
461
+ draw();
462
+ const value2 = ((_a = inputRef.current) == null ? void 0 : _a.value) || "";
463
+ if (value2 && inputRef.current) {
464
+ const maxX = newDataRef.current.reduce(
465
+ (prev, current) => current.x > prev ? current.x : prev,
466
+ 0
467
+ );
468
+ animate(maxX);
469
+ }
470
+ };
471
+ const handleSubmit = (e) => {
472
+ e.preventDefault();
473
+ vanishAndSubmit();
474
+ onSubmit && onSubmit(e);
475
+ };
476
+ return /* @__PURE__ */ React.createElement(
477
+ "form",
478
+ {
479
+ suppressHydrationWarning: true,
480
+ className: cn(
481
+ "w-full relative max-w-xl mx-auto h-9 rounded-sm overflow-hidden shadow-[0px_2px_3px_-1px_rgba(0,0,0,0.1),_0px_1px_0px_0px_rgba(25,28,33,0.02),_0px_0px_0px_1px_rgba(25,28,33,0.08)] transition duration-200"
482
+ ),
483
+ onSubmit: handleSubmit
484
+ },
485
+ /* @__PURE__ */ React.createElement(
486
+ "canvas",
487
+ {
488
+ className: cn(
489
+ "absolute pointer-events-none text-base transform scale-50 top-[20%] left-2 sm:left-8 origin-top-left filter invert dark:invert-0 pr-20",
490
+ !animating ? "opacity-0" : "opacity-100"
491
+ ),
492
+ ref: canvasRef
493
+ }
494
+ ),
495
+ /* @__PURE__ */ React.createElement(
496
+ "input",
497
+ {
498
+ disabled,
499
+ onChange: (e) => {
500
+ if (!animating) {
501
+ setValue(e.target.value);
502
+ onChange && onChange(e);
503
+ }
504
+ },
505
+ onKeyDown: handleKeyDown,
506
+ ref: inputRef,
507
+ value,
508
+ type: "text",
509
+ className: cn(
510
+ "w-full relative text-sm sm:text-base z-50 border-none dark:text-white bg-transparent text-black h-full focus:outline-none focus:ring-0 pl-4 sm:pl-10 pr-20",
511
+ animating && "text-transparent dark:text-transparent"
512
+ )
513
+ }
514
+ ),
515
+ /* @__PURE__ */ React.createElement(
516
+ "button",
517
+ {
518
+ disabled: !value || disabled,
519
+ type: "submit",
520
+ className: "absolute right-2 top-1/2 z-50 -translate-y-1/2 h-5 w-5 rounded-full disabled:bg-gray-100 bg-black dark:bg-zinc-900 dark:disabled:bg-zinc-800 transition duration-200 flex items-center justify-center"
521
+ },
522
+ /* @__PURE__ */ React.createElement(
523
+ motion2.svg,
524
+ {
525
+ xmlns: "http://www.w3.org/2000/svg",
526
+ width: "24",
527
+ height: "24",
528
+ viewBox: "0 0 24 24",
529
+ fill: "none",
530
+ stroke: "currentColor",
531
+ strokeWidth: "2",
532
+ strokeLinecap: "round",
533
+ strokeLinejoin: "round",
534
+ className: "text-gray-300 h-4 w-4"
535
+ },
536
+ /* @__PURE__ */ React.createElement("path", { stroke: "none", d: "M0 0h24v24H0z", fill: "none" }),
537
+ /* @__PURE__ */ React.createElement(
538
+ motion2.path,
539
+ {
540
+ d: "M5 12l14 0",
541
+ initial: {
542
+ strokeDasharray: "50%",
543
+ strokeDashoffset: "50%"
544
+ },
545
+ animate: {
546
+ strokeDashoffset: value ? 0 : "50%"
547
+ },
548
+ transition: {
549
+ duration: 0.3,
550
+ ease: "linear"
551
+ }
552
+ }
553
+ ),
554
+ /* @__PURE__ */ React.createElement("path", { d: "M13 18l6 -6" }),
555
+ /* @__PURE__ */ React.createElement("path", { d: "M13 6l6 6" })
556
+ )
557
+ ),
558
+ /* @__PURE__ */ React.createElement("div", { className: "absolute inset-0 flex items-center rounded-full pointer-events-none" }, /* @__PURE__ */ React.createElement(AnimatePresence, { mode: "wait" }, !value && /* @__PURE__ */ React.createElement(
559
+ motion2.p,
560
+ {
561
+ initial: {
562
+ y: 5,
563
+ opacity: 0
564
+ },
565
+ key: `current-placeholder-${currentPlaceholder}`,
566
+ animate: {
567
+ y: 0,
568
+ opacity: 1
569
+ },
570
+ exit: {
571
+ y: -15,
572
+ opacity: 0
573
+ },
574
+ transition: {
575
+ duration: 0.3,
576
+ ease: "linear"
577
+ },
578
+ className: "dark:text-zinc-500 text-sm sm:text-base font-normal text-neutral-500 pl-4 sm:pl-12 text-left w-[calc(100%-2rem)] truncate"
579
+ },
580
+ placeholders2[currentPlaceholder]
581
+ )))
582
+ );
583
+ }
584
+
585
+ // src/components/ui/ai/ai-button.tsx
586
+ import { motion as motion3 } from "framer-motion";
587
+
588
+ // src/components/editor/utils/ai.ts
589
+ init_react_shim();
590
+ import { $createCodeNode } from "@lexical/code";
591
+ import {
592
+ $createParagraphNode,
593
+ $createRangeSelection,
594
+ $createTextNode,
595
+ $getRoot,
596
+ $getSelection,
597
+ $isRangeSelection,
598
+ $isTextNode,
599
+ createEditor
600
+ } from "lexical";
601
+ import {
602
+ $createHeadingNode
603
+ } from "@lexical/rich-text";
604
+ function getWordsBeforeSelection(editor, numWords) {
605
+ let wordsBeforeSelection = "";
606
+ editor.update(() => {
607
+ const selection = $getSelection();
608
+ if (!$isRangeSelection(selection)) {
609
+ console.warn("No valid text selection found.");
610
+ return;
611
+ }
612
+ const anchor = selection.anchor;
613
+ const firstTextNode = findFirstTextNode($getRoot());
614
+ if (!firstTextNode) {
615
+ console.warn("No text nodes found in the document.");
616
+ return;
617
+ }
618
+ const range = $createRangeSelection();
619
+ range.anchor.set(firstTextNode.__key, 0, "text");
620
+ range.focus.set(anchor.key, anchor.offset, anchor.type);
621
+ const textContent = range.getTextContent();
622
+ const words = textContent.split(/\s+/).filter((word) => word.length > 0);
623
+ const startIndex = Math.max(0, words.length - numWords);
624
+ wordsBeforeSelection = words.slice(startIndex, words.length).join(" ");
625
+ });
626
+ return wordsBeforeSelection;
627
+ }
628
+ function findFirstTextNode(node) {
629
+ if ($isTextNode(node)) {
630
+ return node;
631
+ }
632
+ const children = node.getChildren();
633
+ for (const child of children) {
634
+ const result = findFirstTextNode(child);
635
+ if (result) {
636
+ return result;
637
+ }
638
+ }
639
+ return null;
640
+ }
641
+ function isJSON(text) {
642
+ try {
643
+ JSON.parse(text);
644
+ return true;
645
+ } catch (err) {
646
+ return false;
647
+ }
648
+ }
649
+ function createEditorWithText(text) {
650
+ const editor = createEditor();
651
+ const editorState = editor.parseEditorState(
652
+ JSON.stringify({
653
+ root: {
654
+ children: [
655
+ {
656
+ children: [
657
+ {
658
+ detail: 0,
659
+ format: 0,
660
+ mode: "normal",
661
+ style: "",
662
+ text,
663
+ type: "text",
664
+ version: 1
665
+ }
666
+ ],
667
+ direction: null,
668
+ format: "",
669
+ indent: 0,
670
+ type: "paragraph",
671
+ version: 1,
672
+ textFormat: 0,
673
+ textStyle: ""
674
+ }
675
+ ],
676
+ direction: null,
677
+ format: "",
678
+ indent: 0,
679
+ type: "root",
680
+ version: 1
681
+ }
682
+ })
683
+ );
684
+ editor.setEditorState(editorState);
685
+ return editor;
686
+ }
687
+ function GenerateSteps(json, editor) {
688
+ const stepsData = JSON.parse(json);
689
+ const steps = stepsData.map((step) => {
690
+ return {
691
+ id: step.id,
692
+ title: step.title,
693
+ content: createEditorWithText(step.content)
694
+ };
695
+ });
696
+ editor.update(() => {
697
+ const selection = $getSelection();
698
+ if ($isRangeSelection(selection)) {
699
+ const stepperNode = $createStepperNode(steps);
700
+ selection.insertNodes([stepperNode]);
701
+ }
702
+ return;
703
+ });
704
+ }
705
+ var getSelectedText = (editor, getMore) => {
706
+ let selectedText = "";
707
+ let context = getMore ? getWordsBeforeSelection(editor, getMore) : null;
708
+ editor.update(() => {
709
+ const selection = $getSelection();
710
+ if ($isRangeSelection(selection)) {
711
+ const selectionText = selection.getTextContent();
712
+ if (selectionText.length > 30) {
713
+ selectedText = selectionText;
714
+ } else {
715
+ selectedText = context + selectionText;
716
+ }
717
+ }
718
+ });
719
+ return selectedText;
720
+ };
721
+ function applyStyles(AIString) {
722
+ const pattern = /(```[\s\S]*?```)|(\*\*[\s\S]+?\*\*)|(`[\s\S]+?`)|(###\s+[\s\S]+?(?=\n|$))/g;
723
+ let lastIndex = 0;
724
+ const nodes = [];
725
+ AIString.replace(
726
+ pattern,
727
+ (match, codeBlockMatch, boldMatch, codeMatch, headerMatch, offset) => {
728
+ if (offset > lastIndex) {
729
+ const plainText = AIString.slice(lastIndex, offset);
730
+ nodes.push($createTextNode(plainText));
731
+ }
732
+ if (codeBlockMatch) {
733
+ const matchContent = codeBlockMatch.slice(3, -3);
734
+ let language = "";
735
+ let content = matchContent;
736
+ const firstNewLine = matchContent.indexOf("\n");
737
+ if (firstNewLine !== -1) {
738
+ const firstLine = matchContent.slice(0, firstNewLine).trim();
739
+ if (firstLine.length > 0 && /^[a-zA-Z0-9_\-]+$/.test(firstLine)) {
740
+ language = firstLine;
741
+ content = matchContent.slice(firstNewLine + 1);
742
+ }
743
+ }
744
+ const codeNode = $createCodeNode(language);
745
+ codeNode.append($createTextNode(content));
746
+ nodes.push(codeNode);
747
+ } else if (boldMatch) {
748
+ const content = boldMatch.slice(2, -2);
749
+ const boldTextNode = $createTextNode(content);
750
+ boldTextNode.setFormat("bold");
751
+ nodes.push(boldTextNode);
752
+ } else if (codeMatch) {
753
+ const content = codeMatch.slice(1, -1);
754
+ const codeTextNode = $createTextNode(content);
755
+ codeTextNode.setFormat("code");
756
+ nodes.push(codeTextNode);
757
+ } else if (headerMatch) {
758
+ const content = headerMatch.slice(4).trim();
759
+ const headerNode = $createHeadingNode("h3");
760
+ headerNode.append($createTextNode(content));
761
+ nodes.push(headerNode);
762
+ }
763
+ lastIndex = offset + match.length;
764
+ return match;
765
+ }
766
+ );
767
+ if (lastIndex < AIString.length) {
768
+ nodes.push($createTextNode(AIString.slice(lastIndex)));
769
+ }
770
+ return nodes;
771
+ }
772
+ function insertText(text, editor) {
773
+ if (isJSON(text) || text.startsWith("json")) {
774
+ GenerateSteps(text, editor);
775
+ return;
776
+ }
777
+ editor.update(() => {
778
+ const selection = $getSelection();
779
+ if (!$isRangeSelection(selection))
780
+ return console.log("No valid text selection found.");
781
+ const nodesInSelection = selection.getNodes();
782
+ if (nodesInSelection.length > 0) {
783
+ let insertionPoint = nodesInSelection[nodesInSelection.length - 1];
784
+ const formattedNodes = applyStyles(text);
785
+ formattedNodes.forEach((node) => {
786
+ insertionPoint.insertAfter(node);
787
+ insertionPoint = node;
788
+ });
789
+ }
790
+ });
791
+ }
792
+ function replaceSelectedText(text, editor) {
793
+ if (isJSON(text) || text.startsWith("json")) {
794
+ GenerateSteps(text, editor);
795
+ return;
796
+ }
797
+ editor.update(() => {
798
+ const selection = $getSelection();
799
+ if (!$isRangeSelection(selection)) {
800
+ console.warn("No valid text selection found.");
801
+ return;
802
+ }
803
+ selection.removeText();
804
+ const formattedNodes = applyStyles(text);
805
+ selection.insertNodes(formattedNodes);
806
+ });
807
+ }
808
+ function insertTextUnderSelected(text, editor) {
809
+ if (isJSON(text) || text.startsWith("json")) {
810
+ GenerateSteps(text, editor);
811
+ return;
812
+ }
813
+ editor.update(() => {
814
+ const selection = $getSelection();
815
+ if (!$isRangeSelection(selection)) return;
816
+ const nodes = selection.getNodes();
817
+ if (nodes.length > 0) {
818
+ const lastNode = nodes[nodes.length - 1];
819
+ const newParagraph = $createParagraphNode();
820
+ const formattedNodes = applyStyles(text);
821
+ newParagraph.append(...formattedNodes);
822
+ lastNode.insertAfter(newParagraph);
823
+ }
824
+ });
825
+ }
826
+
827
+ // src/components/ui/ai/ai-button.tsx
828
+ import { useCompletion } from "@ai-sdk/react";
829
+ import { toast } from "sonner";
830
+ import ReactMarkdown from "react-markdown";
831
+
832
+ // src/components/editor/utils/extract-data.ts
833
+ init_react_shim();
834
+ import { $getRoot as $getRoot2, ElementNode as ElementNode2, ParagraphNode, TextNode as TextNode2 } from "lexical";
835
+ import { ListNode } from "@lexical/list";
836
+ import { HeadingNode, QuoteNode } from "@lexical/rich-text";
837
+ import { TableNode } from "@lexical/table";
838
+ import { CodeNode } from "@lexical/code";
839
+ function extractChildrenContent(nodes) {
840
+ return nodes.filter((node) => node instanceof TextNode2).map((node) => node.getTextContent()).join(" ");
841
+ }
842
+ function processListItem(listItem) {
843
+ let textContent = "";
844
+ const children = [];
845
+ listItem.getChildren().forEach((child) => {
846
+ if (child instanceof TextNode2) {
847
+ textContent += child.getTextContent();
848
+ } else if (child instanceof ElementNode2) {
849
+ textContent += extractChildrenContent(child.getChildren());
850
+ }
851
+ if (child instanceof ListNode) {
852
+ children.push(...processList(child));
853
+ }
854
+ });
855
+ return {
856
+ blockType: "list-item",
857
+ content: textContent.trim(),
858
+ children: children.length > 0 ? children : void 0
859
+ };
860
+ }
861
+ function processList(listNode) {
862
+ const listType = listNode.getListType();
863
+ return listNode.getChildren().map((child) => __spreadProps(__spreadValues({}, processListItem(child)), {
864
+ attributes: { listType }
865
+ }));
866
+ }
867
+ function processHeading(headingNode) {
868
+ return {
869
+ blockType: "heading",
870
+ content: headingNode.getTextContent()
871
+ };
872
+ }
873
+ function processTable(TableNode2) {
874
+ return {
875
+ blockType: "Table",
876
+ content: TableNode2.getTextContent()
877
+ };
878
+ }
879
+ function processCodeBlock(codeNode) {
880
+ return {
881
+ blockType: "code",
882
+ content: codeNode.getTextContent()
883
+ };
884
+ }
885
+ function ExtractData(editor) {
886
+ const blocks = [];
887
+ editor.update(() => {
888
+ const root = $getRoot2();
889
+ root.getChildren().forEach((node) => {
890
+ try {
891
+ if (node instanceof HeadingNode) {
892
+ blocks.push(processHeading(node));
893
+ } else if (node instanceof TableNode) {
894
+ blocks.push(processTable(node));
895
+ } else if (node instanceof ListNode) {
896
+ blocks.push({
897
+ blockType: "list",
898
+ content: "",
899
+ children: processList(node)
900
+ });
901
+ } else if (node instanceof CollapsibleContainerNode || node instanceof CollapsibleTitleNode) {
902
+ let title = "";
903
+ let content = "";
904
+ if (node instanceof CollapsibleTitleNode) {
905
+ title = node.getTextContent();
906
+ }
907
+ if (node instanceof CollapsibleContainerNode) {
908
+ const children = node.getChildren();
909
+ const titleNode = children.find((child) => child instanceof CollapsibleTitleNode);
910
+ if (titleNode) {
911
+ title = titleNode.getTextContent();
912
+ }
913
+ content = children.filter((child) => !(child instanceof CollapsibleTitleNode)).map((child) => child.getTextContent()).join("\n");
914
+ }
915
+ blocks.push({
916
+ blockType: "Collapsible",
917
+ content: title,
918
+ // The collapsible title.
919
+ children: [
920
+ {
921
+ blockType: "CollapsibleContent",
922
+ content
923
+ // The collapsible content.
924
+ }
925
+ ]
926
+ });
927
+ } else if (node instanceof ParagraphNode) {
928
+ if (node.getTextContent() == "") return;
929
+ blocks.push({
930
+ blockType: "paragraph",
931
+ content: node.getTextContent()
932
+ });
933
+ } else if (node instanceof CodeNode) {
934
+ blocks.push(processCodeBlock(node));
935
+ } else if (node instanceof QuoteNode) {
936
+ blocks.push({
937
+ blockType: "quote",
938
+ content: node.getTextContent(),
939
+ children: node.getChildren().length >= 2 ? node.getChildren().map((child) => ({
940
+ blockType: "text",
941
+ content: child.getTextContent()
942
+ })) : void 0
943
+ });
944
+ } else if (node instanceof TextNode2) {
945
+ blocks.push({
946
+ blockType: "text",
947
+ content: node.getTextContent()
948
+ });
949
+ }
950
+ } catch (error) {
951
+ console.warn("Error processing node:", error);
952
+ }
953
+ });
954
+ });
955
+ return JSON.stringify(blocks);
956
+ }
957
+
958
+ // src/components/ui/ai/ai-button.tsx
959
+ var placeholders = [
960
+ "Chat with what you are writing.",
961
+ "Click on the stepper to generate tasks step by step.",
962
+ "Click on autocomplete to complete sentences.",
963
+ "Is your text too long? Do you want to make it shorter?"
964
+ ];
965
+ function AiButton({ editor }) {
966
+ const [actionType, setActionType] = useState4(null);
967
+ const [streamedResponse, setStreamedResponse] = useState4("");
968
+ const { apiEndpoint } = useAI();
969
+ const { completion, isLoading, complete, handleInputChange, input } = useCompletion({
970
+ api: apiEndpoint,
971
+ onError: (err) => {
972
+ toast.error(err.message);
973
+ },
974
+ onResponse: (response2) => {
975
+ setStreamedResponse("");
976
+ },
977
+ onFinish: (prompt, completion2) => {
978
+ if (actionType === "Steps") {
979
+ setStreamedResponse(completion2);
980
+ }
981
+ }
982
+ });
983
+ const handleAction = async (action, payload) => {
984
+ try {
985
+ await complete("", {
986
+ body: __spreadValues({
987
+ action
988
+ }, payload)
989
+ });
990
+ setActionType(action);
991
+ } catch (err) {
992
+ toast.error("Failed to process AI action. Please try again.");
993
+ }
994
+ };
995
+ const handleRegeneration = async () => {
996
+ if (!completion) {
997
+ toast.error("No content to regenerate");
998
+ return;
999
+ }
1000
+ await handleAction("GenerateAgain", { prompt: completion });
1001
+ };
1002
+ const handleAutoComplete = async () => {
1003
+ const selectedText = getSelectedText(editor, 30);
1004
+ await handleAction("autoComplete", { prompt: selectedText });
1005
+ };
1006
+ const handleImproveWriting = async () => {
1007
+ const selectedText = getSelectedText(editor);
1008
+ await handleAction("ImproveWriting", { prompt: selectedText });
1009
+ };
1010
+ const handleSimplifyLanguage = async () => {
1011
+ const selectedText = getSelectedText(editor);
1012
+ await handleAction("SimplifyLanguage", { prompt: selectedText });
1013
+ };
1014
+ const handleMakeLong = async () => {
1015
+ const selectedText = getSelectedText(editor);
1016
+ await handleAction("MakeLong", { prompt: selectedText });
1017
+ };
1018
+ const handleMakeShort = async () => {
1019
+ const selectedText = getSelectedText(editor);
1020
+ await handleAction("MakeShort", { prompt: selectedText });
1021
+ };
1022
+ const handleFixSpellingGrammar = async () => {
1023
+ const selectedText = getSelectedText(editor);
1024
+ await handleAction("FixSpellingGrammar", { prompt: selectedText });
1025
+ };
1026
+ const handleSubmit = async (e) => {
1027
+ e.preventDefault();
1028
+ if (!input) {
1029
+ toast.error("Please enter a question or instruction");
1030
+ return;
1031
+ }
1032
+ if (actionType === "Steps") {
1033
+ await handleAction("Steps", { prompt: input });
1034
+ } else {
1035
+ const data = ExtractData(editor);
1036
+ const selectedText = getSelectedText(editor, 30);
1037
+ if (!selectedText) {
1038
+ toast.error("Please select some text first");
1039
+ return;
1040
+ }
1041
+ await handleAction("ChatWithSelectedString", {
1042
+ prompt: input,
1043
+ context: data
1044
+ });
1045
+ setActionType(null);
1046
+ }
1047
+ };
1048
+ const renderSteps = () => {
1049
+ if (!streamedResponse) return null;
1050
+ try {
1051
+ const steps = JSON.parse(streamedResponse);
1052
+ return /* @__PURE__ */ React5.createElement("ul", { className: "list-none space-y-2" }, steps.map((step) => /* @__PURE__ */ React5.createElement("li", { key: step.id, className: "rounded-md shadow-md p-1" }, /* @__PURE__ */ React5.createElement("h3", { className: "font-semibold text-lg" }, step.id + 1, ". ", step.title), /* @__PURE__ */ React5.createElement("p", { className: "text-gray-600 dark:text-gray-300 mtx-2" }, step.content))));
1053
+ } catch (error) {
1054
+ return;
1055
+ }
1056
+ };
1057
+ const Actions = useMemo(
1058
+ () => ({
1059
+ suggestion: [
1060
+ {
1061
+ icon: /* @__PURE__ */ React5.createElement(
1062
+ "svg",
1063
+ {
1064
+ xmlns: "http://www.w3.org/2000/svg",
1065
+ className: "size-5 text-purple-500",
1066
+ viewBox: "0 0 24 24"
1067
+ },
1068
+ /* @__PURE__ */ React5.createElement(
1069
+ "path",
1070
+ {
1071
+ fill: "currentColor",
1072
+ d: "m19 9l-1.25-2.75L15 5l2.75-1.25L19 1l1.25 2.75L23 5l-2.75 1.25Zm0 14l-1.25-2.75L15 19l2.75-1.25L19 15l1.25 2.75L23 19l-2.75 1.25ZM4.8 16L8 7h2l3.2 9h-1.9l-.7-2H7.4l-.7 2Zm3.05-3.35h2.3L9 9ZM9 18q2.5 0 4.25-1.75T15 12q0-2.5-1.75-4.25T9 6Q6.5 6 4.75 7.75T3 12q0 2.5 1.75 4.25T9 18Zm0 2q-3.35 0-5.675-2.325Q1 15.35 1 12q0-3.35 2.325-5.675Q5.65 4 9 4q3.35 0 5.675 2.325Q17 8.65 17 12q0 3.35-2.325 5.675Q12.35 20 9 20Z"
1073
+ }
1074
+ )
1075
+ ),
1076
+ label: "auto compeletion",
1077
+ HoverCard: {
1078
+ desc: "Improve your sentences effortlessly\u2014just select the text you want to refine, and let AI work its magic! \u2728"
1079
+ },
1080
+ onClick: handleAutoComplete
1081
+ },
1082
+ {
1083
+ icon: /* @__PURE__ */ React5.createElement(
1084
+ "svg",
1085
+ {
1086
+ xmlns: "http://www.w3.org/2000/svg",
1087
+ className: "size-5 text-purple-500",
1088
+ viewBox: "0 0 24 24"
1089
+ },
1090
+ /* @__PURE__ */ React5.createElement(
1091
+ "path",
1092
+ {
1093
+ fill: "currentColor",
1094
+ d: "M7.5 5.6L10 7L8.6 4.5L10 2L7.5 3.4L5 2l1.4 2.5L5 7zm12 9.8L17 14l1.4 2.5L17 19l2.5-1.4L22 19l-1.4-2.5L22 14zM22 2l-2.5 1.4L17 2l1.4 2.5L17 7l2.5-1.4L22 7l-1.4-2.5zm-7.63 5.29a.996.996 0 0 0-1.41 0L1.29 18.96a.996.996 0 0 0 0 1.41l2.34 2.34c.39.39 1.02.39 1.41 0L16.7 11.05a.996.996 0 0 0 0-1.41zm-1.03 5.49l-2.12-2.12l2.44-2.44l2.12 2.12z"
1095
+ }
1096
+ )
1097
+ ),
1098
+ label: "Improve Writing",
1099
+ HoverCard: {
1100
+ desc: " Simply select the text you want, and let our AI refine your writing effortlessly! \u{1F4DD}\u{1F680}"
1101
+ },
1102
+ onClick: handleImproveWriting
1103
+ },
1104
+ {
1105
+ icon: /* @__PURE__ */ React5.createElement(
1106
+ "svg",
1107
+ {
1108
+ xmlns: "http://www.w3.org/2000/svg",
1109
+ className: "size-5 text-purple-500",
1110
+ viewBox: "0 0 24 24"
1111
+ },
1112
+ /* @__PURE__ */ React5.createElement(
1113
+ "path",
1114
+ {
1115
+ fill: "currentColor",
1116
+ d: "m9 16.2l-3.5-3.5a.984.984 0 0 0-1.4 0a.984.984 0 0 0 0 1.4l4.19 4.19c.39.39 1.02.39 1.41 0L20.3 7.7a.984.984 0 0 0 0-1.4a.984.984 0 0 0-1.4 0z"
1117
+ }
1118
+ )
1119
+ ),
1120
+ label: "Fix spelling & grammar",
1121
+ HoverCard: {
1122
+ desc: "\u{1F4DD} Select your messy text, and let AI transform it into perfection! \u{1F680}"
1123
+ },
1124
+ onClick: handleFixSpellingGrammar
1125
+ }
1126
+ ],
1127
+ Edit: [
1128
+ {
1129
+ icon: /* @__PURE__ */ React5.createElement(
1130
+ "svg",
1131
+ {
1132
+ xmlns: "http://www.w3.org/2000/svg",
1133
+ className: "h-4 flex-shrink-0 w-4 block text-green-400",
1134
+ viewBox: "0 0 20 20"
1135
+ },
1136
+ /* @__PURE__ */ React5.createElement(
1137
+ "path",
1138
+ {
1139
+ fill: "currentColor",
1140
+ d: "M3.5 5a.5.5 0 0 0 0 1h13a.5.5 0 0 0 0-1zm0 3a.5.5 0 0 0 0 1h13a.5.5 0 0 0 0-1zm0 7h7.002l.416-1H3.5a.5.5 0 0 0 0 1m8.668-4l-.416 1H3.5a.5.5 0 0 1 0-1zm-.667 6.012h1.75l-.59 2.363c-.121.485.462.828.826.488l4.873-4.556c.497-.466.169-1.301-.512-1.301H16.75l.781-2.347a.5.5 0 0 0-.474-.659h-3.473a.5.5 0 0 0-.462.308l-2.083 5.01a.5.5 0 0 0 .462.694"
1141
+ }
1142
+ )
1143
+ ),
1144
+ label: "Make longer",
1145
+ HoverCard: {
1146
+ desc: "Enhance your text by adding more detail and context. Let AI expand your ideas! \u{1F680}"
1147
+ },
1148
+ onClick: handleMakeLong
1149
+ },
1150
+ {
1151
+ icon: /* @__PURE__ */ React5.createElement(
1152
+ "svg",
1153
+ {
1154
+ xmlns: "http://www.w3.org/2000/svg",
1155
+ className: "h-4 flex-shrink-0 w-4 block text-green-400",
1156
+ viewBox: "0 0 32 32"
1157
+ },
1158
+ /* @__PURE__ */ React5.createElement("path", { fill: "currentColor", d: "M6 18h14v2H6zm0-6h20v2H6z" })
1159
+ ),
1160
+ label: "Make shorter",
1161
+ HoverCard: {
1162
+ desc: "Select your dummy short paragraph and let our AI expand it while preserving its original content! \u{1F680}\u2728"
1163
+ },
1164
+ onClick: handleMakeShort
1165
+ },
1166
+ {
1167
+ icon: /* @__PURE__ */ React5.createElement(
1168
+ "svg",
1169
+ {
1170
+ xmlns: "http://www.w3.org/2000/svg",
1171
+ className: "h-4 flex-shrink-0 w-4 block text-green-400",
1172
+ viewBox: "0 0 24 24"
1173
+ },
1174
+ /* @__PURE__ */ React5.createElement(
1175
+ "path",
1176
+ {
1177
+ fill: "currentColor",
1178
+ fillRule: "evenodd",
1179
+ d: "M12.75 18.96V22h-1.5v-3.04A7 7 0 0 1 5 12v-2h1.5v2a5.5 5.5 0 0 0 11 0v-2H19v2a7 7 0 0 1-6.25 6.96M8 6a4 4 0 1 1 8 0v6a4 4 0 1 1-8 0z"
1180
+ }
1181
+ )
1182
+ ),
1183
+ label: "Simplify Language",
1184
+ HoverCard: {
1185
+ desc: "If you're using overly complex language and want to simplify it for easier understanding, let our AI transform your text into clear, concise, and engaging content! \u{1F60A}\u2728"
1186
+ },
1187
+ onClick: handleSimplifyLanguage
1188
+ }
1189
+ ],
1190
+ format_block: [
1191
+ {
1192
+ icon: /* @__PURE__ */ React5.createElement(
1193
+ "svg",
1194
+ {
1195
+ xmlns: "http://www.w3.org/2000/svg",
1196
+ className: "size-5 text-yellow-400",
1197
+ viewBox: "0 0 24 24"
1198
+ },
1199
+ /* @__PURE__ */ React5.createElement("g", { fill: "none" }, /* @__PURE__ */ React5.createElement("path", { d: "m12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035q-.016-.005-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427q-.004-.016-.017-.018m.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093q.019.005.029-.008l.004-.014l-.034-.614q-.005-.018-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014l-.034.614q.001.018.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01z" }), /* @__PURE__ */ React5.createElement(
1200
+ "path",
1201
+ {
1202
+ fill: "currentColor",
1203
+ d: "M5.436 16.72a1.466 1.466 0 0 1 1.22 2.275a1.466 1.466 0 0 1-1.22 2.275c-.587 0-1.134-.21-1.38-.79c-.153-.361-.112-.79.297-.963a.65.65 0 0 1 .852.344a.18.18 0 0 0 .165.11c.114-.003.23-.026.23-.168c0-.1-.073-.143-.156-.155l-.051-.003a.65.65 0 0 1-.112-1.29l.112-.01c.102 0 .207-.037.207-.158c0-.141-.116-.165-.23-.168a.18.18 0 0 0-.164.11a.65.65 0 0 1-.853.345c-.409-.174-.45-.603-.297-.963c.246-.58.793-.79 1.38-.79ZM20 17.5a1.5 1.5 0 0 1 0 3H9a1.5 1.5 0 0 1 0-3zM6.08 9.945a1.552 1.552 0 0 1 .43 2.442l-.554.593h.47a.65.65 0 1 1 0 1.3H4.573a.655.655 0 0 1-.655-.654c0-.207.029-.399.177-.557L5.559 11.5c.142-.152.03-.473-.203-.415c-.087.022-.123.089-.134.165l-.004.059a.65.65 0 1 1-1.3 0c0-.692.439-1.314 1.123-1.485c.35-.088.718-.04 1.04.121ZM20 10.5a1.5 1.5 0 0 1 .144 2.993L20 13.5H9a1.5 1.5 0 0 1-.144-2.993L9 10.5zM6.15 3.39v3.24a.65.65 0 0 1-1.3 0V4.523a.65.65 0 0 1-.46-1.184l.742-.494a.655.655 0 0 1 1.018.544ZM20 3.5a1.5 1.5 0 0 1 .144 2.993L20 6.5H9a1.5 1.5 0 0 1-.144-2.993L9 3.5z"
1204
+ }
1205
+ ))
1206
+ ),
1207
+ label: "Step-by-Step Guide",
1208
+ HoverCard: {
1209
+ desc: "Need a clear roadmap to programming mastery? step-by-step guide that breaks down complex topics into simple, actionable steps. Let it light your path to coding success! \u{1F680}\u{1F4BB}"
1210
+ },
1211
+ onClick: () => setActionType("Steps")
1212
+ }
1213
+ ]
1214
+ }),
1215
+ []
1216
+ );
1217
+ const response = useMemo(
1218
+ () => [
1219
+ {
1220
+ icon: /* @__PURE__ */ React5.createElement(
1221
+ "svg",
1222
+ {
1223
+ xmlns: "http://www.w3.org/2000/svg",
1224
+ className: "text-[#8d5bc1] size-5",
1225
+ viewBox: "0 0 16 16"
1226
+ },
1227
+ /* @__PURE__ */ React5.createElement(
1228
+ "path",
1229
+ {
1230
+ fill: "currentColor",
1231
+ fillRule: "evenodd",
1232
+ d: "M0 3.2c0-1.12 0-1.68.218-2.11C.41.714.716.408 1.092.216c.428-.218.988-.218 2.11-.218h.6c1.12 0 1.68 0 2.11.218c.376.192.682.498.874.874c.218.428.218.988.218 2.11v.6c0 1.12 0 1.68-.218 2.11a2 2 0 0 1-.874.874c-.428.218-.988.218-2.11.218h-.6c-1.12 0-1.68 0-2.11-.218a2 2 0 0 1-.874-.874C0 5.482 0 4.922 0 3.8zM3.2 1h.6c.577 0 .949 0 1.23.024c.272.022.372.06.422.085c.188.096.341.249.437.437c.025.05.063.15.085.422c.023.283.024.656.024 1.23v.6c0 .577 0 .949-.024 1.23c-.022.272-.06.372-.085.422a1 1 0 0 1-.437.437c-.05.025-.15.063-.422.085c-.283.023-.656.024-1.23.024h-.6c-.577 0-.949 0-1.23-.024c-.272-.022-.372-.06-.422-.085a1 1 0 0 1-.437-.437c-.025-.05-.063-.15-.085-.422a17 17 0 0 1-.024-1.23v-.6c0-.577 0-.949.024-1.23c.022-.272.06-.372.085-.422c.096-.188.249-.341.437-.437c.05-.025.15-.063.422-.085C2.253 1 2.626 1 3.2 1M9 12.2c0-1.12 0-1.68.218-2.11c.192-.376.498-.682.874-.874c.428-.218.988-.218 2.11-.218h.6c1.12 0 1.68 0 2.11.218c.376.192.682.498.874.874c.218.428.218.988.218 2.11v.6c0 1.12 0 1.68-.218 2.11a2 2 0 0 1-.874.874c-.428.218-.988.218-2.11.218h-.6c-1.12 0-1.68 0-2.11-.218a2 2 0 0 1-.874-.874C9 14.482 9 13.922 9 12.8zm3.8-2.2c.577 0 .949 0 1.23.024c.272.022.372.06.422.085c.188.096.341.249.437.437c.025.05.063.15.085.422c.023.283.024.656.024 1.23v.6c0 .577 0 .949-.024 1.23c-.022.272-.06.372-.085.422a1 1 0 0 1-.437.437c-.05.025-.15.063-.422.085c-.283.023-.656.024-1.23.024h-.6c-.577 0-.949 0-1.23-.024c-.272-.022-.372-.06-.422-.085a1 1 0 0 1-.437-.437c-.025-.05-.063-.15-.085-.422a17 17 0 0 1-.024-1.23v-.6c0-.577 0-.949.024-1.23c.022-.272.06-.372.085-.422c.096-.188.249-.341.437-.437c.05-.025.15-.063.422-.085c.283-.023.656-.024 1.23-.024z",
1233
+ clipRule: "evenodd"
1234
+ }
1235
+ ),
1236
+ /* @__PURE__ */ React5.createElement(
1237
+ "path",
1238
+ {
1239
+ fill: "currentColor",
1240
+ d: "M8 2.5a.5.5 0 0 1 .5-.5h2A2.5 2.5 0 0 1 13 4.5v1.79l1.15-1.15a.5.5 0 0 1 .707.707l-2 2a.5.5 0 0 1-.707 0l-2-2a.5.5 0 0 1 .707-.707l1.15 1.15V4.5a1.5 1.5 0 0 0-1.5-1.5h-2a.5.5 0 0 1-.5-.5zM3.31 8.04a.5.5 0 0 1 .188-.038h.006a.5.5 0 0 1 .351.146l2 2a.5.5 0 0 1-.707.707l-1.15-1.15v1.79a1.5 1.5 0 0 0 1.5 1.5h2a.5.5 0 0 1 0 1h-2a2.5 2.5 0 0 1-2.5-2.5v-1.79l-1.15 1.15a.5.5 0 0 1-.707-.707l2-2a.5.5 0 0 1 .162-.109z"
1241
+ }
1242
+ )
1243
+ ),
1244
+ label: "rplace text",
1245
+ HoverCard: {
1246
+ desc: "Select your text and let our AI replace it with a polished, enhanced version! \u{1F680}\u2728"
1247
+ },
1248
+ func: () => replaceSelectedText(completion, editor)
1249
+ },
1250
+ {
1251
+ icon: /* @__PURE__ */ React5.createElement(
1252
+ "svg",
1253
+ {
1254
+ xmlns: "http://www.w3.org/2000/svg",
1255
+ className: "text-[#8d5bc1] size-5",
1256
+ viewBox: "0 0 56 56"
1257
+ },
1258
+ /* @__PURE__ */ React5.createElement(
1259
+ "path",
1260
+ {
1261
+ fill: "currentColor",
1262
+ d: "M33.8 11.36h16.01c1.008 0 1.804-.774 1.804-1.782c0-.984-.797-1.758-1.804-1.758H33.8c-1.008 0-1.782.774-1.782 1.758c0 1.008.774 1.781 1.782 1.781M7.083 26.944c1.71 0 2.695-1.195 2.695-3.093v-4.477c0-.516.235-.82.797-.82h6.375v2.343c0 1.852 1.875 2.555 3.281 1.43l6.352-5.062c.96-.774.96-2.11 0-2.86L20.23 9.32c-1.453-1.195-3.28-.469-3.28 1.43v2.438h-6.891c-3.305 0-5.672 2.039-5.672 5.367v5.297c0 1.898.984 3.093 2.695 3.093m26.719-3.304h16.008c1.008 0 1.804-.774 1.804-1.782c0-.984-.797-1.758-1.804-1.758H33.8c-1.008 0-1.782.774-1.782 1.758c0 1.008.774 1.782 1.782 1.782M6.168 35.92h43.64a1.786 1.786 0 0 0 1.805-1.78c0-.985-.797-1.758-1.804-1.758H6.168c-1.008 0-1.781.773-1.781 1.758c0 .984.773 1.78 1.78 1.78m0 12.259h43.64c1.008 0 1.805-.774 1.805-1.758s-.797-1.781-1.804-1.781H6.168a1.766 1.766 0 0 0-1.781 1.78c0 .985.773 1.759 1.78 1.759"
1263
+ }
1264
+ )
1265
+ ),
1266
+ label: "insert text",
1267
+ HoverCard: {
1268
+ desc: "text will inserted immediately following your selection."
1269
+ },
1270
+ func: () => insertText(completion, editor)
1271
+ },
1272
+ {
1273
+ icon: /* @__PURE__ */ React5.createElement(
1274
+ "svg",
1275
+ {
1276
+ xmlns: "http://www.w3.org/2000/svg",
1277
+ className: "text-[#8d5bc1] size-5",
1278
+ viewBox: "0 0 14 14"
1279
+ },
1280
+ /* @__PURE__ */ React5.createElement(
1281
+ "g",
1282
+ {
1283
+ fill: "none",
1284
+ stroke: "currentColor",
1285
+ strokeLinecap: "round",
1286
+ strokeLinejoin: "round"
1287
+ },
1288
+ /* @__PURE__ */ React5.createElement("path", { d: "M9.5 6.5h-9m13-3H.5m13-3H.5" }),
1289
+ /* @__PURE__ */ React5.createElement(
1290
+ "rect",
1291
+ {
1292
+ width: "4",
1293
+ height: "13",
1294
+ x: "5",
1295
+ y: "5",
1296
+ rx: ".5",
1297
+ transform: "rotate(-90 7 11.5)"
1298
+ }
1299
+ )
1300
+ )
1301
+ ),
1302
+ label: "insert below",
1303
+ HoverCard: {
1304
+ desc: "text will inserted under your selection."
1305
+ },
1306
+ func: () => insertTextUnderSelected(completion, editor)
1307
+ },
1308
+ {
1309
+ icon: /* @__PURE__ */ React5.createElement(RotateCcw, { className: "text-[#8d5bc1] size-4" }),
1310
+ label: "try again",
1311
+ HoverCard: {
1312
+ desc: "you did not like the ai response? try it again with what do you want"
1313
+ },
1314
+ func: handleRegeneration
1315
+ }
1316
+ ],
1317
+ [completion]
1318
+ );
1319
+ return /* @__PURE__ */ React5.createElement(Popover, null, /* @__PURE__ */ React5.createElement(PopoverTrigger, { asChild: true }, /* @__PURE__ */ React5.createElement("button", { className: "inline-flex px-6 max-sm:py-2 max-sm:px-[5px] h-6 animate-background-shine items-center justify-center rounded-md border border-gray-800 bg-[linear-gradient(110deg,#000103,45%,#1e2631,55%,#000103)] bg-[length:200%_100%] font-medium text-gray-400 transition-colors focus:outline-none focus:ring-2 focus:ring-gray-400 focus:ring-offset-2 focus:ring-offset-gray-50" }, /* @__PURE__ */ React5.createElement(WandSparkles, { className: " size-4 text-purple-400" }))), /* @__PURE__ */ React5.createElement(PopoverContent, { className: "absolute max-h-[300px] h-fit shadow-sm shadow-black dark:shadow-gray-500 p-0 w-[420px] max-sm:w-[200px] min-w-[200px] max-w-[420px] top-[10px] max-sm:left-6 -left-7 AI-format" }, /* @__PURE__ */ React5.createElement("div", { className: "w-full relative" }, /* @__PURE__ */ React5.createElement("div", { className: "flex flex-col items-start justify-between" }, (completion || actionType === "Steps") && /* @__PURE__ */ React5.createElement(
1320
+ motion3.div,
1321
+ {
1322
+ initial: { opacity: 0, y: 20 },
1323
+ animate: { opacity: 1, y: 0 },
1324
+ transition: { duration: 0.5, ease: "easeOut" },
1325
+ className: "cursor-text w-full p-2 z-20 break-words max-h-64 h-fit overflow-y-auto"
1326
+ },
1327
+ streamedResponse !== "" ? renderSteps() : /* @__PURE__ */ React5.createElement(ReactMarkdown, null, completion || "Ask for a step-by-step guide on any programming topic. Example: 'How can I become a backend developer?'")
1328
+ ), /* @__PURE__ */ React5.createElement("div", { className: "relative w-full" }, /* @__PURE__ */ React5.createElement("div", { className: " absolute top-1/2 -translate-y-1/2 left-2" }, /* @__PURE__ */ React5.createElement(
1329
+ HoverBorderGradient,
1330
+ {
1331
+ duration: 2,
1332
+ clockwise: false,
1333
+ containerClassName: "rounded-full border-0",
1334
+ as: "button",
1335
+ className: "dark:bg-white size-5 bg-black dark:text-white flex justify-center items-center"
1336
+ },
1337
+ isLoading ? /* @__PURE__ */ React5.createElement(Loader2, { className: "size-3 dark:text-black text-white animate-spin" }) : /* @__PURE__ */ React5.createElement(StarsIcon, { className: "dark:text-purple-600 text-purple-300 size-3" })
1338
+ )), /* @__PURE__ */ React5.createElement(
1339
+ PlaceholdersAndVanishInput,
1340
+ {
1341
+ placeholders,
1342
+ onChange: handleInputChange,
1343
+ onSubmit: handleSubmit,
1344
+ disabled: isLoading
1345
+ }
1346
+ ))), /* @__PURE__ */ React5.createElement("div", { className: "w-[200px] h-[180px] z-50 rounded border mt-2 fixed" }, !completion ? /* @__PURE__ */ React5.createElement(Command, { id: "toolbar", className: "w-full " }, /* @__PURE__ */ React5.createElement(CommandInput, { placeholder: "Type a command" }), /* @__PURE__ */ React5.createElement(CommandList, null, /* @__PURE__ */ React5.createElement(CommandEmpty, null, "No results found."), /* @__PURE__ */ React5.createElement(CommandGroup, { heading: "Suggested" }, Actions.suggestion.map((sug) => /* @__PURE__ */ React5.createElement(HoverCard, { key: sug.label }, /* @__PURE__ */ React5.createElement(
1347
+ HoverCardTrigger,
1348
+ {
1349
+ onClick: sug.onClick,
1350
+ className: "w-full p-0"
1351
+ },
1352
+ /* @__PURE__ */ React5.createElement(CommandItem, { className: "w-full" }, /* @__PURE__ */ React5.createElement("div", null, sug.icon), /* @__PURE__ */ React5.createElement("span", null, sug.label))
1353
+ ), /* @__PURE__ */ React5.createElement(
1354
+ HoverCardContent,
1355
+ {
1356
+ className: " p-2",
1357
+ side: "right",
1358
+ alignOffset: 60,
1359
+ sideOffset: 30
1360
+ },
1361
+ /* @__PURE__ */ React5.createElement("span", { className: "text-sm break-words text-muted-foreground" }, sug.HoverCard.desc)
1362
+ )))), /* @__PURE__ */ React5.createElement(CommandSeparator, null), /* @__PURE__ */ React5.createElement(CommandGroup, { heading: "format block" }, Actions.format_block.map((sug) => /* @__PURE__ */ React5.createElement(HoverCard, { key: sug.label }, /* @__PURE__ */ React5.createElement(
1363
+ HoverCardTrigger,
1364
+ {
1365
+ onClick: sug.onClick,
1366
+ className: "w-full p-0"
1367
+ },
1368
+ /* @__PURE__ */ React5.createElement(CommandItem, { className: "w-full" }, /* @__PURE__ */ React5.createElement("div", null, sug.icon), /* @__PURE__ */ React5.createElement("span", null, sug.label))
1369
+ ), /* @__PURE__ */ React5.createElement(
1370
+ HoverCardContent,
1371
+ {
1372
+ className: " p-2",
1373
+ side: "right",
1374
+ alignOffset: 60,
1375
+ sideOffset: 30
1376
+ },
1377
+ /* @__PURE__ */ React5.createElement("span", { className: "text-sm break-words text-muted-foreground" }, sug.HoverCard.desc)
1378
+ )))), /* @__PURE__ */ React5.createElement(CommandSeparator, null), /* @__PURE__ */ React5.createElement(CommandGroup, { heading: "Edit" }, Actions.Edit.map((sug) => /* @__PURE__ */ React5.createElement(HoverCard, { key: sug.label }, /* @__PURE__ */ React5.createElement(
1379
+ HoverCardTrigger,
1380
+ {
1381
+ onClick: sug.onClick,
1382
+ className: "w-full p-0"
1383
+ },
1384
+ /* @__PURE__ */ React5.createElement(CommandItem, { className: "w-full" }, /* @__PURE__ */ React5.createElement("div", null, sug.icon), /* @__PURE__ */ React5.createElement("span", null, sug.label))
1385
+ ), /* @__PURE__ */ React5.createElement(
1386
+ HoverCardContent,
1387
+ {
1388
+ className: "p-2",
1389
+ side: "right",
1390
+ alignOffset: 60,
1391
+ sideOffset: 30
1392
+ },
1393
+ /* @__PURE__ */ React5.createElement("span", { className: "text-sm text-muted-foreground" }, sug.HoverCard.desc)
1394
+ )))))) : /* @__PURE__ */ React5.createElement(Command, { id: "toolbar", className: "w-full" }, /* @__PURE__ */ React5.createElement(CommandInput, { placeholder: "Type a command" }), /* @__PURE__ */ React5.createElement(CommandList, null, /* @__PURE__ */ React5.createElement(CommandEmpty, null, "No results found."), /* @__PURE__ */ React5.createElement(CommandGroup, null, response.map((sug) => /* @__PURE__ */ React5.createElement(HoverCard, { key: sug.label }, /* @__PURE__ */ React5.createElement(
1395
+ HoverCardTrigger,
1396
+ {
1397
+ onClick: sug.func,
1398
+ className: "w-full p-0"
1399
+ },
1400
+ /* @__PURE__ */ React5.createElement(CommandItem, { disabled: isLoading, className: "w-full" }, /* @__PURE__ */ React5.createElement("div", null, sug.icon), /* @__PURE__ */ React5.createElement("span", null, sug.label))
1401
+ ), /* @__PURE__ */ React5.createElement(
1402
+ HoverCardContent,
1403
+ {
1404
+ className: " p-2",
1405
+ side: "right",
1406
+ alignOffset: 60,
1407
+ sideOffset: 30
1408
+ },
1409
+ /* @__PURE__ */ React5.createElement("span", { className: "text-sm break-words text-muted-foreground" }, sug.HoverCard.desc)
1410
+ ))))))))));
1411
+ }
1412
+
1413
+ // src/components/ui/write/text-format-floting-toolbar.tsx
1414
+ function TextFormatFloatingToolbar({
1415
+ editor,
1416
+ anchorElem,
1417
+ isLink,
1418
+ isBold,
1419
+ isItalic,
1420
+ isUnderline,
1421
+ isUppercase,
1422
+ isLowercase,
1423
+ isCapitalize,
1424
+ isCode,
1425
+ fontColor,
1426
+ isStrikethrough,
1427
+ isSubscript,
1428
+ isSuperscript,
1429
+ bgColor,
1430
+ setIsLinkEditMode,
1431
+ blockType,
1432
+ fontFamily,
1433
+ rootType,
1434
+ textAlign,
1435
+ fontSize
1436
+ }) {
1437
+ const popupCharStylesEditorRef = useRef3(null);
1438
+ const isSmall = useIsMobile();
1439
+ const insertLink = useCallback2(() => {
1440
+ if (!isLink) {
1441
+ setIsLinkEditMode(true);
1442
+ editor.dispatchCommand(TOGGLE_LINK_COMMAND, sanitizeUrl("https://"));
1443
+ } else {
1444
+ setIsLinkEditMode(false);
1445
+ editor.dispatchCommand(TOGGLE_LINK_COMMAND, null);
1446
+ }
1447
+ }, [editor, setIsLinkEditMode, isLink]);
1448
+ function mouseMoveListener(e) {
1449
+ if ((popupCharStylesEditorRef == null ? void 0 : popupCharStylesEditorRef.current) && (e.buttons === 1 || e.buttons === 3)) {
1450
+ if (popupCharStylesEditorRef.current.style.pointerEvents !== "none") {
1451
+ const x = e.clientX;
1452
+ const y = e.clientY;
1453
+ const elementUnderMouse = document.elementFromPoint(x, y);
1454
+ if (!popupCharStylesEditorRef.current.contains(elementUnderMouse)) {
1455
+ popupCharStylesEditorRef.current.style.pointerEvents = "none";
1456
+ }
1457
+ }
1458
+ }
1459
+ }
1460
+ function mouseUpListener(e) {
1461
+ if (popupCharStylesEditorRef == null ? void 0 : popupCharStylesEditorRef.current) {
1462
+ if (popupCharStylesEditorRef.current.style.pointerEvents !== "auto") {
1463
+ popupCharStylesEditorRef.current.style.pointerEvents = "auto";
1464
+ }
1465
+ }
1466
+ }
1467
+ useEffect4(() => {
1468
+ if (popupCharStylesEditorRef == null ? void 0 : popupCharStylesEditorRef.current) {
1469
+ popupCharStylesEditorRef.current.style.pointerEvents = "auto";
1470
+ }
1471
+ });
1472
+ useEffect4(() => {
1473
+ if (popupCharStylesEditorRef == null ? void 0 : popupCharStylesEditorRef.current) {
1474
+ document.addEventListener("mousemove", mouseMoveListener);
1475
+ document.addEventListener("mouseup", mouseUpListener);
1476
+ return () => {
1477
+ document.removeEventListener("mousemove", mouseMoveListener);
1478
+ document.removeEventListener("mouseup", mouseUpListener);
1479
+ if (popupCharStylesEditorRef.current) {
1480
+ popupCharStylesEditorRef.current.style.pointerEvents = "auto";
1481
+ }
1482
+ };
1483
+ }
1484
+ }, [popupCharStylesEditorRef]);
1485
+ const $updateTextFormatFloatingToolbar = useCallback2(() => {
1486
+ const selection = $getSelection2();
1487
+ const popupCharStylesEditorElem = popupCharStylesEditorRef.current;
1488
+ const nativeSelection = getDOMSelection(editor._window);
1489
+ if (!popupCharStylesEditorElem) return;
1490
+ const rootElement = editor.getRootElement();
1491
+ if (selection && nativeSelection && !nativeSelection.isCollapsed && rootElement && rootElement.contains(nativeSelection.anchorNode)) {
1492
+ const rangeRect = getDOMRangeRect(nativeSelection, rootElement);
1493
+ setFloatingElemPosition(rangeRect, popupCharStylesEditorElem, anchorElem);
1494
+ }
1495
+ }, [editor, anchorElem]);
1496
+ useEffect4(() => {
1497
+ const scrollerElem = anchorElem.parentElement;
1498
+ const update = () => {
1499
+ editor.getEditorState().read(() => {
1500
+ $updateTextFormatFloatingToolbar();
1501
+ });
1502
+ };
1503
+ window.addEventListener("resize", update);
1504
+ if (scrollerElem) {
1505
+ scrollerElem.addEventListener("scroll", update);
1506
+ }
1507
+ return () => {
1508
+ window.removeEventListener("resize", update);
1509
+ if (scrollerElem) {
1510
+ scrollerElem.removeEventListener("scroll", update);
1511
+ }
1512
+ };
1513
+ }, [editor, $updateTextFormatFloatingToolbar, anchorElem]);
1514
+ useEffect4(() => {
1515
+ editor.getEditorState().read(() => {
1516
+ $updateTextFormatFloatingToolbar();
1517
+ });
1518
+ return mergeRegister(
1519
+ editor.registerUpdateListener(({ editorState }) => {
1520
+ editorState.read(() => {
1521
+ $updateTextFormatFloatingToolbar();
1522
+ });
1523
+ }),
1524
+ editor.registerCommand(
1525
+ SELECTION_CHANGE_COMMAND,
1526
+ () => {
1527
+ $updateTextFormatFloatingToolbar();
1528
+ return false;
1529
+ },
1530
+ COMMAND_PRIORITY_LOW
1531
+ )
1532
+ );
1533
+ }, [editor, $updateTextFormatFloatingToolbar]);
1534
+ return /* @__PURE__ */ React.createElement(
1535
+ "div",
1536
+ {
1537
+ id: "toolbar",
1538
+ ref: popupCharStylesEditorRef,
1539
+ className: `
1540
+ z-[50] h-[30px] p-1 px-2 max-sm:p-2 max-sm:h-[295px] max-sm:w-[32px] max-sm:overflow-y-auto
1541
+ border dark:border-zinc-800 dark:bg-zinc-900 text-zinc-950 dark:text-zinc-50 border-zinc-200 bg-white/90
1542
+ inline-flex flex-row max-sm:flex-col items-center shadow-md absolute top-0 left-0 text-sm rounded-[6px]
1543
+ `
1544
+ },
1545
+ /* @__PURE__ */ React.createElement(AiButton, { editor }),
1546
+ /* @__PURE__ */ React.createElement(
1547
+ Separator,
1548
+ {
1549
+ orientation: "vertical",
1550
+ className: "max-sm:h-[1px] max-sm:my-1 max-sm:w-5 h-5 mx-1"
1551
+ }
1552
+ ),
1553
+ /* @__PURE__ */ React.createElement(
1554
+ BlockFormatDropDown,
1555
+ {
1556
+ editor,
1557
+ blockType,
1558
+ style: { height: "25px" },
1559
+ ShowChevronsUpDown: false,
1560
+ side: isSmall ? "right" : "bottom",
1561
+ sideOffset: isSmall ? 10 : 5
1562
+ }
1563
+ ),
1564
+ /* @__PURE__ */ React.createElement(
1565
+ Separator,
1566
+ {
1567
+ orientation: "vertical",
1568
+ className: "max-sm:h-[1px] max-sm:my-1 max-sm:w-5 h-5 mx-1"
1569
+ }
1570
+ ),
1571
+ /* @__PURE__ */ React.createElement(
1572
+ FontSize,
1573
+ {
1574
+ selectionFontSize: fontSize.slice(0, -2),
1575
+ editor,
1576
+ disabled: false,
1577
+ className: "h-[25px]",
1578
+ classNameContent: "max-sm:flex-col"
1579
+ }
1580
+ ),
1581
+ /* @__PURE__ */ React.createElement(
1582
+ Separator,
1583
+ {
1584
+ orientation: "vertical",
1585
+ className: "max-sm:h-[1px] max-sm:my-1 max-sm:w-5 h-5 mx-1"
1586
+ }
1587
+ ),
1588
+ /* @__PURE__ */ React.createElement(
1589
+ Font,
1590
+ {
1591
+ disabled: false,
1592
+ style: { fontFamily, height: "25px", padding: "0px 13px" },
1593
+ value: fontFamily,
1594
+ editor,
1595
+ ShowChevronsUpDown: false,
1596
+ side: isSmall ? "right" : "bottom",
1597
+ sideOffset: isSmall ? 10 : 5
1598
+ }
1599
+ ),
1600
+ /* @__PURE__ */ React.createElement(
1601
+ Separator,
1602
+ {
1603
+ orientation: "vertical",
1604
+ className: "max-sm:h-[1px] max-sm:my-1 max-sm:w-5 h-5 mx-1"
1605
+ }
1606
+ ),
1607
+ /* @__PURE__ */ React.createElement("div", { className: "flex flex-row max-sm:flex-col gap-1 items-center justify-center" }, /* @__PURE__ */ React.createElement(
1608
+ Toggle,
1609
+ {
1610
+ variant: "outline",
1611
+ size: "floting",
1612
+ pressed: isBold,
1613
+ onPressedChange: () => {
1614
+ editor.dispatchCommand(FORMAT_TEXT_COMMAND, "bold");
1615
+ },
1616
+ tip: `Bold ${SHORTCUTS.BOLD}`,
1617
+ "aria-label": `Format text as bold. Shortcut: ${SHORTCUTS.BOLD}`
1618
+ },
1619
+ /* @__PURE__ */ React.createElement(Bold, null)
1620
+ ), /* @__PURE__ */ React.createElement(
1621
+ Toggle,
1622
+ {
1623
+ variant: "outline",
1624
+ size: "floting",
1625
+ pressed: isItalic,
1626
+ onPressedChange: () => {
1627
+ editor.dispatchCommand(FORMAT_TEXT_COMMAND, "italic");
1628
+ },
1629
+ tip: `Italic (${SHORTCUTS.ITALIC})`,
1630
+ type: "button",
1631
+ "aria-label": `Format text as italics. Shortcut: ${SHORTCUTS.ITALIC}`
1632
+ },
1633
+ /* @__PURE__ */ React.createElement(Italic, null)
1634
+ ), /* @__PURE__ */ React.createElement(
1635
+ Toggle,
1636
+ {
1637
+ variant: "outline",
1638
+ size: "floting",
1639
+ pressed: isUnderline,
1640
+ onPressedChange: () => {
1641
+ editor.dispatchCommand(FORMAT_TEXT_COMMAND, "underline");
1642
+ },
1643
+ tip: `Underline (${SHORTCUTS.UNDERLINE})`,
1644
+ type: "button",
1645
+ "aria-label": `Format text to underlined. Shortcut: ${SHORTCUTS.UNDERLINE}`
1646
+ },
1647
+ /* @__PURE__ */ React.createElement(UnderlineIcon, null)
1648
+ ), /* @__PURE__ */ React.createElement(
1649
+ Toggle,
1650
+ {
1651
+ variant: "outline",
1652
+ size: "floting",
1653
+ pressed: isCode,
1654
+ onPressedChange: () => {
1655
+ editor.dispatchCommand(FORMAT_TEXT_COMMAND, "code");
1656
+ },
1657
+ tip: `Insert code block (${SHORTCUTS.INSERT_CODE_BLOCK})`,
1658
+ type: "button",
1659
+ "aria-label": "Insert code block"
1660
+ },
1661
+ /* @__PURE__ */ React.createElement(Code, null)
1662
+ ), /* @__PURE__ */ React.createElement(
1663
+ Toggle,
1664
+ {
1665
+ variant: "outline",
1666
+ size: "floting",
1667
+ onPressedChange: insertLink,
1668
+ pressed: isLink,
1669
+ "aria-label": "Insert link",
1670
+ tip: `Insert link (${SHORTCUTS.INSERT_LINK})`,
1671
+ type: "button"
1672
+ },
1673
+ /* @__PURE__ */ React.createElement(Link, null)
1674
+ )),
1675
+ /* @__PURE__ */ React.createElement(
1676
+ Separator,
1677
+ {
1678
+ orientation: "vertical",
1679
+ className: "max-sm:h-[1px] max-sm:my-1 max-sm:w-5 h-5 mx-1"
1680
+ }
1681
+ ),
1682
+ /* @__PURE__ */ React.createElement(
1683
+ Color,
1684
+ {
1685
+ disabled: false,
1686
+ side: isSmall ? "right" : "bottom",
1687
+ sideOffset: isSmall ? 10 : 5,
1688
+ style: { height: "25px" },
1689
+ color: fontColor,
1690
+ bgColor,
1691
+ editor
1692
+ }
1693
+ ),
1694
+ /* @__PURE__ */ React.createElement(
1695
+ Separator,
1696
+ {
1697
+ orientation: "vertical",
1698
+ className: "max-sm:h-[1px] max-sm:my-1 max-sm:w-5 h-5 mx-1"
1699
+ }
1700
+ ),
1701
+ /* @__PURE__ */ React.createElement(
1702
+ TextFormat,
1703
+ {
1704
+ disabled: false,
1705
+ editor,
1706
+ ShowChevronsUpDown: false,
1707
+ side: isSmall ? "right" : "bottom",
1708
+ sideOffset: isSmall ? 10 : 5,
1709
+ style: { height: "2px" },
1710
+ toolbarState: {
1711
+ isLowercase,
1712
+ isUppercase,
1713
+ isCapitalize,
1714
+ isStrikethrough,
1715
+ isSubscript,
1716
+ isSuperscript
1717
+ }
1718
+ }
1719
+ )
1720
+ );
1721
+ }
1722
+
1723
+ // src/components/editor/plugins/FloatingTextFormatToolbarPlugin/index.tsx
1724
+ function useFloatingTextFormatToolbar(editor, anchorElem, setIsLinkEditMode) {
1725
+ const [isText, setIsText] = useState5(false);
1726
+ const [isLink, setIsLink] = useState5(false);
1727
+ const [isBold, setIsBold] = useState5(false);
1728
+ const [isItalic, setIsItalic] = useState5(false);
1729
+ const [isUnderline, setIsUnderline] = useState5(false);
1730
+ const [isStrikethrough, setIsStrikethrough] = useState5(false);
1731
+ const [isCode, setIsCode] = useState5(false);
1732
+ const [fontColor, setFontColor] = useState5("#000000");
1733
+ const [bgColor, setBgColor] = useState5("#ffffff");
1734
+ const [fontFamily, setFontFamily] = useState5("Arial");
1735
+ const [blockType, setBlockType] = useState5("paragraph");
1736
+ const [isUppercase, setIsUppercase] = useState5(false);
1737
+ const [isLowercase, setIsLowercase] = useState5(false);
1738
+ const [isCapitalize, setIsCapitalize] = useState5(false);
1739
+ const [isSubscript, setIsSubscript] = useState5(false);
1740
+ const [isSuperscript, setIsSuperscript] = useState5(false);
1741
+ const [rootType, setRootType] = useState5("root");
1742
+ const [textAlign, setTextAlign] = useState5(null);
1743
+ const [fontSize, setFontSize] = useState5("16px");
1744
+ const toolbarRef = useRef4(null);
1745
+ const updatePopup = useCallback3(() => {
1746
+ editor.getEditorState().read(() => {
1747
+ var _a;
1748
+ if (editor.isComposing()) {
1749
+ return;
1750
+ }
1751
+ const selection = $getSelection3();
1752
+ const nativeSelection = getDOMSelection2(editor._window);
1753
+ const rootElement = editor.getRootElement();
1754
+ const aiElement = document.querySelector(".AI-format");
1755
+ if (nativeSelection && nativeSelection.anchorNode instanceof HTMLElement && nativeSelection.anchorNode.closest(".dropdown-portal")) {
1756
+ return;
1757
+ }
1758
+ if (nativeSelection !== null && (!$isRangeSelection2(selection) || rootElement === null || !rootElement.contains(nativeSelection.anchorNode)) && !((_a = toolbarRef == null ? void 0 : toolbarRef.current) == null ? void 0 : _a.contains(nativeSelection.anchorNode)) && !(aiElement && aiElement.contains(nativeSelection.anchorNode))) {
1759
+ setIsText(false);
1760
+ return;
1761
+ }
1762
+ if (!$isRangeSelection2(selection)) {
1763
+ return;
1764
+ }
1765
+ const node = getSelectedNode(selection);
1766
+ setIsBold(selection.hasFormat("bold"));
1767
+ setIsItalic(selection.hasFormat("italic"));
1768
+ setIsUnderline(selection.hasFormat("underline"));
1769
+ setIsStrikethrough(selection.hasFormat("strikethrough"));
1770
+ setIsSubscript(selection.hasFormat("subscript"));
1771
+ setIsLowercase(selection.hasFormat("lowercase"));
1772
+ setIsUppercase(selection.hasFormat("uppercase"));
1773
+ setIsCapitalize(selection.hasFormat("capitalize"));
1774
+ setIsSubscript(selection.hasFormat("subscript"));
1775
+ setIsSuperscript(selection.hasFormat("superscript"));
1776
+ setIsCode(selection.hasFormat("code"));
1777
+ const size = $getSelectionStyleValueForProperty(
1778
+ selection,
1779
+ "font-size",
1780
+ "16px"
1781
+ );
1782
+ setFontSize(size);
1783
+ const alignment = $getSelectionStyleValueForProperty(
1784
+ selection,
1785
+ "text-align",
1786
+ "left"
1787
+ );
1788
+ setTextAlign(alignment);
1789
+ const parent = node.getParent();
1790
+ if ($isLinkNode(parent) || $isLinkNode(node)) {
1791
+ setIsLink(true);
1792
+ } else {
1793
+ setIsLink(false);
1794
+ }
1795
+ if (!$isCodeHighlightNode(selection.anchor.getNode()) && selection.getTextContent() !== "") {
1796
+ setIsText($isTextNode2(node) || $isParagraphNode(node));
1797
+ } else {
1798
+ setIsText(false);
1799
+ }
1800
+ const rawTextContent = selection.getTextContent().replace(/\n/g, "");
1801
+ if (!selection.isCollapsed() && rawTextContent === "") {
1802
+ setIsText(false);
1803
+ return;
1804
+ }
1805
+ setFontFamily(
1806
+ $getSelectionStyleValueForProperty(selection, "font-family", "Arial")
1807
+ );
1808
+ setFontColor($getSelectionStyleValueForProperty(selection, "color"));
1809
+ setBgColor(
1810
+ $getSelectionStyleValueForProperty(selection, "background-color")
1811
+ );
1812
+ const tableNode = $findMatchingParent(node, $isTableNode);
1813
+ if ($isTableNode(tableNode)) {
1814
+ setRootType("table");
1815
+ } else {
1816
+ setRootType("root");
1817
+ }
1818
+ const anchorNode = selection.anchor.getNode();
1819
+ let element = anchorNode.getKey() === "root" ? anchorNode : $findMatchingParent(anchorNode, (e) => {
1820
+ const parent2 = e.getParent();
1821
+ return parent2 !== null && $isRootOrShadowRoot(parent2);
1822
+ });
1823
+ if ($isListNode(element)) {
1824
+ const parentList = $getNearestNodeOfType(
1825
+ anchorNode,
1826
+ ListNode2
1827
+ );
1828
+ const type = parentList ? parentList.getListType() : element.getListType();
1829
+ setBlockType(type);
1830
+ } else {
1831
+ const type = $isHeadingNode(element) ? element.getTag() : (
1832
+ // @ts-ignore
1833
+ element.getType()
1834
+ );
1835
+ setBlockType(type);
1836
+ }
1837
+ });
1838
+ }, [editor]);
1839
+ useEffect5(() => {
1840
+ const handleSelectionChange = () => {
1841
+ if (toolbarRef.current && toolbarRef.current.contains(document.activeElement)) {
1842
+ return;
1843
+ }
1844
+ updatePopup();
1845
+ };
1846
+ document.addEventListener("selectionchange", handleSelectionChange);
1847
+ return () => {
1848
+ document.removeEventListener("selectionchange", handleSelectionChange);
1849
+ };
1850
+ }, [updatePopup]);
1851
+ useEffect5(() => {
1852
+ return mergeRegister2(
1853
+ editor.registerUpdateListener(() => {
1854
+ updatePopup();
1855
+ }),
1856
+ editor.registerRootListener(() => {
1857
+ if (editor.getRootElement() === null) {
1858
+ setIsText(false);
1859
+ }
1860
+ })
1861
+ );
1862
+ }, [editor, updatePopup]);
1863
+ if (!isText) {
1864
+ return null;
1865
+ }
1866
+ return createPortal(
1867
+ /* @__PURE__ */ React6.createElement("div", { ref: toolbarRef }, /* @__PURE__ */ React6.createElement(
1868
+ TextFormatFloatingToolbar,
1869
+ {
1870
+ editor,
1871
+ anchorElem,
1872
+ isLink,
1873
+ isBold,
1874
+ isItalic,
1875
+ isStrikethrough,
1876
+ isUnderline,
1877
+ isCode,
1878
+ fontColor,
1879
+ bgColor,
1880
+ blockType,
1881
+ fontFamily,
1882
+ setIsLinkEditMode,
1883
+ isUppercase,
1884
+ rootType,
1885
+ textAlign,
1886
+ isLowercase,
1887
+ isCapitalize,
1888
+ isSubscript,
1889
+ fontSize,
1890
+ isSuperscript
1891
+ }
1892
+ )),
1893
+ anchorElem
1894
+ );
1895
+ }
1896
+ function FloatingTextFormatToolbarPlugin({
1897
+ anchorElem = document.body,
1898
+ setIsLinkEditMode
1899
+ }) {
1900
+ const [editor] = useLexicalComposerContext();
1901
+ return useFloatingTextFormatToolbar(editor, anchorElem, setIsLinkEditMode);
1902
+ }
1903
+
1904
+ export {
1905
+ FloatingTextFormatToolbarPlugin
1906
+ };