ksk-design-system 1.48.3 → 1.49.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +182 -11
- package/CLAUDE.md +186 -22
- package/DESIGN.md +106 -15
- package/MIGRATION.md +34 -0
- package/PUBLISHING.md +95 -28
- package/README.md +8 -2
- package/RELEASE.md +47 -8
- package/UPDATING.md +59 -1
- package/bin/check-duplicates.js +1 -0
- package/contracts/components.json +29 -15
- package/contracts/composition.json +5 -1
- package/contracts/rules.json +79 -14
- package/contracts/screen-patterns.json +5 -5
- package/contracts/token-hex-cache.json +16 -97
- package/dist/class-names.js +1 -1
- package/dist/index.js +1999 -1874
- package/dist/native/ui.js +48 -35
- package/dist/{native-BYLnbCN-.js → native-VkkXnB0e.js} +133 -260
- package/dist/native.js +1 -1
- package/dist/{server-variants-DF8guEvD.js → server-variants-usol4GK5.js} +3 -3
- package/dist/types/components/patterns/admin/data-table.d.ts +19 -8
- package/dist/types/components/patterns/bottom-sheet-frame.d.ts +5 -2
- package/dist/types/components/patterns/keyboard-aware-sheet-footer.d.ts +5 -2
- package/dist/types/components/patterns/mobile-app-header.d.ts +10 -2
- package/dist/types/components/patterns/sheet-surface.d.ts +4 -0
- package/dist/types/components/patterns/shells/admin-shell.d.ts +31 -0
- package/dist/types/components/patterns/side-drawer-frame.d.ts +5 -2
- package/dist/types/components/ui/alert-dialog.d.ts +1 -1
- package/dist/types/components/ui/icon-badge.d.ts +1 -1
- package/dist/types/components/ui/pill-toggle.d.ts +30 -3
- package/dist/types/components/ui/popover.d.ts +1 -1
- package/dist/types/components/ui/progress-ring.d.ts +10 -2
- package/dist/types/components/ui/progress.d.ts +1 -1
- package/dist/types/components/ui/sheet.d.ts +1 -1
- package/dist/types/components/ui/slider.d.ts +15 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/lib/layer-coordination.d.ts +4 -0
- package/dist/types/lib/server-variants/button-variants.d.ts +1 -1
- package/dist/types/lib/utils.d.ts +26 -0
- package/dist/types/native/components/BottomSheetFrame.d.ts +3 -1
- package/dist/types/native/components/KeyboardAwareSheetFooter.d.ts +3 -1
- package/dist/types/native/components/index.d.ts +1 -1
- package/dist/types/tokens/native/scales.d.ts +0 -1
- package/dist/types/tokens/native/themes.d.ts +78 -204
- package/eslint/icon-button-aria-label.js +101 -0
- package/package.json +17 -4
- package/src/components/COMPONENT_LOOKUP.md +28 -26
- package/src/preset.css +96 -6
- package/src/styles/glass.css +5 -1
- package/src/styles/motion.css +86 -0
- package/src/styles/semantic.css +18 -33
- package/src/styles/source-safelist.css +1031 -0
- package/templates/AGENTS.md +2 -0
- package/templates/CLAUDE.md +2 -0
- package/tokens.json +27 -49
package/AGENTS.md
CHANGED
|
@@ -1,5 +1,46 @@
|
|
|
1
1
|
# KSK Design System — 設計ルールブック(Codex向け)
|
|
2
2
|
|
|
3
|
+
## CLAUDE.md / AGENTS.md の編集ルール
|
|
4
|
+
|
|
5
|
+
<!-- docs-sync-ignore -->
|
|
6
|
+
このファイルと `CLAUDE.md` は Claude Code 用 / Codex 用の対になる作業手順書で、
|
|
7
|
+
共通で守るべき内容(実装前セルフチェック・セッション開始時に読み込むファイル・
|
|
8
|
+
ローカル二重実装ゲート・このDSについて・最大の特徴・技術スタック・AIモデルの
|
|
9
|
+
使い分け方針・ドキュメント構成・ディレクトリ構成・カラートークン体系・
|
|
10
|
+
クイックスタート・コンポーネント追加時のチェックリスト)は**両ファイルで内容を
|
|
11
|
+
同期させる**こと。
|
|
12
|
+
|
|
13
|
+
- 見出し名・本文は基本的に同一にする(ツール名など明確にツール固有の1行だけ
|
|
14
|
+
<!-- docs-sync-ignore --> マーカー(単独行、次の1行を対象から除外)で除外する)
|
|
15
|
+
- Codex 固有の付録(AGENTS.md 末尾の Codex PR Review Guidelines)のような
|
|
16
|
+
完全にツール固有のブロックは BEGIN/END マーカーコメント(例:
|
|
17
|
+
末尾が `codex-pr-review-guidelines` のマーカー)で囲み同期対象から除外する
|
|
18
|
+
- 片方だけ編集したら **`node scripts/check-agents-docs-sync.mjs`**(`npm run check` に
|
|
19
|
+
組み込み済み)を実行し、乖離が無いことを確認する
|
|
20
|
+
- `templates/CLAUDE.md` / `templates/AGENTS.md`(postinstall で配布するテンプレート)も
|
|
21
|
+
同じ仕組みで同期検査の対象
|
|
22
|
+
|
|
23
|
+
## 実装前セルフチェック(AI必読・最優先)
|
|
24
|
+
|
|
25
|
+
UI を書く前に必ず確認すること:
|
|
26
|
+
|
|
27
|
+
- [ ] 画面の骨格は `contracts/screen-patterns.json` の decisionTree で選んだか
|
|
28
|
+
- [ ] 既存コンポーネントを `src/components/COMPONENT_LOOKUP.md` で確認したか(手書き・再定義は禁止)
|
|
29
|
+
- [ ] 色は semantic token(`var(--Surface-*)` / `var(--Brand-Primary)` 等)か。Tailwind標準色・生 `#hex` は禁止
|
|
30
|
+
- [ ] `border` は色を併記したか(`border-[var(--Border-Low-Emphasis)]` 等)。Tailwind v4 では無色 border は currentColor になり、消費側の濃色テキストで黒ずむ(preset.css の base layer が保険だが明示が原則)
|
|
31
|
+
- [ ] **文脈非依存**か(テキスト要素に `text-[var(--Text-*)]`、サーフェス/オーバーレイに `bg-[var(--Surface-*)]` を明示)。親の継承や currentColor に頼ると消費側の色文脈で崩れる。Storybook ツールバーの **Hostile ctx** を loud にして、文字/アイコンがマゼンタ化・背景が透けないか確認する
|
|
32
|
+
- [ ] typography は `typo-*` クラスか(`font-bold` 等の直書きは禁止)
|
|
33
|
+
- [ ] アニメーションは `duration-[var(--Motion-Duration-*)]` / `ease-[var(--Motion-Easing-*)]` か(`duration-200` や生 `cubic-bezier` の直書きは禁止。トークン参照でないと `prefers-reduced-motion` の一括制御から漏れる)
|
|
34
|
+
- [ ] 重なり順は `z-[var(--Z-*)]` か(`z-50` 一律だと Portal のマウント順で勝敗が決まる。`z-10` / `z-20` のコンポーネント内部の重なりは対象外。順序は DESIGN.md の Layering 節)
|
|
35
|
+
- [ ] アイコンは `iconsax-reactjs` か(`lucide-react` / `heroicons` は使わない)
|
|
36
|
+
- [ ] 生タグ(`<button>` / `<input>` / `<a href>`)でなく DS コンポーネントを使ったか
|
|
37
|
+
- [ ] CSS でベンダープレフィックス併記する場合、**`-webkit-` を先・標準形を後**に書いたか(消費側の minifier が同一プロパティとして dedupe し後勝ちのみ残すため。逆順だと Firefox で静かに無効化。`node scripts/check-prefix-order.mjs` が CI で検出)
|
|
38
|
+
- [ ] クラス名は**完全な文字列**で書いたか(`` `bg-${color}` `` のような動的合成は静的抽出できず消費側で CSS が生成されない。分岐は三項演算子か cva variant で。`scripts/generate-source-safelist.mjs` が検出)
|
|
39
|
+
- [ ] `.tsx` 編集後に `bash scripts/lint-scratch.sh`、コンポーネント増減時は `npm run check` を実行したか
|
|
40
|
+
- [ ] `FormField` を import する前にどちらか確認したか(react-hook-form の Controller と統合するなら `RhfFormField`=`ui/form` の `FormField` を index.ts で別名 export したもの。単純な label+error 表示は `patterns/form-field` の `FormField`。迷ったら後者)
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
3
44
|
## このDSについて
|
|
4
45
|
|
|
5
46
|
**KSK Design System** は、フリーランスデザイナー / エンジニア / PdM が **複数クライアント案件を1つのDSで高速に回す** ために設計された統合デザインシステムです。
|
|
@@ -38,6 +79,8 @@ UI コンポーネント・画面の生成/修正・レビューの前には、
|
|
|
38
79
|
|
|
39
80
|
コンポーネントを新規作成する前に `COMPONENT_LOOKUP.md` で同等品がないか確認すること。
|
|
40
81
|
|
|
82
|
+
`FormField` は同名で2種類ある: react-hook-form の Controller と統合するなら `RhfFormField`(`ui/form` の `FormField` を index.ts で別名 export したもの)、単純な label+error 表示なら `FormField`(`patterns/form-field`)。迷ったら後者を使う。
|
|
83
|
+
|
|
41
84
|
### ローカル二重実装ゲート
|
|
42
85
|
|
|
43
86
|
DS に無いと思っても consumer 側に別台帳を作らないこと。最初に `contracts/components.json` と
|
|
@@ -67,13 +110,49 @@ node scripts/check-prefix-order.mjs
|
|
|
67
110
|
minifier が同一プロパティとして dedupe し後勝ちのみ残すため、逆順だと
|
|
68
111
|
標準形が消えて Firefox で静かに無効化される)。
|
|
69
112
|
|
|
113
|
+
**新しい Tailwind クラスを使った後は必ず実行:**
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
npm run generate:safelist
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
DS 内部でしか出現しないクラスを消費側で確実に生成させるための safelist
|
|
120
|
+
(`src/styles/source-safelist.css`・自動生成)を更新する。未更新は
|
|
121
|
+
`npm run check` が検出する。クラス名は必ず完全な文字列で書くこと
|
|
122
|
+
(`` `bg-${color}` `` のような動的合成は静的抽出できず、同スクリプトがエラーにする)。
|
|
123
|
+
|
|
70
124
|
**コンポーネントを追加・削除した後は必ず実行:**
|
|
71
125
|
|
|
72
126
|
```bash
|
|
73
127
|
bash scripts/check-drift.sh
|
|
74
|
-
|
|
128
|
+
npm run generate:lookup
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**play 関数のあるコンポーネントを触った後は必ず実行:**
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
npm run test:interaction
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
対象は Button / Dialog / AlertDialog / Sheet / Select / DropdownMenu /
|
|
138
|
+
Combobox / Tabs / Form / Toast。Storybook の play 関数を playwright chromium で
|
|
139
|
+
ヘッドレス実行する(設定は `vitest.storybook.config.ts`、対象は
|
|
140
|
+
`tags: ["interaction"]` を付けたストーリーのみ)。初回のみ
|
|
141
|
+
`npx playwright install chromium` が必要なため `npm run check` には含まれない。
|
|
142
|
+
CI では常時実行される。
|
|
143
|
+
|
|
144
|
+
**UI コンポーネントを追加・修正した後は `npm run test:a11y` も実行:**
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
npm run test:a11y
|
|
75
148
|
```
|
|
76
149
|
|
|
150
|
+
axe-core による a11y 機械検証(issue #261)。`@storybook/addon-a11y` の
|
|
151
|
+
afterEach フックが全ストーリー(tags フィルタなし)に対して axe-core を
|
|
152
|
+
実行する(設定は `vitest.a11y.config.ts`)。color-contrast ルールも有効
|
|
153
|
+
(AA 未達トークンの darken と opacity 減衰の廃止により全ストーリー通過。
|
|
154
|
+
トークンペアの正本チェックは `scripts/check-contrast.mjs`)。CI では常時実行される。
|
|
155
|
+
|
|
77
156
|
エラーが出た場合は修正してから次に進むこと。
|
|
78
157
|
|
|
79
158
|
---
|
|
@@ -97,41 +176,55 @@ Brand色を差し替え(10行)→ Primitive Layer → Semantic Layer → Bri
|
|
|
97
176
|
|
|
98
177
|
## 技術スタック
|
|
99
178
|
|
|
100
|
-
- React 19 + TypeScript / Vite / **Tailwind CSS v4**(`@import "tailwindcss"`
|
|
179
|
+
- React 19 + TypeScript / Vite / **Tailwind CSS v4**(`@import "tailwindcss"` 構文。`@tailwind base` 等の v3 構文は使わない)
|
|
101
180
|
- shadcn/ui(Radix UI ベース) / CVA(バリアント管理)
|
|
102
|
-
- **iconsax-reactjs
|
|
103
|
-
- Storybook(ドキュメント)
|
|
104
|
-
|
|
105
|
-
> **注意**: Tailwind CSS は v4 です。`@tailwind base` 等の v3 構文は使わないこと。
|
|
181
|
+
- **iconsax-reactjs**(アイコン。`lucide-react` / `heroicons` は使わない) / Storybook(ドキュメント)
|
|
106
182
|
|
|
107
183
|
---
|
|
108
184
|
|
|
109
185
|
## AIモデルの使い分け方針
|
|
110
186
|
|
|
187
|
+
(同一モデルで実装と検証を兼ねない — 同じバイアスを共有し独立検証にならない)
|
|
188
|
+
|
|
189
|
+
### Fable 5 が使えるとき
|
|
190
|
+
|
|
111
191
|
| モデル | 用途 |
|
|
112
192
|
|--------|------|
|
|
113
193
|
| `claude-fable-5` | 最難関の設計・長時間エージェント作業のみ(高コストのため温存) |
|
|
114
194
|
| `claude-opus-4-8` | 通常のUI実装・レビュー・リファクタの既定 |
|
|
115
195
|
|
|
116
|
-
|
|
196
|
+
**検証ループ:** 実装 = Fable 5 / 検証 = Opus 4.8
|
|
117
197
|
|
|
118
198
|
**Fable 5 使用時の注意:**
|
|
119
199
|
- thinking は常時オン(パラメータ省略でデフォルトに任せる)
|
|
120
200
|
- refusal 時は `fallbacks` で Opus 4.8 に自動フォールバック
|
|
121
201
|
- 30日データ保持が必須
|
|
122
202
|
|
|
203
|
+
### Fable 5 が使えないとき(アクセス終了・休止期間)
|
|
204
|
+
|
|
205
|
+
| モデル | 用途 |
|
|
206
|
+
|--------|------|
|
|
207
|
+
| `claude-opus-4-8` | 設計・UI実装・レビュー・リファクタの既定 |
|
|
208
|
+
| `claude-sonnet-5` | 機械的な一括修正・定型作業(トークン節約) |
|
|
209
|
+
|
|
210
|
+
**検証ループ:** 実装 = Opus 4.8 / 検証 = Sonnet 5
|
|
211
|
+
|
|
123
212
|
---
|
|
124
213
|
|
|
125
214
|
## ドキュメント構成
|
|
126
215
|
|
|
127
216
|
| ファイル | 内容 |
|
|
128
217
|
|---------|------|
|
|
129
|
-
|
|
218
|
+
<!-- docs-sync-ignore -->
|
|
219
|
+
| **CLAUDE.md** | 同上(Claude Code用) |
|
|
220
|
+
<!-- docs-sync-ignore -->
|
|
221
|
+
| **AGENTS.md**(本ファイル) | 概要・技術スタック・コマンド・クイックスタート(Codex用。Codex PR Review Guidelines を追記) |
|
|
130
222
|
| **contracts/components.json** | 全コンポーネントの構造化定義(バリアント・アクセシビリティ要件。総数は meta.counts が正本) |
|
|
131
223
|
| **contracts/rules.json** | 禁止パターン・AIアンチパターン・アクセシビリティ要件(正本: rules.json) |
|
|
132
224
|
| **contracts/design-context.json** | `DESIGN.md` の役割・正本ファイル・外部 DESIGN.md 参照方針 |
|
|
133
225
|
| **tokens.json** | カラー・スペーシング・シャドウトークンの機械可読定義 |
|
|
134
|
-
| **
|
|
226
|
+
| **contracts/token-hex-cache.json** | semantic トークンのデフォルトテーマ解決済み hex(テーマ依存キーは meta.themeDependentKeys 参照・自動生成) |
|
|
227
|
+
| **src/components/COMPONENT_LOOKUP.md** | 全コンポーネントのバリアント・インポートパス一覧(自動生成) |
|
|
135
228
|
| **DESIGN.md** | AI エージェント向け視覚言語サマリ(トークン+意図・voice・motion) |
|
|
136
229
|
| **contracts/screen-patterns.json** | 画面実装前にどのシェル/パターンを使うかを決める decisionTree・crudMatrix |
|
|
137
230
|
| **contracts/composition.json** | 選んだパターン内部の並べ方(骨格構造・余白リズム・カード階層・テキスト階層・CTA優先度) |
|
|
@@ -153,7 +246,9 @@ src/
|
|
|
153
246
|
├── styles/
|
|
154
247
|
│ ├── primitive.css # Layer 1: 原色パレット
|
|
155
248
|
│ ├── semantic.css # Layer 2: 用途別トークン
|
|
156
|
-
│
|
|
249
|
+
│ ├── typography.css # typo-* ユーティリティ
|
|
250
|
+
│ ├── motion.css # duration / easing トークン(--Motion-*)
|
|
251
|
+
│ └── source-safelist.css # @source safelist(自動生成・手で編集しない / issue #258)
|
|
157
252
|
├── themes/ # default / orange / green / violet / blue
|
|
158
253
|
├── preset.css # 外部プロジェクト向けプリセット
|
|
159
254
|
└── index.ts # Public API(全コンポーネント)
|
|
@@ -161,6 +256,72 @@ src/
|
|
|
161
256
|
|
|
162
257
|
---
|
|
163
258
|
|
|
259
|
+
## コマンド
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
# 開発サーバー(Storybook)
|
|
263
|
+
npm run storybook
|
|
264
|
+
|
|
265
|
+
# ビルド
|
|
266
|
+
npm run build-storybook
|
|
267
|
+
|
|
268
|
+
# スクラッチ検出(実装後に必ず実行)
|
|
269
|
+
bash scripts/lint-scratch.sh
|
|
270
|
+
|
|
271
|
+
# ドリフト検出(コンポーネント追加後に実行)
|
|
272
|
+
bash scripts/check-drift.sh
|
|
273
|
+
|
|
274
|
+
# COMPONENT_LOOKUP.md 再生成(コンポーネント追加後に実行)
|
|
275
|
+
npm run generate:lookup
|
|
276
|
+
|
|
277
|
+
# DESIGN.md contract 検査
|
|
278
|
+
npm run lint:design
|
|
279
|
+
|
|
280
|
+
# @source safelist 再生成(新しい Tailwind クラスを使ったら実行)
|
|
281
|
+
npm run generate:safelist
|
|
282
|
+
|
|
283
|
+
# 全チェック(tsc + lint + drift + lookup + safelist 一括)
|
|
284
|
+
npm run check
|
|
285
|
+
|
|
286
|
+
# interaction テスト(Storybook play 関数を playwright chromium で実行)
|
|
287
|
+
npm run test:interaction
|
|
288
|
+
|
|
289
|
+
# a11y 機械検証(axe-core。全ストーリー対象。issue #261)
|
|
290
|
+
npm run test:a11y
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
**interaction テストについて(issue #256):**
|
|
294
|
+
|
|
295
|
+
- 実体は Storybook の play 関数。`@storybook/addon-vitest` + vitest browser mode(playwright chromium)で
|
|
296
|
+
ヘッドレス実行する。設定は `vitest.storybook.config.ts`。
|
|
297
|
+
- 対象は `tags: ["interaction"]` を付けたストーリーだけ(全ストーリーのスモークはしない)。
|
|
298
|
+
- 初回のみ `npx playwright install chromium` が必要。**この前提があるため `npm run check` /
|
|
299
|
+
`check:agent` には含めていない**(CI と、下記に該当する変更をしたときに手で回す)。
|
|
300
|
+
- 押下でレイアウトが沈む・入場アニメーション中に操作不能・フォーカストラップ崩れ、といった
|
|
301
|
+
v1.48.x で連続した種類の不具合をここで落とす。
|
|
302
|
+
- **play 関数のあるコンポーネント(Button / Dialog / AlertDialog / Sheet / Select /
|
|
303
|
+
DropdownMenu / Combobox / Tabs / Form / Toast)を触ったら `npm run test:interaction` を回すこと。**
|
|
304
|
+
- ビジュアル回帰(スクリーンショット差分)は未導入。`.claude/skills/audit-pages/SKILL.md` による
|
|
305
|
+
手動の視覚監査が現状の代替。
|
|
306
|
+
|
|
307
|
+
**a11y 機械検証について(issue #261):**
|
|
308
|
+
|
|
309
|
+
- `@storybook/addon-a11y` の afterEach フック(axe-core)が全ストーリー(tags フィルタなし)に
|
|
310
|
+
対して実行される。設定は `vitest.a11y.config.ts`、実行は `npm run test:a11y`。CI では常時実行。
|
|
311
|
+
- color-contrast ルールも有効(全ストーリー対象)。当初はトークン債務のため無効化していたが、
|
|
312
|
+
AA 未達トークンの darken(Success/Warning-Base・Text-Caution/Warning・Text-Low-Emphasis)と
|
|
313
|
+
opacity 減衰の廃止で解消済み。無効状態デモ等 WCAG 1.4.3 の inactive 例外だけ、ストーリー側で
|
|
314
|
+
理由コメント付きの rule 除外を許可(`.storybook/preview.ts` 参照)。トークンペアの正本チェックは
|
|
315
|
+
`scripts/check-contrast.mjs`(`npm run check` 経由)。
|
|
316
|
+
- rules.json の `accessibility.requirements` に `machineVerified` / `verifiedBy` を追加済み。
|
|
317
|
+
axe でカバーできない項目(フォーカスリング視認・タッチターゲット実測・エラー表示の
|
|
318
|
+
色+アイコン+テキスト3点セット等)は今後も目視レビューが必要。
|
|
319
|
+
- icon-only の `<Button size="icon*">` に `aria-label` が無いパターンは
|
|
320
|
+
`eslint/icon-button-aria-label.js`(`ksk-a11y/icon-button-aria-label`)で lint 時に検出する
|
|
321
|
+
(`.stories.tsx` は対象外)。
|
|
322
|
+
|
|
323
|
+
---
|
|
324
|
+
|
|
164
325
|
## カラートークン体系(3層構造)
|
|
165
326
|
|
|
166
327
|
```
|
|
@@ -187,6 +348,16 @@ Layer 3 — Bridge : --primary / --secondary 等 (shadcn/ui 互換
|
|
|
187
348
|
Brand に連動しない固定値で、カレンダー予定ドット・カテゴリ chip・グラフ系列など「N 番目のカテゴリ」を色で区別する用途専用。
|
|
188
349
|
文字には必ず `-Bold` を使う(base は明色相だと白背景でコントラスト不足)。詳細・WCAG/CVD 注記は `src/styles/categorical.css`。
|
|
189
350
|
|
|
351
|
+
**モーション(`src/styles/motion.css`):**
|
|
352
|
+
`duration-[var(--Motion-Duration-{Fast,Base,Slow,Slower})]` /
|
|
353
|
+
`ease-[var(--Motion-Easing-{Standard,Emphasized,Decelerate,Bounce})]`。
|
|
354
|
+
生の `duration-200` / `cubic-bezier(...)` は禁止(`prefers-reduced-motion` の一括制御から漏れる)。
|
|
355
|
+
|
|
356
|
+
**重なり順(`src/preset.css`):**
|
|
357
|
+
`z-[var(--Z-{Sticky,Nav,Overlay,Modal,Popover,Toast,Tooltip,SkipLink})]`。
|
|
358
|
+
`z-50` 一律だと Portal のマウント順で勝敗が決まる。`z-10` / `z-20` のコンポーネント内部の重なりは対象外。
|
|
359
|
+
いずれも詳細は DESIGN.md の Motion / Layering 節。
|
|
360
|
+
|
|
190
361
|
---
|
|
191
362
|
|
|
192
363
|
## クイックスタート(新規クライアント案件)
|
|
@@ -227,7 +398,7 @@ import { Button, Card, Input, FormField } from "ksk-design-system"
|
|
|
227
398
|
- [ ] `contracts/components.json` の `meta.counts` を更新
|
|
228
399
|
- [ ] `bash scripts/check-drift.sh` を実行して乖離がないことを確認
|
|
229
400
|
- [ ] Storybook のストーリーファイル(`.stories.tsx`)を作成
|
|
230
|
-
- [ ] `
|
|
401
|
+
- [ ] `npm run generate:lookup` を実行して COMPONENT_LOOKUP.md を更新
|
|
231
402
|
|
|
232
403
|
<!-- BEGIN:codex-pr-review-guidelines -->
|
|
233
404
|
## Codex PR Review Guidelines
|
package/CLAUDE.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# KSK Design System — 設計ルールブック
|
|
2
2
|
|
|
3
|
+
## CLAUDE.md / AGENTS.md の編集ルール
|
|
4
|
+
|
|
5
|
+
<!-- docs-sync-ignore -->
|
|
6
|
+
このファイルと `AGENTS.md` は Claude Code 用 / Codex 用の対になる作業手順書で、
|
|
7
|
+
共通で守るべき内容(実装前セルフチェック・セッション開始時に読み込むファイル・
|
|
8
|
+
ローカル二重実装ゲート・このDSについて・最大の特徴・技術スタック・AIモデルの
|
|
9
|
+
使い分け方針・ドキュメント構成・ディレクトリ構成・カラートークン体系・
|
|
10
|
+
クイックスタート・コンポーネント追加時のチェックリスト)は**両ファイルで内容を
|
|
11
|
+
同期させる**こと。
|
|
12
|
+
|
|
13
|
+
- 見出し名・本文は基本的に同一にする(ツール名など明確にツール固有の1行だけ
|
|
14
|
+
<!-- docs-sync-ignore --> マーカー(単独行、次の1行を対象から除外)で除外する)
|
|
15
|
+
- Codex 固有の付録(AGENTS.md 末尾の Codex PR Review Guidelines)のような
|
|
16
|
+
完全にツール固有のブロックは BEGIN/END マーカーコメント(例:
|
|
17
|
+
末尾が `codex-pr-review-guidelines` のマーカー)で囲み同期対象から除外する
|
|
18
|
+
- 片方だけ編集したら **`node scripts/check-agents-docs-sync.mjs`**(`npm run check` に
|
|
19
|
+
組み込み済み)を実行し、乖離が無いことを確認する
|
|
20
|
+
- `templates/CLAUDE.md` / `templates/AGENTS.md`(postinstall で配布するテンプレート)も
|
|
21
|
+
同じ仕組みで同期検査の対象
|
|
22
|
+
|
|
3
23
|
## 実装前セルフチェック(AI必読・最優先)
|
|
4
24
|
|
|
5
25
|
UI を書く前に必ず確認すること:
|
|
@@ -10,10 +30,120 @@ UI を書く前に必ず確認すること:
|
|
|
10
30
|
- [ ] `border` は色を併記したか(`border-[var(--Border-Low-Emphasis)]` 等)。Tailwind v4 では無色 border は currentColor になり、消費側の濃色テキストで黒ずむ(preset.css の base layer が保険だが明示が原則)
|
|
11
31
|
- [ ] **文脈非依存**か(テキスト要素に `text-[var(--Text-*)]`、サーフェス/オーバーレイに `bg-[var(--Surface-*)]` を明示)。親の継承や currentColor に頼ると消費側の色文脈で崩れる。Storybook ツールバーの **Hostile ctx** を loud にして、文字/アイコンがマゼンタ化・背景が透けないか確認する
|
|
12
32
|
- [ ] typography は `typo-*` クラスか(`font-bold` 等の直書きは禁止)
|
|
33
|
+
- [ ] アニメーションは `duration-[var(--Motion-Duration-*)]` / `ease-[var(--Motion-Easing-*)]` か(`duration-200` や生 `cubic-bezier` の直書きは禁止。トークン参照でないと `prefers-reduced-motion` の一括制御から漏れる)
|
|
34
|
+
- [ ] 重なり順は `z-[var(--Z-*)]` か(`z-50` 一律だと Portal のマウント順で勝敗が決まる。`z-10` / `z-20` のコンポーネント内部の重なりは対象外。順序は DESIGN.md の Layering 節)
|
|
13
35
|
- [ ] アイコンは `iconsax-reactjs` か(`lucide-react` / `heroicons` は使わない)
|
|
14
36
|
- [ ] 生タグ(`<button>` / `<input>` / `<a href>`)でなく DS コンポーネントを使ったか
|
|
15
37
|
- [ ] CSS でベンダープレフィックス併記する場合、**`-webkit-` を先・標準形を後**に書いたか(消費側の minifier が同一プロパティとして dedupe し後勝ちのみ残すため。逆順だと Firefox で静かに無効化。`node scripts/check-prefix-order.mjs` が CI で検出)
|
|
38
|
+
- [ ] クラス名は**完全な文字列**で書いたか(`` `bg-${color}` `` のような動的合成は静的抽出できず消費側で CSS が生成されない。分岐は三項演算子か cva variant で。`scripts/generate-source-safelist.mjs` が検出)
|
|
16
39
|
- [ ] `.tsx` 編集後に `bash scripts/lint-scratch.sh`、コンポーネント増減時は `npm run check` を実行したか
|
|
40
|
+
- [ ] `FormField` を import する前にどちらか確認したか(react-hook-form の Controller と統合するなら `RhfFormField`=`ui/form` の `FormField` を index.ts で別名 export したもの。単純な label+error 表示は `patterns/form-field` の `FormField`。迷ったら後者)
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## 必須: セッション開始時に読み込むファイル
|
|
45
|
+
|
|
46
|
+
コードを書く前に、以下を必ず読み込むこと:
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
.claude/skills/ksk-design-system/SKILL.md # 判断Skill: 実装・レビューの判断基準(正本への索引)
|
|
50
|
+
contracts/rules.json # 禁止パターン・AIアンチパターン・a11y要件(件数・内容は rules.json が正本)
|
|
51
|
+
contracts/components.json # 全コンポーネントの定義・バリアント・ルール
|
|
52
|
+
contracts/design-context.json # DESIGN.md と正本ファイルの関係・AI向け検査方針
|
|
53
|
+
tokens.json # カラー・スペーシング・シャドウトークン
|
|
54
|
+
contracts/token-hex-cache.json # semantic トークンのデフォルトテーマ解決済み hex(テーマ依存キーは meta.themeDependentKeys 参照・自動生成)
|
|
55
|
+
src/components/COMPONENT_LOOKUP.md # バリアント・インポートパス一覧(自動生成)
|
|
56
|
+
contracts/screen-patterns.json # 画面実装前にどのシェル/パターンを使うかの decisionTree・crudMatrix
|
|
57
|
+
contracts/composition.json # 選んだパターン内部の並べ方(骨格構造・余白リズム・カード階層・テキスト階層・CTA優先度)
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
画面(ページ/ダイアログ等)を実装・修正する場合は、まず `contracts/screen-patterns.json` の
|
|
61
|
+
decisionTree でシェル/パターンを選び、`contracts/composition.json` で内部の並べ方を確認すること。
|
|
62
|
+
|
|
63
|
+
UI コンポーネント・画面の生成/修正・レビューの前には、必ず
|
|
64
|
+
`.claude/skills/ksk-design-system/SKILL.md` を読み、その判断基準に従うこと
|
|
65
|
+
(トークン選定・コンポーネント選択・レビュー優先順位・例外運用。迷ったら同ディレクトリの `references/` を参照)。
|
|
66
|
+
|
|
67
|
+
**必ず `contracts/rules.json` の `prohibited` と `aiPatterns` を確認してから実装すること。**
|
|
68
|
+
特に `aiPatterns` は AI が典型的に犯すパターン集 — 自分が生成しようとしているコードと照合すること。
|
|
69
|
+
|
|
70
|
+
コンポーネントを新規作成する前に `COMPONENT_LOOKUP.md` で同等品がないか確認すること。
|
|
71
|
+
|
|
72
|
+
`FormField` は同名で2種類ある: react-hook-form の Controller と統合するなら `RhfFormField`(`ui/form` の `FormField` を index.ts で別名 export したもの)、単純な label+error 表示なら `FormField`(`patterns/form-field`)。迷ったら後者を使う。
|
|
73
|
+
|
|
74
|
+
### ローカル二重実装ゲート
|
|
75
|
+
|
|
76
|
+
DS に無いと思っても consumer 側に別台帳を作らないこと。最初に `contracts/components.json` と
|
|
77
|
+
`COMPONENT_LOOKUP.md` を検索し、consumer では `npx ksk-ds check-duplicates ./src --strict` を実行する。
|
|
78
|
+
それでも不足する場合は DS 側に issue を登録する。やむを得ない一時実装には、削除条件と issue を
|
|
79
|
+
`// ksk-ds-local-fallback: DS に X が追加されたら削除 (issue #123)` の形式で残すこと。
|
|
80
|
+
|
|
81
|
+
Storybook 全体を横断で視覚監査する(定期監査・リリース前総点検)場合は `.claude/skills/audit-pages/SKILL.md` の手順に従うこと。
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## 必須: ファイル編集後に実行するコマンド
|
|
86
|
+
|
|
87
|
+
**.tsx ファイルを作成・編集した後は必ず実行:**
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
bash scripts/lint-scratch.sh
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**.css を編集した後は必ず実行:**
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
node scripts/check-prefix-order.mjs
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
ベンダープレフィックスは **`-webkit-` を先・標準形を後** に書く(消費側の
|
|
100
|
+
minifier が同一プロパティとして dedupe し後勝ちのみ残すため、逆順だと
|
|
101
|
+
標準形が消えて Firefox で静かに無効化される)。
|
|
102
|
+
|
|
103
|
+
**新しい Tailwind クラスを使った後は必ず実行:**
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
npm run generate:safelist
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
DS 内部でしか出現しないクラスを消費側で確実に生成させるための safelist
|
|
110
|
+
(`src/styles/source-safelist.css`・自動生成)を更新する。未更新は
|
|
111
|
+
`npm run check` が検出する。クラス名は必ず完全な文字列で書くこと
|
|
112
|
+
(`` `bg-${color}` `` のような動的合成は静的抽出できず、同スクリプトがエラーにする)。
|
|
113
|
+
|
|
114
|
+
**コンポーネントを追加・削除した後は必ず実行:**
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
bash scripts/check-drift.sh
|
|
118
|
+
npm run generate:lookup
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
**play 関数のあるコンポーネントを触った後は必ず実行:**
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
npm run test:interaction
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
対象は Button / Dialog / AlertDialog / Sheet / Select / DropdownMenu /
|
|
128
|
+
Combobox / Tabs / Form / Toast。Storybook の play 関数を playwright chromium で
|
|
129
|
+
ヘッドレス実行する(設定は `vitest.storybook.config.ts`、対象は
|
|
130
|
+
`tags: ["interaction"]` を付けたストーリーのみ)。初回のみ
|
|
131
|
+
`npx playwright install chromium` が必要なため `npm run check` には含まれない。
|
|
132
|
+
CI では常時実行される。
|
|
133
|
+
|
|
134
|
+
**UI コンポーネントを追加・修正した後は `npm run test:a11y` も実行:**
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
npm run test:a11y
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
axe-core による a11y 機械検証(issue #261)。`@storybook/addon-a11y` の
|
|
141
|
+
afterEach フックが全ストーリー(tags フィルタなし)に対して axe-core を
|
|
142
|
+
実行する(設定は `vitest.a11y.config.ts`)。color-contrast ルールも有効
|
|
143
|
+
(AA 未達トークンの darken と opacity 減衰の廃止により全ストーリー通過。
|
|
144
|
+
トークンペアの正本チェックは `scripts/check-contrast.mjs`)。CI では常時実行される。
|
|
145
|
+
|
|
146
|
+
エラーが出た場合は修正してから次に進むこと。
|
|
17
147
|
|
|
18
148
|
---
|
|
19
149
|
|
|
@@ -85,8 +215,10 @@ Brand色を差し替え(10行)→ Primitive Layer → Semantic Layer → Bri
|
|
|
85
215
|
|
|
86
216
|
| ファイル | 内容 |
|
|
87
217
|
|---------|------|
|
|
218
|
+
<!-- docs-sync-ignore -->
|
|
88
219
|
| **CLAUDE.md**(本ファイル) | 概要・技術スタック・コマンド・クイックスタート(Claude Code用) |
|
|
89
|
-
|
|
220
|
+
<!-- docs-sync-ignore -->
|
|
221
|
+
| **AGENTS.md** | 同上(Codex用。Codex PR Review Guidelines を追記) |
|
|
90
222
|
| **contracts/components.json** | 全コンポーネントの構造化定義(バリアント・アクセシビリティ要件。総数は meta.counts が正本) |
|
|
91
223
|
| **contracts/rules.json** | 禁止パターン・AIアンチパターン・アクセシビリティ要件(正本: rules.json) |
|
|
92
224
|
| **contracts/design-context.json** | `DESIGN.md` の役割・正本ファイル・外部 DESIGN.md 参照方針 |
|
|
@@ -97,25 +229,6 @@ Brand色を差し替え(10行)→ Primitive Layer → Semantic Layer → Bri
|
|
|
97
229
|
| **contracts/screen-patterns.json** | 画面実装前にどのシェル/パターンを使うかを決める decisionTree・crudMatrix |
|
|
98
230
|
| **contracts/composition.json** | 選んだパターン内部の並べ方(骨格構造・余白リズム・カード階層・テキスト階層・CTA優先度) |
|
|
99
231
|
|
|
100
|
-
**セッション開始時 / コードを書く前に必ず読む:**
|
|
101
|
-
1. `contracts/rules.json` の `prohibited` と `aiPatterns`(AIが典型的に犯すパターン集)を確認
|
|
102
|
-
2. `contracts/components.json` でコンポーネント定義・バリアントを確認
|
|
103
|
-
3. `contracts/design-context.json` で `DESIGN.md` と正本ファイルの関係を確認
|
|
104
|
-
4. `src/components/COMPONENT_LOOKUP.md` で既存コンポーネントを確認(手書き・再定義の防止)
|
|
105
|
-
5. `tokens.json` でカラー・余白・影・タイポのトークンを確認
|
|
106
|
-
6. 画面(ページ/ダイアログ等)を実装する場合は `contracts/screen-patterns.json` の decisionTree でシェル/パターンを選び、`contracts/composition.json` で内部の並べ方を確認
|
|
107
|
-
|
|
108
|
-
### ローカル二重実装ゲート
|
|
109
|
-
|
|
110
|
-
DS に無いと思っても consumer 側に別台帳を作らないこと。最初に `contracts/components.json` と
|
|
111
|
-
`COMPONENT_LOOKUP.md` を検索し、consumer では `npx ksk-ds check-duplicates ./src --strict` を実行する。
|
|
112
|
-
それでも不足する場合は DS 側に issue を登録する。やむを得ない一時実装には、削除条件と issue を
|
|
113
|
-
`// ksk-ds-local-fallback: DS に X が追加されたら削除 (issue #123)` の形式で残すこと。
|
|
114
|
-
|
|
115
|
-
**`.tsx` を編集したら `bash scripts/lint-scratch.sh`、コンポーネント増減時は `npm run check` を実行すること。**
|
|
116
|
-
|
|
117
|
-
Storybook 全体を横断で視覚監査する(定期監査・リリース前総点検・「全ページ確認して」)場合は `.claude/skills/audit-pages/SKILL.md` を使う。
|
|
118
|
-
|
|
119
232
|
---
|
|
120
233
|
|
|
121
234
|
## ディレクトリ構成
|
|
@@ -133,7 +246,9 @@ src/
|
|
|
133
246
|
├── styles/
|
|
134
247
|
│ ├── primitive.css # Layer 1: 原色パレット
|
|
135
248
|
│ ├── semantic.css # Layer 2: 用途別トークン
|
|
136
|
-
│
|
|
249
|
+
│ ├── typography.css # typo-* ユーティリティ
|
|
250
|
+
│ ├── motion.css # duration / easing トークン(--Motion-*)
|
|
251
|
+
│ └── source-safelist.css # @source safelist(自動生成・手で編集しない / issue #258)
|
|
137
252
|
├── themes/ # default / orange / green / violet / blue
|
|
138
253
|
├── preset.css # 外部プロジェクト向けプリセット
|
|
139
254
|
└── index.ts # Public API(全コンポーネント)
|
|
@@ -162,10 +277,49 @@ npm run generate:lookup
|
|
|
162
277
|
# DESIGN.md contract 検査
|
|
163
278
|
npm run lint:design
|
|
164
279
|
|
|
165
|
-
#
|
|
280
|
+
# @source safelist 再生成(新しい Tailwind クラスを使ったら実行)
|
|
281
|
+
npm run generate:safelist
|
|
282
|
+
|
|
283
|
+
# 全チェック(tsc + lint + drift + lookup + safelist 一括)
|
|
166
284
|
npm run check
|
|
285
|
+
|
|
286
|
+
# interaction テスト(Storybook play 関数を playwright chromium で実行)
|
|
287
|
+
npm run test:interaction
|
|
288
|
+
|
|
289
|
+
# a11y 機械検証(axe-core。全ストーリー対象。issue #261)
|
|
290
|
+
npm run test:a11y
|
|
167
291
|
```
|
|
168
292
|
|
|
293
|
+
**interaction テストについて(issue #256):**
|
|
294
|
+
|
|
295
|
+
- 実体は Storybook の play 関数。`@storybook/addon-vitest` + vitest browser mode(playwright chromium)で
|
|
296
|
+
ヘッドレス実行する。設定は `vitest.storybook.config.ts`。
|
|
297
|
+
- 対象は `tags: ["interaction"]` を付けたストーリーだけ(全ストーリーのスモークはしない)。
|
|
298
|
+
- 初回のみ `npx playwright install chromium` が必要。**この前提があるため `npm run check` /
|
|
299
|
+
`check:agent` には含めていない**(CI と、下記に該当する変更をしたときに手で回す)。
|
|
300
|
+
- 押下でレイアウトが沈む・入場アニメーション中に操作不能・フォーカストラップ崩れ、といった
|
|
301
|
+
v1.48.x で連続した種類の不具合をここで落とす。
|
|
302
|
+
- **play 関数のあるコンポーネント(Button / Dialog / AlertDialog / Sheet / Select /
|
|
303
|
+
DropdownMenu / Combobox / Tabs / Form / Toast)を触ったら `npm run test:interaction` を回すこと。**
|
|
304
|
+
- ビジュアル回帰(スクリーンショット差分)は未導入。`.claude/skills/audit-pages/SKILL.md` による
|
|
305
|
+
手動の視覚監査が現状の代替。
|
|
306
|
+
|
|
307
|
+
**a11y 機械検証について(issue #261):**
|
|
308
|
+
|
|
309
|
+
- `@storybook/addon-a11y` の afterEach フック(axe-core)が全ストーリー(tags フィルタなし)に
|
|
310
|
+
対して実行される。設定は `vitest.a11y.config.ts`、実行は `npm run test:a11y`。CI では常時実行。
|
|
311
|
+
- color-contrast ルールも有効(全ストーリー対象)。当初はトークン債務のため無効化していたが、
|
|
312
|
+
AA 未達トークンの darken(Success/Warning-Base・Text-Caution/Warning・Text-Low-Emphasis)と
|
|
313
|
+
opacity 減衰の廃止で解消済み。無効状態デモ等 WCAG 1.4.3 の inactive 例外だけ、ストーリー側で
|
|
314
|
+
理由コメント付きの rule 除外を許可(`.storybook/preview.ts` 参照)。トークンペアの正本チェックは
|
|
315
|
+
`scripts/check-contrast.mjs`(`npm run check` 経由)。
|
|
316
|
+
- rules.json の `accessibility.requirements` に `machineVerified` / `verifiedBy` を追加済み。
|
|
317
|
+
axe でカバーできない項目(フォーカスリング視認・タッチターゲット実測・エラー表示の
|
|
318
|
+
色+アイコン+テキスト3点セット等)は今後も目視レビューが必要。
|
|
319
|
+
- icon-only の `<Button size="icon*">` に `aria-label` が無いパターンは
|
|
320
|
+
`eslint/icon-button-aria-label.js`(`ksk-a11y/icon-button-aria-label`)で lint 時に検出する
|
|
321
|
+
(`.stories.tsx` は対象外)。
|
|
322
|
+
|
|
169
323
|
---
|
|
170
324
|
|
|
171
325
|
## カラートークン体系(3層構造)
|
|
@@ -194,6 +348,16 @@ Layer 3 — Bridge : --primary / --secondary 等 (shadcn/ui 互換
|
|
|
194
348
|
Brand に連動しない固定値で、カレンダー予定ドット・カテゴリ chip・グラフ系列など「N 番目のカテゴリ」を色で区別する用途専用。
|
|
195
349
|
文字には必ず `-Bold` を使う(base は明色相だと白背景でコントラスト不足)。詳細・WCAG/CVD 注記は `src/styles/categorical.css`。
|
|
196
350
|
|
|
351
|
+
**モーション(`src/styles/motion.css`):**
|
|
352
|
+
`duration-[var(--Motion-Duration-{Fast,Base,Slow,Slower})]` /
|
|
353
|
+
`ease-[var(--Motion-Easing-{Standard,Emphasized,Decelerate,Bounce})]`。
|
|
354
|
+
生の `duration-200` / `cubic-bezier(...)` は禁止(`prefers-reduced-motion` の一括制御から漏れる)。
|
|
355
|
+
|
|
356
|
+
**重なり順(`src/preset.css`):**
|
|
357
|
+
`z-[var(--Z-{Sticky,Nav,Overlay,Modal,Popover,Toast,Tooltip,SkipLink})]`。
|
|
358
|
+
`z-50` 一律だと Portal のマウント順で勝敗が決まる。`z-10` / `z-20` のコンポーネント内部の重なりは対象外。
|
|
359
|
+
いずれも詳細は DESIGN.md の Motion / Layering 節。
|
|
360
|
+
|
|
197
361
|
---
|
|
198
362
|
|
|
199
363
|
## クイックスタート(新規クライアント案件)
|