@cakejp/design-system 0.11.0 → 0.13.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.
Files changed (53) hide show
  1. package/CHANGELOG.md +85 -1
  2. package/CLAUDE.md +22 -1
  3. package/README.md +48 -0
  4. package/UPDATING.md +9 -0
  5. package/bin/check-duplicates.mjs +256 -0
  6. package/bin/exports-parser.mjs +54 -0
  7. package/bin/init.js +11 -0
  8. package/contracts/components.json +395 -37
  9. package/contracts/composition.json +10 -7
  10. package/contracts/rules.json +21 -3
  11. package/dist/index.css +1 -1
  12. package/dist/index.js +6134 -3475
  13. package/dist/types/components/ec/admin-shell.d.ts +39 -2
  14. package/dist/types/components/ec/mypage-shell.d.ts +10 -1
  15. package/dist/types/components/ec/product-card.d.ts +3 -1
  16. package/dist/types/components/ec/product-list-item.d.ts +8 -1
  17. package/dist/types/components/foundations/alert.d.ts +5 -1
  18. package/dist/types/components/foundations/button.d.ts +1 -1
  19. package/dist/types/components/foundations/card.d.ts +36 -2
  20. package/dist/types/components/foundations/chip-variants.d.ts +17 -0
  21. package/dist/types/components/foundations/field.d.ts +81 -0
  22. package/dist/types/components/foundations/file-input.d.ts +75 -0
  23. package/dist/types/components/foundations/icon-badge.d.ts +2 -2
  24. package/dist/types/components/foundations/input.d.ts +11 -1
  25. package/dist/types/components/foundations/radio-group.d.ts +12 -2
  26. package/dist/types/components/foundations/skip-link.d.ts +39 -0
  27. package/dist/types/components/foundations/textarea.d.ts +11 -1
  28. package/dist/types/components/primitives/chat-composer.d.ts +87 -0
  29. package/dist/types/components/primitives/chip.d.ts +2 -7
  30. package/dist/types/components/primitives/content-carousel.d.ts +58 -0
  31. package/dist/types/components/primitives/date-picker.d.ts +44 -0
  32. package/dist/types/components/primitives/error-state.d.ts +43 -16
  33. package/dist/types/components/primitives/funnel-shell.d.ts +12 -1
  34. package/dist/types/components/primitives/header.d.ts +15 -1
  35. package/dist/types/components/primitives/image-input.d.ts +119 -0
  36. package/dist/types/components/primitives/section-header.d.ts +9 -2
  37. package/dist/types/components/primitives/section-nav.d.ts +28 -2
  38. package/dist/types/components/primitives/section.d.ts +35 -2
  39. package/dist/types/components/primitives/share-buttons.d.ts +8 -2
  40. package/dist/types/components/primitives/standard-page-shell.d.ts +11 -1
  41. package/dist/types/components/primitives/timeline.d.ts +23 -0
  42. package/dist/types/components/primitives/workspace-shell.d.ts +21 -1
  43. package/dist/types/index.d.ts +80 -4
  44. package/dist/types/lib/pagination-range.d.ts +16 -0
  45. package/dist/types/lib/use-value-length.d.ts +31 -0
  46. package/package.json +2 -1
  47. package/src/preset-standalone.css +322 -4
  48. package/src/preset.css +17 -0
  49. package/src/styles/semantic.css +7 -0
  50. package/src/styles/typography.css +15 -1
  51. package/templates/AGENTS.md +11 -0
  52. package/templates/CLAUDE.md +11 -0
  53. package/tokens.json +18 -2
