Inline edit

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

inline editrenameclick to edit
Preview
Inline edit preview
Activate to edit.Enter saves, Escape cancels.

Click the title to edit it in place.

When to use

  • Titles and descriptions read far more often than edited, like a project name.
  • Single fields that save on their own with optimistic updates and rollback.

When not to use

  • Use input or textarea in a form when several fields save together.
  • Use input when the field should always look editable.

shadcn CLI

Also installs (1)

  • manicat-foundation
Manual install(+)
registry.jsonjson
{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "inline-edit",
  "type": "registry:ui",
  "title": "Inline edit",
  "description": "Rename in place: the text becomes a field without moving.",
  "categories": [
    "inputs"
  ],
  "dependencies": [
    "lucide-react",
    "motion"
  ],
  "registryDependencies": [
    "https://manicat.viraza.net/r/manicat-foundation.json"
  ],
  "files": [
    {
      "path": "registry/components/inline-edit/inline-edit.tsx",
      "type": "registry:component",
      "target": "@components/manicat/inline-edit/inline-edit.tsx"
    },
    {
      "path": "registry/components/inline-edit/inline-edit.module.css",
      "type": "registry:component",
      "target": "@components/manicat/inline-edit/inline-edit.module.css"
    }
  ],
  "docs": "Docs and live preview: https://uiarc.dev/components/inline-edit",
  "meta": {
    "tier": "free",
    "kind": "component",
    "docs": "https://manicat.viraza.net/components/inline-edit",
    "markdown": "https://uiarc.dev/components/inline-edit/markdown",
    "tags": [
      "inline edit",
      "rename",
      "click to edit"
    ]
  }
}

Usage

Install the component, then copy this into your app. Change the content and the props to fit your screen.

example.tsxtsx
"use client";

import { useState } from "react";
import { InlineEdit } from "@/components/manicat/inline-edit/inline-edit";

export function InlineEditExample() {
  const [title, setTitle] = useState("Quarterly plan");

  return (
    <div className="rounded-[var(--radius-panel)] border border-(color:--border) p-6 text-center">
      <InlineEdit value={title} onSave={setTitle} label="Title" />
      <p className="mt-2 text-sm text-(color:--text-muted)">Click the title to edit it in place.</p>
    </div>
  );
}

Examples

Real screens rather than isolated props. Switch to Code to copy a whole example into your project.

Editable title A document title that edits in place and saves on Enter or blur.

Editable title A document title that edits in place and saves on Enter or blur. preview

Document

Activate to edit.Enter saves, Escape cancels.

Keyboard interactions

KeysAction
Enter / SpaceOn the text, starts editing.
EnterSaves the draft. In multiline mode, Shift+Enter inserts a line break.
EscapeCancels and rolls the text back.
TabLeaving the component saves, the way a rename does.

Accessibility

  • The resting text is a native button labelled "<label>: <value>", so it is focusable and announced as editable.
  • The field has aria-label and aria-invalid; validation and save errors render in a polite live region linked through aria-describedby.
  • Save progress and results are announced through a role="status" region; save and cancel buttons are labelled.

Motion

  • Text rolls between values, a check draws once a save lands, and multiline boxes follow their height; failed saves roll back with motion.
  • Reduced motion crossfades text, draws the check instantly, and replaces the spinner with a static mark.

Responsive behavior

  • Text wraps within the column and reserves 66px at the end for the save and cancel buttons.
  • With multiline the box grows in height as the text wraps.
  • Hover hints apply only on fine pointers; on touch a tap starts editing.

Performance

  • Two ResizeObservers size the frame; sizes are measured in a layout effect, so no frame shows a wrong width.

Notes for AI

  • Use for single fields read far more often than edited, like titles and descriptions. Use a regular form with input or textarea when several fields save together.
  • value is controlled by the saved data; update it after onSave resolves. Return a promise from onSave to get saving, saved, and failed states.
  • Exported as both named and default.