Text editors
Text editors capture formatted, long-form input: a compound family built on Tiptap that composes a toolbar, an editable surface, and an optional label, hint, and counter from one namespace.
Text editors
Text editors capture formatted, long-form input: a compound family built on Tiptap that composes a toolbar, an editable surface, and an optional label, hint, and counter from one namespace.
Demo
Change the props and copy the result. The toolbar, floating, and content picks swap fixed children; the other controls are real props. Select some of the seeded text to see the sheet’s Text highlight: the brand selection tint with the bubble menu above it. Insert an image from an advanced strip and drag its corner handles to resize it; the size persists in the document. The bare EditorButton keeps its live states in the States section below.
The composition in this demo is fixed
The family
One namespace plus the standalone toolbar controls. Root owns the editor instance; everything else reads it from context and throws outside Root.
| Component | Description | Import from |
|---|---|---|
| TextEditor.Root | Creates the Tiptap editor (StarterKit plus text style, alignment, image, placeholder, and character count) and shares it via context. | @/components/base/text-editor/text-editor |
| TextEditor.Toolbar | The prebuilt control strip: simple or advanced, docked or floating. | @/components/base/text-editor/text-editor |
| TextEditor.Content | The contenteditable surface bound to the context editor. | @/components/base/text-editor/text-editor |
| TextEditor.Label | The field label, wired to the editor id; clicking it focuses the editor. The only way to name the editor. | @/components/base/text-editor/text-editor |
| TextEditor.HintText | The hint line; with limit set and no children it renders a characters-left counter instead. | @/components/base/text-editor/text-editor |
| TextEditor.Tooltip | The selection bubble menu: 6 fixed controls over the selected text, dark by default. | @/components/base/text-editor/text-editor |
| TextEditorBold / Italic / … | 14 standalone toolbar controls (marks, alignment, list, link, image, color, font selects, generate) for composing custom strips. | @/components/base/text-editor/text-editor-extensions |
| EditorButton | The bare 32px toolbar button with isActive and isDisabled; every extension control renders one. | @/components/base/text-editor/text-editor-button |
Toolbars
The sheet’s 3 toolbar variants, docked and floating: the simple strip carries marks, color, alignment, and list; the advanced strip adds font selects, link, image, and generate, and drops the font selects when floating. hideGenerate renders the sheet’s Advanced w/o Generate form. All 5 are live and drive a headless editor each.
Both strips are compositions of exported parts
text-editor-extensions, so a custom strip is the same parts in a flex row; the Code tab shows one. The generate button is the one exception to working out of the box: it renders and disables with the rest but is wired to no command, which is why the sheet names an Advanced w/o Generate form, rendered by hideGenerate.The composed field
Root arranges whatever parts it is given: label, strip, surface, and hint compose in any order. The counter appears when limit is set and HintText has no children; a hint sentence replaces it. The placeholder shows in an empty document only.
The counter renders once
limit as advisory and validate length where the value is saved; details on the Guidelines tab.States
Every treatment below is painted by the kit through real props: isInvalid and isDisabled on Root, isActive and isDisabled on EditorButton. Hover and focus have no prop and no exported style object to re-apply, so they are not forced here; interact with the live examples instead.
Focus looks different on the two layers