ksk-design-system 1.44.0 → 1.46.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.
Files changed (73) hide show
  1. package/AGENTS.md +17 -0
  2. package/CLAUDE.md +14 -0
  3. package/DESIGN.md +5 -3
  4. package/MIGRATION.md +4 -0
  5. package/PUBLISHING.md +36 -14
  6. package/README.md +84 -2
  7. package/RELEASE.md +2 -1
  8. package/UPDATING.md +160 -0
  9. package/bin/card-child-spacing.js +111 -0
  10. package/bin/check-duplicates.js +167 -0
  11. package/bin/init.js +19 -0
  12. package/bin/lint.js +10 -0
  13. package/contracts/components.json +243 -28
  14. package/contracts/composition.json +153 -0
  15. package/contracts/design-context.json +25 -0
  16. package/contracts/rules.json +34 -2
  17. package/contracts/screen-patterns.json +228 -0
  18. package/contracts/token-hex-cache.json +543 -0
  19. package/dist/index.js +2439 -1773
  20. package/dist/native/ui.js +1375 -1272
  21. package/dist/{native-BelCzh9_.js → native-BYLnbCN-.js} +74 -1
  22. package/dist/native.js +1 -1
  23. package/dist/types/class-names.d.ts +1 -1
  24. package/dist/types/components/patterns/_internal/carousel-primitives.d.ts +24 -0
  25. package/dist/types/components/patterns/bottom-sheet-frame.d.ts +1 -1
  26. package/dist/types/components/patterns/coach-mark-overlay.d.ts +1 -1
  27. package/dist/types/components/patterns/commerce/bottom-tab-bar.d.ts +8 -1
  28. package/dist/types/components/patterns/content-carousel.d.ts +18 -0
  29. package/dist/types/components/patterns/empty-state.d.ts +1 -1
  30. package/dist/types/components/patterns/error-state.d.ts +8 -2
  31. package/dist/types/components/patterns/field.d.ts +23 -0
  32. package/dist/types/components/patterns/list-item.d.ts +22 -2
  33. package/dist/types/components/patterns/mobile-floating-action-button.d.ts +1 -1
  34. package/dist/types/components/patterns/screen.d.ts +4 -1
  35. package/dist/types/components/patterns/share-buttons.d.ts +7 -3
  36. package/dist/types/components/patterns/shells/admin-shell.d.ts +5 -1
  37. package/dist/types/components/patterns/shells/app-shell.d.ts +5 -1
  38. package/dist/types/components/patterns/shells/marketing-shell.d.ts +5 -1
  39. package/dist/types/components/patterns/side-drawer-frame.d.ts +1 -1
  40. package/dist/types/components/ui/alert-dialog.d.ts +1 -1
  41. package/dist/types/components/ui/auto-grow-textarea.d.ts +5 -2
  42. package/dist/types/components/ui/button.d.ts +1 -1
  43. package/dist/types/components/ui/container.d.ts +15 -0
  44. package/dist/types/components/ui/date-picker.d.ts +9 -2
  45. package/dist/types/components/ui/date-time-picker.d.ts +27 -0
  46. package/dist/types/components/ui/dialog.d.ts +7 -2
  47. package/dist/types/components/ui/icon-badge.d.ts +17 -0
  48. package/dist/types/components/ui/input.d.ts +7 -1
  49. package/dist/types/components/ui/section-nav.d.ts +28 -0
  50. package/dist/types/components/ui/section.d.ts +17 -0
  51. package/dist/types/components/ui/sheet.d.ts +7 -2
  52. package/dist/types/components/ui/skip-link.d.ts +8 -0
  53. package/dist/types/components/ui/textarea.d.ts +6 -1
  54. package/dist/types/components/ui/time-picker.d.ts +4 -1
  55. package/dist/types/index.d.ts +22 -2
  56. package/dist/types/lib/use-value-length.d.ts +25 -0
  57. package/dist/types/native/components/CheckboxField.d.ts +3 -1
  58. package/dist/types/native/components/DateTimePicker.d.ts +13 -0
  59. package/dist/types/native/components/IconBadge.d.ts +13 -0
  60. package/dist/types/native/components/Switch.d.ts +4 -1
  61. package/dist/types/native/components/index.d.ts +2 -0
  62. package/dist/types/tokens/native/scales.d.ts +73 -0
  63. package/eslint/deprecated.js +1 -1
  64. package/package.json +20 -20
  65. package/scripts/codemod/README.md +15 -0
  66. package/scripts/codemod/check-migration.mjs +129 -0
  67. package/src/components/COMPONENT_LOOKUP.md +12 -4
  68. package/src/native/COMPONENT_LOOKUP.md +3 -1
  69. package/src/preset.css +25 -0
  70. package/src/styles/glass.css +249 -33
  71. package/templates/AGENTS.md +18 -2
  72. package/templates/CLAUDE.md +18 -2
  73. package/tokens.json +78 -3
package/AGENTS.md CHANGED
@@ -20,9 +20,15 @@ contracts/rules.json # 禁止パターン43件・AIアンチ
20
20
  contracts/components.json # 全132コンポーネントの定義・バリアント・ルール
21
21
  contracts/design-context.json # DESIGN.md と正本ファイルの関係・AI向け検査方針
22
22
  tokens.json # カラー・スペーシング・シャドウトークン
23
+ contracts/token-hex-cache.json # semantic トークンのデフォルトテーマ解決済み hex(テーマ依存キーは meta.themeDependentKeys 参照・自動生成)
23
24
  src/components/COMPONENT_LOOKUP.md # バリアント・インポートパス一覧(自動生成)
