mirror of
https://github.com/ueberdosis/tiptap.git
synced 2024-12-05 04:11:38 +08:00
add renderless FloatingMenu
This commit is contained in:
parent
41f38e1041
commit
d4f6708daa
@ -1,7 +1,12 @@
|
||||
<template>
|
||||
<div class="editor">
|
||||
<floating-menu class="editor__floating-menu" :editor="editor">
|
||||
<template slot-scope="{ commands, isActive }">
|
||||
<floating-menu :editor="editor">
|
||||
<div
|
||||
slot-scope="{ commands, isActive, menu }"
|
||||
class="editor__floating-menu"
|
||||
:class="{ 'is-active': menu.isActive }"
|
||||
:style="`top: ${menu.top}px`"
|
||||
>
|
||||
|
||||
<button
|
||||
class="menubar__button"
|
||||
@ -59,7 +64,7 @@
|
||||
<icon name="code" />
|
||||
</button>
|
||||
|
||||
</template>
|
||||
</div>
|
||||
</floating-menu>
|
||||
|
||||
<editor-content class="editor__content" :editor="editor" />
|
||||
@ -138,6 +143,11 @@ export default {
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
transition: opacity 0.2s, visibility 0.2s;
|
||||
|
||||
&.is-active {
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -7,29 +7,44 @@ export default {
|
||||
type: Object,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
menu: {
|
||||
isActive: false,
|
||||
left: 0,
|
||||
bottom: 0,
|
||||
},
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
editor: {
|
||||
immediate: true,
|
||||
handler(editor) {
|
||||
if (editor) {
|
||||
this.$nextTick(() => {
|
||||
editor.registerPlugin(FloatingMenu(this.$el))
|
||||
editor.registerPlugin(FloatingMenu({
|
||||
element: this.$el,
|
||||
onUpdate: menu => {
|
||||
this.menu = menu
|
||||
},
|
||||
}))
|
||||
})
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
render(createElement) {
|
||||
render() {
|
||||
if (!this.editor) {
|
||||
return null
|
||||
}
|
||||
|
||||
return createElement('div', this.$scopedSlots.default({
|
||||
return this.$scopedSlots.default({
|
||||
focused: this.editor.view.focused,
|
||||
focus: this.editor.focus,
|
||||
commands: this.editor.commands,
|
||||
isActive: this.editor.isActive.bind(this.editor),
|
||||
markAttrs: this.editor.markAttrs.bind(this.editor),
|
||||
}))
|
||||
menu: this.menu,
|
||||
})
|
||||
},
|
||||
}
|
||||
|
@ -1,12 +1,18 @@
|
||||
import { Plugin } from 'prosemirror-state'
|
||||
|
||||
class Toolbar {
|
||||
class Menu {
|
||||
|
||||
constructor({ element, editorView }) {
|
||||
constructor({ options, editorView }) {
|
||||
this.options = {
|
||||
...{
|
||||
element: null,
|
||||
onUpdate: () => false,
|
||||
},
|
||||
...options,
|
||||
}
|
||||
this.editorView = editorView
|
||||
this.element = element
|
||||
this.element.style.visibility = 'hidden'
|
||||
this.element.style.opacity = 0
|
||||
this.isActive = false
|
||||
this.top = 0
|
||||
|
||||
this.editorView.dom.addEventListener('blur', this.hide.bind(this))
|
||||
}
|
||||
@ -35,17 +41,21 @@ class Toolbar {
|
||||
return
|
||||
}
|
||||
|
||||
const editorBoundings = this.element.offsetParent.getBoundingClientRect()
|
||||
const editorBoundings = this.options.element.offsetParent.getBoundingClientRect()
|
||||
const cursorBoundings = view.coordsAtPos(state.selection.$anchor.pos)
|
||||
const top = cursorBoundings.top - editorBoundings.top
|
||||
|
||||
this.element.style.top = `${top}px`
|
||||
this.show()
|
||||
this.isActive = true
|
||||
this.top = top
|
||||
|
||||
this.sendUpdate()
|
||||
}
|
||||
|
||||
show() {
|
||||
this.element.style.visibility = 'visible'
|
||||
this.element.style.opacity = 1
|
||||
sendUpdate() {
|
||||
this.options.onUpdate({
|
||||
isActive: this.isActive,
|
||||
top: this.top,
|
||||
})
|
||||
}
|
||||
|
||||
hide(event) {
|
||||
@ -53,8 +63,8 @@ class Toolbar {
|
||||
return
|
||||
}
|
||||
|
||||
this.element.style.visibility = 'hidden'
|
||||
this.element.style.opacity = 0
|
||||
this.isActive = false
|
||||
this.sendUpdate()
|
||||
}
|
||||
|
||||
destroy() {
|
||||
@ -63,10 +73,10 @@ class Toolbar {
|
||||
|
||||
}
|
||||
|
||||
export default function (element) {
|
||||
export default function (options) {
|
||||
return new Plugin({
|
||||
view(editorView) {
|
||||
return new Toolbar({ editorView, element })
|
||||
return new Menu({ editorView, options })
|
||||
},
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user