Components
Text editor
Rich text field built on Tiptap, sharing Input's own Label and HintText. A simple or advanced toolbar, a bubble menu on selection, an optional character limit, and invalid and disabled states - driven from config/design-system.config.ts.
Contextual config
Text editor sections
Show or hide documentation sections on this page. Changes apply immediately and persist across the site.
Component Playground
Live instance - the controls read their options from the same config that drives the Variants section below.
simple toolbar · valid · enabledControls
Toolbar
Hint
Toolbar types
simple carries bold, italic, underline, alignment and a bullet list. advanced adds the font size select, a link and an image.
Simple / Advanced
Bubble menu
Add TextEditor.Tooltip inside the root and a small menu follows the selection, with the formatting controls closest to hand.
Select some text
Character limit
Pass limit and give TextEditor.HintText no children: it counts the characters left and turns to the error colour once the limit is passed. The editor does not stop the typing.
Limit of 120
Disabled
Dims the field, locks the content and disables every toolbar control.
Disabled
Invalid
Pass isInvalid to switch the ring to the error token - typically paired with a validation-error hint.
Invalid
API
TextEditor is a set of parts that share one editor through context. Every part must sit inside TextEditor.Root.
| Part | What it does |
|---|---|
TextEditor.Root | Creates the editor and shares it with every part below. Takes the options above. |
TextEditor.Label | The shared Label. Clicking it focuses the editor. |
TextEditor.Toolbar | Simple or advanced toolbar. Compose your own from the individual controls listed below. |
TextEditor.Tooltip | A bubble menu that follows the text selection. |
TextEditor.Content | The editable area. Takes the props of Tiptap's EditorContent, without editor. |
TextEditor.HintText | The shared HintText. With a limit and no children it counts the characters left. |
TextEditor.Root
| Prop | Type | Default |
|---|---|---|
placeholder | string | "Write something…" |
limit | number | - |
isDisabled | boolean | false |
isInvalid | boolean | false |
content | string | JSONContent | - |
onUpdate | (props) => void | - |
className | string | - |
inputClassName | string | - |
children | ReactNode | - |
TextEditor.Toolbar
| Prop | Type | Default |
|---|---|---|
type | "simple" | "advanced" | "simple" |
floating | boolean | false |
hideFontSize | boolean | false |
onGenerate | () => void | - (button hidden) |
className | string | - |
TextEditor.Tooltip
| Prop | Type | Default |
|---|---|---|
className | string | - |
Individual controls
Exported from text-editor-extensions for building a toolbar of your own: TextEditorBold, TextEditorItalic, TextEditorUnderline, TextEditorBulletList, TextEditorAlignLeft, TextEditorAlignCenter, TextEditorAlignRight, TextEditorAlignJustify, TextEditorLink, TextEditorImage, TextEditorFontSize, TextEditorGenerate. TextEditorGenerate takes a required onPress.
Usage
import { TextEditor } from "@/components/base/text-editor/text-editor";
<TextEditor.Root placeholder="Describe the survey method." limit={280}>
<TextEditor.Label>Survey method</TextEditor.Label>
<TextEditor.Toolbar type="simple" />
<TextEditor.Content />
<TextEditor.HintText />
</TextEditor.Root>Figma
No linked Figma file yet - this component was pulled in via the Untitled UI CLI, not designed in Figma first.