@tiptap/vue-3 2.11.7 → 3.0.0-beta.1

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.
Files changed (48) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +5 -1
  3. package/dist/index.cjs +562 -528
  4. package/dist/index.cjs.map +1 -1
  5. package/dist/index.d.cts +219 -0
  6. package/dist/index.d.ts +218 -10
  7. package/dist/index.js +526 -516
  8. package/dist/index.js.map +1 -1
  9. package/dist/menus/index.cjs +613 -0
  10. package/dist/menus/index.cjs.map +1 -0
  11. package/dist/menus/index.d.cts +257 -0
  12. package/dist/menus/index.d.ts +257 -0
  13. package/dist/menus/index.js +605 -0
  14. package/dist/menus/index.js.map +1 -0
  15. package/package.json +27 -16
  16. package/src/Editor.ts +6 -11
  17. package/src/EditorContent.ts +10 -20
  18. package/src/VueMarkViewRenderer.ts +114 -0
  19. package/src/VueNodeViewRenderer.ts +19 -30
  20. package/src/VueRenderer.ts +10 -11
  21. package/src/index.ts +1 -2
  22. package/src/menus/BubbleMenu.ts +78 -0
  23. package/src/menus/FloatingMenu.ts +68 -0
  24. package/src/menus/index.ts +2 -0
  25. package/src/useEditor.ts +1 -1
  26. package/dist/BubbleMenu.d.ts +0 -61
  27. package/dist/BubbleMenu.d.ts.map +0 -1
  28. package/dist/Editor.d.ts +0 -24
  29. package/dist/Editor.d.ts.map +0 -1
  30. package/dist/EditorContent.d.ts +0 -18
  31. package/dist/EditorContent.d.ts.map +0 -1
  32. package/dist/FloatingMenu.d.ts +0 -49
  33. package/dist/FloatingMenu.d.ts.map +0 -1
  34. package/dist/NodeViewContent.d.ts +0 -14
  35. package/dist/NodeViewContent.d.ts.map +0 -1
  36. package/dist/NodeViewWrapper.d.ts +0 -14
  37. package/dist/NodeViewWrapper.d.ts.map +0 -1
  38. package/dist/VueNodeViewRenderer.d.ts +0 -63
  39. package/dist/VueNodeViewRenderer.d.ts.map +0 -1
  40. package/dist/VueRenderer.d.ts +0 -37
  41. package/dist/VueRenderer.d.ts.map +0 -1
  42. package/dist/index.d.ts.map +0 -1
  43. package/dist/index.umd.js +0 -570
  44. package/dist/index.umd.js.map +0 -1
  45. package/dist/useEditor.d.ts +0 -4
  46. package/dist/useEditor.d.ts.map +0 -1
  47. package/src/BubbleMenu.ts +0 -71
  48. package/src/FloatingMenu.ts +0 -66
