@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,328 +0,0 @@
1
- import type {
2
- DOMConversionMap,
3
- DOMConversionOutput,
4
- DOMExportOutput,
5
- EditorConfig,
6
- LexicalEditor,
7
- LexicalNode,
8
- LexicalUpdateJSON,
9
- NodeKey,
10
- SerializedEditor,
11
- SerializedLexicalNode,
12
- Spread,
13
- } from "lexical";
14
- import type { JSX } from "react";
15
-
16
- import { $applyNodeReplacement, createEditor, DecoratorNode } from "lexical";
17
- import * as React from "react";
18
- import { Suspense } from "react";
19
-
20
- const ImageComponent = React.lazy(() => import("@/components/ui/image"));
21
- export type alignmentType =
22
- | "center"
23
- | "left"
24
- | "right"
25
- | "bottom"
26
- | "end"
27
- | "start";
28
-
29
- export interface ImagePayload {
30
- altText: string;
31
- caption?: LexicalEditor;
32
- height?: number;
33
- key?: NodeKey;
34
- maxWidth?: number;
35
- showCaption?: boolean;
36
- src: string;
37
- captionsEnabled?: boolean;
38
- alignment?: alignmentType;
39
- width?: number;
40
- rounded?: number;
41
- }
42
-
43
- function isGoogleDocCheckboxImg(img: HTMLImageElement): boolean {
44
- return (
45
- img.parentElement != null &&
46
- img.parentElement.tagName === "LI" &&
47
- img.previousSibling === null &&
48
- img.getAttribute("aria-roledescription") === "checkbox"
49
- );
50
- }
51
-
52
- function $convertImageElement(domNode: Node): null | DOMConversionOutput {
53
- const img = domNode as HTMLImageElement;
54
- if (img.src.startsWith("file:///") || isGoogleDocCheckboxImg(img)) {
55
- return null;
56
- }
57
- const { alt: altText, src, width, height } = img;
58
- const node = $createImageNode({
59
- altText,
60
- height,
61
- src,
62
- width,
63
- alignment: "center",
64
- rounded: 0,
65
- });
66
- return { node };
67
- }
68
-
69
- export type SerializedImageNode = Spread<
70
- {
71
- altText: string;
72
- caption: SerializedEditor;
73
- height?: number;
74
- maxWidth: number;
75
- showCaption: boolean;
76
- src: string;
77
- rounded?: number;
78
- alignment: alignmentType;
79
- width?: number;
80
- },
81
- SerializedLexicalNode
82
- >;
83
-
84
- export class ImageNode extends DecoratorNode<JSX.Element> {
85
- __src: string;
86
- __altText: string;
87
- __width: "inherit" | number;
88
- __height: "inherit" | number;
89
- __maxWidth: number;
90
- __showCaption: boolean;
91
- __caption: LexicalEditor;
92
- __captionsEnabled: boolean;
93
- __rounded: number;
94
- __alignment: alignmentType;
95
-
96
- static getType(): string {
97
- return "image";
98
- }
99
-
100
- static clone(node: ImageNode): ImageNode {
101
- return new ImageNode(
102
- node.__src,
103
- node.__altText,
104
- node.__maxWidth,
105
- node.__width,
106
- node.__height,
107
- node.__showCaption,
108
- node.__caption,
109
- node.__captionsEnabled,
110
- node.__key,
111
- node.__rounded,
112
- node.__alignment
113
- );
114
- }
115
-
116
- static importJSON(serializedNode: SerializedImageNode): ImageNode {
117
- const {
118
- altText,
119
- height,
120
- width,
121
- maxWidth,
122
- src,
123
- showCaption,
124
- alignment,
125
- rounded,
126
- } = serializedNode;
127
- return $createImageNode({
128
- altText,
129
- height,
130
- maxWidth,
131
- showCaption,
132
- src,
133
- width,
134
- rounded,
135
- alignment,
136
- }).updateFromJSON(serializedNode);
137
- }
138
- setAlignment(newAlignment: alignmentType) {
139
- const writable = this.getWritable();
140
- writable.__alignment = newAlignment;
141
- }
142
- getWidth(): number | "inherit" {
143
- return this.__width;
144
- }
145
- getHeight(): number | "inherit" {
146
- return this.__height;
147
- }
148
- setRounded(rounded: number): void {
149
- const writable = this.getWritable();
150
- writable.__rounded = rounded;
151
- }
152
- updateFromJSON(serializedNode: LexicalUpdateJSON<SerializedImageNode>): this {
153
- const node = super.updateFromJSON(serializedNode);
154
- const { caption } = serializedNode;
155
-
156
- const nestedEditor = node.__caption;
157
- const editorState = nestedEditor.parseEditorState(caption.editorState);
158
- if (!editorState.isEmpty()) {
159
- nestedEditor.setEditorState(editorState);
160
- }
161
- return node;
162
- }
163
-
164
- exportDOM(): DOMExportOutput {
165
- const element = document.createElement("img");
166
- element.setAttribute("src", this.__src);
167
- element.setAttribute("alt", this.__altText);
168
- element.setAttribute("width", this.__width.toString());
169
- element.setAttribute("height", this.__height.toString());
170
- return { element };
171
- }
172
-
173
- static importDOM(): DOMConversionMap | null {
174
- return {
175
- img: () => ({
176
- conversion: $convertImageElement,
177
- priority: 0,
178
- }),
179
- };
180
- }
181
- setSrc(src: string) {
182
- const self = this.getWritable();
183
- self.__src = src;
184
- }
185
-
186
- constructor(
187
- src: string,
188
- altText: string,
189
- maxWidth: number,
190
- width?: "inherit" | number,
191
- height?: "inherit" | number,
192
- showCaption?: boolean,
193
- caption?: LexicalEditor,
194
- captionsEnabled?: boolean,
195
- key?: NodeKey,
196
- rounded: number = 0,
197
- alignment: alignmentType = "center"
198
- ) {
199
- super(key);
200
- this.__src = src;
201
- this.__altText = altText;
202
- this.__maxWidth = maxWidth;
203
- this.__width = width || "inherit";
204
- this.__height = height || "inherit";
205
- this.__showCaption = showCaption || false;
206
- this.__alignment = alignment;
207
- this.__rounded = rounded;
208
- this.__caption =
209
- caption ||
210
- createEditor({
211
- nodes: [],
212
- });
213
- this.__captionsEnabled = captionsEnabled || captionsEnabled === undefined;
214
- }
215
-
216
- exportJSON(): SerializedImageNode {
217
- return {
218
- ...super.exportJSON(),
219
- altText: this.getAltText(),
220
- caption: this.__caption.toJSON(),
221
- height: this.__height === "inherit" ? 0 : this.__height,
222
- maxWidth: this.__maxWidth,
223
- showCaption: this.__showCaption,
224
- rounded: this.__rounded,
225
- alignment: this.__alignment,
226
- src: this.getSrc(),
227
- width: this.__width === "inherit" ? 0 : this.__width,
228
- };
229
- }
230
-
231
- setWidthAndHeight(
232
- width: "inherit" | number,
233
- height: "inherit" | number
234
- ): void {
235
- const writable = this.getWritable();
236
- writable.__width = width;
237
- writable.__height = height;
238
- }
239
-
240
- setShowCaption(showCaption: boolean): void {
241
- const writable = this.getWritable();
242
- writable.__showCaption = showCaption;
243
- }
244
-
245
- createDOM(config: EditorConfig): HTMLElement {
246
- const span = document.createElement("span");
247
- const theme = config.theme;
248
- const className = theme.image;
249
- if (className !== undefined) {
250
- span.className = className;
251
- }
252
- return span;
253
- }
254
-
255
- updateDOM(): false {
256
- return false;
257
- }
258
-
259
- getSrc(): string {
260
- return this.__src;
261
- }
262
-
263
- getAltText(): string {
264
- return this.__altText;
265
- }
266
-
267
- decorate(): JSX.Element {
268
- return (
269
- <Suspense fallback={null}>
270
- <div
271
- style={{
272
- textAlign: this.__alignment as React.CSSProperties["textAlign"],
273
- }}
274
- >
275
- <ImageComponent
276
- src={this.__src}
277
- altText={this.__altText}
278
- width={this.__width}
279
- height={this.__height}
280
- maxWidth={this.__maxWidth}
281
- nodeKey={this.getKey()}
282
- showCaption={this.__showCaption}
283
- caption={this.__caption}
284
- captionsEnabled={this.__captionsEnabled}
285
- resizable={true}
286
- rounded={this.__rounded}
287
- />
288
- </div>
289
- </Suspense>
290
- );
291
- }
292
- }
293
-
294
- export function $createImageNode({
295
- altText,
296
- height,
297
- maxWidth = 500,
298
- captionsEnabled,
299
- src,
300
- width,
301
- showCaption,
302
- caption,
303
- key,
304
- rounded,
305
- alignment,
306
- }: ImagePayload): ImageNode {
307
- return $applyNodeReplacement(
308
- new ImageNode(
309
- src,
310
- altText,
311
- maxWidth,
312
- width,
313
- height,
314
- showCaption,
315
- caption,
316
- captionsEnabled,
317
- key,
318
- rounded,
319
- alignment
320
- )
321
- );
322
- }
323
-
324
- export function $isImageNode(
325
- node: LexicalNode | null | undefined
326
- ): node is ImageNode {
327
- return node instanceof ImageNode;
328
- }
@@ -1,383 +0,0 @@
1
- /**
2
- * Copyright (c) Meta Platforms, Inc. and affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- *
7
- */
8
- import type {Position} from './InlineImageNode';
9
- import type {BaseSelection, LexicalEditor, NodeKey} from 'lexical';
10
- import type {JSX} from 'react';
11
-
12
- import './InlineImageNode.css';
13
-
14
- import {AutoFocusPlugin} from '@lexical/react/LexicalAutoFocusPlugin';
15
- import {useLexicalComposerContext} from '@lexical/react/LexicalComposerContext';
16
- import {LexicalErrorBoundary} from '@lexical/react/LexicalErrorBoundary';
17
- import {LexicalNestedComposer} from '@lexical/react/LexicalNestedComposer';
18
- import {RichTextPlugin} from '@lexical/react/LexicalRichTextPlugin';
19
- import {useLexicalEditable} from '@lexical/react/useLexicalEditable';
20
- import {useLexicalNodeSelection} from '@lexical/react/useLexicalNodeSelection';
21
- import {mergeRegister} from '@lexical/utils';
22
- import {
23
- $getNodeByKey,
24
- $getSelection,
25
- $isNodeSelection,
26
- $setSelection,
27
- CLICK_COMMAND,
28
- COMMAND_PRIORITY_LOW,
29
- DRAGSTART_COMMAND,
30
- KEY_ENTER_COMMAND,
31
- KEY_ESCAPE_COMMAND,
32
- SELECTION_CHANGE_COMMAND,
33
- } from 'lexical';
34
- import * as React from 'react';
35
- import {Suspense, useCallback, useEffect, useRef, useState} from 'react';
36
-
37
- // import useModal from '../../hooks/useModal';
38
- import LinkPlugin from '../../plugins/LinkPlugin';
39
- // import ContentEditable from '@/components/ui/ContentEditable';
40
- import {InlineImageNode} from './InlineImageNode';
41
- import { Button } from '@/components/ui/button';
42
- import TextInput from '@/components/ui/TextInput';
43
- import { ContentEditable } from '@lexical/react/LexicalContentEditable';
44
- import { DialogActions } from '@/components/ui/dialog/Dialog';
45
- import Select from '@/components/ui/Select';
46
- import useModal from '@/components/ui/models/use-model';
47
-
48
- const imageCache = new Set();
49
-
50
- function useSuspenseImage(src: string) {
51
- if (!imageCache.has(src)) {
52
- throw new Promise((resolve) => {
53
- const img = new Image();
54
- img.src = src;
55
- img.onload = () => {
56
- imageCache.add(src);
57
- resolve(null);
58
- };
59
- });
60
- }
61
- }
62
-
63
- function LazyImage({
64
- altText,
65
- className,
66
- imageRef,
67
- src,
68
- width,
69
- height,
70
- position,
71
- }: {
72
- altText: string;
73
- className: string | null;
74
- height: 'inherit' | number;
75
- imageRef: {current: null | HTMLImageElement};
76
- src: string;
77
- width: 'inherit' | number;
78
- position: Position;
79
- }): JSX.Element {
80
- useSuspenseImage(src);
81
- return (
82
- <img
83
- className={className || undefined}
84
- src={src}
85
- alt={altText}
86
- ref={imageRef}
87
- data-position={position}
88
- style={{
89
- display: 'block',
90
- height,
91
- width,
92
- }}
93
- draggable="false"
94
- />
95
- );
96
- }
97
-
98
- export function UpdateInlineImageDialog({
99
- activeEditor,
100
- nodeKey,
101
- onClose,
102
- }: {
103
- activeEditor: LexicalEditor;
104
- nodeKey: NodeKey;
105
- onClose: () => void;
106
- }): JSX.Element {
107
- const editorState = activeEditor.getEditorState();
108
- const node = editorState.read(
109
- () => $getNodeByKey(nodeKey) as InlineImageNode,
110
- );
111
- const [altText, setAltText] = useState(node.getAltText());
112
- const [showCaption, setShowCaption] = useState(node.getShowCaption());
113
- const [position, setPosition] = useState<Position>(node.getPosition());
114
-
115
- const handleShowCaptionChange = (e: React.ChangeEvent<HTMLInputElement>) => {
116
- setShowCaption(e.target.checked);
117
- };
118
-
119
- const handlePositionChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
120
- setPosition(e.target.value as Position);
121
- };
122
-
123
- const handleOnConfirm = () => {
124
- const payload = {altText, position, showCaption};
125
- if (node) {
126
- activeEditor.update(() => {
127
- node.update(payload);
128
- });
129
- }
130
- onClose();
131
- };
132
-
133
- return (
134
- <>
135
- <div style={{marginBottom: '1em'}}>
136
- <TextInput
137
- label="Alt Text"
138
- placeholder="Descriptive alternative text"
139
- onChange={setAltText}
140
- value={altText}
141
- data-test-id="image-modal-alt-text-input"
142
- />
143
- </div>
144
-
145
- <Select
146
- style={{marginBottom: '1em', width: '208px'}}
147
- value={position}
148
- label="Position"
149
- name="position"
150
- id="position-select"
151
- onChange={handlePositionChange}>
152
- <option value="left">Left</option>
153
- <option value="right">Right</option>
154
- <option value="full">Full Width</option>
155
- </Select>
156
-
157
- <div className="Input__wrapper">
158
- <input
159
- id="caption"
160
- type="checkbox"
161
- checked={showCaption}
162
- onChange={handleShowCaptionChange}
163
- />
164
- <label htmlFor="caption">Show Caption</label>
165
- </div>
166
-
167
- <DialogActions>
168
- <Button
169
- data-test-id="image-modal-file-upload-btn"
170
- onClick={() => handleOnConfirm()}>
171
- Confirm
172
- </Button>
173
- </DialogActions>
174
- </>
175
- );
176
- }
177
-
178
- export default function InlineImageComponent({
179
- src,
180
- altText,
181
- nodeKey,
182
- width,
183
- height,
184
- showCaption,
185
- caption,
186
- position,
187
- }: {
188
- altText: string;
189
- caption: LexicalEditor;
190
- height: 'inherit' | number;
191
- nodeKey: NodeKey;
192
- showCaption: boolean;
193
- src: string;
194
- width: 'inherit' | number;
195
- position: Position;
196
- }): JSX.Element {
197
- const [modal, showModal] = useModal();
198
- const imageRef = useRef<null | HTMLImageElement>(null);
199
- const buttonRef = useRef<HTMLButtonElement | null>(null);
200
- const [isSelected, setSelected, clearSelection] =
201
- useLexicalNodeSelection(nodeKey);
202
- const [editor] = useLexicalComposerContext();
203
- const [selection, setSelection] = useState<BaseSelection | null>(null);
204
- const activeEditorRef = useRef<LexicalEditor | null>(null);
205
- const isEditable = useLexicalEditable();
206
-
207
- const $onEnter = useCallback(
208
- (event: KeyboardEvent) => {
209
- const latestSelection = $getSelection();
210
- const buttonElem = buttonRef.current;
211
- if (
212
- isSelected &&
213
- $isNodeSelection(latestSelection) &&
214
- latestSelection.getNodes().length === 1
215
- ) {
216
- if (showCaption) {
217
- // Move focus into nested editor
218
- $setSelection(null);
219
- event.preventDefault();
220
- caption.focus();
221
- return true;
222
- } else if (
223
- buttonElem !== null &&
224
- buttonElem !== document.activeElement
225
- ) {
226
- event.preventDefault();
227
- buttonElem.focus();
228
- return true;
229
- }
230
- }
231
- return false;
232
- },
233
- [caption, isSelected, showCaption],
234
- );
235
-
236
- const $onEscape = useCallback(
237
- (event: KeyboardEvent) => {
238
- if (
239
- activeEditorRef.current === caption ||
240
- buttonRef.current === event.target
241
- ) {
242
- $setSelection(null);
243
- editor.update(() => {
244
- setSelected(true);
245
- const parentRootElement = editor.getRootElement();
246
- if (parentRootElement !== null) {
247
- parentRootElement.focus();
248
- }
249
- });
250
- return true;
251
- }
252
- return false;
253
- },
254
- [caption, editor, setSelected],
255
- );
256
-
257
- useEffect(() => {
258
- let isMounted = true;
259
- const unregister = mergeRegister(
260
- editor.registerUpdateListener(({editorState}) => {
261
- if (isMounted) {
262
- setSelection(editorState.read(() => $getSelection()));
263
- }
264
- }),
265
- editor.registerCommand(
266
- SELECTION_CHANGE_COMMAND,
267
- (_, activeEditor) => {
268
- activeEditorRef.current = activeEditor;
269
- return false;
270
- },
271
- COMMAND_PRIORITY_LOW,
272
- ),
273
- editor.registerCommand<MouseEvent>(
274
- CLICK_COMMAND,
275
- (payload) => {
276
- const event = payload;
277
- if (event.target === imageRef.current) {
278
- if (event.shiftKey) {
279
- setSelected(!isSelected);
280
- } else {
281
- clearSelection();
282
- setSelected(true);
283
- }
284
- return true;
285
- }
286
-
287
- return false;
288
- },
289
- COMMAND_PRIORITY_LOW,
290
- ),
291
- editor.registerCommand(
292
- DRAGSTART_COMMAND,
293
- (event) => {
294
- if (event.target === imageRef.current) {
295
- // TODO This is just a temporary workaround for FF to behave like other browsers.
296
- // Ideally, this handles drag & drop too (and all browsers).
297
- event.preventDefault();
298
- return true;
299
- }
300
- return false;
301
- },
302
- COMMAND_PRIORITY_LOW,
303
- ),
304
- editor.registerCommand(KEY_ENTER_COMMAND, $onEnter, COMMAND_PRIORITY_LOW),
305
- editor.registerCommand(
306
- KEY_ESCAPE_COMMAND,
307
- $onEscape,
308
- COMMAND_PRIORITY_LOW,
309
- ),
310
- );
311
- return () => {
312
- isMounted = false;
313
- unregister();
314
- };
315
- }, [
316
- clearSelection,
317
- editor,
318
- isSelected,
319
- nodeKey,
320
- $onEnter,
321
- $onEscape,
322
- setSelected,
323
- ]);
324
-
325
- const draggable = isSelected && $isNodeSelection(selection);
326
- const isFocused = isSelected && isEditable;
327
- return (
328
- <Suspense fallback={null}>
329
- <>
330
- <span draggable={draggable}>
331
- {isEditable && (
332
- <button
333
- className="image-edit-button"
334
- ref={buttonRef}
335
- onClick={() => {
336
- showModal('Update Inline Image', (onClose) => (
337
- <UpdateInlineImageDialog
338
- activeEditor={editor}
339
- nodeKey={nodeKey}
340
- onClose={onClose}
341
- />
342
- ));
343
- }}>
344
- Edit
345
- </button>
346
- )}
347
- <LazyImage
348
- className={
349
- isFocused
350
- ? `focused ${$isNodeSelection(selection) ? 'draggable' : ''}`
351
- : null
352
- }
353
- src={src}
354
- altText={altText}
355
- imageRef={imageRef}
356
- width={width}
357
- height={height}
358
- position={position}
359
- />
360
- </span>
361
- {showCaption && (
362
- <span className="image-caption-container">
363
- <LexicalNestedComposer initialEditor={caption}>
364
- <AutoFocusPlugin />
365
- <LinkPlugin />
366
- <RichTextPlugin
367
- contentEditable={
368
- <ContentEditable
369
- placeholder="Enter a caption..."
370
- placeholderClassName="InlineImageNode__placeholder"
371
- className="InlineImageNode__contentEditable"
372
- />
373
- }
374
- ErrorBoundary={LexicalErrorBoundary}
375
- />
376
- </LexicalNestedComposer>
377
- </span>
378
- )}
379
- </>
380
- {modal}
381
- </Suspense>
382
- );
383
- }