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