Skip to content

RichTextEditor Component

The RichTextEditor component is a powerful rich text editor built with Vue 3 and TipTap. It provides a user-friendly interface for formatting text, creating lists, and adding hyperlinks. The component is highly customizable and perfect for applications requiring rich text editing capabilities.

Installation

To use the RichTextEditor component you need to install the @tiptap/extension-link, @tiptap/starter-kit, @tiptap/vue-3, @floating-ui/vue, and @headlessui/vue packages.

bash
yarn add @robuust-digital/vue-components @tiptap/extension-link @tiptap/starter-kit @tiptap/vue-3 @floating-ui/vue @headlessui/vue

Import the component from the rich-text-editor package

js
import { RichTextEditor } from '@robuust-digital/vue-components/rich-text-editor';

Import CSS

css
@import "@robuust-digital/vue-components/rich-text-editor/css";

Basic Usage

Import and use RichTextEditor in your Vue components as follows:

vue
<template>
  <RichTextEditor
    id="editor-1"
    v-model="editor1"
    placeholder="Start typing..."
  />
</template>

<script setup>
import { RichTextEditor } from '@robuust-digital/vue-components/rich-text-editor';
</script>

Props

The RichTextEditor component accepts the following props:

PropTypeDefaultDescription
idStringRequiredUnique identifier for the editor
modelValueString''The editor's HTML content
rootClassStringundefinedAdditional classes for root element
configString'default'Editor configuration ('default' or 'simple')
customCommandsArray[]Custom commands for the toolbar
customExtensionsArray[]Custom extensions for the editor

Slots

Default Slot

The default slot is used to add custom content to the editor:

vue
<template>
  <RichTextEditor>
    <Modal />
  </RichTextEditor>
</template>

Toolbar Slot

See Toolbar slot example in the Custom Toolbar section.

Features

The RichTextEditor includes the following formatting options:

  • Text Formatting: Bold and italic text
  • Lists: Bullet and numbered lists
  • Hyperlinks: Add and edit URLs
  • Customizable Toolbar: Support for custom toolbar layouts

Examples

Simple Configuration

Use the config="simple" prop to show only basic formatting options (bold and italic):

Show code
vue
<template>
  <RichTextEditor
    id="editor-2"
    v-model="editor3"
    config="simple"
    placeholder="Basic formatting only..."
  />
</template>

Pre-filled Content

Show code
vue
<template>
  <RichTextEditor
    id="editor-3"
    v-model="editor2"
  />
</template>

<script setup>
const editor2 = ref(`
  <p>This is a 🚀 pre-filled rich text editor with some <strong>bold</strong> and <em>italic</em> text.</p>
  <ul>
    <li>Item 1</li>
    <li>Item 2</li>
  </ul>
  <p>And a <a href="https://example.com">link</a>.</p>
`);
</script>

Advanced Examples

You can customize the RichTextEditor component by adding custom extensions and commands.

Use the Link extension to add hyperlink functionality to the editor:

Important note

The Link extension already comes with the default configuration, this is just an example. You can use custom-extensions to add other extensions to the editor.

Show code
vue
<template>
  <RichTextEditor
    id="simpleRichTextWithLink"
    v-model="editorContent"
    config="simple"
    name="simpleRichTextWithLink"
    placeholder="Type something..."
    :custom-commands="[
      {
        name: 'link',
        icon: LinkIcon,
        title: 'Hyperlink',
        isVisible: true,
        disabled: !tiptap?.view.state.selection.empty && !tiptap?.isActive('link'),
        isActive: () => tiptap?.isActive('link'),
        action: () => {
          link = tiptap?.getAttributes('link').href;
          showLinkModal = true;
        },
      },
    ]"
    :custom-extensions="[Link.configure({ openOnClick: false })]"
    @tiptap:on-create="(editor) => tiptap = editor"
  >
    <Modal
      id="just-a-custom-modal-add-hyperlink`"
      title="Add Hyperlink"
      as="form"
      :show="showLinkModal"
      @modal:close="showLinkModal = false"
      @modal:save="setLink"
    >
      <FormInput
        v-model="link"
        placeholder="https://www.example.com"
        type="url"
        required
      />
    </Modal>
  </RichTextEditor>
</template>

<script setup>
import { ref, shallowRef } from 'vue';
import { FormInput } from '@robuust-digital/vue-components/core';
import { Modal } from '@robuust-digital/vue-components/dialogs';
import { RichTextEditor } from '@robuust-digital/vue-components/rich-text-editor';
import { LinkIcon } from '@heroicons/vue/16/solid';
import Link from '@tiptap/extension-link';

const tiptap = shallowRef(null);
const editorContent = ref('');
const showLinkModal = ref(false);
const link = ref('');
const setLink = () => {
  tiptap.value.commands.setLink({ href: link.value });
  showLinkModal.value = false;
  link.value = null;
};
</script>

Custom Toolbar

You can customize the toolbar using the toolbar slot:

vue
<template>
  <RichTextEditor
    id="custom-editor"
    v-model="content"
  >
    <template #toolbar="{ commands }">
      <ul class="rvc-rich-text-toolbar">
        <li v-for="command in commands" :key="command.name">
          <button
            :class="['rvc-rich-text-button', { 'rvc-rich-text-button-active': command.isActive() }]"
            @click="command.action"
          >
            <Component :is="command.icon" />
          </button>
        </li>
      </ul>
    </template>
  </RichTextEditor>
</template>

CSS Customization ⚡️

To customize the richTextEditor styles global

css
:root {
  /* Available variables */
  --rvc-rich-text-list-padding: calc(var(--spacing) * 2.5);
  --rvc-rich-text-list-position: inside;
  --rvc-rich-text-paragraph-spacing: calc(var(--spacing) * 4);
  --rvc-rich-text-icon-size: calc(var(--spacing) * 4);
  --rvc-rich-text-button-border-radius: var(--rvc-base-border-radius);
  --rvc-rich-text-button-padding: calc(var(--spacing) * 1);
  --rvc-rich-text-button-bg-color: transparent;
  --rvc-rich-text-button-bg-color-hover: var(--color-slate-100);
  --rvc-rich-text-button-color: var(--color-slate-600);
  --rvc-rich-text-button-color-active: var(--color-indigo-700);
  --rvc-rich-text-anchor-color: var(--color-indigo-700);
  --rvc-rich-text-anchor-font-weight: var(--font-weight-bold);
  --rvc-rich-text-anchor-text-decoration: underline;
  --rvc-rich-text-min-height: calc(var(--spacing) * 24);
}

Textarea Styling options

This component also uses padding styling variables from FormTextarea:

  • --rvc-textarea-padding-x
  • --rvc-textarea-padding-y