@cakejp/design-system 0.20.1 → 0.21.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 (161) hide show
  1. package/CHANGELOG.md +172 -0
  2. package/CLAUDE.md +5 -3
  3. package/MIGRATION.md +3 -3
  4. package/README.md +31 -11
  5. package/contracts/components.json +420 -63
  6. package/contracts/composition.json +38 -4
  7. package/contracts/rules.json +27 -5
  8. package/contracts/screen-patterns.json +6 -4
  9. package/dist/components/ec/admin-shell.js +62 -60
  10. package/dist/components/ec/anniversary-card.js +13 -12
  11. package/dist/components/ec/coupon-card.js +11 -11
  12. package/dist/components/ec/delivery-calendar.js +51 -45
  13. package/dist/components/ec/mypage-shell.js +80 -69
  14. package/dist/components/ec/product-card.js +93 -76
  15. package/dist/components/ec/product-carousel.js +65 -60
  16. package/dist/components/ec/product-detail-bar.js +13 -11
  17. package/dist/components/ec/product-detail-sidebar.js +60 -58
  18. package/dist/components/ec/product-list-item.js +64 -63
  19. package/dist/components/ec/product-option.js +30 -26
  20. package/dist/components/ec/rating-stars.js +27 -27
  21. package/dist/components/ec/review-card.js +32 -32
  22. package/dist/components/ec/review-form.js +37 -37
  23. package/dist/components/ec/shop-card.js +21 -19
  24. package/dist/components/foundations/accordion.js +33 -31
  25. package/dist/components/foundations/alert-dialog.js +4 -5
  26. package/dist/components/foundations/badge.js +5 -5
  27. package/dist/components/foundations/breadcrumb.js +27 -26
  28. package/dist/components/foundations/button.js +144 -25
  29. package/dist/components/foundations/calendar.js +28 -26
  30. package/dist/components/foundations/checkbox-card.js +71 -47
  31. package/dist/components/foundations/checkbox-group.js +30 -27
  32. package/dist/components/foundations/checkbox.js +69 -52
  33. package/dist/components/foundations/chip-variants.js +13 -0
  34. package/dist/components/foundations/command.js +81 -79
  35. package/dist/components/foundations/confirm-dialog.js +136 -0
  36. package/dist/components/foundations/context-menu.js +43 -38
  37. package/dist/components/foundations/data-table.js +87 -84
  38. package/dist/components/foundations/dialog.js +45 -36
  39. package/dist/components/foundations/dropdown-menu.js +47 -42
  40. package/dist/components/foundations/file-input.js +97 -67
  41. package/dist/components/foundations/hover-card.js +21 -21
  42. package/dist/components/foundations/menubar.js +75 -69
  43. package/dist/components/foundations/navigation-menu.js +31 -26
  44. package/dist/components/foundations/pagination.js +54 -50
  45. package/dist/components/foundations/popover.js +7 -7
  46. package/dist/components/foundations/progress.js +10 -6
  47. package/dist/components/foundations/radio-group.js +6 -3
  48. package/dist/components/foundations/responsive-dialog.js +73 -55
  49. package/dist/components/foundations/scroll-area.js +18 -14
  50. package/dist/components/foundations/select.js +44 -39
  51. package/dist/components/foundations/sheet.js +45 -37
  52. package/dist/components/foundations/skeleton.js +6 -6
  53. package/dist/components/foundations/skip-link.js +10 -8
  54. package/dist/components/foundations/slider.js +73 -48
  55. package/dist/components/foundations/sonner.js +5 -4
  56. package/dist/components/foundations/spinner.js +7 -5
  57. package/dist/components/foundations/switch.js +11 -10
  58. package/dist/components/foundations/tabs.js +54 -39
  59. package/dist/components/foundations/toggle-group.js +29 -21
  60. package/dist/components/foundations/toggle.js +20 -16
  61. package/dist/components/primitives/admin-side-nav.js +65 -62
  62. package/dist/components/primitives/banner-carousel.js +32 -29
  63. package/dist/components/primitives/bottom-tab-bar.js +16 -15
  64. package/dist/components/primitives/category-scroll.js +39 -29
  65. package/dist/components/primitives/category-shortcuts.js +9 -9
  66. package/dist/components/primitives/chat-composer.js +77 -74
  67. package/dist/components/primitives/chip.js +84 -61
  68. package/dist/components/primitives/combobox.js +63 -47
  69. package/dist/components/primitives/container.js +9 -9
  70. package/dist/components/primitives/content-card.js +15 -17
  71. package/dist/components/primitives/content-carousel.js +79 -68
  72. package/dist/components/primitives/date-picker.js +137 -99
  73. package/dist/components/primitives/footer.js +36 -37
  74. package/dist/components/primitives/header.js +175 -168
  75. package/dist/components/primitives/image-carousel.js +107 -87
  76. package/dist/components/primitives/image-gallery.js +32 -27
  77. package/dist/components/primitives/image-uploader.js +6 -6
  78. package/dist/components/primitives/list-item.js +59 -51
  79. package/dist/components/primitives/menu-drawer.js +36 -38
  80. package/dist/components/primitives/multi-select.js +89 -58
  81. package/dist/components/primitives/notification-list.js +10 -9
  82. package/dist/components/primitives/number-input.js +116 -105
  83. package/dist/components/primitives/scroll-row.js +21 -0
  84. package/dist/components/primitives/search-bar.js +31 -28
  85. package/dist/components/primitives/section-header.js +54 -53
  86. package/dist/components/primitives/side-nav.js +57 -56
  87. package/dist/components/primitives/sub-nav.js +13 -14
  88. package/dist/components/primitives/tag.js +4 -2
  89. package/dist/index.css +1 -1
  90. package/dist/index.js +3051 -924
  91. package/dist/lib/field-labelling.js +31 -21
  92. package/dist/lib/focus-ring.js +22 -4
  93. package/dist/lib/high-contrast.js +4 -0
  94. package/dist/lib/image-index.js +8 -0
  95. package/dist/lib/use-prefers-reduced-motion.js +21 -0
  96. package/dist/types/components/ec/admin-shell.d.ts +11 -1
  97. package/dist/types/components/ec/anniversary-card.d.ts +9 -1
  98. package/dist/types/components/ec/mypage-shell.d.ts +12 -1
  99. package/dist/types/components/ec/product-card.d.ts +13 -1
  100. package/dist/types/components/ec/product-carousel.d.ts +13 -1
  101. package/dist/types/components/ec/product-detail-bar.d.ts +12 -1
  102. package/dist/types/components/ec/product-detail-sidebar.d.ts +11 -1
  103. package/dist/types/components/ec/product-list-item.d.ts +9 -1
  104. package/dist/types/components/ec/rating-stars.d.ts +2 -0
  105. package/dist/types/components/ec/review-card.d.ts +1 -1
  106. package/dist/types/components/ec/shop-card.d.ts +8 -1
  107. package/dist/types/components/foundations/badge.d.ts +1 -1
  108. package/dist/types/components/foundations/breadcrumb.d.ts +8 -1
  109. package/dist/types/components/foundations/button.d.ts +38 -3
  110. package/dist/types/components/foundations/checkbox-card.d.ts +7 -1
  111. package/dist/types/components/foundations/checkbox.d.ts +1 -1
  112. package/dist/types/components/foundations/chip-variants.d.ts +2 -2
  113. package/dist/types/components/foundations/confirm-dialog.d.ts +61 -0
  114. package/dist/types/components/foundations/data-table.d.ts +9 -2
  115. package/dist/types/components/foundations/dialog.d.ts +16 -1
  116. package/dist/types/components/foundations/pagination.d.ts +1 -1
  117. package/dist/types/components/foundations/responsive-dialog.d.ts +2 -1
  118. package/dist/types/components/foundations/sheet.d.ts +12 -1
  119. package/dist/types/components/foundations/skeleton.d.ts +6 -0
  120. package/dist/types/components/foundations/slider.d.ts +15 -1
  121. package/dist/types/components/foundations/tabs.d.ts +7 -0
  122. package/dist/types/components/primitives/admin-side-nav.d.ts +22 -2
  123. package/dist/types/components/primitives/banner-carousel.d.ts +9 -1
  124. package/dist/types/components/primitives/bottom-tab-bar.d.ts +13 -2
  125. package/dist/types/components/primitives/category-scroll.d.ts +10 -1
  126. package/dist/types/components/primitives/category-shortcuts.d.ts +11 -2
  127. package/dist/types/components/primitives/chip.d.ts +22 -3
  128. package/dist/types/components/primitives/combobox.d.ts +7 -2
  129. package/dist/types/components/primitives/container.d.ts +3 -0
  130. package/dist/types/components/primitives/content-card.d.ts +1 -1
  131. package/dist/types/components/primitives/content-carousel.d.ts +12 -4
  132. package/dist/types/components/primitives/date-picker.d.ts +10 -3
  133. package/dist/types/components/primitives/footer.d.ts +1 -1
  134. package/dist/types/components/primitives/header.d.ts +14 -2
  135. package/dist/types/components/primitives/image-carousel.d.ts +23 -5
  136. package/dist/types/components/primitives/list-item.d.ts +10 -1
  137. package/dist/types/components/primitives/menu-drawer.d.ts +1 -1
  138. package/dist/types/components/primitives/multi-select.d.ts +7 -2
  139. package/dist/types/components/primitives/notification-list.d.ts +10 -1
  140. package/dist/types/components/primitives/number-input.d.ts +18 -5
  141. package/dist/types/components/primitives/scroll-row.d.ts +43 -0
  142. package/dist/types/components/primitives/section-header.d.ts +9 -2
  143. package/dist/types/components/primitives/side-nav.d.ts +13 -1
  144. package/dist/types/components/primitives/sub-nav.d.ts +1 -1
  145. package/dist/types/components/primitives/tag.d.ts +1 -1
  146. package/dist/types/index.d.ts +7 -1
  147. package/dist/types/lib/field-labelling.d.ts +23 -8
  148. package/dist/types/lib/focus-ring.d.ts +70 -3
  149. package/dist/types/lib/high-contrast.d.ts +25 -0
  150. package/dist/types/lib/image-index.d.ts +2 -0
  151. package/dist/types/lib/link-component.d.ts +26 -21
  152. package/dist/types/lib/use-prefers-reduced-motion.d.ts +9 -0
  153. package/package.json +11 -3
  154. package/src/components/COMPONENT_LOOKUP.md +18 -16
  155. package/src/preset-standalone.css +42 -0
  156. package/src/preset.css +20 -1
  157. package/src/styles/semantic.css +57 -0
  158. package/templates/AGENTS.md +5 -1
  159. package/templates/CLAUDE.md +3 -1
  160. package/tokens.json +49 -0
  161. package/dist/lib/link-component.js +0 -6
