@cakejp/design-system 0.17.0 → 0.19.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 +59 -0
- package/CLAUDE.md +15 -0
- package/contracts/components.json +144 -16
- package/contracts/composition.json +1 -1
- package/contracts/rules.json +5 -1
- package/contracts/screen-patterns.json +1 -1
- package/dist/components/ec/admin-shell.js +7 -6
- package/dist/components/ec/product-card.js +107 -102
- package/dist/components/ec/product-option.js +1 -0
- package/dist/components/ec/review-card.js +22 -20
- package/dist/components/ec/review-form.js +1 -0
- package/dist/components/foundations/accordion.js +23 -22
- package/dist/components/foundations/alert.js +1 -0
- package/dist/components/foundations/aspect-ratio.js +3 -2
- package/dist/components/foundations/avatar.js +1 -0
- package/dist/components/foundations/button.js +7 -1
- package/dist/components/foundations/calendar.js +1 -0
- package/dist/components/foundations/checkbox-group.js +1 -0
- package/dist/components/foundations/checkbox.js +1 -0
- package/dist/components/foundations/command.js +1 -0
- package/dist/components/foundations/context-menu.js +1 -0
- package/dist/components/foundations/drawer.js +1 -0
- package/dist/components/foundations/file-input.js +1 -0
- package/dist/components/foundations/form.js +26 -25
- package/dist/components/foundations/pagination.js +49 -46
- package/dist/components/foundations/popover.js +9 -8
- package/dist/components/foundations/radio-group.js +3 -2
- package/dist/components/foundations/responsive-dialog.js +1 -0
- package/dist/components/foundations/separator.js +7 -6
- package/dist/components/foundations/sheet.js +40 -33
- package/dist/components/foundations/slider.js +7 -6
- package/dist/components/foundations/social-icon.js +30 -10
- package/dist/components/foundations/sonner.js +5 -4
- package/dist/components/foundations/tabs.js +45 -25
- package/dist/components/foundations/toggle-group.js +6 -5
- package/dist/components/primitives/admin-side-nav.js +1 -0
- package/dist/components/primitives/chat-composer.js +1 -0
- package/dist/components/primitives/combobox.js +1 -0
- package/dist/components/primitives/content-card.js +111 -0
- package/dist/components/primitives/content-carousel.js +9 -8
- package/dist/components/primitives/date-picker.js +9 -8
- package/dist/components/primitives/footer.js +169 -100
- package/dist/components/primitives/form-field.js +1 -0
- package/dist/components/primitives/header.js +220 -176
- package/dist/components/primitives/image-carousel.js +8 -7
- package/dist/components/primitives/image-gallery.js +15 -14
- package/dist/components/primitives/image-input.js +9 -8
- package/dist/components/primitives/list-item.js +9 -8
- package/dist/components/primitives/menu-drawer.js +60 -56
- package/dist/components/primitives/multi-select.js +7 -6
- package/dist/components/primitives/number-input.js +1 -0
- package/dist/components/primitives/prose.js +52 -0
- package/dist/components/primitives/search-bar.js +81 -66
- package/dist/components/primitives/section-header.js +58 -55
- package/dist/components/primitives/share-buttons.js +93 -85
- package/dist/components/primitives/status-count-tabs.js +8 -7
- package/dist/components/primitives/sub-nav.js +52 -52
- package/dist/index.css +1 -1
- package/dist/index.js +1785 -831
- package/dist/lib/field-labelling.js +7 -6
- package/dist/lib/link-component.js +6 -0
- package/dist/lib/use-value-length.js +1 -0
- package/dist/types/components/ec/_mypage-menu-data.d.ts +3 -3
- package/dist/types/components/ec/admin-shell.d.ts +1 -1
- package/dist/types/components/ec/anniversary-card.d.ts +1 -1
- package/dist/types/components/ec/mypage-shell.d.ts +3 -3
- package/dist/types/components/ec/product-card.d.ts +13 -20
- package/dist/types/components/ec/product-carousel.d.ts +3 -3
- package/dist/types/components/ec/review-card.d.ts +6 -1
- package/dist/types/components/ec/stat-card.d.ts +1 -1
- package/dist/types/components/foundations/alert-dialog.d.ts +1 -1
- package/dist/types/components/foundations/button.d.ts +1 -1
- package/dist/types/components/foundations/calendar.d.ts +1 -1
- package/dist/types/components/foundations/checkbox-group.d.ts +1 -1
- package/dist/types/components/foundations/chip-variants.d.ts +1 -1
- package/dist/types/components/foundations/command.d.ts +1 -1
- package/dist/types/components/foundations/data-table.d.ts +9 -1
- package/dist/types/components/foundations/field.d.ts +2 -2
- package/dist/types/components/foundations/file-input.d.ts +1 -1
- package/dist/types/components/foundations/pagination.d.ts +8 -2
- package/dist/types/components/foundations/responsive-dialog.d.ts +1 -1
- package/dist/types/components/foundations/sheet.d.ts +6 -1
- package/dist/types/components/foundations/skip-link.d.ts +1 -1
- package/dist/types/components/foundations/social-icon.d.ts +1 -1
- package/dist/types/components/foundations/tabs.d.ts +2 -1
- package/dist/types/components/primitives/admin-header.d.ts +1 -1
- package/dist/types/components/primitives/admin-side-nav.d.ts +1 -1
- package/dist/types/components/primitives/banner-carousel.d.ts +2 -2
- package/dist/types/components/primitives/category-scroll.d.ts +2 -2
- package/dist/types/components/primitives/category-shortcuts.d.ts +1 -1
- package/dist/types/components/primitives/chat-composer.d.ts +1 -1
- package/dist/types/components/primitives/chip.d.ts +1 -1
- package/dist/types/components/primitives/content-card.d.ts +67 -0
- package/dist/types/components/primitives/content-carousel.d.ts +1 -1
- package/dist/types/components/primitives/footer.d.ts +21 -1
- package/dist/types/components/primitives/form-field.d.ts +1 -1
- package/dist/types/components/primitives/header.d.ts +30 -2
- package/dist/types/components/primitives/image-input.d.ts +1 -1
- package/dist/types/components/primitives/kebab-menu.d.ts +1 -1
- package/dist/types/components/primitives/menu-drawer.d.ts +7 -1
- package/dist/types/components/primitives/notification-list.d.ts +1 -1
- package/dist/types/components/primitives/prose.d.ts +35 -0
- package/dist/types/components/primitives/search-bar.d.ts +14 -1
- package/dist/types/components/primitives/search-panel.d.ts +1 -1
- package/dist/types/components/primitives/section-header.d.ts +2 -1
- package/dist/types/components/primitives/section-nav.d.ts +1 -1
- package/dist/types/components/primitives/share-buttons.d.ts +26 -4
- package/dist/types/components/primitives/side-nav.d.ts +1 -1
- package/dist/types/components/primitives/social-login-button.d.ts +1 -1
- package/dist/types/components/primitives/sub-nav.d.ts +16 -1
- package/dist/types/index.d.ts +4 -0
- package/dist/types/lib/link-component.d.ts +26 -0
- package/package.json +10 -5
- package/src/components/COMPONENT_LOOKUP.md +7 -5
- package/src/preset-standalone.css +1 -0
- package/src/preset.css +8 -0
- package/src/styles/semantic.css +1 -0
- package/tokens.json +8 -1
package/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,65 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
9
9
|
|
|
10
10
|
## [Unreleased]
|
|
11
11
|
|
|
12
|
+
## [0.19.0] - 2026-08-20
|
|
13
|
+
|
|
14
|
+
記事メディア系 consumer(cakejp-biz-mag)と仕入れサイト(cake-distributor)から上がっていた不具合・不足を一括で解消する回。**公開 API の破壊的変更はなし**(追加した prop はすべて既定値が従来の挙動)。ただし次の 4 点は既定の挙動・見た目が変わる。
|
|
15
|
+
|
|
16
|
+
- `Sheet` を素で使っている画面は、開閉時にフォーカスが自動で移動するようになる(アクセシビリティの修正)
|
|
17
|
+
- 利用側の `lg:` が Tailwind 既定の 1024px ではなく DS の 960px で切り替わるようになる
|
|
18
|
+
- `SubNav` の PC 表示で左右の余白が 16px → 24px になる
|
|
19
|
+
- `Header variant="back-search"` の戻るボタンが 32px → 44px になる
|
|
20
|
+
|
|
21
|
+
> **0.18.0 は npm に公開されていません**(バージョン確定まで済んでいたが publish が走っていなかった)。npm 上の直前の版は 0.17.1 なので、0.17.x から上げると **0.18.0 の変更も同時に入ります**。0.18.0 の内容は下のセクションを参照してください。
|
|
22
|
+
|
|
23
|
+
### ✨ Added
|
|
24
|
+
|
|
25
|
+
- **`Prose` を追加**(primitives): CMS(microCMS 等)のリッチテキスト HTML に、トークンで揃えた体裁を当てる部品。見出し(h2〜h5)・段落・リスト・引用・リンク・画像・図版キャプション・表・コード・区切り線の余白とサイズと線を 1 箇所に集約し、記事メディアごとに CSS Modules を書き分けて見た目がばらつくのを防ぐ。`html`(**利用側でサニタイズ済み**の HTML)か `children` のどちらでも使える。`as` で `article` / `section` に変えられる。幅は持たないので `Container size="narrow"` と組み合わせる。幅の広い表は表自身が縮む・横スクロールするのでページは横に伸びない([#239](https://github.com/flashpark/cake-design-system/issues/239))
|
|
26
|
+
- **`ContentCard` / `ContentList` を追加**(primitives): 記事・特集・お知らせなど「画像 + タイトル + メタ」のカード。`ProductCard`(商品)/ `ShopCard`(店舗)の兄弟で、記事メディア向け。汎用の `Card` に載せて組むと枠線・タイトル行数・カード高さが揃わない(実測で高さ 268 と 312 に割れる事例)ため部品化した。タイトルは 2 行で省略し**常に 2 行ぶんの高さ**を取るので、タイトルの長短が混ざっても一覧で下端が揃う。`orientation="vertical" | "horizontal" | "list"`、`aspect="16/10" | "16/9" | "1/1"`、画像は `imageSlot`(`next/image` / CMS / 図版を吸収)、`linkComponent` 対応。`ContentList` は区切り線つきの Medium 型リスト([#241](https://github.com/flashpark/cake-design-system/issues/241))
|
|
27
|
+
- **`ShareButtons` に `services` を追加**(共有先の選択と並び替え): 組み込みは `line` / `x` / `facebook` / `hatena`(はてなブックマーク)/ `copy`。既定は従来どおり `["line", "x", "copy"]`。組み込みに無い共有先は `{ key, label, href, icon }` を混ぜて足せる(`href` の `{url}` / `{text}` が URL エンコード済みの値に置換される)。事業者向けメディアで Facebook・はてなブックマークを出すために利用側が `Button asChild` で同意匠を組み直す必要がなくなる([#238](https://github.com/flashpark/cake-design-system/issues/238))
|
|
28
|
+
- **`SocialIcon` に `platform="hatena"` を追加**: はてなブックマークの「B!」マーク。あわせて `--Third-Party-Hatena`(#00A4DE)を配布トークンに追加した
|
|
29
|
+
- **`SearchBar` に `action` を追加**(`<form method="get">` モード): 指定すると素のフォーム送信で遷移するため、**JavaScript 無効の環境やクローラでも検索が成立する**。従来は送信時に `window.location` を書き換える実装しか無く、SEO を重視する記事メディアでは採用できず `Input` + `Button` で `<form>` を手組みすることになっていた。クエリのキーは `name`(既定 `"q"`)。`role="search"` も付く。未指定なら従来どおり([#237](https://github.com/flashpark/cake-design-system/issues/237))
|
|
30
|
+
- **`Header` / `SubNav` に `containerSize` を追加**(`page` / `wide` / `fluid`。`Container` と同じ段): 指定すると**背景・border・sticky は全幅のまま、中身だけ**を中央寄せする。本文を `Container size="page"` で組んでいるサイトで、ロゴ・ナビの左端が本文と揃う(1440px 幅での実測: 指定前 ロゴ 24 / サブナビ 16 / 本文 104 → 指定後すべて **104**)。従来は利用側が `className="mx-auto max-w-[1280px]"` を当てると背景と線まで中央幅になって両脇が抜けるため、sticky と装飾をラッパーに持ち直す必要があった。未指定時は DOM 構造も従来どおり(内側ラッパーを足さない)([#234](https://github.com/flashpark/cake-design-system/issues/234))
|
|
31
|
+
- **`TabsList` に `size="sm"` を追加**: セグメント(ピル型)タブの 1 項目あたりの最小幅(100px)を外し、左右の padding を詰める。既定の `size="md"` は従来どおり。サイドバー幅 266px に 3 択のセグメントを置くと右にはみ出していた(実測 `scrollWidth 308 > clientWidth 266`)のが収まる([#235](https://github.com/flashpark/cake-design-system/issues/235))
|
|
32
|
+
- **`Button` に `size="icon-xl"` を追加**(44px / `size-11`): `size="default"` と同じ高さなので、入力行(`Input` / `SearchBar` / `SelectTrigger`)の横にアイコンボタンを並置しても揃う。既存の icon サイズ(24 / 32 / 36 / 40px)はどれも 44px の入力コントロールと揃わず、`tokens.json` の `touchTarget["text-input"].min` = 44px も満たしていなかった
|
|
33
|
+
|
|
34
|
+
### 🐛 Fixed
|
|
35
|
+
|
|
36
|
+
- **`Header variant="back-search"` の戻るボタンと `centerSlot` の高さが揃っていなかった問題を修正**: 戻るボタンが `size="icon-sm"`(32px)固定で、DS が推奨する組み合わせ(`centerSlot={<SearchBar />}` = 44px)と **12px ずれていた**。`size="icon-xl"`(44px)にして揃えた。あわせて 44px のタップターゲット下限も満たすようになる
|
|
37
|
+
- **`SubNav` の左右余白を `Container` と揃えた**: `px-4` 固定だったため、PC で `Container` の gutter(24px)と 8px ずれていた。SP 16 / PC 24 になる。**PC(768px 以上)で左右の余白が 16px → 24px に変わる**([#234](https://github.com/flashpark/cake-design-system/issues/234))
|
|
38
|
+
- **`SectionHeader`(`align="start"`)で `subtitle` と右側 `action` を併用するとキャプションが早い位置で折り返される問題を修正**: タイトルとキャプションが `action` と同じ Flex 行の中に入っていたため、キャプションまで `action` の幅ぶん狭まっていた。タイトル行とキャプションを別の行に分け、キャプションはヘッダー全幅(右側アクションの下も含む)で折り返す。`moreHref` 併用時にリンクになるのは**タイトル行だけ**になり、`subtitle` はリンクの外に出る(読み上げ対象のリンク数は従来と同じ 1 つ)。`align="center"` は変更なし([#232](https://github.com/flashpark/cake-design-system/issues/232))
|
|
39
|
+
- **`Tabs`(underbar)のトリガーに左右 padding が無く、狭幅で隣のラベルと文字が接触する問題を修正**: 既定で左右 8px を持たせた。サイドバー幅 266px の実測で余白が `1px / 1px` → `8px / 8px` になる。`scrollable` の underbar は `gap-4` で間隔を取っているため従来どおり padding 0([#235](https://github.com/flashpark/cake-design-system/issues/235))
|
|
40
|
+
- **`SheetContent` が開閉時のフォーカス自動移動を無条件に止めていた問題を修正**(a11y / WCAG 2.4.3): `onOpenAutoFocus` / `onCloseAutoFocus` を常に `preventDefault` していたため、素で使うと**開いてもキーボードで中に入れず、閉じてもトリガーにフォーカスが戻らない**状態だった。既定を Radix のまま(開く=中へ / 閉じる=トリガーへ戻る)に直し、止めたい用途向けに `autoFocus={false}` を追加。あわせて利用側が渡した `onOpenAutoFocus` / `onCloseAutoFocus` が DS の既定を消さずに追加で呼ばれるようにした(従来は利用側のハンドラが DS の指定ごと置き換わっていた)。`Sheet` を素で使っている画面はフォーカス挙動が変わる([#233](https://github.com/flashpark/cake-design-system/issues/233))
|
|
41
|
+
- **`preset` がビューポートのブレイクポイント(`--breakpoint-md/lg/xl`)を配っておらず、利用側の `lg:` が Tailwind 既定の 1024px で効いていた問題を修正**: DS の切替段は `md`=768 / `lg`=**960** で、`preset.css` はコンテナクエリ用の `--container-*` しか定義していなかった。そのため `@theme` で自分で書き直したプロダクトだけが正しい位置で切り替わり、書いていないプロダクトは PC 中段が 64px ずれていた(実例: cakejp-biz-mag のトップが 1000px 幅で 1 カラムに落ちる)。`preset` を読み込むだけで `md:` / `lg:` / `xl:` が DS の段に揃う。**利用側の `globals.css` に同じ `@theme` を書いている場合は削除してよい**(値が同じなら実害はない)。`lg:` を Tailwind 既定の 1024px 前提で書いていた画面は切替位置が 960px に変わる([#242](https://github.com/flashpark/cake-design-system/issues/242))
|
|
42
|
+
|
|
43
|
+
## [0.18.0] - 2026-08-19
|
|
44
|
+
|
|
45
|
+
利用側が DS 内部 DOM を `nth-child` / `:has()` で上書きして回避していたケースを公開 props と不具合修正で解消し、あわせてリンクを描く部品に `linkComponent` を追加してフレームワークのリンク部品を差し込めるようにする回。**公開 API の破壊的変更はなし**(追加した prop はすべて既定値が従来の挙動)。ただし `navBreakpoint="lg"` を使っている場合のみ、PC 行の開始が 1024px → 960px に変わる(tokens.json の切替段に合わせた修正)。
|
|
46
|
+
|
|
47
|
+
### 🐛 Fixed
|
|
48
|
+
|
|
49
|
+
- **`Header` の `navBreakpoint="lg"` が 1024px で切り替わっていたのを、tokens.json の切替段 `lg`=960px に修正**: DS の切替段は `md`=768 / `lg`=960 の 2 つで、1024 は存在しない段だった。`navBreakpoint="lg"` を使っている場合、PC 行の開始が 1024px → 960px に変わる
|
|
50
|
+
|
|
51
|
+
- **`Header` の navItems 自動退避で、退避した項目がページのスクロール領域に残り横スクロールが起きる問題を修正**: 計測用の複製は `absolute` + `invisible` で通常フローには影響しないが、絶対配置要素も祖先のスクロール可能領域には寄与する。利用側の実測では viewport 769px に対しページが 932px を要求していた([#243](https://github.com/flashpark/cake-design-system/issues/243))。0 幅 0 高 + `overflow:hidden` の器で包んで寄与を断つ。クリップは描画時のみでレイアウトは保たれるため、退避件数の計算結果は変わらない
|
|
52
|
+
|
|
53
|
+
### ✨ Added
|
|
54
|
+
|
|
55
|
+
- **`Footer` / `MenuDrawer` / `SubNav` / `PaginationLink` に `linkComponent` を追加**: リンクの描画に使うコンポーネントを差し替えられる(`next/link` 等)。これらの部品は素の `<a>` しか描けず、Next.js の consumer ではこの導線だけフルページ遷移になっていた。未指定なら従来どおり `<a>`。`Footer` は `external: true` のリンクだけ常に素の `<a target="_blank">` にフォールバックする(他 3 部品の項目に `external` フラグは無く、渡した href はすべて `linkComponent` で描かれる)([#236](https://github.com/flashpark/cake-design-system/issues/236))
|
|
56
|
+
- **`Header` に `searchBreakpoint` を追加**(`md`=768px / `lg`=960px): `searchSlot` の器を出し始めるコンテナ幅を選べる。中身だけを利用側の CSS で隠しても器は `flex-1` の幅を確保し続けてインラインナビを潰すため、狭い帯で検索を出さない場合はこの prop を使う。値は tokens.json の切替段のみで、コンテンツ上限段の `xl`(1280) は受け付けない([#243](https://github.com/flashpark/cake-design-system/issues/243))
|
|
57
|
+
- **`HeaderAction` に `showLabel` を追加**: アイコンの右に可視ラベルを出すピル型(高さ 40px・枠線)で描画する。「ログイン」等アイコンだけでは意味が伝わらない導線向け。可視テキストがあるときは `aria-label` を付けず二重読み上げを避ける([#245](https://github.com/flashpark/cake-design-system/issues/245))
|
|
58
|
+
- **`ProductCard` に `hoverEffect` を追加**(`zoom` / `fade` / `none`): ホバー時の画像演出を選べる。`fade` は拡大せずわずかに明るくする本番 EC 準拠の挙動で、暗テーマでも明るくなるよう opacity ではなく brightness を使う。未指定時の既定は従来の見た目を保つため orientation ごと(`vertical` = `zoom` / `horizontal` = `none`)で、明示指定すれば `horizontal` でも効く([#244](https://github.com/flashpark/cake-design-system/issues/244))
|
|
59
|
+
- **`ReviewCard` に `bordered` を追加**(既定 `true`): 商品詳細などページ全体をフラットに統一する画面で枠線を外せる([#247](https://github.com/flashpark/cake-design-system/issues/247))
|
|
60
|
+
- **`Footer` に `variant="brand-first"` と `bottomRightSlot` を追加**: ロゴ・説明文を先頭カラムに置き、その右にリンク群を並べる構成。下部バーはコピーライト左・`bottomRightSlot`(`Powered by` 等)右の左右振り分けになる。求人ケーキ屋さん.jp / 仕入れケーキ屋さん.JP のフッターをカスタムマークアップなしで組める([#246](https://github.com/flashpark/cake-design-system/issues/246))
|
|
61
|
+
|
|
62
|
+
## [0.17.1] - 2026-08-06
|
|
63
|
+
|
|
64
|
+
**0.17.0 の型定義が壊れていたため、0.17.0 は使わず 0.17.1 へ上げてください。**
|
|
65
|
+
|
|
66
|
+
### 🐛 Fixed
|
|
67
|
+
|
|
68
|
+
- **配布する型定義の相対パスが 1 階層ズレて、利用側で型が `any` に落ちる問題を修正**: `tsconfig.lib.json` の `outDir`(`./dist`)と `declarationDir`(`./dist/types`)がズレていたため、`tsc-alias` が `@/...` を 1 階層深い相対パスへ書き換えていた。0.16.0 までは指す先が存在せず実害が出ていなかったが、0.17.0 で `dist/components/**`(preserveModules の JS 出力)が増えたことで**誤ったパスが JS 側に当たり**、型が `any` になった。結果 `Pick<any, "size">` などが必須 prop 扱いになり、利用側の typecheck が壊れていた(cake-api で 17 件のエラーを確認)。影響していた型定義は 18 ファイル。`outDir` を `./dist/types` に揃えて解消
|
|
69
|
+
- 回帰防止に `__tests__/dts-import-paths.test.ts` を追加(配布する型定義の相対 import 237 件がすべて型定義ツリー内で解決すること・`dist/types` の外を指さないことを固定)
|
|
70
|
+
|
|
12
71
|
## [0.17.0] - 2026-08-06
|
|
13
72
|
|
|
14
73
|
アクセシビリティ(読み上げソフト対応)の burn-down と、利用側バンドル削減の回。**破壊的変更なし。** 公開 export 名・既定の見た目はどちらも変わらない。
|
package/CLAUDE.md
CHANGED
|
@@ -67,6 +67,21 @@ PdM や社長が AI(Claude 等)で HTML モックを作る際、このパッ
|
|
|
67
67
|
|
|
68
68
|
---
|
|
69
69
|
|
|
70
|
+
## 見た目のフィードバックを受けたときのゲート(DS 起因か consumer 起因かを先に切り分ける)
|
|
71
|
+
|
|
72
|
+
「崩れている」「詰まっている」「揃っていない」等の指摘を受けたら、**直す前に**起因を切り分ける。DS 起因の崩れを consumer 側の `className` だけで握りつぶすと、同じ崩れが他プロダクトで再発し、DS には何も残らない。
|
|
73
|
+
|
|
74
|
+
1. **実測する**: computed style / `getBoundingClientRect` で数値を取る(padding・幅・左端座標)。見た目の印象で判断しない。
|
|
75
|
+
2. **DS 部品のソースを読む**: `node_modules/@cakejp/design-system/dist/index.js` か DS リポジトリの `src/components/**` で該当部品の className を確認し、その挙動が
|
|
76
|
+
- **DS の設計上の仕様/欠落**(実例: `TabsTrigger` の underbar が padding を持たない / `Header` `SubNav` が内側コンテナを持たず全幅に描く / `SubNav` の gutter が `Container` と 8px 違う / segment タブの `min-w-[100px]` / `SheetContent` がフォーカス制御を無条件に `preventDefault`)なのか
|
|
77
|
+
- **consumer の使い方**(variant の選択ミス、`className` の当て方、ラッパーの有無、`Container` を通していない)なのか
|
|
78
|
+
を判定する。
|
|
79
|
+
3. **DS 起因なら**: consumer 側は最小の回避(`className` 追加・ラッパー)に留め、コードコメントに「DS 起因。DS 側で X が直ったら削除」と書く。**同時に flashpark/cake-design-system に issue を立てる**(再現条件・実測値・期待挙動・consumer 側の回避コード)。
|
|
80
|
+
4. **consumer 起因なら**: 素直に直す。同じ誤用が他に無いか grep する。
|
|
81
|
+
5. **報告には「起因: DS / consumer」と根拠(読んだ DS のソース箇所・実測値)を必ず添える。** 起因を書かない「直しました」報告は不完全。
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
70
85
|
## 技術スタック
|
|
71
86
|
|
|
72
87
|
- React 19 + TypeScript
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"meta": {
|
|
3
3
|
"name": "Cake.jp Design System — Component Contracts",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.19.0",
|
|
5
5
|
"description": "全コンポーネントの構造化定義。バリアント・アクセシビリティ要件・使用ルールを機械可読形式で管理。",
|
|
6
6
|
"kind": "kind:\"shell\" は複数ページで再利用されるレイアウト枠(AdminShell / WorkspaceShell / MypageShell 等)。無印は部品コンポーネント。固有ページを組むときは該当 shell から始める。src/components/pages/ 配下のストーリーは特定ページ専用・非配布のため contracts の対象外。",
|
|
7
7
|
"naming": "コンポーネント名は**用途ではなく機能**で付ける。用途名(QuantitySelector = カート数量)にすると、同じ機能を別の文脈で探した人が見つけられず二重実装が生まれる(実例: 用途名だったため NumberInput が別途作られ、意匠の違うステッパーが 2 つになった)。「〜Selector」「〜Picker」等の用途接尾辞を付ける前に、その部品が何をするものかで名前が付けられないかを先に検討する。既存名を機能名へ変える場合は deprecatedAliases に旧名を残す。",
|
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
"formBinding": "react-hook-form との繋ぎ方。formBinding:\"register\"=ネイティブ form control に props/ref を透過するので {...register(\"name\")} を直接 spread できる(Input / Textarea)。formBinding:\"controller\"=Radix ベースで ref が <button> 等に着地する、または値が Date/File など非文字列のため Controller の field.value / field.onChange に繋ぐ。formBinding:\"layout\"=値を持たないレイアウト部品でバインド対象ではない(Field / Form / FormField / ProductOption)。formBinding:\"none\"=値は扱うが単一フィールドのバインド対象ではない自己完結フォーム・複合ウィジェット(DataTable / SearchBar / ReviewForm)。この切り分けは __tests__/react-hook-form-integration.test.tsx が実挙動で固定する(issue #151 / #152)。",
|
|
10
10
|
"counts": {
|
|
11
11
|
"foundations": 51,
|
|
12
|
-
"primitives":
|
|
12
|
+
"primitives": 51,
|
|
13
13
|
"ec": 24,
|
|
14
|
-
"total":
|
|
14
|
+
"total": 126,
|
|
15
15
|
"note": "counts は各ティアの実装ファイル数(scripts/check-drift.sh が src/components/<tier>/*.tsx と突き合わせる)。subcomponents / deprecatedAliases は含まない。"
|
|
16
16
|
}
|
|
17
17
|
},
|
|
@@ -117,7 +117,12 @@
|
|
|
117
117
|
"default",
|
|
118
118
|
"lg",
|
|
119
119
|
"xl",
|
|
120
|
-
"hero"
|
|
120
|
+
"hero",
|
|
121
|
+
"icon-xs",
|
|
122
|
+
"icon-sm",
|
|
123
|
+
"icon",
|
|
124
|
+
"icon-lg",
|
|
125
|
+
"icon-xl"
|
|
121
126
|
],
|
|
122
127
|
"accessibility": [
|
|
123
128
|
"aria-label必須(アイコンのみの場合)"
|
|
@@ -125,6 +130,7 @@
|
|
|
125
130
|
"rules": [
|
|
126
131
|
"<button>を直接使わない。必ずButtonコンポーネントを使う",
|
|
127
132
|
"高さは size='default'=44px(h-11) / xs=24px / sm=32px / lg=48px / xl=56px / hero=min 56px。default はフォーム入力コントロール(Input / SelectTrigger default / DatePicker trigger)と同じ 44px なので、入力行にボタンを並置しても揃う",
|
|
133
|
+
"アイコンのみは icon-xs=24px / icon-sm=32px / icon=36px / icon-lg=40px / icon-xl=44px。入力コントロール(Input / SearchBar / SelectTrigger)の横に並べるときは icon-xl を使う(他は高さが揃わず、44px のタップ領域も満たさない)",
|
|
128
134
|
"⚠️ variant='secondary' はブランドアクセント意匠(Surface-Accent-Primary-Light地+Brand-Cake-Orange文字)。Material/Bootstrap/shadcn の secondary(グレー・控えめ)とは別物なので、他DSの感覚で選ばない",
|
|
129
135
|
"「戻る」「キャンセル」「閉じる」「スキップ」「あとで」等の後退・中立アクションは variant='tertiary'(Surface-Tertiary地+Text-High-Emphasis文字のニュートラルなグレー)を使う。主CTAの隣に置く2番目のボタンでも、役割が後退なら secondary ではなく tertiary",
|
|
130
136
|
"variant='secondary' を使うのは、主CTAと別方向の“前進”を促す副CTAのとき(例: 主='購入する' に対し 副='サンプルを見る')",
|
|
@@ -210,7 +216,12 @@
|
|
|
210
216
|
"formBinding": "none",
|
|
211
217
|
"rules": [
|
|
212
218
|
"管理画面のテーブルはui/tableでなくこちらを使う。ソート・選択行・アクションメニュー対応",
|
|
213
|
-
"ActionCellのメニュー操作は行のonClickへ伝播しない(本体でstopPropagation済み)。行クリック選択との併用時も利用側ガードは不要"
|
|
219
|
+
"ActionCellのメニュー操作は行のonClickへ伝播しない(本体でstopPropagation済み)。行クリック選択との併用時も利用側ガードは不要",
|
|
220
|
+
"見出し文字を出さない列(選択・操作・並び替えハンドル)は DataTableHead の srLabel で読み上げ用ラベルを付ける。空の <th> は列の意味が支援技術に伝わらない(axe: empty-table-header)"
|
|
221
|
+
],
|
|
222
|
+
"accessibility": [
|
|
223
|
+
"sortable な列の押下は <button> が担い、Tab / Enter / Space で操作できる。並び替え状態は <th aria-sort>(none / ascending / descending)で伝わる。th に onClick を直接書かない",
|
|
224
|
+
"方向アイコンは装飾なので aria-hidden。列名は button の中に置き、読み上げ名にする"
|
|
214
225
|
]
|
|
215
226
|
},
|
|
216
227
|
{
|
|
@@ -344,7 +355,10 @@
|
|
|
344
355
|
},
|
|
345
356
|
{
|
|
346
357
|
"name": "Pagination",
|
|
347
|
-
"path": "src/components/foundations/pagination.tsx"
|
|
358
|
+
"path": "src/components/foundations/pagination.tsx",
|
|
359
|
+
"rules": [
|
|
360
|
+
"linkComponent でリンク実装を差し替えられる(next/link 等)。未指定なら素の <a>。この部品の項目に external フラグは無く、渡した href はすべて linkComponent で描かれる(外部 URL を出し分けたい場合は consumer 側でラップする)(#236)"
|
|
361
|
+
]
|
|
348
362
|
},
|
|
349
363
|
{
|
|
350
364
|
"name": "Popover",
|
|
@@ -420,6 +434,15 @@
|
|
|
420
434
|
"SheetDescription",
|
|
421
435
|
"SheetFooter",
|
|
422
436
|
"SheetClose"
|
|
437
|
+
],
|
|
438
|
+
"props": [
|
|
439
|
+
"SheetContent: side?: top | right | bottom | left",
|
|
440
|
+
"SheetContent: showCloseButton?: boolean",
|
|
441
|
+
"SheetContent: autoFocus?: boolean"
|
|
442
|
+
],
|
|
443
|
+
"accessibility": [
|
|
444
|
+
"SheetTitle は必須(ダイアログの読み上げ名)",
|
|
445
|
+
"フォーカスは既定で自動移動する(開く=Sheet の中へ / 閉じる=トリガーへ戻る)。WCAG 2.4.3。autoFocus={false} は止める必要がある特別な場合だけ使う(issue #233)"
|
|
423
446
|
]
|
|
424
447
|
},
|
|
425
448
|
{
|
|
@@ -460,7 +483,7 @@
|
|
|
460
483
|
"name": "SocialIcon",
|
|
461
484
|
"path": "src/components/foundations/social-icon.tsx",
|
|
462
485
|
"props": [
|
|
463
|
-
"platform",
|
|
486
|
+
"platform: line | x | facebook | hatena | amazon | google | apple",
|
|
464
487
|
"tone?: brand | mono",
|
|
465
488
|
"size?: number"
|
|
466
489
|
],
|
|
@@ -497,6 +520,15 @@
|
|
|
497
520
|
"TabsList",
|
|
498
521
|
"TabsTrigger",
|
|
499
522
|
"TabsContent"
|
|
523
|
+
],
|
|
524
|
+
"variants": [
|
|
525
|
+
"TabsList variant: underbar | segment",
|
|
526
|
+
"TabsList scrollable: boolean",
|
|
527
|
+
"TabsList size: md | sm"
|
|
528
|
+
],
|
|
529
|
+
"rules": [
|
|
530
|
+
"サイドバー等の狭い場所に segment を置くときは TabsList size=\"sm\" を使う。既定は 1 項目 100px の最小幅を持ち、3 つ並べると 266px 幅ではみ出す(issue #235)",
|
|
531
|
+
"underbar のトリガーは左右 8px の padding を持つ。className=\"px-2\" を利用側で足さない"
|
|
500
532
|
]
|
|
501
533
|
},
|
|
502
534
|
{
|
|
@@ -646,6 +678,35 @@
|
|
|
646
678
|
"name": "CoachMark",
|
|
647
679
|
"path": "src/components/primitives/coach-mark.tsx"
|
|
648
680
|
},
|
|
681
|
+
{
|
|
682
|
+
"name": "ContentCard",
|
|
683
|
+
"path": "src/components/primitives/content-card.tsx",
|
|
684
|
+
"subcomponents": [
|
|
685
|
+
"ContentList"
|
|
686
|
+
],
|
|
687
|
+
"props": [
|
|
688
|
+
"title: string",
|
|
689
|
+
"href: string",
|
|
690
|
+
"imageSlot?: ReactNode",
|
|
691
|
+
"tag?: { label: string; variant?: TagProps[\"variant\"] }",
|
|
692
|
+
"meta?: ReactNode",
|
|
693
|
+
"orientation?: vertical | horizontal | list",
|
|
694
|
+
"aspect?: 16/10 | 16/9 | 1/1",
|
|
695
|
+
"linkComponent?: LinkComponent"
|
|
696
|
+
],
|
|
697
|
+
"variants": [
|
|
698
|
+
"orientation: vertical | horizontal | list",
|
|
699
|
+
"aspect: 16/10 | 16/9 | 1/1"
|
|
700
|
+
],
|
|
701
|
+
"rules": [
|
|
702
|
+
"記事・特集・お知らせなど「画像 + タイトル + メタ」のカード。ProductCard(商品)/ ShopCard(店舗)の兄弟。Card + CardContent で組まない(枠線・タイトル行数・カード高さが揃わない。実測で高さ 268 / 312 に割れた事例あり)(issue #241)",
|
|
703
|
+
"タイトルは 2 行で省略し常に 2 行ぶんの高さを取る。文字装飾を利用側で足さない(font-bold にしない。既定は font-medium)",
|
|
704
|
+
"meta は 1 行に収める。複数行にすると一覧でカード高さが割れる",
|
|
705
|
+
"画像は imageSlot に渡す(next/image・CMS・図版を吸収する)。縦横比とクリップはカード側が持つ",
|
|
706
|
+
"Medium 型の縦リストは orientation=\"list\" + ContentList(区切り線つき)を使う",
|
|
707
|
+
"カード全体がリンク。linkComponent で next/link 等を差し込める"
|
|
708
|
+
]
|
|
709
|
+
},
|
|
649
710
|
{
|
|
650
711
|
"name": "Combobox",
|
|
651
712
|
"path": "src/components/primitives/combobox.tsx",
|
|
@@ -745,7 +806,15 @@
|
|
|
745
806
|
},
|
|
746
807
|
{
|
|
747
808
|
"name": "Footer",
|
|
748
|
-
"path": "src/components/primitives/footer.tsx"
|
|
809
|
+
"path": "src/components/primitives/footer.tsx",
|
|
810
|
+
"rules": [
|
|
811
|
+
"variant='brand-first' でロゴ・説明文を先頭カラムに置き、その右にリンク群を並べる。下部バーはコピーライト左・bottomRightSlot 右の左右振り分けになる。linkGroups が空でもロゴ・説明文は落ちず、逆に logo/description が無いときは nav を 2 カラムへ押し込まない。この構成をカスタムマークアップで自作しない(#246)",
|
|
812
|
+
"linkComponent でリンク実装を差し替えられる(next/link 等)。未指定なら素の <a>。external:true のリンクは framework のリンク部品へ通す意味が無いため常に素の <a target=_blank> にフォールバックする(#236)"
|
|
813
|
+
],
|
|
814
|
+
"variants": [
|
|
815
|
+
"default",
|
|
816
|
+
"brand-first"
|
|
817
|
+
]
|
|
749
818
|
},
|
|
750
819
|
{
|
|
751
820
|
"name": "FormField",
|
|
@@ -801,7 +870,10 @@
|
|
|
801
870
|
"actions(HeaderAction)はカート・マイページ等の本来リンクである導線には href を指定する。href 指定時は Button asChild + <a> で描画され、中クリック/新規タブ・リンクコピーが効く。onClick と併用可(両方付与される)",
|
|
802
871
|
"navItems は幅に入り切らない項目を自動で「その他」ドロップダウンへ退避する(#200)。consumer 側で項目数を手で slice して減らさない。ラベルを増やしても中幅でロゴ・actions と衝突しない",
|
|
803
872
|
"navBreakpoint でインラインナビ行の開始コンテナ幅を選べる: md(既定 = @[768px]+)/ lg(@[1024px]+)。ロゴが多段で横幅を食うケースは lg にして中幅での同居自体を避ける",
|
|
804
|
-
"「その他」のラベルは navOverflowLabel で差し替えられる(既定 その他)。ハンバーガーを自前で組まない"
|
|
873
|
+
"「その他」のラベルは navOverflowLabel で差し替えられる(既定 その他)。ハンバーガーを自前で組まない",
|
|
874
|
+
"HeaderAction の showLabel=true でアイコン+可視ラベルのピル型(h-10・枠線)になる。「ログイン」等アイコンだけでは伝わらない導線に使い、consumer 側でアイコンにテキストを差し込まない(#245)",
|
|
875
|
+
"searchBreakpoint で searchSlot の器を出し始めるコンテナ幅を選ぶ(md=768 / lg=960 の切替段のみ。xl=1280 は上限段でレイアウト切替に使わない)。狭い帯で検索を出さないときは consumer の CSS で中身を隠さずこの prop を使う。中身だけ隠しても器が flex-1 の幅を確保し、インラインナビを潰す(#243)",
|
|
876
|
+
"本文を Container size=\"page\" で中央寄せしているサイトは containerSize=\"page\" を指定する(Container と同じ段: page / wide / fluid)。背景・border・sticky は全幅のまま中身だけ中央寄せされ、ロゴ・ナビの左端が本文と揃う。consumer 側で className に max-w を当てると背景と線まで中央幅になり両脇が抜けるので使わない(issue #234)"
|
|
805
877
|
]
|
|
806
878
|
},
|
|
807
879
|
{
|
|
@@ -890,7 +962,10 @@
|
|
|
890
962
|
},
|
|
891
963
|
{
|
|
892
964
|
"name": "MenuDrawer",
|
|
893
|
-
"path": "src/components/primitives/menu-drawer.tsx"
|
|
965
|
+
"path": "src/components/primitives/menu-drawer.tsx",
|
|
966
|
+
"rules": [
|
|
967
|
+
"linkComponent でリンク実装を差し替えられる(next/link 等)。未指定なら素の <a>。この部品の項目に external フラグは無く、渡した href はすべて linkComponent で描かれる(外部 URL を出し分けたい場合は consumer 側でラップする)(#236)"
|
|
968
|
+
]
|
|
894
969
|
},
|
|
895
970
|
{
|
|
896
971
|
"name": "MultiSelect",
|
|
@@ -942,6 +1017,21 @@
|
|
|
942
1017
|
"name": "ProgressSteps",
|
|
943
1018
|
"path": "src/components/primitives/progress-steps.tsx"
|
|
944
1019
|
},
|
|
1020
|
+
{
|
|
1021
|
+
"name": "Prose",
|
|
1022
|
+
"path": "src/components/primitives/prose.tsx",
|
|
1023
|
+
"props": [
|
|
1024
|
+
"html?: string",
|
|
1025
|
+
"as?: div | article | section"
|
|
1026
|
+
],
|
|
1027
|
+
"rules": [
|
|
1028
|
+
"CMS(microCMS 等)のリッチテキスト HTML を描くときは、consumer 側で h2 / p / ul の CSS を書かずこれを使う。ArticleBody.module.css のような独自 CSS を作らない(issue #239)",
|
|
1029
|
+
"html に渡す HTML は利用側でサニタイズ済みであること。この部品は体裁を当てるだけで中身の無害化はしない",
|
|
1030
|
+
"記事幅は Container size=\"narrow\"(760px)で決める。この部品は幅を持たない",
|
|
1031
|
+
"見出しレベルは CMS の出力に従う(体裁だけを当て、階層は変えない)",
|
|
1032
|
+
"幅の広い表は表自身が縮む/横スクロールするので、ページは横に伸びない"
|
|
1033
|
+
]
|
|
1034
|
+
},
|
|
945
1035
|
{
|
|
946
1036
|
"name": "NumberInput",
|
|
947
1037
|
"path": "src/components/primitives/number-input.tsx",
|
|
@@ -987,7 +1077,20 @@
|
|
|
987
1077
|
{
|
|
988
1078
|
"name": "SearchBar",
|
|
989
1079
|
"path": "src/components/primitives/search-bar.tsx",
|
|
990
|
-
"formBinding": "none"
|
|
1080
|
+
"formBinding": "none",
|
|
1081
|
+
"props": [
|
|
1082
|
+
"size?: sm | md",
|
|
1083
|
+
"onSearch?: (query: string) => void",
|
|
1084
|
+
"searchHref?: string",
|
|
1085
|
+
"action?: string",
|
|
1086
|
+
"name?: string"
|
|
1087
|
+
],
|
|
1088
|
+
"rules": [
|
|
1089
|
+
"JS 無効環境・クローラでも動かす必要がある画面(SEO 重視の記事メディア等)は action を指定する。<form method=\"get\" action> として描画され、Enter も検索ボタンも素のフォーム送信になる(issue #237)",
|
|
1090
|
+
"action 指定時のクエリキーは name(既定 q)",
|
|
1091
|
+
"Input + Button で <form method=get> を手組みしない",
|
|
1092
|
+
"searchHref は window.location を書き換える JS 前提の導線。action と併用しない(action が優先)"
|
|
1093
|
+
]
|
|
991
1094
|
},
|
|
992
1095
|
{
|
|
993
1096
|
"name": "SearchPanel",
|
|
@@ -1027,7 +1130,8 @@
|
|
|
1027
1130
|
"rules": [
|
|
1028
1131
|
"タイトル+もっと見るボタンをCardTitle+Button手書き禁止。SectionHeaderを使う",
|
|
1029
1132
|
"中央寄せ大見出し(ランディング/ガイド系)は align=\"center\" を使う。eyebrow プロップに Badge 等を載せられる。手書きの中央寄せ見出し禁止",
|
|
1030
|
-
"3xl(28px)は通常ページの主見出しにも使う。4xl/5xlはLP・マーケティング系ヒーロー専用で、size=\"3xl\" に desktopSize=\"4xl\" または desktopSize=\"5xl\" を加えてPC時だけ拡大する"
|
|
1133
|
+
"3xl(28px)は通常ページの主見出しにも使う。4xl/5xlはLP・マーケティング系ヒーロー専用で、size=\"3xl\" に desktopSize=\"4xl\" または desktopSize=\"5xl\" を加えてPC時だけ拡大する",
|
|
1134
|
+
"align=\"start\" では subtitle はタイトル行の下に全幅で置かれ、右側 action の下の空きも使って折り返す。moreHref 併用時にリンクになるのはタイトル行だけで、subtitle はリンクの外(issue #232)"
|
|
1031
1135
|
]
|
|
1032
1136
|
},
|
|
1033
1137
|
{
|
|
@@ -1051,7 +1155,17 @@
|
|
|
1051
1155
|
},
|
|
1052
1156
|
{
|
|
1053
1157
|
"name": "ShareButtons",
|
|
1054
|
-
"path": "src/components/primitives/share-buttons.tsx"
|
|
1158
|
+
"path": "src/components/primitives/share-buttons.tsx",
|
|
1159
|
+
"props": [
|
|
1160
|
+
"url?: string",
|
|
1161
|
+
"text?: string",
|
|
1162
|
+
"services?: Array<'line' | 'x' | 'facebook' | 'hatena' | 'copy' | ShareCustomService>"
|
|
1163
|
+
],
|
|
1164
|
+
"rules": [
|
|
1165
|
+
"共有先は services で選ぶ(既定 line / x / copy)。同じ意匠を Button asChild で組み直さない(issue #238)",
|
|
1166
|
+
"組み込みに無い共有先は services に { key, label, href, icon } を混ぜて足す。href の {url} / {text} が URL エンコード済みの値に置換される",
|
|
1167
|
+
"共有先のロゴは SocialIcon が持つ。SVG を手書きしない"
|
|
1168
|
+
]
|
|
1055
1169
|
},
|
|
1056
1170
|
{
|
|
1057
1171
|
"name": "SideNav",
|
|
@@ -1101,7 +1215,16 @@
|
|
|
1101
1215
|
},
|
|
1102
1216
|
{
|
|
1103
1217
|
"name": "SubNav",
|
|
1104
|
-
"path": "src/components/primitives/sub-nav.tsx"
|
|
1218
|
+
"path": "src/components/primitives/sub-nav.tsx",
|
|
1219
|
+
"variants": [
|
|
1220
|
+
"variant: text | chip",
|
|
1221
|
+
"containerSize: page | wide | fluid"
|
|
1222
|
+
],
|
|
1223
|
+
"rules": [
|
|
1224
|
+
"linkComponent でリンク実装を差し替えられる(next/link 等)。未指定なら素の <a>。この部品の項目に external フラグは無く、渡した href はすべて linkComponent で描かれる(外部 URL を出し分けたい場合は consumer 側でラップする)(#236)",
|
|
1225
|
+
"左右の余白は Container と同じ SP 16 / PC 24。利用側で px-* を足さない",
|
|
1226
|
+
"本文を Container size=\"page\" で中央寄せしているサイトは containerSize=\"page\" を指定する。下線は全幅のまま中身だけ中央寄せされる(issue #234)"
|
|
1227
|
+
]
|
|
1105
1228
|
},
|
|
1106
1229
|
{
|
|
1107
1230
|
"name": "Tag",
|
|
@@ -1263,8 +1386,10 @@
|
|
|
1263
1386
|
"rules": [
|
|
1264
1387
|
"captionは規格・仕様の短い自由記述(例: \"1kg / 冷蔵\")。価格表示の直下にtypo-body-xs / Text-Medium-Emphasisで表示。tags(配送方法等のenum variant)とは別物で代替不可",
|
|
1265
1388
|
"カード幅は列(親グリッド/flex)が決める。カード自身は min-w-0 で、固定の min-width を持たない。自前のカードを組む場合もテキスト列は grid-template-columns: minmax(0, 1fr) にし、auto にしない(nowrapのメタ行のmin-content幅が列を押し広げ、サムネイルが列からはみ出す)",
|
|
1266
|
-
"商品名は line-clamp-2 + min-h-[2lh] で常に2行分の高さを確保する。1行の商品名でも下に続く価格の縦位置が一覧内で揃う"
|
|
1267
|
-
|
|
1389
|
+
"商品名は line-clamp-2 + min-h-[2lh] で常に2行分の高さを確保する。1行の商品名でも下に続く価格の縦位置が一覧内で揃う",
|
|
1390
|
+
"hoverEffect でホバー時の画像演出を選ぶ: zoom / fade(拡大せず明るく・暗テーマ対応のため brightness を使う)/ none。未指定時の既定は orientation ごと(vertical=zoom / horizontal=none)で従来の見た目を維持し、明示指定すれば horizontal でも効く。consumer 側の CSS で scale を打ち消さない。Tailwind v4 の scale-* は transform ではなく scale プロパティのため打ち消しは壊れやすい(#244)"
|
|
1391
|
+
],
|
|
1392
|
+
"variants": {}
|
|
1268
1393
|
},
|
|
1269
1394
|
{
|
|
1270
1395
|
"name": "ProductCarousel",
|
|
@@ -1343,6 +1468,9 @@
|
|
|
1343
1468
|
"features": [
|
|
1344
1469
|
"helpful-count",
|
|
1345
1470
|
"like"
|
|
1471
|
+
],
|
|
1472
|
+
"rules": [
|
|
1473
|
+
"bordered={false} で枠線を外せる。商品詳細等ページ全体をフラットに統一する画面で consumer が border-0 を上書きしない(#247)"
|
|
1346
1474
|
]
|
|
1347
1475
|
},
|
|
1348
1476
|
{
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"meta": {
|
|
3
3
|
"name": "Cake.jp Design System — Composition Contracts",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.19.0",
|
|
5
5
|
"description": "ページ骨格・視覚階層・余白リズムの機械可読な正本。画面パターンを選んだ後の「実際の組み方」を規定する。ページの外枠(モバイル/デスクトップ/管理)、商品グリッドの列数、余白の4段リズム、Surface のネスト階層、テキスト階層、CTA の優先順位を構造化する。人間向けの解説は guidelines/composition/layout.md・guidelines/composition/hierarchy.md・guidelines/overview.md。",
|
|
6
6
|
"source": "guidelines/composition/layout.md, guidelines/composition/hierarchy.md, guidelines/overview.md, guidelines/components/button.md(CTA 密度ルール)を正本化",
|
|
7
7
|
"roleSeparation": "screen-patterns.json はページ種別(Standard Page / Focused Workspace / ResponsiveDialog / Dialog)を選ぶための契約。composition.json は選んだ後、その骨格をどう組むか(外枠構造・余白リズム・階層)の契約。前者=何を使うか、後者=どう並べるか。",
|
package/contracts/rules.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"meta": {
|
|
3
3
|
"name": "Cake.jp Design System — Rules Contracts",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.19.0",
|
|
5
5
|
"description": "禁止パターン・アクセシビリティ要件・ライティングルールの構造化定義。lint-scratch.sh と check-drift.sh で自動検証。"
|
|
6
6
|
},
|
|
7
7
|
"prohibited": [
|
|
@@ -655,6 +655,10 @@
|
|
|
655
655
|
"id": "A007",
|
|
656
656
|
"rule": "全フォーム入力に <Label> または aria-label を紐付ける"
|
|
657
657
|
},
|
|
658
|
+
{
|
|
659
|
+
"id": "A014",
|
|
660
|
+
"rule": "React Server Components 対応: client 専用 API(useState / useEffect / createContext 等)を使うモジュールは先頭に \"use client\" を宣言する。バレル(src/index.ts)には付けない — 付けるとパッケージ全体が client 扱いになり、cn / buttonVariants を Server Component から呼べなくなる。__tests__/client-boundary.test.ts が固定する"
|
|
661
|
+
},
|
|
658
662
|
{
|
|
659
663
|
"id": "A013",
|
|
660
664
|
"rule": "Radix ベースのコントロール(Select / Switch / Checkbox / Combobox / Slider 等)は <button> や <span role=\"slider\"> として描画されるため、<Label htmlFor> や外側の <label> ラップでは名前が付かない。FormField でラップして aria-labelledby を自動付与させるか、単体利用なら日本語の aria-label をコントロール自身に書く(issue #202)"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"meta": {
|
|
3
3
|
"name": "Cake.jp Design System — Screen Patterns Contracts",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.19.0",
|
|
5
5
|
"description": "CRUD 機能でどの画面パターンを使うかの機械可読な判断基準。5パターンの定義・CRUD 対応・決定木・編集UIの観点比較を構造化する。人間向けの解説は guidelines/foundations/screen-patterns.md。",
|
|
6
6
|
"source": "GitHub issue #37 CRUDの画面設計の型化と基本パターンの整備",
|
|
7
7
|
"relatedContract": "本契約はページ種別の選択(何を使うか)を担う。選んだ後の骨格の組み方(外枠構造・余白リズム・視覚階層)は contracts/composition.json を参照する。",
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use client";
|
|
1
2
|
import { jsxs as r, jsx as e, Fragment as N } from "react/jsx-runtime";
|
|
2
3
|
import * as d from "react";
|
|
3
4
|
import { cn as k } from "../../lib/utils.js";
|
|
@@ -130,7 +131,7 @@ function ne({
|
|
|
130
131
|
mainId: f = "main-content",
|
|
131
132
|
skipLink: g
|
|
132
133
|
}) {
|
|
133
|
-
const [y,
|
|
134
|
+
const [y, c] = d.useState(!1), S = /* @__PURE__ */ r(N, { children: [
|
|
134
135
|
/* @__PURE__ */ r("button", { className: "relative flex items-center justify-center size-10 shrink-0 rounded-lg hover:bg-[var(--Surface-Secondary)]", "aria-label": "通知", children: [
|
|
135
136
|
/* @__PURE__ */ e(j, { size: 20, className: "text-[var(--Text-High-Emphasis)]" }),
|
|
136
137
|
/* @__PURE__ */ e("span", { className: "absolute top-1.5 right-1.5 size-2 rounded-full bg-[var(--Surface-Caution)]" })
|
|
@@ -154,7 +155,7 @@ function ne({
|
|
|
154
155
|
activeKey: t,
|
|
155
156
|
drawerTitle: p ?? s,
|
|
156
157
|
open: y,
|
|
157
|
-
onOpenChange:
|
|
158
|
+
onOpenChange: c
|
|
158
159
|
}
|
|
159
160
|
),
|
|
160
161
|
/* @__PURE__ */ r("div", { className: "@container/main flex flex-1 flex-col @md:pl-18", children: [
|
|
@@ -162,7 +163,7 @@ function ne({
|
|
|
162
163
|
L,
|
|
163
164
|
{
|
|
164
165
|
brand: b ?? `${s}管理`,
|
|
165
|
-
onMenuClick: () =>
|
|
166
|
+
onMenuClick: () => c(!0),
|
|
166
167
|
actions: v ?? S
|
|
167
168
|
}
|
|
168
169
|
),
|
|
@@ -182,10 +183,10 @@ function ne({
|
|
|
182
183
|
}
|
|
183
184
|
),
|
|
184
185
|
(n || l) && /* @__PURE__ */ r("div", { className: "mb-4 space-y-1", children: [
|
|
185
|
-
n && n.length > 0 && /* @__PURE__ */ e("nav", { className: "flex items-center gap-1 typo-body-sm text-[var(--Text-Low-Emphasis)]", "aria-label": "パンくず", children: n.map((o,
|
|
186
|
-
|
|
186
|
+
n && n.length > 0 && /* @__PURE__ */ e("nav", { className: "flex items-center gap-1 typo-body-sm text-[var(--Text-Low-Emphasis)]", "aria-label": "パンくず", children: n.map((o, h) => /* @__PURE__ */ r(d.Fragment, { children: [
|
|
187
|
+
h > 0 && /* @__PURE__ */ e(F, { size: 12 }),
|
|
187
188
|
o.href ? /* @__PURE__ */ e("a", { href: o.href, className: "hover:text-[var(--Text-Accent-Primary)] transition-colors", children: o.label }) : /* @__PURE__ */ e("span", { className: "text-[var(--Text-High-Emphasis)]", children: o.label })
|
|
188
|
-
] },
|
|
189
|
+
] }, h)) }),
|
|
189
190
|
l && /* @__PURE__ */ e("h1", { className: "typo-heading-2xl text-[var(--Text-High-Emphasis)]", children: l })
|
|
190
191
|
] }),
|
|
191
192
|
i
|