Skip to content

df-rtf-editor Component ​

df-rtf-editor is a rich text editor on TipTap. Its toolbar is built from Vuetify components, so it uses the application's theme and this library's translated strings.

Basic Usage ​

df-rtf-editor bound to a vue-forms field:

RTF Editor Example
Welcome to RTF Editor This is a rich text editor component built on TipTap. You can: Format text with bold, italic, and headings Insert links, images, and tables Create bulleted and numbered lists And much more...
HTML Output:
<h2>Welcome to RTF Editor</h2><p>This is a <strong>rich text editor</strong> component built on <a href="https://tiptap.dev/">TipTap</a>.</p><p>You can:</p><ul><li>Format text with <strong>bold</strong>, <em>italic</em>, and headings</li><li>Insert links, images, and tables</li><li>Create bulleted and numbered lists</li><li>And much more...</li></ul>

Features ​

  • Binds a @dynamicforms/vue-forms element, a v-model, or neither
  • Headings, bold, italic, block quotes, bulleted and numbered lists
  • Images: insert by URL, upload, or paste directly from the clipboard, embedded as base64 data: URIs, with drag-handle resizing
  • Tables, with row and column insertion/deletion
  • Links, with an optional download attribute
  • Pasting a Word or Google Docs selection: formatted text, embedded images and tables are pasted as structured content, without the source application's markup
  • A "Style" dropdown applying named, class-based styles to the current block or selection
  • Media embeds: paste a YouTube or Vimeo URL to insert a responsive player

Props ​

In addition to common props from InputBase, this component supports:

PropTypeDefaultDescription
minHeightstring'7em'Minimum height of the editing area
fontFamilystring'inherit'font-family of the editing area and its named block styles. The component loads no font of its own; pass a value here (and load the font itself, if needed) to use something other than the surrounding page's font

Inherited Props ​

This component inherits all common props from InputBase, including:

  • control - DynamicForms field object
  • modelValue - The HTML content (v-model)
  • label - Input label
  • hint - Hint text
  • And more...

Toolbar Features ​

  • Text formatting

    • Bold, italic
    • Headings (paragraph, H1-H6)
  • Structured content

    • Bulleted and numbered lists, with indent/outdent
    • Tables — insert, and add/delete rows and columns
    • Block quotes, horizontal line
  • Links, images and media

    • Links, with an optional "Downloadable" attribute (download="file")
    • Images — insert by URL, upload from disk, or paste from the clipboard; all three embed the picture as a base64 data: URI, and a placed image can be resized by dragging its corner and edge handles
    • Media embed — paste a YouTube or Vimeo URL to insert a responsive <iframe> player; any other URL is inserted as a plain link instead
  • Style dropdown

    • Applies one of the named styles from Custom Styles to the current block or selection, and removes it on a second click
  • Alignment

    • Left, center, right, justify
  • Utilities

    • Undo/redo, select all
    • A selection popup with bold, italic, link and list toggles
    • Pasting from Word or Google Docs: formatting, embedded images and tables are pasted as structured content, without the source application's markup

Events ​

This component emits all common events from InputBase:

  • update:modelValue - When the HTML content changes

Working with HTML Content ​

The value is HTML, and the component does not sanitize it. An application that displays HTML entered by users sanitizes it first, to prevent XSS.

List items and table cells save their text wrapped in a paragraph (<li><p>...</p></li>, <td><p>...</p></td>), so HTML rendered outside this component (a public page, a PDF export, a templated email) needs li p, td p, th p { margin: 0; } in its stylesheet; otherwise the browser's default paragraph margin adds space to every list item and cell. <df-rtf-editor>'s editing surface has this rule. See also the migration guide.

Custom Styles ​

The editor's stylesheet styles several predefined content classes, applied from the toolbar's Style dropdown:

StyleElementClass
Article categoryh3category
Titleh2document-title
Subtitleh3document-subtitle
Info boxpinfo-box
Side quoteblockquoteside-quote
Markerspan (inline)marker
Spoilerspan (inline)spoiler
Code (dark)prefancy-code fancy-code-dark
Code (bright)prefancy-code fancy-code-bright

The block-level styles (all but Marker and Spoiler) set the current block's element type and class; Marker and Spoiler toggle over a text selection like bold or italic. Clicking an applied style removes it: the block becomes a plain paragraph, or, for Marker and Spoiler, the mark is removed.

Examples ​

Basic Usage with v-model ​

vue
<template>
  <df-rtf-editor
    v-model="content"
    label="Article Content"
    hint="Use the formatting toolbar to style your content"
  />
</template>

<script setup>
import { ref } from 'vue';
import { DfRtfEditor } from '@dynamicforms/vuetify-inputs';

const content = ref('<h2>Welcome</h2><p>This is a <strong>rich text editor</strong>.</p>');
</script>

With DynamicForms Integration ​

vue
<template>
  <df-rtf-editor
    :control="form.fields.description"
    label="Product Description"
    hint="Format the product description with rich text"
    min-height="15em"
  />
</template>

<script setup>
import { Group, Field, ValidationError, Validators } from '@dynamicforms/vue-forms';
import { DfRtfEditor } from '@dynamicforms/vuetify-inputs';

const form = new Group({
  description: new Field({
    value: '<p>Enter a detailed product description here.</p>',
    validators: [
      new Validators.Validator((value) => {
        if (!value || value === '<p></p>') return [new ValidationError('description_required', {}, 'Description is required')];
        if (value.length < 20) return [new ValidationError('description_too_short', { minLength: 20 }, 'Description is too short')];
        return null;
      })
    ]
  })
});
</script>

Released under the MIT License.