25
+ contracts/screen-patterns.json # 画面実装前にどのシェル/パターンを使うかの decisionTree・crudMatrix
26
+ contracts/composition.json # 選んだパターン内部の並べ方(骨格構造・余白リズム・カード階層・テキスト階層・CTA優先度)
24
27
  ```
25
28
 
29
+ 画面(ページ/ダイアログ等)を実装・修正する場合は、まず `contracts/screen-patterns.json` の
30
+ decisionTree でシェル/パターンを選び、`contracts/composition.json` で内部の並べ方を確認すること。
31
+
26
32
  UI コンポーネント・画面の生成/修正・レビューの前には、必ず
27
33
  `.claude/skills/ksk-design-system/SKILL.md` を読み、その判断基準に従うこと
28
34
  (トークン選定・コンポーネント選択・レビュー優先順位・例外運用。迷ったら同ディレクトリの `references/` を参照)。
@@ -32,6 +38,15 @@ UI コンポーネント・画面の生成/修正・レビューの前には、
32
38
 
33
39
  コンポーネントを新規作成する前に `COMPONENT_LOOKUP.md` で同等品がないか確認すること。
34
40
 
41
+ ### ローカル二重実装ゲート
42
+
43
+ DS に無いと思っても consumer 側に別台帳を作らないこと。最初に `contracts/components.json` と
44
+ `COMPONENT_LOOKUP.md` を検索し、consumer では `npx ksk-ds check-duplicates ./src --strict` を実行する。
45
+ それでも不足する場合は DS 側に issue を登録する。やむを得ない一時実装には、削除条件と issue を
46
+ `// ksk-ds-local-fallback: DS に X が追加されたら削除 (issue #123)` の形式で残すこと。
47
+
48
+ Storybook 全体を横断で視覚監査する(定期監査・リリース前総点検)場合は `.claude/skills/audit-pages/SKILL.md` の手順に従うこと。
49
+
35
50
  ---
36
51
 
37
52
  ## 必須: ファイル編集後に実行するコマンド
@@ -118,6 +133,8 @@ Brand色を差し替え(10行)→ Primitive Layer → Semantic Layer → Bri
118
133
  | **tokens.json** | カラー・スペーシング・シャドウトークンの機械可読定義 |
119
134
  | **src/components/COMPONENT_LOOKUP.md** | 全112コンポーネントのバリアント・インポートパス(自動生成) |
120
135
  | **DESIGN.md** | AI エージェント向け視覚言語サマリ(トークン+意図・voice・motion) |
136
+ | **contracts/screen-patterns.json** | 画面実装前にどのシェル/パターンを使うかを決める decisionTree・crudMatrix |
137
+ | **contracts/composition.json** | 選んだパターン内部の並べ方(骨格構造・余白リズム・カード階層・テキスト階層・CTA優先度) |
121
138
 
122
139
  ---
123
140
 
package/CLAUDE.md CHANGED
@@ -4,6 +4,7 @@
4
4
 
5
5
  UI を書く前に必ず確認すること:
6
6
 
7
+ - [ ] 画面の骨格は `contracts/screen-patterns.json` の decisionTree で選んだか
7
8
  - [ ] 既存コンポーネントを `src/components/COMPONENT_LOOKUP.md` で確認したか(手書き・再定義は禁止)
8
9
  - [ ] 色は semantic token(`var(--Surface-*)` / `var(--Brand-Primary)` 等)か。Tailwind標準色・生 `#hex` は禁止
9
10
  - [ ] `border` は色を併記したか(`border-[var(--Border-Low-Emphasis)]` 等)。Tailwind v4 では無色 border は currentColor になり、消費側の濃色テキストで黒ずむ(preset.css の base layer が保険だが明示が原則)
@@ -77,8 +78,11 @@ Brand色を差し替え(10行)→ Primitive Layer → Semantic Layer → Bri
77
78
  | **contracts/rules.json** | 禁止パターン32件・AIアンチパターン10件・アクセシビリティ要件 |
78
79
  | **contracts/design-context.json** | `DESIGN.md` の役割・正本ファイル・外部 DESIGN.md 参照方針 |
79
80
  | **tokens.json** | カラー・スペーシング・シャドウトークンの機械可読定義 |
81
+ | **contracts/token-hex-cache.json** | semantic トークンのデフォルトテーマ解決済み hex(テーマ依存キーは meta.themeDependentKeys 参照・自動生成) |
80
82
  | **src/components/COMPONENT_LOOKUP.md** | 全112コンポーネントのバリアント・インポートパス一覧(自動生成) |
81
83
  | **DESIGN.md** | AI エージェント向け視覚言語サマリ(トークン+意図・voice・motion) |
84
+ | **contracts/screen-patterns.json** | 画面実装前にどのシェル/パターンを使うかを決める decisionTree・crudMatrix |
85
+ | **contracts/composition.json** | 選んだパターン内部の並べ方(骨格構造・余白リズム・カード階層・テキスト階層・CTA優先度) |
82
86
 
83
87
  **セッション開始時 / コードを書く前に必ず読む:**
84
88
  1. `contracts/rules.json` の `prohibited` と `aiPatterns`(AIが典型的に犯すパターン集)を確認
@@ -86,9 +90,19 @@ Brand色を差し替え(10行)→ Primitive Layer → Semantic Layer → Bri
86
90
  3. `contracts/design-context.json` で `DESIGN.md` と正本ファイルの関係を確認
87
91
  4. `src/components/COMPONENT_LOOKUP.md` で既存コンポーネントを確認(手書き・再定義の防止)
