docs(frontend): add design token and theme-scope guidance

This commit is contained in:
nrslib 2026-02-12 10:22:26 +09:00
parent 680f0a6df5
commit 0c9d7658f8
2 changed files with 96 additions and 0 deletions

View File

@ -224,6 +224,54 @@ Signs to make separate components:
- Added variant is clearly different from original component's purpose
- Props specification becomes complex on the usage side
### Theme Differences and Design Tokens
When you need different visuals with the same functional components, manage it with design tokens + theme scope.
Principles:
- Define color, spacing, radius, shadow, and typography as tokens (CSS variables)
- Apply role/page-specific differences by overriding tokens in a theme scope (e.g. `.consumer-theme`, `.admin-theme`)
- Do not hardcode hex colors (`#xxxxxx`) in feature components
- Keep logic differences (API/state) separate from visual differences (tokens)
```css
/* tokens.css */
:root {
--color-bg-page: #f3f4f6;
--color-surface: #ffffff;
--color-text-primary: #1f2937;
--color-border: #d1d5db;
--color-accent: #2563eb;
}
.consumer-theme {
--color-bg-page: #f7f8fa;
--color-accent: #4daca1;
}
```
```tsx
// same component, different look by scope
<div className="consumer-theme">
<Button variant="primary">Submit</Button>
</div>
```
Operational rules:
- Implement shared UI primitives (Button/Card/Input/Tabs) using tokens only
- In feature views, use theme-common utility classes (e.g. `surface`, `title`, `chip`) to avoid duplicated styling logic
- For a new theme, follow: "add tokens -> override by scope -> reuse existing components"
Review checklist:
- No copy-pasted hardcoded colors/spacings
- No duplicated components per theme for the same UI behavior
- No API/state-management changes made solely for visual adjustments
Anti-patterns:
- Creating `ButtonConsumer`, `ButtonAdmin` for styling only
- Hardcoding colors in each feature component
- Changing response shaping logic when only the theme changed
## Abstraction Level Evaluation
**Conditional branch bloat detection:**

View File

@ -369,6 +369,54 @@ export function StepperButton(props) {
- 追加したvariantが元のコンポーネントの用途と明らかに違う
- 使う側のprops指定が複雑になる
### テーマ差分とデザイントークン
同じ機能コンポーネントを再利用しつつ見た目だけ変える場合は、デザイントークン + テーマスコープで管理する。
原則:
- 色・余白・角丸・影・タイポをトークンCSS Variablesとして定義する
- 画面/ロール別の差分はテーマスコープ(例: `.consumer-theme`, `.admin-theme`)で上書きする
- コンポーネント内に16進カラー値`#xxxxxx`)を直書きしない
- ロジック差分API・状態管理と見た目差分トークンを混在させない
```css
/* tokens.css */
:root {
--color-bg-page: #f3f4f6;
--color-surface: #ffffff;
--color-text-primary: #1f2937;
--color-border: #d1d5db;
--color-accent: #2563eb;
}
.consumer-theme {
--color-bg-page: #f7f8fa;
--color-accent: #4daca1;
}
```
```tsx
// same component, different look by scope
<div className="consumer-theme">
<Button variant="primary">Submit</Button>
</div>
```
運用ルール:
- 共通UIButton/Card/Input/Tabsはトークン参照のみで実装する
- feature側はテーマ共通クラス例: `surface`, `title`, `chip`)を利用し、装飾ロジックを重複させない
- 追加テーマ実装時は「トークン追加 → スコープ上書き → 既存コンポーネント流用」の順で進める
レビュー観点:
- 直書き色・直書き余白のコピペがないか
- 同一UIパターンがテーマごとに別コンポーネント化されていないか
- 見た目変更のためにデータ取得/状態管理が改変されていないか
NG例:
- 見た目差分のために `ButtonConsumer`, `ButtonAdmin` を乱立
- featureコンポーネントごとに色を直書き
- テーマ切り替えのたびにAPIレスポンス整形ロジックを変更
## 抽象化レベルの評価
### 条件分岐の肥大化検出