@tiptap/vue-3 2.11.7 → 3.0.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +21 -0
- package/README.md +5 -1
- package/dist/index.cjs +562 -528
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +219 -0
- package/dist/index.d.ts +218 -10
- package/dist/index.js +526 -516
- package/dist/index.js.map +1 -1
- package/dist/menus/index.cjs +587 -0
- package/dist/menus/index.cjs.map +1 -0
- package/dist/menus/index.d.cts +257 -0
- package/dist/menus/index.d.ts +257 -0
- package/dist/menus/index.js +579 -0
- package/dist/menus/index.js.map +1 -0
- package/package.json +27 -16
- package/src/Editor.ts +6 -11
- package/src/EditorContent.ts +10 -20
- package/src/VueMarkViewRenderer.ts +114 -0
- package/src/VueNodeViewRenderer.ts +19 -30
- package/src/VueRenderer.ts +10 -11
- package/src/index.ts +1 -2
- package/src/menus/BubbleMenu.ts +78 -0
- package/src/menus/FloatingMenu.ts +68 -0
- package/src/menus/index.ts +2 -0
- package/src/useEditor.ts +1 -1
- package/dist/BubbleMenu.d.ts +0 -61
- package/dist/BubbleMenu.d.ts.map +0 -1
- package/dist/Editor.d.ts +0 -24
- package/dist/Editor.d.ts.map +0 -1
- package/dist/EditorContent.d.ts +0 -18
- package/dist/EditorContent.d.ts.map +0 -1
- package/dist/FloatingMenu.d.ts +0 -49
- package/dist/FloatingMenu.d.ts.map +0 -1
- package/dist/NodeViewContent.d.ts +0 -14
- package/dist/NodeViewContent.d.ts.map +0 -1
- package/dist/NodeViewWrapper.d.ts +0 -14
- package/dist/NodeViewWrapper.d.ts.map +0 -1
- package/dist/VueNodeViewRenderer.d.ts +0 -63
- package/dist/VueNodeViewRenderer.d.ts.map +0 -1
- package/dist/VueRenderer.d.ts +0 -37
- package/dist/VueRenderer.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.umd.js +0 -570
- package/dist/index.umd.js.map +0 -1
- package/dist/useEditor.d.ts +0 -4
- package/dist/useEditor.d.ts.map +0 -1
- package/src/BubbleMenu.ts +0 -71
- package/src/FloatingMenu.ts +0 -66
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tiptap/vue-3",
|
|
3
3
|
"description": "Vue components for tiptap",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "3.0.0-beta.0",
|
|
5
5
|
"homepage": "https://tiptap.dev",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"tiptap",
|
|
@@ -14,33 +14,44 @@
|
|
|
14
14
|
},
|
|
15
15
|
"exports": {
|
|
16
16
|
".": {
|
|
17
|
-
"types":
|
|
17
|
+
"types": {
|
|
18
|
+
"import": "./dist/index.d.ts",
|
|
19
|
+
"require": "./dist/index.d.cts"
|
|
20
|
+
},
|
|
18
21
|
"import": "./dist/index.js",
|
|
19
22
|
"require": "./dist/index.cjs"
|
|
23
|
+
},
|
|
24
|
+
"./menus": {
|
|
25
|
+
"types": {
|
|
26
|
+
"import": "./dist/menus/index.d.ts",
|
|
27
|
+
"require": "./dist/menus/index.d.cts"
|
|
28
|
+
},
|
|
29
|
+
"import": "./dist/menus/index.js",
|
|
30
|
+
"require": "./dist/menus/index.cjs"
|
|
20
31
|
}
|
|
21
32
|
},
|
|
22
33
|
"main": "dist/index.cjs",
|
|
23
34
|
"module": "dist/index.js",
|
|
24
|
-
"umd": "dist/index.umd.js",
|
|
25
35
|
"types": "dist/index.d.ts",
|
|
26
36
|
"type": "module",
|
|
27
37
|
"files": [
|
|
28
38
|
"src",
|
|
29
39
|
"dist"
|
|
30
40
|
],
|
|
31
|
-
"dependencies": {
|
|
32
|
-
"@tiptap/extension-bubble-menu": "^2.11.7",
|
|
33
|
-
"@tiptap/extension-floating-menu": "^2.11.7"
|
|
34
|
-
},
|
|
35
41
|
"devDependencies": {
|
|
36
|
-
"@tiptap/core": "^
|
|
37
|
-
"@tiptap/pm": "^
|
|
38
|
-
"vue": "^3.
|
|
42
|
+
"@tiptap/core": "^3.0.0-beta.0",
|
|
43
|
+
"@tiptap/pm": "^3.0.0-beta.0",
|
|
44
|
+
"vue": "^3.5.13"
|
|
45
|
+
},
|
|
46
|
+
"optionalDependencies": {
|
|
47
|
+
"@tiptap/extension-bubble-menu": "^3.0.0-beta.0",
|
|
48
|
+
"@tiptap/extension-floating-menu": "^3.0.0-beta.0"
|
|
39
49
|
},
|
|
40
50
|
"peerDependencies": {
|
|
41
|
-
"@tiptap/core": "^
|
|
42
|
-
"@tiptap/pm": "^
|
|
43
|
-
"vue": "^3.0.0"
|
|
51
|
+
"@tiptap/core": "^3.0.0-beta.0",
|
|
52
|
+
"@tiptap/pm": "^3.0.0-beta.0",
|
|
53
|
+
"vue": "^3.0.0",
|
|
54
|
+
"@floating-ui/dom": "^1.0.0"
|
|
44
55
|
},
|
|
45
56
|
"repository": {
|
|
46
57
|
"type": "git",
|
|
@@ -49,7 +60,7 @@
|
|
|
49
60
|
},
|
|
50
61
|
"sideEffects": false,
|
|
51
62
|
"scripts": {
|
|
52
|
-
"
|
|
53
|
-
"
|
|
63
|
+
"build": "tsup",
|
|
64
|
+
"lint": "prettier ./src/ --check && eslint --cache --quiet --no-error-on-unmatched-pattern ./src/"
|
|
54
65
|
}
|
|
55
|
-
}
|
|
66
|
+
}
|
package/src/Editor.ts
CHANGED
|
@@ -1,14 +1,9 @@
|
|
|
1
1
|
/* eslint-disable react-hooks/rules-of-hooks */
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
ComponentPublicInstance,
|
|
8
|
-
customRef,
|
|
9
|
-
markRaw,
|
|
10
|
-
Ref,
|
|
11
|
-
} from 'vue'
|
|
2
|
+
import type { EditorOptions, Storage } from '@tiptap/core'
|
|
3
|
+
import { Editor as CoreEditor } from '@tiptap/core'
|
|
4
|
+
import type { EditorState, Plugin, PluginKey } from '@tiptap/pm/state'
|
|
5
|
+
import type { AppContext, ComponentInternalInstance, ComponentPublicInstance, Ref } from 'vue'
|
|
6
|
+
import { customRef, markRaw } from 'vue'
|
|
12
7
|
|
|
13
8
|
function useDebouncedRef<T>(value: T) {
|
|
14
9
|
return customRef<T>((track, trigger) => {
|
|
@@ -39,7 +34,7 @@ export type ContentComponent = ComponentInternalInstance & {
|
|
|
39
34
|
export class Editor extends CoreEditor {
|
|
40
35
|
private reactiveState: Ref<EditorState>
|
|
41
36
|
|
|
42
|
-
private reactiveExtensionStorage: Ref<
|
|
37
|
+
private reactiveExtensionStorage: Ref<Storage>
|
|
43
38
|
|
|
44
39
|
public contentComponent: ContentComponent | null = null
|
|
45
40
|
|
package/src/EditorContent.ts
CHANGED
|
@@ -1,17 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
nextTick,
|
|
6
|
-
onBeforeUnmount,
|
|
7
|
-
PropType,
|
|
8
|
-
Ref,
|
|
9
|
-
ref,
|
|
10
|
-
unref,
|
|
11
|
-
watchEffect,
|
|
12
|
-
} from 'vue'
|
|
13
|
-
|
|
14
|
-
import { Editor } from './Editor.js'
|
|
1
|
+
import type { PropType, Ref } from 'vue'
|
|
2
|
+
import { defineComponent, getCurrentInstance, h, nextTick, onBeforeUnmount, ref, unref, watchEffect } from 'vue'
|
|
3
|
+
|
|
4
|
+
import type { Editor } from './Editor.js'
|
|
15
5
|
|
|
16
6
|
export const EditorContent = defineComponent({
|
|
17
7
|
name: 'EditorContent',
|
|
@@ -32,10 +22,11 @@ export const EditorContent = defineComponent({
|
|
|
32
22
|
|
|
33
23
|
if (editor && editor.options.element && rootEl.value) {
|
|
34
24
|
nextTick(() => {
|
|
35
|
-
if (!rootEl.value || !editor.options.element
|
|
25
|
+
if (!rootEl.value || !editor.options.element?.firstChild) {
|
|
36
26
|
return
|
|
37
27
|
}
|
|
38
28
|
|
|
29
|
+
// TODO using the new editor.mount method might allow us to remove this
|
|
39
30
|
const element = unref(rootEl.value)
|
|
40
31
|
|
|
41
32
|
rootEl.value.append(...editor.options.element.childNodes)
|
|
@@ -77,11 +68,10 @@ export const EditorContent = defineComponent({
|
|
|
77
68
|
},
|
|
78
69
|
|
|
79
70
|
render() {
|
|
80
|
-
return h(
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
ref: (el: any) => { this.rootEl = el },
|
|
71
|
+
return h('div', {
|
|
72
|
+
ref: (el: any) => {
|
|
73
|
+
this.rootEl = el
|
|
84
74
|
},
|
|
85
|
-
)
|
|
75
|
+
})
|
|
86
76
|
},
|
|
87
77
|
})
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/* eslint-disable no-underscore-dangle */
|
|
2
|
+
import type { MarkViewProps, MarkViewRenderer, MarkViewRendererOptions } from '@tiptap/core'
|
|
3
|
+
import { MarkView } from '@tiptap/core'
|
|
4
|
+
import type { Component, PropType } from 'vue'
|
|
5
|
+
import { defineComponent, h } from 'vue'
|
|
6
|
+
|
|
7
|
+
import type { Editor } from './Editor.js'
|
|
8
|
+
import { VueRenderer } from './VueRenderer.js'
|
|
9
|
+
|
|
10
|
+
export interface VueMarkViewRendererOptions extends MarkViewRendererOptions {
|
|
11
|
+
as?: string
|
|
12
|
+
className?: string
|
|
13
|
+
attrs?: { [key: string]: string }
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const markViewProps = {
|
|
17
|
+
editor: {
|
|
18
|
+
type: Object as PropType<MarkViewProps['editor']>,
|
|
19
|
+
required: true as const,
|
|
20
|
+
},
|
|
21
|
+
mark: {
|
|
22
|
+
type: Object as PropType<MarkViewProps['mark']>,
|
|
23
|
+
required: true as const,
|
|
24
|
+
},
|
|
25
|
+
extension: {
|
|
26
|
+
type: Object as PropType<MarkViewProps['extension']>,
|
|
27
|
+
required: true as const,
|
|
28
|
+
},
|
|
29
|
+
inline: {
|
|
30
|
+
type: Boolean as PropType<MarkViewProps['inline']>,
|
|
31
|
+
required: true as const,
|
|
32
|
+
},
|
|
33
|
+
view: {
|
|
34
|
+
type: Object as PropType<MarkViewProps['view']>,
|
|
35
|
+
required: true as const,
|
|
36
|
+
},
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export const MarkViewContent = defineComponent({
|
|
40
|
+
name: 'MarkViewContent',
|
|
41
|
+
|
|
42
|
+
props: {
|
|
43
|
+
as: {
|
|
44
|
+
type: String,
|
|
45
|
+
default: 'span',
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
render() {
|
|
50
|
+
return h(this.as, {
|
|
51
|
+
style: {
|
|
52
|
+
whiteSpace: 'inherit',
|
|
53
|
+
},
|
|
54
|
+
'data-mark-view-content': '',
|
|
55
|
+
})
|
|
56
|
+
},
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
export class VueMarkView extends MarkView<Component, VueMarkViewRendererOptions> {
|
|
60
|
+
renderer: VueRenderer
|
|
61
|
+
|
|
62
|
+
constructor(component: Component, props: MarkViewProps, options?: Partial<VueMarkViewRendererOptions>) {
|
|
63
|
+
super(component, props, options)
|
|
64
|
+
|
|
65
|
+
// Create extended component with provide
|
|
66
|
+
const extendedComponent = defineComponent({
|
|
67
|
+
extends: { ...component },
|
|
68
|
+
props: Object.keys(props),
|
|
69
|
+
template: (this.component as any).template,
|
|
70
|
+
setup: reactiveProps => {
|
|
71
|
+
return (component as any).setup?.(reactiveProps, {
|
|
72
|
+
expose: () => undefined,
|
|
73
|
+
})
|
|
74
|
+
},
|
|
75
|
+
// Add support for scoped styles
|
|
76
|
+
__scopeId: (component as any).__scopeId,
|
|
77
|
+
__cssModules: (component as any).__cssModules,
|
|
78
|
+
__name: (component as any).__name,
|
|
79
|
+
__file: (component as any).__file,
|
|
80
|
+
})
|
|
81
|
+
this.renderer = new VueRenderer(extendedComponent, {
|
|
82
|
+
editor: this.editor,
|
|
83
|
+
props,
|
|
84
|
+
})
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
get dom() {
|
|
88
|
+
return this.renderer.element as HTMLElement
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
get contentDOM() {
|
|
92
|
+
return this.dom.querySelector('[data-mark-view-content]') as HTMLElement | null
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
destroy() {
|
|
96
|
+
this.renderer.destroy()
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export function VueMarkViewRenderer(
|
|
101
|
+
component: Component,
|
|
102
|
+
options: Partial<VueMarkViewRendererOptions> = {},
|
|
103
|
+
): MarkViewRenderer {
|
|
104
|
+
return props => {
|
|
105
|
+
// try to get the parent component
|
|
106
|
+
// this is important for vue devtools to show the component hierarchy correctly
|
|
107
|
+
// maybe it’s `undefined` because <editor-content> isn’t rendered yet
|
|
108
|
+
if (!(props.editor as Editor).contentComponent) {
|
|
109
|
+
return {} as unknown as MarkView<any, any>
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return new VueMarkView(component, props, options)
|
|
113
|
+
}
|
|
114
|
+
}
|
|
@@ -1,18 +1,12 @@
|
|
|
1
1
|
/* eslint-disable no-underscore-dangle */
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
import {
|
|
10
|
-
import { Decoration, DecorationSource, NodeView as ProseMirrorNodeView } from '@tiptap/pm/view'
|
|
11
|
-
import {
|
|
12
|
-
Component, defineComponent, PropType, provide, Ref, ref,
|
|
13
|
-
} from 'vue'
|
|
14
|
-
|
|
15
|
-
import { Editor } from './Editor.js'
|
|
2
|
+
import type { DecorationWithType, NodeViewProps, NodeViewRenderer, NodeViewRendererOptions } from '@tiptap/core'
|
|
3
|
+
import { NodeView } from '@tiptap/core'
|
|
4
|
+
import type { Node as ProseMirrorNode } from '@tiptap/pm/model'
|
|
5
|
+
import type { Decoration, DecorationSource, NodeView as ProseMirrorNodeView } from '@tiptap/pm/view'
|
|
6
|
+
import type { Component, PropType, Ref } from 'vue'
|
|
7
|
+
import { defineComponent, provide, ref } from 'vue'
|
|
8
|
+
|
|
9
|
+
import type { Editor } from './Editor.js'
|
|
16
10
|
import { VueRenderer } from './VueRenderer.js'
|
|
17
11
|
|
|
18
12
|
export const nodeViewProps = {
|
|
@@ -65,15 +59,15 @@ export const nodeViewProps = {
|
|
|
65
59
|
export interface VueNodeViewRendererOptions extends NodeViewRendererOptions {
|
|
66
60
|
update:
|
|
67
61
|
| ((props: {
|
|
68
|
-
oldNode: ProseMirrorNode
|
|
69
|
-
oldDecorations: readonly Decoration[]
|
|
70
|
-
oldInnerDecorations: DecorationSource
|
|
71
|
-
newNode: ProseMirrorNode
|
|
72
|
-
newDecorations: readonly Decoration[]
|
|
73
|
-
innerDecorations: DecorationSource
|
|
74
|
-
updateProps: () => void
|
|
62
|
+
oldNode: ProseMirrorNode
|
|
63
|
+
oldDecorations: readonly Decoration[]
|
|
64
|
+
oldInnerDecorations: DecorationSource
|
|
65
|
+
newNode: ProseMirrorNode
|
|
66
|
+
newDecorations: readonly Decoration[]
|
|
67
|
+
innerDecorations: DecorationSource
|
|
68
|
+
updateProps: () => void
|
|
75
69
|
}) => boolean)
|
|
76
|
-
| null
|
|
70
|
+
| null
|
|
77
71
|
}
|
|
78
72
|
|
|
79
73
|
class VueNodeView extends NodeView<Component, Editor, VueNodeViewRendererOptions> {
|
|
@@ -193,11 +187,7 @@ class VueNodeView extends NodeView<Component, Editor, VueNodeViewRendererOptions
|
|
|
193
187
|
* On update, update the React component.
|
|
194
188
|
* To prevent unnecessary updates, the `update` option can be used.
|
|
195
189
|
*/
|
|
196
|
-
update(
|
|
197
|
-
node: ProseMirrorNode,
|
|
198
|
-
decorations: readonly Decoration[],
|
|
199
|
-
innerDecorations: DecorationSource,
|
|
200
|
-
): boolean {
|
|
190
|
+
update(node: ProseMirrorNode, decorations: readonly Decoration[], innerDecorations: DecorationSource): boolean {
|
|
201
191
|
const rerenderComponent = (props?: Record<string, any>) => {
|
|
202
192
|
this.decorationClasses.value = this.getDecorationClasses()
|
|
203
193
|
this.renderer.updateProps(props)
|
|
@@ -294,9 +284,8 @@ export function VueNodeViewRenderer(
|
|
|
294
284
|
return {} as unknown as ProseMirrorNodeView
|
|
295
285
|
}
|
|
296
286
|
// check for class-component and normalize if neccessary
|
|
297
|
-
const normalizedComponent =
|
|
298
|
-
? (component.__vccOpts as Component)
|
|
299
|
-
: component
|
|
287
|
+
const normalizedComponent =
|
|
288
|
+
typeof component === 'function' && '__vccOpts' in component ? (component.__vccOpts as Component) : component
|
|
300
289
|
|
|
301
290
|
return new VueNodeView(normalizedComponent, props, options)
|
|
302
291
|
}
|
package/src/VueRenderer.ts
CHANGED
|
@@ -1,21 +1,20 @@
|
|
|
1
|
-
import { Editor } from '@tiptap/core'
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
} from 'vue'
|
|
1
|
+
import type { Editor } from '@tiptap/core'
|
|
2
|
+
import type { Component, DefineComponent } from 'vue'
|
|
3
|
+
import { h, markRaw, reactive, render } from 'vue'
|
|
5
4
|
|
|
6
|
-
import { Editor as ExtendedEditor } from './Editor.js'
|
|
5
|
+
import type { Editor as ExtendedEditor } from './Editor.js'
|
|
7
6
|
|
|
8
7
|
export interface VueRendererOptions {
|
|
9
|
-
editor: Editor
|
|
10
|
-
props?: Record<string, any
|
|
8
|
+
editor: Editor
|
|
9
|
+
props?: Record<string, any>
|
|
11
10
|
}
|
|
12
11
|
|
|
13
|
-
type ExtendedVNode = ReturnType<typeof h> | null
|
|
12
|
+
type ExtendedVNode = ReturnType<typeof h> | null
|
|
14
13
|
|
|
15
14
|
interface RenderedComponent {
|
|
16
|
-
vNode: ExtendedVNode
|
|
17
|
-
destroy: () => void
|
|
18
|
-
el: Element | null
|
|
15
|
+
vNode: ExtendedVNode
|
|
16
|
+
destroy: () => void
|
|
17
|
+
el: Element | null
|
|
19
18
|
}
|
|
20
19
|
|
|
21
20
|
/**
|
package/src/index.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
export * from './BubbleMenu.js'
|
|
2
1
|
export { Editor } from './Editor.js'
|
|
3
2
|
export * from './EditorContent.js'
|
|
4
|
-
export * from './FloatingMenu.js'
|
|
5
3
|
export * from './NodeViewContent.js'
|
|
6
4
|
export * from './NodeViewWrapper.js'
|
|
7
5
|
export * from './useEditor.js'
|
|
6
|
+
export * from './VueMarkViewRenderer.js'
|
|
8
7
|
export * from './VueNodeViewRenderer.js'
|
|
9
8
|
export * from './VueRenderer.js'
|
|
10
9
|
export * from '@tiptap/core'
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { BubbleMenuPluginProps } from '@tiptap/extension-bubble-menu'
|
|
2
|
+
import { BubbleMenuPlugin } from '@tiptap/extension-bubble-menu'
|
|
3
|
+
import type { PropType } from 'vue'
|
|
4
|
+
import { defineComponent, h, onBeforeUnmount, onMounted, ref, Teleport } from 'vue'
|
|
5
|
+
|
|
6
|
+
export const BubbleMenu = defineComponent({
|
|
7
|
+
name: 'BubbleMenu',
|
|
8
|
+
|
|
9
|
+
props: {
|
|
10
|
+
pluginKey: {
|
|
11
|
+
type: [String, Object] as PropType<BubbleMenuPluginProps['pluginKey']>,
|
|
12
|
+
default: 'bubbleMenu',
|
|
13
|
+
},
|
|
14
|
+
|
|
15
|
+
editor: {
|
|
16
|
+
type: Object as PropType<BubbleMenuPluginProps['editor']>,
|
|
17
|
+
required: true,
|
|
18
|
+
},
|
|
19
|
+
|
|
20
|
+
updateDelay: {
|
|
21
|
+
type: Number as PropType<BubbleMenuPluginProps['updateDelay']>,
|
|
22
|
+
default: undefined,
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
resizeDelay: {
|
|
26
|
+
type: Number as PropType<BubbleMenuPluginProps['resizeDelay']>,
|
|
27
|
+
default: undefined,
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
options: {
|
|
31
|
+
type: Object as PropType<BubbleMenuPluginProps['options']>,
|
|
32
|
+
default: () => ({}),
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
shouldShow: {
|
|
36
|
+
type: Function as PropType<Exclude<Required<BubbleMenuPluginProps>['shouldShow'], null>>,
|
|
37
|
+
default: null,
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
|
|
41
|
+
setup(props, { slots }) {
|
|
42
|
+
const root = ref<HTMLElement | null>(null)
|
|
43
|
+
|
|
44
|
+
onMounted(() => {
|
|
45
|
+
const { editor, options, pluginKey, resizeDelay, shouldShow, updateDelay } = props
|
|
46
|
+
|
|
47
|
+
if (!root.value) {
|
|
48
|
+
return
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
root.value.style.visibility = 'hidden'
|
|
52
|
+
root.value.style.position = 'absolute'
|
|
53
|
+
|
|
54
|
+
// remove the element from the DOM
|
|
55
|
+
root.value.remove()
|
|
56
|
+
|
|
57
|
+
editor.registerPlugin(
|
|
58
|
+
BubbleMenuPlugin({
|
|
59
|
+
editor,
|
|
60
|
+
element: root.value as HTMLElement,
|
|
61
|
+
options,
|
|
62
|
+
pluginKey,
|
|
63
|
+
resizeDelay,
|
|
64
|
+
shouldShow,
|
|
65
|
+
updateDelay,
|
|
66
|
+
}),
|
|
67
|
+
)
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
onBeforeUnmount(() => {
|
|
71
|
+
const { pluginKey, editor } = props
|
|
72
|
+
|
|
73
|
+
editor.unregisterPlugin(pluginKey)
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
return () => h(Teleport, { to: 'body' }, h('div', { ref: root }, slots.default?.()))
|
|
77
|
+
},
|
|
78
|
+
})
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { FloatingMenuPluginProps } from '@tiptap/extension-floating-menu'
|
|
2
|
+
import { FloatingMenuPlugin } from '@tiptap/extension-floating-menu'
|
|
3
|
+
import type { PropType } from 'vue'
|
|
4
|
+
import { defineComponent, h, onBeforeUnmount, onMounted, ref, Teleport } from 'vue'
|
|
5
|
+
|
|
6
|
+
export const FloatingMenu = defineComponent({
|
|
7
|
+
name: 'FloatingMenu',
|
|
8
|
+
|
|
9
|
+
props: {
|
|
10
|
+
pluginKey: {
|
|
11
|
+
// TODO: TypeScript breaks :(
|
|
12
|
+
// type: [String, Object as PropType<Exclude<FloatingMenuPluginProps['pluginKey'], string>>],
|
|
13
|
+
type: null,
|
|
14
|
+
default: 'floatingMenu',
|
|
15
|
+
},
|
|
16
|
+
|
|
17
|
+
editor: {
|
|
18
|
+
type: Object as PropType<FloatingMenuPluginProps['editor']>,
|
|
19
|
+
required: true,
|
|
20
|
+
},
|
|
21
|
+
|
|
22
|
+
options: {
|
|
23
|
+
type: Object as PropType<FloatingMenuPluginProps['options']>,
|
|
24
|
+
default: () => ({}),
|
|
25
|
+
},
|
|
26
|
+
|
|
27
|
+
shouldShow: {
|
|
28
|
+
type: Function as PropType<Exclude<Required<FloatingMenuPluginProps>['shouldShow'], null>>,
|
|
29
|
+
default: null,
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
setup(props, { slots }) {
|
|
34
|
+
const root = ref<HTMLElement | null>(null)
|
|
35
|
+
|
|
36
|
+
onMounted(() => {
|
|
37
|
+
const { pluginKey, editor, options, shouldShow } = props
|
|
38
|
+
|
|
39
|
+
if (!root.value) {
|
|
40
|
+
return
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
root.value.style.visibility = 'hidden'
|
|
44
|
+
root.value.style.position = 'absolute'
|
|
45
|
+
|
|
46
|
+
// remove the element from the DOM
|
|
47
|
+
root.value.remove()
|
|
48
|
+
|
|
49
|
+
editor.registerPlugin(
|
|
50
|
+
FloatingMenuPlugin({
|
|
51
|
+
pluginKey,
|
|
52
|
+
editor,
|
|
53
|
+
element: root.value as HTMLElement,
|
|
54
|
+
options,
|
|
55
|
+
shouldShow,
|
|
56
|
+
}),
|
|
57
|
+
)
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
onBeforeUnmount(() => {
|
|
61
|
+
const { pluginKey, editor } = props
|
|
62
|
+
|
|
63
|
+
editor.unregisterPlugin(pluginKey)
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
return () => h(Teleport, { to: 'body' }, h('div', { ref: root }, slots.default?.()))
|
|
67
|
+
},
|
|
68
|
+
})
|
package/src/useEditor.ts
CHANGED
package/dist/BubbleMenu.d.ts
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { BubbleMenuPluginProps } from '@tiptap/extension-bubble-menu';
|
|
2
|
-
import { PropType } from 'vue';
|
|
3
|
-
export declare const BubbleMenu: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
4
|
-
pluginKey: {
|
|
5
|
-
type: PropType<BubbleMenuPluginProps["pluginKey"]>;
|
|
6
|
-
default: string;
|
|
7
|
-
};
|
|
8
|
-
editor: {
|
|
9
|
-
type: PropType<BubbleMenuPluginProps["editor"]>;
|
|
10
|
-
required: true;
|
|
11
|
-
};
|
|
12
|
-
updateDelay: {
|
|
13
|
-
type: PropType<BubbleMenuPluginProps["updateDelay"]>;
|
|
14
|
-
default: undefined;
|
|
15
|
-
};
|
|
16
|
-
tippyOptions: {
|
|
17
|
-
type: PropType<BubbleMenuPluginProps["tippyOptions"]>;
|
|
18
|
-
default: () => {};
|
|
19
|
-
};
|
|
20
|
-
shouldShow: {
|
|
21
|
-
type: PropType<Exclude<Required<BubbleMenuPluginProps>["shouldShow"], null>>;
|
|
22
|
-
default: null;
|
|
23
|
-
};
|
|
24
|
-
}>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
|
|
25
|
-
[key: string]: any;
|
|
26
|
-
}>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
27
|
-
pluginKey: {
|
|
28
|
-
type: PropType<BubbleMenuPluginProps["pluginKey"]>;
|
|
29
|
-
default: string;
|
|
30
|
-
};
|
|
31
|
-
editor: {
|
|
32
|
-
type: PropType<BubbleMenuPluginProps["editor"]>;
|
|
33
|
-
required: true;
|
|
34
|
-
};
|
|
35
|
-
updateDelay: {
|
|
36
|
-
type: PropType<BubbleMenuPluginProps["updateDelay"]>;
|
|
37
|
-
default: undefined;
|
|
38
|
-
};
|
|
39
|
-
tippyOptions: {
|
|
40
|
-
type: PropType<BubbleMenuPluginProps["tippyOptions"]>;
|
|
41
|
-
default: () => {};
|
|
42
|
-
};
|
|
43
|
-
shouldShow: {
|
|
44
|
-
type: PropType<Exclude<Required<BubbleMenuPluginProps>["shouldShow"], null>>;
|
|
45
|
-
default: null;
|
|
46
|
-
};
|
|
47
|
-
}>> & Readonly<{}>, {
|
|
48
|
-
pluginKey: string | import("prosemirror-state").PluginKey<any>;
|
|
49
|
-
updateDelay: number | undefined;
|
|
50
|
-
tippyOptions: Partial<import("tippy.js").Props> | undefined;
|
|
51
|
-
shouldShow: (props: {
|
|
52
|
-
editor: import("@tiptap/core").Editor;
|
|
53
|
-
element: HTMLElement;
|
|
54
|
-
view: import("prosemirror-view").EditorView;
|
|
55
|
-
state: import("prosemirror-state").EditorState;
|
|
56
|
-
oldState?: import("prosemirror-state").EditorState;
|
|
57
|
-
from: number;
|
|
58
|
-
to: number;
|
|
59
|
-
}) => boolean;
|
|
60
|
-
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
61
|
-
//# sourceMappingURL=BubbleMenu.d.ts.map
|
package/dist/BubbleMenu.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"BubbleMenu.d.ts","sourceRoot":"","sources":["../src/BubbleMenu.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,qBAAqB,EAAE,MAAM,+BAA+B,CAAA;AACvF,OAAO,EAKL,QAAQ,EAET,MAAM,KAAK,CAAA;AAEZ,eAAO,MAAM,UAAU;;cAKS,QAAQ,CAAC,qBAAqB,CAAC,WAAW,CAAC,CAAC;;;;cAKtD,QAAQ,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC;;;;cAKzC,QAAQ,CAAC,qBAAqB,CAAC,aAAa,CAAC,CAAC;;;;cAK9C,QAAQ,CAAC,qBAAqB,CAAC,cAAc,CAAC,CAAC;;;;cAK7C,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAC,CAAC,YAAY,CAAC,EAAE,IAAI,CAAC,CAAC;;;;;;;cApB9D,QAAQ,CAAC,qBAAqB,CAAC,WAAW,CAAC,CAAC;;;;cAKtD,QAAQ,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC;;;;cAKzC,QAAQ,CAAC,qBAAqB,CAAC,aAAa,CAAC,CAAC;;;;cAK9C,QAAQ,CAAC,qBAAqB,CAAC,cAAc,CAAC,CAAC;;;;cAK7C,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAC,CAAC,YAAY,CAAC,EAAE,IAAI,CAAC,CAAC;;;;;;;;;;;;gBAsBtF,CAAJ;;;;4EAaF,CAAA"}
|
package/dist/Editor.d.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { Editor as CoreEditor, EditorOptions } from '@tiptap/core';
|
|
2
|
-
import { EditorState, Plugin, PluginKey } from '@tiptap/pm/state';
|
|
3
|
-
import { AppContext, ComponentInternalInstance, ComponentPublicInstance } from 'vue';
|
|
4
|
-
export type ContentComponent = ComponentInternalInstance & {
|
|
5
|
-
ctx: ComponentPublicInstance;
|
|
6
|
-
};
|
|
7
|
-
export declare class Editor extends CoreEditor {
|
|
8
|
-
private reactiveState;
|
|
9
|
-
private reactiveExtensionStorage;
|
|
10
|
-
contentComponent: ContentComponent | null;
|
|
11
|
-
appContext: AppContext | null;
|
|
12
|
-
constructor(options?: Partial<EditorOptions>);
|
|
13
|
-
get state(): EditorState;
|
|
14
|
-
get storage(): Record<string, any>;
|
|
15
|
-
/**
|
|
16
|
-
* Register a ProseMirror plugin.
|
|
17
|
-
*/
|
|
18
|
-
registerPlugin(plugin: Plugin, handlePlugins?: (newPlugin: Plugin, plugins: Plugin[]) => Plugin[]): EditorState;
|
|
19
|
-
/**
|
|
20
|
-
* Unregister a ProseMirror plugin.
|
|
21
|
-
*/
|
|
22
|
-
unregisterPlugin(nameOrPluginKey: string | PluginKey): EditorState | undefined;
|
|
23
|
-
}
|
|
24
|
-
//# sourceMappingURL=Editor.d.ts.map
|
package/dist/Editor.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Editor.d.ts","sourceRoot":"","sources":["../src/Editor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,IAAI,UAAU,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAClE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AACjE,OAAO,EACL,UAAU,EACV,yBAAyB,EACzB,uBAAuB,EAIxB,MAAM,KAAK,CAAA;AAwBZ,MAAM,MAAM,gBAAgB,GAAG,yBAAyB,GAAG;IACzD,GAAG,EAAE,uBAAuB,CAAA;CAC7B,CAAA;AAED,qBAAa,MAAO,SAAQ,UAAU;IACpC,OAAO,CAAC,aAAa,CAAkB;IAEvC,OAAO,CAAC,wBAAwB,CAA0B;IAEnD,gBAAgB,EAAE,gBAAgB,GAAG,IAAI,CAAO;IAEhD,UAAU,EAAE,UAAU,GAAG,IAAI,CAAO;gBAE/B,OAAO,GAAE,OAAO,CAAC,aAAa,CAAM;IAchD,IAAI,KAAK,gBAER;IAED,IAAI,OAAO,wBAEV;IAED;;OAEG;IACI,cAAc,CACnB,MAAM,EAAE,MAAM,EACd,aAAa,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,MAAM,EAAE,GACjE,WAAW;IAUd;;OAEG;IACI,gBAAgB,CAAC,eAAe,EAAE,MAAM,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS;CAStF"}
|
package/dist/EditorContent.d.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { PropType, Ref } from 'vue';
|
|
2
|
-
import { Editor } from './Editor.js';
|
|
3
|
-
export declare const EditorContent: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
4
|
-
editor: {
|
|
5
|
-
default: null;
|
|
6
|
-
type: PropType<Editor>;
|
|
7
|
-
};
|
|
8
|
-
}>, {
|
|
9
|
-
rootEl: Ref<Element | undefined, Element | undefined>;
|
|
10
|
-
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
11
|
-
editor: {
|
|
12
|
-
default: null;
|
|
13
|
-
type: PropType<Editor>;
|
|
14
|
-
};
|
|
15
|
-
}>> & Readonly<{}>, {
|
|
16
|
-
editor: Editor;
|
|
17
|
-
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
18
|
-
//# sourceMappingURL=EditorContent.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"EditorContent.d.ts","sourceRoot":"","sources":["../src/EditorContent.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,QAAQ,EACR,GAAG,EAIJ,MAAM,KAAK,CAAA;AAEZ,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEpC,eAAO,MAAM,aAAa;;;cAMJ,QAAQ,CAAC,MAAM,CAAC;;;;;;;cAAhB,QAAQ,CAAC,MAAM,CAAC;;;;4EAiEpC,CAAA"}
|