88
92
  5. `tokens.json` でカラー・余白・影・タイポのトークンを確認
93
+ 6. 画面(ページ/ダイアログ等)を実装する場合は `contracts/screen-patterns.json` の decisionTree でシェル/パターンを選び、`contracts/composition.json` で内部の並べ方を確認
94
+
95
+ ### ローカル二重実装ゲート
96
+
97
+ DS に無いと思っても consumer 側に別台帳を作らないこと。最初に `contracts/components.json` と
98
+ `COMPONENT_LOOKUP.md` を検索し、consumer では `npx ksk-ds check-duplicates ./src --strict` を実行する。
99
+ それでも不足する場合は DS 側に issue を登録する。やむを得ない一時実装には、削除条件と issue を
100
+ `// ksk-ds-local-fallback: DS に X が追加されたら削除 (issue #123)` の形式で残すこと。
89
101
 
90
102
  **`.tsx` を編集したら `bash scripts/lint-scratch.sh`、コンポーネント増減時は `npm run check` を実行すること。**
91
103
 
104
+ Storybook 全体を横断で視覚監査する(定期監査・リリース前総点検・「全ページ確認して」)場合は `.claude/skills/audit-pages/SKILL.md` を使う。
105
+
92
106
  ---
93
107
 
94
108
  ## ディレクトリ構成
package/DESIGN.md CHANGED
@@ -46,6 +46,7 @@ rounded:
46
46
  spacing:
47
47
  unit: "4px" # 4px グリッド(scale: 0,4,8,12,16,20,24,28,32,36,40,44,48,...)
48
48
  page: "16px" # 基準画面端マージン。実レイアウトは Screen / Shell の padding contract を優先
49
+ section: { xs: "32px", sm: "40px", md: "48px", lg: "56px", xl: "64px", 2xl: "80px" }
49
50
  elevation: # 影色は neutral(Gray-900 ベース rgba(17,24,39,…))でテーマ非依存
50
51
  sm: "0 1px 2px 0 rgba(0, 0, 0, 0.05)"
51
52
  md: "0 0 8px rgba(20, 20, 20, 0.08)"
@@ -98,7 +99,7 @@ EC/BtoC 系)を回すのが狙い。
98
99
  `DESIGN.md` は Google DESIGN.md の「front matter + rationale」形式を参考にした **AI 向け配布サマリ**であり、
99
100
  実装正本ではない。KSK の正本は次のファイルに置く。
100
101
 
101
- - `tokens.json`: primitive / semantic / dark semantic / typography / spacing / shadow / touch target。
102
+ - `tokens.json`: primitive / semantic / dark semantic / typography / spacing / responsive breakpoint / shadow / touch target。
102
103
  - `src/styles/*.css`: 実際に publish される CSS custom properties と typography / glass utilities。
103
104
  - `contracts/rules.json`: 禁止パターン、AI anti-pattern、a11y、consumer lint の正本。
104
105
  - `contracts/components.json`: component 名、variant、subcomponent、usage rule、件数の正本。
@@ -116,9 +117,9 @@ KSK の必須正本・publish 依存にせず、KSK 固有の multi-theme / nati
116
117
  |---|---|---|
117
118
  | ブランド | `var(--Brand-Primary)` | `#2563EB` |
118
119
  | 背景(白/薄灰) | `var(--Surface-Primary)` / `-Secondary` | `#FFFFFF` / `#F9FAFB` |
119
- | 文字(強/中/弱) | `var(--Text-High/Medium/Low-Emphasis)` | `#111827` / `#374151` / `#6B7280` |
120
+ | 文字(強/中/弱) | `var(--Text-High/Medium/Low-Emphasis)` <!-- docs-drift-ignore: --Text-High/Medium/Low-Emphasis --> | `#111827` / `#374151` / `#6B7280` |
120
121
  | 罫線 | `var(--Border-Low-Emphasis)` | `#E5E7EB` |
121
- | 状態 | `--Success/Warning/Caution/Info-Base` | `#16A34A` / `#EA580C` / `#DC2626` / `#2563EB` |
122
+ | 状態 | `--Success/Warning/Caution/Info-Base` <!-- docs-drift-ignore: --Success/Warning/Caution/Info-Base --> | `#16A34A` / `#EA580C` / `#DC2626` / `#2563EB` |
122
123
 
123
124
  - **状態色の正本**: 上記は `*-Base`(テキスト/アイコン基準=Primitive **600**)。`tokens.json` を正本とし、本表はその要約。
124
125
  バッジ/ピル等の強調 **fill** は別ロール `--Surface-*-Strong`(Primitive **500**)で、わざと一段明るい。役割が違うだけで矛盾ではない。
@@ -140,6 +141,7 @@ KSK の必須正本・publish 依存にせず、KSK 固有の multi-theme / nati
140
141
  ## Layout & Spacing
141
142
 
142
143
  - **4px グリッド**。余白・サイズは 4 の倍数(scale 0–60)。
144
+ - セクション同士の縦リズムは `--Space-Section-{xs..2xl}`(32–80px)を使い、コンポーネント内の gap scale と分離する。
143
145
  - 画面端マージン: 16px を基準にしつつ、実レイアウトでは `Screen` / shell component の padding contract を優先する。
144
146
  - **タッチターゲット**(モバイル): WCAG 2.5.5 / Apple HIG に従い主要操作(ボタン/アイコンボタン/入力/ナビ)の
145
147
  **min は 44px** 以上、推奨 48px。44 未満が避けられない **チップ(min 32px)は hitSlop**(不可視の拡張タップ領域)で