@@ -0,0 +1,58 @@
1
+ import * as React from "react";
2
+ export type ContentCarouselItemsPerView = 1 | 2 | 3 | 4;
3
+ export interface ContentCarouselProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "children"> {
4
+ /**
5
+ * スライド内容(ReactNode)のリスト。
6
+ * 画像URLではなく任意の JSX を受けるため、eyebrow / タイトル / 本文 / 価格 /
7
+ * バッジで構成したテキスト主体のヒーローバナー等を組める。
8
+ * 各スライドは DS コンポーネント(Badge, Button 等)と typo-* / セマンティック
9
+ * トークンで組むこと(スクラッチ禁止ルール準拠)。
10
+ */
11
+ slides: React.ReactNode[];
12
+ /** ドットインジケーター表示 */
13
+ showDots?: boolean;
14
+ /** 矢印ナビゲーション表示 */
15
+ showArrows?: boolean;
16
+ /** 自動再生(ミリ秒、0で無効) */
17
+ autoPlay?: number;
18
+ /**
19
+ * SP: 隣スライドをのぞかせる(peek)表示。
20
+ * true にすると各スライドが `calc(100% - 48px)` 幅になり、
21
+ * 右端に次スライドが見える。PC (@[960px]:) は常に全幅。
22
+ */
23
+ peek?: boolean;
24
+ /**
25
+ * PC(@[960px]:)で同時に見せるカード数。SP は従来どおり1枚表示。
26
+ * 求人カード等、EC 商品以外の複数カードを横スクロールさせる用途に使う。
27
+ */
28
+ itemsPerView?: ContentCarouselItemsPerView;
29
+ /** カルーセル全体の aria-label(スクリーンリーダー向け説明) */
30
+ ariaLabel?: string;
31
+ }
32
+ /**
33
+ * コンテンツカルーセル — ReactNode スライド対応
34
+ *
35
+ * `ImageCarousel` と同じ CSS scroll-snap ベースの実装だが、`images: string[]` ではなく
36
+ * `slides: ReactNode[]` を受け取る。テキスト主体のプロモスライド(eyebrow / タイトル /
37
+ * 本文 / 価格 / バッジ、画像は任意)を DS が autoplay / 矢印 / ドット / スワイプ付きで
38
+ * 提供し、consumer 側の手組みカルーセル(→意匠ドリフト)を不要にする。
39
+ *
40
+ * 矢印・ドットの意匠は `ImageCarousel` と同一(同じ markup を流用)。
41
+ *
42
+ * - SP(狭幅): スワイプ操作 + ドットインジケーター、矢印は非表示
43
+ * - PC(@md: 以上): 左右矢印ボタン(ホバーで出現)、ドット非表示
44
+ *
45
+ * ### インポート
46
+ * ```tsx
47
+ * import { ContentCarousel } from '../../components/primitives/content-carousel'
48
+ * ```
49
+ *
50
+ * ### AI 向け使用ルール
51
+ *
52
+ * - スライド内容は DS コンポーネント(Badge, Button, PriceDisplay 等)と
53
+ * typo-* / セマンティックトークンで組む(生の色・影・角丸は禁止)
54
+ * - 画像だけのバナーは `ImageCarousel` を使う(こちらはテキスト主体向け)
55
+ * - 自動再生: `<ContentCarousel autoPlay={5000} />`
56
+ */
57
+ declare function ContentCarousel({ slides, showDots, showArrows, autoPlay, peek, itemsPerView, ariaLabel, className, ...props }: ContentCarouselProps): import("react/jsx-runtime").JSX.Element;
58
+ export { ContentCarousel };
@@ -0,0 +1,44 @@
1
+ import type { Matcher } from "react-day-picker";
2
+ export interface DatePickerProps {
3
+ /** 選択中の日付 */
4
+ value?: Date;
5
+ /** 日付が変わったときに呼ばれる。クリアされると `undefined` */
6
+ onChange?: (date?: Date) => void;
7
+ /** 未選択時の trigger 表示 */
8
+ placeholder?: string;
9
+ /** 選択可能な最小日(これより前を無効化) */
10
+ min?: Date;
11
+ /** 選択可能な最大日(これより後を無効化) */
12
+ max?: Date;
13
+ /** 個別に無効化する日(Calendar の disabled マッチャーをそのまま透過) */
14
+ disabledDates?: Matcher | Matcher[];
15
+ /** trigger を無効化する */
16
+ disabled?: boolean;
17
+ /**
18
+ * 選択済みの値を消すクリアボタン(×)を trigger 右端に出す。既定 false(後方互換)。
19
+ * `value` があり `disabled` でないときだけ描画し、押すと `onChange(undefined)` を呼ぶ。
20
+ * 未指定だと「カレンダーを開いて選択済みの日付を再クリック」しかクリア手段が無く、
21
+ * 画面から発見できないため、任意項目(null 許容)では true にする。
22
+ */
23
+ clearable?: boolean;
24
+ /** クリアボタンの aria-label。既定「日付をクリア」 */
25
+ clearLabel?: string;
26
+ /** trigger の id(FormField の htmlFor と接続) */
27
+ id?: string;
28
+ /**
29
+ * 追加クラス。**外側のラッパー要素**に付与する(クリアボタンを trigger の
30
+ * 兄弟として絶対配置するため、幅・レイアウト指定はラッパーが受け取る)。
31
+ */
32
+ className?: string;
33
+ }
34
+ declare function DatePicker({ value, onChange, placeholder, min, max, disabledDates, disabled, clearable, clearLabel, id, className, }: DatePickerProps): import("react/jsx-runtime").JSX.Element;
35
+ export interface DateTimePickerProps extends DatePickerProps {
36
+ /** 分の刻み(分 Select の選択肢間隔)。既定 5 分 */
37
+ minuteStep?: number;
38
+ /** 時 Select の aria-label。既定「時」 */
39
+ hourLabel?: string;
40
+ /** 分 Select の aria-label。既定「分」 */
41
+ minuteLabel?: string;
42
+ }
43
+ declare function DateTimePicker({ value, onChange, minuteStep, hourLabel, minuteLabel, clearLabel, disabled, className, ...dateProps }: DateTimePickerProps): import("react/jsx-runtime").JSX.Element;
44
+ export { DatePicker, DateTimePicker };
@@ -1,41 +1,68 @@
1
1
  import * as React from "react";
2
+ export type NotFoundIllustrationProps = React.SVGProps<SVGSVGElement>;
3
+ /**
4
+ * NotFound(404)向けの抽象イラスト(ケーキモチーフ / スライスが欠けた図)。
5
+ *
6
+ * 色は CSS 変数と currentColor のみで構成(HEX 直書きなし)。輪郭は
7
+ * currentColor を継承するため、親の text-color で線色を調整できる。
8
+ * 既定は装飾(`aria-hidden`)。単体で意味を持たせる場合は `aria-label` を渡す。
9
+ *
10
+ * ```tsx
11
+ * <NotFoundIllustration className="w-40 text-[var(--Border-Medium-Emphasis)]" />
12
+ * ```
13
+ */
14
+ declare function NotFoundIllustration({ className, "aria-label": ariaLabel, ...props }: NotFoundIllustrationProps): import("react/jsx-runtime").JSX.Element;
15
+ /** ErrorState の種別。既定は汎用エラー、notFound は 404 向けの定番構成 */
16
+ export type ErrorStateKind = "error" | "notFound";
2
17
  export interface ErrorStateProps extends React.HTMLAttributes<HTMLDivElement> {
3
- /** エラーアイコン */
18
+ /**
19
+ * 状態の種別。
20
+ * - `"error"`(既定): 汎用エラー。`icon` を Object-Caution 色で表示(現行不変)
21
+ * - `"notFound"`: 404 向け。既定でケーキイラスト + 見つからない旨の文言
22
+ */
23
+ kind?: ErrorStateKind;
24
+ /** アイコン / イラスト。省略時、notFound は既定イラスト、error は非表示 */
4
25
  icon?: React.ReactNode;
5
- /** エラータイトル */
6
- title: string;
7
- /** エラーの説明テキスト */
26
+ /** タイトル。省略時は kind に応じた既定文言 */
27
+ title?: string;
28
+ /** 説明テキスト。省略時、notFound は既定文言、error は非表示 */
8
29
  description?: React.ReactNode;
9
30
  /** 再試行ボタンのクリックハンドラ。指定すると再試行ボタンを表示 */
10
31
  onRetry?: () => void;
11
32
  /** 再試行ボタンのラベル */
12
33
  retryLabel?: string;
13
- /** 追加アクション(例: 「ホームに戻る」ボタン) */
34
+ /** 追加アクション(例: 「トップへ戻る」ボタン) */
14
35
  action?: React.ReactNode;
15
36
  }
