Inline Edit Field
點擊即編輯的行內欄位:顯示態與編輯態以 layout morph 無縫互換,Enter/失焦提交、Esc 取消,支援多行、受控/非受控雙模式,IME 組字中不誤觸提交。
載入預覽⋯
Playground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
<InlineEditField />
安裝
npx shadcn@latest add https://webberui.com/r/inline-edit-field.json或在 components.json 設定 registries 後,改用 @webberui/inline-edit-field 安裝。
安裝依賴後,從 registry JSON(/r/inline-edit-field.json 的 files[0].content)複製 inline-edit-field.tsx 原始碼到你的 components/ui/ 目錄:
npm install motion lucide-react clsx tailwind-merge使用
import { InlineEditField } from "@/components/ui/inline-edit-field";
<InlineEditField
value={title}
onValueChange={setTitle}
placeholder="未命名活動"
aria-label="活動標題"
/>未提供 value 時由元件內部管理狀態(非受控),可用 defaultValue 給初始值;提供 value 搭配 onValueChange 則為受控模式。onValueChange 只在「提交」時觸發(Enter、失焦或按 ✓),不會在每次按鍵時觸發。
多行模式:
<InlineEditField
multiline
maxRows={5}
variant="outline"
defaultValue="加一段簡介⋯"
/>Props
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
value | string | — | 受控值;未提供時由元件內部管理 |
defaultValue | string | "" | 非受控模式的初始值 |
onValueChange | (value: string) => void | — | 提交(Enter/失焦/按 ✓)時觸發,帶入最新值 |
onEditingChange | (editing: boolean) => void | — | 編輯狀態切換時觸發 |
placeholder | string | "點擊編輯⋯" | 空值顯示文字,同時作為輸入提示 |
multiline | boolean | false | 使用多行 textarea(Enter 換行、⌘/Ctrl+Enter 提交) |
maxRows | number | 6 | 多行模式最大行數,超過後於輸入框內捲動 |
disabled | boolean | false | 停用:僅唯讀顯示,不可進入編輯 |
submitOnBlur | boolean | true | 失焦時是否提交;false 則失焦視為取消 |
selectOnEdit | boolean | true | 進入編輯時是否全選既有文字 |
showActions | boolean | true | 編輯時是否顯示 ✓/✕ 動作鈕 |
variant | "ghost" | "outline" | "ghost" | 顯示樣式:ghost(懸浮/聚焦才有底色)或 outline(常駐邊框) |
aria-label | string | — | 無障礙標籤,未提供時退回 placeholder |
className | string | — | 附加到最外層容器 |
inputClassName | string | — | 附加到輸入元素(input/textarea) |
細節
- 點擊即編輯:顯示態是一顆與文字同位置、同字級的按鈕,點擊(或 Tab 聚焦後按 Enter/Space)即切換為輸入框;懸浮時右側浮現鉛筆圖示提示可編輯
- 無縫 morph:顯示鈕與編輯區以
AnimatePresence mode="popLayout"交叉淡入淡出,外層容器帶layout以 spring 平滑補足尺寸差,文字維持在原位不跳動;編輯態的邊框、底色與 focus ring 以 CSS 過渡淡入 - 提交與取消:單行按 Enter 提交、Esc 取消、失焦預設提交(
submitOnBlur);多行則 Enter 換行、⌘/Ctrl+Enter 提交、Esc 取消。值未變更時不觸發onValueChange - 動作鈕不搶跑:✓/✕ 以
onMouseDown阻擋預設行為保留輸入框焦點,避免點擊時先觸發失焦提交造成競態 - 多行自動增高:
multiline依內容增高,超過maxRows後於框內捲動(沿用 textarea 自動 resize) - IME 安全:中文等輸入法組字中按 Enter 不會誤觸提交(同時檢查
isComposing與keyCode !== 229,涵蓋 Safari 於compositionend後才發 keydown 的情形)
可及性
- 使用者系統開啟「減少動態效果」時,morph 動畫全部停用,顯示/編輯直接切換(首次渲染與 SSR 一致,掛載後才停用)
- 顯示態為原生
<button>,帶描述值的aria-label,可 Tab 循序聚焦、focus-visible顯示外框 - 輸入框帶
aria-label(未提供時退回placeholder) - 由鍵盤或動作鈕結束編輯時,焦點會還給顯示鈕;因失焦而結束時則不搶回焦點,不干擾使用者實際點擊的目標
- ✓/✕ 為原生
<button>,各帶「確認」「取消」的aria-label