package/MIGRATION.md CHANGED
@@ -105,3 +105,7 @@ npm run build
105
105
  ```
106
106
 
107
107
  それから本番デプロイへ。
108
+
109
+ ## 関連
110
+
111
+ - [UPDATING.md](./UPDATING.md) — 消費側(DS を npm 依存に持つプロジェクト)向けのアップデート手順(バージョンの読み方・PR 作業手順)
package/PUBLISHING.md CHANGED
@@ -5,7 +5,8 @@
5
5
  > **配布方式**: v1.36.0 以降は npm レジストリ経由で配布する。
6
6
  > `npm publish --access public` で公開し、各消費リポジトリの
7
7
  > `package.json` は `ksk-design-system@X.Y.Z` を参照する。
8
- > 消費リポ: belle-todo / trip_todo / ninshin-todo / yokoku-app / pawly(いずれも `~/LocalDev/` 直下)。
8
+ > 対象の消費リポ一覧は `scripts/update-consumers.sh` `DEFAULT_REPOS` が正本
9
+ > (単体リポ・monorepo が混在し、`~/LocalDev/` と `~/LocalDev/Examination/` 配下にまたがる)。
9
10
 
10
11
  ## 前提
11
12
 
@@ -15,18 +16,32 @@
15
16
  ## 最短手順(推奨)
16
17
 
17
18
  ```bash
18
- bash scripts/release.sh minor # patch / minor / major / x.y.z
19
+ # release branch package.json / package-lock.json と契約 version を更新
20
+ # PR を main にマージ
21
+ RUN_ID="$(gh run list --workflow=publish.yml --branch=main --limit=1 \
22
+ --json databaseId --jq '.[0].databaseId')"
23
+ gh run watch "$RUN_ID" --exit-status
19
24
  ```
20
25
 
21
- これだけ。中で以下を全部やる:
26
+ main への version 変更を `.github/workflows/publish.yml` が検知し、npm Trusted
27
+ Publishing (OIDC) で以下を自動実行する:
22
28
 
23
- 1. `git diff --quiet` & main ブランチチェック(曜日チェック)
24
- 2. `npm run check`
25
- 3. `npm version <level>`(tag 切り)
26
- 4. `npm pack`(prepack `dist/` を生成し、中身を検証)
27
- 5. `npm publish --access public`
28
- 6. `git push origin main --tags`
29
- 7. `bash scripts/update-consumers.sh <version>`(5 リポへ PR 自動作成)
29
+ 1. npm 上の最新版と `package.json` version を比較
30
+ 2. `npm ci`
31
+ 3. `npm publish`(prepack `dist/` を生成)
32
+ 4. `vX.Y.Z` tag GitHub Release を作成
33
+
34
+ 公開後、レジストリ反映を確認してから消費リポへ配布する:
35
+
36
+ ```bash
37
+ npm view ksk-design-system@<version> version --json
38
+ npm dist-tag ls ksk-design-system
39
+ bash scripts/update-consumers.sh <version>
40
+ ```
41
+
42
+ PR では `npm run check`、`npm test`、`npm pack --dry-run` を通してからマージする。
43
+ ローカル認証による手動公開が必要な場合だけ `bash scripts/release.sh <version>` を
44
+ フォールバックとして使う。
30
45
 
31
46
  > v1.35.0 で旧名 `@ksk/design-system` 互換 tgz の生成は廃止。
32
47
  > 消費5リポ + todo-shared が新名 `ksk-design-system` に移行済。
@@ -148,13 +163,20 @@ bash scripts/update-consumers.sh <version> <影響リポ...>
148
163
  ## 注意
149
164
 
150
165
  - 配布前に必ず `npm pack --dry-run` で中身確認
151
- - npm registry 公開には `npm login` 済みであること
166
+ - 通常公開は Trusted Publishing (OIDC) を使う。`npm login`
167
+ `scripts/release.sh` でローカル公開へフォールバックする場合のみ必要
152
168
  - `package.json#exports` を変更したら必ず利用側プロジェクトでの import を試す
153
169
  - 金曜午後のリリースは厳禁(週末に障害対応できない)
154
170
  - メジャーリリースは月初の月曜が望ましい(フィードバック収集期間が取れる)
155
171
 
156
172
  ## npm 公開について
157
173
 
158
- v1.36.0 以降は npm registry 経由配布。GitHub Actions による自動 publish はなく、
159
- ローカルの `npm login` 済み環境から `scripts/release.sh` で公開する。
160
- CI/CD に戻す場合は、NPM_TOKEN Secrets 登録と workflow の再作成をセットで行うこと。
174
+ v1.36.0 以降は npm registry 経由配布。通常公開は
175
+ `.github/workflows/publish.yml` npm Trusted Publishing (OIDC) を使うため、
176
+ 長寿命の `NPM_TOKEN` やローカルの `npm login` は不要。
177
+ workflow が利用できない緊急時だけ、`scripts/release.sh` のローカル公開へ
178
+ フォールバックする。
179
+
180
+ ## 関連
181
+
182
+ - [UPDATING.md](./UPDATING.md) — 消費側(DS を npm 依存に持つプロジェクト)向けのアップデート手順
package/README.md CHANGED
@@ -37,7 +37,7 @@ Brand 色を差し替えるだけで業種に合わせた配色に切り替わ
37
37
 
38
38
  React 19 + TypeScript / Vite / **Tailwind CSS v4** / shadcn/ui(Radix UI)/ CVA / iconsax-reactjs / Storybook
39
39
 
