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
valuestring—Controlled committed value
defaultValuestring''Initial committed value (uncontrolled)
onChange(value: string) => void—Called when the committed value changes
editingboolean—Controlled editing state
defaultEditingbooleanfalseInitial editing state (uncontrolled)
onEditingChange(editing: boolean) => void—Called when editing starts or stops
onSubmit(value: string) => void—Called with the new value when an edit is committed
onCancel() => void—Called when an edit is discarded
onEdit() => void—Called when editing begins
submitOnBlurbooleantrueCommit when the field loses focus
disabledbooleanfalsePrevent editing
placeholderstring—Shown 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