@firecms/editor 3.0.0-canary.18 → 3.0.0-canary.180
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 +114 -21
- package/dist/SampleCustomComponent.d.ts +10 -0
- package/dist/components/index.d.ts +0 -3
- package/dist/editor.d.ts +18 -2
- package/dist/editor_extensions.d.ts +6 -0
- package/dist/extensions/CustomBlockComponent.d.ts +7 -0
- package/dist/extensions/HighlightDecorationExtension.d.ts +35 -0
- package/dist/extensions/Image.d.ts +6 -3
- package/dist/extensions/InlineAutocomplete.d.ts +7 -0
- package/dist/extensions/TextLoadingDecorationExtension.d.ts +18 -0
- package/dist/extensions/_image-resizer.d.ts +0 -1
- package/dist/extensions/index.d.ts +1 -2
- package/dist/extensions/slashCommand.d.ts +92 -0
- package/dist/index.es.js +1852 -859
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +1939 -8
- package/dist/index.umd.js.map +1 -1
- package/dist/selectors/node-selector.d.ts +2 -1
- package/dist/types.d.ts +3 -0
- package/dist/utils/utils.d.ts +1 -1
- package/package.json +48 -33
- package/dist/components/editor-command-item.d.ts +0 -20
- package/dist/components/editor-command.d.ts +0 -24
- package/dist/components/editor.d.ts +0 -51
- package/dist/extensions/slash-command.d.ts +0 -29
- package/dist/extensions/updated-image.d.ts +0 -2
package/dist/index.es.js
CHANGED
@@ -1,973 +1,1960 @@
|
|
1
|
-
import { jsx
|
2
|
-
import
|
3
|
-
import
|
4
|
-
import
|
5
|
-
import
|
6
|
-
import { Markdown
|
7
|
-
import
|
8
|
-
import
|
9
|
-
import
|
10
|
-
import
|
11
|
-
import
|
12
|
-
import
|
13
|
-
import
|
14
|
-
import
|
15
|
-
import
|
16
|
-
import
|
17
|
-
import
|
18
|
-
import
|
19
|
-
import
|
20
|
-
import
|
21
|
-
import
|
22
|
-
import
|
23
|
-
import {
|
24
|
-
import {
|
25
|
-
import {
|
26
|
-
import {
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
const
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
}, [o, r]), C(() => {
|
67
|
-
const a = ["ArrowUp", "ArrowDown", "Enter"], c = (n) => {
|
68
|
-
if (a.includes(n.key)) {
|
69
|
-
n.preventDefault();
|
70
|
-
const i = document.querySelector("#slash-command");
|
71
|
-
i && i.dispatchEvent(
|
72
|
-
new KeyboardEvent("keydown", { key: n.key, cancelable: !0, bubbles: !0 })
|
73
|
-
);
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
2
|
+
import React, { forwardRef, useRef, useEffect, useState, useImperativeHandle, useMemo, useDeferredValue } from "react";
|
3
|
+
import { CheckIcon, TextFieldsIcon, LooksOneIcon, LooksTwoIcon, Looks3Icon, CheckBoxIcon, FormatListBulletedIcon, FormatListNumberedIcon, FormatQuoteIcon, CodeIcon, KeyboardArrowDownIcon, Button, Popover, cls, focusedDisabled, DeleteIcon, FormatBoldIcon, FormatItalicIcon, FormatUnderlinedIcon, FormatStrikethroughIcon, defaultBorderMixin, AutoFixHighIcon, ImageIcon, useInjectStyles, Separator } from "@firecms/ui";
|
4
|
+
import { useCurrentEditor, BubbleMenu, isNodeSelection, Node, mergeAttributes, ReactRenderer, EditorProvider } from "@tiptap/react";
|
5
|
+
import Document from "@tiptap/extension-document";
|
6
|
+
import { Markdown } from "tiptap-markdown";
|
7
|
+
import Underline from "@tiptap/extension-underline";
|
8
|
+
import Heading from "@tiptap/extension-heading";
|
9
|
+
import TextStyle from "@tiptap/extension-text-style";
|
10
|
+
import Color from "@tiptap/extension-color";
|
11
|
+
import Highlight from "@tiptap/extension-highlight";
|
12
|
+
import Bold from "@tiptap/extension-bold";
|
13
|
+
import Italic from "@tiptap/extension-italic";
|
14
|
+
import Strike from "@tiptap/extension-strike";
|
15
|
+
import { c } from "react-compiler-runtime";
|
16
|
+
import { Slot } from "@radix-ui/react-slot";
|
17
|
+
import StarterKit from "@tiptap/starter-kit";
|
18
|
+
import HorizontalRule from "@tiptap/extension-horizontal-rule";
|
19
|
+
import TiptapLink from "@tiptap/extension-link";
|
20
|
+
import TiptapImage from "@tiptap/extension-image";
|
21
|
+
import Placeholder from "@tiptap/extension-placeholder";
|
22
|
+
import { TaskItem } from "@tiptap/extension-task-item";
|
23
|
+
import { TaskList } from "@tiptap/extension-task-list";
|
24
|
+
import { Extension, InputRule } from "@tiptap/core";
|
25
|
+
import { PluginKey, Plugin } from "prosemirror-state";
|
26
|
+
import { DecorationSet, Decoration } from "prosemirror-view";
|
27
|
+
import OrderedList from "@tiptap/extension-ordered-list";
|
28
|
+
import BulletList from "@tiptap/extension-bullet-list";
|
29
|
+
import ListItem from "@tiptap/extension-list-item";
|
30
|
+
import CodeBlock from "@tiptap/extension-code-block";
|
31
|
+
import Blockquote from "@tiptap/extension-blockquote";
|
32
|
+
import Code from "@tiptap/extension-code";
|
33
|
+
import { DecorationSet as DecorationSet$1, Decoration as Decoration$1, __serializeForClipboard } from "@tiptap/pm/view";
|
34
|
+
import { PluginKey as PluginKey$1, Plugin as Plugin$1, NodeSelection } from "@tiptap/pm/state";
|
35
|
+
import Suggestion from "@tiptap/suggestion";
|
36
|
+
import tippy from "tippy.js";
|
37
|
+
const EditorBubble = forwardRef((t0, ref) => {
|
38
|
+
const $ = c(21);
|
39
|
+
let children;
|
40
|
+
let rest;
|
41
|
+
let tippyOptions;
|
42
|
+
if ($[0] !== t0) {
|
43
|
+
({
|
44
|
+
children,
|
45
|
+
tippyOptions,
|
46
|
+
...rest
|
47
|
+
} = t0);
|
48
|
+
$[0] = t0;
|
49
|
+
$[1] = children;
|
50
|
+
$[2] = rest;
|
51
|
+
$[3] = tippyOptions;
|
52
|
+
} else {
|
53
|
+
children = $[1];
|
54
|
+
rest = $[2];
|
55
|
+
tippyOptions = $[3];
|
56
|
+
}
|
57
|
+
const {
|
58
|
+
editor
|
59
|
+
} = useCurrentEditor();
|
60
|
+
const instanceRef = useRef(null);
|
61
|
+
let t1;
|
62
|
+
if ($[4] !== tippyOptions) {
|
63
|
+
t1 = () => {
|
64
|
+
if (!instanceRef.current || !tippyOptions?.placement) {
|
65
|
+
return;
|
74
66
|
}
|
67
|
+
instanceRef.current.setProps({
|
68
|
+
placement: tippyOptions.placement
|
69
|
+
});
|
70
|
+
instanceRef.current.popperInstance?.update();
|
75
71
|
};
|
76
|
-
|
77
|
-
|
72
|
+
$[4] = tippyOptions;
|
73
|
+
$[5] = t1;
|
74
|
+
} else {
|
75
|
+
t1 = $[5];
|
76
|
+
}
|
77
|
+
const t2 = tippyOptions?.placement;
|
78
|
+
let t3;
|
79
|
+
if ($[6] !== t2) {
|
80
|
+
t3 = [t2];
|
81
|
+
$[6] = t2;
|
82
|
+
$[7] = t3;
|
83
|
+
} else {
|
84
|
+
t3 = $[7];
|
85
|
+
}
|
86
|
+
useEffect(t1, t3);
|
87
|
+
let t4;
|
88
|
+
const shouldShow = _temp$1;
|
89
|
+
let t5;
|
90
|
+
if ($[8] === Symbol.for("react.memo_cache_sentinel")) {
|
91
|
+
t5 = (val) => {
|
92
|
+
instanceRef.current = val;
|
78
93
|
};
|
79
|
-
|
80
|
-
}
|
81
|
-
|
82
|
-
const a = D(null), [c, n] = we(ne);
|
83
|
-
return /* @__PURE__ */ s(re.In, { children: /* @__PURE__ */ b(
|
84
|
-
S,
|
85
|
-
{
|
86
|
-
ref: r,
|
87
|
-
onKeyDown: (i) => {
|
88
|
-
i.stopPropagation();
|
89
|
-
},
|
90
|
-
id: "slash-command",
|
91
|
-
className: o,
|
92
|
-
...t,
|
93
|
-
children: [
|
94
|
-
/* @__PURE__ */ s(S.Input, { value: c, onValueChange: n, style: { display: "none" } }),
|
95
|
-
/* @__PURE__ */ s(S.List, { ref: a, children: e })
|
96
|
-
]
|
97
|
-
}
|
98
|
-
) });
|
94
|
+
$[8] = t5;
|
95
|
+
} else {
|
96
|
+
t5 = $[8];
|
99
97
|
}
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
name: "slash-command",
|
107
|
-
addOptions() {
|
108
|
-
return {
|
109
|
-
suggestion: {
|
110
|
-
char: "/",
|
111
|
-
command: ({ editor: e, range: o, props: t }) => {
|
112
|
-
t.command({ editor: e, range: o });
|
113
|
-
}
|
114
|
-
}
|
98
|
+
let t6;
|
99
|
+
if ($[9] !== tippyOptions) {
|
100
|
+
t6 = {
|
101
|
+
onCreate: t5,
|
102
|
+
moveTransition: "transform 0.15s ease-out",
|
103
|
+
...tippyOptions
|
115
104
|
};
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
editor: this.editor,
|
121
|
-
...this.options.suggestion
|
122
|
-
})
|
123
|
-
];
|
105
|
+
$[9] = tippyOptions;
|
106
|
+
$[10] = t6;
|
107
|
+
} else {
|
108
|
+
t6 = $[10];
|
124
109
|
}
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
},
|
142
|
-
onUpdate: (t) => {
|
143
|
-
e?.updateProps(t), o && o[0].setProps({
|
144
|
-
getReferenceClientRect: t.clientRect
|
145
|
-
});
|
146
|
-
},
|
147
|
-
onKeyDown: (t) => t.event.key === "Escape" ? (o?.[0].hide(), !0) : e?.ref?.onKeyDown(t),
|
148
|
-
onExit: () => {
|
149
|
-
o?.[0].destroy(), e?.destroy();
|
150
|
-
}
|
151
|
-
};
|
152
|
-
}, at = (e) => e, st = Pe.configure({
|
153
|
-
placeholder: ({ node: e }) => e.type.name === "heading" ? `Heading ${e.attrs.level}` : "Press '/' for commands",
|
154
|
-
includeChildren: !0
|
155
|
-
}), it = Se.extend({
|
156
|
-
addInputRules() {
|
157
|
-
return [
|
158
|
-
new Be({
|
159
|
-
find: /^(?:---|—-|___\s|\*\*\*\s)$/,
|
160
|
-
handler: ({ state: e, range: o }) => {
|
161
|
-
const t = {}, { tr: r } = e, a = o.from, c = o.to;
|
162
|
-
r.insert(a - 1, this.type.create(t)).delete(
|
163
|
-
r.mapping.map(a),
|
164
|
-
r.mapping.map(c)
|
165
|
-
);
|
166
|
-
}
|
167
|
-
})
|
168
|
-
];
|
169
|
-
}
|
170
|
-
}), q = [
|
171
|
-
{
|
172
|
-
name: "Text",
|
173
|
-
icon: X,
|
174
|
-
command: (e) => e?.chain().focus().toggleNode("paragraph", "paragraph").run(),
|
175
|
-
// I feel like there has to be a more efficient way to do this – feel free to PR if you know how!
|
176
|
-
isActive: (e) => (e?.isActive("paragraph") && !e?.isActive("bulletList") && !e?.isActive("orderedList")) ?? !1
|
177
|
-
},
|
178
|
-
{
|
179
|
-
name: "Heading 1",
|
180
|
-
icon: Y,
|
181
|
-
command: (e) => e?.chain().focus().toggleHeading({ level: 1 }).run(),
|
182
|
-
isActive: (e) => e?.isActive("heading", { level: 1 }) ?? !1
|
183
|
-
},
|
184
|
-
{
|
185
|
-
name: "Heading 2",
|
186
|
-
icon: J,
|
187
|
-
command: (e) => e?.chain().focus().toggleHeading({ level: 2 }).run(),
|
188
|
-
isActive: (e) => e?.isActive("heading", { level: 2 }) ?? !1
|
189
|
-
},
|
190
|
-
{
|
191
|
-
name: "Heading 3",
|
192
|
-
icon: G,
|
193
|
-
command: (e) => e?.chain().focus().toggleHeading({ level: 3 }).run(),
|
194
|
-
isActive: (e) => e?.isActive("heading", { level: 3 }) ?? !1
|
195
|
-
},
|
196
|
-
{
|
197
|
-
name: "To-do List",
|
198
|
-
icon: j,
|
199
|
-
command: (e) => e?.chain().focus().toggleTaskList().run(),
|
200
|
-
isActive: (e) => e?.isActive("taskItem") ?? !1
|
201
|
-
},
|
202
|
-
{
|
203
|
-
name: "Bullet List",
|
204
|
-
icon: ee,
|
205
|
-
command: (e) => e?.chain().focus().toggleBulletList().run(),
|
206
|
-
isActive: (e) => e?.isActive("bulletList") ?? !1
|
207
|
-
},
|
208
|
-
{
|
209
|
-
name: "Numbered List",
|
210
|
-
icon: te,
|
211
|
-
command: (e) => e?.chain().focus().toggleOrderedList().run(),
|
212
|
-
isActive: (e) => e?.isActive("orderedList") ?? !1
|
213
|
-
},
|
214
|
-
{
|
215
|
-
name: "Quote",
|
216
|
-
icon: oe,
|
217
|
-
command: (e) => e?.chain().focus().toggleNode("paragraph", "paragraph").toggleBlockquote().run(),
|
218
|
-
isActive: (e) => e?.isActive("blockquote") ?? !1
|
219
|
-
},
|
220
|
-
{
|
221
|
-
name: "Code",
|
222
|
-
icon: z,
|
223
|
-
command: (e) => e?.chain().focus().toggleCodeBlock().run(),
|
224
|
-
isActive: (e) => e?.isActive("codeBlock") ?? !1
|
225
|
-
}
|
226
|
-
], ct = ({
|
227
|
-
open: e,
|
228
|
-
onOpenChange: o
|
229
|
-
}) => {
|
230
|
-
const { editor: t } = y();
|
231
|
-
if (!t)
|
110
|
+
let t7;
|
111
|
+
if ($[11] !== rest || $[12] !== t6) {
|
112
|
+
t7 = {
|
113
|
+
shouldShow,
|
114
|
+
tippyOptions: t6,
|
115
|
+
...rest
|
116
|
+
};
|
117
|
+
$[11] = rest;
|
118
|
+
$[12] = t6;
|
119
|
+
$[13] = t7;
|
120
|
+
} else {
|
121
|
+
t7 = $[13];
|
122
|
+
}
|
123
|
+
t4 = t7;
|
124
|
+
const bubbleMenuProps = t4;
|
125
|
+
if (!editor) {
|
232
126
|
return null;
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
127
|
+
}
|
128
|
+
let t8;
|
129
|
+
if ($[14] !== bubbleMenuProps || $[15] !== children || $[16] !== editor) {
|
130
|
+
t8 = /* @__PURE__ */ jsx(BubbleMenu, { editor, ...bubbleMenuProps, children });
|
131
|
+
$[14] = bubbleMenuProps;
|
132
|
+
$[15] = children;
|
133
|
+
$[16] = editor;
|
134
|
+
$[17] = t8;
|
135
|
+
} else {
|
136
|
+
t8 = $[17];
|
137
|
+
}
|
138
|
+
let t9;
|
139
|
+
if ($[18] !== ref || $[19] !== t8) {
|
140
|
+
t9 = /* @__PURE__ */ jsx("div", { ref, children: t8 });
|
141
|
+
$[18] = ref;
|
142
|
+
$[19] = t8;
|
143
|
+
$[20] = t9;
|
144
|
+
} else {
|
145
|
+
t9 = $[20];
|
146
|
+
}
|
147
|
+
return t9;
|
148
|
+
});
|
149
|
+
function _temp$1(t0) {
|
150
|
+
const {
|
151
|
+
editor: editor_0,
|
152
|
+
state
|
153
|
+
} = t0;
|
154
|
+
const {
|
155
|
+
selection
|
156
|
+
} = state;
|
157
|
+
const {
|
158
|
+
empty
|
159
|
+
} = selection;
|
160
|
+
if (editor_0.isActive("image") || empty || isNodeSelection(selection)) {
|
161
|
+
return false;
|
162
|
+
}
|
163
|
+
return true;
|
164
|
+
}
|
165
|
+
const EditorBubbleItem = forwardRef((t0, ref) => {
|
166
|
+
const $ = c(14);
|
167
|
+
let asChild;
|
168
|
+
let children;
|
169
|
+
let onSelect;
|
170
|
+
let rest;
|
171
|
+
if ($[0] !== t0) {
|
172
|
+
({
|
173
|
+
children,
|
174
|
+
asChild,
|
175
|
+
onSelect,
|
176
|
+
...rest
|
177
|
+
} = t0);
|
178
|
+
$[0] = t0;
|
179
|
+
$[1] = asChild;
|
180
|
+
$[2] = children;
|
181
|
+
$[3] = onSelect;
|
182
|
+
$[4] = rest;
|
183
|
+
} else {
|
184
|
+
asChild = $[1];
|
185
|
+
children = $[2];
|
186
|
+
onSelect = $[3];
|
187
|
+
rest = $[4];
|
188
|
+
}
|
189
|
+
const {
|
190
|
+
editor
|
191
|
+
} = useCurrentEditor();
|
192
|
+
const Comp = asChild ? Slot : "div";
|
193
|
+
if (!editor) {
|
194
|
+
return null;
|
195
|
+
}
|
196
|
+
let t1;
|
197
|
+
if ($[5] !== editor || $[6] !== onSelect) {
|
198
|
+
t1 = () => onSelect?.(editor);
|
199
|
+
$[5] = editor;
|
200
|
+
$[6] = onSelect;
|
201
|
+
$[7] = t1;
|
202
|
+
} else {
|
203
|
+
t1 = $[7];
|
204
|
+
}
|
205
|
+
let t2;
|
206
|
+
if ($[8] !== Comp || $[9] !== children || $[10] !== ref || $[11] !== rest || $[12] !== t1) {
|
207
|
+
t2 = /* @__PURE__ */ jsx(Comp, { ref, ...rest, onClick: t1, children });
|
208
|
+
$[8] = Comp;
|
209
|
+
$[9] = children;
|
210
|
+
$[10] = ref;
|
211
|
+
$[11] = rest;
|
212
|
+
$[12] = t1;
|
213
|
+
$[13] = t2;
|
214
|
+
} else {
|
215
|
+
t2 = $[13];
|
216
|
+
}
|
217
|
+
return t2;
|
218
|
+
});
|
219
|
+
EditorBubbleItem.displayName = "EditorBubbleItem";
|
220
|
+
const items = [{
|
221
|
+
name: "Text",
|
222
|
+
icon: TextFieldsIcon,
|
223
|
+
command: (editor) => editor?.chain().focus().toggleNode("paragraph", "paragraph").run(),
|
224
|
+
// I feel like there has to be a more efficient way to do this – feel free to PR if you know how!
|
225
|
+
isActive: (editor) => (editor?.isActive("paragraph") && !editor?.isActive("bulletList") && !editor?.isActive("orderedList")) ?? false
|
226
|
+
}, {
|
227
|
+
name: "Heading 1",
|
228
|
+
icon: LooksOneIcon,
|
229
|
+
command: (editor) => editor?.chain().focus().toggleHeading({
|
230
|
+
level: 1
|
231
|
+
}).run(),
|
232
|
+
isActive: (editor) => editor?.isActive("heading", {
|
233
|
+
level: 1
|
234
|
+
}) ?? false
|
235
|
+
}, {
|
236
|
+
name: "Heading 2",
|
237
|
+
icon: LooksTwoIcon,
|
238
|
+
command: (editor) => editor?.chain().focus().toggleHeading({
|
239
|
+
level: 2
|
240
|
+
}).run(),
|
241
|
+
isActive: (editor) => editor?.isActive("heading", {
|
242
|
+
level: 2
|
243
|
+
}) ?? false
|
244
|
+
}, {
|
245
|
+
name: "Heading 3",
|
246
|
+
icon: Looks3Icon,
|
247
|
+
command: (editor) => editor?.chain().focus().toggleHeading({
|
248
|
+
level: 3
|
249
|
+
}).run(),
|
250
|
+
isActive: (editor) => editor?.isActive("heading", {
|
251
|
+
level: 3
|
252
|
+
}) ?? false
|
253
|
+
}, {
|
254
|
+
name: "To-do List",
|
255
|
+
icon: CheckBoxIcon,
|
256
|
+
command: (editor) => editor?.chain().focus().toggleTaskList().run(),
|
257
|
+
isActive: (editor) => editor?.isActive("taskItem") ?? false
|
258
|
+
}, {
|
259
|
+
name: "Bullet List",
|
260
|
+
icon: FormatListBulletedIcon,
|
261
|
+
command: (editor) => editor?.chain().focus().toggleBulletList().run(),
|
262
|
+
isActive: (editor) => editor?.isActive("bulletList") ?? false
|
263
|
+
}, {
|
264
|
+
name: "Numbered List",
|
265
|
+
icon: FormatListNumberedIcon,
|
266
|
+
command: (editor) => editor?.chain().focus().toggleOrderedList().run(),
|
267
|
+
isActive: (editor) => editor?.isActive("orderedList") ?? false
|
268
|
+
}, {
|
269
|
+
name: "Quote",
|
270
|
+
icon: FormatQuoteIcon,
|
271
|
+
command: (editor) => editor?.chain().focus().toggleNode("paragraph", "paragraph").toggleBlockquote().run(),
|
272
|
+
isActive: (editor) => editor?.isActive("blockquote") ?? false
|
273
|
+
}, {
|
274
|
+
name: "Code",
|
275
|
+
icon: CodeIcon,
|
276
|
+
command: (editor) => editor?.chain().focus().toggleCodeBlock().run(),
|
277
|
+
isActive: (editor) => editor?.isActive("codeBlock") ?? false
|
278
|
+
}];
|
279
|
+
const NodeSelector = (t0) => {
|
280
|
+
const $ = c(16);
|
281
|
+
const {
|
282
|
+
open,
|
283
|
+
onOpenChange,
|
284
|
+
portalContainer
|
285
|
+
} = t0;
|
286
|
+
const {
|
287
|
+
editor
|
288
|
+
} = useCurrentEditor();
|
289
|
+
if (!editor) {
|
290
|
+
return null;
|
291
|
+
}
|
292
|
+
let t1;
|
293
|
+
if ($[0] !== editor) {
|
294
|
+
t1 = items.filter((item) => item.isActive(editor)).pop() ?? {
|
295
|
+
name: "Multiple"
|
296
|
+
};
|
297
|
+
$[0] = editor;
|
298
|
+
$[1] = t1;
|
299
|
+
} else {
|
300
|
+
t1 = $[1];
|
301
|
+
}
|
302
|
+
const activeItem = t1;
|
303
|
+
let t2;
|
304
|
+
if ($[2] !== activeItem.name) {
|
305
|
+
t2 = /* @__PURE__ */ jsx("span", { className: "whitespace-nowrap text-sm", children: activeItem.name });
|
306
|
+
$[2] = activeItem.name;
|
307
|
+
$[3] = t2;
|
308
|
+
} else {
|
309
|
+
t2 = $[3];
|
310
|
+
}
|
311
|
+
let t3;
|
312
|
+
if ($[4] === Symbol.for("react.memo_cache_sentinel")) {
|
313
|
+
t3 = /* @__PURE__ */ jsx(KeyboardArrowDownIcon, { size: "small" });
|
314
|
+
$[4] = t3;
|
315
|
+
} else {
|
316
|
+
t3 = $[4];
|
317
|
+
}
|
318
|
+
let t4;
|
319
|
+
if ($[5] !== t2) {
|
320
|
+
t4 = /* @__PURE__ */ jsxs(Button, { variant: "text", className: "gap-2 rounded-none", color: "text", children: [
|
321
|
+
t2,
|
322
|
+
t3
|
323
|
+
] });
|
324
|
+
$[5] = t2;
|
325
|
+
$[6] = t4;
|
326
|
+
} else {
|
327
|
+
t4 = $[6];
|
328
|
+
}
|
329
|
+
let t5;
|
330
|
+
if ($[7] !== activeItem.name || $[8] !== onOpenChange) {
|
331
|
+
t5 = items.map((item_0, index) => /* @__PURE__ */ jsxs(EditorBubbleItem, { onSelect: (editor_0) => {
|
332
|
+
item_0.command(editor_0);
|
333
|
+
onOpenChange(false);
|
334
|
+
}, className: "flex cursor-pointer items-center justify-between rounded px-2 py-1 text-sm hover:bg-blue-50 hover:dark:bg-surface-700 text-surface-900 dark:text-white", children: [
|
335
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center space-x-2", children: [
|
336
|
+
/* @__PURE__ */ jsx(item_0.icon, { size: "smallest" }),
|
337
|
+
/* @__PURE__ */ jsx("span", { children: item_0.name })
|
338
|
+
] }),
|
339
|
+
activeItem.name === item_0.name && /* @__PURE__ */ jsx(CheckIcon, { size: "smallest" })
|
340
|
+
] }, index));
|
341
|
+
$[7] = activeItem.name;
|
342
|
+
$[8] = onOpenChange;
|
343
|
+
$[9] = t5;
|
344
|
+
} else {
|
345
|
+
t5 = $[9];
|
346
|
+
}
|
347
|
+
let t6;
|
348
|
+
if ($[10] !== onOpenChange || $[11] !== open || $[12] !== portalContainer || $[13] !== t4 || $[14] !== t5) {
|
349
|
+
t6 = /* @__PURE__ */ jsx(Popover, { sideOffset: 5, align: "start", portalContainer, className: "w-48 p-1", trigger: t4, modal: true, open, onOpenChange, children: t5 });
|
350
|
+
$[10] = onOpenChange;
|
351
|
+
$[11] = open;
|
352
|
+
$[12] = portalContainer;
|
353
|
+
$[13] = t4;
|
354
|
+
$[14] = t5;
|
355
|
+
$[15] = t6;
|
356
|
+
} else {
|
357
|
+
t6 = $[15];
|
358
|
+
}
|
359
|
+
return t6;
|
276
360
|
};
|
277
|
-
function
|
361
|
+
function isValidUrl(url) {
|
278
362
|
try {
|
279
|
-
|
280
|
-
|
281
|
-
|
363
|
+
new URL(url);
|
364
|
+
return true;
|
365
|
+
} catch (e) {
|
366
|
+
return false;
|
282
367
|
}
|
283
368
|
}
|
284
|
-
function
|
285
|
-
if (
|
286
|
-
return e;
|
369
|
+
function getUrlFromString(str) {
|
370
|
+
if (isValidUrl(str)) return str;
|
287
371
|
try {
|
288
|
-
|
289
|
-
|
372
|
+
if (str.includes(".") && !str.includes(" ")) {
|
373
|
+
return new URL(`https://${str}`).toString();
|
374
|
+
}
|
375
|
+
return null;
|
376
|
+
} catch (e) {
|
290
377
|
return null;
|
291
378
|
}
|
292
379
|
}
|
293
|
-
const
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
}
|
365
|
-
|
366
|
-
|
367
|
-
{
|
380
|
+
const LinkSelector = (t0) => {
|
381
|
+
const $ = c(24);
|
382
|
+
const {
|
383
|
+
open,
|
384
|
+
onOpenChange
|
385
|
+
} = t0;
|
386
|
+
const inputRef = useRef(null);
|
387
|
+
const {
|
388
|
+
editor
|
389
|
+
} = useCurrentEditor();
|
390
|
+
let t1;
|
391
|
+
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
392
|
+
t1 = () => {
|
393
|
+
inputRef.current && inputRef.current?.focus();
|
394
|
+
};
|
395
|
+
$[0] = t1;
|
396
|
+
} else {
|
397
|
+
t1 = $[0];
|
398
|
+
}
|
399
|
+
useEffect(t1);
|
400
|
+
if (!editor) {
|
401
|
+
return null;
|
402
|
+
}
|
403
|
+
let t2;
|
404
|
+
if ($[1] !== editor) {
|
405
|
+
t2 = cls("underline decoration-stone-400 underline-offset-4", {
|
406
|
+
"text-blue-500": editor.isActive("link")
|
407
|
+
});
|
408
|
+
$[1] = editor;
|
409
|
+
$[2] = t2;
|
410
|
+
} else {
|
411
|
+
t2 = $[2];
|
412
|
+
}
|
413
|
+
let t3;
|
414
|
+
if ($[3] !== t2) {
|
415
|
+
t3 = /* @__PURE__ */ jsx(Button, { variant: "text", className: "gap-2 rounded-none", color: "text", children: /* @__PURE__ */ jsx("p", { className: t2, children: "Link" }) });
|
416
|
+
$[3] = t2;
|
417
|
+
$[4] = t3;
|
418
|
+
} else {
|
419
|
+
t3 = $[4];
|
420
|
+
}
|
421
|
+
let t4;
|
422
|
+
if ($[5] !== editor) {
|
423
|
+
t4 = (e) => {
|
424
|
+
const target = e.currentTarget;
|
425
|
+
e.preventDefault();
|
426
|
+
const input = target[0];
|
427
|
+
const url = getUrlFromString(input.value);
|
428
|
+
url && editor.chain().focus().setLink({
|
429
|
+
href: url
|
430
|
+
}).run();
|
431
|
+
};
|
432
|
+
$[5] = editor;
|
433
|
+
$[6] = t4;
|
434
|
+
} else {
|
435
|
+
t4 = $[6];
|
436
|
+
}
|
437
|
+
let t5;
|
438
|
+
if ($[7] !== editor) {
|
439
|
+
t5 = editor.getAttributes("link").href || "";
|
440
|
+
$[7] = editor;
|
441
|
+
$[8] = t5;
|
442
|
+
} else {
|
443
|
+
t5 = $[8];
|
444
|
+
}
|
445
|
+
let t6;
|
446
|
+
if ($[9] === Symbol.for("react.memo_cache_sentinel")) {
|
447
|
+
t6 = cls("text-surface-900 dark:text-white flex-grow bg-transparent p-1 text-sm outline-none", focusedDisabled);
|
448
|
+
$[9] = t6;
|
449
|
+
} else {
|
450
|
+
t6 = $[9];
|
451
|
+
}
|
452
|
+
let t7;
|
453
|
+
if ($[10] !== open || $[11] !== t5) {
|
454
|
+
t7 = /* @__PURE__ */ jsx("input", { ref: inputRef, autoFocus: open, placeholder: "Paste a link", defaultValue: t5, className: t6 });
|
455
|
+
$[10] = open;
|
456
|
+
$[11] = t5;
|
457
|
+
$[12] = t7;
|
458
|
+
} else {
|
459
|
+
t7 = $[12];
|
460
|
+
}
|
461
|
+
let t8;
|
462
|
+
if ($[13] !== editor) {
|
463
|
+
t8 = editor.getAttributes("link").href ? /* @__PURE__ */ jsx(Button, { size: "small", variant: "text", type: "button", color: "text", className: "flex items-center", onClick: () => {
|
464
|
+
editor.chain().focus().unsetLink().run();
|
465
|
+
}, children: /* @__PURE__ */ jsx(DeleteIcon, { size: "small" }) }) : /* @__PURE__ */ jsx(Button, { size: "small", variant: "text", children: /* @__PURE__ */ jsx(CheckIcon, { size: "small" }) });
|
466
|
+
$[13] = editor;
|
467
|
+
$[14] = t8;
|
468
|
+
} else {
|
469
|
+
t8 = $[14];
|
470
|
+
}
|
471
|
+
let t9;
|
472
|
+
if ($[15] !== t4 || $[16] !== t7 || $[17] !== t8) {
|
473
|
+
t9 = /* @__PURE__ */ jsxs("form", { onSubmit: t4, className: "flex p-1", children: [
|
474
|
+
t7,
|
475
|
+
t8
|
476
|
+
] });
|
477
|
+
$[15] = t4;
|
478
|
+
$[16] = t7;
|
479
|
+
$[17] = t8;
|
480
|
+
$[18] = t9;
|
481
|
+
} else {
|
482
|
+
t9 = $[18];
|
483
|
+
}
|
484
|
+
let t10;
|
485
|
+
if ($[19] !== onOpenChange || $[20] !== open || $[21] !== t3 || $[22] !== t9) {
|
486
|
+
t10 = /* @__PURE__ */ jsx(Popover, { modal: true, open, onOpenChange, trigger: t3, children: t9 });
|
487
|
+
$[19] = onOpenChange;
|
488
|
+
$[20] = open;
|
489
|
+
$[21] = t3;
|
490
|
+
$[22] = t9;
|
491
|
+
$[23] = t10;
|
492
|
+
} else {
|
493
|
+
t10 = $[23];
|
494
|
+
}
|
495
|
+
return t10;
|
496
|
+
};
|
497
|
+
const TextButtons = () => {
|
498
|
+
const $ = c(2);
|
499
|
+
const {
|
500
|
+
editor
|
501
|
+
} = useCurrentEditor();
|
502
|
+
if (!editor) {
|
503
|
+
return null;
|
504
|
+
}
|
505
|
+
let t0;
|
506
|
+
if ($[0] !== editor) {
|
507
|
+
const items2 = [{
|
368
508
|
name: "bold",
|
369
|
-
isActive:
|
370
|
-
command:
|
371
|
-
icon:
|
372
|
-
},
|
373
|
-
{
|
509
|
+
isActive: _temp,
|
510
|
+
command: _temp2,
|
511
|
+
icon: FormatBoldIcon
|
512
|
+
}, {
|
374
513
|
name: "italic",
|
375
|
-
isActive:
|
376
|
-
command:
|
377
|
-
icon:
|
378
|
-
},
|
379
|
-
{
|
514
|
+
isActive: _temp3,
|
515
|
+
command: _temp4,
|
516
|
+
icon: FormatItalicIcon
|
517
|
+
}, {
|
380
518
|
name: "underline",
|
381
|
-
isActive:
|
382
|
-
command:
|
383
|
-
icon:
|
384
|
-
},
|
385
|
-
{
|
519
|
+
isActive: _temp5,
|
520
|
+
command: _temp6,
|
521
|
+
icon: FormatUnderlinedIcon
|
522
|
+
}, {
|
386
523
|
name: "strike",
|
387
|
-
isActive:
|
388
|
-
command:
|
389
|
-
icon:
|
390
|
-
},
|
391
|
-
{
|
524
|
+
isActive: _temp7,
|
525
|
+
command: _temp8,
|
526
|
+
icon: FormatStrikethroughIcon
|
527
|
+
}, {
|
392
528
|
name: "code",
|
393
|
-
isActive:
|
394
|
-
command:
|
395
|
-
icon:
|
396
|
-
}
|
397
|
-
|
398
|
-
|
399
|
-
{
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
variant: "text",
|
410
|
-
children: /* @__PURE__ */ s(
|
411
|
-
t.icon,
|
412
|
-
{
|
413
|
-
className: g({
|
414
|
-
"text-inherit": !t.isActive(e),
|
415
|
-
"text-blue-500": t.isActive(e)
|
416
|
-
})
|
417
|
-
}
|
418
|
-
)
|
419
|
-
}
|
420
|
-
)
|
421
|
-
},
|
422
|
-
r
|
423
|
-
)) }) : null;
|
529
|
+
isActive: _temp9,
|
530
|
+
command: _temp10,
|
531
|
+
icon: CodeIcon
|
532
|
+
}];
|
533
|
+
t0 = /* @__PURE__ */ jsx("div", { className: "flex", children: items2.map((item, index) => /* @__PURE__ */ jsx(EditorBubbleItem, { onSelect: (editor_10) => {
|
534
|
+
item.command(editor_10);
|
535
|
+
}, children: /* @__PURE__ */ jsx(Button, { size: "small", color: "text", className: "gap-2 rounded-none h-full", variant: "text", children: /* @__PURE__ */ jsx(item.icon, { className: cls({
|
536
|
+
"text-inherit": !item.isActive(editor),
|
537
|
+
"text-blue-500": item.isActive(editor)
|
538
|
+
}) }) }) }, index)) });
|
539
|
+
$[0] = editor;
|
540
|
+
$[1] = t0;
|
541
|
+
} else {
|
542
|
+
t0 = $[1];
|
543
|
+
}
|
544
|
+
return t0;
|
424
545
|
};
|
425
|
-
function
|
426
|
-
|
427
|
-
o(), a.current = !1;
|
428
|
-
}, n = L.useRef(void 0);
|
429
|
-
L.useEffect(
|
430
|
-
() => (a.current = !0, clearTimeout(n.current), n.current = setTimeout(c, r), () => {
|
431
|
-
t && c();
|
432
|
-
}),
|
433
|
-
[t, e]
|
434
|
-
);
|
546
|
+
function _temp(editor_0) {
|
547
|
+
return editor_0?.isActive("bold") ?? false;
|
435
548
|
}
|
436
|
-
function
|
437
|
-
return
|
438
|
-
e[o] = H(e[o]);
|
439
|
-
})), e);
|
549
|
+
function _temp2(editor_1) {
|
550
|
+
return editor_1?.chain().focus().toggleBold().run();
|
440
551
|
}
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
552
|
+
function _temp3(editor_2) {
|
553
|
+
return editor_2?.isActive("italic") ?? false;
|
554
|
+
}
|
555
|
+
function _temp4(editor_3) {
|
556
|
+
return editor_3?.chain().focus().toggleItalic().run();
|
557
|
+
}
|
558
|
+
function _temp5(editor_4) {
|
559
|
+
return editor_4?.isActive("underline") ?? false;
|
560
|
+
}
|
561
|
+
function _temp6(editor_5) {
|
562
|
+
return editor_5?.chain().focus().toggleUnderline().run();
|
563
|
+
}
|
564
|
+
function _temp7(editor_6) {
|
565
|
+
return editor_6?.isActive("strike") ?? false;
|
566
|
+
}
|
567
|
+
function _temp8(editor_7) {
|
568
|
+
return editor_7?.chain().focus().toggleStrike().run();
|
569
|
+
}
|
570
|
+
function _temp9(editor_8) {
|
571
|
+
return editor_8?.isActive("code") ?? false;
|
572
|
+
}
|
573
|
+
function _temp10(editor_9) {
|
574
|
+
return editor_9?.chain().focus().toggleCode().run();
|
575
|
+
}
|
576
|
+
function removeClassesFromJson(jsonObj) {
|
577
|
+
if (Array.isArray(jsonObj)) {
|
578
|
+
return jsonObj.map((item) => removeClassesFromJson(item));
|
579
|
+
} else if (typeof jsonObj === "object" && jsonObj !== null) {
|
580
|
+
if (jsonObj.attrs && typeof jsonObj.attrs === "object" && "class" in jsonObj.attrs) {
|
581
|
+
delete jsonObj.attrs.class;
|
582
|
+
}
|
583
|
+
Object.keys(jsonObj).forEach((key) => {
|
584
|
+
jsonObj[key] = removeClassesFromJson(jsonObj[key]);
|
585
|
+
});
|
450
586
|
}
|
451
|
-
|
452
|
-
|
453
|
-
|
587
|
+
return jsonObj;
|
588
|
+
}
|
589
|
+
const loadingDecorationKey = new PluginKey("loadingDecoration");
|
590
|
+
const TextLoadingDecorationExtension = Extension.create({
|
591
|
+
name: "loadingDecoration",
|
592
|
+
addOptions() {
|
593
|
+
return {
|
594
|
+
pluginKey: loadingDecorationKey
|
595
|
+
};
|
454
596
|
},
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
597
|
+
addProseMirrorPlugins() {
|
598
|
+
const pluginKey = this.options.pluginKey;
|
599
|
+
return [new Plugin({
|
600
|
+
key: pluginKey,
|
601
|
+
state: {
|
602
|
+
init() {
|
603
|
+
return {
|
604
|
+
decorationSet: DecorationSet.empty,
|
605
|
+
hasDecoration: false
|
606
|
+
};
|
607
|
+
},
|
608
|
+
apply(tr, oldState) {
|
609
|
+
const action = tr.getMeta(pluginKey);
|
610
|
+
if (action?.type === "loadingDecoration") {
|
611
|
+
const {
|
612
|
+
pos,
|
613
|
+
remove,
|
614
|
+
loadingHtml
|
615
|
+
} = action;
|
616
|
+
if (remove) {
|
617
|
+
return {
|
618
|
+
decorationSet: DecorationSet.empty,
|
619
|
+
hasDecoration: false
|
620
|
+
};
|
621
|
+
}
|
622
|
+
const decoration = Decoration.widget(pos, () => {
|
623
|
+
const container = document.createElement("span");
|
624
|
+
container.className = "loading-decoration";
|
625
|
+
if (loadingHtml) {
|
626
|
+
container.innerHTML = loadingHtml;
|
627
|
+
} else {
|
628
|
+
const span = document.createElement("span");
|
629
|
+
span.innerText = "loading...";
|
630
|
+
container.appendChild(span);
|
631
|
+
}
|
632
|
+
return container;
|
633
|
+
});
|
634
|
+
return {
|
635
|
+
decorationSet: DecorationSet.empty.add(tr.doc, [decoration]),
|
636
|
+
hasDecoration: true
|
637
|
+
};
|
638
|
+
}
|
639
|
+
return {
|
640
|
+
decorationSet: oldState.decorationSet.map(tr.mapping, tr.doc),
|
641
|
+
hasDecoration: oldState.hasDecoration
|
642
|
+
};
|
643
|
+
}
|
644
|
+
},
|
645
|
+
props: {
|
646
|
+
decorations(state) {
|
647
|
+
return this.getState(state)?.decorationSet || DecorationSet.empty;
|
648
|
+
}
|
649
|
+
}
|
650
|
+
})];
|
465
651
|
},
|
466
|
-
|
467
|
-
|
468
|
-
|
652
|
+
addCommands() {
|
653
|
+
return {
|
654
|
+
toggleLoadingDecoration: (loadingHtml) => ({
|
655
|
+
state,
|
656
|
+
dispatch
|
657
|
+
}) => {
|
658
|
+
const {
|
659
|
+
selection
|
660
|
+
} = state;
|
661
|
+
const pos = selection.from;
|
662
|
+
if (!dispatch) return false;
|
663
|
+
const pluginKey = this.options.pluginKey;
|
664
|
+
const tr = state.tr.setMeta(pluginKey, {
|
665
|
+
pos,
|
666
|
+
type: "loadingDecoration",
|
667
|
+
remove: false,
|
668
|
+
loadingHtml
|
669
|
+
});
|
670
|
+
dispatch(tr);
|
671
|
+
return true;
|
672
|
+
},
|
673
|
+
removeLoadingDecoration: () => ({
|
674
|
+
state,
|
675
|
+
dispatch
|
676
|
+
}) => {
|
677
|
+
if (!dispatch) return false;
|
678
|
+
const pluginKey = this.options.pluginKey;
|
679
|
+
const tr = state.tr.setMeta(pluginKey, {
|
680
|
+
pos: 0,
|
681
|
+
// We can pass any position as it will remove the entire decoration set
|
682
|
+
type: "loadingDecoration",
|
683
|
+
remove: true
|
684
|
+
});
|
685
|
+
dispatch(tr);
|
686
|
+
return true;
|
687
|
+
}
|
688
|
+
};
|
689
|
+
}
|
690
|
+
});
|
691
|
+
const PlaceholderExtension = Placeholder.configure({
|
692
|
+
placeholder: ({
|
693
|
+
node,
|
694
|
+
editor
|
695
|
+
}) => {
|
696
|
+
editor.state.selection;
|
697
|
+
function hasLoadingDecoration(editor2) {
|
698
|
+
const pluginState = loadingDecorationKey.get(editor2.state);
|
699
|
+
return pluginState?.getState(editor2.state)?.hasDecoration ?? false;
|
469
700
|
}
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
class: g("leading-normal -mb-2")
|
701
|
+
const hasDecoration = hasLoadingDecoration(editor);
|
702
|
+
if (hasDecoration) {
|
703
|
+
return "";
|
474
704
|
}
|
475
|
-
|
476
|
-
|
477
|
-
HTMLAttributes: {
|
478
|
-
class: g("border-l-4 border-primary")
|
705
|
+
if (node.type.name === "heading") {
|
706
|
+
return `Heading ${node.attrs.level}`;
|
479
707
|
}
|
480
|
-
|
481
|
-
|
482
|
-
HTMLAttributes: {
|
483
|
-
class: g("rounded bg-blue-50 dark:bg-gray-700 border p-5 font-mono font-medium", x)
|
708
|
+
if (node.type.name === "paragraph") {
|
709
|
+
return "Press '/' for commands";
|
484
710
|
}
|
711
|
+
return "";
|
485
712
|
},
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
713
|
+
includeChildren: true
|
714
|
+
});
|
715
|
+
const Horizontal = HorizontalRule.extend({
|
716
|
+
addInputRules() {
|
717
|
+
return [new InputRule({
|
718
|
+
find: /^(?:---|—-|___\s|\*\*\*\s)$/,
|
719
|
+
handler: ({
|
720
|
+
state,
|
721
|
+
range
|
722
|
+
}) => {
|
723
|
+
const attributes = {};
|
724
|
+
const {
|
725
|
+
tr
|
726
|
+
} = state;
|
727
|
+
const start = range.from;
|
728
|
+
const end = range.to;
|
729
|
+
tr.insert(start - 1, this.type.create(attributes)).delete(tr.mapping.map(start), tr.mapping.map(end));
|
730
|
+
}
|
731
|
+
})];
|
732
|
+
}
|
733
|
+
});
|
734
|
+
const placeholder = PlaceholderExtension;
|
735
|
+
const tiptapLink = TiptapLink.configure({
|
736
|
+
HTMLAttributes: {
|
737
|
+
class: cls("text-surface-700 dark:text-surface-accent-200 underline underline-offset-[3px] hover:text-primary transition-colors cursor-pointer")
|
738
|
+
}
|
739
|
+
});
|
740
|
+
const taskList = TaskList.configure({
|
741
|
+
HTMLAttributes: {
|
742
|
+
class: cls("not-prose")
|
743
|
+
}
|
744
|
+
});
|
745
|
+
const taskItem = TaskItem.configure({
|
746
|
+
HTMLAttributes: {
|
747
|
+
class: cls("flex items-start my-4")
|
491
748
|
},
|
492
|
-
|
749
|
+
nested: true
|
750
|
+
});
|
751
|
+
const horizontalRule = Horizontal.configure({
|
752
|
+
HTMLAttributes: {
|
753
|
+
class: cls("mt-4 mb-6 border-t", defaultBorderMixin)
|
754
|
+
}
|
755
|
+
});
|
756
|
+
const bulletList = BulletList.configure({
|
757
|
+
HTMLAttributes: {
|
758
|
+
class: cls("list-disc list-outside leading-3 -mt-2")
|
759
|
+
}
|
760
|
+
});
|
761
|
+
const orderedList = OrderedList.configure({
|
762
|
+
HTMLAttributes: {
|
763
|
+
class: cls("list-decimal list-outside leading-3 -mt-2")
|
764
|
+
}
|
765
|
+
});
|
766
|
+
const listItem = ListItem.configure({
|
767
|
+
HTMLAttributes: {
|
768
|
+
class: cls("leading-normal -mb-2")
|
769
|
+
}
|
770
|
+
});
|
771
|
+
const blockquote = Blockquote.configure({
|
772
|
+
HTMLAttributes: {
|
773
|
+
class: cls("border-l-4 border-primary")
|
774
|
+
}
|
775
|
+
});
|
776
|
+
const codeBlock = CodeBlock.configure({
|
777
|
+
HTMLAttributes: {
|
778
|
+
class: cls("rounded bg-blue-50 dark:bg-surface-700 border p-5 font-mono font-medium", defaultBorderMixin)
|
779
|
+
}
|
780
|
+
});
|
781
|
+
const code = Code.configure({
|
782
|
+
HTMLAttributes: {
|
783
|
+
class: cls("rounded-md bg-surface-accent-50 dark:bg-surface-700 px-1.5 py-1 font-mono font-medium"),
|
784
|
+
spellcheck: "false"
|
785
|
+
}
|
786
|
+
});
|
787
|
+
const starterKit = StarterKit.configure({
|
788
|
+
document: false,
|
789
|
+
horizontalRule: false,
|
493
790
|
dropcursor: {
|
494
791
|
color: "#DBEAFE",
|
495
792
|
width: 4
|
496
793
|
},
|
497
|
-
gapcursor:
|
794
|
+
gapcursor: false
|
498
795
|
});
|
499
|
-
async function
|
500
|
-
const {
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
796
|
+
async function onFileRead(view, readerEvent, pos, upload, image) {
|
797
|
+
const {
|
798
|
+
schema
|
799
|
+
} = view.state;
|
800
|
+
const plugin = view.state.plugins.find((p) => p.key === ImagePluginKey.key);
|
801
|
+
if (!plugin) {
|
802
|
+
console.error("Image plugin not found");
|
803
|
+
return;
|
804
|
+
}
|
805
|
+
let decorationSet = plugin.getState(view.state);
|
806
|
+
const placeholder2 = document.createElement("div");
|
807
|
+
const imageElement = document.createElement("img");
|
808
|
+
imageElement.setAttribute("class", "opacity-40 rounded-lg border " + defaultBorderMixin);
|
809
|
+
imageElement.src = readerEvent.target?.result;
|
810
|
+
placeholder2.appendChild(imageElement);
|
811
|
+
const deco = Decoration$1.widget(pos, placeholder2);
|
812
|
+
decorationSet = decorationSet?.add(view.state.doc, [deco]);
|
813
|
+
view.dispatch(view.state.tr.setMeta(plugin, {
|
814
|
+
decorationSet
|
815
|
+
}));
|
816
|
+
const src = await upload(image);
|
817
|
+
console.debug("Uploaded image", src);
|
818
|
+
const imageNode = schema.nodes.image.create({
|
819
|
+
src
|
820
|
+
});
|
821
|
+
const tr = view.state.tr.replaceWith(pos, pos, imageNode);
|
822
|
+
decorationSet = decorationSet?.remove([deco]);
|
823
|
+
tr.setMeta(plugin, {
|
824
|
+
decorationSet
|
825
|
+
});
|
826
|
+
view.dispatch(tr);
|
510
827
|
}
|
511
|
-
const
|
512
|
-
|
828
|
+
const ImagePluginKey = new PluginKey$1("imagePlugin");
|
829
|
+
const createDropImagePlugin = (upload) => {
|
830
|
+
const plugin = new Plugin$1({
|
831
|
+
key: ImagePluginKey,
|
513
832
|
state: {
|
514
833
|
// Initialize the plugin state with an empty DecorationSet
|
515
|
-
init: () =>
|
834
|
+
init: () => DecorationSet$1.empty,
|
516
835
|
// Apply transactions to update the state
|
517
|
-
apply: (
|
518
|
-
const
|
519
|
-
|
836
|
+
apply: (tr, old) => {
|
837
|
+
const meta = tr.getMeta(plugin);
|
838
|
+
if (meta && meta.decorationSet) {
|
839
|
+
return meta.decorationSet;
|
840
|
+
}
|
841
|
+
return old.map(tr.mapping, tr.doc);
|
520
842
|
}
|
521
843
|
},
|
522
844
|
props: {
|
523
845
|
handleDOMEvents: {
|
524
|
-
drop: (
|
525
|
-
if (
|
526
|
-
return
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
846
|
+
drop: (view, event) => {
|
847
|
+
if (!event.dataTransfer?.files || event.dataTransfer?.files.length === 0) {
|
848
|
+
return false;
|
849
|
+
}
|
850
|
+
event.preventDefault();
|
851
|
+
const files = Array.from(event.dataTransfer.files);
|
852
|
+
const images = files.filter((file) => /image/i.test(file.type));
|
853
|
+
if (images.length === 0) {
|
854
|
+
console.log("No images found in dropped files");
|
855
|
+
return false;
|
856
|
+
}
|
857
|
+
images.forEach((image) => {
|
858
|
+
const position = view.posAtCoords({
|
859
|
+
left: event.clientX,
|
860
|
+
top: event.clientY
|
861
|
+
});
|
862
|
+
if (!position) return;
|
863
|
+
const reader = new FileReader();
|
864
|
+
reader.onload = async (readerEvent) => {
|
865
|
+
await onFileRead(view, readerEvent, position.pos, upload, image);
|
866
|
+
};
|
867
|
+
reader.readAsDataURL(image);
|
868
|
+
});
|
869
|
+
return true;
|
538
870
|
}
|
539
871
|
},
|
540
|
-
handlePaste(
|
541
|
-
const
|
542
|
-
|
543
|
-
let
|
544
|
-
|
545
|
-
const
|
546
|
-
if (
|
547
|
-
|
548
|
-
const
|
549
|
-
|
550
|
-
await
|
551
|
-
}
|
872
|
+
handlePaste(view, event, slice) {
|
873
|
+
const items2 = Array.from(event.clipboardData?.items || []);
|
874
|
+
const pos = view.state.selection.from;
|
875
|
+
let anyImageFound = false;
|
876
|
+
items2.forEach((item) => {
|
877
|
+
const image = item.getAsFile();
|
878
|
+
if (image) {
|
879
|
+
anyImageFound = true;
|
880
|
+
const reader = new FileReader();
|
881
|
+
reader.onload = async (readerEvent) => {
|
882
|
+
await onFileRead(view, readerEvent, pos, upload, image);
|
883
|
+
};
|
884
|
+
reader.readAsDataURL(image);
|
552
885
|
}
|
553
|
-
})
|
886
|
+
});
|
887
|
+
return anyImageFound;
|
554
888
|
},
|
555
|
-
decorations(
|
556
|
-
return
|
889
|
+
decorations(state) {
|
890
|
+
return plugin.getState(state);
|
557
891
|
}
|
558
892
|
},
|
559
|
-
view(
|
893
|
+
view(editorView) {
|
560
894
|
return {
|
561
|
-
update(
|
562
|
-
const
|
563
|
-
|
895
|
+
update(view, prevState) {
|
896
|
+
const prevDecos = plugin.getState(prevState);
|
897
|
+
const newDecos = plugin.getState(view.state);
|
898
|
+
if (prevDecos !== newDecos) {
|
899
|
+
view.updateState(view.state);
|
900
|
+
}
|
564
901
|
}
|
565
902
|
};
|
566
903
|
}
|
567
904
|
});
|
568
|
-
return
|
569
|
-
}
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
905
|
+
return plugin;
|
906
|
+
};
|
907
|
+
const createImageExtension = (dropImagePlugin) => {
|
908
|
+
return TiptapImage.extend({
|
909
|
+
addProseMirrorPlugins() {
|
910
|
+
return [dropImagePlugin];
|
911
|
+
}
|
912
|
+
}).configure({
|
913
|
+
allowBase64: true,
|
914
|
+
HTMLAttributes: {
|
915
|
+
class: cls("rounded-lg border", defaultBorderMixin)
|
916
|
+
}
|
917
|
+
});
|
918
|
+
};
|
919
|
+
const CustomKeymap = Extension.create({
|
579
920
|
name: "CustomKeymap",
|
580
921
|
addCommands() {
|
581
922
|
return {
|
582
|
-
selectTextWithinNodeBoundaries: () => ({
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
923
|
+
selectTextWithinNodeBoundaries: () => ({
|
924
|
+
editor,
|
925
|
+
commands
|
926
|
+
}) => {
|
927
|
+
const {
|
928
|
+
state
|
929
|
+
} = editor;
|
930
|
+
const {
|
931
|
+
tr
|
932
|
+
} = state;
|
933
|
+
const startNodePos = tr.selection.$from.start();
|
934
|
+
const endNodePos = tr.selection.$to.end();
|
935
|
+
return commands.setTextSelection({
|
936
|
+
from: startNodePos,
|
937
|
+
to: endNodePos
|
587
938
|
});
|
588
939
|
}
|
589
940
|
};
|
590
941
|
},
|
591
942
|
addKeyboardShortcuts() {
|
592
943
|
return {
|
593
|
-
"Mod-a": ({
|
594
|
-
|
595
|
-
|
944
|
+
"Mod-a": ({
|
945
|
+
editor
|
946
|
+
}) => {
|
947
|
+
const {
|
948
|
+
state
|
949
|
+
} = editor;
|
950
|
+
const {
|
951
|
+
tr
|
952
|
+
} = state;
|
953
|
+
const startSelectionPos = tr.selection.from;
|
954
|
+
const endSelectionPos = tr.selection.to;
|
955
|
+
const startNodePos = tr.selection.$from.start();
|
956
|
+
const endNodePos = tr.selection.$to.end();
|
957
|
+
const isCurrentTextSelectionNotExtendedToNodeBoundaries = startSelectionPos > startNodePos || endSelectionPos < endNodePos;
|
958
|
+
if (isCurrentTextSelectionNotExtendedToNodeBoundaries) {
|
959
|
+
editor.chain().selectTextWithinNodeBoundaries().run();
|
960
|
+
return true;
|
961
|
+
}
|
962
|
+
return false;
|
596
963
|
}
|
597
964
|
};
|
598
965
|
}
|
599
966
|
});
|
600
|
-
function
|
601
|
-
const
|
967
|
+
function absoluteRect(element) {
|
968
|
+
const data = element.getBoundingClientRect();
|
969
|
+
let ancestor = element.parentElement;
|
970
|
+
while (ancestor && window.getComputedStyle(ancestor).position === "static") {
|
971
|
+
ancestor = ancestor.parentElement;
|
972
|
+
}
|
973
|
+
const ancestorRect = ancestor?.getBoundingClientRect();
|
602
974
|
return {
|
603
|
-
top:
|
604
|
-
left:
|
605
|
-
width:
|
975
|
+
top: data.top - (ancestorRect?.top ?? 0),
|
976
|
+
left: data.left - (ancestorRect?.left ?? 0),
|
977
|
+
width: data.width
|
606
978
|
};
|
607
979
|
}
|
608
|
-
function
|
609
|
-
return document.elementsFromPoint(
|
610
|
-
(o) => o.parentElement?.matches?.(".ProseMirror") || o.matches(
|
611
|
-
["li", "p:not(:first-child)", "pre", "blockquote", "h1, h2, h3, h4, h5, h6"].join(", ")
|
612
|
-
)
|
613
|
-
);
|
980
|
+
function nodeDOMAtCoords(coords) {
|
981
|
+
return document.elementsFromPoint(coords.x, coords.y).find((elem) => elem.parentElement?.matches?.(".ProseMirror") || elem.matches(["li", "p:not(:first-child)", "pre", "blockquote", "h1, h2, h3, h4, h5, h6"].join(", ")));
|
614
982
|
}
|
615
|
-
function
|
616
|
-
const
|
617
|
-
return
|
618
|
-
left:
|
619
|
-
top:
|
983
|
+
function nodePosAtDOM(node, view, options) {
|
984
|
+
const boundingRect = node.getBoundingClientRect();
|
985
|
+
return view.posAtCoords({
|
986
|
+
left: boundingRect.left + 50 + options.dragHandleWidth,
|
987
|
+
top: boundingRect.top + 1
|
620
988
|
})?.inside;
|
621
989
|
}
|
622
|
-
function
|
623
|
-
function
|
624
|
-
|
625
|
-
|
626
|
-
const
|
627
|
-
x:
|
628
|
-
y:
|
990
|
+
function DragHandle(options) {
|
991
|
+
function handleDragStart(event, view) {
|
992
|
+
view.focus();
|
993
|
+
if (!event.dataTransfer) return;
|
994
|
+
const node = nodeDOMAtCoords({
|
995
|
+
x: event.clientX + 50 + options.dragHandleWidth,
|
996
|
+
y: event.clientY
|
629
997
|
});
|
630
|
-
if (!(
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
998
|
+
if (!(node instanceof Element)) return;
|
999
|
+
const nodePos = nodePosAtDOM(node, view, options);
|
1000
|
+
if (nodePos == null || nodePos < 0) return;
|
1001
|
+
view.dispatch(view.state.tr.setSelection(NodeSelection.create(view.state.doc, nodePos)));
|
1002
|
+
const slice = view.state.selection.content();
|
1003
|
+
const {
|
1004
|
+
dom,
|
1005
|
+
text
|
1006
|
+
} = __serializeForClipboard(view, slice);
|
1007
|
+
event.dataTransfer.clearData();
|
1008
|
+
event.dataTransfer.setData("text/html", dom.innerHTML);
|
1009
|
+
event.dataTransfer.setData("text/plain", text);
|
1010
|
+
event.dataTransfer.effectAllowed = "copyMove";
|
1011
|
+
event.dataTransfer.setDragImage(node, 0, 0);
|
1012
|
+
view.dragging = {
|
1013
|
+
slice,
|
1014
|
+
move: event.ctrlKey
|
1015
|
+
};
|
1016
|
+
}
|
1017
|
+
function handleClick(event, view) {
|
1018
|
+
view.focus();
|
1019
|
+
view.dom.classList.remove("dragging");
|
1020
|
+
const node = nodeDOMAtCoords({
|
1021
|
+
x: event.clientX + 50 + options.dragHandleWidth,
|
1022
|
+
y: event.clientY
|
644
1023
|
});
|
645
|
-
if (!(
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
}
|
650
|
-
let
|
651
|
-
function
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
1024
|
+
if (!(node instanceof Element)) return;
|
1025
|
+
const nodePos = nodePosAtDOM(node, view, options);
|
1026
|
+
if (!nodePos) return;
|
1027
|
+
view.dispatch(view.state.tr.setSelection(NodeSelection.create(view.state.doc, nodePos)));
|
1028
|
+
}
|
1029
|
+
let dragHandleElement = null;
|
1030
|
+
function hideDragHandle() {
|
1031
|
+
if (dragHandleElement) {
|
1032
|
+
dragHandleElement.classList.add("hide");
|
1033
|
+
}
|
1034
|
+
}
|
1035
|
+
function showDragHandle() {
|
1036
|
+
if (dragHandleElement) {
|
1037
|
+
dragHandleElement.classList.remove("hide");
|
1038
|
+
}
|
1039
|
+
}
|
1040
|
+
return new Plugin$1({
|
1041
|
+
view: (view) => {
|
1042
|
+
dragHandleElement = document.createElement("div");
|
1043
|
+
dragHandleElement.draggable = true;
|
1044
|
+
dragHandleElement.dataset.dragHandle = "";
|
1045
|
+
dragHandleElement.classList.add("drag-handle");
|
1046
|
+
dragHandleElement.addEventListener("dragstart", (e) => {
|
1047
|
+
handleDragStart(e, view);
|
1048
|
+
});
|
1049
|
+
dragHandleElement.addEventListener("click", (e) => {
|
1050
|
+
handleClick(e, view);
|
1051
|
+
});
|
1052
|
+
hideDragHandle();
|
1053
|
+
view?.dom?.parentElement?.appendChild(dragHandleElement);
|
1054
|
+
return {
|
1055
|
+
destroy: () => {
|
1056
|
+
}
|
1057
|
+
};
|
1058
|
+
},
|
667
1059
|
props: {
|
668
1060
|
handleDOMEvents: {
|
669
|
-
mousemove: (
|
670
|
-
if (!
|
1061
|
+
mousemove: (view, event) => {
|
1062
|
+
if (!view.editable) {
|
671
1063
|
return;
|
672
|
-
|
673
|
-
|
674
|
-
|
1064
|
+
}
|
1065
|
+
const node = nodeDOMAtCoords({
|
1066
|
+
x: event.clientX + 50 + options.dragHandleWidth,
|
1067
|
+
y: event.clientY
|
675
1068
|
});
|
676
|
-
if (!(
|
677
|
-
|
1069
|
+
if (!(node instanceof Element)) {
|
1070
|
+
hideDragHandle();
|
678
1071
|
return;
|
679
1072
|
}
|
680
|
-
const
|
681
|
-
|
1073
|
+
const compStyle = window.getComputedStyle(node);
|
1074
|
+
const lineHeight = parseInt(compStyle.lineHeight, 10);
|
1075
|
+
const paddingTop = parseInt(compStyle.paddingTop, 10);
|
1076
|
+
const rect = absoluteRect(node);
|
1077
|
+
rect.top += (lineHeight - 24) / 2;
|
1078
|
+
rect.top += paddingTop;
|
1079
|
+
if (node.matches("ul:not([data-type=taskList]) li, ol li")) {
|
1080
|
+
rect.left -= options.dragHandleWidth;
|
1081
|
+
}
|
1082
|
+
rect.width = options.dragHandleWidth;
|
1083
|
+
if (!dragHandleElement) return;
|
1084
|
+
dragHandleElement.style.left = `${rect.left - rect.width}px`;
|
1085
|
+
dragHandleElement.style.top = `${rect.top}px`;
|
1086
|
+
showDragHandle();
|
682
1087
|
},
|
683
1088
|
keydown: () => {
|
684
|
-
|
1089
|
+
hideDragHandle();
|
685
1090
|
},
|
686
1091
|
mousewheel: () => {
|
687
|
-
|
1092
|
+
hideDragHandle();
|
688
1093
|
},
|
689
1094
|
// dragging class is used for CSS
|
690
|
-
dragstart: (
|
691
|
-
|
1095
|
+
dragstart: (view) => {
|
1096
|
+
view.dom.classList.add("dragging");
|
692
1097
|
},
|
693
|
-
drop: (
|
694
|
-
|
1098
|
+
drop: (view) => {
|
1099
|
+
view.dom.classList.remove("dragging");
|
695
1100
|
},
|
696
|
-
dragend: (
|
697
|
-
|
1101
|
+
dragend: (view) => {
|
1102
|
+
view.dom.classList.remove("dragging");
|
698
1103
|
}
|
699
1104
|
}
|
700
1105
|
}
|
701
1106
|
});
|
702
1107
|
}
|
703
|
-
const
|
1108
|
+
const DragAndDrop = Extension.create({
|
704
1109
|
name: "dragAndDrop",
|
705
1110
|
addProseMirrorPlugins() {
|
706
|
-
return [
|
707
|
-
|
708
|
-
|
1111
|
+
return [DragHandle({
|
1112
|
+
dragHandleWidth: 24
|
1113
|
+
})];
|
1114
|
+
}
|
1115
|
+
});
|
1116
|
+
function buildDecorationSet(highlight, doc) {
|
1117
|
+
const decorations = [];
|
1118
|
+
if (highlight) {
|
1119
|
+
decorations.push(Decoration$1.inline(highlight.from, highlight.to, {
|
1120
|
+
class: "dark:bg-surface-accent-700 bg-surface-accent-300"
|
1121
|
+
}));
|
1122
|
+
}
|
1123
|
+
const decorationSet = DecorationSet$1.create(doc, decorations);
|
1124
|
+
return decorationSet;
|
1125
|
+
}
|
1126
|
+
const HighlightDecorationExtension = (initialHighlight) => Extension.create({
|
1127
|
+
name: "highlightDecoration",
|
1128
|
+
addOptions() {
|
1129
|
+
return {
|
1130
|
+
pluginKey: new PluginKey$1("highlightDecoration"),
|
1131
|
+
highlight: initialHighlight
|
1132
|
+
};
|
1133
|
+
},
|
1134
|
+
addProseMirrorPlugins() {
|
1135
|
+
const pluginKey = this.options.pluginKey;
|
1136
|
+
return [new Plugin$1({
|
1137
|
+
key: pluginKey,
|
1138
|
+
state: {
|
1139
|
+
init: (_, {
|
1140
|
+
doc
|
1141
|
+
}) => {
|
1142
|
+
const highlight = this.options.highlight;
|
1143
|
+
const decorationSet = highlight && doc ? buildDecorationSet(highlight, doc) : DecorationSet$1.empty;
|
1144
|
+
return {
|
1145
|
+
decorationSet,
|
1146
|
+
highlight
|
1147
|
+
};
|
1148
|
+
},
|
1149
|
+
apply(transaction, oldState) {
|
1150
|
+
const action = transaction.getMeta(pluginKey);
|
1151
|
+
const highlight = action?.range;
|
1152
|
+
if (action?.type === "highlightDecoration") {
|
1153
|
+
const doc = transaction.doc;
|
1154
|
+
const {
|
1155
|
+
remove
|
1156
|
+
} = action;
|
1157
|
+
if (remove) {
|
1158
|
+
return {
|
1159
|
+
decorationSet: DecorationSet$1.empty
|
1160
|
+
};
|
1161
|
+
}
|
1162
|
+
const decorationSet = buildDecorationSet(highlight, doc);
|
1163
|
+
return {
|
1164
|
+
decorationSet,
|
1165
|
+
highlight
|
1166
|
+
};
|
1167
|
+
} else {
|
1168
|
+
return oldState;
|
1169
|
+
}
|
1170
|
+
}
|
1171
|
+
},
|
1172
|
+
props: {
|
1173
|
+
decorations(state) {
|
1174
|
+
const autocompleteState = this.getState(state);
|
1175
|
+
if (autocompleteState?.decorationSet) {
|
1176
|
+
return autocompleteState.decorationSet;
|
1177
|
+
} else {
|
1178
|
+
return DecorationSet$1.empty;
|
1179
|
+
}
|
1180
|
+
}
|
1181
|
+
}
|
1182
|
+
})];
|
1183
|
+
},
|
1184
|
+
addCommands() {
|
1185
|
+
return {
|
1186
|
+
toggleAutocompleteHighlight: (range) => ({
|
1187
|
+
state,
|
1188
|
+
dispatch
|
1189
|
+
}) => {
|
1190
|
+
const {
|
1191
|
+
selection
|
1192
|
+
} = state;
|
1193
|
+
const pos = selection.from;
|
1194
|
+
if (!dispatch) return false;
|
1195
|
+
const pluginKey = this.options.pluginKey;
|
1196
|
+
const tr = state.tr.setMeta(pluginKey, {
|
1197
|
+
pos,
|
1198
|
+
type: "highlightDecoration",
|
1199
|
+
remove: false,
|
1200
|
+
range
|
1201
|
+
});
|
1202
|
+
dispatch(tr);
|
1203
|
+
return true;
|
1204
|
+
},
|
1205
|
+
removeAutocompleteHighlight: () => ({
|
1206
|
+
state,
|
1207
|
+
dispatch
|
1208
|
+
}) => {
|
1209
|
+
if (!dispatch) return false;
|
1210
|
+
const pluginKey = this.options.pluginKey;
|
1211
|
+
const tr = state.tr.setMeta(pluginKey, {
|
1212
|
+
pos: 0,
|
1213
|
+
// We can pass any position as it will remove the entire decoration set
|
1214
|
+
type: "highlightDecoration",
|
1215
|
+
remove: true
|
1216
|
+
});
|
1217
|
+
dispatch(tr);
|
1218
|
+
return true;
|
1219
|
+
}
|
1220
|
+
};
|
1221
|
+
}
|
1222
|
+
});
|
1223
|
+
const CommandPluginKey = new PluginKey$1("slash-command");
|
1224
|
+
const SlashCommand = Node.create({
|
1225
|
+
name: "command",
|
1226
|
+
addOptions() {
|
1227
|
+
return {
|
1228
|
+
HTMLAttributes: {},
|
1229
|
+
renderText({
|
1230
|
+
options,
|
1231
|
+
node
|
1232
|
+
}) {
|
1233
|
+
return `${options.suggestion.char}${node.attrs.label ?? node.attrs.id}`;
|
1234
|
+
},
|
1235
|
+
deleteTriggerWithBackspace: false,
|
1236
|
+
renderHTML({
|
1237
|
+
options,
|
1238
|
+
node
|
1239
|
+
}) {
|
1240
|
+
return ["span", mergeAttributes(this.HTMLAttributes, options.HTMLAttributes), `${options.suggestion.char}${node.attrs.label ?? node.attrs.id}`];
|
1241
|
+
},
|
1242
|
+
suggestion: {
|
1243
|
+
char: "/",
|
1244
|
+
pluginKey: CommandPluginKey,
|
1245
|
+
command: ({
|
1246
|
+
editor,
|
1247
|
+
range,
|
1248
|
+
props
|
1249
|
+
}) => {
|
1250
|
+
const nodeAfter = editor.view.state.selection.$to.nodeAfter;
|
1251
|
+
const overrideSpace = nodeAfter?.text?.startsWith(" ");
|
1252
|
+
if (overrideSpace) {
|
1253
|
+
range.to += 1;
|
1254
|
+
}
|
1255
|
+
editor.chain().focus().insertContentAt(range, [{
|
1256
|
+
type: this.name,
|
1257
|
+
attrs: props
|
1258
|
+
}, {
|
1259
|
+
type: "text",
|
1260
|
+
text: " "
|
1261
|
+
}]).run();
|
1262
|
+
window.getSelection()?.collapseToEnd();
|
1263
|
+
},
|
1264
|
+
allow: ({
|
1265
|
+
state,
|
1266
|
+
range
|
1267
|
+
}) => {
|
1268
|
+
const $from = state.doc.resolve(range.from);
|
1269
|
+
const type = state.schema.nodes[this.name];
|
1270
|
+
const allow = !!$from.parent.type.contentMatch.matchType(type);
|
1271
|
+
return allow;
|
1272
|
+
}
|
1273
|
+
}
|
1274
|
+
};
|
1275
|
+
},
|
1276
|
+
group: "inline",
|
1277
|
+
inline: true,
|
1278
|
+
selectable: false,
|
1279
|
+
atom: true,
|
1280
|
+
addAttributes() {
|
1281
|
+
return {
|
1282
|
+
id: {
|
1283
|
+
default: null,
|
1284
|
+
parseHTML: (element) => element.getAttribute("data-id"),
|
1285
|
+
renderHTML: (attributes) => {
|
1286
|
+
if (!attributes.id) {
|
1287
|
+
return {};
|
1288
|
+
}
|
1289
|
+
return {
|
1290
|
+
"data-id": attributes.id
|
1291
|
+
};
|
1292
|
+
}
|
1293
|
+
},
|
1294
|
+
label: {
|
1295
|
+
default: null,
|
1296
|
+
parseHTML: (element) => element.getAttribute("data-label"),
|
1297
|
+
renderHTML: (attributes) => {
|
1298
|
+
if (!attributes.label) {
|
1299
|
+
return {};
|
1300
|
+
}
|
1301
|
+
return {
|
1302
|
+
"data-label": attributes.label
|
1303
|
+
};
|
1304
|
+
}
|
1305
|
+
}
|
1306
|
+
};
|
1307
|
+
},
|
1308
|
+
parseHTML() {
|
1309
|
+
return [{
|
1310
|
+
tag: `span[data-type="${this.name}"]`
|
1311
|
+
}];
|
1312
|
+
},
|
1313
|
+
renderHTML({
|
1314
|
+
node,
|
1315
|
+
HTMLAttributes
|
1316
|
+
}) {
|
1317
|
+
if (this.options.renderLabel !== void 0) {
|
1318
|
+
console.warn("renderLabel is deprecated use renderText and renderHTML instead");
|
1319
|
+
return ["span", mergeAttributes({
|
1320
|
+
"data-type": this.name
|
1321
|
+
}, this.options.HTMLAttributes, HTMLAttributes), this.options.renderLabel({
|
1322
|
+
options: this.options,
|
1323
|
+
node
|
1324
|
+
})];
|
1325
|
+
}
|
1326
|
+
const mergedOptions = {
|
1327
|
+
...this.options
|
1328
|
+
};
|
1329
|
+
mergedOptions.HTMLAttributes = mergeAttributes({
|
1330
|
+
"data-type": this.name
|
1331
|
+
}, this.options.HTMLAttributes, HTMLAttributes);
|
1332
|
+
const html = this.options.renderHTML({
|
1333
|
+
options: mergedOptions,
|
1334
|
+
node
|
1335
|
+
});
|
1336
|
+
if (typeof html === "string") {
|
1337
|
+
return ["span", mergeAttributes({
|
1338
|
+
"data-type": this.name
|
1339
|
+
}, this.options.HTMLAttributes, HTMLAttributes), html];
|
1340
|
+
}
|
1341
|
+
return html;
|
1342
|
+
},
|
1343
|
+
renderText({
|
1344
|
+
node
|
1345
|
+
}) {
|
1346
|
+
return this.options.renderText({
|
1347
|
+
options: this.options,
|
1348
|
+
node
|
1349
|
+
});
|
1350
|
+
},
|
1351
|
+
addKeyboardShortcuts() {
|
1352
|
+
return {
|
1353
|
+
Backspace: () => this.editor.commands.command(({
|
1354
|
+
tr,
|
1355
|
+
state
|
1356
|
+
}) => {
|
1357
|
+
let isCommand = false;
|
1358
|
+
const {
|
1359
|
+
selection
|
1360
|
+
} = state;
|
1361
|
+
const {
|
1362
|
+
empty,
|
1363
|
+
anchor
|
1364
|
+
} = selection;
|
1365
|
+
if (!empty) {
|
1366
|
+
return false;
|
1367
|
+
}
|
1368
|
+
state.doc.nodesBetween(anchor - 1, anchor, (node, pos) => {
|
1369
|
+
if (node.type.name === this.name) {
|
1370
|
+
isCommand = true;
|
1371
|
+
tr.insertText(this.options.deleteTriggerWithBackspace ? "" : this.options.suggestion.char || "", pos, pos + node.nodeSize);
|
1372
|
+
return false;
|
1373
|
+
}
|
1374
|
+
return true;
|
1375
|
+
});
|
1376
|
+
return isCommand;
|
709
1377
|
})
|
710
|
-
|
711
|
-
}
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
})
|
719
|
-
|
720
|
-
|
721
|
-
|
1378
|
+
};
|
1379
|
+
},
|
1380
|
+
addProseMirrorPlugins() {
|
1381
|
+
return [Suggestion({
|
1382
|
+
editor: this.editor,
|
1383
|
+
...this.options.suggestion
|
1384
|
+
})];
|
1385
|
+
}
|
1386
|
+
});
|
1387
|
+
const suggestion = (ref, {
|
1388
|
+
upload,
|
1389
|
+
onDisabledAutocompleteClick,
|
1390
|
+
aiController
|
1391
|
+
}) => ({
|
1392
|
+
items: ({
|
1393
|
+
query
|
1394
|
+
}) => {
|
1395
|
+
const availableSuggestionItems = [...suggestionItems];
|
1396
|
+
if (!onDisabledAutocompleteClick && aiController) {
|
1397
|
+
availableSuggestionItems.push(autocompleteSuggestionItem);
|
1398
|
+
}
|
1399
|
+
if (onDisabledAutocompleteClick) {
|
1400
|
+
availableSuggestionItems.push({
|
1401
|
+
title: "Autocomplete",
|
1402
|
+
description: "Add text based on the context.",
|
1403
|
+
searchTerms: ["ai"],
|
1404
|
+
icon: /* @__PURE__ */ jsx(AutoFixHighIcon, { size: 18 }),
|
1405
|
+
command: onDisabledAutocompleteClick
|
1406
|
+
});
|
722
1407
|
}
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
|
1408
|
+
return availableSuggestionItems.filter((item) => {
|
1409
|
+
const inTitle = item.title.toLowerCase().startsWith(query.toLowerCase());
|
1410
|
+
if (inTitle) return inTitle;
|
1411
|
+
const inSearchTerms = item.searchTerms?.some((term) => term.toLowerCase().startsWith(query.toLowerCase()));
|
1412
|
+
return inSearchTerms;
|
1413
|
+
});
|
1414
|
+
},
|
1415
|
+
render: () => {
|
1416
|
+
let component;
|
1417
|
+
let popup;
|
1418
|
+
return {
|
1419
|
+
onStart: (props) => {
|
1420
|
+
component = new ReactRenderer(CommandList, {
|
1421
|
+
props: {
|
1422
|
+
...props,
|
1423
|
+
upload,
|
1424
|
+
aiController
|
1425
|
+
},
|
1426
|
+
editor: props.editor
|
1427
|
+
});
|
1428
|
+
if (!props.clientRect) {
|
1429
|
+
return;
|
1430
|
+
}
|
1431
|
+
popup = tippy("body", {
|
1432
|
+
getReferenceClientRect: props.clientRect,
|
1433
|
+
appendTo: ref?.current,
|
1434
|
+
content: component.element,
|
1435
|
+
showOnCreate: true,
|
1436
|
+
interactive: true,
|
1437
|
+
trigger: "manual",
|
1438
|
+
placement: "bottom-start"
|
1439
|
+
});
|
1440
|
+
},
|
1441
|
+
onUpdate(props) {
|
1442
|
+
component.updateProps(props);
|
1443
|
+
if (!props.clientRect) {
|
1444
|
+
return;
|
1445
|
+
}
|
1446
|
+
popup[0].setProps({
|
1447
|
+
getReferenceClientRect: props.clientRect
|
1448
|
+
});
|
1449
|
+
},
|
1450
|
+
onKeyDown(props) {
|
1451
|
+
if (props.event.key === "Escape") {
|
1452
|
+
popup[0].hide();
|
1453
|
+
props.event.preventDefault();
|
1454
|
+
return true;
|
1455
|
+
}
|
1456
|
+
return component.ref?.onKeyDown(props);
|
1457
|
+
},
|
1458
|
+
onExit() {
|
1459
|
+
if (popup && popup[0]) popup[0].destroy();
|
1460
|
+
component?.destroy();
|
763
1461
|
}
|
764
|
-
}
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
|
1462
|
+
};
|
1463
|
+
}
|
1464
|
+
});
|
1465
|
+
const CommandList = forwardRef((props, ref) => {
|
1466
|
+
const $ = c(33);
|
1467
|
+
const [selectedIndex, setSelectedIndex] = useState(0);
|
1468
|
+
const {
|
1469
|
+
editor
|
1470
|
+
} = useCurrentEditor();
|
1471
|
+
let t0;
|
1472
|
+
if ($[0] !== editor || $[1] !== props.aiController || $[2] !== props.range || $[3] !== props.upload) {
|
1473
|
+
t0 = (item) => {
|
1474
|
+
if (!editor) {
|
1475
|
+
return;
|
772
1476
|
}
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
779
|
-
|
780
|
-
|
1477
|
+
item?.command?.({
|
1478
|
+
editor,
|
1479
|
+
range: props.range,
|
1480
|
+
upload: props.upload,
|
1481
|
+
aiController: props.aiController
|
1482
|
+
});
|
1483
|
+
};
|
1484
|
+
$[0] = editor;
|
1485
|
+
$[1] = props.aiController;
|
1486
|
+
$[2] = props.range;
|
1487
|
+
$[3] = props.upload;
|
1488
|
+
$[4] = t0;
|
1489
|
+
} else {
|
1490
|
+
t0 = $[4];
|
1491
|
+
}
|
1492
|
+
const selectItem = t0;
|
1493
|
+
let t1;
|
1494
|
+
if ($[5] !== props.items.length || $[6] !== selectedIndex) {
|
1495
|
+
t1 = () => {
|
1496
|
+
setSelectedIndex((selectedIndex + props.items.length - 1) % props.items.length);
|
1497
|
+
};
|
1498
|
+
$[5] = props.items.length;
|
1499
|
+
$[6] = selectedIndex;
|
1500
|
+
$[7] = t1;
|
1501
|
+
} else {
|
1502
|
+
t1 = $[7];
|
1503
|
+
}
|
1504
|
+
const upHandler = t1;
|
1505
|
+
let t2;
|
1506
|
+
if ($[8] !== props.items.length || $[9] !== selectedIndex) {
|
1507
|
+
t2 = () => {
|
1508
|
+
setSelectedIndex((selectedIndex + 1) % props.items.length);
|
1509
|
+
};
|
1510
|
+
$[8] = props.items.length;
|
1511
|
+
$[9] = selectedIndex;
|
1512
|
+
$[10] = t2;
|
1513
|
+
} else {
|
1514
|
+
t2 = $[10];
|
1515
|
+
}
|
1516
|
+
const downHandler = t2;
|
1517
|
+
let t3;
|
1518
|
+
if ($[11] !== props.items || $[12] !== selectItem || $[13] !== selectedIndex) {
|
1519
|
+
t3 = () => {
|
1520
|
+
const item_0 = props.items[selectedIndex];
|
1521
|
+
selectItem(item_0);
|
1522
|
+
};
|
1523
|
+
$[11] = props.items;
|
1524
|
+
$[12] = selectItem;
|
1525
|
+
$[13] = selectedIndex;
|
1526
|
+
$[14] = t3;
|
1527
|
+
} else {
|
1528
|
+
t3 = $[14];
|
1529
|
+
}
|
1530
|
+
const enterHandler = t3;
|
1531
|
+
let t4;
|
1532
|
+
if ($[15] === Symbol.for("react.memo_cache_sentinel")) {
|
1533
|
+
t4 = () => setSelectedIndex(0);
|
1534
|
+
$[15] = t4;
|
1535
|
+
} else {
|
1536
|
+
t4 = $[15];
|
1537
|
+
}
|
1538
|
+
let t5;
|
1539
|
+
if ($[16] !== props.items) {
|
1540
|
+
t5 = [props.items];
|
1541
|
+
$[16] = props.items;
|
1542
|
+
$[17] = t5;
|
1543
|
+
} else {
|
1544
|
+
t5 = $[17];
|
1545
|
+
}
|
1546
|
+
useEffect(t4, t5);
|
1547
|
+
let t6;
|
1548
|
+
if ($[18] !== downHandler || $[19] !== enterHandler || $[20] !== upHandler) {
|
1549
|
+
t6 = () => ({
|
1550
|
+
onKeyDown: (t72) => {
|
1551
|
+
const {
|
1552
|
+
event
|
1553
|
+
} = t72;
|
1554
|
+
if (event.key === "ArrowUp") {
|
1555
|
+
upHandler();
|
1556
|
+
return true;
|
1557
|
+
}
|
1558
|
+
if (event.key === "ArrowDown") {
|
1559
|
+
downHandler();
|
1560
|
+
return true;
|
1561
|
+
}
|
1562
|
+
if (event.key === "Enter") {
|
1563
|
+
enterHandler();
|
1564
|
+
return true;
|
1565
|
+
}
|
1566
|
+
return false;
|
781
1567
|
}
|
782
|
-
}
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
1568
|
+
});
|
1569
|
+
$[18] = downHandler;
|
1570
|
+
$[19] = enterHandler;
|
1571
|
+
$[20] = upHandler;
|
1572
|
+
$[21] = t6;
|
1573
|
+
} else {
|
1574
|
+
t6 = $[21];
|
1575
|
+
}
|
1576
|
+
useImperativeHandle(ref, t6);
|
1577
|
+
let t7;
|
1578
|
+
if ($[22] === Symbol.for("react.memo_cache_sentinel")) {
|
1579
|
+
t7 = [];
|
1580
|
+
$[22] = t7;
|
1581
|
+
} else {
|
1582
|
+
t7 = $[22];
|
1583
|
+
}
|
1584
|
+
const itemRefs = useRef(t7);
|
1585
|
+
let t8;
|
1586
|
+
let t9;
|
1587
|
+
if ($[23] !== selectedIndex) {
|
1588
|
+
t8 = () => {
|
1589
|
+
if (itemRefs.current[selectedIndex]) {
|
1590
|
+
itemRefs.current[selectedIndex].scrollIntoView({
|
1591
|
+
block: "nearest"
|
1592
|
+
});
|
790
1593
|
}
|
791
|
-
}
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
1594
|
+
};
|
1595
|
+
t9 = [selectedIndex];
|
1596
|
+
$[23] = selectedIndex;
|
1597
|
+
$[24] = t8;
|
1598
|
+
$[25] = t9;
|
1599
|
+
} else {
|
1600
|
+
t8 = $[24];
|
1601
|
+
t9 = $[25];
|
1602
|
+
}
|
1603
|
+
useEffect(t8, t9);
|
1604
|
+
let t10;
|
1605
|
+
if ($[26] === Symbol.for("react.memo_cache_sentinel")) {
|
1606
|
+
t10 = cls("text-surface-900 dark:text-white z-50 max-h-[280px] h-auto w-72 overflow-y-auto rounded-md border bg-white dark:bg-surface-900 px-1 py-2 shadow transition-all", defaultBorderMixin);
|
1607
|
+
$[26] = t10;
|
1608
|
+
} else {
|
1609
|
+
t10 = $[26];
|
1610
|
+
}
|
1611
|
+
let t11;
|
1612
|
+
if ($[27] !== props.items || $[28] !== selectItem || $[29] !== selectedIndex) {
|
1613
|
+
t11 = props.items.length ? props.items.map((item_1, index) => /* @__PURE__ */ jsxs("button", { value: item_1.title, ref: (el) => {
|
1614
|
+
if (!el) {
|
1615
|
+
return;
|
799
1616
|
}
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
1617
|
+
itemRefs.current[index] = el;
|
1618
|
+
}, onClick: () => selectItem(item_1), tabIndex: index === selectedIndex ? 0 : -1, "aria-selected": index === selectedIndex, className: cls("flex w-full items-center space-x-2 rounded-md px-2 py-1 text-left text-sm hover:bg-blue-50 hover:dark:bg-surface-700 aria-selected:bg-blue-50 aria-selected:dark:bg-surface-700", index === selectedIndex ? "bg-blue-100 dark:bg-surface-accent-950" : ""), children: [
|
1619
|
+
/* @__PURE__ */ jsx("div", { className: cls("flex h-10 w-10 items-center justify-center rounded-md border bg-white dark:bg-surface-900", defaultBorderMixin), children: item_1.icon }),
|
1620
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
1621
|
+
/* @__PURE__ */ jsx("p", { className: "font-medium", children: item_1.title }),
|
1622
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-surface-700 dark:text-surface-accent-300", children: item_1.description })
|
1623
|
+
] })
|
1624
|
+
] }, item_1.title)) : /* @__PURE__ */ jsx("div", { className: "item", children: "No result" });
|
1625
|
+
$[27] = props.items;
|
1626
|
+
$[28] = selectItem;
|
1627
|
+
$[29] = selectedIndex;
|
1628
|
+
$[30] = t11;
|
1629
|
+
} else {
|
1630
|
+
t11 = $[30];
|
1631
|
+
}
|
1632
|
+
let t12;
|
1633
|
+
if ($[31] !== t11) {
|
1634
|
+
t12 = /* @__PURE__ */ jsx("div", { className: t10, children: t11 });
|
1635
|
+
$[31] = t11;
|
1636
|
+
$[32] = t12;
|
1637
|
+
} else {
|
1638
|
+
t12 = $[32];
|
1639
|
+
}
|
1640
|
+
return t12;
|
1641
|
+
});
|
1642
|
+
const autocompleteSuggestionItem = {
|
1643
|
+
title: "Autocomplete",
|
1644
|
+
description: "Add text based on the context.",
|
1645
|
+
searchTerms: ["ai"],
|
1646
|
+
icon: /* @__PURE__ */ jsx(AutoFixHighIcon, { size: 18 }),
|
1647
|
+
command: async ({
|
1648
|
+
editor,
|
1649
|
+
range,
|
1650
|
+
aiController
|
1651
|
+
}) => {
|
1652
|
+
if (!aiController) throw Error("No AiController");
|
1653
|
+
editor.chain().focus().deleteRange(range).toggleNode("paragraph", "paragraph").run();
|
1654
|
+
const {
|
1655
|
+
state
|
1656
|
+
} = editor;
|
1657
|
+
const {
|
1658
|
+
from,
|
1659
|
+
to
|
1660
|
+
} = state.selection;
|
1661
|
+
const textBeforeCursor = state.doc.textBetween(0, from, "\n");
|
1662
|
+
const textAfterCursor = state.doc.textBetween(to, state.doc.content.size, "\n");
|
1663
|
+
let buffer = "";
|
1664
|
+
const result = await aiController.autocomplete(textBeforeCursor, textAfterCursor, (delta) => {
|
1665
|
+
buffer += delta;
|
1666
|
+
if (delta.length !== 0) {
|
1667
|
+
editor.chain().focus().toggleLoadingDecoration(buffer).run();
|
808
1668
|
}
|
809
|
-
}
|
810
|
-
{
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
command: ({ editor: l, range: m }) => {
|
816
|
-
l.chain().focus().deleteRange(m).toggleOrderedList().run();
|
1669
|
+
});
|
1670
|
+
editor.chain().focus().insertContent(result, {
|
1671
|
+
applyInputRules: false,
|
1672
|
+
applyPasteRules: false,
|
1673
|
+
parseOptions: {
|
1674
|
+
preserveWhitespace: false
|
817
1675
|
}
|
818
|
-
}
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
1676
|
+
}).run();
|
1677
|
+
}
|
1678
|
+
};
|
1679
|
+
const suggestionItems = [{
|
1680
|
+
title: "Text",
|
1681
|
+
description: "Just start typing with plain text.",
|
1682
|
+
searchTerms: ["p", "paragraph"],
|
1683
|
+
icon: /* @__PURE__ */ jsx(TextFieldsIcon, { size: 18 }),
|
1684
|
+
command: ({
|
1685
|
+
editor,
|
1686
|
+
range
|
1687
|
+
}) => {
|
1688
|
+
editor.chain().focus().deleteRange(range).toggleNode("paragraph", "paragraph").run();
|
1689
|
+
}
|
1690
|
+
}, {
|
1691
|
+
title: "To-do List",
|
1692
|
+
description: "Track tasks with a to-do list.",
|
1693
|
+
searchTerms: ["todo", "task", "list", "check", "checkbox"],
|
1694
|
+
icon: /* @__PURE__ */ jsx(CheckBoxIcon, { size: 18 }),
|
1695
|
+
command: ({
|
1696
|
+
editor,
|
1697
|
+
range
|
1698
|
+
}) => {
|
1699
|
+
editor.chain().focus().deleteRange(range).toggleTaskList().run();
|
1700
|
+
}
|
1701
|
+
}, {
|
1702
|
+
title: "Heading 1",
|
1703
|
+
description: "Big section heading.",
|
1704
|
+
searchTerms: ["title", "big", "large"],
|
1705
|
+
icon: /* @__PURE__ */ jsx(LooksOneIcon, { size: 18 }),
|
1706
|
+
command: ({
|
1707
|
+
editor,
|
1708
|
+
range
|
1709
|
+
}) => {
|
1710
|
+
editor.chain().focus().deleteRange(range).setNode("heading", {
|
1711
|
+
level: 1
|
1712
|
+
}).run();
|
1713
|
+
}
|
1714
|
+
}, {
|
1715
|
+
title: "Heading 2",
|
1716
|
+
description: "Medium section heading.",
|
1717
|
+
searchTerms: ["subtitle", "medium"],
|
1718
|
+
icon: /* @__PURE__ */ jsx(LooksTwoIcon, { size: 18 }),
|
1719
|
+
command: ({
|
1720
|
+
editor,
|
1721
|
+
range
|
1722
|
+
}) => {
|
1723
|
+
editor.chain().focus().deleteRange(range).setNode("heading", {
|
1724
|
+
level: 2
|
1725
|
+
}).run();
|
1726
|
+
}
|
1727
|
+
}, {
|
1728
|
+
title: "Heading 3",
|
1729
|
+
description: "Small section heading.",
|
1730
|
+
searchTerms: ["subtitle", "small"],
|
1731
|
+
icon: /* @__PURE__ */ jsx(Looks3Icon, { size: 18 }),
|
1732
|
+
command: ({
|
1733
|
+
editor,
|
1734
|
+
range
|
1735
|
+
}) => {
|
1736
|
+
editor.chain().focus().deleteRange(range).setNode("heading", {
|
1737
|
+
level: 3
|
1738
|
+
}).run();
|
1739
|
+
}
|
1740
|
+
}, {
|
1741
|
+
title: "Bullet List",
|
1742
|
+
description: "Create a simple bullet list.",
|
1743
|
+
searchTerms: ["unordered", "point"],
|
1744
|
+
icon: /* @__PURE__ */ jsx(FormatListBulletedIcon, { size: 18 }),
|
1745
|
+
command: ({
|
1746
|
+
editor,
|
1747
|
+
range
|
1748
|
+
}) => {
|
1749
|
+
editor.chain().focus().deleteRange(range).toggleBulletList().run();
|
1750
|
+
}
|
1751
|
+
}, {
|
1752
|
+
title: "Numbered List",
|
1753
|
+
description: "Create a list with numbering.",
|
1754
|
+
searchTerms: ["ordered"],
|
1755
|
+
icon: /* @__PURE__ */ jsx(FormatListNumberedIcon, { size: 18 }),
|
1756
|
+
command: ({
|
1757
|
+
editor,
|
1758
|
+
range
|
1759
|
+
}) => {
|
1760
|
+
editor.chain().focus().deleteRange(range).toggleOrderedList().run();
|
1761
|
+
}
|
1762
|
+
}, {
|
1763
|
+
title: "Quote",
|
1764
|
+
description: "Capture a quote.",
|
1765
|
+
searchTerms: ["blockquote"],
|
1766
|
+
icon: /* @__PURE__ */ jsx(FormatQuoteIcon, { size: 18 }),
|
1767
|
+
command: ({
|
1768
|
+
editor,
|
1769
|
+
range
|
1770
|
+
}) => editor.chain().focus().deleteRange(range).toggleNode("paragraph", "paragraph").toggleBlockquote().run()
|
1771
|
+
}, {
|
1772
|
+
title: "Code",
|
1773
|
+
description: "Capture a code snippet.",
|
1774
|
+
searchTerms: ["codeblock"],
|
1775
|
+
icon: /* @__PURE__ */ jsx(CodeIcon, { size: 18 }),
|
1776
|
+
command: ({
|
1777
|
+
editor,
|
1778
|
+
range
|
1779
|
+
}) => editor.chain().focus().deleteRange(range).toggleCodeBlock().run()
|
1780
|
+
}, {
|
1781
|
+
title: "Image",
|
1782
|
+
description: "Upload an image from your computer.",
|
1783
|
+
searchTerms: ["photo", "picture", "media", "upload", "file"],
|
1784
|
+
icon: /* @__PURE__ */ jsx(ImageIcon, { size: 18 }),
|
1785
|
+
command: ({
|
1786
|
+
editor,
|
1787
|
+
range,
|
1788
|
+
upload
|
1789
|
+
}) => {
|
1790
|
+
editor.chain().focus().deleteRange(range).run();
|
1791
|
+
const input = document.createElement("input");
|
1792
|
+
input.type = "file";
|
1793
|
+
input.accept = "image/*";
|
1794
|
+
input.onchange = async () => {
|
1795
|
+
if (input.files?.length) {
|
1796
|
+
const file = input.files[0];
|
1797
|
+
if (!file) return;
|
1798
|
+
const pos = editor.view.state.selection.from;
|
1799
|
+
const fileList = input.files;
|
1800
|
+
const files = Array.from(fileList);
|
1801
|
+
const images = files.filter((file2) => /image/i.test(file2.type));
|
1802
|
+
if (images.length === 0) {
|
1803
|
+
console.log("No images found in uploaded files");
|
1804
|
+
return false;
|
1805
|
+
}
|
1806
|
+
const view = editor.view;
|
1807
|
+
images.forEach((image) => {
|
1808
|
+
const reader = new FileReader();
|
1809
|
+
reader.onload = async (readerEvent) => {
|
1810
|
+
await onFileRead(view, readerEvent, pos, upload, image);
|
1811
|
+
};
|
1812
|
+
reader.readAsDataURL(image);
|
1813
|
+
});
|
1814
|
+
}
|
1815
|
+
return true;
|
1816
|
+
};
|
1817
|
+
input.click();
|
1818
|
+
}
|
1819
|
+
}];
|
1820
|
+
const CustomDocument = Document.extend({
|
1821
|
+
// content: 'heading block*',
|
1822
|
+
});
|
1823
|
+
const proseClasses = {
|
1824
|
+
"sm": "prose-sm",
|
1825
|
+
"base": "prose-base",
|
1826
|
+
"lg": "prose-lg"
|
1827
|
+
};
|
1828
|
+
const FireCMSEditor = ({
|
1829
|
+
content,
|
1830
|
+
onJsonContentChange,
|
1831
|
+
onHtmlContentChange,
|
1832
|
+
onMarkdownContentChange,
|
1833
|
+
version,
|
1834
|
+
textSize = "base",
|
1835
|
+
highlight,
|
1836
|
+
handleImageUpload,
|
1837
|
+
aiController,
|
1838
|
+
onDisabledAutocompleteClick
|
1839
|
+
}) => {
|
1840
|
+
const ref = React.useRef(null);
|
1841
|
+
const editorRef = React.useRef(null);
|
1842
|
+
const imagePlugin = createDropImagePlugin(handleImageUpload);
|
1843
|
+
const imageExtension = useMemo(() => createImageExtension(imagePlugin), []);
|
1844
|
+
const [openNode, setOpenNode] = useState(false);
|
1845
|
+
const [openLink, setOpenLink] = useState(false);
|
1846
|
+
useInjectStyles("Editor", cssStyles);
|
1847
|
+
const deferredHighlight = useDeferredValue(highlight);
|
1848
|
+
useEffect(() => {
|
1849
|
+
if (version === void 0) return;
|
1850
|
+
if (version > -1 && editorRef.current) {
|
1851
|
+
editorRef.current?.commands.setContent(content ?? "");
|
1852
|
+
}
|
1853
|
+
}, [version]);
|
1854
|
+
useEffect(() => {
|
1855
|
+
if (version === void 0) return;
|
1856
|
+
if (editorRef.current && version > 0) {
|
1857
|
+
const chain = editorRef.current.chain();
|
1858
|
+
if (deferredHighlight) {
|
1859
|
+
chain.focus().toggleAutocompleteHighlight(deferredHighlight).run();
|
1860
|
+
} else {
|
1861
|
+
chain.focus().removeAutocompleteHighlight().run();
|
848
1862
|
}
|
849
1863
|
}
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
1864
|
+
}, [deferredHighlight?.from, deferredHighlight?.to]);
|
1865
|
+
const onEditorUpdate = (editor) => {
|
1866
|
+
editorRef.current = editor;
|
1867
|
+
if (onMarkdownContentChange) {
|
1868
|
+
const markdown = editorRef.current.storage.markdown.getMarkdown();
|
1869
|
+
onMarkdownContentChange?.(addLineBreakAfterImages(markdown));
|
854
1870
|
}
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
|
1871
|
+
if (onJsonContentChange) {
|
1872
|
+
const jsonContent = removeClassesFromJson(editor.getJSON());
|
1873
|
+
onJsonContentChange(jsonContent);
|
1874
|
+
}
|
1875
|
+
if (onHtmlContentChange) {
|
1876
|
+
onHtmlContentChange?.(editor.getHTML());
|
1877
|
+
}
|
1878
|
+
};
|
1879
|
+
const proseClass = proseClasses[textSize];
|
1880
|
+
const extensions = useMemo(() => [
|
1881
|
+
starterKit,
|
1882
|
+
CustomDocument,
|
1883
|
+
HighlightDecorationExtension(highlight),
|
1884
|
+
TextLoadingDecorationExtension,
|
1885
|
+
Underline,
|
1886
|
+
Bold,
|
1887
|
+
TextStyle,
|
1888
|
+
Italic,
|
1889
|
+
Strike,
|
1890
|
+
Color,
|
1891
|
+
Highlight.configure({
|
1892
|
+
multicolor: true
|
861
1893
|
}),
|
862
|
-
|
863
|
-
|
864
|
-
|
1894
|
+
// CustomBlock.configure({
|
1895
|
+
// component: CustomComponent,
|
1896
|
+
// delimiter: "```custom"
|
1897
|
+
// }),
|
1898
|
+
Heading,
|
1899
|
+
CustomKeymap,
|
1900
|
+
DragAndDrop,
|
1901
|
+
placeholder,
|
1902
|
+
tiptapLink,
|
1903
|
+
imageExtension,
|
1904
|
+
taskList,
|
1905
|
+
taskItem,
|
1906
|
+
Markdown.configure({
|
1907
|
+
html: true
|
865
1908
|
}),
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
|
873
|
-
|
874
|
-
|
875
|
-
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
|
882
|
-
|
883
|
-
|
884
|
-
|
885
|
-
|
886
|
-
|
887
|
-
}
|
888
|
-
}, !1, 500), R(M, () => {
|
889
|
-
M && t?.(M);
|
890
|
-
}, !1, 500), R(N, () => {
|
891
|
-
N && r?.(N);
|
892
|
-
}, !1, 500), o ? /* @__PURE__ */ s("div", { className: "relative w-full p-8", children: /* @__PURE__ */ s(Ge, { children: /* @__PURE__ */ s(
|
893
|
-
"div",
|
894
|
-
{
|
895
|
-
className: "relative min-h-[500px] w-full bg-white dark:bg-gray-950 rounded-lg",
|
896
|
-
children: /* @__PURE__ */ b(
|
897
|
-
ye,
|
898
|
-
{
|
899
|
-
content: o,
|
900
|
-
extensions: u,
|
901
|
-
editorProps: {
|
902
|
-
...c,
|
903
|
-
attributes: {
|
904
|
-
class: "prose-lg prose-headings:font-title font-default focus:outline-none max-w-full p-12"
|
905
|
-
}
|
906
|
-
},
|
907
|
-
onUpdate: ({ editor: l }) => {
|
908
|
-
console.log("editor updated"), ue(l);
|
909
|
-
},
|
910
|
-
children: [
|
911
|
-
/* @__PURE__ */ b(
|
912
|
-
tt,
|
913
|
-
{
|
914
|
-
className: g("text-gray-900 dark:text-white z-50 h-auto max-h-[330px] w-72 overflow-y-auto rounded-md border bg-white dark:bg-gray-900 px-1 py-2 shadow transition-all", x),
|
915
|
-
children: [
|
916
|
-
/* @__PURE__ */ s(ot, { className: "px-2 text-gray-700 dark:text-slate-300", children: "No results" }),
|
917
|
-
n.map((l) => /* @__PURE__ */ b(
|
918
|
-
se,
|
919
|
-
{
|
920
|
-
value: l.title,
|
921
|
-
onCommand: (m) => l?.command?.(m),
|
922
|
-
className: "flex w-full items-center space-x-2 rounded-md px-2 py-1 text-left text-sm hover:bg-blue-50 hover:dark:bg-gray-700 aria-selected:bg-blue-50 aria-selected:dark:bg-gray-700",
|
923
|
-
children: [
|
924
|
-
/* @__PURE__ */ s(
|
925
|
-
"div",
|
926
|
-
{
|
927
|
-
className: g("flex h-10 w-10 items-center justify-center rounded-md border bg-white dark:bg-gray-900", x),
|
928
|
-
children: l.icon
|
929
|
-
}
|
930
|
-
),
|
931
|
-
/* @__PURE__ */ b("div", { children: [
|
932
|
-
/* @__PURE__ */ s("p", { className: "font-medium", children: l.title }),
|
933
|
-
/* @__PURE__ */ s("p", { className: "text-xs text-gray-700 dark:text-slate-300", children: l.description })
|
934
|
-
] })
|
935
|
-
]
|
936
|
-
},
|
937
|
-
l.title
|
938
|
-
))
|
939
|
-
]
|
940
|
-
}
|
941
|
-
),
|
942
|
-
/* @__PURE__ */ b(
|
943
|
-
je,
|
944
|
-
{
|
945
|
-
tippyOptions: {
|
946
|
-
placement: "top"
|
947
|
-
},
|
948
|
-
className: g("flex w-fit max-w-[90vw] h-10 overflow-hidden rounded border bg-white dark:bg-gray-900 shadow", x),
|
949
|
-
children: [
|
950
|
-
/* @__PURE__ */ s(ct, { open: p, onOpenChange: h }),
|
951
|
-
/* @__PURE__ */ s(K, { orientation: "vertical" }),
|
952
|
-
/* @__PURE__ */ s(ut, { open: f, onOpenChange: A }),
|
953
|
-
/* @__PURE__ */ s(K, { orientation: "vertical" }),
|
954
|
-
/* @__PURE__ */ s(mt, {})
|
955
|
-
]
|
956
|
-
}
|
957
|
-
)
|
958
|
-
]
|
959
|
-
}
|
960
|
-
)
|
1909
|
+
horizontalRule,
|
1910
|
+
bulletList,
|
1911
|
+
orderedList,
|
1912
|
+
listItem,
|
1913
|
+
blockquote,
|
1914
|
+
codeBlock,
|
1915
|
+
code,
|
1916
|
+
SlashCommand.configure({
|
1917
|
+
HTMLAttributes: {
|
1918
|
+
class: "mention"
|
1919
|
+
},
|
1920
|
+
suggestion: suggestion(ref, {
|
1921
|
+
upload: handleImageUpload,
|
1922
|
+
aiController,
|
1923
|
+
onDisabledAutocompleteClick
|
1924
|
+
})
|
1925
|
+
})
|
1926
|
+
], []);
|
1927
|
+
return /* @__PURE__ */ jsx("div", { ref, className: "relative min-h-[300px] w-full", children: /* @__PURE__ */ jsx(EditorProvider, { content: content ?? "", extensions, editorProps: {
|
1928
|
+
attributes: {
|
1929
|
+
class: cls(proseClass, "prose-headings:font-title font-default focus:outline-none max-w-full p-12")
|
961
1930
|
}
|
962
|
-
|
1931
|
+
}, onCreate: ({
|
1932
|
+
editor: editor_0
|
1933
|
+
}) => {
|
1934
|
+
editorRef.current = editor_0;
|
1935
|
+
}, onUpdate: ({
|
1936
|
+
editor: editor_1
|
1937
|
+
}) => {
|
1938
|
+
onEditorUpdate(editor_1);
|
1939
|
+
}, children: /* @__PURE__ */ jsxs(EditorBubble, { tippyOptions: {
|
1940
|
+
placement: "top"
|
1941
|
+
}, className: cls("flex w-fit max-w-[90vw] h-10 overflow-hidden rounded border bg-white dark:bg-surface-900 shadow", defaultBorderMixin), children: [
|
1942
|
+
/* @__PURE__ */ jsx(NodeSelector, { portalContainer: ref.current, open: openNode, onOpenChange: setOpenNode }),
|
1943
|
+
/* @__PURE__ */ jsx(Separator, { orientation: "vertical" }),
|
1944
|
+
/* @__PURE__ */ jsx(LinkSelector, { open: openLink, onOpenChange: setOpenLink }),
|
1945
|
+
/* @__PURE__ */ jsx(Separator, { orientation: "vertical" }),
|
1946
|
+
/* @__PURE__ */ jsx(TextButtons, {})
|
1947
|
+
] }) }) });
|
963
1948
|
};
|
964
|
-
function
|
965
|
-
const
|
966
|
-
return
|
1949
|
+
function addLineBreakAfterImages(markdown) {
|
1950
|
+
const imageRegex = /!\[.*?\]\(.*?\)/g;
|
1951
|
+
return markdown.replace(imageRegex, (match) => `${match}
|
967
1952
|
`);
|
968
1953
|
}
|
969
|
-
const
|
970
|
-
|
1954
|
+
const cssStyles = `
|
1955
|
+
.ProseMirror {
|
1956
|
+
box-shadow: none !important;
|
1957
|
+
}
|
971
1958
|
.ProseMirror .is-editor-empty:first-child::before {
|
972
1959
|
content: attr(data-placeholder);
|
973
1960
|
float: left;
|
@@ -990,6 +1977,7 @@ const Tt = `
|
|
990
1977
|
}
|
991
1978
|
|
992
1979
|
.is-empty {
|
1980
|
+
cursor: text;
|
993
1981
|
color: rgb(100 116 139); //500
|
994
1982
|
}
|
995
1983
|
|
@@ -1007,6 +1995,7 @@ const Tt = `
|
|
1007
1995
|
&.ProseMirror-selectednode {
|
1008
1996
|
outline: 3px solid #5abbf7;
|
1009
1997
|
filter: brightness(90%);
|
1998
|
+
box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000) !important;
|
1010
1999
|
}
|
1011
2000
|
}
|
1012
2001
|
|
@@ -1034,7 +2023,7 @@ ul[data-type="taskList"] li > label {
|
|
1034
2023
|
}
|
1035
2024
|
|
1036
2025
|
&:active {
|
1037
|
-
background-color: rgb(71 85 105)
|
2026
|
+
background-color: rgb(71 85 105);
|
1038
2027
|
}
|
1039
2028
|
}
|
1040
2029
|
}
|
@@ -1101,7 +2090,7 @@ ul[data-type="taskList"] li[data-checked="true"] > div > p {
|
|
1101
2090
|
}
|
1102
2091
|
|
1103
2092
|
.ProseMirror:not(.dragging) .ProseMirror-selectednode {
|
1104
|
-
outline: none !important;
|
2093
|
+
// outline: none !important;
|
1105
2094
|
background-color: rgb(219 234 254); // blue 100
|
1106
2095
|
transition: background-color 0.2s;
|
1107
2096
|
box-shadow: none;
|
@@ -1111,8 +2100,12 @@ ul[data-type="taskList"] li[data-checked="true"] > div > p {
|
|
1111
2100
|
background-color: rgb(51 65 85); // 700
|
1112
2101
|
}
|
1113
2102
|
|
2103
|
+
.prose-base table p {
|
2104
|
+
margin: 0;
|
2105
|
+
}
|
2106
|
+
|
1114
2107
|
.drag-handle {
|
1115
|
-
position:
|
2108
|
+
position: absolute;
|
1116
2109
|
opacity: 1;
|
1117
2110
|
transition: opacity ease-in 0.2s;
|
1118
2111
|
border-radius: 0.25rem;
|
@@ -1123,7 +2116,7 @@ ul[data-type="taskList"] li[data-checked="true"] > div > p {
|
|
1123
2116
|
background-position: center;
|
1124
2117
|
width: 1.2rem;
|
1125
2118
|
height: 1.5rem;
|
1126
|
-
z-index:
|
2119
|
+
z-index: 100;
|
1127
2120
|
cursor: grab;
|
1128
2121
|
|
1129
2122
|
&:hover {
|
@@ -1158,6 +2151,6 @@ ul[data-type="taskList"] li[data-checked="true"] > div > p {
|
|
1158
2151
|
}
|
1159
2152
|
`;
|
1160
2153
|
export {
|
1161
|
-
|
2154
|
+
FireCMSEditor
|
1162
2155
|
};
|
1163
2156
|
//# sourceMappingURL=index.es.js.map
|