跳至主要内容
💬 回報這一頁

EditableField 唯讀逐欄編輯

預設是唯讀,點一下才變成輸入框。

Storybook:單一欄位 互動 playground——可切九種欄位型別

為什麼順序要反過來

後台主檔表單的使用者,90% 的時間在「看」,只有 10% 在「改」。 一整片輸入框有兩個問題:

  1. 分不清「哪些是我改過的」——所有欄位長得一模一樣
  2. 很容易誤觸改壞資料——尤其是滑鼠滾輪掃過數字欄

唯讀優先解決了這兩件事,代價是多一次點擊。這個交易在主檔表單是划算的。

點一下值就能編輯
已變更

改過的欄位會標成琥珀色,並出現還原鈕。

U-1042

支援的欄位型態

kind編輯態
text / date輸入框
number / money / rate右對齊數字輸入
select下拉(點擊即自動展開)
radio / checkboxSegGroup 分段選擇
multiselectChips 標籤片

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 可用)。 沒有這個線索,使用者不會知道這格可以點。

鎖定態

disabledlockHint。三個細節:

  • 顯示鎖頭圖示(不只是變灰)
  • 仍然可以聚焦——螢幕報讀器要唸得到「為什麼不能改」
  • 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

延伸閱讀:模式 → 唯讀逐欄編輯