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.
- package/AGENTS.md +17 -0
- package/CLAUDE.md +14 -0
- package/DESIGN.md +5 -3
- package/MIGRATION.md +4 -0
- package/PUBLISHING.md +36 -14
- package/README.md +84 -2
- package/RELEASE.md +2 -1
- package/UPDATING.md +160 -0
- package/bin/card-child-spacing.js +111 -0
- package/bin/check-duplicates.js +167 -0
- package/bin/init.js +19 -0
- package/bin/lint.js +10 -0
- package/contracts/components.json +243 -28
- package/contracts/composition.json +153 -0
- package/contracts/design-context.json +25 -0
- package/contracts/rules.json +34 -2
- package/contracts/screen-patterns.json +228 -0
- package/contracts/token-hex-cache.json +543 -0
- package/dist/index.js +2439 -1773
- package/dist/native/ui.js +1375 -1272
- package/dist/{native-BelCzh9_.js → native-BYLnbCN-.js} +74 -1
- package/dist/native.js +1 -1
- package/dist/types/class-names.d.ts +1 -1
- package/dist/types/components/patterns/_internal/carousel-primitives.d.ts +24 -0
- package/dist/types/components/patterns/bottom-sheet-frame.d.ts +1 -1
- package/dist/types/components/patterns/coach-mark-overlay.d.ts +1 -1
- package/dist/types/components/patterns/commerce/bottom-tab-bar.d.ts +8 -1
- package/dist/types/components/patterns/content-carousel.d.ts +18 -0
- package/dist/types/components/patterns/empty-state.d.ts +1 -1
- package/dist/types/components/patterns/error-state.d.ts +8 -2
- package/dist/types/components/patterns/field.d.ts +23 -0
- package/dist/types/components/patterns/list-item.d.ts +22 -2
- package/dist/types/components/patterns/mobile-floating-action-button.d.ts +1 -1
- package/dist/types/components/patterns/screen.d.ts +4 -1
- package/dist/types/components/patterns/share-buttons.d.ts +7 -3
- package/dist/types/components/patterns/shells/admin-shell.d.ts +5 -1
- package/dist/types/components/patterns/shells/app-shell.d.ts +5 -1
- package/dist/types/components/patterns/shells/marketing-shell.d.ts +5 -1
- package/dist/types/components/patterns/side-drawer-frame.d.ts +1 -1
- package/dist/types/components/ui/alert-dialog.d.ts +1 -1
- package/dist/types/components/ui/auto-grow-textarea.d.ts +5 -2
- package/dist/types/components/ui/button.d.ts +1 -1
- package/dist/types/components/ui/container.d.ts +15 -0
- package/dist/types/components/ui/date-picker.d.ts +9 -2
- package/dist/types/components/ui/date-time-picker.d.ts +27 -0
- package/dist/types/components/ui/dialog.d.ts +7 -2
- package/dist/types/components/ui/icon-badge.d.ts +17 -0
- package/dist/types/components/ui/input.d.ts +7 -1
- package/dist/types/components/ui/section-nav.d.ts +28 -0
- package/dist/types/components/ui/section.d.ts +17 -0
- package/dist/types/components/ui/sheet.d.ts +7 -2
- package/dist/types/components/ui/skip-link.d.ts +8 -0
- package/dist/types/components/ui/textarea.d.ts +6 -1
- package/dist/types/components/ui/time-picker.d.ts +4 -1
- package/dist/types/index.d.ts +22 -2
- package/dist/types/lib/use-value-length.d.ts +25 -0
- package/dist/types/native/components/CheckboxField.d.ts +3 -1
- package/dist/types/native/components/DateTimePicker.d.ts +13 -0
- package/dist/types/native/components/IconBadge.d.ts +13 -0
- package/dist/types/native/components/Switch.d.ts +4 -1
- package/dist/types/native/components/index.d.ts +2 -0
- package/dist/types/tokens/native/scales.d.ts +73 -0
- package/eslint/deprecated.js +1 -1
- package/package.json +20 -20
- package/scripts/codemod/README.md +15 -0
- package/scripts/codemod/check-migration.mjs +129 -0
- package/src/components/COMPONENT_LOOKUP.md +12 -4
- package/src/native/COMPONENT_LOOKUP.md +3 -1
- package/src/preset.css +25 -0
- package/src/styles/glass.css +249 -33
- package/templates/AGENTS.md +18 -2
- package/templates/CLAUDE.md +18 -2
- 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
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
|
-
>
|
|
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
|
-
|
|
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.
|
|
24
|
-
2. `npm
|
|
25
|
-
3. `npm
|
|
26
|
-
4. `
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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
|
-
-
|
|
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
|
|
159
|
-
|
|
160
|
-
|
|
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
|
|
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
|
-
/*
|
|
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
|
+
}
|