@cakejp/design-system 0.10.0 → 0.11.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 +26 -0
- package/CLAUDE.md +1 -1
- package/README.md +30 -5
- package/UPDATING.md +36 -0
- package/contracts/rules.json +2 -2
- package/dist/index.css +1 -1
- package/dist/index.js +1147 -1100
- package/dist/types/components/ec/mypage-shell.d.ts +34 -7
- package/dist/types/components/primitives/side-nav.d.ts +24 -3
- package/package.json +8 -26
- package/templates/AGENTS.md +34 -7
- package/templates/CLAUDE.md +35 -7
|
@@ -20,12 +20,15 @@
|
|
|
20
20
|
* ## 事業横断での再利用
|
|
21
21
|
*
|
|
22
22
|
* 骨格(ヘッダー+2カラム+BottomTabBar)は事業横断で再利用できる。
|
|
23
|
-
*
|
|
24
|
-
*
|
|
23
|
+
* ジョブボード・他ブランドの consumer では `logo` / `navItems` / `menuGroups` /
|
|
24
|
+
* `breadcrumbs` / `bottomNavItems` / `headerActions` を差し替えて骨格を再利用する。
|
|
25
|
+
* 既定値は Cake.jp EC(ロゴ=CakeLogo、メニュー=マイページメニュー)。
|
|
26
|
+
* `logo` / `navItems` を渡せば PC ヘッダーのブランドを差し替えられ、
|
|
27
|
+
* 「マイページ配下だけ Cake.jp ロゴに割れる」問題を避けられる。
|
|
25
28
|
*/
|
|
26
29
|
import React from "react";
|
|
27
|
-
import { type HeaderAction } from "../../components/primitives/header";
|
|
28
|
-
import { type SideNavGroup } from "../../components/primitives/side-nav";
|
|
30
|
+
import { type HeaderAction, type HeaderNavItem } from "../../components/primitives/header";
|
|
31
|
+
import { type SideNavGroup, type SideNavItem } from "../../components/primitives/side-nav";
|
|
29
32
|
import { type BottomTabBarItem } from "../../components/primitives/bottom-tab-bar";
|
|
30
33
|
export interface MypageShellBreadcrumb {
|
|
31
34
|
label: string;
|
|
@@ -34,8 +37,20 @@ export interface MypageShellBreadcrumb {
|
|
|
34
37
|
export interface MypageShellProps {
|
|
35
38
|
/** ページタイトル(SP の h1 + PC の main h1 + 末尾パンくず に使用) */
|
|
36
39
|
title: string;
|
|
37
|
-
/** SideNav の activeMenu
|
|
38
|
-
activeMenu
|
|
40
|
+
/** SideNav の activeMenu に渡すキー(完全一致)。`currentPath` / `isActiveMenuItem` 使用時は省略可。 */
|
|
41
|
+
activeMenu?: string;
|
|
42
|
+
/**
|
|
43
|
+
* 現在の URL パス。渡すと SideNav が `href` と照合してアクティブ項目を自動判定する
|
|
44
|
+
* (`activeMenu` の手動指定が不要になる)。既定の照合は完全一致(`activeMatch="prefix"` で配下ページ全体を対象に)。
|
|
45
|
+
*/
|
|
46
|
+
currentPath?: string;
|
|
47
|
+
/**
|
|
48
|
+
* `currentPath` と SideNav 各項目 `href` の照合方法(既定 `"exact"`)。
|
|
49
|
+
* `"prefix"` にすると詳細・配下ページ(例: `/mypage/orders/123/`)でも一覧項目(`/mypage/orders/`)がアクティブになる。
|
|
50
|
+
*/
|
|
51
|
+
activeMatch?: "exact" | "prefix";
|
|
52
|
+
/** SideNav のアクティブ判定を上書きする述語(最優先)。consumer 固有の URL 集約ロジックを注入する。 */
|
|
53
|
+
isActiveMenuItem?: (item: SideNavItem) => boolean;
|
|
39
54
|
/** コンテンツ */
|
|
40
55
|
children: React.ReactNode;
|
|
41
56
|
/** パンくず(省略時はデフォルト: ホーム > 山田 太郎 さまのマイページ > {title}) */
|
|
@@ -52,8 +67,20 @@ export interface MypageShellProps {
|
|
|
52
67
|
* 他事業では差し替えて骨格を再利用する。
|
|
53
68
|
*/
|
|
54
69
|
headerActions?: HeaderAction[];
|
|
70
|
+
/**
|
|
71
|
+
* PC ヘッダーのロゴ(既定=`CakeLogo`)。
|
|
72
|
+
* 他ブランドの consumer は自社ロゴを渡してマイページのブランド割れを防ぐ。
|
|
73
|
+
* ※ SP は `Header variant="back"`(戻るボタン)でロゴを表示しないため、この prop は PC ヘッダーにのみ作用する。
|
|
74
|
+
*/
|
|
75
|
+
logo?: React.ReactNode;
|
|
76
|
+
/**
|
|
77
|
+
* PC ヘッダーのグローバルナビ(既定=なし)。
|
|
78
|
+
* 他ブランドの consumer は自社ナビ(例: 商品を探す/ご利用ガイド/よくある質問)を渡して骨格を再利用する。
|
|
79
|
+
* SP では非表示(`Header` の仕様)。
|
|
80
|
+
*/
|
|
81
|
+
navItems?: HeaderNavItem[];
|
|
55
82
|
/** SP の戻るボタン押下時のハンドラ(Header variant="back" に委譲) */
|
|
56
83
|
onBack?: () => void;
|
|
57
84
|
}
|
|
58
|
-
declare function MypageShell({ title, activeMenu, children, breadcrumbs, bottomNavItems, menuGroups, headerActions, onBack, }: MypageShellProps): import("react/jsx-runtime").JSX.Element;
|
|
85
|
+
declare function MypageShell({ title, activeMenu, currentPath, activeMatch, isActiveMenuItem, children, breadcrumbs, bottomNavItems, menuGroups, headerActions, logo, navItems, onBack, }: MypageShellProps): import("react/jsx-runtime").JSX.Element;
|
|
59
86
|
export { MypageShell };
|
|
@@ -18,8 +18,26 @@ export interface SideNavGroup {
|
|
|
18
18
|
items: SideNavItem[];
|
|
19
19
|
}
|
|
20
20
|
export interface SideNavProps extends React.HTMLAttributes<HTMLElement> {
|
|
21
|
-
/** 現在アクティブなメニューの key */
|
|
21
|
+
/** 現在アクティブなメニューの key(完全一致)。`currentPath` / `isActive` 未指定時の既定判定。 */
|
|
22
22
|
activeMenu?: string;
|
|
23
|
+
/**
|
|
24
|
+
* 現在の URL パス。指定すると各項目の `href` と照合してアクティブ項目を自動判定する
|
|
25
|
+
* (`activeMenu` より優先)。詳細ページや配下ページで `activeMenu` を手動指定する必要がなくなる。
|
|
26
|
+
*/
|
|
27
|
+
currentPath?: string;
|
|
28
|
+
/**
|
|
29
|
+
* `currentPath` と `href` の照合方法(既定 `"exact"`)。
|
|
30
|
+
* - `"exact"`: `href === currentPath`
|
|
31
|
+
* - `"prefix"`: `currentPath` が `href` 配下(前方一致)。1 項目が配下ページ全体でアクティブになる
|
|
32
|
+
* (例: 「注文履歴」`/mypage/orders/` が `/mypage/orders/123/` でもアクティブ)。
|
|
33
|
+
* 複数項目が一致した場合は**最長 href の 1 項目のみ**アクティブにし、親子の二重アクティブを防ぐ。
|
|
34
|
+
*/
|
|
35
|
+
activeMatch?: "exact" | "prefix";
|
|
36
|
+
/**
|
|
37
|
+
* アクティブ判定を完全に上書きする述語(最優先)。
|
|
38
|
+
* consumer 固有の URL 集約ロジック(複数 URL を 1 項目へ束ねる等)を注入する。
|
|
39
|
+
*/
|
|
40
|
+
isActive?: (item: SideNavItem) => boolean;
|
|
23
41
|
/** メニューグループ(必須) */
|
|
24
42
|
groups: SideNavGroup[];
|
|
25
43
|
/** aria-label */
|
|
@@ -55,8 +73,11 @@ export interface SideNavProps extends React.HTMLAttributes<HTMLElement> {
|
|
|
55
73
|
* | Prop | 型 | デフォルト | 説明 |
|
|
56
74
|
* |------|-----|-----------|------|
|
|
57
75
|
* | groups | SideNavGroup[] | — | メニューグループ(必須) |
|
|
58
|
-
* | activeMenu | string | — | アクティブなメニュー項目の key |
|
|
76
|
+
* | activeMenu | string | — | アクティブなメニュー項目の key(完全一致・後方互換) |
|
|
77
|
+
* | currentPath | string | — | 現在 URL。href と照合して自動判定(activeMenu より優先) |
|
|
78
|
+
* | activeMatch | "exact" \| "prefix" | "exact" | currentPath の照合方法。prefix は配下ページ全体でアクティブ |
|
|
79
|
+
* | isActive | (item) => boolean | — | アクティブ判定を上書きする述語(最優先) |
|
|
59
80
|
* | ariaLabel | string | "サイドメニュー" | aria-label |
|
|
60
81
|
*/
|
|
61
|
-
declare function SideNav({ activeMenu, groups, ariaLabel, className, ...props }: SideNavProps): import("react/jsx-runtime").JSX.Element;
|
|
82
|
+
declare function SideNav({ activeMenu, currentPath, activeMatch, isActive, groups, ariaLabel, className, ...props }: SideNavProps): import("react/jsx-runtime").JSX.Element;
|
|
62
83
|
export { SideNav };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cakejp/design-system",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Cake.jp Design System — UI コンポーネント・カラートークン・タイポグラフィ",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -97,52 +97,34 @@
|
|
|
97
97
|
"dependencies": {
|
|
98
98
|
"class-variance-authority": "^0.7.1",
|
|
99
99
|
"clsx": "^2.1.1",
|
|
100
|
-
"
|
|
100
|
+
"cmdk": "^1.0.0",
|
|
101
|
+
"next-themes": "^0.4.0",
|
|
102
|
+
"react-day-picker": "^9.0.0",
|
|
103
|
+
"react-hook-form": "^7.0.0",
|
|
104
|
+
"sonner": "^2.0.0",
|
|
105
|
+
"tailwind-merge": "^3.5.0",
|
|
106
|
+
"vaul": "^1.0.0"
|
|
101
107
|
},
|
|
102
108
|
"peerDependencies": {
|
|
103
109
|
"@hookform/resolvers": "^5.0.0",
|
|
104
|
-
"cmdk": "^1.0.0",
|
|
105
110
|
"date-fns": "^4.0.0",
|
|
106
111
|
"iconsax-reactjs": "^0.0.8",
|
|
107
112
|
"lucide-react": ">=0.400.0",
|
|
108
|
-
"next-themes": "^0.4.0",
|
|
109
113
|
"radix-ui": "^1.0.0",
|
|
110
114
|
"react": "^18.0.0 || ^19.0.0",
|
|
111
|
-
"react-day-picker": "^9.0.0",
|
|
112
115
|
"react-dom": "^18.0.0 || ^19.0.0",
|
|
113
|
-
"react-hook-form": "^7.0.0",
|
|
114
|
-
"sonner": "^2.0.0",
|
|
115
116
|
"tailwindcss": "^4.0.0",
|
|
116
|
-
"vaul": "^1.0.0",
|
|
117
117
|
"zod": "^4.0.0"
|
|
118
118
|
},
|
|
119
119
|
"peerDependenciesMeta": {
|
|
120
120
|
"@hookform/resolvers": {
|
|
121
121
|
"optional": true
|
|
122
122
|
},
|
|
123
|
-
"react-hook-form": {
|
|
124
|
-
"optional": true
|
|
125
|
-
},
|
|
126
123
|
"zod": {
|
|
127
124
|
"optional": true
|
|
128
125
|
},
|
|
129
|
-
"react-day-picker": {
|
|
130
|
-
"optional": true
|
|
131
|
-
},
|
|
132
126
|
"date-fns": {
|
|
133
127
|
"optional": true
|
|
134
|
-
},
|
|
135
|
-
"cmdk": {
|
|
136
|
-
"optional": true
|
|
137
|
-
},
|
|
138
|
-
"next-themes": {
|
|
139
|
-
"optional": true
|
|
140
|
-
},
|
|
141
|
-
"vaul": {
|
|
142
|
-
"optional": true
|
|
143
|
-
},
|
|
144
|
-
"sonner": {
|
|
145
|
-
"optional": true
|
|
146
128
|
}
|
|
147
129
|
},
|
|
148
130
|
"devDependencies": {
|
package/templates/AGENTS.md
CHANGED
|
@@ -36,18 +36,45 @@ DS に該当パターンが無い場合のみカスタム実装を許可。そ
|
|
|
36
36
|
|
|
37
37
|
### CSS のセットアップ(重要)
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
#### ✅ 推奨(consumer が Tailwind v4 を使う場合): `@source` 単一ビルド方式
|
|
40
|
+
|
|
41
|
+
consumer のエントリ CSS で Tailwind を読み込み、`preset`(トークン・`typo-*`・
|
|
42
|
+
コンテナクエリ段・dark variant)を足したうえで、DS の className を **consumer と
|
|
43
|
+
同じ Tailwind ビルド**でスキャン・生成させる。
|
|
44
|
+
|
|
45
|
+
```css
|
|
46
|
+
/* globals.css / app.css など。@source のパスは この CSS ファイルからの相対で
|
|
47
|
+
node_modules/@cakejp/design-system/dist/index.js を指す */
|
|
48
|
+
@import "tailwindcss";
|
|
49
|
+
@import "@cakejp/design-system/preset"; /* トークン・typo-*・コンテナ段・dark variant */
|
|
50
|
+
@source "../node_modules/@cakejp/design-system/dist/index.js"; /* DS の className を consumer と同一ビルドで生成 */
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**なぜこれが推奨か:** ユーティリティのビルドが 1 つに統一されるため、Tailwind の
|
|
54
|
+
「基底ユーティリティ→バリアント」の並び順が保証される。consumer が `.hidden` /
|
|
55
|
+
`.border-transparent` 等 DS と同名のユーティリティを 1 箇所でも使っても、DS の
|
|
56
|
+
コンテナクエリ・データ属性バリアント(`@lg:block`・
|
|
57
|
+
`group-data-[state=active]:border-…` 等)が同一 `@layer utilities` 内で正しく後勝ち
|
|
58
|
+
する。
|
|
59
|
+
|
|
60
|
+
> `@source` のパスは CSS ファイルからの相対。深さが違う場合は `../` の数を調整して
|
|
61
|
+
> 必ず `node_modules/@cakejp/design-system/dist/index.js` を指すこと。Tailwind v4 は
|
|
62
|
+
> 既定で `node_modules` をスキャンしないため、この明示 `@source` が要(かなめ)。
|
|
63
|
+
|
|
64
|
+
#### プリビルド CSS 方式(`dist/index.css`): **consumer が Tailwind を使わない場合のみ**
|
|
42
65
|
|
|
43
66
|
```css
|
|
44
|
-
/* globals.css / app.css など */
|
|
45
67
|
@import "@cakejp/design-system/dist/index.css"; /* DS のコンポーネントスタイル・トークン・preflight */
|
|
46
|
-
@import "tailwindcss"; /* consumer 自身の utility */
|
|
47
68
|
```
|
|
48
69
|
|
|
49
|
-
>
|
|
50
|
-
> Tailwind
|
|
70
|
+
> ⚠️ **consumer が Tailwind v4 を併用する構成でこの方式を使ってはいけない。**
|
|
71
|
+
> DS のプリビルド CSS と consumer の Tailwind は**独立した 2 つのビルド**で、同名
|
|
72
|
+
> ユーティリティ(`.hidden` 等)を別々に同じ `@layer utilities` へ二重出力する。
|
|
73
|
+
> 後段(consumer)の基底ルールが前段(DS)のバリアントルールを宣言順で打ち消し、
|
|
74
|
+
> **DS のバリアントが効かなくなる**。実害例: `Header` / `Footer` / `MenuDrawer` が
|
|
75
|
+
> デスクトップ幅でも永久にモバイル表示になる(consumer の `.hidden` が DS の
|
|
76
|
+
> `@lg:block` に後勝ちする)。import 順を入れ替えても解決しない。**Tailwind 併用時は
|
|
77
|
+
> 上の `@source` 方式を使うこと。**
|
|
51
78
|
|
|
52
79
|
### コンポーネントの使用
|
|
53
80
|
|
package/templates/CLAUDE.md
CHANGED
|
@@ -38,18 +38,46 @@ DS に該当パターンが無い場合のみカスタム実装を許可。そ
|
|
|
38
38
|
|
|
39
39
|
### CSS のセットアップ(重要)
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
#### ✅ 推奨(consumer が Tailwind v4 を使う場合): `@source` 単一ビルド方式
|
|
42
|
+
|
|
43
|
+
consumer のエントリ CSS で Tailwind を読み込み、`preset`(トークン・`typo-*`・
|
|
44
|
+
コンテナクエリ段・dark variant)を足したうえで、DS の className を **consumer と
|
|
45
|
+
同じ Tailwind ビルド**でスキャン・生成させる。
|
|
46
|
+
|
|
47
|
+
```css
|
|
48
|
+
/* globals.css / app.css など。@source のパスは この CSS ファイルからの相対で
|
|
49
|
+
node_modules/@cakejp/design-system/dist/index.js を指す */
|
|
50
|
+
@import "tailwindcss";
|
|
51
|
+
@import "@cakejp/design-system/preset"; /* トークン・typo-*・コンテナ段・dark variant */
|
|
52
|
+
@source "../node_modules/@cakejp/design-system/dist/index.js"; /* DS の className を consumer と同一ビルドで生成 */
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**なぜこれが推奨か:** ユーティリティのビルドが 1 つに統一されるため、Tailwind の
|
|
56
|
+
「基底ユーティリティ→バリアント」の並び順が保証される。consumer が `.hidden` /
|
|
57
|
+
`.border-transparent` 等 DS と同名のユーティリティを 1 箇所でも使っても、DS の
|
|
58
|
+
コンテナクエリ・データ属性バリアント(`@lg:block`・
|
|
59
|
+
`group-data-[state=active]:border-…` 等)が同一 `@layer utilities` 内で正しく後勝ち
|
|
60
|
+
する。プリビルド CSS 方式(下記)はこの整列が破れる(詳細は警告を参照)。
|
|
61
|
+
|
|
62
|
+
> `@source` のパスは CSS ファイルからの相対。深さが違う場合は `../` の数を調整して
|
|
63
|
+
> 必ず `node_modules/@cakejp/design-system/dist/index.js` を指すこと。Tailwind v4 は
|
|
64
|
+
> 既定で `node_modules` をスキャンしないため、この明示 `@source` が DS の className を
|
|
65
|
+
> 拾わせる要(かなめ)になる。
|
|
66
|
+
|
|
67
|
+
#### プリビルド CSS 方式(`dist/index.css`): **consumer が Tailwind を使わない場合のみ**
|
|
44
68
|
|
|
45
69
|
```css
|
|
46
|
-
/* globals.css / app.css など */
|
|
47
70
|
@import "@cakejp/design-system/dist/index.css"; /* DS のコンポーネントスタイル・トークン・preflight */
|
|
48
|
-
@import "tailwindcss"; /* consumer 自身の utility */
|
|
49
71
|
```
|
|
50
72
|
|
|
51
|
-
>
|
|
52
|
-
> Tailwind
|
|
73
|
+
> ⚠️ **consumer が Tailwind v4 を併用する構成でこの方式を使ってはいけない。**
|
|
74
|
+
> DS のプリビルド CSS と consumer の Tailwind は**独立した 2 つのビルド**で、同名
|
|
75
|
+
> ユーティリティ(`.hidden` 等)を別々に同じ `@layer utilities` へ二重出力する。
|
|
76
|
+
> 後段(consumer)の基底ルールが前段(DS)のバリアントルールを宣言順で打ち消し、
|
|
77
|
+
> **DS のバリアントが効かなくなる**。実害例: `Header` / `Footer` / `MenuDrawer` が
|
|
78
|
+
> デスクトップ幅でも永久にモバイル表示になる(consumer の `.hidden` が DS の
|
|
79
|
+
> `@lg:block` に後勝ちする)。import 順を入れ替えても被害者が DS↔consumer で
|
|
80
|
+
> 入れ替わるだけで解決しない。**Tailwind 併用時は上の `@source` 方式を使うこと。**
|
|
53
81
|
|
|
54
82
|
### コンポーネントの使用
|
|
55
83
|
|