40
- **Peer dependencies**: `react` 18 or 19, `react-dom`, `tailwindcss` ^4, `radix-ui`, `@radix-ui/react-slot`, `iconsax-reactjs`
40
+ **Peer dependencies**: `react` 18 or 19, `react-dom`, `tailwindcss` ^4
41
41
 
42
42
  ## 🚀 使い方
43
43
 
@@ -48,11 +48,18 @@ npm install ksk-design-system
48
48
  ```
49
49
 
50
50
  ```css
51
- /* プロジェクトの CSS */
51
+ /* globals.css / app.css(CSS の場所に応じて ../../ の数を調整) */
52
+ @import "tailwindcss";
52
53
  @import "ksk-design-system/preset";
54
+ @import "ksk-design-system/themes/default";
53
55
  @import "./themes/my-client.css"; /* Brand 色を差し替えたテーマ */
56
+ @source "../../node_modules/ksk-design-system/dist";
54
57
  ```
55
58
 
59
+ Tailwind CSS v4 は `node_modules` を既定では走査しません。`@source` がないと、
60
+ DS 内部だけで使うレイアウト・サイズ・状態クラスが生成されず、コンポーネントの表示や操作が崩れます。
61
+ consumer 側の Tailwind と DS を同じビルドで処理するため、上記の設定をセットで使用してください。
62
+
56
63
  ```tsx
57
64
  import { Button, Card, Input, FormField } from "ksk-design-system"
58
65
  ```
@@ -75,6 +82,80 @@ npx ksk-ds lint --changed
75
82
  // ksk-ds-allow-custom-ui: medical chart requires bespoke interaction
76
83
  ```
77
84
 
85
+ ### Jest(CommonJS)でコンポーネントをテストする
86
+
87
+ このパッケージは **ESM-only** です。CJS との dual build は配布せず、Jest
88
+ 側で DS とその ESM 依存を `babel-jest` の変換対象にします。Vitest など
89
+ ESM をネイティブに扱うランナーでは、以下の設定は不要です。
90
+
91
+ Jest 29 では Babel 7 系を使います(Babel 8 は `babel-jest@29` の peer
92
+ 範囲外です)。
93
+
94
+ ```bash
95
+ npm install --save-dev \
96
+ jest@29.7.0 babel-jest@29.7.0 jest-environment-jsdom@29.7.0 \
97
+ @babel/core@^7.28.0 @babel/preset-env@^7.28.0 \
98
+ @babel/preset-react@^7.28.0 @babel/preset-typescript@^7.28.0
99
+ ```
100
+
101
+ ```js
102
+ // babel.config.cjs
103
+ module.exports = {
104
+ presets: [
105
+ ["@babel/preset-env", { targets: { node: "current" } }],
106
+ ["@babel/preset-react", { runtime: "automatic" }],
107
+ ["@babel/preset-typescript", { allExtensions: true, isTSX: true }],
108
+ ],
109
+ }
110
+ ```
111
+
112
+ ```js
113
+ // jest.config.cjs
114
+ module.exports = {
115
+ testEnvironment: "jsdom",
116
+ transform: {
117
+ "^.+\\.m?[jt]sx?$": "babel-jest",
118
+ },
119
+ transformIgnorePatterns: [
120
+ "<rootDir>/node_modules/.pnpm/(?!(ksk-design-system|radix-ui|iconsax-reactjs|@radix-ui\\+[^@]+)@)",
121
+ "node_modules/(?!.pnpm|ksk-design-system|radix-ui|@radix-ui|iconsax-reactjs)",
122
+ ],
123
+ moduleNameMapper: {
124
+ "\\.(css|less|sass|scss)$": "<rootDir>/test/style-mock.cjs",
125
+ "^ksk-design-system/(preset|styles(?:\\.css)?|glass|tokens/(?:primitive|semantic|typography|categorical)|themes/(?:default|blue|orange|green|violet|cobalt))$":
126
+ "<rootDir>/test/style-mock.cjs",
127
+ },
128
+ }
129
+ ```
130
+
131
+ ```js
132
+ // test/style-mock.cjs
133
+ module.exports = {}
134
+ ```
135
+
136
+ この構成なら `ksk-design-system` をコンポーネント単位で mock せず、そのまま
137
+ render できます。リポジトリ内では、実際に `npm pack` した tgz を空の Jest
138
+ プロジェクトへインストールする再現テストを実行できます。
139
+
140
+ ```bash
141
+ npm run test:jest-consumer
142
+ ```
143
+
144
+ React Native / Expo の `jest-expo` でも考え方は同じです。既存の Expo preset
145
+ は維持し、`transformIgnorePatterns` の除外対象へ
146
+ `ksk-design-system` と利用する ESM peer を加えてください。
147
+
148
+ ### Consumer duplicate check
149
+
150
+ DS に存在する部品を consumer 側で再実装しないよう、コンポーネント名の重複検査を同梱しています。
151
+
152
+ ```bash
153
+ npx ksk-ds check-duplicates
154
+ npx ksk-ds check-duplicates ./src --strict
155
+ ```
156
+
157
+ 既定は助言モードで終了コード 0、`--strict` は重複候補があると終了コード 1 です。正本は同梱の `contracts/components.json` であり、consumer 側に別の「昇格候補台帳」を作らないでください。
158
+
78
159
  ### Media overlay utilities
79
160
 
80
161
  動画・写真の上に文字や操作を置く場合は、`--Text-on-Media` と `.text-on-media` / `.text-on-media-secondary`、上下の `.media-scrim-top` / `.media-scrim-bottom` を使います。TikTok / Reels 型の操作群は `MediaActionCluster` が glass ボタン、ラベル、safe-area anchor、idle auto-hide をまとめて扱います。
