InlineEdit
Inline-editable text — the text, then a pencil. A click or Enter turns it into an input in place, at the same size; Enter, blur or Tab commits, Escape restores, and clearing it brings back a muted default.
npx visor add inline-editDefault
The text, then a pencil. Click either one (or press Enter on the pencil) and an input takes the text's place at the same size, so nothing below it moves. A long title wraps; it is never truncated.
Technical rider
A heading, with a default
as sets the element, and the type comes with it: here an h2 at the editor's 21px display size. While value is empty, defaultValue shows, muted. Clear the text and commit, and onCommit("") is called and the default comes back.
Track record
Keyboard
| Key | Action |
|---|---|
Enter (on the pencil) | Opens the input, with the text selected |
Enter | Commits, and returns focus to the pencil |
Tab | Commits, and moves on to the next field |
Escape | Restores the text without committing |
Blur commits too. onCommit receives the trimmed text, and is not called when nothing changed.
Edges
At rest, InlineEdit is text and a pencil, with no edge. While editing, the input draws its resting edge from the shared control-edge tokens, never from border, so --control-edge-width: 0 turns it off with every other form control. Focus still draws its own ring.
Theming
The pencil is the same mark as an icon-only Button: it reads --button-icon-size (the glyph), --button-icon-pad (the hit target, drawn on ::before so it adds no height to the line) and --button-icon-ghost-color (the ink at rest). The default's muted colour is --text-tertiary.
The input takes its size, weight and line height from font: inherit, which comes from Visor's element reset (@import "@loworbitstudio/visor-core/reset"), as it does for every form control. Tailwind's preflight sets the same thing.
When not to use
- Multi-line text: use Textarea.
- A labelled card tile with a save button: use EditableBlock.
Installation
npx visor add inline-editThis copies two files into your project:
components/ui/inline-edit/inline-edit.tsx: the componentcomponents/ui/inline-edit/inline-edit.module.css: the styles
API Reference
InlineEditProps
| Prop | Type | Default | Description |
|---|---|---|---|
value* | string | — | The committed text. An empty string means no override, and `defaultValue` shows instead. |
onCommit* | (value: string) => void | — | Called with the trimmed text on Enter, blur or Tab, only when it differs from `value`. An empty string means "restore the default". The parent updates `value`. |
label* | string | — | The field's name (e.g. "Section title"). Names the input, and the pencil as "Edit {label}". |
defaultValue | string | '' | Shown, muted, while `value` is empty, and used as the input's placeholder. |
as | 'span' | 'div' | 'p' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'span' | The element to render. Typography inherits from it, so a title keeps its heading's size and colour. |
editLabel | string | — | Accessible name of the pencil. Defaults to "Edit {label}". |
defaultEditing | boolean | false | Opens in the editing state on mount, without moving focus. |
InlineEdit also accepts the standard HTML attributes of the element it renders.