Launch prototype

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.

Component Playground

Live instance - the controls read their options from the same config that drives the Variants section below.

simple toolbar · valid · enabled

Controls

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.

PartWhat it does
TextEditor.RootCreates the editor and shares it with every part below. Takes the options above.
TextEditor.LabelThe shared Label. Clicking it focuses the editor.
TextEditor.ToolbarSimple or advanced toolbar. Compose your own from the individual controls listed below.
TextEditor.TooltipA bubble menu that follows the text selection.
TextEditor.ContentThe editable area. Takes the props of Tiptap's EditorContent, without editor.
TextEditor.HintTextThe shared HintText. With a limit and no children it counts the characters left.

TextEditor.Root

PropTypeDefault
placeholderstring"Write something…"
limitnumber-
isDisabledbooleanfalse
isInvalidbooleanfalse
contentstring | JSONContent-
onUpdate(props) => void-
classNamestring-
inputClassNamestring-
childrenReactNode-

TextEditor.Toolbar

PropTypeDefault
type"simple" | "advanced""simple"
floatingbooleanfalse
hideFontSizebooleanfalse
onGenerate() => void- (button hidden)
classNamestring-

TextEditor.Tooltip

PropTypeDefault
classNamestring-

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.