Editor

A TipTap-based rich text editor that lives under the frappe-ui/editor subpath.

It isn't one monolithic widget — it's three pieces that snap together:

  • <Editor> — a renderless component that owns the editor lifecycle, v-model, upload, and placeholder. It renders no UI of its own; you render the chrome via its default slot, which exposes { editor, isEmpty }.
  • Kits (CommentKit, RichTextKit, InlineKit) — configurable bundles of extensions you pass to :extensions. The kit decides what the editor can do.
  • Building blocks (EditorContent, EditorFixedMenu, EditorBubbleMenu, EditorFloatingMenu) — the UI you compose inside the slot.

The examples below are the common recipes. See Exports for the full surface.

Comment editor

CommentKit is comment- and chat-grade: marks, lists, links, images, paste handling, emoji, and @/# suggestions. Here it's wired into a composer with a bubble menu, a bottom toolbar, and submit/discard actions. Open View Code to see the full layout.

Rich text editor

RichTextKit extends CommentKit with block-level extras — headings, tables, task lists, slash commands, color, highlight, alignment, and embeds. It suits articles, wiki pages, and notes. This recipe pairs a wrapping top toolbar with a bubble menu and a floating menu.

Inline editor

InlineKit is single-line rich text: the document holds exactly one block, so Enter is a no-op. It keeps inline marks and links but drops every block-level affordance — ideal for titles and names. It has no fixed toolbar, uploads, or actions.

Composing primitives

When no kit-and-slot recipe fits, drop to useEditor and render the primitives yourself. This owns the editor instance directly — no <Editor> wrapper — and reads editor state (here, a live word count).

Customizing size

EditorContent applies prose-v3 typography by default, with a 14px base. Every size in the scale — headings, lists, code, blockquotes — is em-relative to that base, so you change the whole editor's size by overriding one CSS variable, --prose-font-size. Line spacing (unitless line-height) scales with it automatically.

vue
<!-- scale the editor to a 16px base; headings and spacing follow -->
<EditorContent class="[--prose-font-size:1rem]" />

<!-- or drive it dynamically -->
<EditorContent :style="{ '--prose-font-size': fontSize }" />

Reach for this instead of a font-size utility like text-base: a utility overwrites prose-v3's line-height (cramping the text) and only resizes the element it's on, whereas --prose-font-size feeds the scale that prose-v3 itself derives every size and line-height from.

To pick a different named size altogether, pass a Tailwind Typography size modifier (prose-sm, prose-lg, …) instead — EditorContent detects it and steps aside so the modifier governs.

Suggestions

Build custom @, #, /, or : suggestion menus with SuggestionExtension.configure(...), then pass the configured extension to a kit or to useEditor. The kits use this internally for mention (@) and tag (#).

ts
import { SuggestionExtension } from 'frappe-ui/editor'

const People = SuggestionExtension.configure({
  name: 'people',
  trigger: '@',
  items: (query) => users.filter((user) => user.name.includes(query)),
  command: ({ editor, item, range }) => {
    editor.chain().focus().deleteRange(range).insertContent(item.name).run()
  },
})

Exports

Everything below is importable from frappe-ui/editor.

ts
import { Editor, RichTextKit, articleToolbar } from 'frappe-ui/editor'

Engine & component

ExportWhat it is
useEditorCreates and owns a TipTap editor from an options object. Returns a ShallowRef<Editor | null>. Reach for it when you compose primitives by hand.
EditorRenderless component. Owns the editor lifecycle, v-model, upload-function, and placeholder; exposes { editor, isEmpty } through its slot.

Building-block components

ExportWhat it is
EditorContentRenders the editable surface for a given :editor.
EditorFixedMenuA static toolbar row. Takes :editor and :items (a MenuItem[]).
EditorBubbleMenuFloating toolbar shown over the current text selection.
EditorFloatingMenuFloating toolbar shown on an empty line.

Inside <Editor>, EditorContent and the three menu components read the editor from context — the :editor prop is optional. Pass it explicitly only when composing primitives without <Editor> (see Composing primitives).

Kits

Configurable extension bundles — pass one (or more) to :extensions. Configure or remove any member with Kit.configure({ member: options }) or { member: false }.

ExportWhat it bundles
CommentKitStarterKit base + link, image, video, paste handling, emoji, @ mention, # tag. For comments and chat.
RichTextKitEverything in CommentKit plus tables, task lists, iframe embeds, table of contents, slash commands, color, highlight, typography, and text alignment.
InlineKitSingle-line document (one block, Enter disabled) with inline marks + link only. For titles and names.

Option types: CommentKitOptions, RichTextKitOptions, InlineKitOptions.

Extensions

Individual TipTap extensions with frappe-ui defaults already applied. Use these to assemble a custom extension list (or alongside a kit). StarterKit already ships link, code, and codeBlock, so disable them (StarterKit.configure({ link: false })) before adding the frappe versions to avoid duplicate-name warnings — the kits do this for you.

GroupExports
BaseStarterKit, Placeholder (+ setPlaceholder), Heading, HeadingIds
MarksLink, Code, TextStyle, Color, Highlight
BlocksCodeBlock, Table, TableRow, TableCell, TableHeader, TaskList, TaskItem
MediaImage, ImageGroup, ImageViewer, Video, Iframe
SuggestionsMention, Tag, Emoji, SlashCommands, SuggestionExtension
BehaviorTypography, TextAlign, Toc, ContentPaste, StyleClipboard

Ready-made CommandMenuItems for :items on the menu components.

GroupExports
MarksBold, Italic, Strike, InlineCode
BlocksParagraph, H1H6, HeadingGroup, BulletList, OrderedList, Blockquote
InsertInsertLink, InsertImage, InsertVideo, InsertTable, InsertIframe, HorizontalRule
ColorFontColor, FontHighlight
AlignAlignLeft, AlignCenter, AlignRight
HistoryUndo, Redo
LayoutSeparator

Toolbar presets

Pre-curated MenuItem[] arrays. Items whose extension isn't loaded hide themselves, so one preset adapts across kits.

ExportContents
minimalToolbarBold, Italic, InsertLink
commentToolbarBold, Italic, Strike, BulletList, OrderedList, InsertLink
articleToolbarHeadingGroup, marks, lists, Blockquote, InsertLink, InsertImage, InsertTable

Types

Editor, JSONContent, UploadedFile, MenuItem, CommandMenuItem, MenuGroupItem, MenuActionContext, MentionSuggestionItem, TagSuggestionItem, SuggestionExtensionOptions, SuggestionRange, and the kit option types listed above.