import { Extension } from '@tiptap/core'
import { ReactRenderer } from '@tiptap/react'
import Suggestion from '@tiptap/suggestion'
import tippy, { Instance as TippyInstance } from 'tippy.js'
import SlashCommandMenu, { SlashCommandMenuRef } from './SlashCommandMenu'
const SlashCommandExtension = Extension.create({
name: 'slashCommand',
addProseMirrorPlugins() {
return [
Suggestion({
editor: this.editor,
char: '/',
allowSpaces: false,
startOfLine: false,
command: ({ editor, range, props }) => {
props.command({ editor, range })
},
items: ({ query }) => {
return []
},
render: () => {
let component: ReactRenderer<SlashCommandMenuRef>
let popup: TippyInstance[]
return {
onStart: (props: any) => {
component = new ReactRenderer(SlashCommandMenu, {
props,
editor: props.editor,
})
if (!props.clientRect) {
return
}
popup = tippy('body', {
getReferenceClientRect: props.clientRect,
appendTo: () => document.body,
content: component.element,
showOnCreate: true,
interactive: true,
trigger: 'manual',
placement: 'bottom-start',
})
},
onUpdate: (props: any) => {
component.updateProps(props)
if (!props.clientRect) {
return
}
if (popup && popup[0]) {
popup[0].setProps({
getReferenceClientRect: props.clientRect,
})
}
},
onKeyDown: (props: any) => {
if (props.event.key === 'Escape') {
if (popup && popup[0]) {
popup[0].hide()
}
return true
}
return component.ref?.onKeyDown(props.event) || false
},
onExit: () => {
if (popup && popup[0]) {
popup[0].destroy()
}
if (component) {
component.destroy()
}
},
}
},
}),
]
},
})
export default SlashCommandExtension