@cakejp/design-system 0.14.1 → 0.15.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.
@@ -10,7 +10,7 @@ import { type VariantProps } from "class-variance-authority";
10
10
  * Chip と RadioGroup の chip variant の両方へ自動追従する。
11
11
  */
12
12
  export declare const chipVariants: (props?: {
13
- variant?: "filled" | "accent";
13
+ variant?: "accent" | "filled";
14
14
  size?: "sm" | "lg" | "md" | "tile";
15
15
  shape?: "pill" | "square";
16
16
  } & import("class-variance-authority/types").ClassProp) => string;
@@ -18,7 +18,7 @@ declare function DataTableHead({ className, sortable, sortDirection, onSort, wid
18
18
  }): import("react/jsx-runtime").JSX.Element;
19
19
  declare const dataTableCellVariants: (props?: {
20
20
  width?: "auto" | "max" | "hug";
21
- align?: "center" | "left" | "right";
21
+ align?: "left" | "right" | "center";
22
22
  } & import("class-variance-authority/types").ClassProp) => string;
23
23
  declare function DataTableCell({ className, width, align, ...props }: Omit<React.ComponentProps<"td">, "width" | "align"> & VariantProps<typeof dataTableCellVariants>): import("react/jsx-runtime").JSX.Element;
24
24
  declare function DataTableAvatarCell({ className, src, fallback, title, caption, ...props }: Omit<React.ComponentProps<"td">, "width" | "align"> & {
@@ -12,7 +12,7 @@ import { type VariantProps } from "class-variance-authority";
12
12
  * - 内部 SVG のサイズはバッジが固定する(md=20px / ml=24px / lg=38px)。アイコン側の `size` は不要。
13
13
  */
14
14
  declare const iconBadgeVariants: (props?: {
15
- size?: "lg" | "md" | "ml";
15
+ size?: "ml" | "lg" | "md";
16
16
  } & import("class-variance-authority/types").ClassProp) => string;
17
17
  declare function IconBadge({ className, size, ...props }: React.ComponentProps<"div"> & VariantProps<typeof iconBadgeVariants>): import("react/jsx-runtime").JSX.Element;
18
18
  export { IconBadge, iconBadgeVariants };
@@ -10,9 +10,9 @@ export interface AdminHeaderProps {
10
10
  /**
11
11
  * 管理画面向け固定ヘッダー
12
12
  *
13
- * 上端に **全幅** で fixed 配置される横バー(z-40)。左に SP ハンバーガー+ブランド、
13
+ * 上端に **全幅** で fixed 配置される横バー(--Z-Nav = 40)。左に SP ハンバーガー+ブランド、
14
14
  * 右にアクション slot を持つ。PC ではこのヘッダーの下端(top-16)から `AdminSideNav`
15
- * のレール(z-30)が始まる=ヘッダーが最前面・全幅で、レールはヘッダー帯に重ならない。
15
+ * のレール(--Z-Sticky = 30)が始まる=ヘッダーが最前面・全幅で、レールはヘッダー帯に重ならない。
16
16
  * 「{shopName}管理」のような文言合成は行わない(利用側が `brand` に組み立てて渡す)。
17
17
  *
18
18
  * ### インポート
@@ -48,10 +48,20 @@ export interface HeaderProps extends React.HTMLAttributes<HTMLElement> {
48
48
  /** 右側アクションボタン群(variant="logo"で使用) */
49
49
  actions?: HeaderAction[];
50
50
  /**
51
- * PC(@[768px]+)でヘッダー内インライン表示するグローバルナビ項目。
51
+ * PC(既定 `@[768px]`+)でヘッダー内インライン表示するグローバルナビ項目。
52
52
  * SP では非表示。本番の "ケーキ / スイーツ / ランキング…" メニューに対応。
53
+ * 幅に入り切らない項目は自動で「その他」メニューへ退避する(ロゴ・actions と競合しない)。
53
54
  */
54
55
  navItems?: HeaderNavItem[];
56
+ /**
57
+ * インラインナビ(navItems / searchSlot 行)を出し始めるコンテナ幅。
58
+ * - `md`(既定): `@[768px]`+
59
+ * - `lg` : `@[1024px]`+(ロゴが多段で横幅を食う等、中幅での同居を避けたいとき)
60
+ * 未満の幅では SP 行(ロゴ + actions)になる。
61
+ */
62
+ navBreakpoint?: "md" | "lg";
63
+ /** 「その他」オーバーフローメニューのラベル(既定 "その他") */
64
+ navOverflowLabel?: string;
55
65
  /**
56
66
  * PC(@[768px]+)のロゴ行で navItems と actions の間にインライン配置する検索スロット
57
67
  * (variant="logo" のみ)。`SearchBar` 等を渡す。`flex-1 max-w-[400px]` で伸縮し、
@@ -79,5 +89,5 @@ export interface HeaderProps extends React.HTMLAttributes<HTMLElement> {
79
89
  * アプリ全体で使われるヘッダーの3パターンを1コンポーネントで提供。
80
90
  * ロゴ+アクション、戻るボタン+タイトル、戻るボタン+検索の3バリエーション。
81
91
  */
82
- declare function Header({ className, variant, logo, title, onBack, backLabel, actions, navItems, searchSlot, rightSlot, centerSlot, bottomSlot, disableSticky, ...props }: HeaderProps): import("react/jsx-runtime").JSX.Element;
92
+ declare function Header({ className, variant, logo, title, onBack, backLabel, actions, navItems, navBreakpoint, navOverflowLabel, searchSlot, rightSlot, centerSlot, bottomSlot, disableSticky, ...props }: HeaderProps): import("react/jsx-runtime").JSX.Element;
83
93
  export { Header };
@@ -66,7 +66,7 @@ export interface SectionNavProps extends React.HTMLAttributes<HTMLElement> {
66
66
  * <SectionNav
67
67
  * orientation="horizontal"
68
68
  * activeKey={active}
69
- * className="sticky top-14 z-30 border-b border-[var(--Border-Low-Emphasis)] bg-[var(--Surface-Primary)]"
69
+ * className="sticky top-14 z-[var(--Z-Sticky)] border-b border-[var(--Border-Low-Emphasis)] bg-[var(--Surface-Primary)]"
70
70
  * items={items}
71
71
  * />
72
72
  * // ターゲット: ナビ高さぶん上に余白を確保(scroll-mt-28 ≒ header 56px + nav 48px)
@@ -1,7 +1,7 @@
1
1
  import * as React from "react";
2
2
  import { type VariantProps } from "class-variance-authority";
3
3
  declare const tagVariants: (props?: {
4
- variant?: "default" | "success" | "info" | "warning" | "accent" | "caution" | "sale" | "info-fill" | "timesale" | "berry" | "coupon";
4
+ variant?: "accent" | "default" | "success" | "info" | "warning" | "caution" | "sale" | "info-fill" | "timesale" | "berry" | "coupon";
5
5
  size?: "sm" | "md";
6
6
  } & import("class-variance-authority/types").ClassProp) => string;
7
7
  export interface TagProps extends React.HTMLAttributes<HTMLSpanElement>, VariantProps<typeof tagVariants> {
@@ -1,2 +1,25 @@
1
1
  import { type ClassValue } from "clsx";
2
+ /**
3
+ * src/styles/typography.css の `@utility typo-*` のうち、
4
+ * font-size / line-height / font-weight(+letter-spacing)を定義する「プリセット系」クラス名。
5
+ *
6
+ * デフォルトの twMerge は `typo-*` を認識しないため、`cn("typo-label-sm", "typo-label-md")`
7
+ * のような上書きが「どちらも残す」扱いになり、CSS 宣言順(後発の定義が勝つ)に
8
+ * マージ結果が左右されてしまう(意図した方が静かに負けることがある)。
9
+ * ここではプリセット系 typo-* を単一の classGroup として登録し、同グループ内は
10
+ * 後勝ち(最後に渡したクラスのみ残る)で確実にマージされるようにする。
11
+ *
12
+ * 注意: typography.css に `@utility typo-*` を追加/削除したら、この配列も
13
+ * 同期して更新すること。__tests__/cn-typo-merge.test.ts がドリフトを検知する
14
+ * (typography.css を正規表現でパースし、font-size を持つプリセット系だけを抽出して
15
+ * この配列と突合し、不一致なら fail)。
16
+ */
17
+ export declare const TYPO_PRESET_CLASS_NAMES: readonly ["typo-heading-5xl", "typo-heading-4xl", "typo-heading-3xl", "typo-heading-2xl", "typo-heading-xl", "typo-heading-lg", "typo-heading-md", "typo-heading-sm", "typo-body-lg", "typo-body-md", "typo-body-sm", "typo-body-xs", "typo-label-lg", "typo-label-md", "typo-label-sm", "typo-label-xs"];
18
+ /**
19
+ * font-size を持たない「加算系」typo-*(text-shadow のみ付与する等)クラス名。
20
+ * 現在 cake の typography.css には存在しないため空。追加された場合は
21
+ * 排他 classGroup(TYPO_PRESET_CLASS_NAMES)ではなくこちらに列挙する
22
+ * — プリセット系と併用されるため、同一 classGroup に入れると一方が誤って消される。
23
+ */
24
+ export declare const TYPO_ADDITIVE_CLASS_NAMES: readonly string[];
2
25
  export declare function cn(...inputs: ClassValue[]): string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cakejp/design-system",
3
- "version": "0.14.1",
3
+ "version": "0.15.0",
4
4
  "type": "module",
5
5
  "description": "Cake.jp Design System — UI コンポーネント・カラートークン・タイポグラフィ",
6
6
  "license": "UNLICENSED",
@@ -71,6 +71,7 @@
71
71
  "./tokens/primitive": "./src/styles/primitive.css",
72
72
  "./tokens/semantic": "./src/styles/semantic.css",
73
73
  "./tokens/typography": "./src/styles/typography.css",
74
+ "./tokens/motion": "./src/styles/motion.css",
74
75
  "./eslint/deprecated": "./eslint/deprecated.js"
75
76
  },
76
77
  "sideEffects": [
@@ -96,7 +97,9 @@
96
97
  "generate:lookup": "node scripts/generate-component-lookup.mjs",
97
98
  "lint:contrast": "node scripts/check-contrast.mjs",
98
99
  "check": "tsc --noEmit -p tsconfig.app.json && npm run typecheck:stories && bash scripts/check-deps.sh && bash scripts/check-drift.sh && bash scripts/check-docs-drift.sh && bash scripts/lint-scratch.sh && bash scripts/check-story-reuse.sh && bash scripts/check-responsive.sh && node scripts/check-border-color.mjs && npm run lint:contrast && bash scripts/lint-scratch.sh --components && bash scripts/check-generated-drift.sh",
99
- "test": "vitest run --config vitest.config.ts"
100
+ "test": "vitest run --config vitest.config.ts",
101
+ "test:interaction": "vitest run --config vitest.storybook.config.ts",
102
+ "test:a11y": "vitest run --config vitest.a11y.config.ts"
100
103
  },
101
104
  "dependencies": {
102
105
  "class-variance-authority": "^0.7.1",
@@ -11,7 +11,7 @@
11
11
 
12
12
  | Component | Import | Variants | Stories |
13
13
  |-----------|--------|----------|---------|
14
- | Accordion, AccordionItem, AccordionTrigger, AccordionContent | `@/components/foundations/accordion` | — | Default(単一展開), 複数展開, 商品ページFAQ例 |
14
+ | Accordion, AccordionItem, AccordionTrigger, AccordionContent | `@/components/foundations/accordion` | — | Default(単一展開), 複数展開, 商品ページFAQ例, interaction: 単一展開の排他と折りたたみ |
15
15
  | AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogMedia, AlertDialogOverlay, AlertDialogPortal, AlertDialogTitle, AlertDialogTrigger | `@/components/foundations/alert-dialog` | — | Default, 破壊的操作(アカウント削除), コンパクトサイズ |
16
16
  | Alert, AlertTitle, AlertDescription | `@/components/foundations/alert` | **variant**: `success`, `info`, `error`, `warning`, `inline-info`, `inline-caution`<br>**variant**: `success`, `info`, `error`, `warning`, `inline-info`, `inline-caution`, `inline-warning` | Success(成功), Info(お知らせ), Error(エラー), Warning(注意), Inline Info(インライン情報), Inline Caution(インラインエラー), Inline Warning(インライン警告), Prop-based Warning(旧 Banner 相当), Prop-based Error(エラー), Prop-based Info(お知らせ), Prop-based Success(成功), Prop-based with Action(アクション付き), Prop-based Inline Info(インライン情報), Prop-based Inline Caution(インラインエラー), Prop-based Inline Warning(インライン警告), Info + ボタン, Error(複数メッセージ), 全 Bordered バリアント, 全 Inline バリアント |
17
17
  | AspectRatio | `@/components/foundations/aspect-ratio` | — | Square, Banner16x9, ProductImage4x3, RatioComparison |
@@ -28,8 +28,8 @@
28
28
  | Command, CommandDialog, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem, CommandShortcut, CommandSeparator | `@/components/foundations/command` | — | Default, ProductSearch, DeliveryOptions |
29
29
  | ContextMenu, ContextMenuTrigger, ContextMenuContent, ContextMenuItem, ContextMenuCheckboxItem, ContextMenuRadioItem, ContextMenuLabel, ContextMenuSeparator, ContextMenuShortcut, ContextMenuGroup, ContextMenuPortal, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuRadioGroup | `@/components/foundations/context-menu` | — | Default, WithCheckboxItems |
30
30
  | DataTable, DataTableTable, DataTableHeader, DataTableBody, DataTableRow, DataTableHead, DataTableCell, DataTableAvatarCell, DataTableImageCell, DataTableLinkCell, DataTableCheckboxCell, DataTableActionCell, DataTableInputCell, DataTableSelectCell, DataTableNumberCell, DataTableDragHandleCell, DataTableBulkActions, DataTableSectionRow, DataTableAddRow, DataTableEmptyState | `@/components/foundations/data-table` | **state**: `default`, `selected`<br>**width**: `auto`, `max`, `hug`<br>**align**: `left`, `right`, `center` | Default, チェックボックス選択, タイトル固定, セクション, 空状態, 新規追加行, セル型バリエーション, 実用例(注文管理), 入力系セル一覧, ソートヘッダー, D&D並び替え |
31
- | Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger | `@/components/foundations/dialog` | — | Default, 確認ダイアログ, フォーム入力 |
32
- | Drawer, DrawerPortal, DrawerOverlay, DrawerTrigger, DrawerClose, DrawerContent, DrawerHeader, DrawerFooter, DrawerTitle, DrawerDescription | `@/components/foundations/drawer` | — | Default, カート追加クイックビュー, お届け日選択 |
31
+ | Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger | `@/components/foundations/dialog` | — | Default, 確認ダイアログ, フォーム入力, interaction: 開閉とフォーカストラップ |
32
+ | Drawer, DrawerPortal, DrawerOverlay, DrawerTrigger, DrawerClose, DrawerContent, DrawerHeader, DrawerFooter, DrawerTitle, DrawerDescription | `@/components/foundations/drawer` | — | Default, カート追加クイックビュー |
33
33
  | DropdownMenu, DropdownMenuPortal, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuGroup, DropdownMenuLabel, DropdownMenuItem, DropdownMenuCheckboxItem, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubTrigger, DropdownMenuSubContent | `@/components/foundations/dropdown-menu` | — | Default, グループ付き, 注文アクション例 |
34
34
  | Field, FieldLabel, FieldSet, FieldLegend, FieldGroup, FieldDescription, FieldError, FieldSeparator | `@/components/foundations/field` | — | フォーム一式, ラベル付き区切り, Field / FieldLabel(1フィールドの箱) |
35
35
  | FileInput | `@/components/foundations/file-input` | — | Default, 複数選択 + accept, 無効, maxSize 超過エラー, FormField 連携 |
@@ -44,7 +44,7 @@
44
44
  | Popover, PopoverTrigger, PopoverContent, PopoverAnchor, PopoverHeader, PopoverTitle, PopoverDescription | `@/components/foundations/popover` | — | Default, DeliveryDatePicker, AllergyInfo |
45
45
  | Progress | `@/components/foundations/progress` | — | Default, 送料無料まで, 送料無料達成 |
46
46
  | RadioGroup, RadioGroupItem | `@/components/foundations/radio-group` | — | Default, 説明付き, 選択済み, 無効状態, エラーパターン, 補足説明なし, 配送方法選択例, チップ型(choice chip), チップ型(制御・無効), チップ型(エラー), 支払い方法(クレカ入力済), 支払い方法(クレカ未入力) |
47
- | ResponsiveDialog, ResponsiveDialogTrigger, ResponsiveDialogContent, ResponsiveDialogHeader, ResponsiveDialogFooter, ResponsiveDialogTitle, ResponsiveDialogDescription, ResponsiveDialogClose | `@/components/foundations/responsive-dialog` | — | 確認ダイアログ, フォーム入力, お知らせ(閉じるのみ) |
47
+ | ResponsiveDialog, ResponsiveDialogTrigger, ResponsiveDialogContent, ResponsiveDialogHeader, ResponsiveDialogFooter, ResponsiveDialogTitle, ResponsiveDialogDescription, ResponsiveDialogClose | `@/components/foundations/responsive-dialog` | — | 確認ダイアログ, フォーム入力, お知らせ(閉じるのみ), お届け日選択(選択リスト) |
48
48
  | ScrollArea, ScrollBar | `@/components/foundations/scroll-area` | — | Default, HorizontalTagScroll, OrderHistoryList |
49
49
  | Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue | `@/components/foundations/select` | — | Default, ラベル付き, グループ分け, サイズ比較, 注文フォーム例, エラーパターン, 横並びパターン(氏名・住所), Input と並置(高さが揃う) |
50
50
  | Separator | `@/components/foundations/separator` | — | Default(水平), 垂直, 注文確認ページ例 |
@@ -57,7 +57,7 @@
57
57
  | Spinner | `@/components/foundations/spinner` | — | Default, Small, Large, InlineWithText, FullPage |
58
58
  | Switch | `@/components/foundations/switch` | — | Default, ON 状態, 無効, サイズ比較, ブロック型, 通知設定例(リスト型) |
59
59
  | Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption | `@/components/foundations/table` | — | Default, フッター付き, 商品比較例, カート注文サマリー |
60
- | Tabs, TabsList, TabsTrigger, TabsContent | `@/components/foundations/tabs` | **variant**: `underbar`, `segment`<br>**scrollable**: `true` | Default(Underbar), タブ数バリエーション, 横スクロール(多数タブ), PC モード(文字幅ベース), Segment(ピル型), Segment 3択 |
60
+ | Tabs, TabsList, TabsTrigger, TabsContent | `@/components/foundations/tabs` | **variant**: `underbar`, `segment`<br>**scrollable**: `true` | Default(Underbar), タブ数バリエーション, 横スクロール(多数タブ), PC モード(文字幅ベース), Segment(ピル型), Segment 3択, interaction: クリックと矢印キーでの切り替え |
61
61
  | Textarea | `@/components/foundations/textarea` | — | Default, 無効, メッセージカード入力例, エラーパターン, レビュー投稿例, 文字数カウンタ |
62
62
  | ToggleGroup, ToggleGroupItem | `@/components/foundations/toggle-group` | **width**: `fit`, `full`<br>**variant**: `default`, `outline`<br>**size**: `default`, `sm`, `lg`<br>**variant**: `default`, `outline`<br>**size**: `default`, `sm`, `lg` | Default, 複数選択, サイズ, アイコン付き, アイコンのみ, 無効 |
63
63
  | Toggle | `@/components/foundations/toggle` | **variant**: `default`, `outline`<br>**size**: `default`, `sm`, `lg` | Default, TextFormatting, FavoriteToggle, Outline, Sizes |
@@ -77,7 +77,7 @@
77
77
  | CategoryScroll | `@/components/primitives/category-scroll` | — | Default, CircleThumbnails |
78
78
  | CategoryShortcuts | `@/components/primitives/category-shortcuts` | — | Default, 選択あり, インタラクティブ(onClick), 商品一覧ページでの使用例 |
79
79
  | ChatComposer | `@/components/primitives/chat-composer` | — | 基本, 添付あり, ⌘Enter 送信, 送信中, 無効化, 文字数カウンタ |
80
- | Chip | `@/components/primitives/chip` | **variant**: `filled`, `accent`<br>**size**: `sm`, `md`, `lg`, `tile`<br>**shape**: `pill`, `square` | Default, 人気キーワード, 全バリアント, States(hover / disabled), サイズ比較, フィルター選択, 削除可能(選択済みフィルター), 検索画面での使用例 |
80
+ | Chip | `@/components/primitives/chip` | **variant**: `filled`, `accent`<br>**size**: `sm`, `md`, `lg`, `tile`<br>**shape**: `pill`, `square` | Default, 人気キーワード, 全バリアント, States(hover / disabled), サイズ比較, サイズタイル(狭い横並び), フィルター選択, 削除可能(選択済みフィルター), 検索画面での使用例 |
81
81
  | CoachMark | `@/components/primitives/coach-mark` | — | オンボーディング, 全方向, オンボーディング各方向 |
82
82
  | Combobox | `@/components/primitives/combobox` | — | Default |
83
83
  | Container | `@/components/primitives/container` | — | Default(page / default gutter), サイズ比較, gutter 比較 |
@@ -89,7 +89,7 @@
89
89
  | Footer | `@/components/primitives/footer` | — | Default, 最小構成, SNSリンク付き, 決済方法付き |
90
90
  | FormField | `@/components/primitives/form-field` | — | — |
91
91
  | FunnelShell | `@/components/primitives/funnel-shell` | — | 注文内容の確認(ご購入手続き) |
92
- | Header | `@/components/primitives/header` | — | ロゴ+アクション, ロゴ+未ログイン, ロゴ+グローバルナビ+検索スロット(PC), ロゴセンター(決済・申し込み用), 戻る+タイトル, 戻る+検索バー, 戻る+右側アクション, カスタムロゴ |
92
+ | Header | `@/components/primitives/header` | — | ロゴ+アクション, ロゴ+未ログイン, ロゴ+グローバルナビ+検索スロット(PC), ロゴ+長いナビ(中幅で自動退避), ロゴ+ナビ(navBreakpoint=lg), ロゴセンター(決済・申し込み用), 戻る+タイトル, 戻る+検索バー, 戻る+右側アクション, カスタムロゴ |
93
93
  | ImageCarousel | `@/components/primitives/image-carousel` | — | バナーカルーセル, 横長バナー, 正方形(商品画像), OGP比率, 自動再生(3秒), PC幅(ビューポート切替で確認), トップページ ヒーローバナー |
94
94
  | ImageGallery | `@/components/primitives/image-gallery` | — | ドット付き, サムネイル付き, バナー(16:9), PC商品詳細, 単一画像 |
95
95
  | ImageInput | `@/components/primitives/image-input` | **aspect**: `square`, `landscape`<br>**size**: `sm`, `md`, `lg` | 基本, 保存済み画像あり, 表示サイズ, FormField 連携, 検証エラー, クリア不可, 無効化 |
@@ -100,7 +100,7 @@
100
100
  | MultiSelect | `@/components/primitives/multi-select` | — | Default |
101
101
  | NotificationBadge | `@/components/primitives/notification-badge` | **color**: `red`, `green`<br>**size**: `sm`, `md` | Default, ドットバッジ, 数値バッジ, カラーバリエーション, ヘッダーでの使用例, 非表示状態 |
102
102
  | NotificationList | `@/components/primitives/notification-list` | — | デフォルト, 横並び(管理画面向け), 空の状態 |
103
- | NumberInput, QuantitySelector | `@/components/primitives/number-input` | — | Default, コンパクト型(sm), サイズ比較, 最小・最大値, 無効状態, エラー状態, ゴミ箱アイコン, ゴミ箱+削除確認ダイアログ, 直接入力パターン, 商品詳細での使用例, カート内での使用例, 価格・在庫入力(管理画面) |
103
+ | NumberInput, QuantitySelector | `@/components/primitives/number-input` | — | Default, コンパクト型(sm), サイズ比較, 最小・最大値, 無効状態, エラー状態, ゴミ箱アイコン, ゴミ箱+削除確認ダイアログ, 直接入力パターン, 商品詳細での使用例, カート内での使用例, 価格・在庫入力(管理画面), interaction: 増減と min/max のクランプ |
104
104
  | PriceDisplay | `@/components/primitives/price-display` | — | Default, セール価格, サイズ比較, セール × サイズ, 税込ラベルなし, 高額商品, 価格レンジ |
105
105
  | ProgressSteps | `@/components/primitives/progress-steps` | — | ステップ1(カート), ステップ2(注文内容), ステップ3(確認), ステップ4(完了), 全ステップ一覧, 会員登録フロー |
106
106
  | SearchBar | `@/components/primitives/search-bar` | — | Default, Small(ヘッダー向け), カスタムプレースホルダー |
@@ -20,6 +20,8 @@
20
20
  * - shadcn bridge トークン(--primary, --foreground 等)
21
21
  * - spacing / セクション余白トークン
22
22
  * - シャドウ・角丸トークン
23
+ * - モーショントークン(--Motion-Duration-* / --Motion-Easing-*)
24
+ * - 重なり順トークン(--Z-*)
23
25
  *
24
26
  * タイポグラフィ(typo-*)は Tailwind v4 の @utility に依存するため、
25
27
  * このファイルには含まれない。代わりに typo-* と同等のクラス定義を
@@ -399,6 +401,44 @@
399
401
  --shadow-tooltip: 0px 8px 8px -4px rgba(24, 39, 75, 0.08), 0px 4px 6px -4px rgba(24, 39, 75, 0.12);
400
402
  }
401
403
 
404
+ /* --- Motion tokens ---
405
+ * src/styles/motion.css と同値(Tailwind 非使用 consumer 向けに展開)。
406
+ * 値の正本は tokens.json の motion。両者の一致は
407
+ * __tests__/motion-zindex-token-contract.test.ts が検査する。 */
408
+ :root {
409
+ --Motion-Duration-Fast: 150ms;
410
+ --Motion-Duration-Base: 200ms;
411
+ --Motion-Duration-Slow: 300ms;
412
+ --Motion-Duration-Slower: 500ms;
413
+ --Motion-Easing-Standard: cubic-bezier(0, 0, 0.58, 1);
414
+ }
415
+ @media (prefers-reduced-motion: reduce) {
416
+ :root {
417
+ --Motion-Duration-Fast: 0.01ms;
418
+ --Motion-Duration-Base: 0.01ms;
419
+ --Motion-Duration-Slow: 0.01ms;
420
+ --Motion-Duration-Slower: 0.01ms;
421
+ }
422
+ }
423
+
424
+ /* --- z-index スケール ---
425
+ * src/preset.css と同値(Tailwind 非使用 consumer 向けに展開)。
426
+ * 序列と「現状 50 が並ぶ理由」は preset.css のコメントを参照。 */
427
+ :root {
428
+ --Z-Local-1: 1;
429
+ --Z-Local-2: 2;
430
+ --Z-Local-3: 3;
431
+ --Z-Local-4: 4;
432
+ --Z-Sticky: 30;
433
+ --Z-Nav: 40;
434
+ --Z-Floating: 50;
435
+ --Z-Overlay: 50;
436
+ --Z-Modal: 50;
437
+ --Z-Popover: 50;
438
+ --Z-Tooltip: 50;
439
+ --Z-SkipLink: 50;
440
+ }
441
+
402
442
  /* --- Typography Helper Classes ---
403
443
  * Tailwindのtypo-*と同等のCSSクラス。
404
444
  * 本番CSSでこれらのクラスを使えば、DSと同じタイポグラフィが適用される。
package/src/preset.css CHANGED
@@ -17,6 +17,8 @@
17
17
  * - shadcn bridge トークン(--primary, --foreground 等)
18
18
  * - Tailwind 標準色 → Cake.jp マッピング(bg-red-600 等)
19
19
  * - シャドウ・角丸トークン
20
+ * - モーショントークン(--Motion-Duration-* / --Motion-Easing-*)
21
+ * - 重なり順トークン(--Z-*)
20
22
  * - アニメーションユーティリティ
21
23
  * - 見た目を変えず44pxの操作領域を確保する tap-target ユーティリティ
22
24
  * ============================================ */
@@ -30,6 +32,9 @@
30
32
  /* --- Layer 3: Typography Utilities --- */
31
33
  @import "./styles/typography.css";
32
34
 
35
+ /* --- Layer 4: Motion Tokens (duration / easing) --- */
36
+ @import "./styles/motion.css";
37
+
33
38
  /* --- Dark mode variant --- */
34
39
  @custom-variant dark (&:is(.dark *));
35
40
 
@@ -286,6 +291,47 @@
286
291
  --sidebar-ring: var(--Overlay-Medium);
287
292
  }
288
293
 
294
+ /* --- z-index スケール ---
295
+ * 重なり順を「意味の段」で表す。Portal に載る要素(Dialog / Sheet / Popover /
296
+ * Tooltip 等)は素の z-50 だと差が付かず、勝敗が Portal のマウント順
297
+ * (=開いた順)で決まってしまうため、段を名前で持つ。
298
+ *
299
+ * Tailwind からは z-[var(--Z-Modal)] の形で参照する。
300
+ *
301
+ * ┌ 序列(数値) ─────────────────────────────────────────
302
+ * │ Local-1..4 (1〜4) : カード内部の重なり(バッジ・グラデ・ラベル)
303
+ * │ Sticky (30) : スクロール追従(サブナビ・注文サマリ・レール)
304
+ * │ Nav (40) : シェルが敷く固定ヘッダ / 固定アクションバー
305
+ * │ Floating (50) : ナビの上に浮く固定操作面(ボトムタブ)
306
+ * │ Overlay (50) : Dialog / Sheet / Drawer の scrim
307
+ * │ Modal (50) : Dialog / Sheet / Drawer 本体
308
+ * │ Popover (50) : Select / Popover / DropdownMenu / Menubar / HoverCard
309
+ * │ Tooltip (50) : Tooltip
310
+ * │ SkipLink (50) : SkipLink(何にも隠されてはいけない)
311
+ * └────────────────────────────────────────────────────
312
+ *
313
+ * ⚠️ Floating 以降が全て 50 なのは **現状の実装値をそのまま保存した**結果
314
+ * (本トークン導入は視覚変化ゼロの等値置換)。段差を付けると重なり順が
315
+ * 実際に変わる=視覚変化なので、値の見直しは別途 issue で扱う。名前で段を
316
+ * 分けておくことで、そのときは 1 箇所の数値変更だけで全体を持ち上げられる。
317
+ *
318
+ * z-0 / z-10 のようなコンポーネント内部の局所的な重なり(isolate 配下の
319
+ * 装飾レイヤー等)はこのグローバルスケールの対象外。 */
320
+ :root {
321
+ --Z-Local-1: 1;
322
+ --Z-Local-2: 2;
323
+ --Z-Local-3: 3;
324
+ --Z-Local-4: 4;
325
+ --Z-Sticky: 30;
326
+ --Z-Nav: 40;
327
+ --Z-Floating: 50;
328
+ --Z-Overlay: 50;
329
+ --Z-Modal: 50;
330
+ --Z-Popover: 50;
331
+ --Z-Tooltip: 50;
332
+ --Z-SkipLink: 50;
333
+ }
334
+
289
335
  /* --- Animations --- */
290
336
  @keyframes slide-in-right {
291
337
  from { transform: translateX(30%); opacity: 0; }
@@ -296,11 +342,15 @@
296
342
  to { transform: translateX(0); opacity: 1; }
297
343
  }
298
344
 
345
+ /* duration / easing はモーショントークン参照(値は従来どおり 200ms・
346
+ CSS の ease-out = cubic-bezier(0, 0, 0.58, 1))。
347
+ preset.css 単体ではなく motion.css を上で @import しているので必ず解決するが、
348
+ 万一 motion.css 抜きで読まれても動きが消えないようフォールバックを置く。 */
299
349
  @utility animate-slide-in-right {
300
- animation: slide-in-right 200ms ease-out;
350
+ animation: slide-in-right var(--Motion-Duration-Base, 200ms) var(--Motion-Easing-Standard, cubic-bezier(0, 0, 0.58, 1));
301
351
  }
302
352
  @utility animate-slide-in-left {
303
- animation: slide-in-left 200ms ease-out;
353
+ animation: slide-in-left var(--Motion-Duration-Base, 200ms) var(--Motion-Easing-Standard, cubic-bezier(0, 0, 0.58, 1));
304
354
  }
305
355
 
306
356
  /* --- Touch target utility ---
@@ -0,0 +1,58 @@
1
+ /* ============================================
2
+ * Cake.jp Design System — Motion Tokens
3
+ * ============================================
4
+ *
5
+ * 動きの「速さ」と「加減速カーブ」の semantic トークン。
6
+ * 色と同じく、コンポーネントは生の ms 値 / cubic-bezier を直書きせず
7
+ * このレイヤーを参照する。
8
+ *
9
+ * 使い方(Tailwind v4):
10
+ * duration-[var(--Motion-Duration-Base)]
11
+ * ease-[var(--Motion-Easing-Standard)]
12
+ * Tailwind を使わない consumer は素の CSS から var() で参照できる。
13
+ *
14
+ * 定義しているのは **DS の実装に実在した値だけ**(150/200/300/500ms・
15
+ * CSS の ease-out カーブ)。使われない段は作らない(死にトークン禁止)。
16
+ * 正本の一覧は tokens.json の motion セクション。
17
+ * ============================================ */
18
+
19
+ :root {
20
+ /* ─── Duration スケール ───
21
+ Fast : マイクロ(hover の色変化・fade・下線)。
22
+ Base : 標準。入場・退場・レイアウト変化の既定。
23
+ Slow : 面積の大きい要素(画像ズーム・アコーディオン・カルーセル)。
24
+ Slower : ゆっくり見せたい退場(Sheet の閉じ)。 */
25
+ --Motion-Duration-Fast: 150ms;
26
+ --Motion-Duration-Base: 200ms;
27
+ --Motion-Duration-Slow: 300ms;
28
+ --Motion-Duration-Slower: 500ms;
29
+
30
+ /* ─── Easing ───
31
+ Standard : CSS の `ease-out` キーワードと同一曲線。UI 変化の既定。
32
+ DS の animate-slide-in-* が使っていた曲線をそのまま名前付けしたもの。
33
+
34
+ ⚠️ Tailwind の `ease-out` クラス(cubic-bezier(0, 0, 0.2, 1))は
35
+ CSS キーワードの ease-out(cubic-bezier(0, 0, 0.58, 1))と別の曲線。
36
+ Standard は後者。Tailwind のユーティリティクラスを使っている既存箇所は
37
+ 体感が変わるため本トークンへ寄せていない(曲線を何本に整理するかは
38
+ 視覚が変わる設計判断なので別途扱う)。 */
39
+ --Motion-Easing-Standard: cubic-bezier(0, 0, 0.58, 1);
40
+ }
41
+
42
+ /* ─── prefers-reduced-motion 一括制御 ───
43
+ duration トークンを 0 近傍に落とすことで、トークンを参照している
44
+ 全コンポーネントのアニメーションを一箇所で無効化する。
45
+ 0 ではなく 0.01ms にしているのは、transitionend / animationend を
46
+ 待つ実装が発火しなくなるのを避けるため。
47
+
48
+ ※ 効くのはトークンを参照している箇所だけ。`duration-200` のような
49
+ 直書きや Radix 内蔵アニメーションは対象外なので、コンポーネント側は
50
+ 必ずトークン参照で書くこと。 */
51
+ @media (prefers-reduced-motion: reduce) {
52
+ :root {
53
+ --Motion-Duration-Fast: 0.01ms;
54
+ --Motion-Duration-Base: 0.01ms;
55
+ --Motion-Duration-Slow: 0.01ms;
56
+ --Motion-Duration-Slower: 0.01ms;
57
+ }
58
+ }
package/tokens.json CHANGED
@@ -1000,5 +1000,33 @@
1000
1000
  "modal": "var(--shadow-lg)",
1001
1001
  "overlay": "0 24px 80px rgba(24, 39, 75, 0.16)",
1002
1002
  "_comment": "preset.css の --shadow-* と同期(正)。md/lg は Tailwind 既定を DS 値に再定義済み。xl/2xl は使用禁止(rules.json R53)"
1003
+ },
1004
+ "motion": {
1005
+ "duration": {
1006
+ "fast": "150ms",
1007
+ "base": "200ms",
1008
+ "slow": "300ms",
1009
+ "slower": "500ms"
1010
+ },
1011
+ "easing": {
1012
+ "standard": "cubic-bezier(0, 0, 0.58, 1)"
1013
+ },
1014
+ "_comment": "src/styles/motion.css の --Motion-Duration-* / --Motion-Easing-* と同期(正)。Tailwind からは duration-[var(--Motion-Duration-Base)] の形で参照する。定義しているのは DS 実装に実在した値だけ。prefers-reduced-motion では duration が 0.01ms に落ちる。standard は CSS キーワードの ease-out と同一曲線(Tailwind の ease-out クラス cubic-bezier(0,0,0.2,1) とは別物)"
1015
+ },
1016
+ "zIndex": {
1017
+ "local-1": 1,
1018
+ "local-2": 2,
1019
+ "local-3": 3,
1020
+ "local-4": 4,
1021
+ "sticky": 30,
1022
+ "nav": 40,
1023
+ "floating": 50,
1024
+ "overlay": 50,
1025
+ "modal": 50,
1026
+ "popover": 50,
1027
+ "tooltip": 50,
1028
+ "skip-link": 50,
1029
+ "_order": "local-1 < local-2 < local-3 < local-4 < sticky < nav <= floating <= overlay <= modal <= popover <= tooltip <= skip-link",
1030
+ "_comment": "preset.css の --Z-* と同期(正)。Tailwind からは z-[var(--Z-Modal)] の形で参照する。floating 以降が全て 50 なのは既存実装値をそのまま保存した結果(トークン導入は視覚変化ゼロの等値置換)。段差を付けると重なり順が変わる=視覚変化なので値の見直しは別 issue。z-0/z-10 のコンポーネント内部の重なりはこのスケールの対象外"
1003
1031
  }
1004
1032
  }