Rich Text Editor
Preview: Toolbar
Tiptap 3 editor styled with Marble UI tokens: toolbar or bubble menu, placeholder, word/character count.
Import
import { RichTextEditor } from '@marbleui/ui'Props
<RichTextEditor>
| Prop | Type | Default | Description |
|---|---|---|---|
| className | string | — | |
| content | string | '' | |
| footer | ReactNode | — | |
| label | string | 'Editor' | |
| limit | number | — | |
| onChange | (html: string) => void | — | |
| placeholder | string | 'Write something…' | |
| showCount | boolean | variant === 'full' | |
| variant | 'bubble' | 'full' | 'minimal' | 'full' | "full": fixed toolbar. "bubble": formatting menu appears on text selection. "minimal": no chrome. |
Accessibility
Keyboard interaction, focus management and ARIA semantics come from the underlying primitive: React Aria Toolbar. Follow the primitive's docs for the full keyboard map.
Usage notes
Rich text editing on Tiptap 3, styled with Marble UI tokens; it reports HTML. For plain multi-line text use TextArea.
<RichTextEditor
label="Release notes"
content="<p>This release adds two theme presets.</p>"
limit={2000}
onChange={(html) => setDraft(html)}
/>
contentonly seeds the document. The editor keeps its own state and sends every edit toonChange; changingcontentlater doesn’t reset it.variant:full(fixed toolbar plus word/character count),bubble(formatting menu next to a text selection) orminimal(no chrome). Every variant also takes ⌘/Ctrl+B, ⌘/Ctrl+I, ⌘/Ctrl+Z and Markdown-style input such as##,-and>.label(default “Editor”) is the editing area’s accessible name and isn’t displayed; put a visible label next to it. Toolbar buttons are labelled and report their pressed state. The toolbar is one Tab stop: arrow keys (and Home/End) move between its buttons. The word/character count isn’t a live region; only crossing 90% oflimitand reaching it are announced.limitstops input past that many characters, and the count darkens once 90% is used.
Example source · show· hide
import { RichTextEditor } from './rich-text-editor'
const doc = `<h2>Release notes</h2><p>This release ships <strong>47 components</strong> on React Aria, two theme presets and <em>live previews</em>.</p><ul><li>Overlays portal into the themed container</li><li>Charts follow the validated palette</li></ul><blockquote>Select some text to see the formatting state.</blockquote>`
export const styles = {
Toolbar: () => <RichTextEditor className="w-[34rem]" content={doc} limit={2000} />,
Bubble: () => <RichTextEditor className="w-[34rem]" variant="bubble" content="<p>Select any of this text: a formatting menu appears next to the selection.</p>" />,
Minimal: () => <RichTextEditor className="w-[34rem] bg-surface-muted" variant="minimal" placeholder="Add a description…" />,
}Source: packages/ui/src/rich-text-editor/rich-text-editor.tsx
Catalog
- Category
- editor
- Priority
- Pro
- Primitive
- custom