ADR-0008:頁面章收組成規範與組合 story,不收外殼元件
- 狀態:已採用
- 日期:2026-08
背景
文件站原本的尺度階梯是:基礎(token)→ 元件(單一控制項)→ 模式(跨元件的操作邏輯) → 站台資訊架構(側邊欄與導覽)。中間缺了一階:一整頁怎麼組。
缺這一階的代價由取用端付:每個系統的清單頁、表單頁各自長各自的樣子, 主要動作的位置、錯誤的擺法、儲存回饋的去向都不一致, 使用者每換一套系統就要重學一次。而元件章明文把 Layout、Sidebar、 「綁定業務流程的複合畫面」排除在收錄範圍外——排除是對的, 但排除之後,頁面層的規範就沒有家了。
新開的「頁面」章要補這一階,第一個問題是:它收什麼、以什麼形式存在?
選項
| 選項 | 說明 |
|---|---|
| A. 純文件 | 只寫規範與示意圖,不附可執行的組合範例 |
| B. 文件+組合 story | 規範照寫,另以現有元件組出各頁型的「典型組成」story 當活證據 |
| C. 文件+story+頁面級元件與 registry item | 再把 AppShell、PageHeader 等做成元件發佈 |
決定
採 B:頁面章收「頁型組成規範」與「組合 story」,不收外殼元件、 不發任何頁面級 registry item。
具體邊界:
packages/react/src/pages/只准放.stories.tsx。 build-registry 的掃描與 CI 版號守衛都以 stories 為排除界線—— 放進非 stories 的.tsx會被當成一般元件收進 registry (而且 rewrite 不認pages/的相對匯入,產出的 item 是壞的), 並觸發版號守衛。- 頁面章的行為規範對應的 story 是各頁型的「典型組成」; 行為級的規範證據仍由各元件自己的 story 承擔,頁面 story 不重複。 (「文件寫下的每條行為規範都要有一支 story 對得上」適用於元件層的行為, 不是要求頁面層為每條版面規則各開一支 story。)
- 組頁時遇到的缺件(Toast、Switch、PageHeader…)在頁面章列表並給替代方案; 要成為正式元件一律走 RFC + 三次法則,不隨頁面章夾帶。
理由
- 頁面天生是宿主的。 頁面綁路由、綁資料抓取、綁權限—— 全是邊界守衛禁止進元件庫的東西。把頁面做成可安裝的元件, 等於把應用層的決定硬塞進設計系統,每個宿主裝完都要先拆一半。
- 組合 story 讓規範可驗收,而且零發佈成本。 stories 不進 barrel、 不進 registry、不 bump 版號;但「用現有元件組得出這種頁」從此是 被 CI 驗證的事實,不是文件的宣稱。
- 選項 A 的示意圖會退化成裝飾。 沒有活範例的版面規範, 三個月後就沒有人知道它跟現實的差距有多大——零截圖鐵律在頁面層同樣適用。
- 選項 C 被否決的關鍵是三次法則。 AppShell 與 PageHeader 目前只有 「應該會有用」的推測,沒有三個實際宿主的重複需求; 投機性抽象是設計系統腐爛的第一步(收錄三原則的原文)。 Sidebar 則永遠不收——導覽層的正本是模式章的資訊架構那一頁。
影響
- 文件站多一章(
/pages),Storybook 多一個「頁面/」頂層分類; registry 與 npm 套件完全不變。 - 取用端得到的是「怎麼組」的規範與範例,程式碼仍然自己寫—— 與模式章同一種取用方式(AGENTS.md 三層表的第三層)。
- 未來若某個頁面骨架元件真的過了三次法則(例如 PageHeader 被三個宿主 重複手排),它走 RFC 進元件章,頁面章只更新組成對照表—— 頁面章永遠不是元件的發佈通道。
pages/目錄的「只准 stories」是規約而非守衛;若發現被誤用 (有人放了非 stories 檔),優先補一條 boundary 測試把規約變成守衛。