Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Inline Edit Form Block for React Aria

A contact record whose values you press to edit in place: Enter or the check keeps an edit, Escape drops it, leaving the field keeps the draft open, one row opens at a time, and Undo last edit steps back.

Framework
UI library

Preview

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Overview

Edit a record where it sits, with a rule people can predict, with this inline edit form for React with React Aria. A compact header sits over a hairline frame with a plus mark on each corner. The frame names the contact and holds a description list with five rows, Name, Title, Email, Phone and Notes, whose values are buttons: a pencil shows on hover and always on touch screens, and pressing one swaps it for a field in the same box. The commit rule is explicit and written under the field: Enter or the check button keeps the edit, Escape or the cross discards it, and leaving the field keeps the draft open ("Unsaved: press Enter to save or Escape to discard") instead of saving or losing it behind your back. Only one row is open at a time: opening another while a draft differs sends you back to the open one. A bad email stays open and names the rule. A kept row shows "Changed, was" with the old value, and Undo last edit steps the record back one edit at a time. The foot holds the Shine Button Save contact, the only colored control, with a polite status line. It stays inert until a row has changed. It's built from Input, Button, Shine Button and Guides, with a CSS entrance only. For contact cards, profile fields, settings and any record where most visits change one value.

FAQ

How do I change the fields and the rules?

Edit ROWS for the labels and hints, SAVED for the starting record and problemOf for the rules (a name is required, the email needs an @ and a domain). Everything else, the display button, the field, the hint line and the Changed note, comes from the same row data.

Why does leaving a field keep the draft open?

Saving on blur surprises people who clicked away to look something up, and discarding on blur loses their typing. Keeping the draft open does neither: the hint changes to "Unsaved: press Enter to save or Escape to discard", the status line says the draft is still open, and the field stays where it was. Clicking another row's value while a draft differs sends you back to the open one with the same message.

How does it work with a keyboard and a screen reader?

Each value is a real button named "Edit email" (plus its value), so Tab reaches it and Enter opens it. Opening focuses the field, and Enter, Escape or the check and cross buttons return focus to the value button. The hint under the field is its description, the problem is read with it, and the block's one polite status line reads every result.

How does it look on a phone, and right to left?

Labels sit above the values and the pencil is always visible, since there is no hover. In a right-to-left page the label and value mirror, names follow their own direction, and email and phone stay left to right.

What stays local, and how do I connect it for real?

Everything: kept edits live in this tab and Save contact says "Saved Verity Oduya in this demo. Nothing was sent." To make it real, send the changed fields from the submit handler, or save each row on commit with a PATCH and show the result in the hint, and keep the undo trail as the way back.

How do I connect it to react-hook-form or TanStack Form?

Keep the record as the form's values and treat the open row as local view state. With react-hook-form, call setValue(name, draft, { shouldDirty: true }) in commit and trigger(name) first to run the rule; reset serves Undo.