InlineEditField
<InlineEditField> is a single-property cell. Default state shows plain text; click (or focus + Enter) turns it into an editor. Blur or Enter commits; Esc cancels. The value flips immediately, with a brief ✓ on success or × + message on failure (with rollback).
When to use
- A property cell on an entity detail page (CRM person/deal) where edits are individual.
- Quick rename / quick description / quick tag-edit affordances.
Don’t use InlineEditField for: forms (Form — has Save / Cancel and field-level validation), bulk editing, or any change that requires confirmation before persisting (use a modal).
Basic
Click the value, type, blur or Enter to commit. Esc cancels.
Name
const [name, setName] = useState('Acme Corp');
<InlineEditField value={name} onCommit={async (next) => { await api.update({ name: next }); setName(next); }} placeholder="Add a name" aria-label="Name"/>Server validation rejects
Reject in onCommit to roll back the optimistic value and surface an inline error.
Name (empty rejects)
<InlineEditField value={name} onCommit={async (next) => { if (!next.trim()) throw new Error('Name cannot be empty.'); await api.update({ name: next }); setName(next); }} aria-label="Name"/>Read-only
Name (read-only)
<InlineEditField value="Acme Corp" onCommit={() => undefined} readOnly aria-label="Name" />API
| Prop | Type | Default | Description |
|---|---|---|---|
value * | string | number | null | undefined | — | Current value. Rendered as plain text in read mode. |
onCommit * | (next: string) => void | Promise<unknown> | — | Resolve = success (✓ flash). Reject = failure (× + message, rollback). |
type | "text" | "url" | "number" | "date" | "select" | "person" | "text" | Edit-mode input flavour. select requires `options`. |
options | Array<{ value: string; label: string }> | — | Required when type="select". |
placeholder | string | — | Shown in read mode when the value is empty. |
readOnly | boolean | false | Renders as plain text only — no edit affordance. |
formatDisplay | (value) => ReactNode | — | Override the read-mode text (e.g., formatted dates). |
successTimeout | number | 1500 | Milliseconds the ✓ stays visible after a successful commit. |
inputProps | InputProps | — | Forwarded to the underlying Input in edit mode. |
aria-label | string | — | Required when there is no surrounding label. |
Design guidelines
✓ Do
- Pair every InlineEditField with an aria-label or a surrounding label that describes the property.
- Reject in onCommit to surface validation. The component handles rollback + inline error for you.
- Use formatDisplay for dates and numbers — show the user-readable form in read mode.
✗ Don't
- Wrap InlineEditField in a Form. It bypasses the react-hook-form pattern by design.
- Add a Save button next to it. The blur / Enter contract is the contract.
- Use it for fields that require multi-step confirmation (destructive renames, role changes). Use a modal.
Accessibility
- Read mode is a focusable element; Enter / Space activates edit mode.
- Edit mode is a real
<Input>— Esc cancels, Enter commits, blur commits. - Errors surface inline with
role="alert"so screen readers announce them on rejection.
Related
Form— For multi-field forms with explicit Save.PropertyList— Often hosts InlineEditField cells.InlineEditField(test) — More complex inline editors are tracked in the roadmap.