tiptap/packages/vue-3/src/FloatingMenu.ts
bdbch 7eaa34d0d1 Remove tippy.js and replace with Floating UI (#5398)
* start experimenting with floating-ui

* add options to floating-ui bubble menu plugin & fix smaller issues

* add vue support for new floating-ui

* start experimenting with floating-ui

* adjust floating-menu plugin for floating-ui & update react component

* add vue support for floating-menu with floating-ui

* update tests for new floating-ui integration

* added changeset file

* move floating-ui dependency to peerDeps

* add install notice to changelog

* remove unnecessary code for destroying and removing component element in Vue suggestion.js

* remove unnecessary code for destroying and removing component element in React suggestion.js

* sync package-lock

* widen range for peerDeps again
2024-07-31 03:51:53 +02:00

79 lines
1.7 KiB
TypeScript

import type { BubbleMenuPluginProps } from '@tiptap/extension-bubble-menu'
import { FloatingMenuPlugin, FloatingMenuPluginProps } from '@tiptap/extension-floating-menu'
import {
defineComponent,
h,
onBeforeUnmount,
onMounted,
PropType,
ref,
Teleport,
} from 'vue'
export const FloatingMenu = defineComponent({
name: 'FloatingMenu',
props: {
pluginKey: {
// TODO: TypeScript breaks :(
// type: [String, Object as PropType<Exclude<FloatingMenuPluginProps['pluginKey'], string>>],
type: null,
default: 'floatingMenu',
},
editor: {
type: Object as PropType<FloatingMenuPluginProps['editor']>,
required: true,
},
options: {
type: Object as PropType<BubbleMenuPluginProps['options']>,
default: () => ({}),
},
shouldShow: {
type: Function as PropType<Exclude<Required<FloatingMenuPluginProps>['shouldShow'], null>>,
default: null,
},
},
setup(props, { slots }) {
const root = ref<HTMLElement | null>(null)
onMounted(() => {
const {
pluginKey,
editor,
options,
shouldShow,
} = props
if (!root.value) {
return
}
root.value.style.visibility = 'hidden'
root.value.style.position = 'absolute'
// remove the element from the DOM
root.value.remove()
editor.registerPlugin(FloatingMenuPlugin({
pluginKey,
editor,
element: root.value as HTMLElement,
options,
shouldShow,
}))
})
onBeforeUnmount(() => {
const { pluginKey, editor } = props
editor.unregisterPlugin(pluginKey)
})
return () => h(Teleport, { to: 'body' }, h('div', { ref: root }, slots.default?.()))
},
})