@cakejp/design-system 0.16.0 → 0.17.1

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 (151) hide show
  1. package/CHANGELOG.md +58 -0
  2. package/CLAUDE.md +1 -0
  3. package/bin/init.js +29 -6
  4. package/contracts/components.json +42 -7
  5. package/contracts/composition.json +8 -2
  6. package/contracts/rules.json +5 -1
  7. package/contracts/screen-patterns.json +1 -1
  8. package/dist/components/ec/_mypage-menu-data.js +166 -0
  9. package/dist/components/ec/admin-shell.js +202 -0
  10. package/dist/components/ec/anniversary-card.js +63 -0
  11. package/dist/components/ec/cake-logo.js +38 -0
  12. package/dist/components/ec/chart-controls.js +91 -0
  13. package/dist/components/ec/countdown-timer.js +50 -0
  14. package/dist/components/ec/coupon-card.js +136 -0
  15. package/dist/components/ec/delivery-calendar.js +105 -0
  16. package/dist/components/ec/mypage-shell.js +98 -0
  17. package/dist/components/ec/order-section.js +53 -0
  18. package/dist/components/ec/order-summary.js +78 -0
  19. package/dist/components/ec/payment-method.js +81 -0
  20. package/dist/components/ec/product-card.js +235 -0
  21. package/dist/components/ec/product-carousel.js +106 -0
  22. package/dist/components/ec/product-cta.js +80 -0
  23. package/dist/components/ec/product-detail-bar.js +86 -0
  24. package/dist/components/ec/product-detail-sidebar.js +296 -0
  25. package/dist/components/ec/product-list-item.js +266 -0
  26. package/dist/components/ec/product-option.js +165 -0
  27. package/dist/components/ec/rating-stars.js +74 -0
  28. package/dist/components/ec/review-card.js +126 -0
  29. package/dist/components/ec/review-form.js +181 -0
  30. package/dist/components/ec/review-summary.js +95 -0
  31. package/dist/components/ec/shop-card.js +179 -0
  32. package/dist/components/ec/stat-card.js +50 -0
  33. package/dist/components/foundations/accordion.js +67 -0
  34. package/dist/components/foundations/alert-dialog.js +165 -0
  35. package/dist/components/foundations/alert.js +218 -0
  36. package/dist/components/foundations/aspect-ratio.js +10 -0
  37. package/dist/components/foundations/avatar.js +58 -0
  38. package/dist/components/foundations/badge.js +54 -0
  39. package/dist/components/foundations/breadcrumb.js +104 -0
  40. package/dist/components/foundations/button.js +99 -0
  41. package/dist/components/foundations/calendar.js +173 -0
  42. package/dist/components/foundations/card.js +109 -0
  43. package/dist/components/foundations/checkbox-card.js +111 -0
  44. package/dist/components/foundations/checkbox-group.js +92 -0
  45. package/dist/components/foundations/checkbox.js +90 -0
  46. package/dist/components/foundations/chip-variants.js +41 -0
  47. package/dist/components/foundations/collapsible.js +34 -0
  48. package/dist/components/foundations/command.js +171 -0
  49. package/dist/components/foundations/context-menu.js +225 -0
  50. package/dist/components/foundations/data-table.js +59 -0
  51. package/dist/components/foundations/dialog.js +148 -0
  52. package/dist/components/foundations/drawer.js +129 -0
  53. package/dist/components/foundations/dropdown-menu.js +232 -0
  54. package/dist/components/foundations/field.js +150 -0
  55. package/dist/components/foundations/file-input.js +116 -0
  56. package/dist/components/foundations/form.js +101 -0
  57. package/dist/components/foundations/hover-card.js +41 -0
  58. package/dist/components/foundations/icon-badge.js +41 -0
  59. package/dist/components/foundations/input.js +74 -0
  60. package/dist/components/foundations/label.js +29 -0
  61. package/dist/components/foundations/menubar.js +252 -0
  62. package/dist/components/foundations/navigation-menu.js +171 -0
  63. package/dist/components/foundations/pagination.js +120 -0
  64. package/dist/components/foundations/popover.js +45 -0
  65. package/dist/components/foundations/progress.js +34 -0
  66. package/dist/components/foundations/radio-group.js +134 -0
  67. package/dist/components/foundations/responsive-dialog.js +76 -0
  68. package/dist/components/foundations/scroll-area.js +62 -0
  69. package/dist/components/foundations/select.js +190 -0
  70. package/dist/components/foundations/separator.js +27 -0
  71. package/dist/components/foundations/sheet.js +130 -0
  72. package/dist/components/foundations/skeleton.js +15 -0
  73. package/dist/components/foundations/skip-link.js +27 -0
  74. package/dist/components/foundations/slider.js +81 -0
  75. package/dist/components/foundations/social-icon.js +36 -0
  76. package/dist/components/foundations/sonner.js +49 -0
  77. package/dist/components/foundations/spinner.js +28 -0
  78. package/dist/components/foundations/switch.js +54 -0
  79. package/dist/components/foundations/table.js +115 -0
  80. package/dist/components/foundations/tabs.js +102 -0
  81. package/dist/components/foundations/textarea.js +65 -0
  82. package/dist/components/foundations/toggle-group.js +107 -0
  83. package/dist/components/foundations/toggle.js +44 -0
  84. package/dist/components/foundations/tooltip.js +56 -0
  85. package/dist/components/primitives/admin-header.js +31 -0
  86. package/dist/components/primitives/admin-side-nav.js +135 -0
  87. package/dist/components/primitives/banner-carousel.js +97 -0
  88. package/dist/components/primitives/bottom-tab-bar.js +81 -0
  89. package/dist/components/primitives/bulk-action-bar.js +27 -0
  90. package/dist/components/primitives/category-scroll.js +110 -0
  91. package/dist/components/primitives/category-shortcuts.js +66 -0
  92. package/dist/components/primitives/chat-composer.js +141 -0
  93. package/dist/components/primitives/chip.js +123 -0
  94. package/dist/components/primitives/coach-mark.js +102 -0
  95. package/dist/components/primitives/combobox.js +88 -0
  96. package/dist/components/primitives/container.js +50 -0
  97. package/dist/components/primitives/content-carousel.js +144 -0
  98. package/dist/components/primitives/date-picker.js +175 -0
  99. package/dist/components/primitives/empty-state.js +32 -0
  100. package/dist/components/primitives/error-state.js +115 -0
  101. package/dist/components/primitives/filter-bar.js +144 -0
  102. package/dist/components/primitives/footer.js +247 -0
  103. package/dist/components/primitives/form-field.js +38 -0
  104. package/dist/components/primitives/funnel-shell.js +99 -0
  105. package/dist/components/primitives/header.js +257 -0
  106. package/dist/components/primitives/image-carousel.js +156 -0
  107. package/dist/components/primitives/image-gallery.js +177 -0
  108. package/dist/components/primitives/image-input.js +207 -0
  109. package/dist/components/primitives/image-uploader.js +69 -0
  110. package/dist/components/primitives/kebab-menu.js +40 -0
  111. package/dist/components/primitives/list-item.js +80 -0
  112. package/dist/components/primitives/menu-drawer.js +154 -0
  113. package/dist/components/primitives/multi-select.js +93 -0
  114. package/dist/components/primitives/notification-badge.js +61 -0
  115. package/dist/components/primitives/notification-list.js +72 -0
  116. package/dist/components/primitives/number-input.js +235 -0
  117. package/dist/components/primitives/price-display.js +101 -0
  118. package/dist/components/primitives/progress-steps.js +62 -0
  119. package/dist/components/primitives/search-bar.js +81 -0
  120. package/dist/components/primitives/search-panel.js +43 -0
  121. package/dist/components/primitives/section-header.js +148 -0
  122. package/dist/components/primitives/section-nav.js +85 -0
  123. package/dist/components/primitives/section.js +78 -0
  124. package/dist/components/primitives/share-buttons.js +102 -0
  125. package/dist/components/primitives/side-nav.js +98 -0
  126. package/dist/components/primitives/social-login-button.js +53 -0
  127. package/dist/components/primitives/standard-page-shell.js +34 -0
  128. package/dist/components/primitives/status-count-tabs.js +42 -0
  129. package/dist/components/primitives/sticky-action-bar.js +26 -0
  130. package/dist/components/primitives/sub-nav.js +67 -0
  131. package/dist/components/primitives/tag.js +57 -0
  132. package/dist/components/primitives/timeline.js +55 -0
  133. package/dist/components/primitives/workspace-shell.js +57 -0
  134. package/dist/index.css +1 -1
  135. package/dist/index.js +22961 -13130
  136. package/dist/lib/field-labelling.js +29 -0
  137. package/dist/lib/focus-ring.js +6 -0
  138. package/dist/lib/pagination-range.js +42 -0
  139. package/dist/lib/use-value-length.js +63 -0
  140. package/dist/lib/utils.js +33 -0
  141. package/dist/types/components/foundations/accordion.d.ts +8 -1
  142. package/dist/types/components/foundations/data-table.d.ts +6 -1
  143. package/dist/types/components/foundations/slider.d.ts +13 -1
  144. package/dist/types/components/primitives/admin-header.d.ts +10 -0
  145. package/dist/types/components/primitives/admin-side-nav.d.ts +18 -0
  146. package/dist/types/components/primitives/combobox.d.ts +9 -1
  147. package/dist/types/components/primitives/menu-drawer.d.ts +0 -16
  148. package/dist/types/components/primitives/multi-select.d.ts +9 -1
  149. package/dist/types/lib/field-labelling.d.ts +66 -0
  150. package/package.json +8 -4
  151. package/scripts/codemod/README.md +9 -0
