@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.cjs
CHANGED
|
@@ -78,10 +78,10 @@ let lucide_react = require("lucide-react");
|
|
|
78
78
|
let _radix_ui_react_popover = require("@radix-ui/react-popover");
|
|
79
79
|
_radix_ui_react_popover = __toESM(_radix_ui_react_popover);
|
|
80
80
|
let _tiptap_react_menus = require("@tiptap/react/menus");
|
|
81
|
+
let _floating_ui_react_dom = require("@floating-ui/react-dom");
|
|
81
82
|
let _tiptap_suggestion = require("@tiptap/suggestion");
|
|
82
83
|
_tiptap_suggestion = __toESM(_tiptap_suggestion);
|
|
83
|
-
let
|
|
84
|
-
tippy_js = __toESM(tippy_js);
|
|
84
|
+
let react_dom = require("react-dom");
|
|
85
85
|
|
|
86
86
|
//#region src/core/event-bus.ts
|
|
87
87
|
const EVENT_PREFIX = "@react-email/editor:";
|
|
@@ -3047,7 +3047,7 @@ function BubbleMenuNodeSelector({ omit = [], className, triggerContent, open, on
|
|
|
3047
3047
|
|
|
3048
3048
|
//#endregion
|
|
3049
3049
|
//#region src/ui/bubble-menu/root.tsx
|
|
3050
|
-
function BubbleMenuRoot({ excludeNodes = [], placement = "bottom", offset = 8, onHide, className, children }) {
|
|
3050
|
+
function BubbleMenuRoot({ excludeNodes = [], placement = "bottom", offset: offset$1 = 8, onHide, className, children }) {
|
|
3051
3051
|
const { editor } = (0, _tiptap_react.useCurrentEditor)();
|
|
3052
3052
|
if (!editor) return null;
|
|
3053
3053
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_tiptap_react_menus.BubbleMenu, {
|
|
@@ -3060,7 +3060,7 @@ function BubbleMenuRoot({ excludeNodes = [], placement = "bottom", offset = 8, o
|
|
|
3060
3060
|
},
|
|
3061
3061
|
options: {
|
|
3062
3062
|
placement,
|
|
3063
|
-
offset,
|
|
3063
|
+
offset: offset$1,
|
|
3064
3064
|
onHide
|
|
3065
3065
|
},
|
|
3066
3066
|
className,
|
|
@@ -3100,7 +3100,7 @@ const BubbleMenuUppercase = createMarkBubbleItem({
|
|
|
3100
3100
|
|
|
3101
3101
|
//#endregion
|
|
3102
3102
|
//#region src/ui/bubble-menu/default.tsx
|
|
3103
|
-
function BubbleMenuDefault({ excludeItems = [], excludeNodes, placement, offset, onHide, className }) {
|
|
3103
|
+
function BubbleMenuDefault({ excludeItems = [], excludeNodes, placement, offset: offset$1, onHide, className }) {
|
|
3104
3104
|
const [isNodeSelectorOpen, setIsNodeSelectorOpen] = react.useState(false);
|
|
3105
3105
|
const [isLinkSelectorOpen, setIsLinkSelectorOpen] = react.useState(false);
|
|
3106
3106
|
const has = (item) => !excludeItems.includes(item);
|
|
@@ -3122,7 +3122,7 @@ function BubbleMenuDefault({ excludeItems = [], excludeNodes, placement, offset,
|
|
|
3122
3122
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(BubbleMenuRoot, {
|
|
3123
3123
|
excludeNodes,
|
|
3124
3124
|
placement,
|
|
3125
|
-
offset,
|
|
3125
|
+
offset: offset$1,
|
|
3126
3126
|
onHide: handleHide,
|
|
3127
3127
|
className,
|
|
3128
3128
|
children: [
|
|
@@ -3219,7 +3219,7 @@ function ButtonBubbleMenuEditLink({ className, children, onClick, onMouseDown, .
|
|
|
3219
3219
|
|
|
3220
3220
|
//#endregion
|
|
3221
3221
|
//#region src/ui/button-bubble-menu/root.tsx
|
|
3222
|
-
function ButtonBubbleMenuRoot({ onHide, placement = "top", offset = 8, className, children }) {
|
|
3222
|
+
function ButtonBubbleMenuRoot({ onHide, placement = "top", offset: offset$1 = 8, className, children }) {
|
|
3223
3223
|
const { editor } = (0, _tiptap_react.useCurrentEditor)();
|
|
3224
3224
|
const [isEditing, setIsEditing] = react.useState(false);
|
|
3225
3225
|
if (!editor) return null;
|
|
@@ -3229,7 +3229,7 @@ function ButtonBubbleMenuRoot({ onHide, placement = "top", offset = 8, className
|
|
|
3229
3229
|
shouldShow: ({ editor: e, view }) => e.isActive("button") && !view.dom.classList.contains("dragging"),
|
|
3230
3230
|
options: {
|
|
3231
3231
|
placement,
|
|
3232
|
-
offset,
|
|
3232
|
+
offset: offset$1,
|
|
3233
3233
|
onHide: () => {
|
|
3234
3234
|
setIsEditing(false);
|
|
3235
3235
|
onHide?.();
|
|
@@ -3261,10 +3261,10 @@ function ButtonBubbleMenuToolbar({ children, ...rest }) {
|
|
|
3261
3261
|
|
|
3262
3262
|
//#endregion
|
|
3263
3263
|
//#region src/ui/button-bubble-menu/default.tsx
|
|
3264
|
-
function ButtonBubbleMenuDefault({ excludeItems = [], placement, offset, onHide, className }) {
|
|
3264
|
+
function ButtonBubbleMenuDefault({ excludeItems = [], placement, offset: offset$1, onHide, className }) {
|
|
3265
3265
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ButtonBubbleMenuRoot, {
|
|
3266
3266
|
placement,
|
|
3267
|
-
offset,
|
|
3267
|
+
offset: offset$1,
|
|
3268
3268
|
onHide,
|
|
3269
3269
|
className,
|
|
3270
3270
|
children: !excludeItems.includes("edit-link") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ButtonBubbleMenuToolbar, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ButtonBubbleMenuEditLink, {}) })
|
|
@@ -3314,7 +3314,7 @@ function ImageBubbleMenuEditLink({ className, children, onClick, onMouseDown, ..
|
|
|
3314
3314
|
|
|
3315
3315
|
//#endregion
|
|
3316
3316
|
//#region src/ui/image-bubble-menu/root.tsx
|
|
3317
|
-
function ImageBubbleMenuRoot({ onHide, placement = "top", offset = 8, className, children }) {
|
|
3317
|
+
function ImageBubbleMenuRoot({ onHide, placement = "top", offset: offset$1 = 8, className, children }) {
|
|
3318
3318
|
const { editor } = (0, _tiptap_react.useCurrentEditor)();
|
|
3319
3319
|
const [isEditing, setIsEditing] = react.useState(false);
|
|
3320
3320
|
if (!editor) return null;
|
|
@@ -3324,7 +3324,7 @@ function ImageBubbleMenuRoot({ onHide, placement = "top", offset = 8, className,
|
|
|
3324
3324
|
shouldShow: ({ editor: e, view }) => e.isActive("image") && !view.dom.classList.contains("dragging"),
|
|
3325
3325
|
options: {
|
|
3326
3326
|
placement,
|
|
3327
|
-
offset,
|
|
3327
|
+
offset: offset$1,
|
|
3328
3328
|
onHide: () => {
|
|
3329
3329
|
setIsEditing(false);
|
|
3330
3330
|
onHide?.();
|
|
@@ -3356,10 +3356,10 @@ function ImageBubbleMenuToolbar({ children, ...rest }) {
|
|
|
3356
3356
|
|
|
3357
3357
|
//#endregion
|
|
3358
3358
|
//#region src/ui/image-bubble-menu/default.tsx
|
|
3359
|
-
function ImageBubbleMenuDefault({ excludeItems = [], placement, offset, onHide, className }) {
|
|
3359
|
+
function ImageBubbleMenuDefault({ excludeItems = [], placement, offset: offset$1, onHide, className }) {
|
|
3360
3360
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ImageBubbleMenuRoot, {
|
|
3361
3361
|
placement,
|
|
3362
|
-
offset,
|
|
3362
|
+
offset: offset$1,
|
|
3363
3363
|
onHide,
|
|
3364
3364
|
className,
|
|
3365
3365
|
children: !excludeItems.includes("edit-link") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ImageBubbleMenuToolbar, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ImageBubbleMenuEditLink, {}) })
|
|
@@ -3531,7 +3531,7 @@ function LinkBubbleMenuOpenLink({ className, children, ...rest }) {
|
|
|
3531
3531
|
|
|
3532
3532
|
//#endregion
|
|
3533
3533
|
//#region src/ui/link-bubble-menu/root.tsx
|
|
3534
|
-
function LinkBubbleMenuRoot({ onHide, placement = "top", offset = 8, className, children }) {
|
|
3534
|
+
function LinkBubbleMenuRoot({ onHide, placement = "top", offset: offset$1 = 8, className, children }) {
|
|
3535
3535
|
const { editor } = (0, _tiptap_react.useCurrentEditor)();
|
|
3536
3536
|
const [isEditing, setIsEditing] = react.useState(false);
|
|
3537
3537
|
const linkHref = (0, _tiptap_react.useEditorState)({
|
|
@@ -3545,7 +3545,7 @@ function LinkBubbleMenuRoot({ onHide, placement = "top", offset = 8, className,
|
|
|
3545
3545
|
shouldShow: ({ editor: e }) => e.isActive("link") && e.view.state.selection.content().size === 0,
|
|
3546
3546
|
options: {
|
|
3547
3547
|
placement,
|
|
3548
|
-
offset,
|
|
3548
|
+
offset: offset$1,
|
|
3549
3549
|
onHide: () => {
|
|
3550
3550
|
setIsEditing(false);
|
|
3551
3551
|
onHide?.();
|
|
@@ -3601,11 +3601,11 @@ function LinkBubbleMenuUnlink({ className, children, onClick, onMouseDown, ...re
|
|
|
3601
3601
|
|
|
3602
3602
|
//#endregion
|
|
3603
3603
|
//#region src/ui/link-bubble-menu/default.tsx
|
|
3604
|
-
function LinkBubbleMenuDefault({ excludeItems = [], placement, offset, onHide, className, validateUrl, onLinkApply, onLinkRemove }) {
|
|
3604
|
+
function LinkBubbleMenuDefault({ excludeItems = [], placement, offset: offset$1, onHide, className, validateUrl, onLinkApply, onLinkRemove }) {
|
|
3605
3605
|
const has = (item) => !excludeItems.includes(item);
|
|
3606
3606
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(LinkBubbleMenuRoot, {
|
|
3607
3607
|
placement,
|
|
3608
|
-
offset,
|
|
3608
|
+
offset: offset$1,
|
|
3609
3609
|
onHide,
|
|
3610
3610
|
className,
|
|
3611
3611
|
children: [(has("edit-link") || has("open-link") || has("unlink")) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(LinkBubbleMenuToolbar, { children: [
|
|
@@ -3691,42 +3691,14 @@ function CommandItem({ item, selected, onSelect }) {
|
|
|
3691
3691
|
children: [item.icon, /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: item.title })]
|
|
3692
3692
|
});
|
|
3693
3693
|
}
|
|
3694
|
-
function CommandList({ items,
|
|
3695
|
-
const [selectedIndex, setSelectedIndex] = (0, react.useState)(0);
|
|
3694
|
+
function CommandList({ items, query, selectedIndex, onSelect }) {
|
|
3696
3695
|
const containerRef = (0, react.useRef)(null);
|
|
3697
|
-
(0, react.useEffect)(() => {
|
|
3698
|
-
setSelectedIndex(0);
|
|
3699
|
-
}, [items]);
|
|
3700
3696
|
(0, react.useLayoutEffect)(() => {
|
|
3701
3697
|
const container = containerRef.current;
|
|
3702
3698
|
if (!container) return;
|
|
3703
3699
|
const selected = container.querySelector("[data-selected]");
|
|
3704
3700
|
if (selected) updateScrollView(container, selected);
|
|
3705
3701
|
}, [selectedIndex]);
|
|
3706
|
-
const selectItem = (0, react.useCallback)((index) => {
|
|
3707
|
-
const item = items[index];
|
|
3708
|
-
if (item) command(item);
|
|
3709
|
-
}, [items, command]);
|
|
3710
|
-
(0, react.useImperativeHandle)(ref, () => ({ onKeyDown: ({ event }) => {
|
|
3711
|
-
if (items.length === 0) return false;
|
|
3712
|
-
if (event.key === "ArrowUp") {
|
|
3713
|
-
setSelectedIndex((i) => (i + items.length - 1) % items.length);
|
|
3714
|
-
return true;
|
|
3715
|
-
}
|
|
3716
|
-
if (event.key === "ArrowDown") {
|
|
3717
|
-
setSelectedIndex((i) => (i + 1) % items.length);
|
|
3718
|
-
return true;
|
|
3719
|
-
}
|
|
3720
|
-
if (event.key === "Enter") {
|
|
3721
|
-
selectItem(selectedIndex);
|
|
3722
|
-
return true;
|
|
3723
|
-
}
|
|
3724
|
-
return false;
|
|
3725
|
-
} }), [
|
|
3726
|
-
items.length,
|
|
3727
|
-
selectItem,
|
|
3728
|
-
selectedIndex
|
|
3729
|
-
]);
|
|
3730
3702
|
if (items.length === 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3731
3703
|
"data-re-slash-command": "",
|
|
3732
3704
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
@@ -3739,7 +3711,7 @@ function CommandList({ items, command, query, ref }) {
|
|
|
3739
3711
|
ref: containerRef,
|
|
3740
3712
|
children: items.map((item, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CommandItem, {
|
|
3741
3713
|
item,
|
|
3742
|
-
onSelect: () =>
|
|
3714
|
+
onSelect: () => onSelect(index),
|
|
3743
3715
|
selected: index === selectedIndex
|
|
3744
3716
|
}, item.title))
|
|
3745
3717
|
});
|
|
@@ -3755,7 +3727,7 @@ function CommandList({ items, command, query, ref }) {
|
|
|
3755
3727
|
const currentIndex = flatIndex++;
|
|
3756
3728
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CommandItem, {
|
|
3757
3729
|
item,
|
|
3758
|
-
onSelect: () =>
|
|
3730
|
+
onSelect: () => onSelect(currentIndex),
|
|
3759
3731
|
selected: currentIndex === selectedIndex
|
|
3760
3732
|
}, item.title);
|
|
3761
3733
|
})] }, group.category))
|
|
@@ -3973,76 +3945,6 @@ const defaultSlashCommands = [
|
|
|
3973
3945
|
FOUR_COLUMNS
|
|
3974
3946
|
];
|
|
3975
3947
|
|
|
3976
|
-
//#endregion
|
|
3977
|
-
//#region src/ui/slash-command/extension.ts
|
|
3978
|
-
const SlashCommandExtension = _tiptap_core.Extension.create({
|
|
3979
|
-
name: "slash-command",
|
|
3980
|
-
addOptions() {
|
|
3981
|
-
return { suggestion: {
|
|
3982
|
-
char: "/",
|
|
3983
|
-
allow: ({ editor }) => !editor.isActive("codeBlock"),
|
|
3984
|
-
command: ({ editor, range, props }) => {
|
|
3985
|
-
props.command({
|
|
3986
|
-
editor,
|
|
3987
|
-
range
|
|
3988
|
-
});
|
|
3989
|
-
}
|
|
3990
|
-
} };
|
|
3991
|
-
},
|
|
3992
|
-
addProseMirrorPlugins() {
|
|
3993
|
-
return [(0, _tiptap_suggestion.default)({
|
|
3994
|
-
pluginKey: new _tiptap_pm_state.PluginKey("slash-command"),
|
|
3995
|
-
editor: this.editor,
|
|
3996
|
-
...this.options.suggestion
|
|
3997
|
-
})];
|
|
3998
|
-
}
|
|
3999
|
-
});
|
|
4000
|
-
|
|
4001
|
-
//#endregion
|
|
4002
|
-
//#region src/ui/slash-command/render.tsx
|
|
4003
|
-
function createRenderItems(component = CommandList) {
|
|
4004
|
-
return () => {
|
|
4005
|
-
let renderer = null;
|
|
4006
|
-
let popup = null;
|
|
4007
|
-
return {
|
|
4008
|
-
onStart: (props) => {
|
|
4009
|
-
renderer = new _tiptap_react.ReactRenderer(component, {
|
|
4010
|
-
props,
|
|
4011
|
-
editor: props.editor
|
|
4012
|
-
});
|
|
4013
|
-
if (!props.clientRect) return;
|
|
4014
|
-
popup = (0, tippy_js.default)("body", {
|
|
4015
|
-
getReferenceClientRect: props.clientRect,
|
|
4016
|
-
appendTo: () => document.body,
|
|
4017
|
-
content: renderer.element,
|
|
4018
|
-
showOnCreate: true,
|
|
4019
|
-
interactive: true,
|
|
4020
|
-
trigger: "manual",
|
|
4021
|
-
placement: "bottom-start"
|
|
4022
|
-
});
|
|
4023
|
-
},
|
|
4024
|
-
onUpdate: (props) => {
|
|
4025
|
-
if (!renderer) return;
|
|
4026
|
-
renderer.updateProps(props);
|
|
4027
|
-
if (popup?.[0] && props.clientRect) popup[0].setProps({ getReferenceClientRect: props.clientRect });
|
|
4028
|
-
},
|
|
4029
|
-
onKeyDown: (props) => {
|
|
4030
|
-
if (props.event.key === "Escape") {
|
|
4031
|
-
popup?.[0]?.hide();
|
|
4032
|
-
return true;
|
|
4033
|
-
}
|
|
4034
|
-
return renderer?.ref?.onKeyDown(props) ?? false;
|
|
4035
|
-
},
|
|
4036
|
-
onExit: () => {
|
|
4037
|
-
popup?.[0]?.destroy();
|
|
4038
|
-
renderer?.destroy();
|
|
4039
|
-
popup = null;
|
|
4040
|
-
renderer = null;
|
|
4041
|
-
}
|
|
4042
|
-
};
|
|
4043
|
-
};
|
|
4044
|
-
}
|
|
4045
|
-
|
|
4046
3948
|
//#endregion
|
|
4047
3949
|
//#region src/ui/slash-command/search.ts
|
|
4048
3950
|
function scoreItem(item, query) {
|
|
@@ -4073,22 +3975,144 @@ function filterAndRankItems(items, query) {
|
|
|
4073
3975
|
}
|
|
4074
3976
|
|
|
4075
3977
|
//#endregion
|
|
4076
|
-
//#region src/ui/slash-command/
|
|
3978
|
+
//#region src/ui/slash-command/root.tsx
|
|
3979
|
+
const pluginKey = new _tiptap_pm_state.PluginKey("slash-command");
|
|
3980
|
+
const INITIAL_STATE = {
|
|
3981
|
+
active: false,
|
|
3982
|
+
query: "",
|
|
3983
|
+
items: [],
|
|
3984
|
+
clientRect: null
|
|
3985
|
+
};
|
|
4077
3986
|
function defaultFilterItems(items, query, editor) {
|
|
4078
3987
|
return filterAndRankItems(isAtMaxColumnsDepth(editor) ? items.filter((item) => item.category !== "Layout" || !item.title.includes("column")) : items, query);
|
|
4079
3988
|
}
|
|
4080
|
-
function
|
|
4081
|
-
const
|
|
4082
|
-
const
|
|
4083
|
-
|
|
4084
|
-
|
|
4085
|
-
|
|
4086
|
-
|
|
3989
|
+
function SlashCommandRoot({ items: itemsProp, filterItems: filterItemsProp, char = "/", allow: allowProp, children }) {
|
|
3990
|
+
const { editor } = (0, _tiptap_react.useCurrentEditor)();
|
|
3991
|
+
const [state, setState] = (0, react.useState)(INITIAL_STATE);
|
|
3992
|
+
const [selectedIndex, setSelectedIndex] = (0, react.useState)(0);
|
|
3993
|
+
const itemsRef = (0, react.useRef)(itemsProp ?? defaultSlashCommands);
|
|
3994
|
+
const filterRef = (0, react.useRef)(filterItemsProp ?? defaultFilterItems);
|
|
3995
|
+
const allowRef = (0, react.useRef)(allowProp ?? (({ editor: e }) => !e.isActive("codeBlock")));
|
|
3996
|
+
itemsRef.current = itemsProp ?? defaultSlashCommands;
|
|
3997
|
+
filterRef.current = filterItemsProp ?? defaultFilterItems;
|
|
3998
|
+
allowRef.current = allowProp ?? (({ editor: e }) => !e.isActive("codeBlock"));
|
|
3999
|
+
const commandRef = (0, react.useRef)(null);
|
|
4000
|
+
const suggestionItemsRef = (0, react.useRef)([]);
|
|
4001
|
+
const selectedIndexRef = (0, react.useRef)(0);
|
|
4002
|
+
suggestionItemsRef.current = state.items;
|
|
4003
|
+
selectedIndexRef.current = selectedIndex;
|
|
4004
|
+
const { refs, floatingStyles } = (0, _floating_ui_react_dom.useFloating)({
|
|
4005
|
+
open: state.active,
|
|
4006
|
+
placement: "bottom-start",
|
|
4007
|
+
middleware: [
|
|
4008
|
+
(0, _floating_ui_react_dom.offset)(8),
|
|
4009
|
+
(0, _floating_ui_react_dom.flip)(),
|
|
4010
|
+
(0, _floating_ui_react_dom.shift)({ padding: 8 })
|
|
4011
|
+
],
|
|
4012
|
+
whileElementsMounted: _floating_ui_react_dom.autoUpdate
|
|
4013
|
+
});
|
|
4014
|
+
(0, react.useEffect)(() => {
|
|
4015
|
+
if (!state.clientRect) return;
|
|
4016
|
+
refs.setReference({ getBoundingClientRect: state.clientRect });
|
|
4017
|
+
}, [state.clientRect, refs]);
|
|
4018
|
+
(0, react.useEffect)(() => {
|
|
4019
|
+
setSelectedIndex(0);
|
|
4020
|
+
}, [state.items]);
|
|
4021
|
+
const onSelect = (0, react.useCallback)((index) => {
|
|
4022
|
+
const item = suggestionItemsRef.current[index];
|
|
4023
|
+
if (item && commandRef.current) commandRef.current(item);
|
|
4024
|
+
}, []);
|
|
4025
|
+
(0, react.useEffect)(() => {
|
|
4026
|
+
if (!editor) return;
|
|
4027
|
+
const plugin = (0, _tiptap_suggestion.default)({
|
|
4028
|
+
pluginKey,
|
|
4029
|
+
editor,
|
|
4030
|
+
char,
|
|
4031
|
+
allow: ({ editor: e }) => allowRef.current({ editor: e }),
|
|
4032
|
+
command: ({ editor: e, range, props }) => {
|
|
4033
|
+
props.command({
|
|
4034
|
+
editor: e,
|
|
4035
|
+
range
|
|
4036
|
+
});
|
|
4037
|
+
},
|
|
4038
|
+
items: ({ query, editor: e }) => filterRef.current(itemsRef.current, query, e),
|
|
4039
|
+
render: () => ({
|
|
4040
|
+
onStart: (props) => {
|
|
4041
|
+
commandRef.current = props.command;
|
|
4042
|
+
setState({
|
|
4043
|
+
active: true,
|
|
4044
|
+
query: props.query,
|
|
4045
|
+
items: props.items,
|
|
4046
|
+
clientRect: props.clientRect ?? null
|
|
4047
|
+
});
|
|
4048
|
+
},
|
|
4049
|
+
onUpdate: (props) => {
|
|
4050
|
+
commandRef.current = props.command;
|
|
4051
|
+
setState({
|
|
4052
|
+
active: true,
|
|
4053
|
+
query: props.query,
|
|
4054
|
+
items: props.items,
|
|
4055
|
+
clientRect: props.clientRect ?? null
|
|
4056
|
+
});
|
|
4057
|
+
},
|
|
4058
|
+
onKeyDown: ({ event }) => {
|
|
4059
|
+
if (event.key === "Escape") {
|
|
4060
|
+
setState(INITIAL_STATE);
|
|
4061
|
+
return true;
|
|
4062
|
+
}
|
|
4063
|
+
const items = suggestionItemsRef.current;
|
|
4064
|
+
if (items.length === 0) return false;
|
|
4065
|
+
if (event.key === "ArrowUp") {
|
|
4066
|
+
setSelectedIndex((i) => (i + items.length - 1) % items.length);
|
|
4067
|
+
return true;
|
|
4068
|
+
}
|
|
4069
|
+
if (event.key === "ArrowDown") {
|
|
4070
|
+
setSelectedIndex((i) => (i + 1) % items.length);
|
|
4071
|
+
return true;
|
|
4072
|
+
}
|
|
4073
|
+
if (event.key === "Enter") {
|
|
4074
|
+
const item = items[selectedIndexRef.current];
|
|
4075
|
+
if (item && commandRef.current) commandRef.current(item);
|
|
4076
|
+
return true;
|
|
4077
|
+
}
|
|
4078
|
+
return false;
|
|
4079
|
+
},
|
|
4080
|
+
onExit: () => {
|
|
4081
|
+
setState(INITIAL_STATE);
|
|
4082
|
+
requestAnimationFrame(() => {
|
|
4083
|
+
commandRef.current = null;
|
|
4084
|
+
});
|
|
4085
|
+
}
|
|
4086
|
+
})
|
|
4087
|
+
});
|
|
4088
|
+
editor.registerPlugin(plugin, (newPlugin, plugins) => [newPlugin, ...plugins]);
|
|
4089
|
+
return () => {
|
|
4090
|
+
editor.unregisterPlugin(pluginKey);
|
|
4091
|
+
};
|
|
4092
|
+
}, [editor, char]);
|
|
4093
|
+
if (!editor || !state.active) return null;
|
|
4094
|
+
const renderProps = {
|
|
4095
|
+
items: state.items,
|
|
4096
|
+
query: state.query,
|
|
4097
|
+
selectedIndex,
|
|
4098
|
+
onSelect
|
|
4099
|
+
};
|
|
4100
|
+
let content;
|
|
4101
|
+
if (children) content = children(renderProps);
|
|
4102
|
+
else content = /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CommandList, { ...renderProps });
|
|
4103
|
+
return (0, react_dom.createPortal)(/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4104
|
+
ref: refs.setFloating,
|
|
4105
|
+
style: floatingStyles,
|
|
4106
|
+
children: content
|
|
4107
|
+
}), document.body);
|
|
4087
4108
|
}
|
|
4088
4109
|
|
|
4089
4110
|
//#endregion
|
|
4090
4111
|
//#region src/ui/slash-command/index.ts
|
|
4091
|
-
const SlashCommand =
|
|
4112
|
+
const SlashCommand = {
|
|
4113
|
+
Root: SlashCommandRoot,
|
|
4114
|
+
CommandList
|
|
4115
|
+
};
|
|
4092
4116
|
|
|
4093
4117
|
//#endregion
|
|
4094
4118
|
exports.AlignmentAttribute = AlignmentAttribute;
|
|
@@ -4187,7 +4211,6 @@ exports.TwoColumns = TwoColumns;
|
|
|
4187
4211
|
exports.Underline = Underline;
|
|
4188
4212
|
exports.Uppercase = Uppercase;
|
|
4189
4213
|
exports.composeReactEmail = composeReactEmail;
|
|
4190
|
-
exports.createSlashCommand = createSlashCommand;
|
|
4191
4214
|
exports.defaultSlashCommands = defaultSlashCommands;
|
|
4192
4215
|
exports.editorEventBus = editorEventBus;
|
|
4193
4216
|
exports.filterAndRankItems = filterAndRankItems;
|