@@ -1,39 +1,42 @@
1
1
  "use client";
2
- import { jsxs as r, jsx as a } from "react/jsx-runtime";
3
- import * as w from "react";
4
- import { ChevronsUpDown as N, Check as j } from "lucide-react";
5
- import { cn as h } from "../../lib/utils.js";
6
- import { Button as k } from "../foundations/button.js";
7
- import { Command as E, CommandInput as P, CommandList as O, CommandEmpty as S, CommandGroup as T, CommandItem as A } from "../foundations/command.js";
8
- import { Popover as F, PopoverTrigger as I, PopoverContent as B } from "../foundations/popover.js";
9
- import { useFieldLabelling as G, resolveFieldAria as H } from "../../lib/field-labelling.js";
10
- function K({
11
- options: s,
12
- value: l,
2
+ import { jsxs as r, jsx as e } from "react/jsx-runtime";
3
+ import * as N from "react";
4
+ import { ChevronsUpDown as w, Check as T } from "lucide-react";
5
+ import { cn as f } from "../../lib/utils.js";
6
+ import { Button as j } from "../foundations/button.js";
7
+ import { Command as E, CommandInput as O, CommandList as k, CommandEmpty as P, CommandGroup as S, CommandItem as A } from "../foundations/command.js";
8
+ import { Popover as H, PopoverTrigger as I, PopoverContent as B } from "../foundations/popover.js";
9
+ import { useFieldLabelling as F, resolveFieldAria as G } from "../../lib/field-labelling.js";
10
+ import { HIGH_CONTRAST_OUTLINE as L } from "../../lib/high-contrast.js";
11
+ function Q({
12
+ options: n,
13
+ value: i,
13
14
  onValueChange: u,
14
- placeholder: o = "選択してください",
15
- searchPlaceholder: f = "検索",
16
- emptyLabel: v = "候補がありません",
15
+ placeholder: t = "選択してください",
16
+ searchPlaceholder: h = "検索",
17
+ emptyLabel: C = "候補がありません",
17
18
  disabled: x,
18
19
  className: y,
19
20
  id: d,
20
- "aria-invalid": C,
21
- "aria-describedby": n,
22
- "aria-label": i,
23
- "aria-labelledby": t
21
+ "aria-invalid": s,
22
+ "aria-describedby": c,
23
+ "aria-label": l,
24
+ "aria-labelledby": o
24
25
  }) {
25
- const [m, c] = w.useState(!1), p = s.find((e) => e.value === l), b = G(), g = H(
26
+ const [m, p] = N.useState(!1), v = n.find((a) => a.value === i), b = F(), g = G(
26
27
  {
27
28
  id: d,
28
- "aria-label": i,
29
- "aria-labelledby": t,
30
- "aria-describedby": n
29
+ "aria-label": l,
30
+ "aria-labelledby": o,
31
+ "aria-describedby": c,
32
+ // 渡さないと、利用側の明示指定が FormField 由来の値(error の有無)で上書きされる
33
+ "aria-invalid": s
31
34
  },
32
35
  b
33
36
  );
34
- return /* @__PURE__ */ r(F, { open: m, onOpenChange: c, children: [
35
- /* @__PURE__ */ a(I, { asChild: !0, children: /* @__PURE__ */ r(
36
- k,
37
+ return /* @__PURE__ */ r(H, { open: m, onOpenChange: p, children: [
38
+ /* @__PURE__ */ e(I, { asChild: !0, children: /* @__PURE__ */ r(
39
+ j,
37
40
  {
38
41
  type: "button",
39
42
  variant: "tertiary",
@@ -41,49 +44,62 @@ function K({
41
44
  id: d,
42
45
  "aria-expanded": m,
43
46
  "aria-haspopup": "listbox",
44
- "aria-invalid": C,
45
- "aria-describedby": n,
46
- "aria-label": i ?? (!b && !i && !t ? o : void 0),
47
- "aria-labelledby": t,
47
+ "aria-invalid": s,
48
+ "aria-describedby": c,
49
+ "aria-label": l ?? (!b && !l && !o ? t : void 0),
50
+ "aria-labelledby": o,
48
51
  ...g,
49
52
  disabled: x,
50
- className: h("w-full justify-between bg-[var(--Surface-Primary)]", y),
53
+ className: f(
54
+ "w-full justify-between bg-[var(--Surface-Primary)]",
55
+ // 高コントラスト(prefers-contrast: more / data-contrast="more")のときだけ見える内側 1px の輪郭。
56
+ // トリガーは枠を持たず地もページ地と同色で、既定では境界が 3:1 に届かない(#301)
57
+ L,
58
+ // エラー時の赤枠。トリガーは Button tertiary(枠幅 0)なので border 色だけ変えても見えず、
59
+ // border を足すと 1px 広がる。内側リング(inset-ring)で描いて高さを変えない。
60
+ // inset-ring は ring(フォーカスリング)と別の box-shadow 層なので同時に表示される。
61
+ "aria-invalid:inset-ring-1 aria-invalid:inset-ring-[var(--Border-Caution)]",
62
+ // forced-colors(Windows ハイコントラスト)では box-shadow が消えるため、エラー時だけ輪郭線
63
+ // (outline。レイアウトに影響しない)で境界を出す。forced-colors 以外では効かない
64
+ "forced-colors:aria-invalid:outline-solid forced-colors:aria-invalid:outline-1 forced-colors:aria-invalid:-outline-offset-1 forced-colors:aria-invalid:outline-[CanvasText]",
65
+ y
66
+ ),
51
67
  children: [
52
- /* @__PURE__ */ a("span", { className: p ? "text-[var(--Text-High-Emphasis)]" : "text-[var(--Text-Low-Emphasis)]", children: p?.label ?? o }),
53
- /* @__PURE__ */ a(N, { "aria-hidden": "true", className: "text-[var(--Object-Medium-Emphasis)]" })
68
+ /* @__PURE__ */ e("span", { className: v ? "text-[var(--Text-High-Emphasis)]" : "text-[var(--Text-Low-Emphasis)]", children: v?.label ?? t }),
69
+ /* @__PURE__ */ e(w, { "aria-hidden": "true", className: "text-[var(--Object-Medium-Emphasis)]" })
54
70
  ]
55
71
  }
56
72
  ) }),
57
- /* @__PURE__ */ a(B, { align: "start", className: "w-[var(--radix-popover-trigger-width)] p-0", children: /* @__PURE__ */ r(E, { children: [
58
- /* @__PURE__ */ a(P, { placeholder: f }),
59
- /* @__PURE__ */ r(O, { children: [
60
- /* @__PURE__ */ a(S, { children: v }),
61
- /* @__PURE__ */ a(T, { children: s.map((e) => /* @__PURE__ */ r(
73
+ /* @__PURE__ */ e(B, { align: "start", className: "w-[var(--radix-popover-trigger-width)] p-0", children: /* @__PURE__ */ r(E, { children: [
74
+ /* @__PURE__ */ e(O, { placeholder: h }),
75
+ /* @__PURE__ */ r(k, { children: [
76
+ /* @__PURE__ */ e(P, { children: C }),
77
+ /* @__PURE__ */ e(S, { children: n.map((a) => /* @__PURE__ */ r(
62
78
  A,
63
79
  {
64
- value: [e.label, ...e.keywords ?? []].join(" "),
65
- disabled: e.disabled,
80
+ value: [a.label, ...a.keywords ?? []].join(" "),
81
+ disabled: a.disabled,
66
82
  onSelect: () => {
67
- u?.(e.value), c(!1);
83
+ u?.(a.value), p(!1);
68
84
  },
69
85
  children: [
70
- /* @__PURE__ */ a(
71
- j,
86
+ /* @__PURE__ */ e(
87
+ T,
72
88
  {
73
89
  "aria-hidden": "true",
74
- className: h(e.value === l ? "opacity-100" : "opacity-0")
90
+ className: f(a.value === i ? "opacity-100" : "opacity-0")
75
91
  }
76
92
  ),
77
- e.label,
78
- e.value === l && /* @__PURE__ */ a("span", { className: "sr-only", children: "選択済み" })
93
+ a.label,
94
+ a.value === i && /* @__PURE__ */ e("span", { className: "sr-only", children: "選択済み" })
79
95
  ]
80
96
  },
81
- e.value
97
+ a.value
82
98
  )) })
83
99
  ] })
84
100
  ] }) })
85
101
  ] });
86
102
  }
87
103
  export {
88
- K as Combobox
104
+ Q as Combobox
89
105
  };
@@ -16,11 +16,11 @@ const p = o("mx-auto w-full", {
16
16
  // 上限なし(全幅)
17
17
  },
18
18
  gutter: {
19
- default: "px-4 md:px-6",
19
+ default: "px-4 md:px-6 [--Container-Gutter:16px] md:[--Container-Gutter:24px]",
20
20
  // SP 16 / PC 24
21
- tight: "px-3 md:px-4",
21
+ tight: "px-3 md:px-4 [--Container-Gutter:12px] md:[--Container-Gutter:16px]",
22
22
  // SP 12 / PC 16
23
- none: "px-0"
23
+ none: "px-0 [--Container-Gutter:0px]"
24
24
  }
25
25
  },
26
26
  defaultVariants: {
@@ -28,9 +28,9 @@ const p = o("mx-auto w-full", {
28
28
  gutter: "default"
29
29
  }
30
30
  });
31
- function u({
32
- className: t,
33
- size: a,
31
+ function s({
32
+ className: a,
33
+ size: t,
34
34
  gutter: r,
35
35
  ...e
36
36
  }) {
@@ -38,13 +38,13 @@ function u({
38
38
  "div",
39
39
  {
40
40
  "data-slot": "container",
41
- "data-size": a ?? "page",
42
- className: i(p({ size: a, gutter: r }), t),
41
+ "data-size": t ?? "page",
42
+ className: i(p({ size: t, gutter: r }), a),
43
43
  ...e
44
44
  }
45
45
  );
46
46
  }
47
47
  export {
48
- u as Container,
48
+ s as Container,
49
49
  p as containerVariants
50
50
  };
@@ -1,23 +1,22 @@
1
1
  import { jsxs as l, jsx as t } from "react/jsx-runtime";
2
2
  import "react";
3
3
  import { cn as s } from "../../lib/utils.js";
4
- import { FOCUS_RING as v } from "../../lib/focus-ring.js";
5
- import { resolveLinkComponent as h } from "../../lib/link-component.js";
6
- import { Tag as u } from "./tag.js";
7
- const x = {
4
+ import { FOCUS_RING as f } from "../../lib/focus-ring.js";
5
+ import { Tag as h } from "./tag.js";
6
+ const v = {
8
7
  "16/10": "aspect-[16/10]",
9
8
  "16/9": "aspect-[16/9]",
10
9
  "1/1": "aspect-[1/1]"
11
- }, w = {
10
+ }, u = {
12
11
  vertical: "flex-col gap-2",
13
12
  horizontal: "flex-row items-start gap-3",
14
13
  list: "flex-row-reverse items-start gap-3"
15
- }, g = {
14
+ }, x = {
16
15
  vertical: "w-full",
17
16
  horizontal: "w-28 shrink-0",
18
17
  list: "w-24 shrink-0"
19
18
  };
20
- function k({
19
+ function E({
21
20
  className: a,
22
21
  title: e,
23
22
  href: c,
@@ -29,17 +28,16 @@ function k({
29
28
  linkComponent: m,
30
29
  ...p
31
30
  }) {
32
- const f = h(m);
33
31
  return /* @__PURE__ */ l(
34
- f,
32
+ m ?? "a",
35
33
  {
36
34
  "data-slot": "content-card",
37
35
  "data-orientation": o,
38
36
  href: c,
39
37
  className: s(
40
38
  "group flex rounded-lg bg-[var(--card-surface,var(--Surface-Primary))]",
41
- w[o],
42
- v,
39
+ u[o],
40
+ f,
43
41
  a
44
42
  ),
45
43
  ...p,
@@ -50,13 +48,13 @@ function k({
50
48
  "data-slot": "content-card-media",
51
49
  className: s(
52
50
  "relative overflow-hidden rounded-lg",
53
- x[d],
54
- g[o]
51
+ v[d],
52
+ x[o]
55
53
  ),
56
54
  children: [
57
55
  /* @__PURE__ */ t("div", { className: "h-full w-full transition-transform duration-[var(--Motion-Duration-Base)] ease-[var(--Motion-Easing-Standard)] group-hover:scale-[1.02]", children: i }),
58
56
  r && /* @__PURE__ */ t(
59
- u,
57
+ h,
60
58
  {
61
59
  variant: r.variant,
62
60
  className: "absolute bottom-2 left-2 max-w-[calc(100%-1rem)] overflow-hidden text-ellipsis",
@@ -88,7 +86,7 @@ function k({
88
86
  }
89
87
  );
90
88
  }
91
- function M({
89
+ function L({
92
90
  className: a,
93
91
  ...e
94
92
  }) {
@@ -106,6 +104,6 @@ function M({
106
104
  );
107
105
  }
108
106
  export {
109
- k as ContentCard,
110
- M as ContentList
107
+ E as ContentCard,
108
+ L as ContentList
111
109
  };
@@ -1,87 +1,97 @@
1
1
  "use client";
2
- import { jsxs as v, jsx as a, Fragment as z } from "react/jsx-runtime";
2
+ import { jsxs as w, jsx as a, Fragment as k } from "react/jsx-runtime";
3
3
  import * as s from "react";
4
- import F from "iconsax-reactjs/dist/esm/ArrowLeft2.js";
5
- import L from "iconsax-reactjs/dist/esm/ArrowRight2.js";
6
- import { cn as i } from "../../lib/utils.js";
7
- const k = {
4
+ import O from "iconsax-reactjs/dist/esm/ArrowLeft2.js";
5
+ import R from "iconsax-reactjs/dist/esm/ArrowRight2.js";
6
+ import { cn as u } from "../../lib/utils.js";
7
+ import { usePrefersReducedMotion as F } from "../../lib/use-prefers-reduced-motion.js";
8
+ const M = {
8
9
  1: "@[960px]:w-full",
9
10
  2: "@[960px]:w-[calc((100%-16px)/2)]",
10
11
  3: "@[960px]:w-[calc((100%-32px)/3)]",
11
12
  4: "@[960px]:w-[calc((100%-48px)/4)]"
12
13
  };
13
- function M({
14
- slides: c,
15
- showDots: b = !0,
16
- showArrows: y = !0,
17
- autoPlay: u = 0,
18
- peek: p = !1,
19
- itemsPerView: f = 1,
20
- ariaLabel: g = "コンテンツカルーセル",
21
- className: w,
22
- ...E
14
+ function q({
15
+ slides: p,
16
+ showDots: E = !0,
17
+ showArrows: C = !0,
18
+ autoPlay: f = 0,
19
+ peek: x = !1,
20
+ itemsPerView: v = 1,
21
+ ariaLabel: I = "コンテンツカルーセル",
22
+ className: N,
23
+ ...S
23
24
  }) {
24
- const d = s.useRef(null), [o, I] = s.useState(0), t = c.length;
25
+ const c = s.useRef(null), [n, z] = s.useState(0), i = F(), t = p.length;
25
26
  s.useEffect(() => {
26
- const r = d.current;
27
+ const r = c.current;
27
28
  if (!r) return;
28
29
  let e = 0;
29
- const n = () => {
30
+ const o = () => {
30
31
  cancelAnimationFrame(e), e = requestAnimationFrame(() => {
31
- const A = Array.from(
32
+ const h = Array.from(
32
33
  r.querySelectorAll("[data-slide]")
33
- );
34
- let m = 0, h = Number.POSITIVE_INFINITY;
35
- A.forEach((T, j) => {
36
- const x = Math.abs(T.offsetLeft - r.scrollLeft);
37
- x < h && (h = x, m = j);
38
- }), I(m);
34
+ ), L = h[0]?.offsetLeft ?? 0;
35
+ let b = 0, g = Number.POSITIVE_INFINITY;
36
+ h.forEach((T, j) => {
37
+ const y = Math.abs(T.offsetLeft - L - r.scrollLeft);
38
+ y < g && (g = y, b = j);
39
+ }), z(b);
39
40
  });
40
41
  };
41
- return n(), r.addEventListener("scroll", n, { passive: !0 }), () => {
42
- cancelAnimationFrame(e), r.removeEventListener("scroll", n);
42
+ o(), r.addEventListener("scroll", o, { passive: !0 });
43
+ const l = typeof ResizeObserver > "u" ? void 0 : new ResizeObserver(o);
44
+ return l?.observe(r), () => {
45
+ cancelAnimationFrame(e), r.removeEventListener("scroll", o), l?.disconnect();
43
46
  };
44
47
  }, [t]);
45
- function l(r) {
46
- const e = d.current;
47
- if (!e) return;
48
- const n = e.children[r];
49
- n && e.scrollTo({ left: n.offsetLeft, behavior: "smooth" });
50
- }
48
+ const d = s.useCallback(
49
+ (r) => {
50
+ const e = c.current;
51
+ if (!e) return;
52
+ const o = e.children[r], l = e.children[0];
53
+ o && l && e.scrollTo({
54
+ left: o.offsetLeft - l.offsetLeft,
55
+ behavior: i ? "auto" : "smooth"
56
+ });
57
+ },
58
+ [i]
59
+ ), m = s.useCallback(() => {
60
+ const r = c.current, e = r ? r.scrollLeft >= r.scrollWidth - r.clientWidth - 1 : !1;
61
+ d(n >= t - 1 || e ? 0 : n + 1);
62
+ }, [n, t, d]);
51
63
  s.useEffect(() => {
52
- if (u <= 0 || t <= 1) return;
53
- const r = setInterval(() => {
54
- l((o + 1) % t);
55
- }, u);
64
+ if (i || f <= 0 || t <= 1) return;
65
+ const r = setInterval(m, f);
56
66
  return () => clearInterval(r);
57
- }, [u, o, t]);
58
- function N() {
59
- l(o <= 0 ? t - 1 : o - 1);
60
- }
61
- function S() {
62
- l(o >= t - 1 ? 0 : o + 1);
67
+ }, [f, t, i, m]);
68
+ function A() {
69
+ d(n <= 0 ? t - 1 : n - 1);
63
70
  }
64
- return t === 0 ? null : /* @__PURE__ */ v(
71
+ return t === 0 ? null : /* @__PURE__ */ w(
65
72
  "div",
66
73
  {
67
74
  "data-slot": "content-carousel",
68
75
  role: "region",
69
76
  "aria-roledescription": "carousel",
70
- "aria-label": g,
71
- className: i("@container group/carousel relative", w),
72
- ...E,
77
+ "aria-label": I,
78
+ className: u("@container group/carousel relative", N),
79
+ ...S,
73
80
  children: [
74
81
  /* @__PURE__ */ a(
75
82
  "div",
76
83
  {
77
- ref: d,
78
- className: i(
79
- "flex snap-x snap-mandatory overflow-x-auto scroll-smooth scrollbar-none",
80
- p && "pl-4 @[960px]:pl-0",
81
- f > 1 && "@[960px]:gap-4"
84
+ ref: c,
85
+ className: u(
86
+ "flex snap-x snap-mandatory overflow-x-auto scroll-smooth motion-reduce:scroll-auto scrollbar-none",
87
+ // peek: 端の余白 = Container の gutter(外に置いたときは 16px)。Container の中では
88
+ // gutter 分だけ外へはみ出して画面端までスクロールさせる。scroll-padding も同じ幅にして、
89
+ // スナップ後も端の余白が消えないようにする。PC (@[960px]:) では peek しないので外す
90
+ x && "-mx-[var(--Container-Gutter,0px)] gap-3 px-[var(--Container-Gutter,16px)] scroll-px-[var(--Container-Gutter,16px)] @[960px]:mx-0 @[960px]:gap-0 @[960px]:px-0 @[960px]:scroll-px-0",
91
+ v > 1 && "@[960px]:gap-4"
82
92
  ),
83
93
  style: { scrollbarWidth: "none", msOverflowStyle: "none" },
84
- children: c.map((r, e) => /* @__PURE__ */ a(
94
+ children: p.map((r, e) => /* @__PURE__ */ a(
85
95
  "div",
86
96
  {
87
97
  "data-slide": !0,
@@ -89,10 +99,11 @@ function M({
89
99
  role: "group",
90
100
  "aria-roledescription": "スライド",
91
101
  "aria-label": `${e + 1} / ${t}`,
92
- className: i(
102
+ className: u(
93
103
  "shrink-0 snap-start",
94
- p ? "w-[calc(100%-48px)] pr-3 @[960px]:pr-0" : "w-full",
95
- k[f]
104
+ // peek: 端の余白 16px のとき、カード幅は導入前(全幅に置いた場合)と同じ「全幅 - 76px」
105
+ x ? "w-[calc(100%-44px)]" : "w-full",
106
+ M[v]
96
107
  ),
97
108
  children: r
98
109
  },
@@ -100,38 +111,38 @@ function M({
100
111
  ))
101
112
  }
102
113
  ),
103
- y && t > 1 && /* @__PURE__ */ v(z, { children: [
114
+ C && t > 1 && /* @__PURE__ */ w(k, { children: [
104
115
  /* @__PURE__ */ a(
105
116
  "button",
106
117
  {
107
118
  type: "button",
108
- onClick: N,
119
+ onClick: A,
109
120
  "aria-label": "前へ",
110
- className: "absolute left-2 top-1/2 z-10 hidden size-10 -translate-y-1/2 items-center justify-center rounded-full border border-[var(--Border-Medium-Emphasis)] bg-[var(--Surface-Secondary)] shadow-md transition-opacity hover:bg-[var(--Surface-Tertiary)] @md:flex @[960px]:opacity-0 @[960px]:group-hover/carousel:opacity-100",
111
- children: /* @__PURE__ */ a(F, { size: 20, className: "text-[var(--Object-High-Emphasis)]" })
121
+ className: "absolute left-2 top-1/2 z-10 hidden size-10 -translate-y-1/2 items-center justify-center rounded-full border border-[var(--Border-Control,var(--Border-Medium-Emphasis))] bg-[var(--Surface-Secondary)] shadow-md transition-opacity hover:bg-[var(--Surface-Tertiary)] @md:flex @[960px]:opacity-0 @[960px]:group-hover/carousel:opacity-100",
122
+ children: /* @__PURE__ */ a(O, { size: 20, className: "text-[var(--Object-High-Emphasis)]" })
112
123
  }
113
124
  ),
114
125
  /* @__PURE__ */ a(
115
126
  "button",
116
127
  {
117
128
  type: "button",
118
- onClick: S,
129
+ onClick: m,
119
130
  "aria-label": "次へ",
120
- className: "absolute right-2 top-1/2 z-10 hidden size-10 -translate-y-1/2 items-center justify-center rounded-full border border-[var(--Border-Medium-Emphasis)] bg-[var(--Surface-Secondary)] shadow-md transition-opacity hover:bg-[var(--Surface-Tertiary)] @md:flex @[960px]:opacity-0 @[960px]:group-hover/carousel:opacity-100",
121
- children: /* @__PURE__ */ a(L, { size: 20, className: "text-[var(--Object-High-Emphasis)]" })
131
+ className: "absolute right-2 top-1/2 z-10 hidden size-10 -translate-y-1/2 items-center justify-center rounded-full border border-[var(--Border-Control,var(--Border-Medium-Emphasis))] bg-[var(--Surface-Secondary)] shadow-md transition-opacity hover:bg-[var(--Surface-Tertiary)] @md:flex @[960px]:opacity-0 @[960px]:group-hover/carousel:opacity-100",
132
+ children: /* @__PURE__ */ a(R, { size: 20, className: "text-[var(--Object-High-Emphasis)]" })
122
133
  }
123
134
  )
124
135
  ] }),
125
- b && t > 1 && /* @__PURE__ */ a("div", { className: "mt-2 flex flex-wrap items-center justify-center gap-1.5 @[960px]:hidden", children: c.map((r, e) => /* @__PURE__ */ a(
136
+ E && t > 1 && /* @__PURE__ */ a("div", { className: "mt-2 flex flex-wrap items-center justify-center gap-1.5 @[960px]:hidden", children: p.map((r, e) => /* @__PURE__ */ a(
126
137
  "button",
127
138
  {
128
139
  type: "button",
129
- onClick: () => l(e),
140
+ onClick: () => d(e),
130
141
  "aria-label": `スライド ${e + 1}`,
131
- className: i(
142
+ className: u(
132
143
  // shrink-0 必須: 空要素なので min-content 幅が 0、既定の flex-shrink:1 だとドットが消える
133
144
  "size-2 shrink-0 rounded-full transition-colors",
134
- e === o ? "bg-[var(--Text-High-Emphasis)]" : "bg-[var(--Surface-Tertiary)]"
145
+ e === n ? "bg-[var(--Text-High-Emphasis)]" : "bg-[var(--Surface-Tertiary)]"
135
146
  )
136
147
  },
137
148
  e
@@ -141,5 +152,5 @@ function M({
141
152
  );
142
153
  }
143
154
  export {
144
- M as ContentCarousel
155
+ q as ContentCarousel
145
156
  };