package/dist/index.js CHANGED
@@ -1,553 +1,563 @@
1
- import { BubbleMenuPlugin } from '@tiptap/extension-bubble-menu';
2
- import { defineComponent, ref, onMounted, onBeforeUnmount, h, markRaw, customRef, getCurrentInstance, watchEffect, nextTick, unref, shallowRef, reactive, render, provide } from 'vue';
3
- import { Editor as Editor$1, NodeView } from '@tiptap/core';
4
- export * from '@tiptap/core';
5
- import { FloatingMenuPlugin } from '@tiptap/extension-floating-menu';
6
-
7
- const BubbleMenu = defineComponent({
8
- name: 'BubbleMenu',
9
- props: {
10
- pluginKey: {
11
- type: [String, Object],
12
- default: 'bubbleMenu',
13
- },
14
- editor: {
15
- type: Object,
16
- required: true,
17
- },
18
- updateDelay: {
19
- type: Number,
20
- default: undefined,
21
- },
22
- tippyOptions: {
23
- type: Object,
24
- default: () => ({}),
25
- },
26
- shouldShow: {
27
- type: Function,
28
- default: null,
29
- },
30
- },
31
- setup(props, { slots }) {
32
- const root = ref(null);
33
- onMounted(() => {
34
- const { updateDelay, editor, pluginKey, shouldShow, tippyOptions, } = props;
35
- editor.registerPlugin(BubbleMenuPlugin({
36
- updateDelay,
37
- editor,
38
- element: root.value,
39
- pluginKey,
40
- shouldShow,
41
- tippyOptions,
42
- }));
43
- });
44
- onBeforeUnmount(() => {
45
- const { pluginKey, editor } = props;
46
- editor.unregisterPlugin(pluginKey);
47
- });
48
- return () => { var _a; return h('div', { ref: root }, (_a = slots.default) === null || _a === void 0 ? void 0 : _a.call(slots)); };
49
- },
50
- });
51
-
52
- /* eslint-disable react-hooks/rules-of-hooks */
1
+ // src/Editor.ts
2
+ import { Editor as CoreEditor } from "@tiptap/core";
3
+ import { customRef, markRaw } from "vue";
53
4
  function useDebouncedRef(value) {
54
- return customRef((track, trigger) => {
55
- return {
56
- get() {
57
- track();
58
- return value;
59
- },
60
- set(newValue) {
61
- // update state
62
- value = newValue;
63
- // update view as soon as possible
64
- requestAnimationFrame(() => {
65
- requestAnimationFrame(() => {
66
- trigger();
67
- });
68
- });
69
- },
70
- };
71
- });
72
- }
73
- class Editor extends Editor$1 {
74
- constructor(options = {}) {
75
- super(options);
76
- this.contentComponent = null;
77
- this.appContext = null;
78
- this.reactiveState = useDebouncedRef(this.view.state);
79
- this.reactiveExtensionStorage = useDebouncedRef(this.extensionStorage);
80
- this.on('beforeTransaction', ({ nextState }) => {
81
- this.reactiveState.value = nextState;
82
- this.reactiveExtensionStorage.value = this.extensionStorage;
5
+ return customRef((track, trigger) => {
6
+ return {
7
+ get() {
8
+ track();
9
+ return value;
10
+ },
11
+ set(newValue) {
12
+ value = newValue;
13
+ requestAnimationFrame(() => {
14
+ requestAnimationFrame(() => {
15
+ trigger();
16
+ });
83
17
  });
84
- return markRaw(this); // eslint-disable-line
85
- }
86
- get state() {
87
- return this.reactiveState ? this.reactiveState.value : this.view.state;
88
- }
89
- get storage() {
90
- return this.reactiveExtensionStorage ? this.reactiveExtensionStorage.value : super.storage;
91
- }
92
- /**
93
- * Register a ProseMirror plugin.
94
- */
95
- registerPlugin(plugin, handlePlugins) {
96
- const nextState = super.registerPlugin(plugin, handlePlugins);
97
- if (this.reactiveState) {
98
- this.reactiveState.value = nextState;
99
- }
100
- return nextState;
18
+ }
19
+ };
20
+ });
21
+ }
22
+ var Editor = class extends CoreEditor {
23
+ constructor(options = {}) {
24
+ super(options);
25
+ this.contentComponent = null;
26
+ this.appContext = null;
27
+ this.reactiveState = useDebouncedRef(this.view.state);
28
+ this.reactiveExtensionStorage = useDebouncedRef(this.extensionStorage);
29
+ this.on("beforeTransaction", ({ nextState }) => {
30
+ this.reactiveState.value = nextState;
31
+ this.reactiveExtensionStorage.value = this.extensionStorage;
32
+ });
33
+ return markRaw(this);
34
+ }
35
+ get state() {
36
+ return this.reactiveState ? this.reactiveState.value : this.view.state;
37
+ }
38
+ get storage() {
39
+ return this.reactiveExtensionStorage ? this.reactiveExtensionStorage.value : super.storage;
40
+ }
41
+ /**
42
+ * Register a ProseMirror plugin.
43
+ */
44
+ registerPlugin(plugin, handlePlugins) {
45
+ const nextState = super.registerPlugin(plugin, handlePlugins);
46
+ if (this.reactiveState) {
47
+ this.reactiveState.value = nextState;
101
48
  }
102
- /**
103
- * Unregister a ProseMirror plugin.
104
- */
105
- unregisterPlugin(nameOrPluginKey) {
106
- const nextState = super.unregisterPlugin(nameOrPluginKey);
107
- if (this.reactiveState && nextState) {
108
- this.reactiveState.value = nextState;
109
- }
110
- return nextState;
49
+ return nextState;
50
+ }
51
+ /**
52
+ * Unregister a ProseMirror plugin.
53
+ */
54
+ unregisterPlugin(nameOrPluginKey) {
55
+ const nextState = super.unregisterPlugin(nameOrPluginKey);
56
+ if (this.reactiveState && nextState) {
57
+ this.reactiveState.value = nextState;
111
58
  }
112
- }
113
-
114
- const EditorContent = defineComponent({
115
- name: 'EditorContent',
116
- props: {
117
- editor: {
118
- default: null,
119
- type: Object,
120
- },
121
- },
122
- setup(props) {
123
- const rootEl = ref();
124
- const instance = getCurrentInstance();
125
- watchEffect(() => {
126
- const editor = props.editor;
127
- if (editor && editor.options.element && rootEl.value) {
128
- nextTick(() => {
129
- if (!rootEl.value || !editor.options.element.firstChild) {
130
- return;
131
- }
132
- const element = unref(rootEl.value);
133
- rootEl.value.append(...editor.options.element.childNodes);
134
- // @ts-ignore
135
- editor.contentComponent = instance.ctx._;
136
- if (instance) {
137
- editor.appContext = {
138
- ...instance.appContext,
139
- // Vue internally uses prototype chain to forward/shadow injects across the entire component chain
140
- // so don't use object spread operator or 'Object.assign' and just set `provides` as is on editor's appContext
141
- // @ts-expect-error forward instance's 'provides' into appContext
142
- provides: instance.provides,
143
- };
144
- }
145
- editor.setOptions({
146
- element,
147
- });
148
- editor.createNodeViews();
149
- });
150
- }
151
- });
152
- onBeforeUnmount(() => {
153
- const editor = props.editor;
154
- if (!editor) {
155
- return;
156
- }
157
- editor.contentComponent = null;
158
- editor.appContext = null;
159
- });
160
- return { rootEl };
161
- },
162
- render() {
163
- return h('div', {
164
- ref: (el) => { this.rootEl = el; },
165
- });
166
- },
167
- });
59
+ return nextState;
60
+ }
61
+ };
168
62
 
169
- const FloatingMenu = defineComponent({
170
- name: 'FloatingMenu',
171
- props: {
172
- pluginKey: {
173
- // TODO: TypeScript breaks :(
174
- // type: [String, Object as PropType<Exclude<FloatingMenuPluginProps['pluginKey'], string>>],
175
- type: null,
176
- default: 'floatingMenu',
177
- },
178
- editor: {
179
- type: Object,
180
- required: true,
181
- },
182
- tippyOptions: {
183
- type: Object,
184
- default: () => ({}),
185
- },
186
- shouldShow: {
187
- type: Function,
188
- default: null,
189
- },
190
- },
191
- setup(props, { slots }) {
192
- const root = ref(null);
193
- onMounted(() => {
194
- const { pluginKey, editor, tippyOptions, shouldShow, } = props;
195
- editor.registerPlugin(FloatingMenuPlugin({
196
- pluginKey,
197
- editor,
198
- element: root.value,
199
- tippyOptions,
200
- shouldShow,
201
- }));
202
- });
203
- onBeforeUnmount(() => {
204
- const { pluginKey, editor } = props;
205
- editor.unregisterPlugin(pluginKey);
63
+ // src/EditorContent.ts
64
+ import { defineComponent, getCurrentInstance, h, nextTick, onBeforeUnmount, ref, unref, watchEffect } from "vue";
65
+ var EditorContent = defineComponent({
66
+ name: "EditorContent",
67
+ props: {
68
+ editor: {
69
+ default: null,
70
+ type: Object
71
+ }
72
+ },
73
+ setup(props) {
74
+ const rootEl = ref();
75
+ const instance = getCurrentInstance();
76
+ watchEffect(() => {
77
+ const editor = props.editor;
78
+ if (editor && editor.options.element && rootEl.value) {
79
+ nextTick(() => {
80
+ var _a;
81
+ if (!rootEl.value || !((_a = editor.options.element) == null ? void 0 : _a.firstChild)) {
82
+ return;
83
+ }
84
+ const element = unref(rootEl.value);
85
+ rootEl.value.append(...editor.options.element.childNodes);
86
+ editor.contentComponent = instance.ctx._;
87
+ if (instance) {
88
+ editor.appContext = {
89
+ ...instance.appContext,
90
+ // Vue internally uses prototype chain to forward/shadow injects across the entire component chain
91
+ // so don't use object spread operator or 'Object.assign' and just set `provides` as is on editor's appContext
92
+ // @ts-expect-error forward instance's 'provides' into appContext
93
+ provides: instance.provides
94
+ };
95
+ }
96
+ editor.setOptions({
97
+ element
98
+ });
99
+ editor.createNodeViews();
206
100
  });
207
- return () => { var _a; return h('div', { ref: root }, (_a = slots.default) === null || _a === void 0 ? void 0 : _a.call(slots)); };
208
- },
101
+ }
102
+ });
103
+ onBeforeUnmount(() => {
104
+ const editor = props.editor;
105
+ if (!editor) {
106
+ return;
107
+ }
108
+ editor.contentComponent = null;
109
+ editor.appContext = null;
110
+ });
111
+ return { rootEl };
112
+ },
113
+ render() {
114
+ return h("div", {
115
+ ref: (el) => {
116
+ this.rootEl = el;
117
+ }
118
+ });
119
+ }
209
120
  });
210
121
 
211
- const NodeViewContent = defineComponent({
212
- name: 'NodeViewContent',
213
- props: {
214
- as: {
215
- type: String,
216
- default: 'div',
217
- },
218
- },
219
- render() {
220
- return h(this.as, {
221
- style: {
222
- whiteSpace: 'pre-wrap',
223
- },
224
- 'data-node-view-content': '',
225
- });
226
- },
122
+ // src/NodeViewContent.ts
123
+ import { defineComponent as defineComponent2, h as h2 } from "vue";
124
+ var NodeViewContent = defineComponent2({
125
+ name: "NodeViewContent",
126
+ props: {
127
+ as: {
128
+ type: String,
129
+ default: "div"
130
+ }
131
+ },
132
+ render() {
133
+ return h2(this.as, {
134
+ style: {
135
+ whiteSpace: "pre-wrap"
136
+ },
137
+ "data-node-view-content": ""
138
+ });
139
+ }
227
140
  });
228
141
 
229
- const NodeViewWrapper = defineComponent({
230
- name: 'NodeViewWrapper',
231
- props: {
232
- as: {
233
- type: String,
234
- default: 'div',
142
+ // src/NodeViewWrapper.ts
143
+ import { defineComponent as defineComponent3, h as h3 } from "vue";
144
+ var NodeViewWrapper = defineComponent3({
145
+ name: "NodeViewWrapper",
146
+ props: {
147
+ as: {
148
+ type: String,
149
+ default: "div"
150
+ }
151
+ },
152
+ inject: ["onDragStart", "decorationClasses"],
153
+ render() {
154
+ var _a, _b;
155
+ return h3(
156
+ this.as,
157
+ {
158
+ // @ts-ignore
159
+ class: this.decorationClasses,
160
+ style: {
161
+ whiteSpace: "normal"
235
162
  },
236
- },
237
- inject: ['onDragStart', 'decorationClasses'],
238
- render() {
239
- var _a, _b;
240
- return h(this.as, {
241
- // @ts-ignore
242
- class: this.decorationClasses,
243
- style: {
244
- whiteSpace: 'normal',
245
- },
246
- 'data-node-view-wrapper': '',
247
- // @ts-ignore (https://github.com/vuejs/vue-next/issues/3031)
248
- onDragstart: this.onDragStart,
249
- }, (_b = (_a = this.$slots).default) === null || _b === void 0 ? void 0 : _b.call(_a));
250
- },
163
+ "data-node-view-wrapper": "",
164
+ // @ts-ignore (https://github.com/vuejs/vue-next/issues/3031)
165
+ onDragstart: this.onDragStart
166
+ },
167
+ (_b = (_a = this.$slots).default) == null ? void 0 : _b.call(_a)
168
+ );
169
+ }
251
170
  });
252
171
 
253
- const useEditor = (options = {}) => {
254
- const editor = shallowRef();
255
- onMounted(() => {
256
- editor.value = new Editor(options);
257
- });
258
- onBeforeUnmount(() => {
259
- var _a, _b, _c;
260
- // Cloning root node (and its children) to avoid content being lost by destroy
261
- const nodes = (_a = editor.value) === null || _a === void 0 ? void 0 : _a.options.element;
262
- const newEl = nodes === null || nodes === void 0 ? void 0 : nodes.cloneNode(true);
263
- (_b = nodes === null || nodes === void 0 ? void 0 : nodes.parentNode) === null || _b === void 0 ? void 0 : _b.replaceChild(newEl, nodes);
264
- (_c = editor.value) === null || _c === void 0 ? void 0 : _c.destroy();
265
- });
266
- return editor;
172
+ // src/useEditor.ts
173
+ import { onBeforeUnmount as onBeforeUnmount2, onMounted, shallowRef } from "vue";
174
+ var useEditor = (options = {}) => {
175
+ const editor = shallowRef();
176
+ onMounted(() => {
177
+ editor.value = new Editor(options);
178
+ });
179
+ onBeforeUnmount2(() => {
180
+ var _a, _b, _c;
181
+ const nodes = (_a = editor.value) == null ? void 0 : _a.options.element;
182
+ const newEl = nodes == null ? void 0 : nodes.cloneNode(true);
183
+ (_b = nodes == null ? void 0 : nodes.parentNode) == null ? void 0 : _b.replaceChild(newEl, nodes);
184
+ (_c = editor.value) == null ? void 0 : _c.destroy();
185
+ });
186
+ return editor;
267
187
  };
268
188
 
269
- /**
270
- * This class is used to render Vue components inside the editor.
271
- */
272
- class VueRenderer {
273
- constructor(component, { props = {}, editor }) {
274
- this.editor = editor;
275
- this.component = markRaw(component);
276
- this.el = document.createElement('div');
277
- this.props = reactive(props);
278
- this.renderedComponent = this.renderComponent();
189
+ // src/VueMarkViewRenderer.ts
190
+ import { MarkView } from "@tiptap/core";
191
+ import { defineComponent as defineComponent4, h as h5 } from "vue";
192
+
193
+ // src/VueRenderer.ts
194
+ import { h as h4, markRaw as markRaw2, reactive, render } from "vue";
195
+ var VueRenderer = class {
196
+ constructor(component, { props = {}, editor }) {
197
+ this.editor = editor;
198
+ this.component = markRaw2(component);
199
+ this.el = document.createElement("div");
200
+ this.props = reactive(props);
201
+ this.renderedComponent = this.renderComponent();
202
+ }
203
+ get element() {
204
+ return this.renderedComponent.el;
205
+ }
206
+ get ref() {
207
+ var _a, _b, _c, _d;
208
+ if ((_b = (_a = this.renderedComponent.vNode) == null ? void 0 : _a.component) == null ? void 0 : _b.exposed) {
209
+ return this.renderedComponent.vNode.component.exposed;
279
210
  }
280
- get element() {
281
- return this.renderedComponent.el;
211
+ return (_d = (_c = this.renderedComponent.vNode) == null ? void 0 : _c.component) == null ? void 0 : _d.proxy;
212
+ }
213
+ renderComponent() {
214
+ let vNode = h4(this.component, this.props);
215
+ if (this.editor.appContext) {
216
+ vNode.appContext = this.editor.appContext;
282
217
  }
283
- get ref() {
284
- var _a, _b, _c, _d;
285
- // Composition API
286
- if ((_b = (_a = this.renderedComponent.vNode) === null || _a === void 0 ? void 0 : _a.component) === null || _b === void 0 ? void 0 : _b.exposed) {
287
- return this.renderedComponent.vNode.component.exposed;
288
- }
289
- // Option API
290
- return (_d = (_c = this.renderedComponent.vNode) === null || _c === void 0 ? void 0 : _c.component) === null || _d === void 0 ? void 0 : _d.proxy;
218
+ if (typeof document !== "undefined" && this.el) {
219
+ render(vNode, this.el);
291
220
  }
292
- renderComponent() {
293
- let vNode = h(this.component, this.props);
294
- if (this.editor.appContext) {
295
- vNode.appContext = this.editor.appContext;
296
- }
297
- if (typeof document !== 'undefined' && this.el) {
298
- render(vNode, this.el);
299
- }
300
- const destroy = () => {
301
- if (this.el) {
302
- render(null, this.el);
303
- }
304
- this.el = null;
305
- vNode = null;
306
- };
307
- return { vNode, destroy, el: this.el ? this.el.firstElementChild : null };
221
+ const destroy = () => {
222
+ if (this.el) {
223
+ render(null, this.el);
224
+ }
225
+ this.el = null;
226
+ vNode = null;
227
+ };
228
+ return { vNode, destroy, el: this.el ? this.el.firstElementChild : null };
229
+ }
230
+ updateProps(props = {}) {
231
+ Object.entries(props).forEach(([key, value]) => {
232
+ this.props[key] = value;
233
+ });
234
+ this.renderComponent();
235
+ }
236
+ destroy() {
237
+ this.renderedComponent.destroy();
238
+ }
239
+ };
240
+
241
+ // src/VueMarkViewRenderer.ts
242
+ var markViewProps = {
243
+ editor: {
244
+ type: Object,
245
+ required: true
246
+ },
247
+ mark: {
248
+ type: Object,
249
+ required: true
250
+ },
251
+ extension: {
252
+ type: Object,
253
+ required: true
254
+ },
255
+ inline: {
256
+ type: Boolean,
257
+ required: true
258
+ },
259
+ view: {
260
+ type: Object,
261
+ required: true
262
+ }
263
+ };
264
+ var MarkViewContent = defineComponent4({
265
+ name: "MarkViewContent",
266
+ props: {
267
+ as: {
268
+ type: String,
269
+ default: "span"
308
270
  }
309
- updateProps(props = {}) {
310
- Object.entries(props).forEach(([key, value]) => {
311
- this.props[key] = value;
271
+ },
272
+ render() {
273
+ return h5(this.as, {
274
+ style: {
275
+ whiteSpace: "inherit"
276
+ },
277
+ "data-mark-view-content": ""
278
+ });
279
+ }
280
+ });
281
+ var VueMarkView = class extends MarkView {
282
+ constructor(component, props, options) {
283
+ super(component, props, options);
284
+ const extendedComponent = defineComponent4({
285
+ extends: { ...component },
286
+ props: Object.keys(props),
287
+ template: this.component.template,
288
+ setup: (reactiveProps) => {
289
+ var _a;
290
+ return (_a = component.setup) == null ? void 0 : _a.call(component, reactiveProps, {
291
+ expose: () => void 0
312
292
  });
313
- this.renderComponent();
314
- }
315
- destroy() {
316
- this.renderedComponent.destroy();
293
+ },
294
+ // Add support for scoped styles
295
+ __scopeId: component.__scopeId,
296
+ __cssModules: component.__cssModules,
297
+ __name: component.__name,
298
+ __file: component.__file
299
+ });
300
+ this.renderer = new VueRenderer(extendedComponent, {
301
+ editor: this.editor,
302
+ props
303
+ });
304
+ }
305
+ get dom() {
306
+ return this.renderer.element;
307
+ }
308
+ get contentDOM() {
309
+ return this.dom.querySelector("[data-mark-view-content]");
310
+ }
311
+ destroy() {
312
+ this.renderer.destroy();
313
+ }
314
+ };
315
+ function VueMarkViewRenderer(component, options = {}) {
316
+ return (props) => {
317
+ if (!props.editor.contentComponent) {
318
+ return {};
317
319
  }
320
+ return new VueMarkView(component, props, options);
321
+ };
318
322
  }
319
323
 
320
- /* eslint-disable no-underscore-dangle */
321
- const nodeViewProps = {
322
- editor: {
323
- type: Object,
324
- required: true,
325
- },
326
- node: {
327
- type: Object,
328
- required: true,
329
- },
330
- decorations: {
331
- type: Object,
332
- required: true,
333
- },
334
- selected: {
335
- type: Boolean,
336
- required: true,
337
- },
338
- extension: {
339
- type: Object,
340
- required: true,
341
- },
342
- getPos: {
343
- type: Function,
344
- required: true,
345
- },
346
- updateAttributes: {
347
- type: Function,
348
- required: true,
349
- },
350
- deleteNode: {
351
- type: Function,
352
- required: true,
353
- },
354
- view: {
355
- type: Object,
356
- required: true,
357
- },
358
- innerDecorations: {
359
- type: Object,
360
- required: true,
361
- },
362
- HTMLAttributes: {
363
- type: Object,
364
- required: true,
365
- },
324
+ // src/VueNodeViewRenderer.ts
325
+ import { NodeView } from "@tiptap/core";
326
+ import { defineComponent as defineComponent5, provide, ref as ref2 } from "vue";
327
+ var nodeViewProps = {
328
+ editor: {
329
+ type: Object,
330
+ required: true
331
+ },
332
+ node: {
333
+ type: Object,
334
+ required: true
335
+ },
336
+ decorations: {
337
+ type: Object,
338
+ required: true
339
+ },
340
+ selected: {
341
+ type: Boolean,
342
+ required: true
343
+ },
344
+ extension: {
345
+ type: Object,
346
+ required: true
347
+ },
348
+ getPos: {
349
+ type: Function,
350
+ required: true
351
+ },
352
+ updateAttributes: {
353
+ type: Function,
354
+ required: true
355
+ },
356
+ deleteNode: {
357
+ type: Function,
358
+ required: true
359
+ },
360
+ view: {
361
+ type: Object,
362
+ required: true
363
+ },
364
+ innerDecorations: {
365
+ type: Object,
366
+ required: true
367
+ },
368
+ HTMLAttributes: {
369
+ type: Object,
370
+ required: true
371
+ }
366
372
  };
367
- class VueNodeView extends NodeView {
368
- mount() {
369
- const props = {
370
- editor: this.editor,
371
- node: this.node,
372
- decorations: this.decorations,
373
- innerDecorations: this.innerDecorations,
374
- view: this.view,
375
- selected: false,
376
- extension: this.extension,
377
- HTMLAttributes: this.HTMLAttributes,
378
- getPos: () => this.getPos(),
379
- updateAttributes: (attributes = {}) => this.updateAttributes(attributes),
380
- deleteNode: () => this.deleteNode(),
381
- };
382
- const onDragStart = this.onDragStart.bind(this);
383
- this.decorationClasses = ref(this.getDecorationClasses());
384
- const extendedComponent = defineComponent({
385
- extends: { ...this.component },
386
- props: Object.keys(props),
387
- template: this.component.template,
388
- setup: reactiveProps => {
389
- var _a, _b;
390
- provide('onDragStart', onDragStart);
391
- provide('decorationClasses', this.decorationClasses);
392
- return (_b = (_a = this.component).setup) === null || _b === void 0 ? void 0 : _b.call(_a, reactiveProps, {
393
- expose: () => undefined,
394
- });
395
- },
396
- // add support for scoped styles
397
- // @ts-ignore
398
- // eslint-disable-next-line
399
- __scopeId: this.component.__scopeId,
400
- // add support for CSS Modules
401
- // @ts-ignore
402
- // eslint-disable-next-line
403
- __cssModules: this.component.__cssModules,
404
- // add support for vue devtools
405
- // @ts-ignore
406
- // eslint-disable-next-line
407
- __name: this.component.__name,
408
- // @ts-ignore
409
- // eslint-disable-next-line
410
- __file: this.component.__file,
411
- });
412
- this.handleSelectionUpdate = this.handleSelectionUpdate.bind(this);
413
- this.editor.on('selectionUpdate', this.handleSelectionUpdate);
414
- this.renderer = new VueRenderer(extendedComponent, {
415
- editor: this.editor,
416
- props,
373
+ var VueNodeView = class extends NodeView {
374
+ mount() {
375
+ const props = {
376
+ editor: this.editor,
377
+ node: this.node,
378
+ decorations: this.decorations,
379
+ innerDecorations: this.innerDecorations,
380
+ view: this.view,
381
+ selected: false,
382
+ extension: this.extension,
383
+ HTMLAttributes: this.HTMLAttributes,
384
+ getPos: () => this.getPos(),
385
+ updateAttributes: (attributes = {}) => this.updateAttributes(attributes),
386
+ deleteNode: () => this.deleteNode()
387
+ };
388
+ const onDragStart = this.onDragStart.bind(this);
389
+ this.decorationClasses = ref2(this.getDecorationClasses());
390
+ const extendedComponent = defineComponent5({
391
+ extends: { ...this.component },
392
+ props: Object.keys(props),
393
+ template: this.component.template,
394
+ setup: (reactiveProps) => {
395
+ var _a, _b;
396
+ provide("onDragStart", onDragStart);
397
+ provide("decorationClasses", this.decorationClasses);
398
+ return (_b = (_a = this.component).setup) == null ? void 0 : _b.call(_a, reactiveProps, {
399
+ expose: () => void 0
417
400
  });
401
+ },
402
+ // add support for scoped styles
403
+ // @ts-ignore
404
+ // eslint-disable-next-line
405
+ __scopeId: this.component.__scopeId,
406
+ // add support for CSS Modules
407
+ // @ts-ignore
408
+ // eslint-disable-next-line
409
+ __cssModules: this.component.__cssModules,
410
+ // add support for vue devtools
411
+ // @ts-ignore
412
+ // eslint-disable-next-line
413
+ __name: this.component.__name,
414
+ // @ts-ignore
415
+ // eslint-disable-next-line
416
+ __file: this.component.__file
417
+ });
418
+ this.handleSelectionUpdate = this.handleSelectionUpdate.bind(this);
419
+ this.editor.on("selectionUpdate", this.handleSelectionUpdate);
420
+ this.renderer = new VueRenderer(extendedComponent, {
421
+ editor: this.editor,
422
+ props
423
+ });
424
+ }
425
+ /**
426
+ * Return the DOM element.
427
+ * This is the element that will be used to display the node view.
428
+ */
429
+ get dom() {
430
+ if (!this.renderer.element || !this.renderer.element.hasAttribute("data-node-view-wrapper")) {
431
+ throw Error("Please use the NodeViewWrapper component for your node view.");
418
432
  }
419
- /**
420
- * Return the DOM element.
421
- * This is the element that will be used to display the node view.
422
- */
423
- get dom() {
424
- if (!this.renderer.element || !this.renderer.element.hasAttribute('data-node-view-wrapper')) {
425
- throw Error('Please use the NodeViewWrapper component for your node view.');
426
- }
427
- return this.renderer.element;
433
+ return this.renderer.element;
434
+ }
435
+ /**
436
+ * Return the content DOM element.
437
+ * This is the element that will be used to display the rich-text content of the node.
438
+ */
439
+ get contentDOM() {
440
+ if (this.node.isLeaf) {
441
+ return null;
428
442
  }
429
- /**
430
- * Return the content DOM element.
431
- * This is the element that will be used to display the rich-text content of the node.
432
- */
433
- get contentDOM() {
434
- if (this.node.isLeaf) {
435
- return null;
436
- }
437
- return this.dom.querySelector('[data-node-view-content]');
443
+ return this.dom.querySelector("[data-node-view-content]");
444
+ }
445
+ /**
446
+ * On editor selection update, check if the node is selected.
447
+ * If it is, call `selectNode`, otherwise call `deselectNode`.
448
+ */
449
+ handleSelectionUpdate() {
450
+ const { from, to } = this.editor.state.selection;
451
+ const pos = this.getPos();
452
+ if (typeof pos !== "number") {
453
+ return;
438
454
  }
439
- /**
440
- * On editor selection update, check if the node is selected.
441
- * If it is, call `selectNode`, otherwise call `deselectNode`.
442
- */
443
- handleSelectionUpdate() {
444
- const { from, to } = this.editor.state.selection;
445
- const pos = this.getPos();
446
- if (typeof pos !== 'number') {
447
- return;
448
- }
449
- if (from <= pos && to >= pos + this.node.nodeSize) {
450
- if (this.renderer.props.selected) {
451
- return;
452
- }
453
- this.selectNode();
454
- }
455
- else {
456
- if (!this.renderer.props.selected) {
457
- return;
458
- }
459
- this.deselectNode();
460
- }
455
+ if (from <= pos && to >= pos + this.node.nodeSize) {
456
+ if (this.renderer.props.selected) {
457
+ return;
458
+ }
459
+ this.selectNode();
460
+ } else {
461
+ if (!this.renderer.props.selected) {
462
+ return;
463
+ }
464
+ this.deselectNode();
461
465
  }
462
- /**
463
- * On update, update the React component.
464
- * To prevent unnecessary updates, the `update` option can be used.
465
- */
466
- update(node, decorations, innerDecorations) {
467
- const rerenderComponent = (props) => {
468
- this.decorationClasses.value = this.getDecorationClasses();
469
- this.renderer.updateProps(props);
470
- };
471
- if (typeof this.options.update === 'function') {
472
- const oldNode = this.node;
473
- const oldDecorations = this.decorations;
474
- const oldInnerDecorations = this.innerDecorations;
475
- this.node = node;
476
- this.decorations = decorations;
477
- this.innerDecorations = innerDecorations;
478
- return this.options.update({
479
- oldNode,
480
- oldDecorations,
481
- newNode: node,
482
- newDecorations: decorations,
483
- oldInnerDecorations,
484
- innerDecorations,
485
- updateProps: () => rerenderComponent({ node, decorations, innerDecorations }),
486
- });
487
- }
488
- if (node.type !== this.node.type) {
489
- return false;
490
- }
491
- if (node === this.node && this.decorations === decorations && this.innerDecorations === innerDecorations) {
492
- return true;
493
- }
494
- this.node = node;
495
- this.decorations = decorations;
496
- this.innerDecorations = innerDecorations;
497
- rerenderComponent({ node, decorations, innerDecorations });
498
- return true;
466
+ }
467
+ /**
468
+ * On update, update the React component.
469
+ * To prevent unnecessary updates, the `update` option can be used.
470
+ */
471
+ update(node, decorations, innerDecorations) {
472
+ const rerenderComponent = (props) => {
473
+ this.decorationClasses.value = this.getDecorationClasses();
474
+ this.renderer.updateProps(props);
475
+ };
476
+ if (typeof this.options.update === "function") {
477
+ const oldNode = this.node;
478
+ const oldDecorations = this.decorations;
479
+ const oldInnerDecorations = this.innerDecorations;
480
+ this.node = node;
481
+ this.decorations = decorations;
482
+ this.innerDecorations = innerDecorations;
483
+ return this.options.update({
484
+ oldNode,
485
+ oldDecorations,
486
+ newNode: node,
487
+ newDecorations: decorations,
488
+ oldInnerDecorations,
489
+ innerDecorations,
490
+ updateProps: () => rerenderComponent({ node, decorations, innerDecorations })
491
+ });
499
492
  }
500
- /**
501
- * Select the node.
502
- * Add the `selected` prop and the `ProseMirror-selectednode` class.
503
- */
504
- selectNode() {
505
- this.renderer.updateProps({
506
- selected: true,
507
- });
508
- if (this.renderer.element) {
509
- this.renderer.element.classList.add('ProseMirror-selectednode');
510
- }
493
+ if (node.type !== this.node.type) {
494
+ return false;
511
495
  }
512
- /**
513
- * Deselect the node.
514
- * Remove the `selected` prop and the `ProseMirror-selectednode` class.
515
- */
516
- deselectNode() {
517
- this.renderer.updateProps({
518
- selected: false,
519
- });
520
- if (this.renderer.element) {
521
- this.renderer.element.classList.remove('ProseMirror-selectednode');
522
- }
496
+ if (node === this.node && this.decorations === decorations && this.innerDecorations === innerDecorations) {
497
+ return true;
523
498
  }
524
- getDecorationClasses() {
525
- return (this.decorations
526
- // @ts-ignore
527
- .map(item => item.type.attrs.class)
528
- .flat()
529
- .join(' '));
499
+ this.node = node;
500
+ this.decorations = decorations;
501
+ this.innerDecorations = innerDecorations;
502
+ rerenderComponent({ node, decorations, innerDecorations });
503
+ return true;
504
+ }
505
+ /**
506
+ * Select the node.
507
+ * Add the `selected` prop and the `ProseMirror-selectednode` class.
508
+ */
509
+ selectNode() {
510
+ this.renderer.updateProps({
511
+ selected: true
512
+ });
513
+ if (this.renderer.element) {
514
+ this.renderer.element.classList.add("ProseMirror-selectednode");
530
515
  }
531
- destroy() {
532
- this.renderer.destroy();
533
- this.editor.off('selectionUpdate', this.handleSelectionUpdate);
516
+ }
517
+ /**
518
+ * Deselect the node.
519
+ * Remove the `selected` prop and the `ProseMirror-selectednode` class.
520
+ */
521
+ deselectNode() {
522
+ this.renderer.updateProps({
523
+ selected: false
524
+ });
525
+ if (this.renderer.element) {
526
+ this.renderer.element.classList.remove("ProseMirror-selectednode");
534
527
  }
535
- }
528
+ }
529
+ getDecorationClasses() {
530
+ return this.decorations.map((item) => item.type.attrs.class).flat().join(" ");
531
+ }
532
+ destroy() {
533
+ this.renderer.destroy();
534
+ this.editor.off("selectionUpdate", this.handleSelectionUpdate);
535
+ }
536
+ };
536
537
  function VueNodeViewRenderer(component, options) {
537
- return props => {
538
- // try to get the parent component
539
- // this is important for vue devtools to show the component hierarchy correctly
540
- // maybe it’s `undefined` because <editor-content> isn’t rendered yet
541
- if (!props.editor.contentComponent) {
542
- return {};
543
- }
544
- // check for class-component and normalize if neccessary
545
- const normalizedComponent = typeof component === 'function' && '__vccOpts' in component
546
- ? component.__vccOpts
547
- : component;
548
- return new VueNodeView(normalizedComponent, props, options);
549
- };
538
+ return (props) => {
539
+ if (!props.editor.contentComponent) {
540
+ return {};
541
+ }
542
+ const normalizedComponent = typeof component === "function" && "__vccOpts" in component ? component.__vccOpts : component;
543
+ return new VueNodeView(normalizedComponent, props, options);
544
+ };
550
545
  }
551
546
 
552
- export { BubbleMenu, Editor, EditorContent, FloatingMenu, NodeViewContent, NodeViewWrapper, VueNodeViewRenderer, VueRenderer, nodeViewProps, useEditor };
553
- //# sourceMappingURL=index.js.map
547
+ // src/index.ts
548
+ export * from "@tiptap/core";
549
+ export {
550
+ Editor,
551
+ EditorContent,
552
+ MarkViewContent,
553
+ NodeViewContent,
554
+ NodeViewWrapper,
555
+ VueMarkView,
556
+ VueMarkViewRenderer,
557
+ VueNodeViewRenderer,
558
+ VueRenderer,
559
+ markViewProps,
560
+ nodeViewProps,
561
+ useEditor
562
+ };
563
+ //# sourceMappingURL=index.js.map