@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
@@ -1,264 +0,0 @@
1
- import { $getNodeByKey, LexicalEditor, NodeKey } from "lexical";
2
- import React, { useCallback, useEffect, useState } from "react";
3
- import { $isImageNode } from "../../editor/nodes/ImageNode";
4
- import { Button } from "@/components/ui/button";
5
- import {
6
- AlignCenterVertical,
7
- CaptionsIcon,
8
- Fullscreen,
9
- PanelLeftClose,
10
- Radius,
11
- } from "lucide-react";
12
- import { cn } from "@/lib/utils";
13
- import { Input } from "@/components/ui/input";
14
- import { Separator } from "@/components/ui/separator";
15
-
16
- export default function ImageToolBar({
17
- editor,
18
- nodeKey,
19
- height,
20
- width,
21
- }: {
22
- editor: LexicalEditor;
23
- nodeKey: NodeKey;
24
- height: string | number;
25
- width: string | number;
26
- }) {
27
- const [showResizeInput, setShowResizeInput] = useState(false);
28
- const [widthInput, setWidthInput] = useState(String(width));
29
- const [heightInput, setHeightInput] = useState(String(height));
30
- const [showInput, setShowInput] = useState(false);
31
-
32
- const toggleResizeInput = useCallback(() => {
33
- setShowResizeInput((prev) => !prev);
34
- }, []);
35
- const setShowCaption = () => {
36
- editor.update(() => {
37
- const node = $getNodeByKey(nodeKey);
38
- if ($isImageNode(node)) {
39
- const currentState = node.__showCaption;
40
- node.setShowCaption(!currentState);
41
- }
42
- });
43
- };
44
-
45
- const updateWidthAndHeight = useCallback(() => {
46
- const newWidth = Number(widthInput);
47
- const newHeight = Number(heightInput);
48
- console.log("update", newWidth, newHeight);
49
-
50
- if (isNaN(newWidth) || isNaN(newHeight)) return;
51
- if (newWidth > 990 || newHeight > 1800) return;
52
- if (newWidth < 140 || newHeight < 90) return;
53
-
54
- editor.update(() => {
55
- const node = $getNodeByKey(nodeKey);
56
- if ($isImageNode(node)) {
57
- node.setWidthAndHeight(newWidth, newHeight);
58
- }
59
- });
60
- }, [editor, nodeKey, widthInput, heightInput]);
61
-
62
- useEffect(() => {
63
- const debounceTimeout = setTimeout(() => {
64
- updateWidthAndHeight();
65
- }, 500);
66
- return () => clearTimeout(debounceTimeout);
67
- }, [widthInput, heightInput, updateWidthAndHeight]);
68
-
69
- const handleKeyDown = useCallback(
70
- (e: React.KeyboardEvent<HTMLInputElement>) => {
71
- if (e.key === "Enter") {
72
- updateWidthAndHeight();
73
- }
74
- },
75
- [updateWidthAndHeight]
76
- );
77
-
78
- const handleWidthChange = useCallback(
79
- (e: React.ChangeEvent<HTMLInputElement>) => {
80
- setWidthInput(e.target.value);
81
- },
82
- []
83
- );
84
-
85
- const handleHeightChange = useCallback(
86
- (e: React.ChangeEvent<HTMLInputElement>) => {
87
- setHeightInput(e.target.value);
88
- },
89
- []
90
- );
91
- useEffect(() => {
92
- setWidthInput(String(width));
93
- setHeightInput(String(height));
94
- }, [height, width]);
95
-
96
- const ChangeSideToLeft = useCallback(() => {
97
- editor.update(() => {
98
- const node = $getNodeByKey(nodeKey);
99
- if ($isImageNode(node)) {
100
- node.setAlignment("start");
101
- }
102
- });
103
- }, [editor, nodeKey]);
104
-
105
- const ChangeSideToCenter = useCallback(() => {
106
- editor.update(() => {
107
- const node = $getNodeByKey(nodeKey);
108
- if ($isImageNode(node)) {
109
- node.setAlignment("center");
110
- }
111
- });
112
- }, [editor, nodeKey]);
113
-
114
- const ChangeSideToRight = useCallback(() => {
115
- editor.update(() => {
116
- const node = $getNodeByKey(nodeKey);
117
- if ($isImageNode(node)) {
118
- node.setAlignment("end");
119
- }
120
- });
121
- }, [editor, nodeKey]);
122
- const ChangeRounded = useCallback(
123
- (event: React.ChangeEvent<HTMLInputElement>) => {
124
- editor.update(() => {
125
- const node = $getNodeByKey(nodeKey);
126
- if ($isImageNode(node)) {
127
- const roundedValue = parseInt(event.target.value);
128
- node.setRounded(roundedValue);
129
- }
130
- });
131
- },
132
- [editor, nodeKey]
133
- );
134
- return (
135
- <div className="flex flex-row items-center z-50 gap-x-2 absolute top-1 left-1 group-hover:opacity-100 duration-500 opacity-0 transition-all">
136
- <div className="p-1 rounded-sm bg-background/40 flex flex-row items-center justify-between">
137
- <div className="flex flex-row items-center">
138
- <Button
139
- onClick={toggleResizeInput}
140
- tip="Resize image"
141
- variant={"ghost"}
142
- size={"sm"}
143
- className="p-1 w-6 h-6 "
144
- >
145
- <Fullscreen className="size-2" />
146
- </Button>
147
- <div
148
- className={cn(
149
- "transition-all duration-500 ease-in-out",
150
- showResizeInput ? "w-[30px] mx-1" : "w-0"
151
- )}
152
- >
153
- <Input
154
- type="number"
155
- placeholder="0px"
156
- max={990}
157
- min={120}
158
- value={widthInput}
159
- onChange={handleWidthChange}
160
- onKeyDown={handleKeyDown}
161
- className={cn(
162
- "h-5 px-0.5 w-full rounded-sm text-xs outline-none transition-opacity duration-300 ease-in-out",
163
- showResizeInput ? "opacity-100" : "opacity-0"
164
- )}
165
- />
166
- </div>
167
- <div
168
- className={cn(
169
- "transition-all duration-500 ease-in-out",
170
- showResizeInput ? "w-[30px]" : "w-0"
171
- )}
172
- >
173
- <Input
174
- type="number"
175
- placeholder="0px"
176
- max={1800}
177
- min={120}
178
- value={heightInput}
179
- onChange={handleHeightChange}
180
- onKeyDown={handleKeyDown}
181
- className={cn(
182
- "h-5 px-0.5 w-full text-xs rounded-sm outline-none transition-opacity duration-300 ease-in-out",
183
- showResizeInput ? "opacity-100" : "opacity-0"
184
- )}
185
- />
186
- </div>
187
- </div>
188
- <Separator orientation="vertical" className="mx-1 h-5" />
189
- <div className="flex flex-row items-center gap-x-1">
190
- <Button
191
- onClick={ChangeSideToLeft}
192
- variant={"ghost"}
193
- size={"sm"}
194
- tip="move left"
195
- className="w-6 h-6 p-1 "
196
- >
197
- <PanelLeftClose />
198
- </Button>
199
- <Button
200
- size={"sm"}
201
- variant={"ghost"}
202
- onClick={ChangeSideToCenter}
203
- className=" mx-1 w-6 h-6 p-1 opacity-[0.70] hover:opacity-100 transition-opacity"
204
- tip="move center"
205
- >
206
- <AlignCenterVertical />
207
- </Button>
208
- <Button
209
- size={"sm"}
210
- variant={"ghost"}
211
- onClick={ChangeSideToRight}
212
- className=" w-6 h-6 p-1 opacity-[0.70] hover:opacity-100 transition-opacity"
213
- tip="move right"
214
- >
215
- <PanelLeftClose />
216
- </Button>
217
- </div>
218
- <Separator orientation="vertical" className="mx-1 h-5" />
219
-
220
- <Button
221
- size={"sm"}
222
- variant={"ghost"}
223
- onClick={() => {
224
- setShowInput(!showInput);
225
- }}
226
- className=" w-6 h-6 p-1 opacity-[0.70] hover:opacity-100 transition-opacity"
227
- tip="border radius"
228
- >
229
- <Radius />
230
- </Button>
231
- <div
232
- className={cn(
233
- "overflow-hidden transition-all duration-500 ease-in-out ",
234
- showInput ? "w-[60px]" : "w-0"
235
- )}
236
- >
237
- <Input
238
- type="range"
239
- min="0"
240
- max="120"
241
- defaultValue="0"
242
- onChange={ChangeRounded}
243
- className={cn(
244
- "h-5 px-1 py-0 transition-opacity duration-300 ease-in-out",
245
- showInput ? "opacity-100" : "opacity-0"
246
- )}
247
- />
248
- </div>
249
-
250
- <Separator orientation="vertical" className="mx-1 h-5" />
251
-
252
- <Button
253
- size={"sm"}
254
- variant={"ghost"}
255
- onClick={setShowCaption}
256
- className=" w-6 h-6 p-1 opacity-[0.70] hover:opacity-100 transition-opacity"
257
- tip="add caption"
258
- >
259
- <CaptionsIcon />
260
- </Button>
261
- </div>
262
- </div>
263
- );
264
- }
@@ -1,408 +0,0 @@
1
- import type {
2
- BaseSelection,
3
- LexicalCommand,
4
- LexicalEditor,
5
- NodeKey,
6
- } from "lexical";
7
- import type { JSX } from "react";
8
-
9
- import { LinkNode } from "@lexical/link";
10
- import { AutoFocusPlugin } from "@lexical/react/LexicalAutoFocusPlugin";
11
- import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
12
- import { LexicalErrorBoundary } from "@lexical/react/LexicalErrorBoundary";
13
- import { HistoryPlugin } from "@lexical/react/LexicalHistoryPlugin";
14
- import { LexicalNestedComposer } from "@lexical/react/LexicalNestedComposer";
15
- import { RichTextPlugin } from "@lexical/react/LexicalRichTextPlugin";
16
- import { useLexicalEditable } from "@lexical/react/useLexicalEditable";
17
- import { useLexicalNodeSelection } from "@lexical/react/useLexicalNodeSelection";
18
- import { mergeRegister } from "@lexical/utils";
19
- import {
20
- $getNodeByKey,
21
- $getSelection,
22
- $isNodeSelection,
23
- $isRangeSelection,
24
- $setSelection,
25
- CLICK_COMMAND,
26
- COMMAND_PRIORITY_LOW,
27
- createCommand,
28
- DRAGSTART_COMMAND,
29
- KEY_BACKSPACE_COMMAND,
30
- KEY_DELETE_COMMAND,
31
- KEY_ENTER_COMMAND,
32
- KEY_ESCAPE_COMMAND,
33
- LineBreakNode,
34
- ParagraphNode,
35
- RootNode,
36
- SELECTION_CHANGE_COMMAND,
37
- TextNode,
38
- } from "lexical";
39
- import * as React from "react";
40
- import { Suspense, useCallback, useEffect, useRef, useState } from "react";
41
- import { $isImageNode } from "../../editor/nodes/ImageNode";
42
- import { useSharedHistoryContext } from "@/components/providers/SharedHistoryContext";
43
- import ErrorImage from "./error-image";
44
- import { LinkPlugin } from "@lexical/react/LexicalLinkPlugin";
45
- import { ContentEditable } from "@lexical/react/LexicalContentEditable";
46
- import ImageResizer from "./image-resizer";
47
- import LazyImage from "./lazy-image";
48
- import LazyVideo from "./lazy-video";
49
- import ImageToolBar from "./image-toolbar";
50
-
51
- export const RIGHT_CLICK_IMAGE_COMMAND: LexicalCommand<MouseEvent> =
52
- createCommand("RIGHT_CLICK_IMAGE_COMMAND");
53
-
54
- export default function ImageComponent({
55
- src,
56
- altText,
57
- nodeKey,
58
- width,
59
- height,
60
- maxWidth,
61
- resizable,
62
- showCaption,
63
- caption,
64
- rounded,
65
- }: {
66
- altText: string;
67
- caption: LexicalEditor;
68
- height: "inherit" | number;
69
- maxWidth: number;
70
- nodeKey: NodeKey;
71
- resizable: boolean;
72
- showCaption: boolean;
73
- src: string;
74
- width: "inherit" | number;
75
- rounded: number;
76
- captionsEnabled: boolean;
77
- }): JSX.Element {
78
- const MediaRef = useRef<HTMLImageElement | HTMLVideoElement | null>(null); // Updated type
79
- const buttonRef = useRef<HTMLButtonElement | null>(null);
80
- const [isSelected, setSelected, clearSelection] =
81
- useLexicalNodeSelection(nodeKey);
82
- const [isResizing, setIsResizing] = useState<boolean>(false);
83
- const [editor] = useLexicalComposerContext();
84
- const [selection, setSelection] = useState<BaseSelection | null>(null);
85
- const activeEditorRef = useRef<LexicalEditor | null>(null);
86
- const [isLoadError, setIsLoadError] = useState<boolean>(false);
87
- const isEditable = useLexicalEditable();
88
- const [MediaType, setMediaType] = useState<"IMAGE" | "VIDEO">("IMAGE");
89
-
90
- const $onDelete = useCallback(
91
- (payload: KeyboardEvent) => {
92
- const deleteSelection = $getSelection();
93
- if (isSelected && $isNodeSelection(deleteSelection)) {
94
- const event: KeyboardEvent = payload;
95
- event.preventDefault();
96
- deleteSelection.getNodes().forEach((node) => {
97
- if ($isImageNode(node)) {
98
- node.remove();
99
- }
100
- });
101
- }
102
- return false;
103
- },
104
- [isSelected]
105
- );
106
-
107
- const $onEnter = useCallback(
108
- (event: KeyboardEvent) => {
109
- const latestSelection = $getSelection();
110
- const buttonElem = buttonRef.current;
111
- if (
112
- isSelected &&
113
- $isNodeSelection(latestSelection) &&
114
- latestSelection.getNodes().length === 1
115
- ) {
116
- if (showCaption) {
117
- // Move focus into nested editor
118
- $setSelection(null);
119
- event.preventDefault();
120
- caption.focus();
121
- return true;
122
- } else if (
123
- buttonElem !== null &&
124
- buttonElem !== document.activeElement
125
- ) {
126
- event.preventDefault();
127
- buttonElem.focus();
128
- return true;
129
- }
130
- }
131
- return false;
132
- },
133
- [caption, isSelected, showCaption]
134
- );
135
-
136
- const $onEscape = useCallback(
137
- (event: KeyboardEvent) => {
138
- if (
139
- activeEditorRef.current === caption ||
140
- buttonRef.current === event.target
141
- ) {
142
- $setSelection(null);
143
- editor.update(() => {
144
- setSelected(true);
145
- const parentRootElement = editor.getRootElement();
146
- if (parentRootElement !== null) {
147
- parentRootElement.focus();
148
- }
149
- });
150
- return true;
151
- }
152
- return false;
153
- },
154
- [caption, editor, setSelected]
155
- );
156
-
157
- const onClick = useCallback(
158
- (payload: MouseEvent) => {
159
- const event = payload;
160
-
161
- if (isResizing) {
162
- return true;
163
- }
164
- if (event.target === MediaRef.current) {
165
- if (event.shiftKey) {
166
- setSelected(!isSelected);
167
- } else {
168
- clearSelection();
169
- setSelected(true);
170
- }
171
- return true;
172
- }
173
-
174
- return false;
175
- },
176
- [isResizing, isSelected, setSelected, clearSelection]
177
- );
178
-
179
- const onRightClick = useCallback(
180
- (event: MouseEvent): void => {
181
- editor.getEditorState().read(() => {
182
- const latestSelection = $getSelection();
183
- const domElement = event.target as HTMLElement;
184
- if (
185
- (domElement.tagName === "IMG" || domElement.tagName === "VIDEO") &&
186
- $isRangeSelection(latestSelection) &&
187
- latestSelection.getNodes().length === 1
188
- ) {
189
- editor.dispatchCommand(
190
- RIGHT_CLICK_IMAGE_COMMAND,
191
- event as MouseEvent
192
- );
193
- }
194
- });
195
- },
196
- [editor]
197
- );
198
-
199
- useEffect(() => {
200
- let isMounted = true;
201
- const rootElement = editor.getRootElement();
202
- const unregister = mergeRegister(
203
- editor.registerUpdateListener(({ editorState }) => {
204
- if (isMounted) {
205
- setSelection(editorState.read(() => $getSelection()));
206
- }
207
- }),
208
- editor.registerCommand(
209
- SELECTION_CHANGE_COMMAND,
210
- (_, activeEditor) => {
211
- activeEditorRef.current = activeEditor;
212
- return false;
213
- },
214
- COMMAND_PRIORITY_LOW
215
- ),
216
- editor.registerCommand<MouseEvent>(
217
- CLICK_COMMAND,
218
- onClick,
219
- COMMAND_PRIORITY_LOW
220
- ),
221
- editor.registerCommand<MouseEvent>(
222
- RIGHT_CLICK_IMAGE_COMMAND,
223
- onClick,
224
- COMMAND_PRIORITY_LOW
225
- ),
226
- editor.registerCommand(
227
- DRAGSTART_COMMAND,
228
- (event) => {
229
- if (event.target === MediaRef.current) {
230
- event.preventDefault();
231
- return true;
232
- }
233
- return false;
234
- },
235
- COMMAND_PRIORITY_LOW
236
- ),
237
- editor.registerCommand(
238
- KEY_DELETE_COMMAND,
239
- $onDelete,
240
- COMMAND_PRIORITY_LOW
241
- ),
242
- editor.registerCommand(
243
- KEY_BACKSPACE_COMMAND,
244
- $onDelete,
245
- COMMAND_PRIORITY_LOW
246
- ),
247
- editor.registerCommand(KEY_ENTER_COMMAND, $onEnter, COMMAND_PRIORITY_LOW),
248
- editor.registerCommand(
249
- KEY_ESCAPE_COMMAND,
250
- $onEscape,
251
- COMMAND_PRIORITY_LOW
252
- )
253
- );
254
-
255
- rootElement?.addEventListener("contextmenu", onRightClick);
256
-
257
- return () => {
258
- isMounted = false;
259
- unregister();
260
- rootElement?.removeEventListener("contextmenu", onRightClick);
261
- };
262
- }, [
263
- clearSelection,
264
- editor,
265
- isResizing,
266
- isSelected,
267
- nodeKey,
268
- $onDelete,
269
- $onEnter,
270
- $onEscape,
271
- onClick,
272
- onRightClick,
273
- setSelected,
274
- ]);
275
-
276
- useEffect(() => {
277
- if (src.endsWith(".mp4")) {
278
- setMediaType("VIDEO");
279
- } else if (
280
- src.endsWith(".jpg") ||
281
- src.endsWith(".jpeg") ||
282
- src.endsWith(".png")
283
- ) {
284
- setMediaType("IMAGE");
285
- }
286
- }, [src]);
287
-
288
- const onResizeEnd = (
289
- nextWidth: "inherit" | number,
290
- nextHeight: "inherit" | number
291
- ) => {
292
- setTimeout(() => {
293
- setIsResizing(false);
294
- }, 200);
295
-
296
- editor.update(() => {
297
- const node = $getNodeByKey(nodeKey);
298
- if ($isImageNode(node)) {
299
- node.setWidthAndHeight(nextWidth, nextHeight);
300
- }
301
- });
302
- };
303
-
304
- const onResizeStart = () => {
305
- setIsResizing(true);
306
- };
307
-
308
- const { historyState } = useSharedHistoryContext();
309
-
310
- const draggable = isSelected && $isNodeSelection(selection) && !isResizing;
311
- const isFocused = (isSelected || isResizing) && isEditable;
312
-
313
- return (
314
- <Suspense fallback={null}>
315
- <div className="relative inline-block group">
316
- <div draggable={draggable}>
317
- {isLoadError ? (
318
- <ErrorImage />
319
- ) : (
320
- <>
321
- {MediaType === "IMAGE" ? (
322
- <LazyImage
323
- style={{
324
- width: width === "inherit" ? "400px" : `${width}px`,
325
- height: height === "inherit" ? "400px" : `${height}px`,
326
- borderRadius: `${rounded}px`,
327
- }}
328
- src={src}
329
- altText={altText}
330
- imageRef={MediaRef as React.RefObject<HTMLImageElement>}
331
- onError={() => setIsLoadError(true)}
332
- />
333
- ) : (
334
- <LazyVideo
335
- src={src}
336
- style={{
337
- width: width === "inherit" ? "800px" : `${width}px`,
338
- height: height === "inherit" ? "450px" : `${height}px`,
339
- borderRadius: `${rounded}px`,
340
- }}
341
- videoRef={MediaRef as React.RefObject<HTMLVideoElement>}
342
- onError={() => setIsLoadError(true)}
343
- rounded={rounded}
344
- controls={true}
345
- />
346
- )}
347
- </>
348
- )}
349
- </div>
350
- {showCaption && (
351
- <div>
352
- <LexicalNestedComposer
353
- initialEditor={caption}
354
- initialNodes={[
355
- RootNode,
356
- TextNode,
357
- LineBreakNode,
358
- ParagraphNode,
359
- LinkNode,
360
- ]}
361
- >
362
- <AutoFocusPlugin />
363
- <LinkPlugin />
364
- <HistoryPlugin externalHistoryState={historyState} />
365
- <RichTextPlugin
366
- contentEditable={
367
- <ContentEditable
368
- aria-placeholder="Enter a caption..."
369
- placeholder={() => (
370
- <span
371
- className="
372
- color-[#999] text-xs overflow-hidden absolute text-ellipsis
373
- select-none text-nowrap inline-block pointer-events-none
374
- transform -translate-x-1/2 -translate-y-1/2 bottom-[-8px]
375
- "
376
- >
377
- Enter a caption...
378
- </span>
379
- )}
380
- className="text-center relative text-xs text-muted-foreground outline-none"
381
- />
382
- }
383
- ErrorBoundary={LexicalErrorBoundary}
384
- />
385
- </LexicalNestedComposer>
386
- </div>
387
- )}
388
- {isEditable && !isResizing && (
389
- <ImageToolBar
390
- width={width}
391
- height={height}
392
- editor={editor}
393
- nodeKey={nodeKey}
394
- />
395
- )}
396
-
397
- {resizable && $isNodeSelection(selection) && isFocused && (
398
- <ImageResizer
399
- editor={editor}
400
- MediaRef={MediaRef}
401
- onResizeStart={onResizeStart}
402
- onResizeEnd={onResizeEnd}
403
- />
404
- )}
405
- </div>
406
- </Suspense>
407
- );
408
- }