@@ -186,6 +267,7 @@ DS コンポーネントを最大限活用したモックが `src/prototypes/`
186
267
  - **ライブ Storybook**: https://ksk-design-system.vercel.app — 全コンポーネントのバリアント・テーマ切り替えを操作可能
187
268
  - **npm**: https://www.npmjs.com/package/ksk-design-system
188
269
  - 設計思想・トークン体系の詳細は `CLAUDE.md` / `DESIGN.md` を参照
270
+ - バージョンアップ時の確認事項・PR 手順は `UPDATING.md` を参照
189
271
 
190
272
  ## 📈 ダウンロード数
191
273
 
package/RELEASE.md CHANGED
@@ -70,7 +70,7 @@ GitHub Releases にコピペできるテンプレ:
70
70
 
71
71
  ```md
72
72
  ### Breaking Changes
73
- - `OldComponent` を削除。`NewComponent` を使ってください。
73
+ - `OldComponent` を削除。`NewComponent` を使ってください。<!-- docs-drift-ignore: OldComponent NewComponent -->
74
74
  自動移行: `npx ksk-design-system codemod v1-to-v2 ./src`
75
75
  - 詳細: [MIGRATION.md](./MIGRATION.md)
76
76
  ```
@@ -80,3 +80,4 @@ GitHub Releases にコピペできるテンプレ:
80
80
  - [PUBLISHING.md](./PUBLISHING.md) — 実際の手順
81
81
  - [MIGRATION.md](./MIGRATION.md) — メジャー毎の移行ガイド
82
82
  - [scripts/codemod/README.md](./scripts/codemod/README.md) — codemod 雛形と使い方
