webapp/src/components/EditorNew/prosemirror/plugins/selectionMenu.ts
2023-02-10 09:33:26 +01:00

56 lines
1.7 KiB
TypeScript

// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-nocheck
import { renderGrouped } from 'prosemirror-menu'
import { EditorState, Plugin } from 'prosemirror-state'
import styles from '../styles/ProseMirror.module.scss'
import type { EditorView } from 'prosemirror-view'
import type { DiscoursSchema } from '../schema'
import { buildMenuItems } from '../helpers/menu'
export class SelectionMenuView {
tooltip: HTMLDivElement
constructor(view: EditorView, schema: DiscoursSchema) {
this.tooltip = document.createElement('div')
this.tooltip.className = styles.selectionMenu
view.dom.parentNode.appendChild(this.tooltip)
const { dom } = renderGrouped(view, buildMenuItems(schema))
this.tooltip.appendChild(dom)
this.update(view, null)
}
update(view: EditorView, lastState: EditorState) {
const state = view.state
if (lastState && lastState.doc.eq(state.doc) && lastState.selection.eq(state.selection)) {
return
}
if (state.selection.empty) {
this.tooltip.style.display = 'none'
return
}
this.tooltip.style.display = ''
const { from, to } = state.selection
const start = view.coordsAtPos(from)
const end = view.coordsAtPos(to)
const box = this.tooltip.offsetParent.getBoundingClientRect()
const width = this.tooltip.getBoundingClientRect().width
const left = (start.left + end.left - width) / 2
this.tooltip.style.left = `${left - box.left}px`
this.tooltip.style.bottom = `${box.bottom - start.top + 8}px`
}
destroy() {
this.tooltip.remove()
}
}
export const selectionMenu = (schema: DiscoursSchema) =>
new Plugin({
view(editorView: EditorView) {
return new SelectionMenuView(editorView, schema)
}
})