@@ -0,0 +1,257 @@
1
+ import { jsx as r, jsxs as i } from "react/jsx-runtime";
2
+ import * as k from "react";
3
+ import H from "iconsax-reactjs/dist/esm/ArrowDown2.js";
4
+ import j from "iconsax-reactjs/dist/esm/ArrowLeft.js";
5
+ import { cn as d } from "../../lib/utils.js";
6
+ import { Button as z } from "../foundations/button.js";
7
+ import { DropdownMenu as M, DropdownMenuTrigger as L, DropdownMenuContent as P, DropdownMenuItem as T } from "../foundations/dropdown-menu.js";
8
+ function E(n) {
9
+ return d(
10
+ "px-3 py-1.5 typo-body-md rounded-md transition-colors whitespace-nowrap",
11
+ n ? "text-[var(--Text-High-Emphasis)] font-bold" : "text-[var(--Text-Medium-Emphasis)] hover:text-[var(--Text-High-Emphasis)] hover:bg-[var(--Surface-Secondary)]"
12
+ );
13
+ }
14
+ const D = 2;
15
+ function V({
16
+ items: n,
17
+ overflowLabel: u = "その他"
18
+ }) {
19
+ const t = k.useRef(null), C = k.useRef(null), [g, m] = k.useState(n.length);
20
+ k.useEffect(() => {
21
+ const e = t.current, h = C.current;
22
+ if (!e || !h) return;
23
+ const a = () => {
24
+ const b = Array.from(h.children), w = b.slice(0, n.length).map((s) => s.getBoundingClientRect().width), R = b[n.length]?.getBoundingClientRect().width ?? 0, o = e.clientWidth;
25
+ if (o === 0 || w.some((s) => s === 0)) {
26
+ m(n.length);
27
+ return;
28
+ }
29
+ if (w.reduce((s, p) => s + p, 0) + D * (n.length - 1) <= o) {
30
+ m(n.length);
31
+ return;
32
+ }
33
+ let f = R, N = 0;
34
+ for (let s = 0; s < n.length; s++) {
35
+ const p = f + w[s] + D;
36
+ if (p > o) break;
37
+ f = p, N = s + 1;
38
+ }
39
+ m(N);
40
+ };
41
+ a(), window.addEventListener("resize", a);
42
+ const v = typeof ResizeObserver < "u" ? new ResizeObserver(a) : null;
43
+ return v?.observe(e), v?.observe(h), () => {
44
+ window.removeEventListener("resize", a), v?.disconnect();
45
+ };
46
+ }, [n]);
47
+ const x = n.slice(0, g), c = n.slice(g);
48
+ return /* @__PURE__ */ i("div", { ref: t, className: "relative min-w-0 flex-1", children: [
49
+ /* @__PURE__ */ i(
50
+ "div",
51
+ {
52
+ ref: C,
53
+ "aria-hidden": "true",
54
+ className: "invisible pointer-events-none absolute top-0 left-0 flex w-max items-center gap-0.5",
55
+ children: [
56
+ n.map((e) => /* @__PURE__ */ r("span", { className: E(e.isActive), children: e.label }, e.label)),
57
+ /* @__PURE__ */ i("span", { className: d(E(!1), "inline-flex items-center gap-1"), children: [
58
+ u,
59
+ /* @__PURE__ */ r(H, { size: 16 })
60
+ ] })
61
+ ]
62
+ }
63
+ ),
64
+ /* @__PURE__ */ i("nav", { className: "flex items-center gap-0.5", children: [
65
+ x.map((e) => {
66
+ const h = e.href ? "a" : "button", a = e.href ? { href: e.href } : { type: "button", onClick: e.onClick };
67
+ return /* @__PURE__ */ r(
68
+ h,
69
+ {
70
+ className: E(e.isActive),
71
+ ...a,
72
+ children: e.label
73
+ },
74
+ e.label
75
+ );
76
+ }),
77
+ c.length > 0 && /* @__PURE__ */ i(M, { children: [
78
+ /* @__PURE__ */ i(
79
+ L,
80
+ {
81
+ className: d(
82
+ E(c.some((e) => e.isActive)),
83
+ "inline-flex items-center gap-1"
84
+ ),
85
+ children: [
86
+ u,
87
+ /* @__PURE__ */ r(H, { size: 16, "aria-hidden": "true" })
88
+ ]
89
+ }
90
+ ),
91
+ /* @__PURE__ */ r(P, { align: "end", children: c.map(
92
+ (e) => e.href ? /* @__PURE__ */ r(T, { asChild: !0, children: /* @__PURE__ */ r(
93
+ "a",
94
+ {
95
+ href: e.href,
96
+ onClick: e.onClick,
97
+ "aria-current": e.isActive ? "page" : void 0,
98
+ children: e.label
99
+ }
100
+ ) }, e.label) : /* @__PURE__ */ r(
101
+ T,
102
+ {
103
+ onSelect: () => e.onClick?.(),
104
+ children: e.label
105
+ },
106
+ e.label
107
+ )
108
+ ) })
109
+ ] })
110
+ ] })
111
+ ] });
112
+ }
113
+ function Z({
114
+ className: n,
115
+ variant: u = "logo",
116
+ logo: t,
117
+ title: C,
118
+ onBack: g,
119
+ backLabel: m = "戻る",
120
+ actions: x,
121
+ navItems: c,
122
+ navBreakpoint: e = "md",
123
+ navOverflowLabel: h,
124
+ searchSlot: a,
125
+ rightSlot: v,
126
+ centerSlot: b,
127
+ bottomSlot: w,
128
+ disableSticky: R = !1,
129
+ ...o
130
+ }) {
131
+ const y = R ? "" : "sticky top-0 z-[var(--Z-Nav)]", f = "border-b border-[var(--Border-Low-Emphasis)] bg-[var(--Surface-Primary)]", N = e === "lg" ? "@[1024px]:hidden" : "@[768px]:hidden", s = e === "lg" ? "hidden @[1024px]:flex" : "hidden @[768px]:flex";
132
+ if (u === "logo") {
133
+ const p = typeof t == "string" ? /* @__PURE__ */ r("span", { className: "typo-heading-lg text-[var(--Text-High-Emphasis)]", children: t }) : t ?? null, A = x && x.length > 0 && /* @__PURE__ */ r("div", { className: "flex shrink-0 items-center gap-1", children: x.map(
134
+ (l) => l.href ? /* @__PURE__ */ r(
135
+ z,
136
+ {
137
+ asChild: !0,
138
+ variant: "ghost",
139
+ size: "icon-sm",
140
+ "aria-label": l.label,
141
+ children: /* @__PURE__ */ r("a", { href: l.href, onClick: l.onClick, children: l.badge ? l.badge : l.icon })
142
+ },
143
+ l.label
144
+ ) : /* @__PURE__ */ r(
145
+ z,
146
+ {
147
+ variant: "ghost",
148
+ size: "icon-sm",
149
+ "aria-label": l.label,
150
+ onClick: l.onClick,
151
+ children: l.badge ? l.badge : l.icon
152
+ },
153
+ l.label
154
+ )
155
+ ) });
156
+ return /* @__PURE__ */ i(
157
+ "header",
158
+ {
159
+ "data-slot": "header",
160
+ className: d(y, f, "@container", n),
161
+ ...o,
162
+ children: [
163
+ /* @__PURE__ */ i("div", { className: d(
164
+ "flex items-center justify-between px-4 py-3",
165
+ (c || a) && N
166
+ ), children: [
167
+ p,
168
+ A
169
+ ] }),
170
+ (c || a) && /* @__PURE__ */ i("div", { className: d(s, "items-center justify-between gap-4 h-14 px-6"), children: [
171
+ /* @__PURE__ */ i("div", { className: "flex min-w-0 flex-1 items-center gap-6", children: [
172
+ /* @__PURE__ */ r("div", { className: "shrink-0", children: p }),
173
+ c && c.length > 0 && /* @__PURE__ */ r(
174
+ V,
175
+ {
176
+ items: c,
177
+ overflowLabel: h
178
+ }
179
+ )
180
+ ] }),
181
+ a && /* @__PURE__ */ r("div", { className: "min-w-0 flex-1 max-w-[400px]", children: a }),
182
+ A
183
+ ] }),
184
+ w
185
+ ]
186
+ }
187
+ );
188
+ }
189
+ return u === "logo-center" ? /* @__PURE__ */ r(
190
+ "header",
191
+ {
192
+ "data-slot": "header",
193
+ className: d(
194
+ y,
195
+ f,
196
+ "flex items-center justify-center px-4 py-3",
197
+ n
198
+ ),
199
+ ...o,
200
+ children: typeof t == "string" ? /* @__PURE__ */ r("span", { className: "typo-heading-lg text-[var(--Text-High-Emphasis)]", children: t }) : t ?? null
201
+ }
202
+ ) : u === "back-search" ? /* @__PURE__ */ r(
203
+ "header",
204
+ {
205
+ "data-slot": "header",
206
+ className: d(
207
+ y,
208
+ f,
209
+ "px-4 py-3",
210
+ n
211
+ ),
212
+ ...o,
213
+ children: /* @__PURE__ */ i("div", { className: "flex items-center gap-2", children: [
214
+ /* @__PURE__ */ r(
215
+ z,
216
+ {
217
+ variant: "ghost",
218
+ size: "icon-sm",
219
+ "aria-label": m,
220
+ onClick: g,
221
+ children: /* @__PURE__ */ r(j, { size: 20 })
222
+ }
223
+ ),
224
+ b && /* @__PURE__ */ r("div", { className: "flex-1", children: b })
225
+ ] })
226
+ }
227
+ ) : /* @__PURE__ */ i(
228
+ "header",
229
+ {
230
+ "data-slot": "header",
231
+ className: d(
232
+ y,
233
+ f,
234
+ "grid grid-cols-[1fr_auto_1fr] items-center gap-2 px-2 py-3",
235
+ n
236
+ ),
237
+ ...o,
238
+ children: [
239
+ /* @__PURE__ */ r("div", { className: "justify-self-start", children: /* @__PURE__ */ r(
240
+ z,
241
+ {
242
+ variant: "ghost",
243
+ size: "icon-sm",
244
+ "aria-label": m,
245
+ onClick: g,
246
+ children: /* @__PURE__ */ r(j, { size: 20 })
247
+ }
248
+ ) }),
249
+ /* @__PURE__ */ r("h1", { className: "min-w-0 truncate text-center typo-heading-md text-[var(--Text-High-Emphasis)]", children: C }),
250
+ /* @__PURE__ */ r("div", { className: "justify-self-end", children: v })
251
+ ]
252
+ }
253
+ );
254
+ }
255
+ export {
256
+ Z as Header
257
+ };
@@ -0,0 +1,156 @@
1
+ import { jsxs as y, jsx as t, Fragment as T } from "react/jsx-runtime";
2
+ import * as l from "react";
3
+ import k from "iconsax-reactjs/dist/esm/ArrowLeft2.js";
4
+ import C from "iconsax-reactjs/dist/esm/ArrowRight2.js";
5
+ import { cn as o } from "../../lib/utils.js";
6
+ function B({
7
+ images: c,
8
+ aspectRatio: i = "banner",
9
+ showDots: N = !0,
10
+ showArrows: w = !0,
11
+ autoPlay: d = 0,
12
+ peek: x = !1,
13
+ pcSlidesPerView: u = 1,
14
+ centeredSlides: h = !1,
15
+ className: j,
16
+ ...z
17
+ }) {
18
+ const p = l.useRef(null), [s, E] = l.useState(0), a = c.length, b = i === "square" ? "aspect-square" : i === "video" ? "aspect-video" : i === "ogp" ? "aspect-[1.91/1]" : "aspect-[311/162.5]";
19
+ l.useEffect(() => {
20
+ const r = p.current;
21
+ if (!r) return;
22
+ const e = new IntersectionObserver(
23
+ (m) => {
24
+ for (const v of m)
25
+ if (v.isIntersecting) {
26
+ const g = Number(
27
+ v.target.dataset.index
28
+ );
29
+ Number.isNaN(g) || E(g);
30
+ }
31
+ },
32
+ { root: r, threshold: 0.6 }
33
+ );
34
+ return r.querySelectorAll("[data-slide]").forEach((m) => e.observe(m)), () => e.disconnect();
35
+ }, [a]);
36
+ function n(r) {
37
+ const e = p.current;
38
+ if (!e) return;
39
+ const f = e.children[r];
40
+ f && e.scrollTo({ left: f.offsetLeft, behavior: "smooth" });
41
+ }
42
+ l.useEffect(() => {
43
+ if (d <= 0 || a <= 1) return;
44
+ const r = setInterval(() => {
45
+ n((s + 1) % a);
46
+ }, d);
47
+ return () => clearInterval(r);
48
+ }, [d, s, a]);
49
+ function I() {
50
+ n(s <= 0 ? a - 1 : s - 1);
51
+ }
52
+ function S() {
53
+ n(s >= a - 1 ? 0 : s + 1);
54
+ }
55
+ return a === 0 ? null : /* @__PURE__ */ y(
56
+ "div",
57
+ {
58
+ "data-slot": "image-carousel",
59
+ className: o("@container group/carousel relative", j),
60
+ ...z,
61
+ children: [
62
+ /* @__PURE__ */ t(
63
+ "div",
64
+ {
65
+ ref: p,
66
+ tabIndex: 0,
67
+ className: o(
68
+ "flex snap-x snap-mandatory overflow-x-auto scroll-smooth scrollbar-none",
69
+ "focus-visible:outline-none focus-visible:ring-[3px] focus-visible:ring-[var(--Focus-High-Emphasis)]/50",
70
+ x && "pl-4 @[960px]:pl-0",
71
+ // タブレット centeredSlides: コンテナに px-[22.25%] を付与し
72
+ // flex item の w-full が自動で ~426px になる(768px の 55.5%)
73
+ // @[768px]: と @[960px]: は数値指定で CSS 出力順が保証されるため
74
+ // 960px+ では @[960px]:px-0 が必ず上書きする
75
+ h && "@[768px]:px-[22.25%] @[960px]:px-0 @[768px]:gap-4",
76
+ // PC 複数枚表示時のスライド間ギャップ(本番 spaceBetween:24 準拠)
77
+ // cascade: @[960px]:gap-6 > @[768px]:gap-4 at 960px+
78
+ u > 1 && "@[960px]:gap-6"
79
+ ),
80
+ style: { scrollbarWidth: "none", msOverflowStyle: "none" },
81
+ children: c.map((r, e) => /* @__PURE__ */ t(
82
+ "div",
83
+ {
84
+ "data-slide": !0,
85
+ "data-index": e,
86
+ className: o(
87
+ "shrink-0 snap-start",
88
+ // centeredSlides: タブレットで snap-center、PC で snap-start に戻す
89
+ h && "@[768px]:snap-center @[960px]:snap-start",
90
+ x ? u > 1 ? "w-[calc(100%-48px)] pr-3 @[960px]:w-[calc((100%-48px)/3)] @[960px]:pr-0" : "w-[calc(100%-48px)] pr-3 @[960px]:w-full @[960px]:pr-0" : u > 1 ? "w-full @[960px]:w-[calc((100%-48px)/3)]" : "w-full"
91
+ ),
92
+ children: r.href ? /* @__PURE__ */ t("a", { href: r.href, className: "block", children: /* @__PURE__ */ t(
93
+ "img",
94
+ {
95
+ src: r.src,
96
+ alt: r.alt,
97
+ loading: e === 0 ? "eager" : "lazy",
98
+ className: o("w-full rounded-md object-cover @[960px]:rounded-lg", b)
99
+ }
100
+ ) }) : /* @__PURE__ */ t(
101
+ "img",
102
+ {
103
+ src: r.src,
104
+ alt: r.alt,
105
+ loading: e === 0 ? "eager" : "lazy",
106
+ className: o("w-full rounded-md object-cover @[960px]:rounded-lg", b)
107
+ }
108
+ )
109
+ },
110
+ e
111
+ ))
112
+ }
113
+ ),
114
+ w && a > 1 && /* @__PURE__ */ y(T, { children: [
115
+ /* @__PURE__ */ t(
116
+ "button",
117
+ {
118
+ type: "button",
119
+ onClick: I,
120
+ "aria-label": "前へ",
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-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__ */ t(k, { size: 20, className: "text-[var(--Object-High-Emphasis)]" })
123
+ }
124
+ ),
125
+ /* @__PURE__ */ t(
126
+ "button",
127
+ {
128
+ type: "button",
129
+ onClick: S,
130
+ "aria-label": "次へ",
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-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__ */ t(C, { size: 20, className: "text-[var(--Object-High-Emphasis)]" })
133
+ }
134
+ )
135
+ ] }),
136
+ N && a > 1 && /* @__PURE__ */ t("div", { className: "mt-2 flex flex-wrap items-center justify-center gap-1.5 @[960px]:hidden", children: c.map((r, e) => /* @__PURE__ */ t(
137
+ "button",
138
+ {
139
+ type: "button",
140
+ onClick: () => n(e),
141
+ "aria-label": `スライド ${e + 1}`,
142
+ className: o(
143
+ // shrink-0 必須: 空要素なので min-content 幅が 0、既定の flex-shrink:1 だとドットが消える
144
+ "size-2 shrink-0 rounded-full transition-colors",
145
+ e === s ? "bg-[var(--Text-High-Emphasis)]" : "bg-[var(--Surface-Tertiary)]"
146
+ )
147
+ },
148
+ e
149
+ )) })
150
+ ]
151
+ }
152
+ );
153
+ }
154
+ export {
155
+ B as ImageCarousel
156
+ };
@@ -0,0 +1,177 @@
1
+ import { jsxs as o, jsx as t, Fragment as b } from "react/jsx-runtime";
2
+ import * as x from "react";
3
+ import y from "iconsax-reactjs/dist/esm/ArrowLeft2.js";
4
+ import g from "iconsax-reactjs/dist/esm/ArrowRight2.js";
5
+ import { cn as n } from "../../lib/utils.js";
6
+ function P({
7
+ images: r,
8
+ alts: c,
9
+ aspectRatio: h = "square",
10
+ showThumbnails: f = !1,
11
+ showDots: m = !0,
12
+ layout: v = "default",
13
+ className: i,
14
+ ...d
15
+ }) {
16
+ const [a, p] = x.useState(0);
17
+ if (r.length === 0) return null;
18
+ const s = (l) => {
19
+ const e = (l % r.length + r.length) % r.length;
20
+ e !== a && p(e);
21
+ }, u = {
22
+ square: "aspect-square",
23
+ "4:3": "aspect-[4/3]",
24
+ "16:9": "aspect-video",
25
+ auto: ""
26
+ }[h];
27
+ return v === "pc-detail" ? /* @__PURE__ */ o(
28
+ "div",
29
+ {
30
+ "data-slot": "image-gallery",
31
+ className: n("flex flex-row-reverse gap-6", i),
32
+ ...d,
33
+ children: [
34
+ /* @__PURE__ */ o("div", { className: n("relative min-w-0 grow overflow-hidden rounded-lg", u), children: [
35
+ /* @__PURE__ */ t(
36
+ "div",
37
+ {
38
+ className: "flex h-full transition-transform duration-[var(--Motion-Duration-Slow)] ease-out",
39
+ style: { transform: `translateX(-${a * 100}%)` },
40
+ children: r.map((l, e) => /* @__PURE__ */ t(
41
+ "img",
42
+ {
43
+ src: l,
44
+ alt: c?.[e] ?? `画像 ${e + 1}`,
45
+ className: "h-full w-full shrink-0 object-contain"
46
+ },
47
+ e
48
+ ))
49
+ }
50
+ ),
51
+ r.length > 1 && /* @__PURE__ */ o("span", { className: "absolute bottom-2 right-2 rounded-full bg-[var(--Overlay-Medium)] px-2 py-0.5 typo-label-xs text-[var(--Text-on-Inverse)]", children: [
52
+ a + 1,
53
+ " / ",
54
+ r.length
55
+ ] })
56
+ ] }),
57
+ r.length > 1 && /* @__PURE__ */ t("div", { className: "flex w-16 shrink-0 flex-col gap-2 overflow-y-auto scrollbar-hide", children: r.map((l, e) => /* @__PURE__ */ t(
58
+ "button",
59
+ {
60
+ type: "button",
61
+ onClick: () => s(e),
62
+ onMouseOver: () => s(e),
63
+ className: n(
64
+ "size-16 shrink-0 overflow-hidden rounded-lg border-2 transition-colors",
65
+ e === a ? "border-[var(--Border-Accent-Primary)]" : "border-transparent opacity-60 hover:opacity-100"
66
+ ),
67
+ children: /* @__PURE__ */ t(
68
+ "img",
69
+ {
70
+ src: l,
71
+ alt: c?.[e] ?? `サムネイル ${e + 1}`,
72
+ className: "h-full w-full object-cover"
73
+ }
74
+ )
75
+ },
76
+ e
77
+ )) })
78
+ ]
79
+ }
80
+ ) : /* @__PURE__ */ o(
81
+ "div",
82
+ {
83
+ "data-slot": "image-gallery",
84
+ className: n("space-y-2", i),
85
+ ...d,
86
+ children: [
87
+ /* @__PURE__ */ o("div", { className: n("relative w-full overflow-hidden", u), children: [
88
+ /* @__PURE__ */ t(
89
+ "div",
90
+ {
91
+ className: "flex h-full transition-transform duration-[var(--Motion-Duration-Slow)] ease-out",
92
+ style: { transform: `translateX(-${a * 100}%)` },
93
+ children: r.map((l, e) => /* @__PURE__ */ t(
94
+ "img",
95
+ {
96
+ src: l,
97
+ alt: c?.[e] ?? `画像 ${e + 1}`,
98
+ className: "h-full w-full shrink-0 object-cover"
99
+ },
100
+ e
101
+ ))
102
+ }
103
+ ),
104
+ r.length > 1 && /* @__PURE__ */ o(b, { children: [
105
+ /* @__PURE__ */ t(
106
+ "button",
107
+ {
108
+ type: "button",
109
+ className: "absolute left-2 top-1/2 flex size-10 -translate-y-1/2 items-center justify-center rounded-full bg-[var(--Surface-Primary)]/80 shadow-sm transition-colors hover:bg-[var(--Surface-Primary)]",
110
+ onClick: () => s(a - 1),
111
+ "aria-label": "前の画像",
112
+ children: /* @__PURE__ */ t(y, { size: 20, className: "text-[var(--Text-High-Emphasis)]" })
113
+ }
114
+ ),
115
+ /* @__PURE__ */ t(
116
+ "button",
117
+ {
118
+ type: "button",
119
+ className: "absolute right-2 top-1/2 flex size-10 -translate-y-1/2 items-center justify-center rounded-full bg-[var(--Surface-Primary)]/80 shadow-sm transition-colors hover:bg-[var(--Surface-Primary)]",
120
+ onClick: () => s(a + 1),
121
+ "aria-label": "次の画像",
122
+ children: /* @__PURE__ */ t(g, { size: 20, className: "text-[var(--Text-High-Emphasis)]" })
123
+ }
124
+ )
125
+ ] }),
126
+ r.length > 1 && /* @__PURE__ */ o("span", { className: "absolute bottom-2 right-2 rounded-full bg-[var(--Overlay-Medium)] px-2 py-0.5 typo-label-xs text-[var(--Text-on-Inverse)]", children: [
127
+ a + 1,
128
+ " / ",
129
+ r.length
130
+ ] })
131
+ ] }),
132
+ m && r.length > 1 && /* @__PURE__ */ t("div", { className: "flex flex-wrap justify-center gap-0.5", children: r.map((l, e) => /* @__PURE__ */ t(
133
+ "button",
134
+ {
135
+ type: "button",
136
+ onClick: () => s(e),
137
+ className: "flex h-6 shrink-0 items-center justify-center px-0.5",
138
+ "aria-label": `画像 ${e + 1}`,
139
+ children: /* @__PURE__ */ t(
140
+ "span",
141
+ {
142
+ className: n(
143
+ "h-1.5 shrink-0 rounded-full transition-all",
144
+ e === a ? "w-4 bg-[var(--Brand-Cake-Orange)]" : "w-1.5 bg-[var(--Text-Low-Emphasis)]/30"
145
+ )
146
+ }
147
+ )
148
+ },
149
+ e
150
+ )) }),
151
+ f && r.length > 1 && /* @__PURE__ */ t("div", { className: "flex gap-1.5 overflow-x-auto scrollbar-hide", children: r.map((l, e) => /* @__PURE__ */ t(
152
+ "button",
153
+ {
154
+ type: "button",
155
+ onClick: () => s(e),
156
+ className: n(
157
+ "size-14 shrink-0 overflow-hidden rounded-md border-2 transition-colors",
158
+ e === a ? "border-[var(--Brand-Cake-Orange)]" : "border-transparent opacity-60 hover:opacity-100"
159
+ ),
160
+ children: /* @__PURE__ */ t(
161
+ "img",
162
+ {
163
+ src: l,
164
+ alt: c?.[e] ?? `サムネイル ${e + 1}`,
165
+ className: "h-full w-full object-cover"
166
+ }
167
+ )
168
+ },
169
+ e
170
+ )) })
171
+ ]
172
+ }
173
+ );
174
+ }
175
+ export {
176
+ P as ImageGallery
177
+ };