@collabchron/notiq 0.2.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.
- package/LICENSE +21 -0
- package/README.md +230 -39
- package/dist/CodeActionMenuPlugin-EINOY4U4.mjs +15 -0
- package/dist/DynamicBlockComponent-NRQJ4WW4.mjs +161 -0
- package/dist/EquationComponent-CB6DFIHV.mjs +154 -0
- package/dist/ExcalidrawComponent-XW6646OH.mjs +528 -0
- package/dist/ExcalidrawPlugin-ZFHT62IF.mjs +14 -0
- package/dist/ExportPlugin-V2RLM63S.mjs +11 -0
- package/dist/FloatingLinkEditorPlugin-TRTCMSP4.mjs +12 -0
- package/dist/FloatingTextFormatToolbarPlugin-F2GY6LMI.mjs +30 -0
- package/dist/HintComponet-BRL6EAMS.mjs +217 -0
- package/dist/InlineImageComponent-UWIUWBHI.mjs +453 -0
- package/dist/MobileToolbar-BOOZAMQE.mjs +268 -0
- package/dist/SlashCommand-GMT5JI33.mjs +28 -0
- package/dist/StoryBuilderComponent-JGDBM5JU.mjs +562 -0
- package/{src/components/editor/plugins/TableCellActionMenuPlugin/index.tsx → dist/TableCellActionMenuPlugin-PGK2K3VG.mjs} +667 -759
- package/{src/components/editor/plugins/TableHoverActionsPlugin/index.tsx → dist/TableHoverActionsPlugin-GJVE6VRW.mjs} +258 -314
- package/dist/TemplatePlugin-ZD3QEVTI.mjs +9 -0
- package/dist/ToolbarPlugin-7TOZRD2R.mjs +1547 -0
- package/dist/babel-JZ2EV6AX.mjs +7233 -0
- package/dist/background-color-XZTYLGO2.mjs +362 -0
- package/dist/block-format-YJCV2DIY.mjs +15 -0
- package/dist/chunk-2FNEAMSP.mjs +127 -0
- package/dist/chunk-3CPBODXA.mjs +84 -0
- package/dist/chunk-3G37YKTV.mjs +83 -0
- package/dist/chunk-3JVFG7ER.mjs +184 -0
- package/dist/chunk-456TN7IM.mjs +110 -0
- package/dist/chunk-4EXYCTGJ.mjs +27 -0
- package/{src/utils/getSelectedNode.ts → dist/chunk-4HBCVSE6.mjs} +26 -27
- package/dist/chunk-4MEDW3T6.mjs +125 -0
- package/dist/chunk-4VWFVWYP.mjs +36 -0
- package/dist/chunk-5BAKY5KN.mjs +84 -0
- package/dist/chunk-5QSNIVIG.mjs +333 -0
- package/dist/chunk-64Z3FI7T.mjs +37 -0
- package/{src/components/editor/nodes/Stepper/index.tsx → dist/chunk-6RNZQOH2.mjs} +214 -260
- package/dist/chunk-77KXU36M.mjs +64 -0
- package/dist/chunk-77UA6HYR.mjs +165 -0
- package/dist/chunk-7NZAPJ4G.mjs +102 -0
- package/dist/chunk-7VUMHWWL.mjs +152 -0
- package/dist/chunk-AMMKBSST.mjs +1256 -0
- package/dist/chunk-BIU7WTLX.mjs +95 -0
- package/dist/chunk-EGMI62PP.mjs +83 -0
- package/dist/chunk-EHNQD5KO.mjs +88 -0
- package/dist/chunk-FSM26655.mjs +37 -0
- package/{src/components/editor/nodes/Hint/index.tsx → dist/chunk-G53GLEAY.mjs} +158 -190
- package/dist/chunk-GK35L7UY.mjs +28 -0
- package/dist/chunk-GXYD4VZM.mjs +193 -0
- package/dist/chunk-GYIOYVCN.mjs +538 -0
- package/dist/chunk-GZPNVR7L.mjs +157 -0
- package/dist/chunk-JXDPPUJI.mjs +52 -0
- package/dist/chunk-K36V4SIW.mjs +141 -0
- package/dist/chunk-KJ6AJ44Q.mjs +128 -0
- package/dist/chunk-KJV3FAZ7.mjs +142 -0
- package/{src/components/editor/plugins/ImagesPlugin/index.tsx → dist/chunk-LGG4IUIA.mjs} +189 -222
- package/dist/chunk-LQN3CMKV.mjs +1906 -0
- package/dist/chunk-N3WN46VL.mjs +236 -0
- package/dist/chunk-PBD6LMLC.mjs +366 -0
- package/dist/chunk-POGRR73N.mjs +33 -0
- package/{src/components/editor/utils/editorFormatting.ts → dist/chunk-PZSUSXQG.mjs} +238 -282
- package/dist/chunk-QEIFVK5M.mjs +29 -0
- package/dist/chunk-QHIQKMVN.mjs +427 -0
- package/dist/chunk-TCYK7DM7.mjs +36 -0
- package/dist/chunk-TTHQCW5F.mjs +47 -0
- package/dist/chunk-U47ABU5Z.mjs +53 -0
- package/dist/chunk-WDG7J2DY.mjs +116 -0
- package/dist/chunk-WJRHXI2C.mjs +733 -0
- package/dist/chunk-XLER2DHM.mjs +357 -0
- package/dist/chunk-XWC4TK2N.mjs +315 -0
- package/dist/chunk-YHPNOWFH.mjs +15 -0
- package/dist/chunk-YKC3SO4Z.mjs +32 -0
- package/dist/chunk-YMBXLRW5.mjs +374 -0
- package/dist/chunk-YPHOEJ46.mjs +64 -0
- package/dist/chunk-YUDCJRJM.mjs +25 -0
- package/dist/chunk-Z4EWP7BI.mjs +65 -0
- package/dist/chunk-ZB5LZQKC.mjs +191 -0
- package/dist/chunk-ZJRKATOJ.mjs +65 -0
- package/dist/color-BPKOPQKN.mjs +12 -0
- package/dist/estree-XC56IUFX.mjs +4414 -0
- package/dist/font-FEZ3GKSF.mjs +13 -0
- package/dist/font-size-EK775WRH.mjs +15 -0
- package/dist/html-S3ACX7NI.mjs +2738 -0
- package/dist/image-2PJIAYAT.mjs +993 -0
- package/dist/index.d.mts +145 -0
- package/dist/index.d.ts +145 -0
- package/dist/index.js +57855 -0
- package/dist/index.mjs +1790 -0
- package/dist/insert-gif-SAIDYURE.mjs +100 -0
- package/dist/insert-image-U3RJN3OW.mjs +259 -0
- package/dist/insert-node-5P2CRJ7S.mjs +201 -0
- package/dist/insert-poll-HCPM7MO6.mjs +33 -0
- package/dist/insert-table-24XYUS2W.mjs +66 -0
- package/dist/markdown-SNVBOSRA.mjs +3487 -0
- package/dist/poll-component-2R4MDLHS.mjs +303 -0
- package/dist/postcss-ONF3VDIM.mjs +5051 -0
- package/dist/standalone-EOIALU3M.mjs +2373 -0
- package/dist/stepper-FSARL6X6.mjs +304 -0
- package/dist/styles/notiq.css +1149 -0
- package/dist/text-align-VLECWO4H.mjs +118 -0
- package/dist/text-format-BG5WOOPZ.mjs +16 -0
- package/dist/typescript-AMPI6OVS.mjs +13135 -0
- package/package.json +94 -10
- package/src/styles/notiq.css +1149 -0
- package/src/styles/tailwind-plugin.ts +134 -0
- package/components.json +0 -21
- package/eslint.config.mjs +0 -16
- package/next.config.ts +0 -12
- package/postcss.config.mjs +0 -5
- package/public/file.svg +0 -1
- package/public/globe.svg +0 -1
- package/public/images/icons/plus.svg +0 -10
- package/public/next.svg +0 -1
- package/public/vercel.svg +0 -1
- package/public/window.svg +0 -1
- package/src/app/actions.ts +0 -2
- package/src/app/api/ai/route.ts +0 -175
- package/src/app/api/edgestore/[...edgestore]/route.ts +0 -28
- package/src/app/favicon.ico +0 -0
- package/src/app/globals.css +0 -205
- package/src/app/layout.tsx +0 -38
- package/src/app/page.tsx +0 -12
- package/src/components/editor/Core.tsx +0 -220
- package/src/components/editor/hooks/instructions-messages.ts +0 -300
- package/src/components/editor/hooks/use-mobile.ts +0 -19
- package/src/components/editor/hooks/useReport.ts +0 -67
- package/src/components/editor/hooks/useResizeObservert.ts +0 -22
- package/src/components/editor/index.tsx +0 -39
- package/src/components/editor/lexical-on-change.tsx +0 -28
- package/src/components/editor/nodes/CollapsibleNode/CollapsibleContainerNode.ts +0 -92
- package/src/components/editor/nodes/CollapsibleNode/CollapsibleContentNode.ts +0 -65
- package/src/components/editor/nodes/CollapsibleNode/CollapsibleTitleNode.ts +0 -105
- package/src/components/editor/nodes/EquationNode/EquationComponent.tsx +0 -143
- package/src/components/editor/nodes/EquationNode/EquationNode.tsx +0 -170
- package/src/components/editor/nodes/ExcalidrawNode/ExcalidrawComponent.tsx +0 -228
- package/src/components/editor/nodes/ExcalidrawNode/ExcalidrawImage.tsx +0 -137
- package/src/components/editor/nodes/ExcalidrawNode/ImageResizer.tsx +0 -317
- package/src/components/editor/nodes/ExcalidrawNode/index.tsx +0 -204
- package/src/components/editor/nodes/FigmaNode/FigmaNode.tsx +0 -134
- package/src/components/editor/nodes/Hint/HintComponet.tsx +0 -221
- package/src/components/editor/nodes/ImageNode/index.tsx +0 -328
- package/src/components/editor/nodes/InlineImageNode/InlineImageComponent.tsx +0 -383
- package/src/components/editor/nodes/InlineImageNode/InlineImageNode.css +0 -94
- package/src/components/editor/nodes/InlineImageNode/InlineImageNode.tsx +0 -309
- package/src/components/editor/nodes/LayoutNode/LayoutContainerNode.ts +0 -146
- package/src/components/editor/nodes/LayoutNode/LayoutItemNode.ts +0 -79
- package/src/components/editor/nodes/PollNode/index.tsx +0 -204
- package/src/components/editor/nodes/TweetNode/index.tsx +0 -214
- package/src/components/editor/nodes/index.ts +0 -81
- package/src/components/editor/plugins/AutoEmbedPlugin/index.tsx +0 -350
- package/src/components/editor/plugins/AutoLinkPlugin/index.tsx +0 -56
- package/src/components/editor/plugins/CodeActionMenuPlugin/components/CopyButton.tsx +0 -70
- package/src/components/editor/plugins/CodeActionMenuPlugin/components/PrettierButton.tsx +0 -192
- package/src/components/editor/plugins/CodeActionMenuPlugin/index.tsx +0 -217
- package/src/components/editor/plugins/CodeActionMenuPlugin/utils.ts +0 -26
- package/src/components/editor/plugins/CodeHighlightPlugin/index.ts +0 -21
- package/src/components/editor/plugins/CollapsiblePlugin/Collapsible.css +0 -76
- package/src/components/editor/plugins/CollapsiblePlugin/index.ts +0 -228
- package/src/components/editor/plugins/DragDropPastePlugin/index.tsx +0 -44
- package/src/components/editor/plugins/DraggableBlockPlugin/index.tsx +0 -52
- package/src/components/editor/plugins/EquationsPlugin/index.tsx +0 -85
- package/src/components/editor/plugins/ExcalidrawPlugin/index.tsx +0 -98
- package/src/components/editor/plugins/FigmaPlugin/index.tsx +0 -42
- package/src/components/editor/plugins/FloatingLinkEditorPlugin/index.tsx +0 -445
- package/src/components/editor/plugins/FloatingTextFormatToolbarPlugin/index.tsx +0 -275
- package/src/components/editor/plugins/InlineImagePlugin/index.tsx +0 -351
- package/src/components/editor/plugins/LayoutPlugin/index.tsx +0 -238
- package/src/components/editor/plugins/LinkPlugin/index.tsx +0 -36
- package/src/components/editor/plugins/LinkWithMetaData/index.tsx +0 -271
- package/src/components/editor/plugins/MarkdownShortcutPlugin/index.tsx +0 -11
- package/src/components/editor/plugins/MarkdownTransformers/index.tsx +0 -304
- package/src/components/editor/plugins/PollPlugin/index.tsx +0 -49
- package/src/components/editor/plugins/ShortcutsPlugin/index.tsx +0 -180
- package/src/components/editor/plugins/ShortcutsPlugin/shortcuts.ts +0 -253
- package/src/components/editor/plugins/SlashCommand/index.tsx +0 -621
- package/src/components/editor/plugins/SpeechToTextPlugin/index.ts +0 -127
- package/src/components/editor/plugins/TabFocusPlugin/index.ts +0 -58
- package/src/components/editor/plugins/TableCellResizer/index.tsx +0 -438
- package/src/components/editor/plugins/TablePlugin/index.tsx +0 -99
- package/src/components/editor/plugins/ToolbarPlugin/index.tsx +0 -522
- package/src/components/editor/plugins/TwitterPlugin/index.ts +0 -35
- package/src/components/editor/plugins/YouTubeNode/index.tsx +0 -179
- package/src/components/editor/plugins/YouTubePlugin/index.ts +0 -41
- package/src/components/editor/themes/editor-theme.ts +0 -113
- package/src/components/editor/themes/theme.css +0 -377
- package/src/components/editor/utils/ai.ts +0 -291
- package/src/components/editor/utils/canUseDOM.ts +0 -12
- package/src/components/editor/utils/environment.ts +0 -50
- package/src/components/editor/utils/extract-data.ts +0 -166
- package/src/components/editor/utils/getAllLexicalChildren.ts +0 -13
- package/src/components/editor/utils/getDOMRangeRect.ts +0 -27
- package/src/components/editor/utils/getSelectedNode.ts +0 -27
- package/src/components/editor/utils/gif.ts +0 -29
- package/src/components/editor/utils/invariant.ts +0 -15
- package/src/components/editor/utils/setFloatingElemPosition.ts +0 -51
- package/src/components/editor/utils/setFloatingElemPositionForLinkEditor.ts +0 -40
- package/src/components/editor/utils/setNodePlaceholderFromSelection/getNodePlaceholder.ts +0 -51
- package/src/components/editor/utils/setNodePlaceholderFromSelection/setNodePlaceholderFromSelection.ts +0 -15
- package/src/components/editor/utils/setNodePlaceholderFromSelection/setPlaceholderOnSelection.ts +0 -114
- package/src/components/editor/utils/setNodePlaceholderFromSelection/styles.css +0 -6
- package/src/components/editor/utils/url.ts +0 -109
- package/src/components/editor/utils/useLayoutEffect.ts +0 -13
- package/src/components/providers/QueryProvider.tsx +0 -15
- package/src/components/providers/SharedHistoryContext.tsx +0 -28
- package/src/components/providers/ToolbarContext.tsx +0 -123
- package/src/components/providers/theme-provider.tsx +0 -11
- package/src/components/theme/ModeToggle.tsx +0 -40
- package/src/components/ui/FileInput.tsx +0 -40
- package/src/components/ui/Input.css +0 -32
- package/src/components/ui/Select.css +0 -42
- package/src/components/ui/Select.tsx +0 -36
- package/src/components/ui/TextInput.tsx +0 -48
- package/src/components/ui/ai/ai-button.tsx +0 -574
- package/src/components/ui/ai/border.tsx +0 -99
- package/src/components/ui/ai/placeholder-input-vanish.tsx +0 -282
- package/src/components/ui/button.tsx +0 -89
- package/src/components/ui/card.tsx +0 -76
- package/src/components/ui/checkbox.tsx +0 -30
- package/src/components/ui/command.tsx +0 -153
- package/src/components/ui/dialog/Dialog.css +0 -25
- package/src/components/ui/dialog/Dialog.tsx +0 -34
- package/src/components/ui/dialog.tsx +0 -122
- package/src/components/ui/drop-downs/background-color.tsx +0 -183
- package/src/components/ui/drop-downs/block-format.tsx +0 -159
- package/src/components/ui/drop-downs/code.tsx +0 -42
- package/src/components/ui/drop-downs/color.tsx +0 -177
- package/src/components/ui/drop-downs/font-size.tsx +0 -138
- package/src/components/ui/drop-downs/font.tsx +0 -155
- package/src/components/ui/drop-downs/index.tsx +0 -122
- package/src/components/ui/drop-downs/insert-node.tsx +0 -213
- package/src/components/ui/drop-downs/text-align.tsx +0 -123
- package/src/components/ui/drop-downs/text-format.tsx +0 -104
- package/src/components/ui/dropdown-menu.tsx +0 -201
- package/src/components/ui/equation/EquationEditor.css +0 -38
- package/src/components/ui/equation/EquationEditor.tsx +0 -56
- package/src/components/ui/equation/KatexEquationAlterer.css +0 -41
- package/src/components/ui/equation/KatexEquationAlterer.tsx +0 -83
- package/src/components/ui/equation/KatexRenderer.tsx +0 -66
- package/src/components/ui/excalidraw/ExcalidrawModal.css +0 -64
- package/src/components/ui/excalidraw/ExcalidrawModal.tsx +0 -234
- package/src/components/ui/excalidraw/Modal.css +0 -62
- package/src/components/ui/excalidraw/Modal.tsx +0 -110
- package/src/components/ui/hover-card.tsx +0 -29
- package/src/components/ui/image/error-image.tsx +0 -17
- package/src/components/ui/image/file-upload.tsx +0 -240
- package/src/components/ui/image/image-resizer.tsx +0 -297
- package/src/components/ui/image/image-toolbar.tsx +0 -264
- package/src/components/ui/image/index.tsx +0 -408
- package/src/components/ui/image/lazy-image.tsx +0 -68
- package/src/components/ui/image/lazy-video.tsx +0 -71
- package/src/components/ui/input.tsx +0 -22
- package/src/components/ui/models/custom-dialog.tsx +0 -320
- package/src/components/ui/models/insert-gif.tsx +0 -90
- package/src/components/ui/models/insert-image.tsx +0 -52
- package/src/components/ui/models/insert-poll.tsx +0 -29
- package/src/components/ui/models/insert-table.tsx +0 -62
- package/src/components/ui/models/use-model.tsx +0 -91
- package/src/components/ui/poll/poll-component.tsx +0 -304
- package/src/components/ui/popover.tsx +0 -33
- package/src/components/ui/progress.tsx +0 -28
- package/src/components/ui/scroll-area.tsx +0 -48
- package/src/components/ui/separator.tsx +0 -31
- package/src/components/ui/skeleton.tsx +0 -15
- package/src/components/ui/sonner.tsx +0 -31
- package/src/components/ui/stepper/step.tsx +0 -179
- package/src/components/ui/stepper/stepper.tsx +0 -89
- package/src/components/ui/textarea.tsx +0 -22
- package/src/components/ui/toggle.tsx +0 -71
- package/src/components/ui/tooltip.tsx +0 -32
- package/src/components/ui/write/text-format-floting-toolbar.tsx +0 -346
- package/src/lib/edgestore.ts +0 -9
- package/src/lib/pinecone-client.ts +0 -0
- package/src/lib/utils.ts +0 -6
- package/src/utils/docSerialization.ts +0 -77
- package/src/utils/emoji-list.ts +0 -16615
- package/src/utils/getDOMRangeRect.ts +0 -27
- package/src/utils/getThemeSelector.ts +0 -25
- package/src/utils/isMobileWidth.ts +0 -7
- package/src/utils/joinClasses.ts +0 -13
- package/src/utils/setFloatingElemPosition.ts +0 -74
- package/src/utils/setFloatingElemPositionForLinkEditor.ts +0 -46
- package/src/utils/swipe.ts +0 -127
- package/src/utils/url.ts +0 -38
- package/tsconfig.json +0 -27
|
@@ -0,0 +1,1256 @@
|
|
|
1
|
+
import {
|
|
2
|
+
useModal
|
|
3
|
+
} from "./chunk-5QSNIVIG.mjs";
|
|
4
|
+
import {
|
|
5
|
+
$createCollapsibleContainerNode,
|
|
6
|
+
$createCollapsibleContentNode,
|
|
7
|
+
$createCollapsibleTitleNode,
|
|
8
|
+
$isCollapsibleContainerNode,
|
|
9
|
+
$isCollapsibleContentNode,
|
|
10
|
+
$isCollapsibleTitleNode,
|
|
11
|
+
CollapsibleContainerNode,
|
|
12
|
+
CollapsibleContentNode,
|
|
13
|
+
CollapsibleTitleNode
|
|
14
|
+
} from "./chunk-GXYD4VZM.mjs";
|
|
15
|
+
import {
|
|
16
|
+
Skeleton
|
|
17
|
+
} from "./chunk-QEIFVK5M.mjs";
|
|
18
|
+
import {
|
|
19
|
+
Input
|
|
20
|
+
} from "./chunk-POGRR73N.mjs";
|
|
21
|
+
import {
|
|
22
|
+
Button
|
|
23
|
+
} from "./chunk-BIU7WTLX.mjs";
|
|
24
|
+
import {
|
|
25
|
+
__spreadProps,
|
|
26
|
+
__spreadValues,
|
|
27
|
+
init_react_shim
|
|
28
|
+
} from "./chunk-77KXU36M.mjs";
|
|
29
|
+
|
|
30
|
+
// src/components/editor/plugins/LayoutPlugin/index.tsx
|
|
31
|
+
init_react_shim();
|
|
32
|
+
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
|
|
33
|
+
import {
|
|
34
|
+
$findMatchingParent,
|
|
35
|
+
$insertNodeToNearestRoot,
|
|
36
|
+
mergeRegister
|
|
37
|
+
} from "@lexical/utils";
|
|
38
|
+
import {
|
|
39
|
+
$createParagraphNode,
|
|
40
|
+
$getNodeByKey,
|
|
41
|
+
$getSelection,
|
|
42
|
+
$isRangeSelection,
|
|
43
|
+
COMMAND_PRIORITY_EDITOR,
|
|
44
|
+
COMMAND_PRIORITY_LOW,
|
|
45
|
+
createCommand,
|
|
46
|
+
KEY_ARROW_DOWN_COMMAND,
|
|
47
|
+
KEY_ARROW_LEFT_COMMAND,
|
|
48
|
+
KEY_ARROW_RIGHT_COMMAND,
|
|
49
|
+
KEY_ARROW_UP_COMMAND
|
|
50
|
+
} from "lexical";
|
|
51
|
+
import { useEffect } from "react";
|
|
52
|
+
|
|
53
|
+
// src/components/editor/nodes/LayoutNode/LayoutContainerNode.ts
|
|
54
|
+
init_react_shim();
|
|
55
|
+
import { addClassNamesToElement } from "@lexical/utils";
|
|
56
|
+
import { ElementNode } from "lexical";
|
|
57
|
+
function $convertLayoutContainerElement(domNode) {
|
|
58
|
+
const styleAttributes = window.getComputedStyle(domNode);
|
|
59
|
+
const templateColumns = styleAttributes.getPropertyValue(
|
|
60
|
+
"grid-template-columns"
|
|
61
|
+
);
|
|
62
|
+
if (templateColumns) {
|
|
63
|
+
const node = $createLayoutContainerNode(templateColumns);
|
|
64
|
+
return { node };
|
|
65
|
+
}
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
var LayoutContainerNode = class _LayoutContainerNode extends ElementNode {
|
|
69
|
+
constructor(templateColumns, key) {
|
|
70
|
+
super(key);
|
|
71
|
+
this.__templateColumns = templateColumns;
|
|
72
|
+
}
|
|
73
|
+
static getType() {
|
|
74
|
+
return "layout-container";
|
|
75
|
+
}
|
|
76
|
+
static clone(node) {
|
|
77
|
+
return new _LayoutContainerNode(node.__templateColumns, node.__key);
|
|
78
|
+
}
|
|
79
|
+
createDOM(config) {
|
|
80
|
+
const dom = document.createElement("div");
|
|
81
|
+
dom.style.gridTemplateColumns = this.__templateColumns;
|
|
82
|
+
if (typeof config.theme.layoutContainer === "string") {
|
|
83
|
+
addClassNamesToElement(dom, config.theme.layoutContainer);
|
|
84
|
+
}
|
|
85
|
+
return dom;
|
|
86
|
+
}
|
|
87
|
+
exportDOM() {
|
|
88
|
+
const element = document.createElement("div");
|
|
89
|
+
element.style.gridTemplateColumns = this.__templateColumns;
|
|
90
|
+
element.setAttribute("data-lexical-layout-container", "true");
|
|
91
|
+
return { element };
|
|
92
|
+
}
|
|
93
|
+
updateDOM(prevNode, dom) {
|
|
94
|
+
if (prevNode.__templateColumns !== this.__templateColumns) {
|
|
95
|
+
dom.style.gridTemplateColumns = this.__templateColumns;
|
|
96
|
+
}
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
static importDOM() {
|
|
100
|
+
return {
|
|
101
|
+
div: (domNode) => {
|
|
102
|
+
if (!domNode.hasAttribute("data-lexical-layout-container")) {
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
return {
|
|
106
|
+
conversion: $convertLayoutContainerElement,
|
|
107
|
+
priority: 2
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
static importJSON(json) {
|
|
113
|
+
return $createLayoutContainerNode().updateFromJSON(json);
|
|
114
|
+
}
|
|
115
|
+
updateFromJSON(serializedNode) {
|
|
116
|
+
return super.updateFromJSON(serializedNode).setTemplateColumns(serializedNode.templateColumns);
|
|
117
|
+
}
|
|
118
|
+
isShadowRoot() {
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
canBeEmpty() {
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
exportJSON() {
|
|
125
|
+
return __spreadProps(__spreadValues({}, super.exportJSON()), {
|
|
126
|
+
templateColumns: this.__templateColumns
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
getTemplateColumns() {
|
|
130
|
+
return this.getLatest().__templateColumns;
|
|
131
|
+
}
|
|
132
|
+
setTemplateColumns(templateColumns) {
|
|
133
|
+
const self = this.getWritable();
|
|
134
|
+
self.__templateColumns = templateColumns;
|
|
135
|
+
return self;
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
function $createLayoutContainerNode(templateColumns = "") {
|
|
139
|
+
return new LayoutContainerNode(templateColumns);
|
|
140
|
+
}
|
|
141
|
+
function $isLayoutContainerNode(node) {
|
|
142
|
+
return node instanceof LayoutContainerNode;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// src/components/editor/nodes/LayoutNode/LayoutItemNode.ts
|
|
146
|
+
init_react_shim();
|
|
147
|
+
import { addClassNamesToElement as addClassNamesToElement2 } from "@lexical/utils";
|
|
148
|
+
import { ElementNode as ElementNode2 } from "lexical";
|
|
149
|
+
function $convertLayoutItemElement() {
|
|
150
|
+
return { node: $createLayoutItemNode() };
|
|
151
|
+
}
|
|
152
|
+
var LayoutItemNode = class _LayoutItemNode extends ElementNode2 {
|
|
153
|
+
static getType() {
|
|
154
|
+
return "layout-item";
|
|
155
|
+
}
|
|
156
|
+
static clone(node) {
|
|
157
|
+
return new _LayoutItemNode(node.__key);
|
|
158
|
+
}
|
|
159
|
+
createDOM(config) {
|
|
160
|
+
const dom = document.createElement("div");
|
|
161
|
+
dom.setAttribute("data-lexical-layout-item", "true");
|
|
162
|
+
if (typeof config.theme.layoutItem === "string") {
|
|
163
|
+
addClassNamesToElement2(dom, config.theme.layoutItem);
|
|
164
|
+
}
|
|
165
|
+
return dom;
|
|
166
|
+
}
|
|
167
|
+
updateDOM() {
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
static importDOM() {
|
|
171
|
+
return {
|
|
172
|
+
div: (domNode) => {
|
|
173
|
+
if (!domNode.hasAttribute("data-lexical-layout-item")) {
|
|
174
|
+
return null;
|
|
175
|
+
}
|
|
176
|
+
return {
|
|
177
|
+
conversion: $convertLayoutItemElement,
|
|
178
|
+
priority: 2
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
static importJSON(serializedNode) {
|
|
184
|
+
return $createLayoutItemNode().updateFromJSON(serializedNode);
|
|
185
|
+
}
|
|
186
|
+
isShadowRoot() {
|
|
187
|
+
return true;
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
function $createLayoutItemNode() {
|
|
191
|
+
return new LayoutItemNode();
|
|
192
|
+
}
|
|
193
|
+
function $isLayoutItemNode(node) {
|
|
194
|
+
return node instanceof LayoutItemNode;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// src/components/editor/plugins/LayoutPlugin/index.tsx
|
|
198
|
+
var INSERT_LAYOUT_COMMAND = createCommand();
|
|
199
|
+
var UPDATE_LAYOUT_COMMAND = createCommand();
|
|
200
|
+
function LayoutPlugin() {
|
|
201
|
+
const [editor] = useLexicalComposerContext();
|
|
202
|
+
useEffect(() => {
|
|
203
|
+
if (!editor.hasNodes([LayoutContainerNode, LayoutItemNode])) {
|
|
204
|
+
throw new Error(
|
|
205
|
+
"LayoutPlugin: LayoutContainerNode, or LayoutItemNode not registered on editor"
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
const $onEscape = (before) => {
|
|
209
|
+
var _a, _b;
|
|
210
|
+
const selection = $getSelection();
|
|
211
|
+
if ($isRangeSelection(selection) && selection.isCollapsed() && selection.anchor.offset === 0) {
|
|
212
|
+
const container = $findMatchingParent(
|
|
213
|
+
selection.anchor.getNode(),
|
|
214
|
+
$isLayoutContainerNode
|
|
215
|
+
);
|
|
216
|
+
if ($isLayoutContainerNode(container)) {
|
|
217
|
+
const parent = container.getParent();
|
|
218
|
+
const child = parent && (before ? parent.getFirstChild() : parent == null ? void 0 : parent.getLastChild());
|
|
219
|
+
const descendant = before ? (_a = container.getFirstDescendant()) == null ? void 0 : _a.getKey() : (_b = container.getLastDescendant()) == null ? void 0 : _b.getKey();
|
|
220
|
+
if (parent !== null && child === container && selection.anchor.key === descendant) {
|
|
221
|
+
if (before) {
|
|
222
|
+
container.insertBefore($createParagraphNode());
|
|
223
|
+
} else {
|
|
224
|
+
container.insertAfter($createParagraphNode());
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return false;
|
|
230
|
+
};
|
|
231
|
+
const $fillLayoutItemIfEmpty = (node) => {
|
|
232
|
+
if (node.isEmpty()) {
|
|
233
|
+
node.append($createParagraphNode());
|
|
234
|
+
}
|
|
235
|
+
};
|
|
236
|
+
const $removeIsolatedLayoutItem = (node) => {
|
|
237
|
+
const parent = node.getParent();
|
|
238
|
+
if (!$isLayoutContainerNode(parent)) {
|
|
239
|
+
const children = node.getChildren();
|
|
240
|
+
for (const child of children) {
|
|
241
|
+
node.insertBefore(child);
|
|
242
|
+
}
|
|
243
|
+
node.remove();
|
|
244
|
+
return true;
|
|
245
|
+
}
|
|
246
|
+
return false;
|
|
247
|
+
};
|
|
248
|
+
return mergeRegister(
|
|
249
|
+
// When layout is the last child pressing down/right arrow will insert paragraph
|
|
250
|
+
// below it to allow adding more content. It's similar what $insertBlockNode
|
|
251
|
+
// (mainly for decorators), except it'll always be possible to continue adding
|
|
252
|
+
// new content even if trailing paragraph is accidentally deleted
|
|
253
|
+
editor.registerCommand(
|
|
254
|
+
KEY_ARROW_DOWN_COMMAND,
|
|
255
|
+
() => $onEscape(false),
|
|
256
|
+
COMMAND_PRIORITY_LOW
|
|
257
|
+
),
|
|
258
|
+
editor.registerCommand(
|
|
259
|
+
KEY_ARROW_RIGHT_COMMAND,
|
|
260
|
+
() => $onEscape(false),
|
|
261
|
+
COMMAND_PRIORITY_LOW
|
|
262
|
+
),
|
|
263
|
+
// When layout is the first child pressing up/left arrow will insert paragraph
|
|
264
|
+
// above it to allow adding more content. It's similar what $insertBlockNode
|
|
265
|
+
// (mainly for decorators), except it'll always be possible to continue adding
|
|
266
|
+
// new content even if leading paragraph is accidentally deleted
|
|
267
|
+
editor.registerCommand(
|
|
268
|
+
KEY_ARROW_UP_COMMAND,
|
|
269
|
+
() => $onEscape(true),
|
|
270
|
+
COMMAND_PRIORITY_LOW
|
|
271
|
+
),
|
|
272
|
+
editor.registerCommand(
|
|
273
|
+
KEY_ARROW_LEFT_COMMAND,
|
|
274
|
+
() => $onEscape(true),
|
|
275
|
+
COMMAND_PRIORITY_LOW
|
|
276
|
+
),
|
|
277
|
+
editor.registerCommand(
|
|
278
|
+
INSERT_LAYOUT_COMMAND,
|
|
279
|
+
(template) => {
|
|
280
|
+
editor.update(() => {
|
|
281
|
+
const container = $createLayoutContainerNode(template);
|
|
282
|
+
const itemsCount = getItemsCountFromTemplate(template);
|
|
283
|
+
for (let i = 0; i < itemsCount; i++) {
|
|
284
|
+
container.append(
|
|
285
|
+
$createLayoutItemNode().append($createParagraphNode())
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
$insertNodeToNearestRoot(container);
|
|
289
|
+
container.selectStart();
|
|
290
|
+
});
|
|
291
|
+
return true;
|
|
292
|
+
},
|
|
293
|
+
COMMAND_PRIORITY_EDITOR
|
|
294
|
+
),
|
|
295
|
+
editor.registerCommand(
|
|
296
|
+
UPDATE_LAYOUT_COMMAND,
|
|
297
|
+
({ template, nodeKey }) => {
|
|
298
|
+
editor.update(() => {
|
|
299
|
+
const container = $getNodeByKey(nodeKey);
|
|
300
|
+
if (!$isLayoutContainerNode(container)) {
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
const itemsCount = getItemsCountFromTemplate(template);
|
|
304
|
+
const prevItemsCount = getItemsCountFromTemplate(
|
|
305
|
+
container.getTemplateColumns()
|
|
306
|
+
);
|
|
307
|
+
if (itemsCount > prevItemsCount) {
|
|
308
|
+
for (let i = prevItemsCount; i < itemsCount; i++) {
|
|
309
|
+
container.append(
|
|
310
|
+
$createLayoutItemNode().append($createParagraphNode())
|
|
311
|
+
);
|
|
312
|
+
}
|
|
313
|
+
} else if (itemsCount < prevItemsCount) {
|
|
314
|
+
for (let i = prevItemsCount - 1; i >= itemsCount; i--) {
|
|
315
|
+
const layoutItem = container.getChildAtIndex(i);
|
|
316
|
+
if ($isLayoutItemNode(layoutItem)) {
|
|
317
|
+
layoutItem.remove();
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
container.setTemplateColumns(template);
|
|
322
|
+
});
|
|
323
|
+
return true;
|
|
324
|
+
},
|
|
325
|
+
COMMAND_PRIORITY_EDITOR
|
|
326
|
+
),
|
|
327
|
+
editor.registerNodeTransform(LayoutItemNode, (node) => {
|
|
328
|
+
const isRemoved = $removeIsolatedLayoutItem(node);
|
|
329
|
+
if (!isRemoved) {
|
|
330
|
+
$fillLayoutItemIfEmpty(node);
|
|
331
|
+
}
|
|
332
|
+
}),
|
|
333
|
+
editor.registerNodeTransform(LayoutContainerNode, (node) => {
|
|
334
|
+
const children = node.getChildren();
|
|
335
|
+
if (!children.every($isLayoutItemNode)) {
|
|
336
|
+
for (const child of children) {
|
|
337
|
+
node.insertBefore(child);
|
|
338
|
+
}
|
|
339
|
+
node.remove();
|
|
340
|
+
}
|
|
341
|
+
})
|
|
342
|
+
);
|
|
343
|
+
}, [editor]);
|
|
344
|
+
return null;
|
|
345
|
+
}
|
|
346
|
+
function getItemsCountFromTemplate(template) {
|
|
347
|
+
return template.trim().split(/\s+/).length;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// src/components/editor/plugins/CollapsiblePlugin/index.ts
|
|
351
|
+
init_react_shim();
|
|
352
|
+
import { useLexicalComposerContext as useLexicalComposerContext2 } from "@lexical/react/LexicalComposerContext";
|
|
353
|
+
import { $findMatchingParent as $findMatchingParent2, mergeRegister as mergeRegister2 } from "@lexical/utils";
|
|
354
|
+
import {
|
|
355
|
+
$createParagraphNode as $createParagraphNode2,
|
|
356
|
+
$getNodeByKey as $getNodeByKey2,
|
|
357
|
+
$getPreviousSelection,
|
|
358
|
+
$getSelection as $getSelection2,
|
|
359
|
+
$isElementNode,
|
|
360
|
+
$isRangeSelection as $isRangeSelection2,
|
|
361
|
+
$setSelection,
|
|
362
|
+
COMMAND_PRIORITY_EDITOR as COMMAND_PRIORITY_EDITOR2,
|
|
363
|
+
COMMAND_PRIORITY_LOW as COMMAND_PRIORITY_LOW2,
|
|
364
|
+
createCommand as createCommand2,
|
|
365
|
+
DELETE_CHARACTER_COMMAND,
|
|
366
|
+
INSERT_PARAGRAPH_COMMAND,
|
|
367
|
+
KEY_ARROW_DOWN_COMMAND as KEY_ARROW_DOWN_COMMAND2
|
|
368
|
+
} from "lexical";
|
|
369
|
+
import { useEffect as useEffect2 } from "react";
|
|
370
|
+
var INSERT_COLLAPSIBLE_COMMAND = createCommand2();
|
|
371
|
+
var TOGGLE_COLLAPSIBLE_COMMAND = createCommand2();
|
|
372
|
+
function CollapsiblePlugin() {
|
|
373
|
+
const [editor] = useLexicalComposerContext2();
|
|
374
|
+
useEffect2(() => {
|
|
375
|
+
if (!editor.hasNodes([
|
|
376
|
+
CollapsibleContainerNode,
|
|
377
|
+
CollapsibleTitleNode,
|
|
378
|
+
CollapsibleContentNode
|
|
379
|
+
])) {
|
|
380
|
+
throw new Error(
|
|
381
|
+
"CollapsiblePlugin: CollapsibleContainerNode, CollapsibleTitleNode, or CollapsibleContentNode not registered on editor"
|
|
382
|
+
);
|
|
383
|
+
}
|
|
384
|
+
return mergeRegister2(
|
|
385
|
+
// Structure enforcing transformers for each node type. In case nesting structure is not
|
|
386
|
+
// "Container > Title + Content" it'll unwrap nodes and convert it back
|
|
387
|
+
// to regular content.
|
|
388
|
+
editor.registerNodeTransform(CollapsibleContentNode, (node) => {
|
|
389
|
+
const parent = node.getParent();
|
|
390
|
+
if (!$isCollapsibleContainerNode(parent)) {
|
|
391
|
+
const children = node.getChildren();
|
|
392
|
+
for (const child of children) {
|
|
393
|
+
node.insertAfter(child);
|
|
394
|
+
}
|
|
395
|
+
node.remove();
|
|
396
|
+
}
|
|
397
|
+
}),
|
|
398
|
+
editor.registerNodeTransform(CollapsibleTitleNode, (node) => {
|
|
399
|
+
const parent = node.getParent();
|
|
400
|
+
if (!$isCollapsibleContainerNode(parent)) {
|
|
401
|
+
node.replace($createParagraphNode2().append(...node.getChildren()));
|
|
402
|
+
}
|
|
403
|
+
}),
|
|
404
|
+
editor.registerNodeTransform(CollapsibleContainerNode, (node) => {
|
|
405
|
+
const children = node.getChildren();
|
|
406
|
+
if (children.length !== 2 || !$isCollapsibleTitleNode(children[0]) || !$isCollapsibleContentNode(children[1])) {
|
|
407
|
+
for (const child of children) {
|
|
408
|
+
node.insertAfter(child);
|
|
409
|
+
}
|
|
410
|
+
node.remove();
|
|
411
|
+
}
|
|
412
|
+
}),
|
|
413
|
+
// This handles the case when container is collapsed and we delete its previous sibling
|
|
414
|
+
// into it, it would cause collapsed content deleted (since it's display: none, and selection
|
|
415
|
+
// swallows it when deletes single char). Instead we expand container, which is although
|
|
416
|
+
// not perfect, but avoids bigger problem
|
|
417
|
+
editor.registerCommand(
|
|
418
|
+
DELETE_CHARACTER_COMMAND,
|
|
419
|
+
() => {
|
|
420
|
+
const selection = $getSelection2();
|
|
421
|
+
if (!$isRangeSelection2(selection) || !selection.isCollapsed() || selection.anchor.offset !== 0) {
|
|
422
|
+
return false;
|
|
423
|
+
}
|
|
424
|
+
const anchorNode = selection.anchor.getNode();
|
|
425
|
+
const topLevelElement = anchorNode.getTopLevelElement();
|
|
426
|
+
if (topLevelElement === null) {
|
|
427
|
+
return false;
|
|
428
|
+
}
|
|
429
|
+
const container = topLevelElement.getPreviousSibling();
|
|
430
|
+
if (!$isCollapsibleContainerNode(container) || container.getOpen()) {
|
|
431
|
+
return false;
|
|
432
|
+
}
|
|
433
|
+
container.setOpen(true);
|
|
434
|
+
return true;
|
|
435
|
+
},
|
|
436
|
+
COMMAND_PRIORITY_LOW2
|
|
437
|
+
),
|
|
438
|
+
// When collapsible is the last child pressing down arrow will insert paragraph
|
|
439
|
+
// below it to allow adding more content. It's similar what $insertBlockNode
|
|
440
|
+
// (mainly for decorators), except it'll always be possible to continue adding
|
|
441
|
+
// new content even if trailing paragraph is accidentally deleted
|
|
442
|
+
editor.registerCommand(
|
|
443
|
+
KEY_ARROW_DOWN_COMMAND2,
|
|
444
|
+
() => {
|
|
445
|
+
const selection = $getSelection2();
|
|
446
|
+
if (!$isRangeSelection2(selection) || !selection.isCollapsed()) {
|
|
447
|
+
return false;
|
|
448
|
+
}
|
|
449
|
+
const container = $findMatchingParent2(
|
|
450
|
+
selection.anchor.getNode(),
|
|
451
|
+
$isCollapsibleContainerNode
|
|
452
|
+
);
|
|
453
|
+
if (container === null) {
|
|
454
|
+
return false;
|
|
455
|
+
}
|
|
456
|
+
const parent = container.getParent();
|
|
457
|
+
if (parent !== null && parent.getLastChild() === container) {
|
|
458
|
+
parent.append($createParagraphNode2());
|
|
459
|
+
}
|
|
460
|
+
return false;
|
|
461
|
+
},
|
|
462
|
+
COMMAND_PRIORITY_LOW2
|
|
463
|
+
),
|
|
464
|
+
// Handling CMD+Enter to toggle collapsible element collapsed state
|
|
465
|
+
editor.registerCommand(
|
|
466
|
+
INSERT_PARAGRAPH_COMMAND,
|
|
467
|
+
() => {
|
|
468
|
+
var _a;
|
|
469
|
+
const windowEvent = (_a = editor._window) == null ? void 0 : _a.event;
|
|
470
|
+
if (windowEvent && (windowEvent.ctrlKey || windowEvent.metaKey) && windowEvent.key === "Enter") {
|
|
471
|
+
const selection = $getPreviousSelection();
|
|
472
|
+
if ($isRangeSelection2(selection) && selection.isCollapsed()) {
|
|
473
|
+
const parent = $findMatchingParent2(
|
|
474
|
+
selection.anchor.getNode(),
|
|
475
|
+
(node) => $isElementNode(node) && !node.isInline()
|
|
476
|
+
);
|
|
477
|
+
if ($isCollapsibleTitleNode(parent)) {
|
|
478
|
+
const container = parent.getParent();
|
|
479
|
+
if ($isCollapsibleContainerNode(container)) {
|
|
480
|
+
container.toggleOpen();
|
|
481
|
+
$setSelection(selection.clone());
|
|
482
|
+
return true;
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
return false;
|
|
488
|
+
},
|
|
489
|
+
COMMAND_PRIORITY_LOW2
|
|
490
|
+
),
|
|
491
|
+
editor.registerCommand(
|
|
492
|
+
INSERT_COLLAPSIBLE_COMMAND,
|
|
493
|
+
() => {
|
|
494
|
+
editor.update(() => {
|
|
495
|
+
const selection = $getSelection2();
|
|
496
|
+
if (!$isRangeSelection2(selection)) {
|
|
497
|
+
return;
|
|
498
|
+
}
|
|
499
|
+
const title = $createCollapsibleTitleNode();
|
|
500
|
+
const content = $createCollapsibleContentNode().append(
|
|
501
|
+
$createParagraphNode2()
|
|
502
|
+
);
|
|
503
|
+
const container = $createCollapsibleContainerNode().append(
|
|
504
|
+
title,
|
|
505
|
+
content
|
|
506
|
+
);
|
|
507
|
+
selection.insertNodes([container]);
|
|
508
|
+
title.selectStart();
|
|
509
|
+
});
|
|
510
|
+
return true;
|
|
511
|
+
},
|
|
512
|
+
COMMAND_PRIORITY_EDITOR2
|
|
513
|
+
),
|
|
514
|
+
editor.registerCommand(
|
|
515
|
+
TOGGLE_COLLAPSIBLE_COMMAND,
|
|
516
|
+
(key) => {
|
|
517
|
+
editor.update(() => {
|
|
518
|
+
const containerNode = $getNodeByKey2(key);
|
|
519
|
+
if ($isCollapsibleContainerNode(containerNode)) {
|
|
520
|
+
containerNode.toggleOpen();
|
|
521
|
+
}
|
|
522
|
+
});
|
|
523
|
+
return true;
|
|
524
|
+
},
|
|
525
|
+
COMMAND_PRIORITY_EDITOR2
|
|
526
|
+
)
|
|
527
|
+
);
|
|
528
|
+
}, [editor]);
|
|
529
|
+
return null;
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
// src/components/editor/plugins/AutoEmbedPlugin/index.tsx
|
|
533
|
+
init_react_shim();
|
|
534
|
+
import {
|
|
535
|
+
AutoEmbedOption,
|
|
536
|
+
LexicalAutoEmbedPlugin,
|
|
537
|
+
URL_MATCHER
|
|
538
|
+
} from "@lexical/react/LexicalAutoEmbedPlugin";
|
|
539
|
+
import { useLexicalComposerContext as useLexicalComposerContext6 } from "@lexical/react/LexicalComposerContext";
|
|
540
|
+
import { useMemo, useState as useState2 } from "react";
|
|
541
|
+
import * as React5 from "react";
|
|
542
|
+
import * as ReactDOM from "react-dom";
|
|
543
|
+
|
|
544
|
+
// src/components/editor/plugins/FigmaPlugin/index.tsx
|
|
545
|
+
init_react_shim();
|
|
546
|
+
import { useLexicalComposerContext as useLexicalComposerContext3 } from "@lexical/react/LexicalComposerContext";
|
|
547
|
+
import { $insertNodeToNearestRoot as $insertNodeToNearestRoot2 } from "@lexical/utils";
|
|
548
|
+
import { COMMAND_PRIORITY_EDITOR as COMMAND_PRIORITY_EDITOR3, createCommand as createCommand3 } from "lexical";
|
|
549
|
+
import { useEffect as useEffect3 } from "react";
|
|
550
|
+
|
|
551
|
+
// src/components/editor/nodes/FigmaNode/FigmaNode.tsx
|
|
552
|
+
init_react_shim();
|
|
553
|
+
import { BlockWithAlignableContents } from "@lexical/react/LexicalBlockWithAlignableContents";
|
|
554
|
+
import {
|
|
555
|
+
DecoratorBlockNode
|
|
556
|
+
} from "@lexical/react/LexicalDecoratorBlockNode";
|
|
557
|
+
import * as React2 from "react";
|
|
558
|
+
function FigmaComponent({
|
|
559
|
+
className,
|
|
560
|
+
format,
|
|
561
|
+
nodeKey,
|
|
562
|
+
documentID
|
|
563
|
+
}) {
|
|
564
|
+
return /* @__PURE__ */ React2.createElement(
|
|
565
|
+
BlockWithAlignableContents,
|
|
566
|
+
{
|
|
567
|
+
className,
|
|
568
|
+
format,
|
|
569
|
+
nodeKey
|
|
570
|
+
},
|
|
571
|
+
/* @__PURE__ */ React2.createElement(
|
|
572
|
+
"iframe",
|
|
573
|
+
{
|
|
574
|
+
width: "560",
|
|
575
|
+
height: "315",
|
|
576
|
+
src: `https://www.figma.com/embed?embed_host=lexical&url= https://www.figma.com/file/${documentID}`,
|
|
577
|
+
allowFullScreen: true
|
|
578
|
+
}
|
|
579
|
+
)
|
|
580
|
+
);
|
|
581
|
+
}
|
|
582
|
+
var FigmaNode = class _FigmaNode extends DecoratorBlockNode {
|
|
583
|
+
static getType() {
|
|
584
|
+
return "figma";
|
|
585
|
+
}
|
|
586
|
+
static clone(node) {
|
|
587
|
+
return new _FigmaNode(node.__id, node.__format, node.__key);
|
|
588
|
+
}
|
|
589
|
+
static importJSON(serializedNode) {
|
|
590
|
+
return $createFigmaNode(serializedNode.documentID).updateFromJSON(
|
|
591
|
+
serializedNode
|
|
592
|
+
);
|
|
593
|
+
}
|
|
594
|
+
exportJSON() {
|
|
595
|
+
return __spreadProps(__spreadValues({}, super.exportJSON()), {
|
|
596
|
+
documentID: this.__id
|
|
597
|
+
});
|
|
598
|
+
}
|
|
599
|
+
constructor(id, format, key) {
|
|
600
|
+
super(format, key);
|
|
601
|
+
this.__id = id;
|
|
602
|
+
}
|
|
603
|
+
updateDOM() {
|
|
604
|
+
return false;
|
|
605
|
+
}
|
|
606
|
+
getId() {
|
|
607
|
+
return this.__id;
|
|
608
|
+
}
|
|
609
|
+
getTextContent(_includeInert, _includeDirectionless) {
|
|
610
|
+
return `https://www.figma.com/file/${this.__id}`;
|
|
611
|
+
}
|
|
612
|
+
decorate(_editor, config) {
|
|
613
|
+
const embedBlockTheme = config.theme.embedBlock || {};
|
|
614
|
+
const className = {
|
|
615
|
+
base: embedBlockTheme.base || "",
|
|
616
|
+
focus: embedBlockTheme.focus || ""
|
|
617
|
+
};
|
|
618
|
+
return /* @__PURE__ */ React2.createElement(
|
|
619
|
+
FigmaComponent,
|
|
620
|
+
{
|
|
621
|
+
className,
|
|
622
|
+
format: this.__format,
|
|
623
|
+
nodeKey: this.getKey(),
|
|
624
|
+
documentID: this.__id
|
|
625
|
+
}
|
|
626
|
+
);
|
|
627
|
+
}
|
|
628
|
+
};
|
|
629
|
+
function $createFigmaNode(documentID) {
|
|
630
|
+
return new FigmaNode(documentID);
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
// src/components/editor/plugins/FigmaPlugin/index.tsx
|
|
634
|
+
var INSERT_FIGMA_COMMAND = createCommand3(
|
|
635
|
+
"INSERT_FIGMA_COMMAND"
|
|
636
|
+
);
|
|
637
|
+
function FigmaPlugin() {
|
|
638
|
+
const [editor] = useLexicalComposerContext3();
|
|
639
|
+
useEffect3(() => {
|
|
640
|
+
if (!editor.hasNodes([FigmaNode])) {
|
|
641
|
+
throw new Error("FigmaPlugin: FigmaNode not registered on editor");
|
|
642
|
+
}
|
|
643
|
+
return editor.registerCommand(
|
|
644
|
+
INSERT_FIGMA_COMMAND,
|
|
645
|
+
(payload) => {
|
|
646
|
+
const figmaNode = $createFigmaNode(payload);
|
|
647
|
+
$insertNodeToNearestRoot2(figmaNode);
|
|
648
|
+
return true;
|
|
649
|
+
},
|
|
650
|
+
COMMAND_PRIORITY_EDITOR3
|
|
651
|
+
);
|
|
652
|
+
}, [editor]);
|
|
653
|
+
return null;
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
// src/components/editor/plugins/YouTubePlugin/index.ts
|
|
657
|
+
init_react_shim();
|
|
658
|
+
import { useLexicalComposerContext as useLexicalComposerContext4 } from "@lexical/react/LexicalComposerContext";
|
|
659
|
+
import { $insertNodeToNearestRoot as $insertNodeToNearestRoot3 } from "@lexical/utils";
|
|
660
|
+
import { COMMAND_PRIORITY_EDITOR as COMMAND_PRIORITY_EDITOR4, createCommand as createCommand4 } from "lexical";
|
|
661
|
+
import { useEffect as useEffect4 } from "react";
|
|
662
|
+
|
|
663
|
+
// src/components/editor/plugins/YouTubeNode/index.tsx
|
|
664
|
+
init_react_shim();
|
|
665
|
+
import { BlockWithAlignableContents as BlockWithAlignableContents2 } from "@lexical/react/LexicalBlockWithAlignableContents";
|
|
666
|
+
import {
|
|
667
|
+
DecoratorBlockNode as DecoratorBlockNode2
|
|
668
|
+
} from "@lexical/react/LexicalDecoratorBlockNode";
|
|
669
|
+
import * as React3 from "react";
|
|
670
|
+
function YouTubeComponent({
|
|
671
|
+
className,
|
|
672
|
+
format,
|
|
673
|
+
nodeKey,
|
|
674
|
+
videoID
|
|
675
|
+
}) {
|
|
676
|
+
return /* @__PURE__ */ React3.createElement(
|
|
677
|
+
BlockWithAlignableContents2,
|
|
678
|
+
{
|
|
679
|
+
className,
|
|
680
|
+
format,
|
|
681
|
+
nodeKey
|
|
682
|
+
},
|
|
683
|
+
/* @__PURE__ */ React3.createElement(
|
|
684
|
+
"iframe",
|
|
685
|
+
{
|
|
686
|
+
width: "560",
|
|
687
|
+
height: "315",
|
|
688
|
+
style: {
|
|
689
|
+
width: "100%",
|
|
690
|
+
aspectRatio: "16/9",
|
|
691
|
+
borderRadius: "8px",
|
|
692
|
+
border: "4px solid #e6c10aff"
|
|
693
|
+
},
|
|
694
|
+
src: `https://www.youtube-nocookie.com/embed/${videoID}`,
|
|
695
|
+
frameBorder: "0",
|
|
696
|
+
allow: "accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture",
|
|
697
|
+
allowFullScreen: true,
|
|
698
|
+
title: "YouTube video"
|
|
699
|
+
}
|
|
700
|
+
)
|
|
701
|
+
);
|
|
702
|
+
}
|
|
703
|
+
function $convertYoutubeElement(domNode) {
|
|
704
|
+
const videoID = domNode.getAttribute("data-lexical-youtube");
|
|
705
|
+
if (videoID) {
|
|
706
|
+
const node = $createYouTubeNode(videoID);
|
|
707
|
+
return { node };
|
|
708
|
+
}
|
|
709
|
+
return null;
|
|
710
|
+
}
|
|
711
|
+
var YouTubeNode = class _YouTubeNode extends DecoratorBlockNode2 {
|
|
712
|
+
static getType() {
|
|
713
|
+
return "youtube";
|
|
714
|
+
}
|
|
715
|
+
static clone(node) {
|
|
716
|
+
return new _YouTubeNode(node.__id, node.__format, node.__key);
|
|
717
|
+
}
|
|
718
|
+
static importJSON(serializedNode) {
|
|
719
|
+
return $createYouTubeNode(serializedNode.videoID).updateFromJSON(
|
|
720
|
+
serializedNode
|
|
721
|
+
);
|
|
722
|
+
}
|
|
723
|
+
exportJSON() {
|
|
724
|
+
return __spreadProps(__spreadValues({}, super.exportJSON()), {
|
|
725
|
+
videoID: this.__id
|
|
726
|
+
});
|
|
727
|
+
}
|
|
728
|
+
constructor(id, format, key) {
|
|
729
|
+
super(format, key);
|
|
730
|
+
this.__id = id;
|
|
731
|
+
}
|
|
732
|
+
exportDOM() {
|
|
733
|
+
const element = document.createElement("iframe");
|
|
734
|
+
element.setAttribute("data-lexical-youtube", this.__id);
|
|
735
|
+
element.setAttribute("width", "560");
|
|
736
|
+
element.setAttribute("height", "315");
|
|
737
|
+
element.setAttribute(
|
|
738
|
+
"src",
|
|
739
|
+
`https://www.youtube-nocookie.com/embed/${this.__id}`
|
|
740
|
+
);
|
|
741
|
+
element.setAttribute("frameborder", "0");
|
|
742
|
+
element.setAttribute(
|
|
743
|
+
"allow",
|
|
744
|
+
"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
|
745
|
+
);
|
|
746
|
+
element.setAttribute("allowfullscreen", "true");
|
|
747
|
+
element.setAttribute("title", "YouTube video");
|
|
748
|
+
return { element };
|
|
749
|
+
}
|
|
750
|
+
static importDOM() {
|
|
751
|
+
return {
|
|
752
|
+
iframe: (domNode) => {
|
|
753
|
+
if (!domNode.hasAttribute("data-lexical-youtube")) {
|
|
754
|
+
return null;
|
|
755
|
+
}
|
|
756
|
+
return {
|
|
757
|
+
conversion: $convertYoutubeElement,
|
|
758
|
+
priority: 1
|
|
759
|
+
};
|
|
760
|
+
}
|
|
761
|
+
};
|
|
762
|
+
}
|
|
763
|
+
updateDOM() {
|
|
764
|
+
return false;
|
|
765
|
+
}
|
|
766
|
+
getId() {
|
|
767
|
+
return this.__id;
|
|
768
|
+
}
|
|
769
|
+
getTextContent() {
|
|
770
|
+
return `https://www.youtube.com/watch?v=${this.__id}`;
|
|
771
|
+
}
|
|
772
|
+
decorate(_editor, config) {
|
|
773
|
+
const embedBlockTheme = config.theme.embedBlock || {};
|
|
774
|
+
const className = {
|
|
775
|
+
base: embedBlockTheme.base || "",
|
|
776
|
+
focus: embedBlockTheme.focus || ""
|
|
777
|
+
};
|
|
778
|
+
return /* @__PURE__ */ React3.createElement(
|
|
779
|
+
YouTubeComponent,
|
|
780
|
+
{
|
|
781
|
+
className,
|
|
782
|
+
format: this.__format,
|
|
783
|
+
nodeKey: this.getKey(),
|
|
784
|
+
videoID: this.__id
|
|
785
|
+
}
|
|
786
|
+
);
|
|
787
|
+
}
|
|
788
|
+
};
|
|
789
|
+
function $createYouTubeNode(videoID) {
|
|
790
|
+
return new YouTubeNode(videoID);
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
// src/components/editor/plugins/YouTubePlugin/index.ts
|
|
794
|
+
var INSERT_YOUTUBE_COMMAND = createCommand4(
|
|
795
|
+
"INSERT_YOUTUBE_COMMAND"
|
|
796
|
+
);
|
|
797
|
+
function YouTubePlugin() {
|
|
798
|
+
const [editor] = useLexicalComposerContext4();
|
|
799
|
+
useEffect4(() => {
|
|
800
|
+
if (!editor.hasNodes([YouTubeNode])) {
|
|
801
|
+
throw new Error("YouTubePlugin: YouTubeNode not registered on editor");
|
|
802
|
+
}
|
|
803
|
+
return editor.registerCommand(
|
|
804
|
+
INSERT_YOUTUBE_COMMAND,
|
|
805
|
+
(payload) => {
|
|
806
|
+
const youTubeNode = $createYouTubeNode(payload);
|
|
807
|
+
$insertNodeToNearestRoot3(youTubeNode);
|
|
808
|
+
return true;
|
|
809
|
+
},
|
|
810
|
+
COMMAND_PRIORITY_EDITOR4
|
|
811
|
+
);
|
|
812
|
+
}, [editor]);
|
|
813
|
+
return null;
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
// src/components/editor/plugins/TwitterPlugin/index.ts
|
|
817
|
+
init_react_shim();
|
|
818
|
+
import { useLexicalComposerContext as useLexicalComposerContext5 } from "@lexical/react/LexicalComposerContext";
|
|
819
|
+
import { $insertNodeToNearestRoot as $insertNodeToNearestRoot4 } from "@lexical/utils";
|
|
820
|
+
import { COMMAND_PRIORITY_EDITOR as COMMAND_PRIORITY_EDITOR5, createCommand as createCommand5 } from "lexical";
|
|
821
|
+
import { useEffect as useEffect6 } from "react";
|
|
822
|
+
|
|
823
|
+
// src/components/editor/nodes/TweetNode/index.tsx
|
|
824
|
+
init_react_shim();
|
|
825
|
+
import { BlockWithAlignableContents as BlockWithAlignableContents3 } from "@lexical/react/LexicalBlockWithAlignableContents";
|
|
826
|
+
import {
|
|
827
|
+
DecoratorBlockNode as DecoratorBlockNode3
|
|
828
|
+
} from "@lexical/react/LexicalDecoratorBlockNode";
|
|
829
|
+
import * as React4 from "react";
|
|
830
|
+
import { useCallback, useEffect as useEffect5, useRef, useState } from "react";
|
|
831
|
+
var WIDGET_SCRIPT_URL = "https://platform.twitter.com/widgets.js";
|
|
832
|
+
function $convertTweetElement(domNode) {
|
|
833
|
+
const id = domNode.getAttribute("data-lexical-tweet-id");
|
|
834
|
+
if (id) {
|
|
835
|
+
const node = $createTweetNode(id);
|
|
836
|
+
return { node };
|
|
837
|
+
}
|
|
838
|
+
return null;
|
|
839
|
+
}
|
|
840
|
+
var isTwitterScriptLoading = true;
|
|
841
|
+
function TweetComponent({
|
|
842
|
+
className,
|
|
843
|
+
format,
|
|
844
|
+
nodeKey,
|
|
845
|
+
onError,
|
|
846
|
+
onLoad,
|
|
847
|
+
tweetID
|
|
848
|
+
}) {
|
|
849
|
+
const containerRef = useRef(null);
|
|
850
|
+
const previousTweetIDRef = useRef("");
|
|
851
|
+
const [isTweetLoading, setIsTweetLoading] = useState(false);
|
|
852
|
+
const createTweet = useCallback(async () => {
|
|
853
|
+
try {
|
|
854
|
+
await window.twttr.widgets.createTweet(tweetID, containerRef.current);
|
|
855
|
+
setIsTweetLoading(false);
|
|
856
|
+
isTwitterScriptLoading = false;
|
|
857
|
+
if (onLoad) {
|
|
858
|
+
onLoad();
|
|
859
|
+
}
|
|
860
|
+
} catch (error) {
|
|
861
|
+
if (onError) {
|
|
862
|
+
onError(String(error));
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
}, [onError, onLoad, tweetID]);
|
|
866
|
+
useEffect5(() => {
|
|
867
|
+
var _a;
|
|
868
|
+
if (tweetID !== previousTweetIDRef.current) {
|
|
869
|
+
setIsTweetLoading(true);
|
|
870
|
+
if (isTwitterScriptLoading) {
|
|
871
|
+
const script = document.createElement("script");
|
|
872
|
+
script.src = WIDGET_SCRIPT_URL;
|
|
873
|
+
script.async = true;
|
|
874
|
+
(_a = document.body) == null ? void 0 : _a.appendChild(script);
|
|
875
|
+
script.onload = createTweet;
|
|
876
|
+
if (onError) {
|
|
877
|
+
script.onerror = onError;
|
|
878
|
+
}
|
|
879
|
+
} else {
|
|
880
|
+
createTweet();
|
|
881
|
+
}
|
|
882
|
+
if (previousTweetIDRef) {
|
|
883
|
+
previousTweetIDRef.current = tweetID;
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
}, [createTweet, onError, tweetID]);
|
|
887
|
+
return /* @__PURE__ */ React4.createElement(
|
|
888
|
+
BlockWithAlignableContents3,
|
|
889
|
+
{
|
|
890
|
+
className,
|
|
891
|
+
format,
|
|
892
|
+
nodeKey
|
|
893
|
+
},
|
|
894
|
+
isTweetLoading ? /* @__PURE__ */ React4.createElement(Skeleton, { className: "max-h-[200px] w-full h-full max-w-[400px]" }) : null,
|
|
895
|
+
/* @__PURE__ */ React4.createElement(
|
|
896
|
+
"div",
|
|
897
|
+
{
|
|
898
|
+
style: {
|
|
899
|
+
display: "inline-block",
|
|
900
|
+
width: "100%"
|
|
901
|
+
},
|
|
902
|
+
ref: containerRef
|
|
903
|
+
}
|
|
904
|
+
)
|
|
905
|
+
);
|
|
906
|
+
}
|
|
907
|
+
var TweetNode = class _TweetNode extends DecoratorBlockNode3 {
|
|
908
|
+
static getType() {
|
|
909
|
+
return "tweet";
|
|
910
|
+
}
|
|
911
|
+
static clone(node) {
|
|
912
|
+
return new _TweetNode(node.__id, node.__format, node.__key);
|
|
913
|
+
}
|
|
914
|
+
static importJSON(serializedNode) {
|
|
915
|
+
return $createTweetNode(serializedNode.id).updateFromJSON(serializedNode);
|
|
916
|
+
}
|
|
917
|
+
exportJSON() {
|
|
918
|
+
return __spreadProps(__spreadValues({}, super.exportJSON()), {
|
|
919
|
+
id: this.getId()
|
|
920
|
+
});
|
|
921
|
+
}
|
|
922
|
+
static importDOM() {
|
|
923
|
+
return {
|
|
924
|
+
div: (domNode) => {
|
|
925
|
+
if (!domNode.hasAttribute("data-lexical-tweet-id")) {
|
|
926
|
+
return null;
|
|
927
|
+
}
|
|
928
|
+
return {
|
|
929
|
+
conversion: $convertTweetElement,
|
|
930
|
+
priority: 2
|
|
931
|
+
};
|
|
932
|
+
}
|
|
933
|
+
};
|
|
934
|
+
}
|
|
935
|
+
exportDOM() {
|
|
936
|
+
const element = document.createElement("div");
|
|
937
|
+
element.setAttribute("data-lexical-tweet-id", this.__id);
|
|
938
|
+
const text = document.createTextNode(this.getTextContent());
|
|
939
|
+
element.append(text);
|
|
940
|
+
return { element };
|
|
941
|
+
}
|
|
942
|
+
constructor(id, format, key) {
|
|
943
|
+
super(format, key);
|
|
944
|
+
this.__id = id;
|
|
945
|
+
}
|
|
946
|
+
getId() {
|
|
947
|
+
return this.__id;
|
|
948
|
+
}
|
|
949
|
+
getTextContent() {
|
|
950
|
+
return `https://x.com/i/web/status/${this.__id}`;
|
|
951
|
+
}
|
|
952
|
+
decorate(editor, config) {
|
|
953
|
+
const embedBlockTheme = config.theme.embedBlock || {};
|
|
954
|
+
const className = {
|
|
955
|
+
base: embedBlockTheme.base || "",
|
|
956
|
+
focus: embedBlockTheme.focus || ""
|
|
957
|
+
};
|
|
958
|
+
return /* @__PURE__ */ React4.createElement(
|
|
959
|
+
TweetComponent,
|
|
960
|
+
{
|
|
961
|
+
className,
|
|
962
|
+
format: this.__format,
|
|
963
|
+
loadingComponent: "Loading...",
|
|
964
|
+
nodeKey: this.getKey(),
|
|
965
|
+
tweetID: this.__id
|
|
966
|
+
}
|
|
967
|
+
);
|
|
968
|
+
}
|
|
969
|
+
};
|
|
970
|
+
function $createTweetNode(tweetID) {
|
|
971
|
+
return new TweetNode(tweetID);
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
// src/components/editor/plugins/TwitterPlugin/index.ts
|
|
975
|
+
var INSERT_TWEET_COMMAND = createCommand5(
|
|
976
|
+
"INSERT_TWEET_COMMAND"
|
|
977
|
+
);
|
|
978
|
+
function TwitterPlugin() {
|
|
979
|
+
const [editor] = useLexicalComposerContext5();
|
|
980
|
+
useEffect6(() => {
|
|
981
|
+
if (!editor.hasNodes([TweetNode])) {
|
|
982
|
+
throw new Error("TwitterPlugin: TweetNode not registered on editor");
|
|
983
|
+
}
|
|
984
|
+
return editor.registerCommand(
|
|
985
|
+
INSERT_TWEET_COMMAND,
|
|
986
|
+
(payload) => {
|
|
987
|
+
const tweetNode = $createTweetNode(payload);
|
|
988
|
+
$insertNodeToNearestRoot4(tweetNode);
|
|
989
|
+
return true;
|
|
990
|
+
},
|
|
991
|
+
COMMAND_PRIORITY_EDITOR5
|
|
992
|
+
);
|
|
993
|
+
}, [editor]);
|
|
994
|
+
return null;
|
|
995
|
+
}
|
|
996
|
+
|
|
997
|
+
// src/components/editor/plugins/AutoEmbedPlugin/index.tsx
|
|
998
|
+
import { Twitter, Youtube, Figma } from "lucide-react";
|
|
999
|
+
var YoutubeEmbedConfig = {
|
|
1000
|
+
contentName: "Youtube Video",
|
|
1001
|
+
exampleUrl: "https://www.youtube.com/watch?v=jNQXAC9IVRw",
|
|
1002
|
+
// Icon for display.
|
|
1003
|
+
icon: /* @__PURE__ */ React5.createElement(Youtube, { className: "h-4 w-4" }),
|
|
1004
|
+
insertNode: (editor, result) => {
|
|
1005
|
+
editor.dispatchCommand(INSERT_YOUTUBE_COMMAND, result.id);
|
|
1006
|
+
},
|
|
1007
|
+
keywords: ["youtube", "video"],
|
|
1008
|
+
// Determine if a given URL is a match and return url data.
|
|
1009
|
+
parseUrl: async (url) => {
|
|
1010
|
+
const match = /^.*(youtu\.be\/|v\/|u\/\w\/|embed\/|watch\?v=|&v=)([^#&?]*).*/.exec(url);
|
|
1011
|
+
const id = match ? (match == null ? void 0 : match[2].length) === 11 ? match[2] : null : null;
|
|
1012
|
+
if (id != null) {
|
|
1013
|
+
return {
|
|
1014
|
+
id,
|
|
1015
|
+
url
|
|
1016
|
+
};
|
|
1017
|
+
}
|
|
1018
|
+
return null;
|
|
1019
|
+
},
|
|
1020
|
+
type: "youtube-video"
|
|
1021
|
+
};
|
|
1022
|
+
var TwitterEmbedConfig = {
|
|
1023
|
+
// e.g. Tweet or Google Map.
|
|
1024
|
+
contentName: "Tweet",
|
|
1025
|
+
exampleUrl: "https://twitter.com/jack/status/20",
|
|
1026
|
+
// Icon for display.
|
|
1027
|
+
icon: /* @__PURE__ */ React5.createElement(Twitter, { className: "h-4 w-4" }),
|
|
1028
|
+
// Create the Lexical embed node from the url data.
|
|
1029
|
+
insertNode: (editor, result) => {
|
|
1030
|
+
editor.dispatchCommand(INSERT_TWEET_COMMAND, result.id);
|
|
1031
|
+
},
|
|
1032
|
+
// For extra searching.
|
|
1033
|
+
keywords: ["tweet", "twitter"],
|
|
1034
|
+
// Determine if a given URL is a match and return url data.
|
|
1035
|
+
parseUrl: (text) => {
|
|
1036
|
+
const match = /^https:\/\/(twitter|x)\.com\/(#!\/)?(\w+)\/status(es)*\/(\d+)/.exec(
|
|
1037
|
+
text
|
|
1038
|
+
);
|
|
1039
|
+
if (match != null) {
|
|
1040
|
+
return {
|
|
1041
|
+
id: match[5],
|
|
1042
|
+
url: match[1]
|
|
1043
|
+
};
|
|
1044
|
+
}
|
|
1045
|
+
return null;
|
|
1046
|
+
},
|
|
1047
|
+
type: "tweet"
|
|
1048
|
+
};
|
|
1049
|
+
var FigmaEmbedConfig = {
|
|
1050
|
+
contentName: "Figma Document",
|
|
1051
|
+
exampleUrl: "https://www.figma.com/file/LKQ4FJ4bTnCSjedbRpk931/Sample-File",
|
|
1052
|
+
icon: /* @__PURE__ */ React5.createElement(Figma, { className: "h-4 w-4" }),
|
|
1053
|
+
insertNode: (editor, result) => {
|
|
1054
|
+
editor.dispatchCommand(INSERT_FIGMA_COMMAND, result.id);
|
|
1055
|
+
},
|
|
1056
|
+
keywords: ["figma", "figma.com", "mock-up"],
|
|
1057
|
+
// Determine if a given URL is a match and return url data.
|
|
1058
|
+
parseUrl: (text) => {
|
|
1059
|
+
const match = /https:\/\/([\w.-]+\.)?figma.com\/(file|proto)\/([0-9a-zA-Z]{22,128})(?:\/.*)?$/.exec(
|
|
1060
|
+
text
|
|
1061
|
+
);
|
|
1062
|
+
if (match != null) {
|
|
1063
|
+
return {
|
|
1064
|
+
id: match[3],
|
|
1065
|
+
url: match[0]
|
|
1066
|
+
};
|
|
1067
|
+
}
|
|
1068
|
+
return null;
|
|
1069
|
+
},
|
|
1070
|
+
type: "figma"
|
|
1071
|
+
};
|
|
1072
|
+
var EmbedConfigs = [
|
|
1073
|
+
TwitterEmbedConfig,
|
|
1074
|
+
YoutubeEmbedConfig,
|
|
1075
|
+
FigmaEmbedConfig
|
|
1076
|
+
];
|
|
1077
|
+
function AutoEmbedMenuItem({
|
|
1078
|
+
index,
|
|
1079
|
+
isSelected,
|
|
1080
|
+
onClick,
|
|
1081
|
+
onMouseEnter,
|
|
1082
|
+
option
|
|
1083
|
+
}) {
|
|
1084
|
+
let className = "item";
|
|
1085
|
+
if (isSelected) {
|
|
1086
|
+
className += " selected";
|
|
1087
|
+
}
|
|
1088
|
+
return /* @__PURE__ */ React5.createElement(
|
|
1089
|
+
"li",
|
|
1090
|
+
{
|
|
1091
|
+
key: option.key,
|
|
1092
|
+
tabIndex: -1,
|
|
1093
|
+
className,
|
|
1094
|
+
ref: option.setRefElement,
|
|
1095
|
+
role: "option",
|
|
1096
|
+
"aria-selected": isSelected,
|
|
1097
|
+
id: "typeahead-item-" + index,
|
|
1098
|
+
onMouseEnter,
|
|
1099
|
+
onClick
|
|
1100
|
+
},
|
|
1101
|
+
/* @__PURE__ */ React5.createElement("span", { className: "text" }, option.title)
|
|
1102
|
+
);
|
|
1103
|
+
}
|
|
1104
|
+
function AutoEmbedMenu({
|
|
1105
|
+
options,
|
|
1106
|
+
selectedItemIndex,
|
|
1107
|
+
onOptionClick,
|
|
1108
|
+
onOptionMouseEnter
|
|
1109
|
+
}) {
|
|
1110
|
+
return /* @__PURE__ */ React5.createElement("div", { className: "typeahead-popover" }, /* @__PURE__ */ React5.createElement("ul", null, options.map((option, i) => /* @__PURE__ */ React5.createElement(
|
|
1111
|
+
AutoEmbedMenuItem,
|
|
1112
|
+
{
|
|
1113
|
+
index: i,
|
|
1114
|
+
isSelected: selectedItemIndex === i,
|
|
1115
|
+
onClick: () => onOptionClick(option, i),
|
|
1116
|
+
onMouseEnter: () => onOptionMouseEnter(i),
|
|
1117
|
+
key: option.key,
|
|
1118
|
+
option
|
|
1119
|
+
}
|
|
1120
|
+
))));
|
|
1121
|
+
}
|
|
1122
|
+
var debounce = (callback, delay) => {
|
|
1123
|
+
let timeoutId;
|
|
1124
|
+
return (text) => {
|
|
1125
|
+
window.clearTimeout(timeoutId);
|
|
1126
|
+
timeoutId = window.setTimeout(() => {
|
|
1127
|
+
callback(text);
|
|
1128
|
+
}, delay);
|
|
1129
|
+
};
|
|
1130
|
+
};
|
|
1131
|
+
function AutoEmbedDialog({
|
|
1132
|
+
embedConfig,
|
|
1133
|
+
onClose
|
|
1134
|
+
}) {
|
|
1135
|
+
const [text, setText] = useState2("");
|
|
1136
|
+
const [editor] = useLexicalComposerContext6();
|
|
1137
|
+
const [embedResult, setEmbedResult] = useState2(null);
|
|
1138
|
+
const validateText = useMemo(
|
|
1139
|
+
() => debounce((inputText) => {
|
|
1140
|
+
const urlMatch = URL_MATCHER.exec(inputText);
|
|
1141
|
+
if (embedConfig != null && inputText != null && urlMatch != null) {
|
|
1142
|
+
Promise.resolve(embedConfig.parseUrl(inputText)).then(
|
|
1143
|
+
(parseResult) => {
|
|
1144
|
+
setEmbedResult(parseResult);
|
|
1145
|
+
}
|
|
1146
|
+
);
|
|
1147
|
+
} else if (embedResult != null) {
|
|
1148
|
+
setEmbedResult(null);
|
|
1149
|
+
}
|
|
1150
|
+
}, 200),
|
|
1151
|
+
[embedConfig, embedResult]
|
|
1152
|
+
);
|
|
1153
|
+
const onClick = () => {
|
|
1154
|
+
if (embedResult != null) {
|
|
1155
|
+
embedConfig.insertNode(editor, embedResult);
|
|
1156
|
+
onClose();
|
|
1157
|
+
}
|
|
1158
|
+
};
|
|
1159
|
+
return /* @__PURE__ */ React5.createElement("div", { className: "flex items-center justify-center flex-col space-y-3" }, /* @__PURE__ */ React5.createElement("div", null, /* @__PURE__ */ React5.createElement(
|
|
1160
|
+
Input,
|
|
1161
|
+
{
|
|
1162
|
+
type: "text",
|
|
1163
|
+
className: "Input__input",
|
|
1164
|
+
placeholder: embedConfig.exampleUrl,
|
|
1165
|
+
value: text,
|
|
1166
|
+
"data-test-id": `${embedConfig.type}-embed-modal-url`,
|
|
1167
|
+
onChange: (e) => {
|
|
1168
|
+
const { value } = e.target;
|
|
1169
|
+
setText(value);
|
|
1170
|
+
validateText(value);
|
|
1171
|
+
}
|
|
1172
|
+
}
|
|
1173
|
+
)), /* @__PURE__ */ React5.createElement(
|
|
1174
|
+
Button,
|
|
1175
|
+
{
|
|
1176
|
+
disabled: !embedResult,
|
|
1177
|
+
onClick,
|
|
1178
|
+
"data-test-id": `${embedConfig.type}-embed-modal-submit-btn`
|
|
1179
|
+
},
|
|
1180
|
+
"Embed"
|
|
1181
|
+
));
|
|
1182
|
+
}
|
|
1183
|
+
function AutoEmbedPlugin() {
|
|
1184
|
+
const [modal, showModal] = useModal();
|
|
1185
|
+
const openEmbedModal = (embedConfig) => {
|
|
1186
|
+
showModal(`Embed ${embedConfig.contentName}`, "type the url", (onClose) => /* @__PURE__ */ React5.createElement(AutoEmbedDialog, { embedConfig, onClose }));
|
|
1187
|
+
};
|
|
1188
|
+
const getMenuOptions = (activeEmbedConfig, embedFn, dismissFn) => {
|
|
1189
|
+
return [
|
|
1190
|
+
new AutoEmbedOption("Dismiss", {
|
|
1191
|
+
onSelect: dismissFn
|
|
1192
|
+
}),
|
|
1193
|
+
new AutoEmbedOption(`Embed ${activeEmbedConfig.contentName}`, {
|
|
1194
|
+
onSelect: embedFn
|
|
1195
|
+
})
|
|
1196
|
+
];
|
|
1197
|
+
};
|
|
1198
|
+
return /* @__PURE__ */ React5.createElement(React5.Fragment, null, modal, /* @__PURE__ */ React5.createElement(
|
|
1199
|
+
LexicalAutoEmbedPlugin,
|
|
1200
|
+
{
|
|
1201
|
+
embedConfigs: EmbedConfigs,
|
|
1202
|
+
onOpenEmbedModalForConfig: openEmbedModal,
|
|
1203
|
+
getMenuOptions,
|
|
1204
|
+
menuRenderFn: (anchorElementRef, { selectedIndex, options, selectOptionAndCleanUp, setHighlightedIndex }) => anchorElementRef.current ? ReactDOM.createPortal(
|
|
1205
|
+
/* @__PURE__ */ React5.createElement(
|
|
1206
|
+
"div",
|
|
1207
|
+
{
|
|
1208
|
+
className: "typeahead-popover flex items-center auto-embed-menu",
|
|
1209
|
+
style: {
|
|
1210
|
+
marginLeft: `${Math.max(
|
|
1211
|
+
parseFloat(anchorElementRef.current.style.width) - 200,
|
|
1212
|
+
0
|
|
1213
|
+
)}px`,
|
|
1214
|
+
width: 200
|
|
1215
|
+
}
|
|
1216
|
+
},
|
|
1217
|
+
/* @__PURE__ */ React5.createElement(
|
|
1218
|
+
AutoEmbedMenu,
|
|
1219
|
+
{
|
|
1220
|
+
options,
|
|
1221
|
+
selectedItemIndex: selectedIndex,
|
|
1222
|
+
onOptionClick: (option, index) => {
|
|
1223
|
+
setHighlightedIndex(index);
|
|
1224
|
+
selectOptionAndCleanUp(option);
|
|
1225
|
+
},
|
|
1226
|
+
onOptionMouseEnter: (index) => {
|
|
1227
|
+
setHighlightedIndex(index);
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
)
|
|
1231
|
+
),
|
|
1232
|
+
anchorElementRef.current
|
|
1233
|
+
) : null
|
|
1234
|
+
}
|
|
1235
|
+
));
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1238
|
+
export {
|
|
1239
|
+
LayoutContainerNode,
|
|
1240
|
+
LayoutItemNode,
|
|
1241
|
+
INSERT_LAYOUT_COMMAND,
|
|
1242
|
+
LayoutPlugin,
|
|
1243
|
+
INSERT_COLLAPSIBLE_COMMAND,
|
|
1244
|
+
CollapsiblePlugin,
|
|
1245
|
+
TweetNode,
|
|
1246
|
+
TwitterPlugin,
|
|
1247
|
+
FigmaNode,
|
|
1248
|
+
FigmaPlugin,
|
|
1249
|
+
YouTubeNode,
|
|
1250
|
+
YouTubePlugin,
|
|
1251
|
+
YoutubeEmbedConfig,
|
|
1252
|
+
TwitterEmbedConfig,
|
|
1253
|
+
FigmaEmbedConfig,
|
|
1254
|
+
AutoEmbedDialog,
|
|
1255
|
+
AutoEmbedPlugin
|
|
1256
|
+
};
|