Gantt 時間軸
檢視與選取用的精簡時間軸:左欄項目、右欄長條,加上刻度、格線與今天線。 定位刻意窄——它回答「哪些項目在什麼期間、進行到哪」,不做拖拉排程。
時間軸:分類色長條、進度、列選取在 Storybook 開啟
何時不要用
- 要拖拉改期、要相依線(前置後續)、要週期規則——那是排程編輯器,不是這支。 評估過現成的 ReUI Gantt(MIT):功能完整,但 9 檔 325KB、需要 5 個本書沒有的元件 與 3 個新 npm 相依。依三次法則,等「編輯型時間軸」真的被用過三次再收, 不為了可能性先揹 40% 的元件數。
- 超過一兩百列——這支逐列渲染,沒有虛擬捲動。列多先分組或分頁。
- 只是要顯示一個日期區間——用文字。時間軸的成本是一整塊畫面, 兩三筆資料撐不起這個成本。
改期怎麼做
選中一列之後,用旁邊的表單改日期——與逐欄編輯同一個模式: 改動標琥珀、送出前看變更摘要。 拖拉排程直觀,但它把「改資料」藏進一個沒有確認步驟的手勢裡; 後台系統的日期變更通常需要留痕與覆核,表單路徑天然滿足這些。
色彩:每一層吃什麼
| 元素 | 吃什麼 | 為什麼 |
|---|---|---|
| 長條 | --chart-N(category 1–8) | 顏色編類別不編狀態——甲案在時間軸、圖表、畫布上永遠同色(配色策略) |
| 進度 | 未完成段蓋 --background/45% | 實色=已完成、淡段=剩餘。不換色相,對任何分類色與深淺模式都成立 |
| 今天線 | --foreground/50%(中性) | 結構標記不吃狀態色(ADR-0007)——用 info 藍會被讀成「這裡有提示」 |
| 列互動 | state-layer 6%/14%/20% | 與資料表列完全同一套 |
✅ 這樣做
延誤、待補件這類狀態走獨立通道:列尾放狀態徽章,或左欄加圖示。
🚫 不要這樣
不要把長條染紅表達延誤。長條顏色一旦身兼狀態,「這一類是紅色」與「這一筆出事了」 就分不開;而且紅色面積是有預算的——保留給真正的警報。
狀態
| 狀態 | 表現 |
|---|---|
| hover | 狀態層 6%(整列,含左欄與時間軸) |
| pressed | 狀態層 14% |
| 已選 | 狀態層 20%;次要文字換回正文色(20% 疊加下 --muted-foreground 會低於 4.5:1) |
| focus-visible | 2px 聚焦環+2px 偏移(列是 <button>,只在有 onSelect 時) |
刻度與粒度
跨度 ≤21 天出日刻度、≤120 天出週一刻度、更長出月初刻度。 刻意不做縮放切換——檢視用的時間軸,粒度自動選對就好;要縮放的是編輯器。
視窗省略時由資料推導,前後各留 5% 邊距。今天線只在落於視窗內時出現。
無障礙
- 有
onSelect時每列是真的<button>:Tab 可及、aria-pressed表達選取。 - 每列的
aria-label含完整資訊:名稱,起 到 迄,進度 n%—— 讀屏使用者不需要解讀長條的幾何位置。 - 顏色永遠不是唯一線索:分類靠左欄文字、進度有數字可讀、狀態靠徽章文字。
取用
npx shadcn add https://kielchang.github.io/dooping-design-book/r/gantt.json
零外部相依(只吃 @dooping/tokens 的變數)。列互動需要 tokens ≥ 0.6.0 的
.state-layer。