Inline Edit

Text that turns into a field when clicked, for changing a value where it's shown.

Name
Title
Email
Notes

Installation

  1. Add the registryOnce per project
  2. Add inline-edit

Usage

InlineEditPreview shows the value as text, with an underline and a pencil when it's hovered and a pencil when it's focused, and a click swaps it for InlineEditInput in the same place, at the same size, with the value selected. The input is an Input with variant="underline", which has no padding at the sides, so the text lines up with the label whether it's being edited or not. Enter saves the edit and Escape puts the value back, and both return focus to the preview. Moving focus anywhere else saves it too. onValueChange is called only when a saved value differs from the last one, and value makes it controlled.

A FieldLabel in the same Field names the preview and the input, and clicking it starts an edit. Without one, give InlineEdit an aria-label, or point its aria-labelledby at the element that names it, such as a <dt>.

Composition

Examples

Basic

Multiple lines

InlineEditTextarea edits text over several lines, growing with it, in a Textarea with variant="underline". Enter starts a new line, so ⌘Enter, or Ctrl+Enter, saves. The preview keeps the line breaks.

Save and cancel buttons

InlineEditControls adds buttons to save and cancel at the end of the field, each with a tooltip naming its shortcut. Pass it InlineEditSubmit and InlineEditCancel to change their order or icons. Here blurAction="none" keeps the field open when focus leaves it, so only Enter or a button saves, and "cancel" would put the value back.

Validation

validate checks the value before it's saved. Return a message to keep the field open, and an InlineEditError shows it and is announced. It clears as soon as the value changes.

Saving

When onValueChange returns a promise, the field stays open and read-only, with a spinner, until the promise settles, and the save button shows the spinner in its place. If it rejects, the field stays open with the error's message in the InlineEditError, to try again or press Escape.

“admin” is taken, to show a failed save.

Headings

The preview and the field take the font of the InlineEdit, so a larger or bolder one makes an editable heading. The field is never smaller than 16 pixels on phones, so Safari doesn't zoom into it.

Edit button

Set activationMode="none" when the preview holds something clickable of its own, such as a link, and add an InlineEditTrigger, a button with a pencil, to start an edit. A function as the preview's child renders the value.

Double-click

activationMode="double-click" starts an edit on a double click, or on Enter or Space from the keyboard, so a single click is free for something else, such as selecting a row. selectOnFocus set to false puts the caret at the end of the value in place of selecting it.

In a description list

In the example at the top, each value of a Description List is an InlineEdit named by its <dt>, which takes the same vertical padding as the preview so the two line up.

Disabled

Read-only

A read-only preview isn't a button, and shows no pencil.

acct_8f2k19

In a form

Give a Field or the InlineEdit a name, and the saved value submits under it, or pass form with a form's id when it sits outside it. A Form's onFormSubmit gets it too. An edit still open when the form submits isn't included until it's saved, and a form reset brings back defaultValue. A controlled InlineEdit leaves resets to its parent: a reset still closes an open edit, but value stays until the parent changes it, such as from the form's onReset. required stops the form submitting without a saved value. In a Field, a FieldLabel names the preview and the input, they read out the field's FieldDescription, and an invalid field marks them invalid.

Shown on your profile and beside your comments.

Props

Base UI's styling and composition guides say more about className, style and render.

InlineEdit

InlineEditPreview

InlineEditTrigger

InlineEditInput

InlineEditTextarea

InlineEditControls

InlineEditSubmit

InlineEditCancel

InlineEditError