16
37
  /**
17
- * エラー状態コンポーネント
38
+ * エラー状態 / 404 状態コンポーネント
18
39
  *
19
- * APIエラー、ネットワークエラー、タイムアウト等のエラー状態を表示するUI。
20
- * EmptyState と同様のレイアウトだが、再試行アクションに特化。
40
+ * APIエラー・ネットワークエラー・タイムアウト等(`kind="error"`)と、
41
+ * 404 Not Found(`kind="notFound"`)の定番構成を1つのコンポーネントで扱う。
42
+ * EmptyState と同様の中央寄せレイアウト。
21
43
  *
22
44
  * ### AI 向け使用ルール
23
45
  *
24
- * - `icon` にエラー種別に合ったアイコン(size-16)を渡す
25
- * - `title` でエラー内容を簡潔に伝える
26
- * - `description` で対処方法を案内
27
- * - `onRetry` を渡すと再試行ボタンが表示される
28
- * - `action` に追加のナビゲーションボタンを渡せる
29
- * - ページコンテンツの中央に配置
46
+ * - システムエラーは `kind="error"`(既定)。`icon`(size-16)+ `onRetry` を渡す
47
+ * - 404 ページは `kind="notFound"`。イラスト・見出し・説明は既定で入るため
48
+ * 基本は `action`(「トップへ戻る」等の導線)だけ渡せばよい
49
+ * - データが無いだけ(カート空・検索0件)は EmptyState を使う
30
50
  *
31
51
  * ```tsx
52
+ * // 汎用エラー
32
53
  * <ErrorState
33
54
  * icon={<WifiOff className="size-16" />}
34
55
  * title="接続エラー"
35
56
  * description="ネットワークに接続できませんでした。"
36
57
  * onRetry={() => location.reload()}
37
58
  * />
59
+ *
60
+ * // 404
61
+ * <ErrorState
62
+ * kind="notFound"
63
+ * action={<Button size="lg">トップへ戻る</Button>}
64
+ * />
38
65
  * ```
39
66
  */
40
- declare function ErrorState({ className, icon, title, description, onRetry, retryLabel, action, ...props }: ErrorStateProps): import("react/jsx-runtime").JSX.Element;
41
- export { ErrorState };
67
+ declare function ErrorState({ className, kind, icon, title, description, onRetry, retryLabel, action, ...props }: ErrorStateProps): import("react/jsx-runtime").JSX.Element;
68
+ export { ErrorState, NotFoundIllustration };
@@ -44,6 +44,15 @@ export interface FunnelShellProps {
44
44
  bottomAction?: React.ReactNode;
45
45
  /** ルート要素の追加クラス */
46
46
  className?: string;
47
+ /**
48
+ * `<main>` の id(既定 "main-content")。内蔵の SkipLink の飛び先(`#${mainId}`)と対になる。
49
+ */
50
+ mainId?: string;
51
+ /**
52
+ * DOM 先頭に SkipLink(キーボードで本文へ飛ぶ a11y リンク)を標準内蔵する。
53
+ * `sr-only` なので視覚には影響しない。`false` で無効化。
54
+ */
55
+ skipLink?: false;
47
56
  }
48
57
  /**
49
58
  * FunnelShell — EC 購入導線等のファネル用集中モード(Full Page)のシェル。
@@ -77,9 +86,11 @@ export interface FunnelShellProps {
77
86
  * で表す。各ステップはドット(上)+ラベル(下)の縦積みで、コネクタ線はドット中心の
78
87
  * 高さで隣ステップ中心まで引く。ラベルは SP でも省略しない。
79
88
  * - `bottomAction` を渡すと本文の下余白はシェルが管理する(二重がけ/付け忘れの構造的防止)。
89
+ * - 地が Surface-Secondary なので、配下 `Card` の既定サーフェスを白にする文脈
90
+ * (`--card-surface`)をシェルが宣言する。`Card` は `surface` 未指定のまま地から浮く(#150)。
80
91
  *
81
92
  * 管理画面の集中編集は `WorkspaceShell`(EC 購入導線=本コンポーネント)。
82
93
  * 判断基準は contracts/screen-patterns.json(focused-workspace)を参照。
83
94
  */
84
- declare function FunnelShell({ logo, title, onBack, backLabel, steps, activeStep, children, bottomAction, className, }: FunnelShellProps): import("react/jsx-runtime").JSX.Element;
95
+ declare function FunnelShell({ logo, title, onBack, backLabel, steps, activeStep, children, bottomAction, className, mainId, skipLink, }: FunnelShellProps): import("react/jsx-runtime").JSX.Element;
85
96
  export { FunnelShell };
