Inline edit ported
Rename in place: the text becomes a field without moving.
Rename in place: the text becomes a field without moving.
Loading demo…
Guidance
When to use
- Names and short fields read far more often than they change, such as a project name or description.
- Single values saved on their own with Enter, where optimistic feedback matters.
- Headings that stay headings while editable through the as prop.
When not to use
- Use input inside a regular form when several fields must be saved together.
- Use textarea-backed forms for long documents rather than one-line renames.
- Use a dialog when saving needs confirmation before it applies.
pnpm add sveltearcUsage
<script lang="ts">
import { InlineEdit } from '$lib/components/inline-edit';
let name = $state('Launch plan');
async function save(next: string) {
name = next;
}
</script>
<InlineEdit label="Project name" bind:value={name} onSave={save} />Variants & Examples
Default
Standard appearance and configuration.
<InlineEdit label="Project name" value="Launch plan" onSave={(next) => console.log(next)} />API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | – | (Required) The saved value. A new value from outside replaces the text while it is not being edited; bindable. |
onSave | (next: string) => void | Promise<unknown> | – | (Required) Persists the new value. Return a promise to show the saving state, and reject it to roll back. |
label | string | – | (Required) Accessible name, for example “Project name”. |
validate | (next: string) => string | null | undefined | – | Returns a message when the draft cannot be saved. |
placeholder | string | "" | Shown when the value is empty. |
multiline | boolean | false | Wraps onto several lines and grows in height. Enter still saves; Shift+Enter adds a line break. |
variant | "title" | "body" | "title" | title for names and headings, body for descriptions. |
as | "span" | "p" | "h1" | "h2" | "h3" | "span" | The element that holds the text, so a title can stay a heading. |
Keyboard Interactions
| Key | Action |
|---|---|
Enter | Saves the draft. With multiline, Shift+Enter adds a line break instead. |
Escape | Cancels editing and rolls the text back. |
Tab | Moves focus to the interactive element. |
Accessibility
- The display is a real button labeled with the value, with hints for both modes exposed as screen reader copy.
- Validation and failed-save messages render in a polite live region with a retry action.
- Save, cancel, and status changes announce through a status live region.
Motion
Phase 1 still-port: text swaps, icon springs, the drawn check, frame morph, and message reveal render their static end states; Phase 2 wires the springs without restructuring.
Notes for AI
- Click-to-edit text with optimistic save. Reject onSave's promise to roll back to the last saved value.
- Validate drafts with validate; leaving the component saves like a rename, switching windows does not.
- Use multiline + body variant for descriptions; keep as matched to the surrounding semantics.
Source of truth: registry/components/inline-edit/inline-edit.tsx