EditableField 唯讀逐欄編輯
預設是唯讀,點一下才變成輸入框。
Storybook:單一欄位 互動 playground——可切九種欄位型別為什麼順序要反過來
後台主檔表單的使用者,90% 的時間在「看」,只有 10% 在「改」。 一整片輸入框有兩個問題:
- 分不清「哪些是我改過的」——所有欄位長得一模一樣
- 很容易誤觸改壞資料——尤其是滑鼠滾輪掃過數字欄
唯讀優先解決了這兩件事,代價是多一次點擊。這個交易在主檔表單是划算的。
改過的欄位會標成琥珀色,並出現還原鈕。
支援的欄位型態
kind | 編輯態 |
|---|---|
text / date | 輸入框 |
number / money / rate | 右對齊數字輸入 |
select | 下拉(點擊即自動展開) |
radio / checkbox | SegGroup 分段選擇 |
multiselect | Chips 標籤片 |
rate 欄位對使用者說的是「%」,存的是比值——輸入時 ×100、送出時 ÷100。
別讓使用者自己去換算,那是每個系統都會被回報一次的 bug。
數值的三條顯示規則
number / money / rate 三種型態在唯讀態的呈現有三條規則。
它們都是可以自己想出別種做法的地方——所以必須寫下來,否則各專案會各長一套。
1. 千分位、等寬數字、右對齊
三者一起才有意義:右對齊讓位數對齊,等寬數字讓每一位的寬度一致, 千分位讓人不必數零。少任何一項,一整欄金額就沒辦法用眼睛比大小。
2. 顯示不四捨五入
存的是多少就顯示多少。168.5 顯示 168.5。
不要為了版面整齊而在顯示時四捨五入。使用者會拿畫面上的數字去核對別的系統, 對不起來的時候他不會懷疑是「顯示」的問題——他會懷疑資料錯了,然後開一張單。
真的需要進位,在資料層做,而且要讓使用者知道進位規則。 「畫面顯示一套、實際存另一套」是資料不信任感的起點。
3. 負值用會計括號 + 紅字
money 型態的負值顯示成 ($2,000) 而不是 -$2,000。
理由不是傳統,是掃視速度:負號只有幾個像素寬,在一整欄數字裡幾乎看不見, 而括號會改變整個數字的輪廓,掃過去就抓得到。紅字是第二條線索, 在灰階列印時括號仍然有效——顏色永遠不是唯一線索。
(number 型態不套會計括號:它可能是溫度、差異值、座標,負值是正常的一種值,
不需要被特別標記。這個差別是刻意的。)
unit 是顯示層的事,不進值裡
<EditableField label="總重量" kind="number" value={168.5} unit="kg" … />
唯讀態顯示 168.5 kg,編輯態只有 168.5。
單位用 unit prop。值本身永遠是純數字。
不要把單位塞進值裡("168.5 kg")。那一刻起這個欄位就不能排序、
不能加總、不能比大小,而且總有一天會有人存成 "168.5kg"(沒有空格)。
編輯態不顯示單位,是為了不讓使用者以為自己要連單位一起打。
已改動未送出=琥珀
值 ≠ 原值時整欄標琥珀(邊框+底色+文字+「已變更」標籤)。 這個顏色是保留色,不做別的用途。
undo / redo 都會先確認
顯示「舊值 → 新值」,確認才執行。
還原前先問一次。「還原」本身也是一次資料變更。
不要做一鍵無聲還原。它跟一鍵無聲改壞一樣危險, 而且使用者按下去之後沒有任何線索知道剛剛發生了什麼。
可發現性:低調的鉛筆
唯讀態右側有一個很淡的鉛筆圖示,hover 加深;觸控裝置上恆微顯(沒有 hover 可用)。 沒有這個線索,使用者不會知道這格可以點。
鎖定態
disabled + lockHint。三個細節:
- 顯示鎖頭圖示(不只是變灰)
- 仍然可以聚焦——螢幕報讀器要唸得到「為什麼不能改」
aria-label帶上鎖定原因
搭配硬鎖定模式使用。
欄位撐不撐得住極端值
設定表單的欄寬通常是固定的(響應式 grid 的一格,約 288px)。 以下是實際塞進極端值後的行為,這些是規格,不是實作細節:
| 極端情況 | 行為 |
|---|---|
| 超長文字值 | 唯讀態截斷 + Tooltip 顯示完整;編輯態正常水平捲動。不換行——換行會讓表單裡每一列的高度不一致 |
| 超長欄位標籤 | 標籤換行,欄位本身不變形。標籤是給人讀的,可以佔兩行 |
| 13 位數金額 | 千分位照樣分組,容器水平捲動。不縮小字級——同一列裡有兩種字級比捲動更難讀 |
| 多選 24 個選項 | 標籤片區塊自動換行成多列,欄位變高。這是對的:使用者需要看到自己選了什麼 |
| 單選 6 個長標籤 | 分段列換行。此時應該改用 select——SegGroup 換行就失去「一眼看完」的意義 |
把最長的真實資料放進最窄的欄位裡試一次。
不要只用示範資料驗收。示範資料的名稱永遠剛好三四個字, 而真實資料裡一定有一筆是二十個字的。
新增模式
<EditableField alwaysEdit trackChanges={false} … />
恆為輸入態,且不會把整張表單標成「已變更」(新增時每個欄位都「不同於原值」, 不關掉的話整張表都是琥珀色,訊號完全失效)。
取用
npx shadcn@latest add https://kielchang.github.io/dooping-design-book/r/editable-field.json
延伸閱讀:模式 → 唯讀逐欄編輯