@@ -6,6 +6,12 @@ export interface HeaderAction {
6
6
  label: string;
7
7
  /** クリックハンドラ */
8
8
  onClick?: () => void;
9
+ /**
10
+ * リンク先。指定すると `<a>`(Button asChild)で描画し、
11
+ * 中クリック/Cmd+クリックでの新規タブ・リンクコピー・hoverプレビューが効くようになる。
12
+ * onClick と併用可(両方付与される)
13
+ */
14
+ href?: string;
9
15
  /** バッジ数(通知やカート件数) */
10
16
  badge?: React.ReactNode;
11
17
  }
@@ -46,6 +52,14 @@ export interface HeaderProps extends React.HTMLAttributes<HTMLElement> {
46
52
  * SP では非表示。本番の "ケーキ / スイーツ / ランキング…" メニューに対応。
47
53
  */
48
54
  navItems?: HeaderNavItem[];
55
+ /**
56
+ * PC(@[768px]+)のロゴ行で navItems と actions の間にインライン配置する検索スロット
57
+ * (variant="logo" のみ)。`SearchBar` 等を渡す。`flex-1 max-w-[400px]` で伸縮し、
58
+ * 既存のロゴ・ナビ・アクションを潰さない。SP 行には出さない
59
+ * (SP の常設検索は従来どおり `bottomSlot` で運用する)。
60
+ * navItems が無く searchSlot だけを渡した場合も PC 行を描画する。
61
+ */
62
+ searchSlot?: React.ReactNode;
49
63
  /** 右側に配置するカスタム要素(variant="back"で使用) */
50
64
  rightSlot?: React.ReactNode;
51
65
  /** 検索バーなど中央に配置するカスタム要素(variant="back-search"で使用) */
@@ -65,5 +79,5 @@ export interface HeaderProps extends React.HTMLAttributes<HTMLElement> {
65
79
  * アプリ全体で使われるヘッダーの3パターンを1コンポーネントで提供。
66
80
  * ロゴ+アクション、戻るボタン+タイトル、戻るボタン+検索の3バリエーション。
67
81
  */
68
- declare function Header({ className, variant, logo, title, onBack, backLabel, actions, navItems, rightSlot, centerSlot, bottomSlot, disableSticky, ...props }: HeaderProps): import("react/jsx-runtime").JSX.Element;
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;
69
83
  export { Header };
@@ -0,0 +1,119 @@
1
+ import { type VariantProps } from "class-variance-authority";
2
+ /** 選択されたファイルが受理されなかったときのコールバック引数。 */
3
+ export interface ImageInputValidationError {
4
+ /** `accept`: 形式不一致 / `max-size`: サイズ上限超過 */
5
+ code: "accept" | "max-size";
6
+ /** 受理されなかったファイル */
7
+ file: File;
8
+ /** 表示に使う日本語メッセージ */
9
+ message: string;
10
+ }
11
+ /**
12
+ * accept(例: "image/png,image/jpeg" / "image/*")に対して File の MIME を検査する。
13
+ * ネイティブの accept はファイル選択ダイアログの絞り込みでしかなく強制力がないため、
14
+ * 選択後に必ずここで検査する。accept が空なら全許可。
15
+ */
16
+ export declare function isAcceptedImageType(file: File, accept: string): boolean;
17
+ /**
18
+ * accept を日本語エラー文言用の形式名に整形する(例: "image/png,image/jpeg" → "PNG、JPEG")。
19
+ */
20
+ export declare function formatAcceptedFormats(accept: string): string;
21
+ /**
22
+ * 上限サイズ(MB)を表示用に整形する(1MB 未満は KB 表記)。
23
+ */
24
+ export declare function formatMaxSize(maxSizeMb: number): string;
25
+ /**
26
+ * プレビュー枠の寸法。
27
+ * 任意値 px は 4px グリッド上の値(156=4×39 / 380=4×95 / 568=4×142)で、
28
+ * 「画像入力の枠サイズ」という固有寸法のため spacing トークンの対象外。
29
+ * landscape は OGP 相当の 1200:630(≒1.9:1)。
30
+ */
31
+ declare const imageInputPreviewVariants: (props?: {
32
+ aspect?: "square" | "landscape";
33
+ size?: "sm" | "lg" | "md";
34
+ } & import("class-variance-authority/types").ClassProp) => string;
35
+ export interface ImageInputProps extends VariantProps<typeof imageInputPreviewVariants> {
36
+ /**
37
+ * 現在の値。`File`=新規に選択された画像 / `string`=保存済み画像の URL / `null`=未設定。
38
+ * 制御コンポーネントのため必ず渡す。
39
+ */
40
+ value: File | string | null;
41
+ /** 値の変更。クリア時は `null` が渡る。検証を通ったファイルだけが渡る。 */
42
+ onChange: (file: File | null) => void;
43
+ /** フォーカスが部品の外へ抜けたときに呼ぶ(React Hook Form の touched 連携用) */
44
+ onBlur?: () => void;
45
+ /** 内包する `<input type="file">` の id。Label / FormField の htmlFor と揃える。 */
46
+ id?: string;
47
+ /** input name(フォーム送信用) */
48
+ name?: string;
49
+ /** 受け付ける MIME/拡張子 */
50
+ accept?: string;
51
+ /** 1ファイルあたりの上限サイズ(MB)。超過ファイルは受理しない。 */
52
+ maxSizeMb?: number;
53
+ /** プレビューの表示方法 */
54
+ objectFit?: "cover" | "contain";
55
+ /** 無効化 */
56
+ disabled?: boolean;
57
+ /** クリアボタンを表示する。false で「画像を必ず1枚持つ」入力にできる。 */
58
+ clearable?: boolean;
59
+ /**
60
+ * 外部(React Hook Form 等)から与えるエラーメッセージ。
61
+ * 指定するとこちらが優先して表示される(内蔵検証のエラーより上位)。
62
+ */
63
+ error?: string;
64
+ /**
65
+ * 内蔵検証で弾かれたときのコールバック。
66
+ * 既定ではインラインの FieldError に日本語で表示されるため、
67
+ * Dialog / トーストで通知したい場合のみ使う。
68
+ */
69
+ onValidationError?: (error: ImageInputValidationError) => void;
70
+ /** プレビュー画像の alt */
71
+ alt?: string;
72
+ /** 未選択時にプレビュー枠へ表示する文言 */
73
+ placeholder?: string;
74
+ /** 「画像を選択」ボタンの文言 */
75
+ buttonLabel?: string;
76
+ /** 説明文などの id(内包 input の aria-describedby に連結する) */
77
+ "aria-describedby"?: string;
78
+ /** 追加クラス(ルート要素) */
79
+ className?: string;
80
+ }
81
+ /**
82
+ * ## ImageInput / 画像入力
83
+ *
84
+ * **1枚の画像**を選ぶフォーム部品。プレビュー + ファイル選択 + 形式/サイズ検証 + クリアを内包する。
85
+ * 値は `File | string | null`(`string` は保存済み画像の URL)で、そのままフォームの値として扱える。
86
+ *
87
+ * ### FileInput / ImageUploader との使い分け
88
+ * | 用途 | 使う部品 |
89
+ * |------|---------|
90
+ * | 画像 1 枚の入力(プレビュー付き・値をフォームに持つ) | **ImageInput**(primitives) |
91
+ * | 画像以外も含む汎用の添付(PDF / CSV 等・1行表示) | `FileInput`(foundations) |
92
+ * | 複数枚の画像を並べて管理するグリッド(追加・削除・並び順) | `ImageUploader`(primitives) |
93
+ *
94
+ * ### インポート
95
+ * ```tsx
96
+ * import { ImageInput } from "../../components/primitives/image-input"
97
+ * ```
98
+ *
99
+ * ### 表示サイズ
100
+ * `aspect`(square / landscape)× `size`(sm / md / lg)の組み合わせで指定する。
101
+ * 例: 正方形サムネイル=`aspect="square" size="sm"` / OGP 相当のバナー=`aspect="landscape" size="lg"`。
102
+ *
103
+ * ### エラー表示
104
+ * 形式・サイズの検証エラーは**インラインの `FieldError`**(`role="alert"`)に日本語で表示し、
105
+ * 内包 input に `aria-invalid` / `aria-describedby` を付けて紐付ける。
106
+ * モーダルで通知したい場合だけ `onValidationError` を使って consumer 側で出す。
107
+ *
108
+ * ### 非同期検証
109
+ * 画像の寸法チェック等の非同期検証は本部品には持たせていない。
110
+ * `onChange` を受けた consumer 側で検証し、結果を `error` prop で戻す。
111
+ *
112
+ * ### AI 向け使用ルール
113
+ * - `<input type="file">` + `<img>` で画像入力を手組みしない
114
+ * - `value` / `onChange` の制御コンポーネント。保存済み画像は URL 文字列をそのまま渡す
115
+ * - ラベル・必須バッジは `FormField` でラップし、`id` を `htmlFor` と揃える
116
+ * - プレビューの objectURL は内部で解放される。consumer 側で createObjectURL しない
117
+ */
118
+ declare function ImageInput({ value, onChange, onBlur, id, name, accept, maxSizeMb, aspect, size, objectFit, disabled, clearable, error, onValidationError, alt, placeholder, buttonLabel, className, "aria-describedby": ariaDescribedby, }: ImageInputProps): import("react/jsx-runtime").JSX.Element;
119
+ export { ImageInput, imageInputPreviewVariants };
@@ -1,5 +1,6 @@
1
1
  import * as React from "react";
2
2
  export type SectionHeaderSize = "3xl" | "2xl" | "xl" | "lg" | "md" | "sm";
3
+ export type SectionHeaderDesktopSize = "5xl" | "4xl";
3
4
  export interface SectionHeaderProps extends React.HTMLAttributes<HTMLDivElement> {
4
5
  /** セクションタイトル */
5
6
  title: string;
@@ -21,8 +22,13 @@ export interface SectionHeaderProps extends React.HTMLAttributes<HTMLDivElement>
21
22
  prevDisabled?: boolean;
22
23
  /** カルーセル用: 次へボタン無効化 */
23
24
  nextDisabled?: boolean;
24
- /** タイトルのサイズ(Figma 準拠: 3xl=28px / 2xl=24px / xl=21px / lg=18px / md=16px / sm=14px) */
25
+ /** SPを含む基本サイズ(3xl=通常ページの主見出し。2xl以下=セクション見出し) */
25
26
  size?: SectionHeaderSize;
27
+ /**
28
+ * LP・マーケティング系ヒーローのPCサイズ。
29
+ * `size="3xl" desktopSize="5xl"` のように指定し、通常ページでは使わない。
30
+ */
31
+ desktopSize?: SectionHeaderDesktopSize;
26
32
  /** 見出しのHTML要素を上書き(デフォルトは size に応じて h1〜h6 を自動選択) */
27
33
  as?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "p" | "span";
28
34
  /**
@@ -48,6 +54,7 @@ export interface SectionHeaderProps extends React.HTMLAttributes<HTMLDivElement>
48
54
  * ### AI 向け使用ルール
49
55
  *
50
56
  * - ページの主タイトル: `size="3xl"` or `size="2xl"`
57
+ * - LP・マーケティング系ヒーロー: `size="3xl" desktopSize="4xl"` または `desktopSize="5xl"`
51
58
  * - セクション見出し(ランキング等): `size="xl"` or `size="lg"`(デフォルト)
52
59
  * - 小見出し・グループラベル: `size="md"` or `size="sm"`
53
60
  * - `as` で見出しレベルを上書き可能(同一ページに h1 が複数必要な場合など)
@@ -55,5 +62,5 @@ export interface SectionHeaderProps extends React.HTMLAttributes<HTMLDivElement>
55
62
  * - `action` に任意の ReactNode(Button 等)を渡して右側にアクションを配置可能
56
63
  * - `align="center"` でランディング/ガイド系の中央寄せ大見出しに切替(`eyebrow` に Badge 等を載せられる)
57
64
  */
58
- declare function SectionHeader({ className, title, subtitle, moreHref, moreLabel, onMoreClick, action, onPrev, onNext, prevDisabled, nextDisabled, size, as, align, eyebrow, ...props }: SectionHeaderProps): import("react/jsx-runtime").JSX.Element;
65
+ declare function SectionHeader({ className, title, subtitle, moreHref, moreLabel, onMoreClick, action, onPrev, onNext, prevDisabled, nextDisabled, size, desktopSize, as, align, eyebrow, ...props }: SectionHeaderProps): import("react/jsx-runtime").JSX.Element;
59
66
  export { SectionHeader };
@@ -14,6 +14,14 @@ export interface SectionNavProps extends React.HTMLAttributes<HTMLElement> {
14
14
  items: SectionNavItem[];
15
15
  /** アクティブなセクションの key(利用側が scrollspy 等で制御。本体では監視しない) */
16
16
  activeKey?: string;
17
+ /**
18
+ * レイアウト方向(既定 "vertical")。
19
+ * - "vertical": 縦積みの目次(WorkspaceShell の左レール等)。従来の挙動。
20
+ * - "horizontal": 横並びの Tabs アンダーバー式(ガイド・FAQ 等の長い静的ページの
21
+ * ページ内ジャンプナビ)。横スクロール対応(overflow-x-auto)。sticky は内蔵しない
22
+ * (sticky/top オフセットは利用側が className で付与する)。
23
+ */
24
+ orientation?: "vertical" | "horizontal";
17
25
  /** aria-label */
18
26
  ariaLabel?: string;
19
27
  /** 項目クリック時のコールバック(任意) */
@@ -31,13 +39,14 @@ export interface SectionNavProps extends React.HTMLAttributes<HTMLElement> {
31
39
  * - 固有幅・背景・境界を持たない(`w-full`)。パネル化・幅決定はシェル/利用側の責務。
32
40
  * (SideNav の `w-64` 固定が WorkspaceShell で幅ミスマッチを起こした反省)
33
41
  * - IntersectionObserver は内包しない。`activeKey` を利用側が渡す。
42
+ * - sticky は内蔵しない。sticky/top オフセットは利用側が className で付与する。
34
43
  *
35
44
  * ### インポート
36
45
  * ```tsx
37
46
  * import { SectionNav } from '../../components/primitives/section-nav'
38
47
  * ```
39
48
  *
40
- * ### 使い方
49
+ * ### 使い方(vertical=既定)
41
50
  * ```tsx
42
51
  * <SectionNav
43
52
  * activeKey="basic"
@@ -48,13 +57,30 @@ export interface SectionNavProps extends React.HTMLAttributes<HTMLElement> {
48
57
  * />
49
58
  * ```
50
59
  *
60
+ * ### 使い方(horizontal=ページ内ジャンプの sticky アンダーバー)
61
+ * ガイド・FAQ のような長い静的ページ向け。sticky は利用側で付与する。
62
+ * ジャンプ先セクション側には `scroll-mt-*`(sticky ナビ高さ + α)を付けて、
63
+ * 見出しがナビの裏に隠れないようにする。
64
+ * ```tsx
65
+ * // ナビ: ヘッダー(h-14)直下に貼り付ける
66
+ * <SectionNav
67
+ * orientation="horizontal"
68
+ * activeKey={active}
69
+ * className="sticky top-14 z-30 border-b border-[var(--Border-Low-Emphasis)] bg-[var(--Surface-Primary)]"
70
+ * items={items}
71
+ * />
72
+ * // ターゲット: ナビ高さぶん上に余白を確保(scroll-mt-28 ≒ header 56px + nav 48px)
73
+ * <section id="basic" className="scroll-mt-28">…</section>
74
+ * ```
75
+ *
51
76
  * ### Props
52
77
  * | Prop | 型 | デフォルト | 説明 |
53
78
  * |------|-----|-----------|------|
54
79
  * | items | SectionNavItem[] | — | 目次項目(アンカー、必須) |
55
80
  * | activeKey | string | — | アクティブなセクションの key |
81
+ * | orientation | "vertical"\|"horizontal" | "vertical" | 縦積み目次 / 横アンダーバー |
56
82
  * | ariaLabel | string | "ページ内セクション" | aria-label |
57
83
  * | onItemClick | (key: string) => void | — | 項目クリック時のコールバック |
58
84
  */
59
- declare function SectionNav({ items, activeKey, ariaLabel, onItemClick, className, ...props }: SectionNavProps): import("react/jsx-runtime").JSX.Element;
85
+ declare function SectionNav({ items, activeKey, orientation, ariaLabel, onItemClick, className, ...props }: SectionNavProps): import("react/jsx-runtime").JSX.Element;
60
86
  export { SectionNav };
@@ -1,5 +1,12 @@
1
1
  import * as React from "react";
2
2
  import { type VariantProps } from "class-variance-authority";
3
+ export type SectionScrim = "none" | "dark" | "light" | "bottom-dark";
4
+ export interface SectionProps extends Omit<React.ComponentProps<"section">, "background">, VariantProps<typeof sectionVariants> {
5
+ /** 背景画像 URL。左右余白は引き続き内側の Container が所有する */
6
+ backgroundImage?: string;
7
+ /** 背景画像上の文字を読みやすくする DS 管理のオーバーレイ */
8
+ scrim?: SectionScrim;
9
+ }
3
10
  /**
4
11
  * Section — 全幅の縦リズム+(任意で)背景色付きの帯。
5
12
  *
@@ -8,6 +15,8 @@ import { type VariantProps } from "class-variance-authority";
8
15
  * 背景色は Section(全幅)が持ち、中央寄せは Container が持つ ── この分担により
9
16
  * 「背景帯は画面端まで、コンテンツは中央寄せ」が二重がけなしで成立する。
10
17
  * - 縦余白は SP/PC ペアで `--Space-Section-*` トークンを消費する(rem 直書きの撲滅)。
18
+ * - **色地の Section(`subtle` / `accent-subtle`)は配下 Card のサーフェス文脈を宣言する**
19
+ * (`--card-surface: var(--Surface-Primary)`)。詳細は下記。
11
20
  *
12
21
  * 推奨パターン:
13
22
  * ```tsx
@@ -17,10 +26,34 @@ import { type VariantProps } from "class-variance-authority";
17
26
  * </Container>
18
27
  * </Section>
19
28
  * ```
29
+ *
30
+ * ## 配下 Card へのサーフェス伝播(#150)
31
+ *
32
+ * `background="subtle"`(Surface-Tertiary)/ `"accent-subtle"` は色地なので、既定の
33
+ * `bg-card`(Surface-Secondary)のままでは Card が地に沈む。Section が
34
+ * `--card-surface: var(--Surface-Primary)` を配下に流すことで、**Section 配下の Card は
35
+ * `surface` 未指定でも白**になる(`Card surface="primary"` の明示指定は従来通り優先)。
36
+ *
37
+ * 「グレー地の上の Card は白」を**構造で**保証するのが狙いで、あとからカードを足しても
38
+ * prop の付け忘れが起きない。伝播は CSS カスタムプロパティのカスケードのみで、React context は
39
+ * 使わない(Server Component のまま使える/DS 外の要素は影響を受けない)。
40
+ *
41
+ * `background="none"` は文脈をリセットしない。色地 Section の内側に入れ子にした
42
+ * `background="none"` の Section は背景が透過して外側の色地が見えるため、
43
+ * 配下の Card も外側の文脈(白)を引き継ぐのが正しい。
44
+ *
45
+ * dark では伝播値を切り替えない(`Surface-Secondary` のまま)。dark の Surface-Secondary は
46
+ * 「地の上に重ねる半透明白」なので色地の上でも一段明るく浮き、そもそも沈まない。
47
+ * ここで `Surface-Primary`(ほぼ不透明の黒)を強制すると地より暗い「穴」になり
48
+ * elevation が反転する。※ `Card surface="primary"` の**明示指定**は light/dark とも
49
+ * Surface-Primary で固定(明示は明示のまま)。
20
50
  */
21
51
  declare const sectionVariants: (props?: {
22
52
  spacing?: "sm" | "lg" | "xl" | "md";
23
53
  background?: "none" | "accent-subtle" | "subtle";
24
54
  } & import("class-variance-authority/types").ClassProp) => string;
25
- declare function Section({ className, spacing, background, ...props }: React.ComponentProps<"section"> & VariantProps<typeof sectionVariants>): import("react/jsx-runtime").JSX.Element;
26
- export { Section, sectionVariants };
55
+ declare const sectionScrimVariants: (props?: {
56
+ scrim?: "none" | "light" | "dark" | "bottom-dark";
57
+ } & import("class-variance-authority/types").ClassProp) => string;
58
+ declare function Section({ className, spacing, background, backgroundImage, scrim, style, ...props }: SectionProps): import("react/jsx-runtime").JSX.Element;
59
+ export { Section, sectionVariants, sectionScrimVariants };
@@ -1,11 +1,17 @@
1
1
  import * as React from "react";
2
- export interface ShareButtonsProps extends React.HTMLAttributes<HTMLDivElement> {
2
+ export interface ShareButtonsProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "onCopy"> {
3
3
  /** シェアURL */
4
4
  url?: string;
5
5
  /** シェアテキスト */
6
6
  text?: string;
7
7
  /** コピーボタンのラベル */
8
8
  copyLabel?: string;
9
+ /** コピー成功時に一時表示するラベル(約2秒) */
10
+ copiedLabel?: string;
11
+ /** コピー失敗時に一時表示するラベル(約2秒) */
12
+ copyErrorLabel?: string;
13
+ /** コピー完了時のコールバック(成功/失敗) */
14
+ onCopy?: (result: "success" | "error") => void;
9
15
  }
10
16
  /**
11
17
  * シェアボタンコンポーネント
@@ -19,5 +25,5 @@ export interface ShareButtonsProps extends React.HTMLAttributes<HTMLDivElement>
19
25
  * - `url` と `text` でシェア内容を指定
20
26
  * - ボタンは横並び、等幅表示
21
27
  */
22
- declare function ShareButtons({ className, url, text, copyLabel, ...props }: ShareButtonsProps): import("react/jsx-runtime").JSX.Element;
28
+ declare function ShareButtons({ className, url, text, copyLabel, copiedLabel, copyErrorLabel, onCopy, ...props }: ShareButtonsProps): import("react/jsx-runtime").JSX.Element;
23
29
  export { ShareButtons };
@@ -21,6 +21,16 @@ export interface StandardPageShellProps {
21
21
  children: React.ReactNode;
22
22
  /** ルート要素の追加クラス。 */
23
23
  className?: string;
24
+ /**
25
+ * `<main>` の id(既定 "main-content")。内蔵の SkipLink の飛び先(`#${mainId}`)と対になる。
26
+ * スキップ先アンカーを別 id にしたい場合に変更する。
27
+ */
28
+ mainId?: string;
29
+ /**
30
+ * DOM 先頭に SkipLink(キーボードで本文へ飛ぶ a11y リンク)を標準内蔵する。
31
+ * `sr-only` なので視覚には影響しない。`false` で無効化。
32
+ */
33
+ skipLink?: false;
24
34
  }
25
35
  /**
26
36
  * StandardPageShell — 消費者向け標準ページ(standard-page-view / standard-page-edit)の骨格。
@@ -47,5 +57,5 @@ export interface StandardPageShellProps {
47
57
  *
48
58
  * 判断基準は contracts/composition.json(pageSkeletons)/ contracts/screen-patterns.json を参照。
49
59
  */
50
- declare function StandardPageShell({ header, bottomTab, footer, children, className, }: StandardPageShellProps): import("react/jsx-runtime").JSX.Element;
60
+ declare function StandardPageShell({ header, bottomTab, footer, children, className, mainId, skipLink, }: StandardPageShellProps): import("react/jsx-runtime").JSX.Element;
51
61
  export { StandardPageShell };
@@ -0,0 +1,23 @@
1
+ import * as React from "react";
2
+ export interface TimelineItem {
3
+ /** 省略時は1始まりの連番を表示。IconBadge 等の ReactNode も渡せる */
4
+ marker?: React.ReactNode;
5
+ /** 各項目の見出し */
6
+ title: React.ReactNode;
7
+ /** Card・本文・メタ情報等の任意コンテンツ */
8
+ children?: React.ReactNode;
9
+ }
10
+ export interface TimelineProps extends Omit<React.ComponentProps<"ol">, "children"> {
11
+ items: TimelineItem[];
12
+ /** タイムライン全体の日本語ラベル */
13
+ ariaLabel?: string;
14
+ }
15
+ /**
16
+ * 本文付きの縦タイムライン。
17
+ *
18
+ * 応募フロー・オンボーディング手順・注文/配送履歴のように、各段階へ本文を
19
+ * ぶら下げる用途で使う。現在位置を示す横型の `ProgressSteps` とは役割が異なる。
20
+ * コネクター線は DS が所有するため consumer 側で `::before` を手組みしない。
21
+ */
22
+ declare function Timeline({ items, ariaLabel, className, ...props }: TimelineProps): import("react/jsx-runtime").JSX.Element;
23
+ export { Timeline };
@@ -32,6 +32,24 @@ export interface WorkspaceShellProps {
32
32
  children: React.ReactNode;
33
33
  /** ルート要素の追加クラス */
34
34
  className?: string;
35
+ /**
36
+ * 編集本体 `<main>` の id(既定 "main-content")。内蔵の SkipLink の飛び先(`#${mainId}`)と対になる。
37
+ */
38
+ mainId?: string;
39
+ /**
40
+ * DOM 先頭に SkipLink(キーボードで本文へ飛ぶ a11y リンク)を標準内蔵する。
41
+ * `sr-only` なので視覚には影響しない。`false` で無効化。
42
+ */
43
+ skipLink?: false;
44
+ /**
45
+ * 編集ヘッダーのレイアウト(既定 "start"、現行と同じ挙動)。
46
+ * "center" にすると左=戻る導線/中央=タイトル/右=primaryAction の
47
+ * 3 カラム grid(`grid-cols-[minmax(0,1fr)_auto_minmax(0,1fr)]`)に固定し、
48
+ * primaryAction の有無・幅に関わらずタイトルを真の中央に揃える。
49
+ * consumer が `[&>[data-slot=header]]:!grid ...` のようなセレクタ上書きで
50
+ * 実現していた構成を公開 API として公式化したもの(#112)。
51
+ */
52
+ headerLayout?: "start" | "center";
35
53
  }
36
54
  /**
37
55
  * WorkspaceShell — Focused Workspace(全画面集中編集)のシェル。
@@ -44,9 +62,11 @@ export interface WorkspaceShellProps {
44
62
  * 右上=`primaryAction`(ワークスペース全体の上位アクションがある場合のみ)。
45
63
  * - `sectionNav` は編集内ナビのみ。グロナビは置かない。
46
64
  * - `sectionNav` は Surface-Secondary から浮いた独立パネルとして、シェル側で角丸パネルにラップされる。
65
+ * - 地が Surface-Secondary なので、配下 `Card` の既定サーフェスを白にする文脈
66
+ * (`--card-surface`)をシェルが宣言する。`Card` は `surface` 未指定のまま地から浮く(#150)。
47
67
  * - 標準的な編集は `AdminShell`(Standard Page(Edit)/旧 Form Page)。複雑・集中編集・没入執筆のみ本コンポーネント。
48
68
  *
49
69
  * 判断基準は contracts/screen-patterns.json / guidelines/foundations/screen-patterns.md を参照。
50
70
  */
51
- declare function WorkspaceShell({ title, onBack, backLabel, primaryAction, sectionNav, asidePanel, children, className, }: WorkspaceShellProps): import("react/jsx-runtime").JSX.Element;
71
+ declare function WorkspaceShell({ title, onBack, backLabel, primaryAction, sectionNav, asidePanel, children, className, mainId, skipLink, headerLayout, }: WorkspaceShellProps): import("react/jsx-runtime").JSX.Element;
52
72
  export { WorkspaceShell };