Skip to main content

RichTextEditor

A Tiptap-based rich text editor — edits an HTML string, committing on blur.

import { RichTextEditor } from '@jbpark/ui-kit';

<RichTextEditor value={value} onChange={setValue} toolbar />;
committed HTML: <p>Hello, <strong>world</strong>!</p>

Props

PropTypeDefault
valuestring''
placeholderstring'Enter text...'
onChange(value: string) => void-
classNamestring-
classNames{ toolbar?: string; content?: string }-
toolbarboolean | ToolbarPreset[]false
toolbarItemsToolbarItem[]-

RichTextEditor is always controlled via value/onChange — there is no defaultValue. onChange fires with the editor's HTML (editor.getHTML()) on blur, not on every keystroke.

Toolbar

toolbar is opt-in (defaults to no toolbar, matching the original, toolbar-less output). Pass toolbar (bare, or toolbar={true}) for every built-in ToolbarPreset, or an array to pick a subset and order them, e.g. toolbar={['bold', 'italic', 'link']}.

Every preset maps onto a command StarterKit or the added @tiptap/extension-text-style TextStyleKit already registers — no extra Tiptap extension is needed beyond what the package ships:

PresetDoes
undo / redoHistory
headingParagraph / Heading 1-4, via a Select
bold / italic / underline / strike / codeInline marks
bulletList / orderedListLists
blockquote / codeBlock / horizontalRuleBlock nodes
linkSmall URL popover — pre-fills from the selection's existing link, empty href unsets it
fontSize / colorTextStyleKit-backed, via Select / ColorPicker

toolbarItems appends custom buttons after the built-in presets, for anything not already covered above. Each item receives the live Tiptap Editor instance, so it can call any registered command:

import type { Editor } from '@tiptap/core';
import { Eraser } from 'lucide-react';

<RichTextEditor
value={value}
onChange={setValue}
toolbar={['bold', 'italic', 'link']}
toolbarItems={[
{
key: 'clearFormatting',
icon: <Eraser />,
label: 'Clear formatting',
onClick: (editor: Editor) =>
editor.chain().focus().clearNodes().unsetAllMarks().run(),
},
]}
/>;