Skip to Content
⭐️ Leave a star →
ComponentsEditable

Editable

Inline text editing: click the preview to edit, Enter/blur to commit, Escape to discard. Pair with Editable.Area for multiline. Controlled and uncontrolled.

Features

Click the preview to switch into an editable input.
Enter or blur commits, Escape discards the edit.
Single-line Input or multiline Area (Cmd/Ctrl+Enter to save).
Optional explicit Edit, Submit and Cancel triggers.
Can be controlled or uncontrolled for both value and editing state.
Supports disabled and placeholder states.

Example

Jerald Austero
Designing accessible component systems.
import { Editable } from '@wire-ui/react' <Editable.Root defaultValue="Click to edit me" placeholder="Enter some text…"> <Editable.Preview /> <Editable.Input /> </Editable.Root>

Multiline

Swap Editable.Input for Editable.Area to edit longer text in a <textarea>. In multiline mode a plain Enter inserts a newline — commit with Cmd/Ctrl+Enter (or blur, unless submitOnBlur is false).

<Editable.Root defaultValue="A longer description…"> <Editable.Preview /> <Editable.Area rows={3} /> </Editable.Root>

Styling

Editable ships no styles. Editable.Root sets data-editing while editing and data-disabled when disabled. Editable.Preview sets data-empty when the committed value is empty — use it to style placeholder text.

<Editable.Preview className=" text-black data-[empty]:text-[#9ca3af] " /> <Editable.Root className=" data-[disabled]:opacity-50 data-[disabled]:cursor-not-allowed " />

Note that Editable.Preview is only rendered while not editing, and Editable.Input / Editable.Area / Editable.SubmitTrigger / Editable.CancelTrigger only while editing, so they never overlap.

Using data attributes

/* Placeholder styling on an empty preview */ [data-empty] { color: #9ca3af; } /* Disabled root */ [data-disabled] { opacity: 0.5; cursor: not-allowed; }

Root props

PropTypeDefaultDescription
valuestringControlled committed value
defaultValuestring''Initial committed value (uncontrolled)
onChange(value: string) => voidCalled when the committed value changes
editingbooleanControlled editing state
defaultEditingbooleanfalseInitial editing state (uncontrolled)
onEditingChange(editing: boolean) => voidCalled when editing starts or stops
onSubmit(value: string) => voidCalled with the new value when an edit is committed
onCancel() => voidCalled when an edit is discarded
onEdit() => voidCalled when editing begins
submitOnBlurbooleantrueCommit when the field loses focus
disabledbooleanfalsePrevent editing
placeholderstringShown by Preview when the value is empty

Sub-component props

ComponentElementNotes
Editable.Preview<span role="button">Click or Enter/Space to start editing; only shown when not editing
Editable.Input<input type="text">Single-line field; only shown while editing
Editable.Area<textarea>Multiline field; only shown while editing
Editable.EditTrigger<button type="button">Starts editing; only shown when not editing
Editable.SubmitTrigger<button type="button">Commits the edit; only shown while editing
Editable.CancelTrigger<button type="button">Discards the edit; only shown while editing

Input and Area manage their own value/onChange/defaultValue from context, so those props are omitted from their types; all other native attributes pass through.

Data attributes

AttributeElementValues
data-editingRootPresent while editing
data-disabledRootPresent when disabled
data-emptyPreviewPresent when the committed value is empty

Preview also sets role="button", tabindex (0, or -1 when disabled), and aria-disabled when disabled.

Accessibility

  • Editable.Preview is exposed as a button (role="button", focusable) and starts editing on Enter or Space
  • Input and Area receive focus and select their contents automatically when editing begins
  • When disabled, the preview is removed from the tab order (tabindex="-1") and marked aria-disabled

Keyboard Interactions

KeyDescription
Enter / SpaceOn a focused preview, starts editing.
EnterIn single-line Input, commits the edit.
Cmd/Ctrl+EnterIn multiline Area, commits the edit.
EscapeDiscards the edit and restores the previous value.
TabMoves focus to the field or the next trigger.
Last updated on

MIT License © 2026 wire-ui

Editable – Wire UI