UNPKG

@tiptap/extension-bubble-menu

Version:

bubble-menu extension for tiptap

1 lines 17.4 kB
{"version":3,"file":"index.cjs","sources":["../src/bubble-menu-plugin.ts","../src/bubble-menu.ts"],"sourcesContent":["import {\n Editor, isNodeSelection, isTextSelection, posToDOMRect,\n} from '@tiptap/core'\nimport { EditorState, Plugin, PluginKey } from '@tiptap/pm/state'\nimport { EditorView } from '@tiptap/pm/view'\nimport tippy, { Instance, Props } from 'tippy.js'\n\nexport interface BubbleMenuPluginProps {\n /**\n * The plugin key.\n * @type {PluginKey | string}\n * @default 'bubbleMenu'\n */\n pluginKey: PluginKey | string\n\n /**\n * The editor instance.\n */\n editor: Editor\n\n /**\n * The DOM element that contains your menu.\n * @type {HTMLElement}\n * @default null\n */\n element: HTMLElement\n\n /**\n * The options for the tippy.js instance.\n * @see https://atomiks.github.io/tippyjs/v6/all-props/\n */\n tippyOptions?: Partial<Props>\n\n /**\n * The delay in milliseconds before the menu should be updated.\n * This can be useful to prevent performance issues.\n * @type {number}\n * @default 250\n */\n updateDelay?: number\n\n /**\n * A function that determines whether the menu should be shown or not.\n * If this function returns `false`, the menu will be hidden, otherwise it will be shown.\n */\n shouldShow?:\n | ((props: {\n editor: Editor\n element: HTMLElement\n view: EditorView\n state: EditorState\n oldState?: EditorState\n from: number\n to: number\n }) => boolean)\n | null\n}\n\nexport type BubbleMenuViewProps = BubbleMenuPluginProps & {\n view: EditorView\n}\n\nexport class BubbleMenuView {\n public editor: Editor\n\n public element: HTMLElement\n\n public view: EditorView\n\n public preventHide = false\n\n public tippy: Instance | undefined\n\n public tippyOptions?: Partial<Props>\n\n public updateDelay: number\n\n private updateDebounceTimer: number | undefined\n\n public shouldShow: Exclude<BubbleMenuPluginProps['shouldShow'], null> = ({\n view,\n state,\n from,\n to,\n }) => {\n const { doc, selection } = state\n const { empty } = selection\n\n // Sometime check for `empty` is not enough.\n // Doubleclick an empty paragraph returns a node size of 2.\n // So we check also for an empty text size.\n const isEmptyTextBlock = !doc.textBetween(from, to).length && isTextSelection(state.selection)\n\n // When clicking on a element inside the bubble menu the editor \"blur\" event\n // is called and the bubble menu item is focussed. In this case we should\n // consider the menu as part of the editor and keep showing the menu\n const isChildOfMenu = this.element.contains(document.activeElement)\n\n const hasEditorFocus = view.hasFocus() || isChildOfMenu\n\n if (!hasEditorFocus || empty || isEmptyTextBlock || !this.editor.isEditable) {\n return false\n }\n\n return true\n }\n\n constructor({\n editor,\n element,\n view,\n tippyOptions = {},\n updateDelay = 250,\n shouldShow,\n }: BubbleMenuViewProps) {\n this.editor = editor\n this.element = element\n this.view = view\n this.updateDelay = updateDelay\n\n if (shouldShow) {\n this.shouldShow = shouldShow\n }\n\n this.element.addEventListener('mousedown', this.mousedownHandler, { capture: true })\n this.view.dom.addEventListener('dragstart', this.dragstartHandler)\n this.editor.on('focus', this.focusHandler)\n this.editor.on('blur', this.blurHandler)\n this.tippyOptions = tippyOptions\n // Detaches menu content from its current parent\n this.element.remove()\n this.element.style.visibility = 'visible'\n }\n\n mousedownHandler = () => {\n this.preventHide = true\n }\n\n dragstartHandler = () => {\n this.hide()\n }\n\n focusHandler = () => {\n // we use `setTimeout` to make sure `selection` is already updated\n setTimeout(() => this.update(this.editor.view))\n }\n\n blurHandler = ({ event }: { event: FocusEvent }) => {\n if (this.preventHide) {\n this.preventHide = false\n\n return\n }\n\n if (event?.relatedTarget && this.element.parentNode?.contains(event.relatedTarget as Node)) {\n return\n }\n\n if (\n event?.relatedTarget === this.editor.view.dom\n ) {\n return\n }\n\n this.hide()\n }\n\n tippyBlurHandler = (event: FocusEvent) => {\n this.blurHandler({ event })\n }\n\n createTooltip() {\n const { element: editorElement } = this.editor.options\n const editorIsAttached = !!editorElement.parentElement\n\n if (this.tippy || !editorIsAttached) {\n return\n }\n\n this.tippy = tippy(editorElement, {\n duration: 0,\n getReferenceClientRect: null,\n content: this.element,\n interactive: true,\n trigger: 'manual',\n placement: 'top',\n hideOnClick: 'toggle',\n ...this.tippyOptions,\n })\n\n // maybe we have to hide tippy on its own blur event as well\n if (this.tippy.popper.firstChild) {\n (this.tippy.popper.firstChild as HTMLElement).addEventListener('blur', this.tippyBlurHandler)\n }\n }\n\n update(view: EditorView, oldState?: EditorState) {\n const { state } = view\n const hasValidSelection = state.selection.from !== state.selection.to\n\n if (this.updateDelay > 0 && hasValidSelection) {\n this.handleDebouncedUpdate(view, oldState)\n return\n }\n\n const selectionChanged = !oldState?.selection.eq(view.state.selection)\n const docChanged = !oldState?.doc.eq(view.state.doc)\n\n this.updateHandler(view, selectionChanged, docChanged, oldState)\n }\n\n handleDebouncedUpdate = (view: EditorView, oldState?: EditorState) => {\n const selectionChanged = !oldState?.selection.eq(view.state.selection)\n const docChanged = !oldState?.doc.eq(view.state.doc)\n\n if (!selectionChanged && !docChanged) {\n return\n }\n\n if (this.updateDebounceTimer) {\n clearTimeout(this.updateDebounceTimer)\n }\n\n this.updateDebounceTimer = window.setTimeout(() => {\n this.updateHandler(view, selectionChanged, docChanged, oldState)\n }, this.updateDelay)\n }\n\n updateHandler = (view: EditorView, selectionChanged: boolean, docChanged: boolean, oldState?: EditorState) => {\n const { state, composing } = view\n const { selection } = state\n\n const isSame = !selectionChanged && !docChanged\n\n if (composing || isSame) {\n return\n }\n\n this.createTooltip()\n\n // support for CellSelections\n const { ranges } = selection\n const from = Math.min(...ranges.map(range => range.$from.pos))\n const to = Math.max(...ranges.map(range => range.$to.pos))\n\n const shouldShow = this.shouldShow?.({\n editor: this.editor,\n element: this.element,\n view,\n state,\n oldState,\n from,\n to,\n })\n\n if (!shouldShow) {\n this.hide()\n\n return\n }\n\n this.tippy?.setProps({\n getReferenceClientRect:\n this.tippyOptions?.getReferenceClientRect\n || (() => {\n if (isNodeSelection(state.selection)) {\n let node = view.nodeDOM(from) as HTMLElement\n\n if (node) {\n const nodeViewWrapper = node.dataset.nodeViewWrapper ? node : node.querySelector('[data-node-view-wrapper]')\n\n if (nodeViewWrapper) {\n node = nodeViewWrapper.firstChild as HTMLElement\n }\n\n if (node) {\n return node.getBoundingClientRect()\n }\n }\n }\n\n return posToDOMRect(view, from, to)\n }),\n })\n\n this.show()\n }\n\n show() {\n this.tippy?.show()\n }\n\n hide() {\n this.tippy?.hide()\n }\n\n destroy() {\n if (this.tippy?.popper.firstChild) {\n (this.tippy.popper.firstChild as HTMLElement).removeEventListener(\n 'blur',\n this.tippyBlurHandler,\n )\n }\n this.tippy?.destroy()\n this.element.removeEventListener('mousedown', this.mousedownHandler, { capture: true })\n this.view.dom.removeEventListener('dragstart', this.dragstartHandler)\n this.editor.off('focus', this.focusHandler)\n this.editor.off('blur', this.blurHandler)\n }\n}\n\nexport const BubbleMenuPlugin = (options: BubbleMenuPluginProps) => {\n return new Plugin({\n key:\n typeof options.pluginKey === 'string' ? new PluginKey(options.pluginKey) : options.pluginKey,\n view: view => new BubbleMenuView({ view, ...options }),\n })\n}\n","import { Extension } from '@tiptap/core'\n\nimport { BubbleMenuPlugin, BubbleMenuPluginProps } from './bubble-menu-plugin.js'\n\nexport type BubbleMenuOptions = Omit<BubbleMenuPluginProps, 'editor' | 'element'> & {\n /**\n * The DOM element that contains your menu.\n * @type {HTMLElement}\n * @default null\n */\n element: HTMLElement | null,\n}\n\n/**\n * This extension allows you to create a bubble menu.\n * @see https://tiptap.dev/api/extensions/bubble-menu\n */\nexport const BubbleMenu = Extension.create<BubbleMenuOptions>({\n name: 'bubbleMenu',\n\n addOptions() {\n return {\n element: null,\n tippyOptions: {},\n pluginKey: 'bubbleMenu',\n updateDelay: undefined,\n shouldShow: null,\n }\n },\n\n addProseMirrorPlugins() {\n if (!this.options.element) {\n return []\n }\n\n return [\n BubbleMenuPlugin({\n pluginKey: this.options.pluginKey,\n editor: this.editor,\n element: this.options.element,\n tippyOptions: this.options.tippyOptions,\n updateDelay: this.options.updateDelay,\n shouldShow: this.options.shouldShow,\n }),\n ]\n },\n})\n"],"names":["isTextSelection","isNodeSelection","posToDOMRect","tippy","Plugin","PluginKey","Extension"],"mappings":"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"}