BubbleMenu 扩展
此扩展会在文本选择附近显示上下文菜单。用户可以对其文本选择应用 标记。
和往常一样,标记和样式完全由您决定。
如果您使用的是 React 或 Vue 等框架,请使用特定于框架的 BubbleMenu 组件,而不是扩展。该组件提供了更方便的 API,并为您处理 DOM 元素。您可以在下方的与框架一起使用章节中找到有关该组件的更多信息。
安装
npm install @tiptap/extension-bubble-menu设置
element
包含您的菜单的 DOM 元素。
类型: HTMLElement
默认: null
在 React 版本的 BubbleMenu 中,可通过 BubbleMenu 组件的 ref 属性访问 DOM 元素,方法是将 ref 传递 给它。
updateDelay
BubbleMenu 会对 update 方法进行去抖动,以允许气泡菜单不会在每次选择更新时进行更新。此延迟可以以毫秒为单位进行控制。
BubbleMenuPlugin 默认有 250 毫秒的延迟。将延迟设置为 0 可禁用该功能,从而禁用去抖动。
类型: Number
默认: undefined
resizeDelay
BubbleMenu 会对气泡菜单大小的计算进行去抖动,以允许气泡菜单不会在每次调整大小事件时更新。此延迟可以以毫秒为单位进行控制。
类型: Number
默认: 100
options
在底层,BubbleMenu 使用 Floating UI。您可以使用这些选项控制浮动菜单的中间件和定位。
类型: Object
默认: { strategy: 'absolute', placement: 'right' }
| 选项 | 类型 | 描述 |
|---|---|---|
strategy | string | 定位策略。请参见 这里 |
placement | string | 菜单的位置。请参见 这里 |
offset | number, OffsetOptions 或 boolean | 偏移中间件选项。如果为 true,则使用默认选项;如果为 false,则禁用中间件 |
flip | FlipOptions 或 boolean | 翻转中间件选项。如果为 true,则使用默认选项;如果为 false,则禁用中间件 |
shift | ShiftOptions 或 boolean | 移动中间件选项。如果为 true,则使用默认选项;如果为 false,则禁用中间件 |
arrow | ArrowOptions 或 false | 箭头中间件选项。如果为 false,则禁用中间件 |
size | SizeOptions 或 boolean | 大小中间件选项。如果为 true,则使用默认选项;如果为 false,则禁用中间件 |
autoPlacement | AutoPlacementOptions 或 boolean | 自动定位中间件选项。如果为 true,则使用默认选项;如果为 false,则禁用中间件 |
hide | HideOptions 或 boolean | 隐藏中间件选项。如果为 true,则使用默认选项;如果为 false,则禁用中间件 |
inline | InlineOptions 或 boolean | 内联中间件选项。如果为 true,则使用默认选项;如果为 false,则禁用中间件 |
onShow | Function 或 undefined | 菜单显示时调用的回调函数。可用于在菜单显示时添加自定义逻辑或样式。 |
onHide | Function 或 undefined | 菜单隐藏时调用的回调函数。可用于在菜单隐藏时添加自定义逻辑或样式。 |
onUpdate | Function 或 undefined | 菜单更新时调用的回调函数。可用于在菜单更新时添加自定义逻辑或样式。 |
onDestroy | Function 或 undefined | 菜单销毁时调用的回调函数。可用于在菜单移除时添加自定义逻辑或样式。 |
pluginKey
底层 ProseMirror 插件的键。如果添加多个实例,请确保使用不同的键。
类型: string | PluginKey
默认: 'bubbleMenu'
shouldShow
一个回调,用于控制菜单是否应该显示。
类型: (props) => boolean
appendTo
气泡菜单应该被附加到 DOM 中的元素。可以是 HTMLElement,也可以是返回 HTMLElement 的回调函数。
类型: HTMLElement | (() => HTMLElement) | undefined
默认: undefined,菜单将附加到编辑器的父元素(editor.view.dom.parentElement)。
getReferencedVirtualElement
一个回调,用于提供用于定位菜单的锚点坐标。应返回 Floating UI 预期的 虚拟元素。
类型: () => VirtualElement | null
默认: null,锚点由编辑器选区隐式确定。
源代码
packages/extension-bubble-menu/
使用扩展
JavaScript
import { Editor } from '@tiptap/core'
import BubbleMenu from '@tiptap/extension-bubble-menu'
new Editor({
element: document.querySelector('#editor'),
extensions: [
StarterKit,
BubbleMenu.configure({
element: document.querySelector('#bubble-menu'),
}),
],
content: '<p>Select some text to see the bubble menu.</p>',
})向您的 HTML 中添加一个菜单元素:
<div id="bubble-menu" style="display: none; position: absolute;">
<button onclick="editor.chain().focus().toggleBold().run()">加粗</button>
<button onclick="editor.chain().focus().toggleItalic().run()">斜体</button>
</div>
<div id="editor"></div>当选中文本时,Tiptap 会自动显示并定位菜单元素。
与框架一起使用
React
@tiptap/react 包含一个可从 @tiptap/react/menus 导入的 BubbleMenu 组件。它提供与扩展相同的功能,但采用了更适合 React 的 API。使用此组件时,无需将 BubbleMenu 扩展添加到编辑器中。
import { BubbleMenu } from '@tiptap/react/menus'
function MyBubbleMenu({ editor }) {
return (
<BubbleMenu editor={editor}>
<button onClick={() => editor.chain().focus().toggleBold().run()}>
加粗
</button>
<button onClick={() => editor.chain().focus().toggleItalic().run()}>
斜体
</button>
</BubbleMenu>
)
}Vue
@tiptap/vue-3 包含一个可从 @tiptap/vue-3/menus 导入的 BubbleMenu 组件。它提供与扩展相同的功能,但采用了更适合 Vue 的 API。使用此组件时,无需将 BubbleMenu 扩展添加到编辑器中。
<template>
<BubbleMenu :editor="editor">
<button @click="editor.chain().focus().toggleBold().run()">
加粗
</button>
<button @click="editor.chain().focus().toggleItalic().run()">
斜体
</button>
</BubbleMenu>
</template>
<script setup>
import { BubbleMenu } from '@tiptap/vue-3/menus'
// 确保将编辑器实例作为属性传递给 BubbleMenu 组件
const { editor } = defineProps({
editor: {
type: Object,
required: true,
},
})
</script>注意:相同的菜单也可用于 Vue 2 版本的 Tiptap,您可以从 @tiptap/vue-2/menus 导入。
自定义逻辑
使用 shouldShow 选项自定义显示菜单的逻辑。对于组件,shouldShow 可以作为道具传递。
BubbleMenu.configure({
shouldShow: ({ editor, view, state, oldState, from, to }) => {
// 仅对图像和链接显示气泡菜单
return editor.isActive('image') || editor.isActive('link')
},
})多个菜单
通过设置唯一的 pluginKey 使用多个菜单。
import { Editor } from '@tiptap/core'
import BubbleMenu from '@tiptap/extension-bubble-menu'
new Editor({
extensions: [
BubbleMenu.configure({
pluginKey: 'bubbleMenuOne',
element: document.querySelector('.menu-one'),
}),
BubbleMenu.configure({
pluginKey: 'bubbleMenuTwo',
element: document.querySelector('.menu-two'),
}),
],
})或者,您可以传递一个 ProseMirror PluginKey。
import { Editor } from '@tiptap/core'
import BubbleMenu from '@tiptap/extension-bubble-menu'
import { PluginKey } from '@tiptap/pm/state'
new Editor({
extensions: [
BubbleMenu.configure({
pluginKey: new PluginKey('bubbleMenuOne'),
element: document.querySelector('.menu-one'),
}),
BubbleMenu.configure({
pluginKey: new PluginKey('bubbleMenuTwo'),
element: document.querySelector('.menu-two'),
}),
],
})强制更新气泡菜单位置
如果气泡菜单在初始渲染后改变了大小,其位置不会自动调整。要解决此问题,您可以通过在扩展上设置 pluginKey,并使用该键发出 'updatePosition' 事件来强制更新位置。
BubbleMenu.configure({
pluginKey: 'myBubbleMenu',
element: document.querySelector('.menu'),
})
editor.commands.setMeta('myBubbleMenu', 'updatePosition')要针对特定的气泡菜单,请改为传递该菜单的 pluginKey。
editor.commands.setMeta('bubbleMenuOne', 'updatePosition')如果您使用 React 或 Vue 的 BubbleMenu 组件,并希望在外部触发 updatePosition,请先为组件传入一个明确的 pluginKey 属性。如果省略 pluginKey,组件会创建自己的 ProseMirror PluginKey,外部代码之后无法可靠地引用它。
以编程方式显示或隐藏气泡菜单
您可以通过在扩展上设置 pluginKey,并使用该键分发带有 'show' 或 'hide' 元值的事务,来以编程方式显示或隐藏气泡菜单。
BubbleMenu.configure({
pluginKey: 'myBubbleMenu',
element: document.querySelector('.menu'),
})
// 显示气泡菜单
editor.commands.setMeta('myBubbleMenu', 'show')
// 隐藏气泡菜单
editor.commands.setMeta('myBubbleMenu', 'hide')注意: 分发 'show' 或 'hide' 将覆盖 shouldShow 中定义的行为。