@react-email/editor 0.0.0-experimental.21 → 0.0.0-experimental.22
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/dist/index.cjs +152 -129
- package/dist/index.d.cts +74 -63
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +74 -63
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +155 -130
- package/dist/index.mjs.map +1 -1
- package/dist/ui/themes/default.css +20 -1
- package/package.json +6 -5
package/dist/index.mjs
CHANGED
|
@@ -3,9 +3,9 @@ import { Body as Body$1, Button as Button$1, CodeBlock, Column, Head, Heading as
|
|
|
3
3
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
4
4
|
import { Extension, InputRule, Mark, Node as Node$1, findChildren, mergeAttributes } from "@tiptap/core";
|
|
5
5
|
import { UndoRedo } from "@tiptap/extensions";
|
|
6
|
-
import { NodeViewContent, NodeViewWrapper, ReactNodeViewRenderer,
|
|
6
|
+
import { NodeViewContent, NodeViewWrapper, ReactNodeViewRenderer, useCurrentEditor, useEditor as useEditor$1, useEditorState } from "@tiptap/react";
|
|
7
7
|
import * as React from "react";
|
|
8
|
-
import { useCallback, useEffect,
|
|
8
|
+
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from "react";
|
|
9
9
|
import TipTapStarterKit from "@tiptap/starter-kit";
|
|
10
10
|
import BlockquoteBase from "@tiptap/extension-blockquote";
|
|
11
11
|
import BoldBase from "@tiptap/extension-bold";
|
|
@@ -32,8 +32,9 @@ import { generateJSON } from "@tiptap/html";
|
|
|
32
32
|
import { AlignCenterIcon, AlignLeftIcon, AlignRightIcon, BoldIcon, CaseUpperIcon, Check, ChevronDown, Code as Code$1, CodeIcon, Columns2, Columns3, Columns4, ExternalLinkIcon, Heading1, Heading2, Heading3, ItalicIcon, LinkIcon, List, ListOrdered, MousePointer, PencilIcon, Rows2, SplitSquareVertical, SquareCode, StrikethroughIcon, Text, TextIcon, TextQuote, UnderlineIcon, UnlinkIcon } from "lucide-react";
|
|
33
33
|
import * as Popover from "@radix-ui/react-popover";
|
|
34
34
|
import { BubbleMenu as BubbleMenu$1 } from "@tiptap/react/menus";
|
|
35
|
+
import { autoUpdate, flip, offset, shift, useFloating } from "@floating-ui/react-dom";
|
|
35
36
|
import Suggestion from "@tiptap/suggestion";
|
|
36
|
-
import
|
|
37
|
+
import { createPortal } from "react-dom";
|
|
37
38
|
|
|
38
39
|
//#region src/core/event-bus.ts
|
|
39
40
|
const EVENT_PREFIX = "@react-email/editor:";
|
|
@@ -2999,7 +3000,7 @@ function BubbleMenuNodeSelector({ omit = [], className, triggerContent, open, on
|
|
|
2999
3000
|
|
|
3000
3001
|
//#endregion
|
|
3001
3002
|
//#region src/ui/bubble-menu/root.tsx
|
|
3002
|
-
function BubbleMenuRoot({ excludeNodes = [], placement = "bottom", offset = 8, onHide, className, children }) {
|
|
3003
|
+
function BubbleMenuRoot({ excludeNodes = [], placement = "bottom", offset: offset$1 = 8, onHide, className, children }) {
|
|
3003
3004
|
const { editor } = useCurrentEditor();
|
|
3004
3005
|
if (!editor) return null;
|
|
3005
3006
|
return /* @__PURE__ */ jsx(BubbleMenu$1, {
|
|
@@ -3012,7 +3013,7 @@ function BubbleMenuRoot({ excludeNodes = [], placement = "bottom", offset = 8, o
|
|
|
3012
3013
|
},
|
|
3013
3014
|
options: {
|
|
3014
3015
|
placement,
|
|
3015
|
-
offset,
|
|
3016
|
+
offset: offset$1,
|
|
3016
3017
|
onHide
|
|
3017
3018
|
},
|
|
3018
3019
|
className,
|
|
@@ -3052,7 +3053,7 @@ const BubbleMenuUppercase = createMarkBubbleItem({
|
|
|
3052
3053
|
|
|
3053
3054
|
//#endregion
|
|
3054
3055
|
//#region src/ui/bubble-menu/default.tsx
|
|
3055
|
-
function BubbleMenuDefault({ excludeItems = [], excludeNodes, placement, offset, onHide, className }) {
|
|
3056
|
+
function BubbleMenuDefault({ excludeItems = [], excludeNodes, placement, offset: offset$1, onHide, className }) {
|
|
3056
3057
|
const [isNodeSelectorOpen, setIsNodeSelectorOpen] = React.useState(false);
|
|
3057
3058
|
const [isLinkSelectorOpen, setIsLinkSelectorOpen] = React.useState(false);
|
|
3058
3059
|
const has = (item) => !excludeItems.includes(item);
|
|
@@ -3074,7 +3075,7 @@ function BubbleMenuDefault({ excludeItems = [], excludeNodes, placement, offset,
|
|
|
3074
3075
|
return /* @__PURE__ */ jsxs(BubbleMenuRoot, {
|
|
3075
3076
|
excludeNodes,
|
|
3076
3077
|
placement,
|
|
3077
|
-
offset,
|
|
3078
|
+
offset: offset$1,
|
|
3078
3079
|
onHide: handleHide,
|
|
3079
3080
|
className,
|
|
3080
3081
|
children: [
|
|
@@ -3171,7 +3172,7 @@ function ButtonBubbleMenuEditLink({ className, children, onClick, onMouseDown, .
|
|
|
3171
3172
|
|
|
3172
3173
|
//#endregion
|
|
3173
3174
|
//#region src/ui/button-bubble-menu/root.tsx
|
|
3174
|
-
function ButtonBubbleMenuRoot({ onHide, placement = "top", offset = 8, className, children }) {
|
|
3175
|
+
function ButtonBubbleMenuRoot({ onHide, placement = "top", offset: offset$1 = 8, className, children }) {
|
|
3175
3176
|
const { editor } = useCurrentEditor();
|
|
3176
3177
|
const [isEditing, setIsEditing] = React.useState(false);
|
|
3177
3178
|
if (!editor) return null;
|
|
@@ -3181,7 +3182,7 @@ function ButtonBubbleMenuRoot({ onHide, placement = "top", offset = 8, className
|
|
|
3181
3182
|
shouldShow: ({ editor: e, view }) => e.isActive("button") && !view.dom.classList.contains("dragging"),
|
|
3182
3183
|
options: {
|
|
3183
3184
|
placement,
|
|
3184
|
-
offset,
|
|
3185
|
+
offset: offset$1,
|
|
3185
3186
|
onHide: () => {
|
|
3186
3187
|
setIsEditing(false);
|
|
3187
3188
|
onHide?.();
|
|
@@ -3213,10 +3214,10 @@ function ButtonBubbleMenuToolbar({ children, ...rest }) {
|
|
|
3213
3214
|
|
|
3214
3215
|
//#endregion
|
|
3215
3216
|
//#region src/ui/button-bubble-menu/default.tsx
|
|
3216
|
-
function ButtonBubbleMenuDefault({ excludeItems = [], placement, offset, onHide, className }) {
|
|
3217
|
+
function ButtonBubbleMenuDefault({ excludeItems = [], placement, offset: offset$1, onHide, className }) {
|
|
3217
3218
|
return /* @__PURE__ */ jsx(ButtonBubbleMenuRoot, {
|
|
3218
3219
|
placement,
|
|
3219
|
-
offset,
|
|
3220
|
+
offset: offset$1,
|
|
3220
3221
|
onHide,
|
|
3221
3222
|
className,
|
|
3222
3223
|
children: !excludeItems.includes("edit-link") && /* @__PURE__ */ jsx(ButtonBubbleMenuToolbar, { children: /* @__PURE__ */ jsx(ButtonBubbleMenuEditLink, {}) })
|
|
@@ -3266,7 +3267,7 @@ function ImageBubbleMenuEditLink({ className, children, onClick, onMouseDown, ..
|
|
|
3266
3267
|
|
|
3267
3268
|
//#endregion
|
|
3268
3269
|
//#region src/ui/image-bubble-menu/root.tsx
|
|
3269
|
-
function ImageBubbleMenuRoot({ onHide, placement = "top", offset = 8, className, children }) {
|
|
3270
|
+
function ImageBubbleMenuRoot({ onHide, placement = "top", offset: offset$1 = 8, className, children }) {
|
|
3270
3271
|
const { editor } = useCurrentEditor();
|
|
3271
3272
|
const [isEditing, setIsEditing] = React.useState(false);
|
|
3272
3273
|
if (!editor) return null;
|
|
@@ -3276,7 +3277,7 @@ function ImageBubbleMenuRoot({ onHide, placement = "top", offset = 8, className,
|
|
|
3276
3277
|
shouldShow: ({ editor: e, view }) => e.isActive("image") && !view.dom.classList.contains("dragging"),
|
|
3277
3278
|
options: {
|
|
3278
3279
|
placement,
|
|
3279
|
-
offset,
|
|
3280
|
+
offset: offset$1,
|
|
3280
3281
|
onHide: () => {
|
|
3281
3282
|
setIsEditing(false);
|
|
3282
3283
|
onHide?.();
|
|
@@ -3308,10 +3309,10 @@ function ImageBubbleMenuToolbar({ children, ...rest }) {
|
|
|
3308
3309
|
|
|
3309
3310
|
//#endregion
|
|
3310
3311
|
//#region src/ui/image-bubble-menu/default.tsx
|
|
3311
|
-
function ImageBubbleMenuDefault({ excludeItems = [], placement, offset, onHide, className }) {
|
|
3312
|
+
function ImageBubbleMenuDefault({ excludeItems = [], placement, offset: offset$1, onHide, className }) {
|
|
3312
3313
|
return /* @__PURE__ */ jsx(ImageBubbleMenuRoot, {
|
|
3313
3314
|
placement,
|
|
3314
|
-
offset,
|
|
3315
|
+
offset: offset$1,
|
|
3315
3316
|
onHide,
|
|
3316
3317
|
className,
|
|
3317
3318
|
children: !excludeItems.includes("edit-link") && /* @__PURE__ */ jsx(ImageBubbleMenuToolbar, { children: /* @__PURE__ */ jsx(ImageBubbleMenuEditLink, {}) })
|
|
@@ -3483,7 +3484,7 @@ function LinkBubbleMenuOpenLink({ className, children, ...rest }) {
|
|
|
3483
3484
|
|
|
3484
3485
|
//#endregion
|
|
3485
3486
|
//#region src/ui/link-bubble-menu/root.tsx
|
|
3486
|
-
function LinkBubbleMenuRoot({ onHide, placement = "top", offset = 8, className, children }) {
|
|
3487
|
+
function LinkBubbleMenuRoot({ onHide, placement = "top", offset: offset$1 = 8, className, children }) {
|
|
3487
3488
|
const { editor } = useCurrentEditor();
|
|
3488
3489
|
const [isEditing, setIsEditing] = React.useState(false);
|
|
3489
3490
|
const linkHref = useEditorState({
|
|
@@ -3497,7 +3498,7 @@ function LinkBubbleMenuRoot({ onHide, placement = "top", offset = 8, className,
|
|
|
3497
3498
|
shouldShow: ({ editor: e }) => e.isActive("link") && e.view.state.selection.content().size === 0,
|
|
3498
3499
|
options: {
|
|
3499
3500
|
placement,
|
|
3500
|
-
offset,
|
|
3501
|
+
offset: offset$1,
|
|
3501
3502
|
onHide: () => {
|
|
3502
3503
|
setIsEditing(false);
|
|
3503
3504
|
onHide?.();
|
|
@@ -3553,11 +3554,11 @@ function LinkBubbleMenuUnlink({ className, children, onClick, onMouseDown, ...re
|
|
|
3553
3554
|
|
|
3554
3555
|
//#endregion
|
|
3555
3556
|
//#region src/ui/link-bubble-menu/default.tsx
|
|
3556
|
-
function LinkBubbleMenuDefault({ excludeItems = [], placement, offset, onHide, className, validateUrl, onLinkApply, onLinkRemove }) {
|
|
3557
|
+
function LinkBubbleMenuDefault({ excludeItems = [], placement, offset: offset$1, onHide, className, validateUrl, onLinkApply, onLinkRemove }) {
|
|
3557
3558
|
const has = (item) => !excludeItems.includes(item);
|
|
3558
3559
|
return /* @__PURE__ */ jsxs(LinkBubbleMenuRoot, {
|
|
3559
3560
|
placement,
|
|
3560
|
-
offset,
|
|
3561
|
+
offset: offset$1,
|
|
3561
3562
|
onHide,
|
|
3562
3563
|
className,
|
|
3563
3564
|
children: [(has("edit-link") || has("open-link") || has("unlink")) && /* @__PURE__ */ jsxs(LinkBubbleMenuToolbar, { children: [
|
|
@@ -3643,42 +3644,14 @@ function CommandItem({ item, selected, onSelect }) {
|
|
|
3643
3644
|
children: [item.icon, /* @__PURE__ */ jsx("span", { children: item.title })]
|
|
3644
3645
|
});
|
|
3645
3646
|
}
|
|
3646
|
-
function CommandList({ items,
|
|
3647
|
-
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
3647
|
+
function CommandList({ items, query, selectedIndex, onSelect }) {
|
|
3648
3648
|
const containerRef = useRef(null);
|
|
3649
|
-
useEffect(() => {
|
|
3650
|
-
setSelectedIndex(0);
|
|
3651
|
-
}, [items]);
|
|
3652
3649
|
useLayoutEffect(() => {
|
|
3653
3650
|
const container = containerRef.current;
|
|
3654
3651
|
if (!container) return;
|
|
3655
3652
|
const selected = container.querySelector("[data-selected]");
|
|
3656
3653
|
if (selected) updateScrollView(container, selected);
|
|
3657
3654
|
}, [selectedIndex]);
|
|
3658
|
-
const selectItem = useCallback((index) => {
|
|
3659
|
-
const item = items[index];
|
|
3660
|
-
if (item) command(item);
|
|
3661
|
-
}, [items, command]);
|
|
3662
|
-
useImperativeHandle(ref, () => ({ onKeyDown: ({ event }) => {
|
|
3663
|
-
if (items.length === 0) return false;
|
|
3664
|
-
if (event.key === "ArrowUp") {
|
|
3665
|
-
setSelectedIndex((i) => (i + items.length - 1) % items.length);
|
|
3666
|
-
return true;
|
|
3667
|
-
}
|
|
3668
|
-
if (event.key === "ArrowDown") {
|
|
3669
|
-
setSelectedIndex((i) => (i + 1) % items.length);
|
|
3670
|
-
return true;
|
|
3671
|
-
}
|
|
3672
|
-
if (event.key === "Enter") {
|
|
3673
|
-
selectItem(selectedIndex);
|
|
3674
|
-
return true;
|
|
3675
|
-
}
|
|
3676
|
-
return false;
|
|
3677
|
-
} }), [
|
|
3678
|
-
items.length,
|
|
3679
|
-
selectItem,
|
|
3680
|
-
selectedIndex
|
|
3681
|
-
]);
|
|
3682
3655
|
if (items.length === 0) return /* @__PURE__ */ jsx("div", {
|
|
3683
3656
|
"data-re-slash-command": "",
|
|
3684
3657
|
children: /* @__PURE__ */ jsx("div", {
|
|
@@ -3691,7 +3664,7 @@ function CommandList({ items, command, query, ref }) {
|
|
|
3691
3664
|
ref: containerRef,
|
|
3692
3665
|
children: items.map((item, index) => /* @__PURE__ */ jsx(CommandItem, {
|
|
3693
3666
|
item,
|
|
3694
|
-
onSelect: () =>
|
|
3667
|
+
onSelect: () => onSelect(index),
|
|
3695
3668
|
selected: index === selectedIndex
|
|
3696
3669
|
}, item.title))
|
|
3697
3670
|
});
|
|
@@ -3707,7 +3680,7 @@ function CommandList({ items, command, query, ref }) {
|
|
|
3707
3680
|
const currentIndex = flatIndex++;
|
|
3708
3681
|
return /* @__PURE__ */ jsx(CommandItem, {
|
|
3709
3682
|
item,
|
|
3710
|
-
onSelect: () =>
|
|
3683
|
+
onSelect: () => onSelect(currentIndex),
|
|
3711
3684
|
selected: currentIndex === selectedIndex
|
|
3712
3685
|
}, item.title);
|
|
3713
3686
|
})] }, group.category))
|
|
@@ -3925,76 +3898,6 @@ const defaultSlashCommands = [
|
|
|
3925
3898
|
FOUR_COLUMNS
|
|
3926
3899
|
];
|
|
3927
3900
|
|
|
3928
|
-
//#endregion
|
|
3929
|
-
//#region src/ui/slash-command/extension.ts
|
|
3930
|
-
const SlashCommandExtension = Extension.create({
|
|
3931
|
-
name: "slash-command",
|
|
3932
|
-
addOptions() {
|
|
3933
|
-
return { suggestion: {
|
|
3934
|
-
char: "/",
|
|
3935
|
-
allow: ({ editor }) => !editor.isActive("codeBlock"),
|
|
3936
|
-
command: ({ editor, range, props }) => {
|
|
3937
|
-
props.command({
|
|
3938
|
-
editor,
|
|
3939
|
-
range
|
|
3940
|
-
});
|
|
3941
|
-
}
|
|
3942
|
-
} };
|
|
3943
|
-
},
|
|
3944
|
-
addProseMirrorPlugins() {
|
|
3945
|
-
return [Suggestion({
|
|
3946
|
-
pluginKey: new PluginKey("slash-command"),
|
|
3947
|
-
editor: this.editor,
|
|
3948
|
-
...this.options.suggestion
|
|
3949
|
-
})];
|
|
3950
|
-
}
|
|
3951
|
-
});
|
|
3952
|
-
|
|
3953
|
-
//#endregion
|
|
3954
|
-
//#region src/ui/slash-command/render.tsx
|
|
3955
|
-
function createRenderItems(component = CommandList) {
|
|
3956
|
-
return () => {
|
|
3957
|
-
let renderer = null;
|
|
3958
|
-
let popup = null;
|
|
3959
|
-
return {
|
|
3960
|
-
onStart: (props) => {
|
|
3961
|
-
renderer = new ReactRenderer(component, {
|
|
3962
|
-
props,
|
|
3963
|
-
editor: props.editor
|
|
3964
|
-
});
|
|
3965
|
-
if (!props.clientRect) return;
|
|
3966
|
-
popup = tippy("body", {
|
|
3967
|
-
getReferenceClientRect: props.clientRect,
|
|
3968
|
-
appendTo: () => document.body,
|
|
3969
|
-
content: renderer.element,
|
|
3970
|
-
showOnCreate: true,
|
|
3971
|
-
interactive: true,
|
|
3972
|
-
trigger: "manual",
|
|
3973
|
-
placement: "bottom-start"
|
|
3974
|
-
});
|
|
3975
|
-
},
|
|
3976
|
-
onUpdate: (props) => {
|
|
3977
|
-
if (!renderer) return;
|
|
3978
|
-
renderer.updateProps(props);
|
|
3979
|
-
if (popup?.[0] && props.clientRect) popup[0].setProps({ getReferenceClientRect: props.clientRect });
|
|
3980
|
-
},
|
|
3981
|
-
onKeyDown: (props) => {
|
|
3982
|
-
if (props.event.key === "Escape") {
|
|
3983
|
-
popup?.[0]?.hide();
|
|
3984
|
-
return true;
|
|
3985
|
-
}
|
|
3986
|
-
return renderer?.ref?.onKeyDown(props) ?? false;
|
|
3987
|
-
},
|
|
3988
|
-
onExit: () => {
|
|
3989
|
-
popup?.[0]?.destroy();
|
|
3990
|
-
renderer?.destroy();
|
|
3991
|
-
popup = null;
|
|
3992
|
-
renderer = null;
|
|
3993
|
-
}
|
|
3994
|
-
};
|
|
3995
|
-
};
|
|
3996
|
-
}
|
|
3997
|
-
|
|
3998
3901
|
//#endregion
|
|
3999
3902
|
//#region src/ui/slash-command/search.ts
|
|
4000
3903
|
function scoreItem(item, query) {
|
|
@@ -4025,23 +3928,145 @@ function filterAndRankItems(items, query) {
|
|
|
4025
3928
|
}
|
|
4026
3929
|
|
|
4027
3930
|
//#endregion
|
|
4028
|
-
//#region src/ui/slash-command/
|
|
3931
|
+
//#region src/ui/slash-command/root.tsx
|
|
3932
|
+
const pluginKey = new PluginKey("slash-command");
|
|
3933
|
+
const INITIAL_STATE = {
|
|
3934
|
+
active: false,
|
|
3935
|
+
query: "",
|
|
3936
|
+
items: [],
|
|
3937
|
+
clientRect: null
|
|
3938
|
+
};
|
|
4029
3939
|
function defaultFilterItems(items, query, editor) {
|
|
4030
3940
|
return filterAndRankItems(isAtMaxColumnsDepth(editor) ? items.filter((item) => item.category !== "Layout" || !item.title.includes("column")) : items, query);
|
|
4031
3941
|
}
|
|
4032
|
-
function
|
|
4033
|
-
const
|
|
4034
|
-
const
|
|
4035
|
-
|
|
4036
|
-
|
|
4037
|
-
|
|
4038
|
-
|
|
3942
|
+
function SlashCommandRoot({ items: itemsProp, filterItems: filterItemsProp, char = "/", allow: allowProp, children }) {
|
|
3943
|
+
const { editor } = useCurrentEditor();
|
|
3944
|
+
const [state, setState] = useState(INITIAL_STATE);
|
|
3945
|
+
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
3946
|
+
const itemsRef = useRef(itemsProp ?? defaultSlashCommands);
|
|
3947
|
+
const filterRef = useRef(filterItemsProp ?? defaultFilterItems);
|
|
3948
|
+
const allowRef = useRef(allowProp ?? (({ editor: e }) => !e.isActive("codeBlock")));
|
|
3949
|
+
itemsRef.current = itemsProp ?? defaultSlashCommands;
|
|
3950
|
+
filterRef.current = filterItemsProp ?? defaultFilterItems;
|
|
3951
|
+
allowRef.current = allowProp ?? (({ editor: e }) => !e.isActive("codeBlock"));
|
|
3952
|
+
const commandRef = useRef(null);
|
|
3953
|
+
const suggestionItemsRef = useRef([]);
|
|
3954
|
+
const selectedIndexRef = useRef(0);
|
|
3955
|
+
suggestionItemsRef.current = state.items;
|
|
3956
|
+
selectedIndexRef.current = selectedIndex;
|
|
3957
|
+
const { refs, floatingStyles } = useFloating({
|
|
3958
|
+
open: state.active,
|
|
3959
|
+
placement: "bottom-start",
|
|
3960
|
+
middleware: [
|
|
3961
|
+
offset(8),
|
|
3962
|
+
flip(),
|
|
3963
|
+
shift({ padding: 8 })
|
|
3964
|
+
],
|
|
3965
|
+
whileElementsMounted: autoUpdate
|
|
3966
|
+
});
|
|
3967
|
+
useEffect(() => {
|
|
3968
|
+
if (!state.clientRect) return;
|
|
3969
|
+
refs.setReference({ getBoundingClientRect: state.clientRect });
|
|
3970
|
+
}, [state.clientRect, refs]);
|
|
3971
|
+
useEffect(() => {
|
|
3972
|
+
setSelectedIndex(0);
|
|
3973
|
+
}, [state.items]);
|
|
3974
|
+
const onSelect = useCallback((index) => {
|
|
3975
|
+
const item = suggestionItemsRef.current[index];
|
|
3976
|
+
if (item && commandRef.current) commandRef.current(item);
|
|
3977
|
+
}, []);
|
|
3978
|
+
useEffect(() => {
|
|
3979
|
+
if (!editor) return;
|
|
3980
|
+
const plugin = Suggestion({
|
|
3981
|
+
pluginKey,
|
|
3982
|
+
editor,
|
|
3983
|
+
char,
|
|
3984
|
+
allow: ({ editor: e }) => allowRef.current({ editor: e }),
|
|
3985
|
+
command: ({ editor: e, range, props }) => {
|
|
3986
|
+
props.command({
|
|
3987
|
+
editor: e,
|
|
3988
|
+
range
|
|
3989
|
+
});
|
|
3990
|
+
},
|
|
3991
|
+
items: ({ query, editor: e }) => filterRef.current(itemsRef.current, query, e),
|
|
3992
|
+
render: () => ({
|
|
3993
|
+
onStart: (props) => {
|
|
3994
|
+
commandRef.current = props.command;
|
|
3995
|
+
setState({
|
|
3996
|
+
active: true,
|
|
3997
|
+
query: props.query,
|
|
3998
|
+
items: props.items,
|
|
3999
|
+
clientRect: props.clientRect ?? null
|
|
4000
|
+
});
|
|
4001
|
+
},
|
|
4002
|
+
onUpdate: (props) => {
|
|
4003
|
+
commandRef.current = props.command;
|
|
4004
|
+
setState({
|
|
4005
|
+
active: true,
|
|
4006
|
+
query: props.query,
|
|
4007
|
+
items: props.items,
|
|
4008
|
+
clientRect: props.clientRect ?? null
|
|
4009
|
+
});
|
|
4010
|
+
},
|
|
4011
|
+
onKeyDown: ({ event }) => {
|
|
4012
|
+
if (event.key === "Escape") {
|
|
4013
|
+
setState(INITIAL_STATE);
|
|
4014
|
+
return true;
|
|
4015
|
+
}
|
|
4016
|
+
const items = suggestionItemsRef.current;
|
|
4017
|
+
if (items.length === 0) return false;
|
|
4018
|
+
if (event.key === "ArrowUp") {
|
|
4019
|
+
setSelectedIndex((i) => (i + items.length - 1) % items.length);
|
|
4020
|
+
return true;
|
|
4021
|
+
}
|
|
4022
|
+
if (event.key === "ArrowDown") {
|
|
4023
|
+
setSelectedIndex((i) => (i + 1) % items.length);
|
|
4024
|
+
return true;
|
|
4025
|
+
}
|
|
4026
|
+
if (event.key === "Enter") {
|
|
4027
|
+
const item = items[selectedIndexRef.current];
|
|
4028
|
+
if (item && commandRef.current) commandRef.current(item);
|
|
4029
|
+
return true;
|
|
4030
|
+
}
|
|
4031
|
+
return false;
|
|
4032
|
+
},
|
|
4033
|
+
onExit: () => {
|
|
4034
|
+
setState(INITIAL_STATE);
|
|
4035
|
+
requestAnimationFrame(() => {
|
|
4036
|
+
commandRef.current = null;
|
|
4037
|
+
});
|
|
4038
|
+
}
|
|
4039
|
+
})
|
|
4040
|
+
});
|
|
4041
|
+
editor.registerPlugin(plugin, (newPlugin, plugins) => [newPlugin, ...plugins]);
|
|
4042
|
+
return () => {
|
|
4043
|
+
editor.unregisterPlugin(pluginKey);
|
|
4044
|
+
};
|
|
4045
|
+
}, [editor, char]);
|
|
4046
|
+
if (!editor || !state.active) return null;
|
|
4047
|
+
const renderProps = {
|
|
4048
|
+
items: state.items,
|
|
4049
|
+
query: state.query,
|
|
4050
|
+
selectedIndex,
|
|
4051
|
+
onSelect
|
|
4052
|
+
};
|
|
4053
|
+
let content;
|
|
4054
|
+
if (children) content = children(renderProps);
|
|
4055
|
+
else content = /* @__PURE__ */ jsx(CommandList, { ...renderProps });
|
|
4056
|
+
return createPortal(/* @__PURE__ */ jsx("div", {
|
|
4057
|
+
ref: refs.setFloating,
|
|
4058
|
+
style: floatingStyles,
|
|
4059
|
+
children: content
|
|
4060
|
+
}), document.body);
|
|
4039
4061
|
}
|
|
4040
4062
|
|
|
4041
4063
|
//#endregion
|
|
4042
4064
|
//#region src/ui/slash-command/index.ts
|
|
4043
|
-
const SlashCommand =
|
|
4065
|
+
const SlashCommand = {
|
|
4066
|
+
Root: SlashCommandRoot,
|
|
4067
|
+
CommandList
|
|
4068
|
+
};
|
|
4044
4069
|
|
|
4045
4070
|
//#endregion
|
|
4046
|
-
export { AlignmentAttribute, BULLET_LIST, BUTTON, Blockquote, Body, Bold, BubbleMenu, BubbleMenuAlignCenter, BubbleMenuAlignLeft, BubbleMenuAlignRight, BubbleMenuBold, BubbleMenuCode, BubbleMenuDefault, BubbleMenuItalic, BubbleMenuItem, BubbleMenuItemGroup, BubbleMenuLinkSelector, BubbleMenuNodeSelector, BubbleMenuRoot, BubbleMenuSeparator, BubbleMenuStrike, BubbleMenuUnderline, BubbleMenuUppercase, BulletList, Button, ButtonBubbleMenu, ButtonBubbleMenuDefault, ButtonBubbleMenuEditLink, ButtonBubbleMenuRoot, ButtonBubbleMenuToolbar, CODE, COLUMN_PARENT_TYPES, ClassAttribute, Code, CodeBlockPrism, ColumnsColumn, CommandList, DIVIDER, Div, Divider, EmailNode, FOUR_COLUMNS, FourColumns, GlobalContent, H1, H2, H3, HardBreak, Heading, ImageBubbleMenu, ImageBubbleMenuDefault, ImageBubbleMenuEditLink, ImageBubbleMenuRoot, ImageBubbleMenuToolbar, Italic, Link, LinkBubbleMenu, LinkBubbleMenuDefault, LinkBubbleMenuEditLink, LinkBubbleMenuForm, LinkBubbleMenuOpenLink, LinkBubbleMenuRoot, LinkBubbleMenuToolbar, LinkBubbleMenuUnlink, ListItem, MAX_COLUMNS_DEPTH, MaxNesting, NUMBERED_LIST, NodeSelectorContent, NodeSelectorRoot, NodeSelectorTrigger, OrderedList, Paragraph, Placeholder, PreservedStyle, PreviewText, QUOTE, SECTION, Section, SlashCommand, StarterKit, Strike, StyleAttribute, Sup, TEXT, THREE_COLUMNS, TWO_COLUMNS, Table, TableCell, TableHeader, TableRow, ThreeColumns, TwoColumns, Underline, Uppercase, composeReactEmail,
|
|
4071
|
+
export { AlignmentAttribute, BULLET_LIST, BUTTON, Blockquote, Body, Bold, BubbleMenu, BubbleMenuAlignCenter, BubbleMenuAlignLeft, BubbleMenuAlignRight, BubbleMenuBold, BubbleMenuCode, BubbleMenuDefault, BubbleMenuItalic, BubbleMenuItem, BubbleMenuItemGroup, BubbleMenuLinkSelector, BubbleMenuNodeSelector, BubbleMenuRoot, BubbleMenuSeparator, BubbleMenuStrike, BubbleMenuUnderline, BubbleMenuUppercase, BulletList, Button, ButtonBubbleMenu, ButtonBubbleMenuDefault, ButtonBubbleMenuEditLink, ButtonBubbleMenuRoot, ButtonBubbleMenuToolbar, CODE, COLUMN_PARENT_TYPES, ClassAttribute, Code, CodeBlockPrism, ColumnsColumn, CommandList, DIVIDER, Div, Divider, EmailNode, FOUR_COLUMNS, FourColumns, GlobalContent, H1, H2, H3, HardBreak, Heading, ImageBubbleMenu, ImageBubbleMenuDefault, ImageBubbleMenuEditLink, ImageBubbleMenuRoot, ImageBubbleMenuToolbar, Italic, Link, LinkBubbleMenu, LinkBubbleMenuDefault, LinkBubbleMenuEditLink, LinkBubbleMenuForm, LinkBubbleMenuOpenLink, LinkBubbleMenuRoot, LinkBubbleMenuToolbar, LinkBubbleMenuUnlink, ListItem, MAX_COLUMNS_DEPTH, MaxNesting, NUMBERED_LIST, NodeSelectorContent, NodeSelectorRoot, NodeSelectorTrigger, OrderedList, Paragraph, Placeholder, PreservedStyle, PreviewText, QUOTE, SECTION, Section, SlashCommand, StarterKit, Strike, StyleAttribute, Sup, TEXT, THREE_COLUMNS, TWO_COLUMNS, Table, TableCell, TableHeader, TableRow, ThreeColumns, TwoColumns, Underline, Uppercase, composeReactEmail, defaultSlashCommands, editorEventBus, filterAndRankItems, getColumnsDepth, getGlobalContent, isAtMaxColumnsDepth, isDocumentVisuallyEmpty, isInsideNode, processStylesForUnlink, scoreItem, setTextAlignment, useButtonBubbleMenuContext, useEditor, useImageBubbleMenuContext, useLinkBubbleMenuContext };
|
|
4047
4072
|
//# sourceMappingURL=index.mjs.map
|