TextEditor
A rich text editor based on TipTap for creating and formatting content. Offers intuitive controls, styling options, and smooth editing experience.
Default
<script setup lang="ts">
import { ref } from 'vue'
import { TextEditor } from 'frappe-ui'
const value = ref(`
<div>
<h2>Heading 2</h2>
<p>
This is a paragraph with <strong>bold</strong> and <em>italic</em> text.
</p>
<ul>
<li>Item 1</li>
<li>Item 2</li>
</ul>
<p>
<a href="https://frappe.io">Frappe</a>
</p>
<pre><code class="language-javascript">import { Button } from 'frappe-ui'
const value = ref(true);</code></pre>
</div>
`)
</script>
<template>
<TextEditor
editor-class="prose-sm min-h-[4rem] border rounded-b-lg border-t-0 p-2"
:content="value"
placeholder="Type something..."
@change="(val) => (value.value = val)"
:bubbleMenu="true"
:fixed-menu="true"
/>
</template>Comment Editor
<script setup lang="ts">
import { ref } from 'vue'
import { EditorContent } from '@tiptap/vue-3'
import { Button, TextEditor, TextEditorFixedMenu } from 'frappe-ui'
const customValue = ref('')
const customButtons = [
'Paragraph',
['Heading 2', 'Heading 3', 'Heading 4'],
'Separator',
'Bold',
'Italic',
'Separator',
'Bullet List',
'Numbered List',
'Separator',
'Link',
'Image',
]
</script>
<template>
<TextEditor
ref="textEditor"
editor-class="prose-sm max-w-none min-h-[4rem]"
:content="customValue"
@change="(val) => (customValue.value = val)"
:starterkit-options="{ heading: { levels: [2, 3, 4] } }"
placeholder="Write something amazing..."
>
<template v-slot:editor="{ editor }">
<EditorContent
class="max-h-[50vh] overflow-y-auto border rounded-lg p-4"
:editor="editor"
/>
</template>
<template v-slot:bottom>
<div
class="mt-2 flex flex-col justify-between sm:flex-row sm:items-center"
>
<TextEditorFixedMenu
class="-ml-1 overflow-x-auto"
:buttons="customButtons"
/>
<div class="mt-2 flex items-center justify-end space-x-2 sm:mt-0">
<Button>Cancel</Button>
<Button variant="solid">Submit</Button>
</div>
</div>
</template>
</TextEditor>
</template>API Reference
Show types
import { type Component } from 'vue'
import { type UploadedFile } from '../../utils/useFileUpload'
import { type MentionSuggestionItem } from './extensions/mention/mention-extension'
type ConfigureMentionOptions =
| {
mentions: MentionSuggestionItem[]
component?: Component
}
| MentionSuggestionItem[]
| null
export interface TextEditorProps {
/** Initial editor content (HTML/string). `null` renders an empty editor */
content?: string | null
/** Placeholder text or dynamic placeholder resolver */
placeholder?: string | (() => string)
/** Custom classes applied to the editor root */
editorClass?: string | string[] | object
/** Toggles editability of the editor */
editable?: boolean
/** Autofocus the editor on mount */
autofocus?: boolean
/** Enables bubble menu or provides custom bubble menu items */
bubbleMenu?: boolean | any[]
/** Configuration options for the bubble menu */
bubbleMenuOptions?: object
/** Enables fixed menu or provides custom fixed menu items */
fixedMenu?: boolean | any[]
/** Enables floating menu or provides custom floating menu items */
floatingMenu?: boolean | any[]
/** Custom TipTap extensions */
extensions?: any[]
/** Options passed to TipTap StarterKit */
starterkitOptions?: any
/** Mention extension configuration */
mentions?: ConfigureMentionOptions
/** Tag / hashtag configuration */
tags?: any[] | null
/** Async file upload handler (used for images, files, etc.) */
uploadFunction?: (file: File) => Promise<UploadedFile>
/** Extra arguments passed to the upload function */
uploadArgs?: object
}
export interface TextEditorEmits {
/** Fired whenever editor content changes */
change: [content: string]
/** Fired when the editor gains focus */
focus: [event: FocusEvent]
/** Fired when the editor loses focus */
blur: [event: FocusEvent]
/** Fired on every editor transaction */
transaction: [editor: object]
}Initial editor content (HTML/string). `null` renders an empty editor
Placeholder text or dynamic placeholder resolver
Custom classes applied to the editor root
Toggles editability of the editor
Autofocus the editor on mount
Enables bubble menu or provides custom bubble menu items
Configuration options for the bubble menu
Enables fixed menu or provides custom fixed menu items
Enables floating menu or provides custom floating menu items
Custom TipTap extensions
Options passed to TipTap StarterKit
Mention extension configuration
Tag / hashtag configuration
Async file upload handler (used for images, files, etc.)
Extra arguments passed to the upload function
| Slot | Payload |
|---|---|
top | { editor: { contentComponent: { uid: number; type: FunctionalComponent<{}, {}, any, {}> | { [x: stri |
editor | { editor: { contentComponent: { uid: number; type: FunctionalComponent<{}, {}, any, {}> | { [x: stri |
bottom | { editor: { contentComponent: { uid: number; type: FunctionalComponent<{}, {}, any, {}> | { [x: stri |
| Event | Payload |
|---|---|
change | [content: string] Fired after the value is committed. |
focus | [event: FocusEvent] |
blur | [event: FocusEvent] |
transaction | [editor: object] |
Fired after the value is committed.