motif svelteArc

Inline edit ported

Rename in place: the text becomes a field without moving.

Rename in place: the text becomes a field without moving.

Live specimen

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.

Installation

pnpm add sveltearc

Usage

<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

PropTypeDefaultDescription
valuestring–(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.
labelstring–(Required) Accessible name, for example “Project name”.
validate(next: string) => string | null | undefined–Returns a message when the draft cannot be saved.
placeholderstring""Shown when the value is empty.
multilinebooleanfalseWraps 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

KeyAction
EnterSaves the draft. With multiline, Shift+Enter adds a line break instead.
EscapeCancels editing and rolls the text back.
TabMoves 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