@cakejp/design-system 0.22.1 → 0.23.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/CHANGELOG.md +82 -0
- package/CLAUDE.md +3 -1
- package/MIGRATION.md +43 -0
- package/UPDATING.md +1 -1
- package/bin/check-tokens.mjs +20 -0
- package/contracts/components.json +87 -25
- package/contracts/composition.json +9 -9
- package/contracts/rules.json +1 -1
- package/contracts/screen-patterns.json +1 -1
- package/dist/components/ec/admin-shell.js +7 -7
- package/dist/components/ec/anniversary-card.js +1 -1
- package/dist/components/ec/chart-controls.js +7 -7
- package/dist/components/ec/coupon-card.js +10 -10
- package/dist/components/ec/delivery-calendar.js +1 -1
- package/dist/components/ec/mypage-shell.js +1 -1
- package/dist/components/ec/order-section.js +1 -1
- package/dist/components/ec/order-summary.js +7 -5
- package/dist/components/ec/product-card.js +32 -30
- package/dist/components/ec/product-detail-sidebar.js +1 -1
- package/dist/components/ec/product-list-item.js +57 -56
- package/dist/components/ec/product-option.js +30 -30
- package/dist/components/ec/review-summary.js +1 -1
- package/dist/components/ec/shop-card.js +7 -7
- package/dist/components/foundations/accordion.js +1 -1
- package/dist/components/foundations/alert-dialog.js +65 -43
- package/dist/components/foundations/alert.js +74 -68
- package/dist/components/foundations/badge.js +4 -4
- package/dist/components/foundations/button.js +15 -15
- package/dist/components/foundations/checkbox-card.js +18 -18
- package/dist/components/foundations/checkbox.js +6 -6
- package/dist/components/foundations/chip-variants.js +8 -8
- package/dist/components/foundations/data-table.js +244 -209
- package/dist/components/foundations/dialog.js +84 -60
- package/dist/components/foundations/drawer.js +61 -53
- package/dist/components/foundations/field.js +51 -35
- package/dist/components/foundations/file-input.js +1 -1
- package/dist/components/foundations/input.js +9 -8
- package/dist/components/foundations/popover.js +15 -12
- package/dist/components/foundations/progress.js +19 -18
- package/dist/components/foundations/radio-group.js +26 -23
- package/dist/components/foundations/select.js +9 -8
- package/dist/components/foundations/sheet.js +82 -59
- package/dist/components/foundations/skeleton.js +6 -6
- package/dist/components/foundations/slider.js +7 -7
- package/dist/components/foundations/sonner.js +9 -8
- package/dist/components/foundations/switch.js +3 -2
- package/dist/components/foundations/tabs.js +5 -5
- package/dist/components/foundations/textarea.js +7 -6
- package/dist/components/foundations/toggle-group.js +5 -5
- package/dist/components/primitives/admin-header.js +3 -3
- package/dist/components/primitives/admin-side-nav.js +101 -92
- package/dist/components/primitives/category-shortcuts.js +6 -6
- package/dist/components/primitives/chat-composer.js +1 -1
- package/dist/components/primitives/chip.js +25 -25
- package/dist/components/primitives/combobox.js +74 -63
- package/dist/components/primitives/content-carousel.js +64 -62
- package/dist/components/primitives/date-picker.js +99 -96
- package/dist/components/primitives/error-state.js +9 -9
- package/dist/components/primitives/filter-bar.js +4 -4
- package/dist/components/primitives/footer.js +1 -1
- package/dist/components/primitives/form-field.js +8 -8
- package/dist/components/primitives/funnel-shell.js +5 -5
- package/dist/components/primitives/header.js +16 -16
- package/dist/components/primitives/image-carousel.js +42 -41
- package/dist/components/primitives/image-gallery.js +61 -58
- package/dist/components/primitives/image-input.js +2 -2
- package/dist/components/primitives/image-uploader.js +1 -1
- package/dist/components/primitives/kebab-menu.js +20 -16
- package/dist/components/primitives/list-item.js +17 -17
- package/dist/components/primitives/menu-drawer.js +11 -11
- package/dist/components/primitives/multi-select.js +66 -66
- package/dist/components/primitives/notification-list.js +13 -13
- package/dist/components/primitives/number-input.js +118 -112
- package/dist/components/primitives/progress-steps.js +3 -3
- package/dist/components/primitives/search-bar.js +6 -6
- package/dist/components/primitives/section-nav.js +1 -1
- package/dist/components/primitives/side-nav.js +1 -1
- package/dist/components/primitives/sub-nav.js +12 -12
- package/dist/components/primitives/tag.js +3 -3
- package/dist/components/primitives/workspace-shell.js +8 -8
- package/dist/index.css +1 -1
- package/dist/index.js +1479 -704
- package/dist/lib/focus-restore.js +67 -0
- package/dist/lib/focus-ring.js +1 -1
- package/dist/lib/ime.js +17 -0
- package/dist/lib/search-normalize.js +30 -0
- package/dist/types/components/ec/admin-shell.d.ts +1 -1
- package/dist/types/components/foundations/alert-dialog.d.ts +2 -2
- package/dist/types/components/foundations/alert.d.ts +14 -1
- package/dist/types/components/foundations/card.d.ts +3 -3
- package/dist/types/components/foundations/confirm-dialog.d.ts +3 -3
- package/dist/types/components/foundations/data-table.d.ts +1 -1
- package/dist/types/components/foundations/dialog.d.ts +2 -2
- package/dist/types/components/foundations/drawer.d.ts +1 -1
- package/dist/types/components/foundations/field.d.ts +23 -3
- package/dist/types/components/foundations/popover.d.ts +1 -1
- package/dist/types/components/foundations/sheet.d.ts +4 -3
- package/dist/types/components/foundations/sonner.d.ts +3 -2
- package/dist/types/components/primitives/admin-side-nav.d.ts +2 -0
- package/dist/types/components/primitives/combobox.d.ts +6 -0
- package/dist/types/components/primitives/date-picker.d.ts +8 -3
- package/dist/types/components/primitives/funnel-shell.d.ts +1 -1
- package/dist/types/components/primitives/kebab-menu.d.ts +10 -1
- package/dist/types/components/primitives/number-input.d.ts +20 -1
- package/dist/types/components/primitives/progress-steps.d.ts +1 -1
- package/dist/types/components/primitives/section.d.ts +1 -1
- package/dist/types/components/primitives/workspace-shell.d.ts +2 -2
- package/dist/types/index.d.ts +3 -4
- package/dist/types/lib/focus-restore.d.ts +52 -0
- package/dist/types/lib/focus-ring.d.ts +3 -0
- package/dist/types/lib/ime.d.ts +36 -0
- package/dist/types/lib/search-normalize.d.ts +28 -0
- package/package.json +3 -1
- package/src/components/COMPONENT_LOOKUP.md +12 -12
- package/src/preset-standalone.css +43 -21
- package/src/preset.css +36 -18
- package/src/styles/primitive.css +1 -0
- package/src/styles/semantic.css +12 -2
- package/tokens.json +22 -3
package/CHANGELOG.md
CHANGED
|
@@ -11,6 +11,88 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
11
11
|
|
|
12
12
|
---
|
|
13
13
|
|
|
14
|
+
## [0.23.0] - 2026-11-06
|
|
15
|
+
|
|
16
|
+
KSK(姉妹 DS)の 2026-10-14〜11-02 の改善を取り込み(見た目の既定値は変えない範囲。見た目が変わる候補は #335 で判断待ち)。
|
|
17
|
+
|
|
18
|
+
### ⚠️ Upgrade impact
|
|
19
|
+
|
|
20
|
+
- **light の `--Surface-Secondary` / `--Surface-Tertiary` がグレーからベージュ(`#FCF9F2`)になる(視覚変更あり)**: 情報をまとめる面の色として使っている箇所はそのままでよい。押せる部品(自前のボタン・チップ・タブ・ラベル)の地、hover / active / focus / selected / disabled の地、溝・トラック・スケルトン・画像の仮の地、画面全体の地(`min-h-screen` の地など)に使っている箇所は、グレーを保つ `--Surface-Neutral-Secondary` / `--Surface-Neutral-Tertiary` に付け替える(手順は MIGRATION.md の「面の色をベージュに」)
|
|
21
|
+
- DS の部品は付け替え済み。`Card` の既定の地(`bg-card` = `--card`)と `Section background="subtle"`・Alert 中立・表の見出し行はベージュになる。shadcn 互換の `--secondary` / `--muted` / `--accent` は Neutral に付け替えたので、`bg-muted` / `bg-accent` / `hover:bg-accent` 等はグレーのまま
|
|
22
|
+
- dark の値は変わらない(`--Surface-Neutral-*` は dark では `--Surface-Secondary` / `--Surface-Tertiary` と同値)
|
|
23
|
+
- **Alert の既定の読み上げが variant で変わる(挙動変化)**: これまで全 variant が `role="alert"`(即時に割り込んで読み上げ)だった。今後は `error` / `warning` / `inline-caution` / `inline-warning` が `role="alert"`、`success` / `info` / `inline-info` が `role="status"`(読み上げ中の内容を遮らない)。画面表示時から出ている静的な補足が assertive に読み上げられていたのを直すための変更で、見た目は変わらない。
|
|
24
|
+
- `role="alert"` の存在をテストで探している consumer(`getByRole("alert")`、スナップショット、`querySelector('[role=alert]')`)は、info / success の Alert で見つからなくなる。`getByRole("status")` に変えるか、`live="alert"` / `role="alert"` を明示する
|
|
25
|
+
- 従来どおり即時に読み上げたい info / success(送信直後の完了通知など)は `live="alert"` を付ける。読み上げ領域にしたくない静的な補足は `live="off"`
|
|
26
|
+
- `role` を直接渡している箇所は、これまでと同じくそのまま優先される
|
|
27
|
+
- `querySelectorAll('[role="alert"]')` などで inline-info / info / success の Alert を探している consumer のテスト(実例: cake-api の `staffManagement.integration.test.tsx`)は、`[role="status"]` に直す。error / warning 系を探しているものは変わらない
|
|
28
|
+
- **Progress に `max` を渡している場合、帯の長さが `value / max` の割合になる**: 従来は `max` を無視して `value` を % として帯を描いていた(`max={200}`・`value={150}` で 100% 側に偏っていた)。`aria-valuenow` も 0〜`max` の範囲で付く。`max` を渡していない Progress(0〜100)は変わらない
|
|
29
|
+
- **`tap-target` と `absolute` / `fixed` / `sticky` を併用すると指定どおりの `position` になる**: `.tap-target { position: relative }` を `@layer components` に移したため、consumer が `tap-target`(KebabMenu の `className` を含む)に `absolute` / `fixed` / `sticky` を足すと、従来の `relative` ではなく指定した `position` になる。`relative` のままにしたい画面は何も足さなければ従来どおり
|
|
30
|
+
- **DataTable の行 `onClick` は、セル内の操作要素から来たクリックでは呼ばれない**: 行クリックで詳細を開く表では不具合の解消になる。逆に、セル内のボタン・リンクを押したときにも行の `onClick` が呼ばれることを前提にしていた consumer は、そのセル側のハンドラへ処理を移す。href 未指定の `DataTableLinkCell`(既定 `"#"`)をクリックしても行の `onClick` は呼ばれない(リンクを押した扱いになる)。子の処理が `preventDefault()` したクリック・キーも行へ渡さない
|
|
31
|
+
- **`Combobox` の絞り込みが「連続した部分一致」になり、並びは元の順のまま**: これまでは cmdk 既定の fuzzy スコア(「とうきょう」に対して「と…う…き…」と飛び飛びの文字が当たる)で絞り込み、一致度の高い順に並べ替えていた。今後は label / `keywords` に検索語が連続して含まれるか(表記ゆれは同一視)の二値で判定し、当たった候補は `options` の並びのまま表示する
|
|
32
|
+
- 飛び飛びの文字だけで当たっていた候補は出なくなる。一致度順の並べ替えに頼っていた画面(前方一致を上に出したい等)は、`options` を呼び出し側で並べ替えて渡す
|
|
33
|
+
- 候補の個数や並びを `getAllByRole("option")` の順序で検証しているテストは、期待値を元の並びに直す
|
|
34
|
+
- **`DatePicker` / `DateTimePicker` は、選択中の日をもう一度押しても値が消えなくなった**: 再押下では同じ日のまま閉じる(`DateTimePicker` は時刻も保つ)。値を消せるのは `clearable` の × だけ
|
|
35
|
+
- 「選択中の日を再クリックして値を消す」操作に頼っていた画面(任意項目)は、値を空に戻す手段が無くなる。`clearable` を付ける
|
|
36
|
+
|
|
37
|
+
### ✨ Added
|
|
38
|
+
|
|
39
|
+
- **`FieldSet` に `gap`、`FieldLegend` に `size="sm"` を追加(opt-in・既定の見た目は不変)**(姉妹 DS ksk #714 の逆輸入): `<legend>` は fieldset の枠側に描かれ flex の並びに入らないため、`FieldSet` の間隔は legend の直下に効かない(0px)。`gap="sm" | "md" | "lg"`(8 / 16 / 24px)を指定すると、子の間隔をその段にし、legend の下にも同じ間隔を空ける。`FieldLegend size="sm"` は `typo-label-md` + `Text-Medium-Emphasis` の小見出し(絞り込みの選択肢グループ等)。未指定は従来どおり gap-6・legend 直下 0px。型 `FieldSetGap` を公開
|
|
40
|
+
- **`NumberInput` に `name` / `inputRef` / `inputProps` を追加**(姉妹 DS ksk #662 の逆輸入): これまで props はグループの div に付くだけで、`<form>` の FormData 送信や入力欄のフォーカス制御ができなかった
|
|
41
|
+
- `name`: FormData に現在値が素の数値で入る。`formatOptions`(桁区切り・通貨表示)や `editable={false}` のときは、表示ではなく素の数値を持つ hidden input に付く。`disabled` のときは送らない
|
|
42
|
+
- `inputRef`: 内部の入力欄(`<input>`)への ref
|
|
43
|
+
- `inputProps`: 入力欄だけに付けるイベント・属性(`onFocus` / `onBlur` / `onKeyDown` / `autoComplete` / `data-*` 等)。`onFocus` / `onBlur` は部品の処理(編集開始・値の確定)の後、`onKeyDown` は部品のキー処理の前に呼ぶ(`preventDefault` で Enter 確定・矢印キーの増減を止められる)。値・id・name・aria・disabled は渡せない。型 `NumberInputInputProps` を公開
|
|
44
|
+
- 既存の props(グループの div への spread)と、指定しないときの DOM は変わらない
|
|
45
|
+
- **KebabMenu に `menuLabel`**: トリガーボタンの読み上げ名(`aria-label`)を変えられる。既定は従来どおり「メニュー」。一覧の各行に置くときは「苺のショートケーキのメニュー」のように対象が分かる名前を渡す(全行が「メニュー」だと読み上げ・音声操作で区別できない)
|
|
46
|
+
- **Alert に `live`**: 読み上げの強さを `"alert"` / `"status"` / `"off"`(role を付けない)で指定できる。`role` を直接渡した場合はそちらが最優先(下の「導入上の注意」参照)
|
|
47
|
+
- **`check-tokens` に警告 `translucent-focus-ring`**: `focus:ring-[var(--Focus-High-Emphasis)]/50` や `focus-visible:ring-ring/50` のような半透明フォーカスリングの直書きを警告する(exit code は変えない)。高コントラスト opt-in(`--Focus-Ring-Control`)で不透明に切り替わらないため、`ring-[color:var(--Focus-Ring-Control,color-mix(in_oklab,var(--Focus-High-Emphasis)_50%,transparent))]` か `FOCUS_RING*` 定数に置き換える。エラー表示の `aria-invalid:ring-.../20` は対象外。DS 内向けの `scripts/lint-scratch.sh --components` にも同じ検出(C5・エラー)を追加
|
|
48
|
+
|
|
49
|
+
### 🎨 Changed
|
|
50
|
+
|
|
51
|
+
- **面の色をケーキ配色に合わせる(ベリー = 押すもの / ベージュ = 情報をまとめる面 / グレー = 押せる部品と画面の地)**: light の `--Surface-Secondary` / `--Surface-Tertiary` を `--Primitive-Wood-25`(`#FCF9F2`)に変更(`semantic.css`・`preset-standalone.css`・`tokens.json`)
|
|
52
|
+
- パレットに `--Primitive-Wood-25: #FCF9F2` を追加
|
|
53
|
+
- グレーを保つ意味トークン `--Surface-Neutral-Secondary`(light = Gray-50 `#FBF9F8`)/ `--Surface-Neutral-Tertiary`(light = Gray-100 `#F4F2F1`)を追加。dark は `--Surface-Secondary` / `--Surface-Tertiary` と同値
|
|
54
|
+
- DS 内の使用箇所を仕分けて、押せる部品(Button tertiary・Chip・Badge・Tag・NumberInput・タブの溝など)、hover / active / selected / disabled の地、溝・トラック(Slider の `--Surface-Control-Track` のフォールバックを含む)、スケルトン・画像の仮の地、画面全体の地(`AdminShell` / `MypageShell` / `WorkspaceShell` / `FunnelShell`)を Neutral に付け替えた。見た目はこれまでと同じグレー
|
|
55
|
+
- ベージュになるのは、`Card` 既定の地、`Section background="subtle"`、Alert 中立の地、`DataTable` の見出し行・セクション行、`Prose` の表の見出し・code・pre、CountdownTimer・ReviewCard・ReviewForm・ProductDetailSidebar の情報ボックス、ProductListItem の `lp` variant
|
|
56
|
+
- コントラスト検査に「ベージュの面の上の補足文字(`--Text-Low-Emphasis`)」と「グレーの部品の上の文字(`--Surface-Neutral-Tertiary`)」の組を追加。前者は 4.30:1(旧グレーでも 4.31:1 で未達だった組)のため #335 の期限付き例外に登録(文字色は変えていない)
|
|
57
|
+
|
|
58
|
+
### 🐛 Fixed
|
|
59
|
+
|
|
60
|
+
- **Dialog / Sheet / AlertDialog / Drawer を Trigger 無しで開くと、閉じたあとのフォーカスが body に落ちていた**(KSK #850 / #851 / #662 の逆輸入): 閉じたとき、その回に開く直前にフォーカスがあった要素(一覧の行のボタンなど)へ戻すようにした。開くたびに記録し直すので、行ごとのボタンから 1 つのダイアログを開いても毎回その行へ戻る。戻すときは `preventScroll` で、一覧がスクロールで飛ばない。ResponsiveDialog・CommandDialog など内部でこれらを使う部品にも効く
|
|
61
|
+
- 戻り先が DOM から消えている・disabled・inert のときは従来どおり Radix の既定(Trigger へ戻す)に任せる
|
|
62
|
+
- Sheet / Dialog / AlertDialog は記録を Root 側に持つため、開いたまま Content を作り直しても(key の変更など)元の要素へ戻る
|
|
63
|
+
- 導入上の注意: consumer の `onCloseAutoFocus` が先に呼ばれ、`event.preventDefault()` すると DS は何もしない。閉じたあとに独自の場所へフォーカスを移している画面は、従来どおり `preventDefault()` してから移せばよい。`useConfirm`(ConfirmDialogProvider)は従来どおり自前で戻す(confirm() を呼んだ時点の要素・メニューのトリガーへ戻す)
|
|
64
|
+
- **日本語入力の変換中に Esc を押すと、Dialog / Sheet / AlertDialog / Drawer / Popover が閉じて入力内容が消えていた**: 変換中(`isComposing`、または Safari の変換終了時の `keyCode` 229)の Esc では閉じないようにした。変換していない Esc は従来どおり閉じる。Popover 経由の Combobox / MultiSelect の検索欄にも効く
|
|
65
|
+
- consumer の `onEscapeKeyDown` は従来どおり呼ばれる(DS の判定より先に呼ぶ)
|
|
66
|
+
- **`FormField` 配下の `RadioGroup` に読み上げ名が付かなかった**(姉妹 DS ksk #734 #741 #746 #751 の逆輸入): `role="radiogroup"` は `<label for>` では名前が付かない。Select / Switch 等と同じく、`FormField` のラベル id を `aria-labelledby`、説明・エラーを `aria-describedby` / `aria-invalid` で受け取る(tile / chip 共通)。利用側の `aria-label` / `aria-labelledby` / `aria-invalid` の明示が優先され、`aria-describedby` は連結される。FormField の外の DOM は変わらない
|
|
67
|
+
- **`RadioGroup` tile の選択中の点が、Windows のハイコントラスト(forced-colors)で消えていた**(姉妹 DS ksk #782 の逆輸入): 点を背景色で描いていたため Canvas に置き換わり、選択中でも中が空に見えた。forced-colors のときだけ `Highlight`(無効時は `GrayText`)で塗る。通常表示は変わらない
|
|
68
|
+
- **`Combobox` の絞り込みが表記ゆれに弱かった**(姉妹 DS ksk #853 の逆輸入): 既定の絞り込みは大文字小文字しかそろえず、「しぶや」で「シブヤ」、「市ケ谷」で「市ヶ谷」に当たらなかった。label と `keywords` を、大文字小文字・全角半角(NFKC)・ひらがな/カタカナ・漢字に挟まれた「ヶ/ケ/ヵ/が」(市ヶ谷/市ケ谷・霞が関/霞ケ関)を区別しない部分一致で絞り込む(「ケーキ」と「がーき」は同一視しない)
|
|
69
|
+
- **`Combobox` で選んだ値が読み上げられなかった**(姉妹 DS ksk #853 の逆輸入): 選択中は読み上げ名が「ラベル + 選択中の値」(例「都道府県 東京都」)になる。ラベルは 利用側の `aria-labelledby` → `aria-label`(無ければ placeholder)→ `FormField` のラベル の順。未選択のときの名前は従来どおり
|
|
70
|
+
- 導入上の注意: 選択中の Combobox を `getByRole("combobox", { name: "都道府県" })` のように名前の完全一致で探しているテストは、名前に値が加わるため見つからなくなる。`{ name: /^都道府県/ }` などに直す
|
|
71
|
+
- **`DatePicker` / `DateTimePicker` で、選択中の日をもう一度押すと値が消えていた**(姉妹 DS ksk #847 の逆輸入): 誤操作で値が消えても気付けなかった。挙動変化と対処は上の「Upgrade impact」を参照
|
|
72
|
+
- **`DatePicker` / `DateTimePicker` のカレンダーが、値があっても常に今月で開いていた**: 選択中の日が別の月にあると見えなかった。開くたびに選択中の日の月を表示する(値が無ければ今月)。開く月を指定する `defaultMonth` を追加し、渡したときは値より優先する
|
|
73
|
+
- **`Combobox` / `MultiSelect` の候補一覧(Popover の `role="dialog"`)に名前が無かった**: 開いた状態で a11y 検査(aria-dialog-name)に違反していた。トリガーと同じ出どころ(利用側の `aria-labelledby` → `aria-label` / placeholder → `FormField` のラベル)の名前を付ける。見た目は変わらない
|
|
74
|
+
- **DataTable: セル内の操作で行の `onClick` が誤って発火していた**: `DataTableSelectCell` の選択肢(Portal 先)・`DataTableInputCell`・`DataTableLinkCell`、セル内に置いた button / a / input / select / textarea / `[role=combobox|option|checkbox|switch…]` などを操作しても、`DataTableRow` に付けた `onClick` が呼ばれなくなった。`onKeyDown` も Enter / Space だけ、セル内の操作要素から来たものを渡さない(Tab・矢印などは、子が `preventDefault` していなければ行へ渡す)。セルの `td` に `data-table-ignore-row-click` を付けると、そのセル内の操作も行へ伝えない。`DataTableActionCell` / `DataTableCheckboxCell` の既存の伝播停止はそのまま
|
|
75
|
+
- **Progress: `value` が読み上げに伝わらなかった**: `value` を Radix の Root に渡すようにし、`aria-valuenow` と `data-state`(loading / complete)が付く。`value` は 0〜`max`(未指定は 100)に丸める。未指定・`null`・NaN は不確定(indeterminate)で `aria-valuenow` が付かない。`max` を渡さない場合、見た目の帯は変わらない(`max` を渡した場合は上の「Upgrade impact」を参照)
|
|
76
|
+
- **AdminSideNav(AdminShell のスマホ用ドロワー): 別タブで開く操作でもドロワーが閉じていた**: Cmd / Ctrl / Shift / Alt 付きクリック・中クリック・`target="_blank"`(`_self` 以外)のリンクでは `onOpenChange(false)` を呼ばない(今の画面が移らないため)。通常の左クリックは従来どおり閉じる(SPA の `preventDefault` 遷移も含む)
|
|
77
|
+
- **KebabMenu: 当たり判定が 32px しか無かった**: 見た目は 32px のまま、`tap-target` で当たり判定を 44px に広げた。隣のボタンとの間は 12px 以上空ける。`.tap-target` は `@layer components` に入れ、consumer の `className`(`absolute` など)で `position` を上書きできる
|
|
78
|
+
- **KebabMenu: キーボードでフォーカスしても現在地が見えなかった**: トリガーに DS 標準のフォーカスリング(`FOCUS_RING_ONLY`)を付けた。フォーカスしていないときの見た目は変わらない
|
|
79
|
+
- **OrderSummary: 画面下に固定したとき、ホームインジケータのある iPhone で BottomTabBar に重なっていた**: `bottom-[52px]` を `bottom-[calc(52px+env(safe-area-inset-bottom))]` にした。BottomTabBar は下端に safe-area 分の余白を足して高さが 52px より高くなるため。`viewport-fit=cover` 以外(safe-area が 0)では見た目は変わらない
|
|
80
|
+
- **`scrollbar-hide` がどの CSS にも定義されておらず、横スクロール部品のスクロールバーが消えていなかった**: 11 部品(ProductCarousel / BannerCarousel / CategoryScroll / CategoryShortcuts / FilterBar / ImageGallery / StatusCountTabs / SubNav と、`scrollbar-none` を書いていた ToggleGroup / ImageCarousel / ContentCarousel)が使っていたが、Tailwind v4 本体に `scrollbar-hide` は無く、`scrollbar-none` も tailwindcss 4.2.1 ではクラスを書いても CSS が生成されなかった(実測)。`preset.css` に `@utility scrollbar-hide`(`scrollbar-width` / `-ms-overflow-style` / `::-webkit-scrollbar`)、`preset-standalone.css` に同名の素のクラスを定義した。ToggleGroup / ImageCarousel / ContentCarousel は `scrollbar-none` から `scrollbar-hide` に統一した(Tailwind のどの版でも・Safari 18.2 未満でも効く)
|
|
81
|
+
- 導入上の注意: 上の 11 部品は、これまでスクロールバーが出ていた環境(Windows・Linux の常時表示スクロールバー)で出なくなる。意図どおりの見た目。consumer が自前で `scrollbar-hide` を定義している場合は二重定義になるだけで害はない
|
|
82
|
+
- **`FOCUS_RING_WITHIN`(SearchBar の枠・FileInput など)と ProductOption の select のリングが、高コントラスト opt-in(`--Focus-Ring-Control`)で不透明に切り替わらなかった**: `ring-[var(--Focus-High-Emphasis)]/50` の直書きを `FOCUS_RING` / `FOCUS_RING_ONLY` と同じ `ring-[color:var(--Focus-Ring-Control,color-mix(…50%…))]` の形に揃えた。既定の見た目は変わらない
|
|
83
|
+
- **写真・メディアの上の操作子にフォーカスリングが無く、ブラウザ既定の outline 頼みだった**: ImageGallery の前後の矢印・ドット・サムネイル、ImageCarousel / ContentCarousel の矢印・ドット、ProductCard のお気に入り、ProductListItem のブックマークに DS のリングを付けた(`FOCUS_RING_ONLY`。overflow-hidden の行の中の ProductListItem のブックマークだけ `FOCUS_RING_INSET`)。フォーカスしていないときの見た目は変わらない
|
|
84
|
+
- PC(`@[960px]`)で `opacity-0`(ホバーで出現)の ImageCarousel / ContentCarousel の矢印は、キーボードフォーカスが来たら見える(`@[960px]:focus-visible:opacity-100`)
|
|
85
|
+
- ImageGallery のサムネイル列は、リング(3px)がスクロール領域に切り取られないよう 内側に `p-1`(余白 4px)を取り、外へ戻す負マージンを付けた。PC の縦の列は `-m-1` でレイアウト・寸法は変わらない。SP の横の列は右へはみ出さないよう `-my-1 -ml-1` にしたため、列の中身の幅が 4px 狭くなり、サムネイルの合計幅がちょうどその境目のときだけ列内に数 px の横スクロールが出うる
|
|
86
|
+
- 導入上の注意: consumer がこれらの部品に `focus-visible:outline-*` などを自前で足している場合は、DS のリングと重なって見えないか確認する。写真の色に溶けにくい二重リング(白 + 濃色)は見た目の判断が要るため、今回は入れていない
|
|
87
|
+
|
|
88
|
+
### 🛠 Tooling
|
|
89
|
+
|
|
90
|
+
- **配布物のサイズと tree-shaking の予算ゲート(`npm run check:bundle`)**: `build:lib` の後に `dist` を測る。`dist/index.js` / `dist/index.css` / `dist/**/*.js` 合計の gzip サイズと、`cn` / `Button` / `Badge` / `Card` / `Dialog` / `Select` / `DatePicker` を 1 つだけ import して esbuild でバンドルしたときの gzip サイズが、実測 +10% の予算以内か、react-day-picker・date-fns・cmdk・vaul・react-hook-form・next-themes・floating-ui 等の重い依存が混ざっていないかを CI(`check` ジョブ)で検査する。`npm run check` には含めない(dist が要るため)。devDependencies に `esbuild`(すでに vite 経由で入っていた版)を明示した(KSK #768)
|
|
91
|
+
- 修正した漏れ: バレル(`src/index.ts`)が `import { toast } from "sonner"` を直接持っていたため、sonner(minify 後約 19KB)が、どの部品を 1 つ import しても利用側のバンドルに残っていた。`toast` を `foundations/sonner.tsx` 経由で公開する形にして解消(公開 API の名前・型は変更なし。`cn` 単独のバンドルは gzip 12.9KB → 8.7KB、`Button` は 16.9KB → 12.7KB)。**導入上の注意**: 利用側のコード変更は不要。バンドルが軽くなるだけで、`toast` は従来どおり `@cakejp/design-system` から import できる
|
|
92
|
+
- **コントラスト検査(`lint:contrast`)に状態色の「文字 × 淡い面」を追加**: Badge の caution / warning / info / success の subtle、Alert の inline-caution / inline-warning、ProductDetailSidebar の案内(Info-Light 上の Text-Info)、Alert inline-info・Badge muted-subtle を light / dark の両方で 4.5:1 検査する。基準未達の 7 組(caution 2.66〜3.90、warning 3.55、dark の info 3.46、success/Forest-50 3.06)は、色を変えずに #335・見直し期限 2027-02-01 の例外として登録し、悪化だけを止める(KSK #852)
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
14
96
|
## [0.22.1] - 2026-10-26
|
|
15
97
|
|
|
16
98
|
### ✨ Added
|
package/CLAUDE.md
CHANGED
|
@@ -105,6 +105,8 @@ PdM や社長が AI(Claude 等)で HTML モックを作る際、このパッ
|
|
|
105
105
|
| テキスト(弱) | `var(--color-gray-400)` |
|
|
106
106
|
| エラー | `var(--color-red-500)` |
|
|
107
107
|
| 浮遊レイヤーの地(メニュー・ポップオーバー・ダイアログ・シート) | `var(--Surface-Elevated)` |
|
|
108
|
+
| 情報をまとめる押せない面(説明ボックス・フォームのまとまり・表の見出し行。light はベージュ) | `var(--Surface-Secondary)` / `var(--Surface-Tertiary)` |
|
|
109
|
+
| 押せる部品・hover / 選択 / 無効の地・溝・画像の仮の地・画面全体の地(グレー) | `var(--Surface-Neutral-Secondary)` / `var(--Surface-Neutral-Tertiary)` |
|
|
108
110
|
| 成功 | `var(--color-green-500)` |
|
|
109
111
|
|
|
110
112
|
詳細は `tokens.json` を参照。高コントラスト(OS の「コントラストを上げる」か、`<html data-contrast="more">`。`#root` など Portal の外側の要素に付けると body 直下に描かれる Dialog / Popover / 選択肢の一覧には効かない)のときの枠・溝・フォーカスリングは DS が自動で切り替えるので、`--Border-Control` 等を自分で宣言・上書きしない。
|
|
@@ -125,7 +127,7 @@ PdM や社長が AI(Claude 等)で HTML モックを作る際、このパッ
|
|
|
125
127
|
- **RadioGroupItem を div で囲む / Label を併置する**: 禁止 — **ラベルは `children` として内側に書く**(`<RadioGroupItem value="x">ラベル</RadioGroupItem>`)。タイルの枠は `RadioGroupItem` 自身が描くので外側で囲むと**枠が二重**になる。`<Label htmlFor>` を兄弟に置くのもラベル重複で誤り。補足説明は `description`、展開内容は `expandedContent` prop を使う
|
|
126
128
|
- **Tag に onClick**: 禁止 — 押せるものは Chip を使う
|
|
127
129
|
- **選択チップ(単一選択)**: `Chip` に onClick で排他選択を自作しない — 単一選択は `RadioGroup variant="chip"` を使う(Radix のキーボード操作・a11y を維持したまま Chip 意匠で選ばせる)
|
|
128
|
-
-
|
|
130
|
+
- **色地の上の Card**: `Section background="subtle"`/`"accent-subtle"` と、地が Surface-Neutral-Secondary のシェル(`AdminShell` / `WorkspaceShell` / `FunnelShell`)の配下は `--card-surface` が伝播するので、**Card は `surface` 未指定のままで自動的に白**になる(付け忘れ事故が起きない)。DS の `Section` を使わない自前の色地では、親要素に `className="[--card-surface:var(--Surface-Primary)]"` を宣言する(dark にも配慮するなら `dark:[--card-surface:var(--Surface-Secondary)]` を併記)。`Card surface="primary"` の明示指定も従来どおり有効・優先
|
|
129
131
|
- **大見出し**: 通常ページの主見出しは `typo-heading-3xl`(28px)を上限にする。`typo-heading-4xl`(32px)/ `typo-heading-5xl`(40px)は**LP・マーケティング系ヒーローの PC 表示限定**で、SP は `typo-heading-3xl` から段階を上げる。`SectionHeader` では `size="3xl"` に `desktopSize="4xl"` または `desktopSize="5xl"` を加える。手書きの `text-[32px]` / `text-[40px]` 等は禁止
|
|
130
132
|
- **画像・メディア上の操作ボタン**: `rgba(...)` の半透過下地を手組みしない — `--Surface-Overlay-Light`/`--Surface-Overlay-Dark` + `Button variant="overlay"` を使う
|
|
131
133
|
- **SectionHeader が担う「パターン」の手書き**: 禁止 — 次の2パターンは `SectionHeader` を使う。①「タイトル + もっと見る/すべて見るアクション」の並び、②中央寄せの大見出し(ランディング/ガイド系。`align="center"`、eyebrow に Badge 等)。**通常の文書見出し(`<h1>`〜`<h6>` 相当の素の semantic heading)まで SectionHeader に置き換える意味ではない** — 見出し単体なら `typo-heading-*` を付けた素の heading 要素でよい。正典は `contracts/components.json` の SectionHeader `rules`
|
package/MIGRATION.md
CHANGED
|
@@ -7,6 +7,49 @@
|
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
+
## 次期リリース — 面の色をベージュに(`--Surface-Neutral-*` の追加)
|
|
11
|
+
|
|
12
|
+
### 概要
|
|
13
|
+
|
|
14
|
+
light の `--Surface-Secondary` / `--Surface-Tertiary` を、グレー(`#FBF9F8` / `#F4F2F1`)から
|
|
15
|
+
ベージュ(`--Primitive-Wood-25` = `#FCF9F2`)に変えました。Cake.jp 本体の「ケーキ配色」に合わせたものです。
|
|
16
|
+
|
|
17
|
+
| 役割 | 色 | トークン |
|
|
18
|
+
|---|---|---|
|
|
19
|
+
| 押すもの(主 CTA) | ベリー | `--Brand-Cake-Orange` ほか |
|
|
20
|
+
| 情報をまとめる押せない面(説明ボックス・フォームのまとまり・Section subtle・Card 既定・表の見出し行) | ベージュ | `--Surface-Secondary` / `--Surface-Tertiary` |
|
|
21
|
+
| 押せる部品・状態の地・溝・画像の仮の地・画面全体の地 | グレー(従来どおり) | `--Surface-Neutral-Secondary`(`#FBF9F8`)/ `--Surface-Neutral-Tertiary`(`#F4F2F1`) |
|
|
22
|
+
|
|
23
|
+
dark の値は変わりません(`--Surface-Neutral-*` は dark では `--Surface-Secondary` / `--Surface-Tertiary` と同値)。
|
|
24
|
+
DS の部品は付け替え済みなので、DS の部品だけで組んだ画面は対応不要です。
|
|
25
|
+
|
|
26
|
+
### 各サイトでやること
|
|
27
|
+
|
|
28
|
+
自前のコード(className・CSS)で `--Surface-Secondary` / `--Surface-Tertiary` を使っている箇所を探し、
|
|
29
|
+
次のどれかに当たるものだけ `--Surface-Neutral-Secondary` / `--Surface-Neutral-Tertiary` に付け替えます。
|
|
30
|
+
それ以外(押せない情報の面)はそのままにしてベージュにします。
|
|
31
|
+
|
|
32
|
+
- 押せる部品の地(自前のボタン・チップ・タブ・リンクのタイル・ファイル選択の破線エリア)
|
|
33
|
+
- `hover:` / `active:` / `focus:` / `selected` / `aria-selected` / `disabled:` の地
|
|
34
|
+
- Badge・Tag・ピル型のラベル、アバターやアイコンタイルの地
|
|
35
|
+
- 溝・トラック・プログレス・評価バー・スケルトン
|
|
36
|
+
- 画像・地図・埋め込みの読み込み中の仮の地
|
|
37
|
+
- 画面全体の地(`min-h-screen` / `min-h-dvh` のラッパー、ページシェルの `className`)
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# 付け替え候補を洗い出す(状態の地は機械的に付け替えてよい)
|
|
41
|
+
grep -rnE "(hover|active|focus|focus-visible|disabled|aria-selected|data-\[[^]]*\]):bg-\[var\(--Surface-(Secondary|Tertiary)\)\]" src
|
|
42
|
+
# 残りは 1 件ずつ「押せるか・画面の地か」で判断する
|
|
43
|
+
grep -rnE "Surface-(Secondary|Tertiary)" src
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
- 迷ったらグレー(Neutral)にしておく。ベージュは押せるものに使わない
|
|
47
|
+
- `Card` は既定でベージュになる。白い Card が欲しい面では従来どおり `surface="primary"`、色地の上では `--card-surface` の伝播(`Section` / シェル)で白になる
|
|
48
|
+
- shadcn 互換の `bg-muted` / `bg-accent` / `bg-secondary` はグレーのまま(DS 側で Neutral に付け替え済み)
|
|
49
|
+
- Slider の溝を自前で書いている場合は `bg-[var(--Surface-Control-Track,var(--Surface-Neutral-Tertiary))]` の形にする
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
10
53
|
## 次期リリース — `QuantitySelector` → `NumberInput`
|
|
11
54
|
|
|
12
55
|
### 概要
|
package/UPDATING.md
CHANGED
|
@@ -169,7 +169,7 @@ npm run test # あれば
|
|
|
169
169
|
- **マイナー更新では CHANGELOG の「✨ Added」を読み、ローカルに持っている同等実装の削除候補を確認する**。
|
|
170
170
|
DS に新しく追加された部品(例: 0.10.0 の `ImageUploader` / `ResponsiveDialog` / `DataTable`)と同名のローカル実装が残っていないか、`npx cakejp-ds check-duplicates ./src` を流すと機械検出できる(`--strict` で検出時 exit 1)。
|
|
171
171
|
検出されたローカル実装は DS の import に置き換え、不要になったファイルを削除する。
|
|
172
|
-
- **`npx cakejp-ds check-tokens` を流し、DS を上げても色が追従しない箇所が無いか確認する**(ブランド色の直書き・DS のブランド系トークンの上書き・DS に無い変数・ブランド原色の直接参照を検出、検出時 exit 1
|
|
172
|
+
- **`npx cakejp-ds check-tokens` を流し、DS を上げても色が追従しない箇所が無いか確認する**(ブランド色の直書き・DS のブランド系トークンの上書き・DS に無い変数・ブランド原色の直接参照を検出、検出時 exit 1。半透明フォーカスリングの直書き `focus:ring-[var(--Focus-High-Emphasis)]/50` は警告だけで exit code は変わらない)。
|
|
173
173
|
lint / build のスクリプトに組み込んでおくと、色の変更が告知されたときに DS を上げるだけで済む。
|
|
174
174
|
|
|
175
175
|
### 5. PR 作成・マージ
|
package/bin/check-tokens.mjs
CHANGED
|
@@ -12,6 +12,11 @@
|
|
|
12
12
|
* (var(--X, #ffecd9) のフォールバックが表示され続ける)
|
|
13
13
|
* brand-primitive ブランドの原色(--Primitive-Orange-* / --Primitive-Berry-*)の直接参照
|
|
14
14
|
*
|
|
15
|
+
* 加えて、次の 1 つは「警告」として出す(件数を数えるだけで exit code は変えない)。
|
|
16
|
+
*
|
|
17
|
+
* translucent-focus-ring フォーカスリングの半透明の直書き(focus:ring-[var(--Focus-High-Emphasis)]/50 など)。
|
|
18
|
+
* 高コントラスト(--Focus-Ring-Control)で不透明に切り替わらない
|
|
19
|
+
*
|
|
15
20
|
* ブランド色の一覧は、この package の src/styles/primitive.css から毎回読み直す。
|
|
16
21
|
* そのため DS 側でパレットを変えても、この検査の更新は要らない。
|
|
17
22
|
*
|
|
@@ -35,6 +40,11 @@ DS のバージョンを上げても色が追従しない書き方を検出す
|
|
|
35
40
|
undefined-token DS にも DIR にも無い変数の参照 → DS にある名前を使う
|
|
36
41
|
brand-primitive --Primitive-Orange-* / --Primitive-Berry-* の直接参照 → 意味のあるトークンを使う
|
|
37
42
|
|
|
43
|
+
警告(exit code は変えない):
|
|
44
|
+
translucent-focus-ring focus:ring-[var(--Focus-High-Emphasis)]/50 などの半透明リングの直書き
|
|
45
|
+
→ ring-[color:var(--Focus-Ring-Control,color-mix(in_oklab,var(--Focus-High-Emphasis)_50%,transparent))]
|
|
46
|
+
にする(既定の見た目は同じで、高コントラストのときだけ不透明になる)
|
|
47
|
+
|
|
38
48
|
除外: node_modules / .next / out / dist / build / coverage / __tests__ / tests / docs / public / scripts と、
|
|
39
49
|
*.test.* / *.spec.* / *.stories.* / *.d.ts
|
|
40
50
|
例外: 同じ行か直前の行に「design-tokens-allow: <理由>」(理由必須)`)
|
|
@@ -49,6 +59,9 @@ const ALLOW_RE = /design-tokens-allow:\s*\S/
|
|
|
49
59
|
const BRAND_TOKEN_RE = /^(Brand-|Primitive-(Orange|Berry)-|(Surface|Text|Object|Border)-Accent-|(Hover|Active)-(Primary|Secondary)-Button$|Object-Favorite$|Border-Favorite$)/
|
|
50
60
|
// CSS の宣言(--X:)に加え、JS/TS のオブジェクトのキー('--X': / "--X":)も宣言として扱う
|
|
51
61
|
const DECL_RE = /(?:^|[\s;{,("'`])--([A-Za-z][\w-]*)["'`]?\s*:/g
|
|
62
|
+
// 半透明のフォーカスリング: focus / focus-visible / focus-within(group-focus-visible/name も)+ ring-[var(--Focus-*)]/NN または ring-ring/NN。
|
|
63
|
+
// aria-invalid:ring-.../20 などエラー表示のリングはフォーカスリングではないので対象にしない
|
|
64
|
+
const TRANSLUCENT_FOCUS_RING_RE = /(?:^|[^\w-])(?:group-)?focus(?:-visible|-within)?(?:\/[\w-]+)?:ring-(?:\[var\(--(?:Focus-[\w-]+|ring)\)\]|ring)\/\d+/
|
|
52
65
|
const VAR_RE = /var\(\s*--([A-Z][\w-]*)/g
|
|
53
66
|
|
|
54
67
|
function walk(dir, filter, skip, out = []) {
|
|
@@ -90,11 +103,14 @@ const localNames = new Set()
|
|
|
90
103
|
for (const [, text] of texts) for (const m of text.matchAll(DECL_RE)) localNames.add(m[1])
|
|
91
104
|
|
|
92
105
|
const problems = []
|
|
106
|
+
const warnings = []
|
|
93
107
|
for (const [file, text] of texts) {
|
|
94
108
|
const lines = text.split("\n")
|
|
95
109
|
lines.forEach((line, i) => {
|
|
96
110
|
if (ALLOW_RE.test(line) || (i > 0 && ALLOW_RE.test(lines[i - 1]))) return
|
|
97
111
|
const where = `${relative(target, file)}:${i + 1}`
|
|
112
|
+
const ring = line.match(TRANSLUCENT_FOCUS_RING_RE)
|
|
113
|
+
if (ring) warnings.push([where, "translucent-focus-ring", `半透明のフォーカスリングの直書き → ring-[color:var(--Focus-Ring-Control,color-mix(in_oklab,var(--Focus-High-Emphasis)_50%,transparent))] にする(高コントラストで不透明に切り替わる)`])
|
|
98
114
|
const hex = line.match(HEX_RE) || line.match(RGB_RE)
|
|
99
115
|
if (hex) problems.push([where, "brand-hex", `ブランド色の直書き ${hex[0]} → var(--Brand-Cake-Orange) / var(--Text-Accent-Primary) などの DS トークンを使う`])
|
|
100
116
|
for (const m of line.matchAll(DECL_RE)) {
|
|
@@ -107,6 +123,10 @@ for (const [file, text] of texts) {
|
|
|
107
123
|
})
|
|
108
124
|
}
|
|
109
125
|
|
|
126
|
+
if (warnings.length) {
|
|
127
|
+
console.error(`check-tokens: 警告 ${warnings.length} 件(exit code には影響しません)`)
|
|
128
|
+
for (const [where, rule, msg] of warnings) console.error(` ${where} [${rule}] ${msg}`)
|
|
129
|
+
}
|
|
110
130
|
if (problems.length) {
|
|
111
131
|
console.error(`check-tokens: ${problems.length} 件`)
|
|
112
132
|
for (const [where, rule, msg] of problems) console.error(` ${where} [${rule}] ${msg}`)
|