tiptap 中文文档

Tiptap Bubble Menu 气泡菜单

Tiptap BubbleMenu 浮动菜单扩展,当选中对象菜单将悬浮在鼠标附近,你可以对选中的标记mark进行操作。

Install 安装

npm install @tiptap/extension-bubble-menu

Settings 配置

element 包含菜单的元素,默认为null。

BubbleMenu.configure({
  element: null,
})

updateDelay BubbleMenu取消了更新方法,允许在每次选择更新时不更新气泡菜单。这可以在毫秒内控制。BubbleMenuPlugin的默认延迟为250ms。这可以通过将延迟设置为0来停用。

BubbleMenu.configure({
  updateDelay: 0,
})

tippyOptions BubbleMenu使用tippy.js,您可以直接将配置传递给它。

BubbleMenu.configure({
  tippyOptions: { },
})

pluginKey 当有多个实例时你需要用到这个参数,默认为bubbleMenu。

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'),
    }),
  ],
})

shouldShow 一个控制菜单是否显示的回调函数。

BubbleMenu.configure({
  shouldShow: ({ editor, view, state, oldState, from, to }) => {
    //如果是图片或链接才显示菜单
    return editor.isActive('image') || editor.isActive('link')
  },
})

Usage 用例

import { Editor } from '@tiptap/core'
import BubbleMenu from '@tiptap/extension-bubble-menu'

new Editor({
  extensions: [
    BubbleMenu.configure({
      element: document.querySelector('.menu'),
    }),
  ],
})

源代码

bubble-menu 源代码

在线例子

vue 在线例子

BubbleMenu 例子

  • Vue 例子

  • React 例子

  • React CSS

<template>
  <div>
    <div>
      <input type="checkbox" :checked="isEditable" @change="() => isEditable = !isEditable">
      Editable
    </div>
    <bubble-menu
      :editor="editor"
      :tippy-options="{ duration: 100 }"
      v-if="editor"
    >
      <button @click="editor.chain().focus().toggleBold().run()" :class="{ 'is-active': editor.isActive('bold') }">
        bold
      </button>
      <button @click="editor.chain().focus().toggleItalic().run()" :class="{ 'is-active': editor.isActive('italic') }">
        italic
      </button>
      <button @click="editor.chain().focus().toggleStrike().run()" :class="{ 'is-active': editor.isActive('strike') }">
        strike
      </button>
    </bubble-menu>
    <editor-content :editor="editor" />
  </div>
</template>
<script>
import StarterKit from '@tiptap/starter-kit'
import { BubbleMenu, Editor, EditorContent } from '@tiptap/vue-3'

export default {
  components: {
    EditorContent,
    BubbleMenu,
  },
  data() {
    return {
      editor: null,
      isEditable: true,
    }
  },
  watch: {
    isEditable(value) {
      this.editor.setEditable(value)
    },
  },
  mounted() {
    this.editor = new Editor({
      extensions: [
        StarterKit,
      ],
      content: `
        <p>
          IT小书童 - 为程序员提供优质教程和文档,你选择几个文字试试看 www.itxst.com
        </p>
      `,
    })
  },
  beforeUnmount() {
    this.editor.destroy()
  },
}
</script>
<style>
/* Basic editor styles */
.ProseMirror {
  > * + * {
    margin-top: 0.75em;
  }
}

input[type="checkbox"] {
  margin-right: 4px;
}
</style>
import './styles.scss'
import {
  BubbleMenu, EditorContent, useEditor,
} from '@tiptap/react'
import StarterKit from '@tiptap/starter-kit'
import React, { useEffect } from 'react'

export default () => {
  const editor = useEditor({
    extensions: [
      StarterKit,
    ],
    content: `
      <p>
        Hey, try to select some text here. There will popup a menu for selecting some inline styles. Remember: you have full control about content and styling of this menu.
      </p>
    `,
  })

  const [isEditable, setIsEditable] = React.useState(true)

  useEffect(() => {
    if (editor) {
      editor.setEditable(isEditable)
    }
  }, [isEditable, editor])
  return (
    <>
      <div>
        <input type="checkbox" checked={isEditable} onChange={() => setIsEditable(!isEditable)} />
        Editable
      </div>
      {editor && <BubbleMenu editor={editor} tippyOptions={{ duration: 100 }}>
        <button
          onClick={() => editor.chain().focus().toggleBold().run()}
          className={editor.isActive('bold') ? 'is-active' : ''}
        >
          bold
        </button>
        <button
          onClick={() => editor.chain().focus().toggleItalic().run()}
          className={editor.isActive('italic') ? 'is-active' : ''}
        >
          italic
        </button>
        <button
          onClick={() => editor.chain().focus().toggleStrike().run()}
          className={editor.isActive('strike') ? 'is-active' : ''}
        >
          strike
        </button>
      </BubbleMenu>}
      <EditorContent editor={editor} />
    </>
  )
}
.ProseMirror {
  > * + * {
    margin-top: 0.75em;
  }
}

input[type="checkbox"] {
  margin-right: 8px;
}
Catalog
快速入门 Guide 向导 API 列表 tiptap 方法 tiptap 属性 titap 配置 commands 命令 nodes 节点 marks 标记 extensions 扩展 Color 颜色扩展 Bubble Menu 气泡菜单 CharacterCount 文字统计 Collaboration 实时协作 CollaborationCursor 协作光标 Dropcursor 拖动光标 Floating Menu 浮动菜单 Focus 焦点扩展 FontFamily 字体 Gapcursor 空光标 History 历史记录 Placeholder 占位符 StarterKit 核心扩展 TextAlign 对齐方式 Typography 特殊符号