83
+ - [UPDATING.md](./UPDATING.md) — 消費側(DS を npm 依存に持つプロジェクト)向けのアップデート手順
package/UPDATING.md ADDED
@@ -0,0 +1,160 @@
1
+ # Updating Guide — `ksk-design-system` を使うプロジェクト向け
2
+
3
+ `ksk-design-system` を npm 依存として利用しているプロジェクト(消費リポ)が、
4
+ バージョンアップ時に何を確認し、どう作業すればよいかをまとめたガイド。
5
+
6
+ DS 本体側のリリース運用は [RELEASE.md](./RELEASE.md) / [PUBLISHING.md](./PUBLISHING.md)、
7
+ 破壊変更の詳細は [MIGRATION.md](./MIGRATION.md) を参照。本ファイルは**消費側**の視点に特化する。
8
+
9
+ ---
10
+
11
+ ## 1. 前提
12
+
13
+ - `package.json` の依存は通常キャレット指定(`"ksk-design-system": "^1.x.x"`)。
14
+ `npm install` するだけでは **patch/minor は自動では上がらない**(lockfile が既存バージョンを固定するため)。
15
+ 実際にバージョンを上げるのは `npm install ksk-design-system@latest` 等を明示的に実行したときだけ。
16
+ - したがって「アップデート」は自動で降ってくるものではなく、**意図的な PR 作業**として扱う。
17
+ 無警戒に `npm update` を通常の依存更新作業に混ぜない。
18
+
19
+ ## 2. 1.x でのバージョンの読み方
20
+
21
+ [Semantic Versioning](https://semver.org/lang/ja/) に従う。`X.Y.Z` の各桁の意味:
22
+
23
+ | 種別 | 意味 | 対応要否 |
24
+ |---|---|---|
25
+ | **patch**(`X.Y.Z` の Z) | バグ修正・内部最適化のみ | 対応不要。そのまま上げてよい |
26
+ | **minor**(`X.Y.Z` の Y) | 新コンポーネント・新 prop 追加など機能追加。既存 API は壊れない想定だが、**視覚的な変更**(デフォルト値の見た目調整など)が入ることがある。まれに識別子の rename 等「要対応」の変更も minor で入る | 上げた後は画面を目視確認。**必ず [MIGRATION.md](./MIGRATION.md) の当該バージョン節を確認**する |
27
+ | **major**(`X.Y.Z` の X) | 2.0 以降、正式な破壊変更を含むリリース | [MIGRATION.md](./MIGRATION.md) 必読。codemod / 手動移行が前提 |
28
+
29
+ **実例(minor だが要対応だったケース)**: v1.34.0 で npm パッケージ名が `@ksk/design-system` → `ksk-design-system` に変更された。
30
+ 機能的な破壊変更ではないため minor リリースだったが、消費側は `import` 文とpackage.json の依存名を一括置換する必要があった。
31
+ 「minor だから確認不要」と決めつけず、必ず MIGRATION.md の該当バージョン節に目を通すこと。
32
+
33
+ ## 3. いつ・誰が上げるか
34
+
35
+ DS メンテナが新バージョンを `npm publish` した後、`scripts/update-consumers.sh` を実行して
36
+ 対象の消費リポに対して一括で bump PR を自動起票する(各リポに `chore/bump-ds-<version>` ブランチを作成し、
37
+ `package.json` の書き換え・`npm install`・commit・push・`gh pr create` まで自動で行う)。
38
+
39
+ - 対象リポの一覧は `scripts/update-consumers.sh` のデフォルト引数が正本。バージョンや対象は都度変わりうるため、本書に固定のリポ名・リポ数は書かない。
40
+ - 各消費リポ側の作業は、**起票された PR の内容を確認してマージする**こと(下記チェックリスト参照)。
41
+ - 緊急のホットフィックス(本番障害対応)の場合も同じ流れで、影響リポに絞って配布されることがある。
42
+
43
+ ## 4. 手順(消費リポ側で手動アップデートする場合)
44
+
45
+ 一括 PR を待たずに自分で上げる場合、または一括 PR の内容を検証する場合の手順:
46
+
47
+ ```bash
48
+ # 1. 現在のバージョンと最新版を確認
49
+ npm view ksk-design-system version
50
+ cat node_modules/ksk-design-system/package.json | grep '"version"'
51
+
52
+ # 2. 作業ブランチを切る
53
+ git checkout -b chore/bump-ds-<version>
54
+
55
+ # 3. 最新化
56
+ npm install ksk-design-system@latest
57
+ # 特定バージョンを指定する場合:
58
+ # npm install ksk-design-system@1.44.0
59
+
60
+ # 4. 非推奨 API の残存を検査(read-only。書き換えは行わない)
61
+ npx ksk-design-system check-migration ./src
62
+
63
+ # 5. 検出があれば MIGRATION.md の該当バージョン節の手順に従って移行する
64
+ # (codemod が提供されているバージョンは MIGRATION.md に実行コマンドが記載される。
65
+ # 提供がないバージョンは MIGRATION.md の before/after に沿って手動で置換)
66
+ git diff # 移行で src を書き換えた場合は意図通りか必ず目視確認
67
+
68
+ # 6. ビルド・lint・テスト
69
+ npm run build
70
+ npm run lint
71
+ npm test
72
+
73
+ # 7. 目視確認(視覚変更があり得る minor 以上は特に)
74
+ npm run dev # または storybook 等、対象プロジェクトの起動コマンド
75
+
76
+ # 8. commit / push / PR
77
+ # 依存ファイルに加え、移行(codemod / 手動置換)で書き換えたソースも忘れずに stage する
78
+ git add package.json package-lock.json
79
+ git add <移行で変更した src 配下のファイル> # 変更がある場合。git status で漏れがないか確認
80
+ git commit -m "chore: ksk-design-system を <version> に更新"
81
+ git push -u origin chore/bump-ds-<version>
82
+ gh pr create
83
+ ```
84
+
85
+ 手動移行が必要な項目(codemod で拾いきれないもの)は [MIGRATION.md](./MIGRATION.md) の
86
+ 「移行作業の進め方」節を参照。
87
+
88
+ ### Tailwind CSS v4 の走査設定
89
+
90
+ アップデート後も、consumer のエントリCSSには次の構成を維持する。
91
+ CSSファイルの場所に応じて `../../` の数だけ調整する。
92
+
93
+ ```css
94
+ @import "tailwindcss";
95
+ @import "ksk-design-system/preset";
96
+ @import "ksk-design-system/themes/default";
97
+ @source "../../node_modules/ksk-design-system/dist";
98
+ ```
99
+
100
+ `@source` を外すと、DS内部だけで使われるクラスが生成されない。`dist` のプリビルドCSSと
101
+ consumer側Tailwindを重ねる二重ビルド方式にも切り替えないこと。
102
+
103
+ ## 5. していい・ダメ早見表
104
+
105
+ | していい | ダメ |
106
+ |---|---|
107
+ | `^1.x.x` のようなキャレット指定で依存を宣言する | `"*"` や `"latest"` で依存バージョンを固定禁止にする(意図しない破壊変更を無警戒に取り込む) |
108
+ | `npm install ksk-design-system@latest` で明示的に更新する | `node_modules/ksk-design-system` の中身を直接編集する(次の `npm install` で消え、変更が誰にも共有されない) |
109
+ | アップデート専用の PR(`chore/bump-ds-*`)を切る | 機能開発 PR に依存バージョン更新を混ぜる(レビューが困難になり、ロールバック時に機能ごと戻ってしまう) |
110
+ | `npx ksk-design-system check-migration ./src` で非推奨 API の残存を確認する | 警告を無視して非推奨 API を放置したままメジャーへ上げる |
111
+ | MIGRATION.md を確認してから minor/major を上げる | バージョン種別だけを見て「minor だから安全」と確認を省略する |
112
+
113
+ ## 6. トラブル時
114
+
115
+ ### ロールバック
116
+
117
+ 問題が出た場合は前バージョンに戻す:
118
+
119
+ ```bash
120
+ npm install ksk-design-system@<前のバージョン>
121
+ git diff package.json package-lock.json # 意図通り戻ったか確認
122
+ ```
123
+
124
+ 戻した後は、DS 側の Issue に再現手順を添えて報告する(下記「Issue 起票先」参照)。
125
+
126
+ ### npm キャッシュが反映されない
127
+
128
+ `npm view ksk-design-system version` で最新バージョンが取得できない、
129
+ または `npm install` 後もバージョンが変わらない場合:
130
+
131
+ ```bash
132
+ npm cache verify # まずキャッシュの整合性を確認
133
+ npm install ksk-design-system@<version> # バージョンを明示して再取得
134
+ ```
135
+
136
+ publish 直後は registry への反映に数分かかることがあるため、少し待ってから再実行する。
137
+ それでも解決しない場合は `npm cache clean --force` の後に上記の再取得を試す。
138
+ **追跡済みの `package-lock.json` を削除しないこと**(lockfile 全体が再生成され、
139
+ 無関係な依存まで差分に混ざる)。
140
+
141
+ ### peer dependency 警告
142
+
143
+ `npm install` 時に React / Tailwind CSS のバージョン不一致警告が出ることがある。
144
+ `package.json#peerDependencies` の範囲を確認し、警告の対象パッケージ自体を先に更新してから
145
+ `ksk-design-system` を上げる。警告を `--force` / `--legacy-peer-deps` で握りつぶして進めない。
146
+
147
+ ### Issue 起票先
148
+
149
+ DS 本体のバグ・想定外の破壊変更に遭遇した場合は、
150
+ `ksk-design-system` リポジトリ([GitHub](https://github.com/ekusiek716/ksk-design-system))に Issue を起票する。
151
+ 再現手順・バージョン(更新前後)・エラーメッセージを添えること。
152
+
153
+ ## 7. 関連ドキュメント
154
+
155
+ | ファイル | 役割 |
156
+ |---|---|
157
+ | [RELEASE.md](./RELEASE.md) | DS 側のリリースサイクル・運用ルール(メンテナ向け) |
158
+ | [PUBLISHING.md](./PUBLISHING.md) | DS 側の公開・配布手順(`npm publish` 〜 `update-consumers.sh`。メンテナ向け) |
159
+ | [MIGRATION.md](./MIGRATION.md) | バージョン間の変更点・破壊変更の詳細(消費側が上げる際に必読) |
160
+ | **本ファイル(UPDATING.md)** | 消費側がアップデート PR をどう作業するかの手順書 |
@@ -0,0 +1,111 @@
1
+ import ts from "typescript"
2
+
3
+ const SPACING_CLASS =
4
+ /(?:^|[\s"'`:({[])-?(?:mt|mb|my|space-y)-[^\s"'`})\]]+/
5
+
6
+ function tagNameOf(node, sourceFile) {
7
+ if (ts.isJsxElement(node)) {
8
+ return node.openingElement.tagName.getText(sourceFile)
9
+ }
10
+ if (ts.isJsxSelfClosingElement(node)) {
11
+ return node.tagName.getText(sourceFile)
12
+ }
13
+ return ""
14
+ }
15
+
16
+ function openingOf(node) {
17
+ if (ts.isJsxElement(node)) return node.openingElement
18
+ if (ts.isJsxSelfClosingElement(node)) return node
19
+ return null
20
+ }
21
+
22
+ function hasMediaVariant(opening, sourceFile) {
23
+ const attribute = opening.attributes.properties.find(
24
+ (property) =>
25
+ ts.isJsxAttribute(property) &&
26
+ property.name.getText(sourceFile) === "variant",
27
+ )
28
+ if (!attribute || !ts.isJsxAttribute(attribute) || !attribute.initializer) {
29
+ return false
30
+ }
31
+ if (ts.isStringLiteral(attribute.initializer)) {
32
+ return attribute.initializer.text === "media"
33
+ }
34
+ if (
35
+ ts.isJsxExpression(attribute.initializer) &&
36
+ attribute.initializer.expression &&
37
+ (ts.isStringLiteral(attribute.initializer.expression) ||
38
+ ts.isNoSubstitutionTemplateLiteral(attribute.initializer.expression))
39
+ ) {
40
+ return attribute.initializer.expression.text === "media"
41
+ }
42
+ return false
43
+ }
44
+
45
+ function spacingClassOf(node, sourceFile) {
46
+ const opening = openingOf(node)
47
+ if (!opening) return null
48
+ const className = opening.attributes.properties.find(
49
+ (property) =>
50
+ ts.isJsxAttribute(property) &&
51
+ property.name.getText(sourceFile) === "className",
52
+ )
53
+ if (!className || !ts.isJsxAttribute(className) || !className.initializer) {
54
+ return null
55
+ }
56
+ const raw = className.initializer.getText(sourceFile)
57
+ return raw.match(SPACING_CLASS)?.[0]?.trim() ?? null
58
+ }
59
+
60
+ function directJsxRoots(node, visit) {
61
+ if (ts.isJsxElement(node) || ts.isJsxSelfClosingElement(node)) {
62
+ visit(node)
63
+ return
64
+ }
65
+ if (ts.isJsxFragment(node)) {
66
+ for (const child of node.children) directJsxRoots(child, visit)
67
+ return
68
+ }
69
+ if (ts.isJsxExpression(node) && !node.expression) return
70
+ ts.forEachChild(node, (child) => directJsxRoots(child, visit))
71
+ }
72
+
73
+ export function inspectCardChildSpacing(source, filePath = "source.tsx") {
74
+ const sourceFile = ts.createSourceFile(
75
+ filePath,
76
+ source,
77
+ ts.ScriptTarget.Latest,
78
+ true,
79
+ ts.ScriptKind.TSX,
80
+ )
81
+ const findings = []
82
+
83
+ function walk(node) {
84
+ if (
85
+ ts.isJsxElement(node) &&
86
+ tagNameOf(node, sourceFile) === "Card" &&
87
+ !hasMediaVariant(node.openingElement, sourceFile)
88
+ ) {
89
+ for (const child of node.children) {
90
+ directJsxRoots(child, (root) => {
91
+ const spacingClass = spacingClassOf(root, sourceFile)
92
+ if (!spacingClass) return
93
+ const position = sourceFile.getLineAndCharacterOfPosition(
94
+ root.getStart(),
95
+ )
96
+ findings.push({
97
+ line: position.line + 1,
98
+ tag: tagNameOf(root, sourceFile),
99
+ spacingClass,
100
+ })
101
+ })
102
+ }
103
+ ts.forEachChild(node, walk)
104
+ return
105
+ }
106
+ ts.forEachChild(node, walk)
107
+ }
108
+
109
+ walk(sourceFile)
110
+ return findings
111
+ }