@shopify/shop-minis-react 0.0.32 → 0.0.34

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 (50) hide show
  1. package/dist/_virtual/index2.js +4 -4
  2. package/dist/_virtual/index3.js +4 -4
  3. package/dist/_virtual/index4.js +2 -2
  4. package/dist/_virtual/index5.js +3 -2
  5. package/dist/_virtual/index5.js.map +1 -1
  6. package/dist/_virtual/index6.js +2 -2
  7. package/dist/_virtual/index7.js +2 -3
  8. package/dist/_virtual/index7.js.map +1 -1
  9. package/dist/_virtual/index8.js +2 -2
  10. package/dist/_virtual/index9.js +2 -2
  11. package/dist/components/atoms/image.js +52 -0
  12. package/dist/components/atoms/image.js.map +1 -0
  13. package/dist/components/commerce/merchant-card.js +188 -245
  14. package/dist/components/commerce/merchant-card.js.map +1 -1
  15. package/dist/components/commerce/product-card.js +11 -11
  16. package/dist/components/commerce/product-card.js.map +1 -1
  17. package/dist/components/content/image-content-wrapper.js +29 -22
  18. package/dist/components/content/image-content-wrapper.js.map +1 -1
  19. package/dist/hooks/content/useCreateImageContent.js +16 -22
  20. package/dist/hooks/content/useCreateImageContent.js.map +1 -1
  21. package/dist/hooks/storage/useImageUpload.js +36 -37
  22. package/dist/hooks/storage/useImageUpload.js.map +1 -1
  23. package/dist/index.js +252 -246
  24. package/dist/shop-minis-platform/src/types/content.js.map +1 -1
  25. package/dist/shop-minis-react/node_modules/.pnpm/@radix-ui_react-use-is-hydrated@0.1.0_@types_react@19.1.6_react@19.1.0/node_modules/@radix-ui/react-use-is-hydrated/dist/index.js +1 -1
  26. package/dist/shop-minis-react/node_modules/.pnpm/@videojs_xhr@2.7.0/node_modules/@videojs/xhr/lib/index.js +1 -1
  27. package/dist/shop-minis-react/node_modules/.pnpm/@xmldom_xmldom@0.8.10/node_modules/@xmldom/xmldom/lib/index.js +1 -1
  28. package/dist/shop-minis-react/node_modules/.pnpm/color-string@1.9.1/node_modules/color-string/index.js +1 -1
  29. package/dist/shop-minis-react/node_modules/.pnpm/mpd-parser@1.3.1/node_modules/mpd-parser/dist/mpd-parser.es.js +1 -1
  30. package/dist/shop-minis-react/node_modules/.pnpm/querystringify@2.2.0/node_modules/querystringify/index.js +1 -1
  31. package/dist/shop-minis-react/node_modules/.pnpm/video.js@8.23.3/node_modules/video.js/dist/video.es.js +1 -1
  32. package/dist/utils/colors.js +1 -1
  33. package/dist/utils/image.js +45 -9
  34. package/dist/utils/image.js.map +1 -1
  35. package/package.json +2 -2
  36. package/src/components/atoms/{thumbhash-image.tsx → image.tsx} +14 -14
  37. package/src/components/commerce/merchant-card.tsx +224 -225
  38. package/src/components/commerce/product-card.tsx +2 -2
  39. package/src/components/content/image-content-wrapper.tsx +9 -2
  40. package/src/components/index.ts +1 -1
  41. package/src/hooks/content/useCreateImageContent.ts +1 -7
  42. package/src/hooks/storage/useImageUpload.ts +22 -20
  43. package/src/stories/MerchantCard.stories.tsx +0 -3
  44. package/src/utils/image.ts +72 -0
  45. package/src/utils/index.ts +1 -1
  46. package/dist/components/atoms/thumbhash-image.js +0 -54
  47. package/dist/components/atoms/thumbhash-image.js.map +0 -1
  48. package/dist/utils/imageToDataUri.js +0 -10
  49. package/dist/utils/imageToDataUri.js.map +0 -1
  50. package/src/utils/imageToDataUri.ts +0 -8
@@ -1,188 +1,204 @@
1
- import { jsx as e, jsxs as i, Fragment as w } from "react/jsx-runtime";
2
- import * as d from "react";
3
- import { cva as F } from "../../shop-minis-react/node_modules/.pnpm/class-variance-authority@0.7.1/node_modules/class-variance-authority/dist/index.js";
4
- import { useShopNavigation as O } from "../../hooks/navigation/useShopNavigation.js";
5
- import { cn as l } from "../../lib/utils.js";
6
- import { isDarkColor as N } from "../../utils/colors.js";
7
- import { ThumbhashImage as H } from "../atoms/thumbhash-image.js";
8
- import { Touchable as P } from "../atoms/touchable.js";
9
- import { getFeaturedImages as V, extractBrandTheme as q, normalizeRating as L, formatReviewCount as U } from "../../utils/merchant-card.js";
10
- import E from "../../shop-minis-react/node_modules/.pnpm/lucide-react@0.513.0_react@19.1.0/node_modules/lucide-react/dist/esm/icons/star.js";
11
- import { Root as G } from "../../shop-minis-react/node_modules/.pnpm/@radix-ui_react-slot@1.2.3_@types_react@19.1.6_react@19.1.0/node_modules/@radix-ui/react-slot/dist/index.js";
12
- const J = F(
13
- "relative w-full overflow-hidden rounded-xl bg-white flex flex-col border border-gray-200",
14
- {
15
- variants: {
16
- touchable: {
17
- true: "cursor-pointer",
18
- false: ""
19
- }
20
- },
21
- defaultVariants: {
22
- touchable: !0
23
- }
24
- }
1
+ import { jsx as e, jsxs as u, Fragment as p } from "react/jsx-runtime";
2
+ import { useCallback as w, useMemo as f, createContext as N, useContext as y } from "react";
3
+ import { useShopNavigation as T } from "../../hooks/navigation/useShopNavigation.js";
4
+ import { cn as c } from "../../lib/utils.js";
5
+ import { isDarkColor as b } from "../../utils/colors.js";
6
+ import { Image as k } from "../atoms/image.js";
7
+ import { Touchable as I } from "../atoms/touchable.js";
8
+ import { extractBrandTheme as M, normalizeRating as z, formatReviewCount as j, getFeaturedImages as D } from "../../utils/merchant-card.js";
9
+ import S from "../../shop-minis-react/node_modules/.pnpm/lucide-react@0.513.0_react@19.1.0/node_modules/lucide-react/dist/esm/icons/star.js";
10
+ const C = N(
11
+ void 0
25
12
  );
26
- function C({
27
- className: t,
28
- touchable: a = !0,
29
- asChild: r = !1,
30
- onPress: o,
31
- ...n
13
+ function i() {
14
+ const a = y(C);
15
+ if (!a)
16
+ throw new Error(
17
+ "useMerchantCardContext must be used within a MerchantCardProvider"
18
+ );
19
+ return a;
20
+ }
21
+ function B({
22
+ className: a,
23
+ ...r
32
24
  }) {
33
- const m = /* @__PURE__ */ e(
34
- r ? G : "div",
25
+ const { touchable: t, cardTheme: n, onClick: o } = i(), l = /* @__PURE__ */ e(
26
+ "div",
35
27
  {
36
- className: l(J({ touchable: a }), t),
37
- ...n
28
+ style: {
29
+ backgroundColor: n.backgroundColor
30
+ },
31
+ className: c(
32
+ "relative w-full overflow-hidden rounded-xl bg-white flex flex-col border border-gray-200 aspect-square",
33
+ a
34
+ ),
35
+ ...r
38
36
  }
39
37
  );
40
- return a && o ? /* @__PURE__ */ e(
41
- P,
38
+ return t && o ? /* @__PURE__ */ e(
39
+ I,
42
40
  {
43
41
  onClick: o,
44
42
  whileTap: { opacity: 0.7 },
45
43
  transition: {
46
44
  opacity: { type: "tween", duration: 0.08, ease: "easeInOut" }
47
45
  },
48
- children: m
46
+ children: l
49
47
  }
50
- ) : m;
48
+ ) : l;
51
49
  }
52
- function y({
53
- className: t,
54
- ...a
55
- }) {
56
- return /* @__PURE__ */ e(
57
- "div",
58
- {
59
- "data-slot": "merchant-card-image-container",
60
- className: l("relative overflow-hidden w-full flex-grow", t),
61
- ...a
62
- }
63
- );
64
- }
65
- function g({
66
- className: t,
67
- src: a,
68
- alt: r,
69
- thumbhash: o,
70
- ...n
50
+ function v({
51
+ className: a,
52
+ src: r,
53
+ alt: t,
54
+ thumbhash: n,
55
+ ...o
71
56
  }) {
72
- return a ? o ? /* @__PURE__ */ e(
73
- H,
57
+ return r ? n ? /* @__PURE__ */ e(
58
+ k,
74
59
  {
75
60
  "data-slot": "merchant-card-image",
76
- src: a,
77
- alt: r,
78
- thumbhash: o,
79
- className: l("w-full h-full object-cover", t),
80
- ...n
61
+ src: r,
62
+ alt: t,
63
+ thumbhash: n,
64
+ className: c(a),
65
+ ...o
81
66
  }
82
67
  ) : /* @__PURE__ */ e(
83
68
  "img",
84
69
  {
85
70
  "data-slot": "merchant-card-image",
86
- src: a,
87
- alt: r,
88
- className: l("w-full h-full object-cover", t),
89
- ...n
71
+ src: r,
72
+ alt: t,
73
+ className: c("size-full object-cover", a),
74
+ ...o
90
75
  }
91
76
  ) : /* @__PURE__ */ e("div", { className: "w-full h-full bg-gray-100" });
92
77
  }
93
- function v({
94
- className: t,
95
- src: a,
96
- alt: r,
97
- shopName: o,
98
- ...n
99
- }) {
78
+ function x({ className: a, ...r }) {
79
+ const { shop: t } = i(), { name: n, visualTheme: o } = t, l = o?.brandSettings?.colors?.logoAverage, d = o?.brandSettings?.colors?.logoDominant, m = l || d, h = f(
80
+ () => m && b(m) ? "bg-white" : "bg-gray-800",
81
+ [m]
82
+ ), s = o?.logoImage?.url, g = `${n} logo`;
100
83
  return /* @__PURE__ */ e(
101
84
  "div",
102
85
  {
103
86
  "data-slot": "merchant-card-logo",
104
- className: l(
87
+ className: c(
105
88
  "absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 z-10",
106
89
  "w-16 h-16 rounded-xl bg-white border-2 border-white shadow-sm",
107
90
  "flex items-center justify-center overflow-hidden",
108
- t
91
+ h,
92
+ a
109
93
  ),
110
- ...n,
111
- children: a ? /* @__PURE__ */ e("img", { src: a, alt: r, className: "w-full h-full object-cover" }) : /* @__PURE__ */ e("div", { className: "w-full h-full bg-gray-200 flex items-center justify-center", children: /* @__PURE__ */ e("span", { className: "text-gray-600 font-semibold text-lg", children: o?.slice(0, 1) }) })
94
+ ...r,
95
+ children: s ? /* @__PURE__ */ e(
96
+ "img",
97
+ {
98
+ src: s,
99
+ alt: g,
100
+ className: "w-full h-full object-cover"
101
+ }
102
+ ) : /* @__PURE__ */ e("div", { className: "w-full h-full bg-gray-200 flex items-center justify-center", children: /* @__PURE__ */ e("span", { className: "text-gray-600 font-semibold text-lg", children: n?.slice(0, 1) }) })
112
103
  }
113
104
  );
114
105
  }
115
- function k({ className: t, ...a }) {
106
+ function R({ className: a, ...r }) {
107
+ const { cardTheme: t } = i(), o = f(() => t.backgroundColor !== "white" && b(t.backgroundColor), [t.backgroundColor]) ? "text-primary-foreground" : "text-foreground";
116
108
  return /* @__PURE__ */ e(
117
109
  "div",
118
110
  {
119
111
  "data-slot": "merchant-card-info",
120
- className: l(
121
- "p-3 space-y-2 flex-shrink-0 flex items-center justify-between",
122
- t
112
+ className: c(
113
+ "p-3 flex-shrink-0 flex flex-col min-w-0",
114
+ o,
115
+ a
123
116
  ),
124
- ...a
117
+ ...r
125
118
  }
126
119
  );
127
120
  }
128
- function I({
129
- className: t,
130
- children: a,
131
- ...r
121
+ function $({
122
+ className: a,
123
+ children: r,
124
+ ...t
132
125
  }) {
126
+ const { shop: n } = i(), { name: o } = n, l = r ?? o;
133
127
  return /* @__PURE__ */ e(
134
128
  "h3",
135
129
  {
136
130
  "data-slot": "merchant-card-name",
137
- className: l(
138
- "text-sm font-medium text-grayscale-d100",
139
- "truncate overflow-hidden whitespace-nowrap text-ellipsis",
140
- t
141
- ),
142
- ...r,
143
- children: a
131
+ className: c("text-sm font-medium truncate", a),
132
+ ...t,
133
+ children: l
144
134
  }
145
135
  );
146
136
  }
147
- function M({
148
- className: t,
149
- rating: a,
150
- reviewCount: r,
151
- ...o
137
+ function A({
138
+ className: a,
139
+ ...r
152
140
  }) {
153
- return !a || !r ? null : /* @__PURE__ */ i(
141
+ const { shop: t } = i(), {
142
+ reviewAnalytics: { averageRating: n, reviewCount: o }
143
+ } = t;
144
+ return !n || !o ? null : /* @__PURE__ */ u(
154
145
  "div",
155
146
  {
156
147
  "data-slot": "merchant-card-rating",
157
- className: l("flex items-center gap-1 text-xs", t),
158
- ...o,
148
+ className: c("flex items-center gap-1 text-xs", a),
149
+ ...r,
159
150
  children: [
160
- /* @__PURE__ */ e(E, { className: "h-3 w-3 fill-current" }),
161
- /* @__PURE__ */ i("span", { className: "text-xs", children: [
162
- L(a),
151
+ /* @__PURE__ */ e(S, { className: "h-3 w-3 fill-current" }),
152
+ /* @__PURE__ */ u("span", { className: "text-xs", children: [
153
+ z(n),
163
154
  " (",
164
- U(r),
155
+ j(o),
165
156
  ")"
166
157
  ] })
167
158
  ]
168
159
  }
169
160
  );
170
161
  }
171
- function j({
172
- shop: t,
173
- cardTheme: a,
174
- logoBackgroundClassName: r
175
- }) {
176
- const o = t.visualTheme?.brandSettings?.headerTheme?.wordmark;
177
- return /* @__PURE__ */ i("div", { className: "size-full relative", children: [
178
- a.type === "coverImage" && /* @__PURE__ */ i(w, { children: [
162
+ function F({ withLogo: a = !1 }) {
163
+ const { shop: r, cardTheme: t, featuredImagesLimit: n } = i(), { visualTheme: o } = r, l = f(
164
+ () => D(o, n),
165
+ [o, n]
166
+ ), d = l?.length ?? 0;
167
+ return /* @__PURE__ */ u("div", { className: "w-full h-full bg-muted relative flex flex-wrap overflow-hidden", children: [
168
+ a && /* @__PURE__ */ e("div", { className: "absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 z-10", children: /* @__PURE__ */ e(x, {}) }),
169
+ (() => {
170
+ if (d > 0) {
171
+ const h = d === 2 ? "h-full" : "h-1/2";
172
+ return l?.map((s, g) => /* @__PURE__ */ e("div", { className: `z-0 w-1/2 ${h}`, children: /* @__PURE__ */ e(
173
+ v,
174
+ {
175
+ src: s.url,
176
+ alt: s.altText ?? void 0,
177
+ thumbhash: s.thumbhash ?? void 0,
178
+ className: "aspect-square"
179
+ }
180
+ ) }, s.url || g));
181
+ } else if (t.type === "coverImage")
182
+ return /* @__PURE__ */ e(
183
+ v,
184
+ {
185
+ src: t.coverImageUrl,
186
+ thumbhash: t.coverImageThumbhash
187
+ }
188
+ );
189
+ })()
190
+ ] });
191
+ }
192
+ function H({ withLogo: a = !1 }) {
193
+ const { shop: r, cardTheme: t } = i(), n = r.visualTheme?.brandSettings?.headerTheme?.wordmark;
194
+ return /* @__PURE__ */ u("div", { className: "size-full relative", children: [
195
+ t.type === "coverImage" && /* @__PURE__ */ u(p, { children: [
179
196
  /* @__PURE__ */ e(
180
- g,
197
+ v,
181
198
  {
182
- src: a.coverImageUrl,
183
- alt: t.name,
184
- thumbhash: a.coverImageThumbhash ?? void 0,
185
- className: "size-full"
199
+ src: t.coverImageUrl,
200
+ alt: r.name,
201
+ thumbhash: t.coverImageThumbhash ?? void 0
186
202
  }
187
203
  ),
188
204
  /* @__PURE__ */ e("div", { className: "absolute inset-0 z-[1] bg-black/20" }),
@@ -191,146 +207,73 @@ function j({
191
207
  {
192
208
  className: "absolute bottom-0 z-[1] size-full",
193
209
  style: {
194
- background: `linear-gradient(to top, ${a.backgroundColor} 0%, ${a.backgroundColor}00 40%)`
210
+ background: `linear-gradient(to top, ${t.backgroundColor} 0%, ${t.backgroundColor}00 40%)`
195
211
  }
196
212
  }
197
213
  )
198
214
  ] }),
199
- /* @__PURE__ */ e("div", { className: "absolute inset-0 z-[1] flex items-center justify-center", children: o ? /* @__PURE__ */ e(
215
+ a && /* @__PURE__ */ e("div", { className: "absolute inset-0 z-[1] flex items-center justify-center", children: n ? /* @__PURE__ */ e(
200
216
  "img",
201
217
  {
202
- src: o.url,
203
- alt: o.altText || t.name,
218
+ src: n.url,
219
+ alt: n.altText || r.name,
204
220
  className: "max-h-16 min-h-10 max-w-28 object-contain",
205
221
  "data-testid": "store-data-wordmark"
206
222
  }
207
- ) : /* @__PURE__ */ e(
208
- v,
209
- {
210
- src: t.visualTheme?.logoImage?.url,
211
- alt: `${t.name} logo`,
212
- shopName: t.name,
213
- className: r
214
- }
215
- ) })
223
+ ) : /* @__PURE__ */ e(x, {}) })
216
224
  ] });
217
225
  }
218
- function oe({
219
- shop: t,
220
- touchable: a = !0,
221
- fixedHeight: r = !1,
222
- featuredImagesLimit: o = 4
226
+ function U({
227
+ isDefault: a,
228
+ withLogo: r,
229
+ className: t,
230
+ ...n
223
231
  }) {
224
- const { navigateToShop: n } = O(), {
225
- id: f,
226
- name: m,
227
- reviewAnalytics: { averageRating: T, reviewCount: z },
228
- visualTheme: s
229
- } = t, S = d.useCallback(() => {
230
- a && n({ shopId: f });
231
- }, [n, f, a]), b = d.useMemo(
232
- () => V(s, o),
233
- [s, o]
234
- ), R = b?.length ?? 0, B = s?.brandSettings?.colors?.logoAverage, D = s?.brandSettings?.colors?.logoDominant, h = B || D, x = d.useMemo(
235
- () => h && N(h) ? "bg-white" : "bg-gray-800",
236
- [h]
237
- ), c = d.useMemo(
238
- () => q(s?.brandSettings),
239
- [s?.brandSettings]
240
- ), p = d.useMemo(() => c.backgroundColor !== "white" && N(c.backgroundColor), [c.backgroundColor]) ? "text-primary-foreground" : "text-foreground", $ = c.type === "coverImage" || c.type === "brandColor";
241
- return /* @__PURE__ */ e("div", { className: l("flex", r ? "" : "aspect-square"), children: /* @__PURE__ */ i(
242
- C,
232
+ const { cardTheme: o } = i(), l = o.type === "coverImage" || o.type === "brandColor";
233
+ return /* @__PURE__ */ e(
234
+ "div",
243
235
  {
244
- touchable: a,
245
- onPress: S,
246
- style: {
247
- backgroundColor: c.backgroundColor
248
- },
249
- children: [
250
- /* @__PURE__ */ e(
251
- y,
252
- {
253
- className: l(
254
- "relative overflow-hidden w-full",
255
- r ? "h-[120px]" : "flex-1"
256
- ),
257
- children: $ ? /* @__PURE__ */ e(
258
- j,
259
- {
260
- shop: t,
261
- cardTheme: c,
262
- logoBackgroundClassName: x
263
- }
264
- ) : /* @__PURE__ */ i(w, { children: [
265
- /* @__PURE__ */ e("div", { className: "absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 z-10", children: /* @__PURE__ */ e(
266
- v,
267
- {
268
- src: s?.logoImage?.url,
269
- alt: `${m} logo`,
270
- shopName: m,
271
- className: x,
272
- "data-testid": "merchant-logo"
273
- }
274
- ) }),
275
- R > 0 ? b?.map((u, A) => /* @__PURE__ */ e(
276
- "div",
277
- {
278
- className: "z-0 flex h-full flex-1",
279
- children: /* @__PURE__ */ e(
280
- g,
281
- {
282
- src: u.url,
283
- alt: u.altText || "",
284
- thumbhash: u.thumbhash ?? void 0
285
- }
286
- )
287
- },
288
- u.url || A
289
- )) : /* @__PURE__ */ e(
290
- "div",
291
- {
292
- className: "h-20 bg-gray-100",
293
- "data-testid": "image-fallback"
294
- }
295
- )
296
- ] })
297
- }
298
- ),
299
- /* @__PURE__ */ e(k, { className: "flex items-center justify-between p-3", children: /* @__PURE__ */ e("div", { className: "flex flex-col items-start gap-2", children: /* @__PURE__ */ i("div", { className: "flex min-w-0 flex-1 flex-col", children: [
300
- /* @__PURE__ */ e(
301
- I,
302
- {
303
- className: l(
304
- "line-clamp-1 overflow-hidden text-ellipsis",
305
- p
306
- ),
307
- children: m
308
- }
309
- ),
310
- /* @__PURE__ */ e(
311
- M,
312
- {
313
- rating: T,
314
- reviewCount: z,
315
- className: p
316
- }
317
- )
318
- ] }) }) })
319
- ]
236
+ className: c("relative overflow-hidden flex-1 flex-wrap", t),
237
+ ...n,
238
+ children: l && !a ? /* @__PURE__ */ e(H, { withLogo: r }) : /* @__PURE__ */ e(F, { withLogo: r })
320
239
  }
321
- ) });
240
+ );
241
+ }
242
+ function Q({
243
+ shop: a,
244
+ touchable: r = !0,
245
+ featuredImagesLimit: t = 4,
246
+ children: n
247
+ }) {
248
+ const { navigateToShop: o } = T(), { id: l, visualTheme: d } = a, m = w(() => {
249
+ r && o({ shopId: l });
250
+ }, [o, l, r]), h = f(
251
+ () => M(d?.brandSettings),
252
+ [d?.brandSettings]
253
+ ), s = f(
254
+ () => ({
255
+ shop: a,
256
+ cardTheme: h,
257
+ touchable: r,
258
+ featuredImagesLimit: t,
259
+ onClick: m
260
+ }),
261
+ [a, h, r, t, m]
262
+ );
263
+ return /* @__PURE__ */ e(C.Provider, { value: s, children: n ?? /* @__PURE__ */ u(B, { children: [
264
+ /* @__PURE__ */ e(U, { withLogo: !0 }),
265
+ /* @__PURE__ */ u(R, { children: [
266
+ /* @__PURE__ */ e($, {}),
267
+ /* @__PURE__ */ e(A, {})
268
+ ] })
269
+ ] }) });
322
270
  }
323
- const le = Object.assign(C, {
324
- ImageContainer: y,
325
- Image: g,
326
- Logo: v,
327
- Info: k,
328
- Name: I,
329
- Rating: M,
330
- BrandedHeader: j
331
- });
332
271
  export {
333
- oe as MerchantCard,
334
- le as MerchantCardPrimitive
272
+ Q as MerchantCard,
273
+ B as MerchantCardContainer,
274
+ U as MerchantCardHeader,
275
+ R as MerchantCardInfo,
276
+ $ as MerchantCardName,
277
+ A as MerchantCardRating
335
278
  };
336
279
  //# sourceMappingURL=merchant-card.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"merchant-card.js","sources":["../../../src/components/commerce/merchant-card.tsx"],"sourcesContent":["import * as React from 'react'\n\nimport {type Shop} from '@shopify/shop-minis-platform'\nimport {cva, type VariantProps} from 'class-variance-authority'\nimport {Star} from 'lucide-react'\nimport {Slot as SlotPrimitive} from 'radix-ui'\n\nimport {useShopNavigation} from '../../hooks/navigation/useShopNavigation'\nimport {cn} from '../../lib/utils'\nimport {\n type ExtractedBrandTheme,\n extractBrandTheme,\n formatReviewCount,\n getFeaturedImages,\n normalizeRating,\n} from '../../utils'\nimport {isDarkColor} from '../../utils/colors'\nimport {ThumbhashImage} from '../atoms/thumbhash-image'\nimport {Touchable} from '../atoms/touchable'\n\nconst merchantCardVariants = cva(\n 'relative w-full overflow-hidden rounded-xl bg-white flex flex-col border border-gray-200',\n {\n variants: {\n touchable: {\n true: 'cursor-pointer',\n false: '',\n },\n },\n defaultVariants: {\n touchable: true,\n },\n }\n)\n\nexport interface MerchantCardRootProps\n extends React.ComponentProps<'div'>,\n VariantProps<typeof merchantCardVariants> {\n touchable?: boolean\n asChild?: boolean\n onPress?: () => void\n}\n\nfunction MerchantCardRoot({\n className,\n touchable = true,\n asChild = false,\n onPress,\n ...props\n}: MerchantCardRootProps) {\n const Comp = asChild ? SlotPrimitive.Slot : 'div'\n\n const content = (\n <Comp\n className={cn(merchantCardVariants({touchable}), className)}\n {...props}\n />\n )\n\n if (touchable && onPress) {\n return (\n <Touchable\n onClick={onPress}\n whileTap={{opacity: 0.7}}\n transition={{\n opacity: {type: 'tween', duration: 0.08, ease: 'easeInOut'},\n }}\n >\n {content}\n </Touchable>\n )\n }\n\n return content\n}\n\nfunction MerchantCardImageContainer({\n className,\n ...props\n}: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"merchant-card-image-container\"\n className={cn('relative overflow-hidden w-full flex-grow', className)}\n {...props}\n />\n )\n}\n\nfunction MerchantCardImage({\n className,\n src,\n alt,\n thumbhash,\n ...props\n}: React.ComponentProps<'img'> & {\n src?: string\n alt?: string\n thumbhash?: string\n}) {\n if (!src) {\n return <div className=\"w-full h-full bg-gray-100\" />\n }\n\n if (thumbhash) {\n return (\n <ThumbhashImage\n data-slot=\"merchant-card-image\"\n src={src}\n alt={alt}\n thumbhash={thumbhash}\n className={cn('w-full h-full object-cover', className)}\n {...props}\n />\n )\n }\n\n return (\n <img\n data-slot=\"merchant-card-image\"\n src={src}\n alt={alt}\n className={cn('w-full h-full object-cover', className)}\n {...props}\n />\n )\n}\n\nfunction MerchantCardLogo({\n className,\n src,\n alt,\n shopName,\n ...props\n}: React.ComponentProps<'div'> & {\n src?: string\n alt?: string\n shopName?: string\n}) {\n return (\n <div\n data-slot=\"merchant-card-logo\"\n className={cn(\n 'absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 z-10',\n 'w-16 h-16 rounded-xl bg-white border-2 border-white shadow-sm',\n 'flex items-center justify-center overflow-hidden',\n className\n )}\n {...props}\n >\n {src ? (\n <img src={src} alt={alt} className=\"w-full h-full object-cover\" />\n ) : (\n <div className=\"w-full h-full bg-gray-200 flex items-center justify-center\">\n <span className=\"text-gray-600 font-semibold text-lg\">\n {shopName?.slice(0, 1)}\n </span>\n </div>\n )}\n </div>\n )\n}\n\nfunction MerchantCardInfo({className, ...props}: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"merchant-card-info\"\n className={cn(\n 'p-3 space-y-2 flex-shrink-0 flex items-center justify-between',\n className\n )}\n {...props}\n />\n )\n}\n\nfunction MerchantCardName({\n className,\n children,\n ...props\n}: React.ComponentProps<'h3'>) {\n return (\n <h3\n data-slot=\"merchant-card-name\"\n className={cn(\n 'text-sm font-medium text-grayscale-d100',\n 'truncate overflow-hidden whitespace-nowrap text-ellipsis',\n className\n )}\n {...props}\n >\n {children}\n </h3>\n )\n}\n\nfunction MerchantCardRating({\n className,\n rating,\n reviewCount,\n ...props\n}: React.ComponentProps<'div'> & {\n rating?: number | null\n reviewCount?: number\n}) {\n if (!rating || !reviewCount) return null\n\n return (\n <div\n data-slot=\"merchant-card-rating\"\n className={cn('flex items-center gap-1 text-xs', className)}\n {...props}\n >\n <Star className=\"h-3 w-3 fill-current\" />\n <span className=\"text-xs\">\n {normalizeRating(rating)} ({formatReviewCount(reviewCount)})\n </span>\n </div>\n )\n}\n\nfunction MerchantCardBrandedHeader({\n shop,\n cardTheme,\n logoBackgroundClassName,\n}: {\n shop: Shop\n cardTheme: ExtractedBrandTheme\n logoBackgroundClassName?: string\n}) {\n const wordmarkImage = shop.visualTheme?.brandSettings?.headerTheme?.wordmark\n\n return (\n <div className=\"size-full relative\">\n {cardTheme.type === 'coverImage' && (\n <>\n <MerchantCardImage\n src={cardTheme.coverImageUrl}\n alt={shop.name}\n thumbhash={cardTheme.coverImageThumbhash ?? undefined}\n className=\"size-full\"\n />\n\n <div className=\"absolute inset-0 z-[1] bg-black/20\" />\n\n <div\n className=\"absolute bottom-0 z-[1] size-full\"\n style={{\n background: `linear-gradient(to top, ${cardTheme.backgroundColor} 0%, ${cardTheme.backgroundColor}00 40%)`,\n }}\n />\n </>\n )}\n\n <div className=\"absolute inset-0 z-[1] flex items-center justify-center\">\n {wordmarkImage ? (\n <img\n src={wordmarkImage.url}\n alt={wordmarkImage.altText || shop.name}\n className=\"max-h-16 min-h-10 max-w-28 object-contain\"\n data-testid=\"store-data-wordmark\"\n />\n ) : (\n <MerchantCardLogo\n src={shop.visualTheme?.logoImage?.url}\n alt={`${shop.name} logo`}\n shopName={shop.name}\n className={logoBackgroundClassName}\n />\n )}\n </div>\n </div>\n )\n}\nexport interface MerchantCardProps {\n shop: Shop\n touchable?: boolean\n fixedHeight?: boolean\n featuredImagesLimit?: number\n}\n\nfunction MerchantCard({\n shop,\n touchable = true,\n fixedHeight = false,\n featuredImagesLimit = 4,\n}: MerchantCardProps) {\n const {navigateToShop} = useShopNavigation()\n\n const {\n id,\n name,\n reviewAnalytics: {averageRating, reviewCount},\n visualTheme,\n } = shop\n\n const handlePress = React.useCallback(() => {\n if (!touchable) return\n navigateToShop({shopId: id})\n }, [navigateToShop, id, touchable])\n\n const featuredImages = React.useMemo(\n () => getFeaturedImages(visualTheme, featuredImagesLimit),\n [visualTheme, featuredImagesLimit]\n )\n\n const numberOfFeaturedImages = featuredImages?.length ?? 0\n\n const logoAverageColor = visualTheme?.brandSettings?.colors?.logoAverage\n const logoDominantColor = visualTheme?.brandSettings?.colors?.logoDominant\n const logoColor = logoAverageColor || logoDominantColor\n\n const logoBackgroundClassName = React.useMemo(\n () => (logoColor && isDarkColor(logoColor) ? 'bg-white' : 'bg-gray-800'),\n [logoColor]\n )\n\n const cardTheme = React.useMemo(\n () => extractBrandTheme(visualTheme?.brandSettings),\n [visualTheme?.brandSettings]\n )\n\n const isDarkTheme = React.useMemo(() => {\n return (\n cardTheme.backgroundColor !== 'white' &&\n isDarkColor(cardTheme.backgroundColor)\n )\n }, [cardTheme.backgroundColor])\n\n const textColor = isDarkTheme ? 'text-primary-foreground' : 'text-foreground'\n\n const hasBrandedHeader =\n cardTheme.type === 'coverImage' || cardTheme.type === 'brandColor'\n\n return (\n <div className={cn('flex', fixedHeight ? '' : 'aspect-square')}>\n <MerchantCardRoot\n touchable={touchable}\n onPress={handlePress}\n style={{\n backgroundColor: cardTheme.backgroundColor,\n }}\n >\n <MerchantCardImageContainer\n className={cn(\n 'relative overflow-hidden w-full',\n fixedHeight ? 'h-[120px]' : 'flex-1'\n )}\n >\n {hasBrandedHeader ? (\n <MerchantCardBrandedHeader\n shop={shop}\n cardTheme={cardTheme}\n logoBackgroundClassName={logoBackgroundClassName}\n />\n ) : (\n <>\n <div className=\"absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 z-10\">\n <MerchantCardLogo\n src={visualTheme?.logoImage?.url}\n alt={`${name} logo`}\n shopName={name}\n className={logoBackgroundClassName}\n data-testid=\"merchant-logo\"\n />\n </div>\n\n {numberOfFeaturedImages > 0 ? (\n featuredImages?.map((image, index) => (\n <div\n className=\"z-0 flex h-full flex-1\"\n key={image.url || index}\n >\n <MerchantCardImage\n src={image.url}\n alt={image.altText || ''}\n thumbhash={image.thumbhash ?? undefined}\n />\n </div>\n ))\n ) : (\n <div\n className=\"h-20 bg-gray-100\"\n data-testid=\"image-fallback\"\n />\n )}\n </>\n )}\n </MerchantCardImageContainer>\n\n <MerchantCardInfo className=\"flex items-center justify-between p-3\">\n <div className=\"flex flex-col items-start gap-2\">\n <div className=\"flex min-w-0 flex-1 flex-col\">\n <MerchantCardName\n className={cn(\n 'line-clamp-1 overflow-hidden text-ellipsis',\n textColor\n )}\n >\n {name}\n </MerchantCardName>\n\n <MerchantCardRating\n rating={averageRating}\n reviewCount={reviewCount}\n className={textColor}\n />\n </div>\n </div>\n </MerchantCardInfo>\n </MerchantCardRoot>\n </div>\n )\n}\n\nexport const MerchantCardPrimitive = Object.assign(MerchantCardRoot, {\n ImageContainer: MerchantCardImageContainer,\n Image: MerchantCardImage,\n Logo: MerchantCardLogo,\n Info: MerchantCardInfo,\n Name: MerchantCardName,\n Rating: MerchantCardRating,\n BrandedHeader: MerchantCardBrandedHeader,\n})\n\nexport {MerchantCard}\n"],"names":["merchantCardVariants","cva","MerchantCardRoot","className","touchable","asChild","onPress","props","content","jsx","SlotPrimitive.Slot","cn","Touchable","MerchantCardImageContainer","MerchantCardImage","src","alt","thumbhash","ThumbhashImage","MerchantCardLogo","shopName","MerchantCardInfo","MerchantCardName","children","MerchantCardRating","rating","reviewCount","jsxs","Star","normalizeRating","formatReviewCount","MerchantCardBrandedHeader","shop","cardTheme","logoBackgroundClassName","wordmarkImage","Fragment","MerchantCard","fixedHeight","featuredImagesLimit","navigateToShop","useShopNavigation","id","name","averageRating","visualTheme","handlePress","React","featuredImages","getFeaturedImages","numberOfFeaturedImages","logoAverageColor","logoDominantColor","logoColor","isDarkColor","extractBrandTheme","textColor","hasBrandedHeader","image","index","MerchantCardPrimitive"],"mappings":"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"}
1
+ {"version":3,"file":"merchant-card.js","sources":["../../../src/components/commerce/merchant-card.tsx"],"sourcesContent":["import * as React from 'react'\nimport {createContext, useCallback, useContext, useMemo} from 'react'\n\nimport {type Shop} from '@shopify/shop-minis-platform'\nimport {Star} from 'lucide-react'\n\nimport {useShopNavigation} from '../../hooks/navigation/useShopNavigation'\nimport {cn} from '../../lib/utils'\nimport {\n type ExtractedBrandTheme,\n extractBrandTheme,\n formatReviewCount,\n getFeaturedImages,\n normalizeRating,\n} from '../../utils'\nimport {isDarkColor} from '../../utils/colors'\nimport {Image} from '../atoms/image'\nimport {Touchable} from '../atoms/touchable'\n\ninterface MerchantCardContextValue {\n // Core data\n shop: Shop\n\n // Derived data\n cardTheme: ExtractedBrandTheme\n\n // UI configuration\n touchable: boolean\n featuredImagesLimit: number\n\n // Actions\n onClick: () => void\n}\n\nconst MerchantCardContext = createContext<MerchantCardContextValue | undefined>(\n undefined\n)\n\nfunction useMerchantCardContext() {\n const context = useContext(MerchantCardContext)\n if (!context) {\n throw new Error(\n 'useMerchantCardContext must be used within a MerchantCardProvider'\n )\n }\n return context\n}\n\nfunction MerchantCardContainer({\n className,\n ...props\n}: React.ComponentProps<'div'>) {\n const {touchable, cardTheme, onClick} = useMerchantCardContext()\n\n const content = (\n <div\n style={{\n backgroundColor: cardTheme.backgroundColor,\n }}\n className={cn(\n 'relative w-full overflow-hidden rounded-xl bg-white flex flex-col border border-gray-200 aspect-square',\n\n className\n )}\n {...props}\n />\n )\n\n if (touchable && onClick) {\n return (\n <Touchable\n onClick={onClick}\n whileTap={{opacity: 0.7}}\n transition={{\n opacity: {type: 'tween', duration: 0.08, ease: 'easeInOut'},\n }}\n >\n {content}\n </Touchable>\n )\n }\n\n return content\n}\n\nfunction MerchantCardImage({\n className,\n src,\n alt,\n thumbhash,\n ...props\n}: React.ComponentProps<'img'> & {\n src?: string\n alt?: string\n thumbhash?: string\n}) {\n if (!src) {\n return <div className=\"w-full h-full bg-gray-100\" />\n }\n\n if (thumbhash) {\n return (\n <Image\n data-slot=\"merchant-card-image\"\n src={src}\n alt={alt}\n thumbhash={thumbhash}\n className={cn(className)}\n {...props}\n />\n )\n }\n\n return (\n <img\n data-slot=\"merchant-card-image\"\n src={src}\n alt={alt}\n className={cn('size-full object-cover', className)}\n {...props}\n />\n )\n}\n\nfunction MerchantCardLogo({className, ...props}: React.ComponentProps<'div'>) {\n const {shop} = useMerchantCardContext()\n const {name, visualTheme} = shop\n\n const logoAverageColor = visualTheme?.brandSettings?.colors?.logoAverage\n const logoDominantColor = visualTheme?.brandSettings?.colors?.logoDominant\n const logoColor = logoAverageColor || logoDominantColor\n\n const logoBackgroundClassName = useMemo(\n () => (logoColor && isDarkColor(logoColor) ? 'bg-white' : 'bg-gray-800'),\n [logoColor]\n )\n\n const logoUrl = visualTheme?.logoImage?.url\n const altText = `${name} logo`\n\n return (\n <div\n data-slot=\"merchant-card-logo\"\n className={cn(\n 'absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 z-10',\n 'w-16 h-16 rounded-xl bg-white border-2 border-white shadow-sm',\n 'flex items-center justify-center overflow-hidden',\n logoBackgroundClassName,\n className\n )}\n {...props}\n >\n {logoUrl ? (\n <img\n src={logoUrl}\n alt={altText}\n className=\"w-full h-full object-cover\"\n />\n ) : (\n <div className=\"w-full h-full bg-gray-200 flex items-center justify-center\">\n <span className=\"text-gray-600 font-semibold text-lg\">\n {name?.slice(0, 1)}\n </span>\n </div>\n )}\n </div>\n )\n}\n\nfunction MerchantCardInfo({className, ...props}: React.ComponentProps<'div'>) {\n const {cardTheme} = useMerchantCardContext()\n\n const isDarkTheme = useMemo(() => {\n return (\n cardTheme.backgroundColor !== 'white' &&\n isDarkColor(cardTheme.backgroundColor)\n )\n }, [cardTheme.backgroundColor])\n\n const textColor = isDarkTheme ? 'text-primary-foreground' : 'text-foreground'\n\n return (\n <div\n data-slot=\"merchant-card-info\"\n className={cn(\n 'p-3 flex-shrink-0 flex flex-col min-w-0',\n textColor,\n className\n )}\n {...props}\n />\n )\n}\n\nfunction MerchantCardName({\n className,\n children,\n ...props\n}: React.ComponentProps<'h3'>) {\n const {shop} = useMerchantCardContext()\n const {name} = shop\n const nameContent = children ?? name\n\n return (\n <h3\n data-slot=\"merchant-card-name\"\n className={cn('text-sm font-medium truncate', className)}\n {...props}\n >\n {nameContent}\n </h3>\n )\n}\n\nfunction MerchantCardRating({\n className,\n\n ...props\n}: React.ComponentProps<'div'> & {\n rating?: number | null\n reviewCount?: number\n}) {\n const {shop} = useMerchantCardContext()\n\n const {\n reviewAnalytics: {averageRating, reviewCount},\n } = shop\n\n if (!averageRating || !reviewCount) return null\n\n return (\n <div\n data-slot=\"merchant-card-rating\"\n className={cn('flex items-center gap-1 text-xs', className)}\n {...props}\n >\n <Star className=\"h-3 w-3 fill-current\" />\n <span className=\"text-xs\">\n {normalizeRating(averageRating)} ({formatReviewCount(reviewCount)})\n </span>\n </div>\n )\n}\n\nfunction MerchantCardDefaultHeader({withLogo = false}: {withLogo?: boolean}) {\n const {shop, cardTheme, featuredImagesLimit} = useMerchantCardContext()\n const {visualTheme} = shop\n\n const featuredImages = useMemo(\n () => getFeaturedImages(visualTheme, featuredImagesLimit),\n [visualTheme, featuredImagesLimit]\n )\n\n const numberOfFeaturedImages = featuredImages?.length ?? 0\n\n const displayDefaultCover = () => {\n if (numberOfFeaturedImages > 0) {\n const heightClass = numberOfFeaturedImages === 2 ? 'h-full' : 'h-1/2'\n return featuredImages?.map((image, index) => (\n <div className={`z-0 w-1/2 ${heightClass}`} key={image.url || index}>\n <MerchantCardImage\n src={image.url}\n alt={image.altText ?? undefined}\n thumbhash={image.thumbhash ?? undefined}\n className=\"aspect-square\"\n />\n </div>\n ))\n } else if (cardTheme.type === 'coverImage') {\n return (\n <MerchantCardImage\n src={cardTheme.coverImageUrl}\n thumbhash={cardTheme.coverImageThumbhash}\n />\n )\n }\n }\n\n return (\n <div className=\"w-full h-full bg-muted relative flex flex-wrap overflow-hidden\">\n {withLogo && (\n <div className=\"absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 z-10\">\n <MerchantCardLogo />\n </div>\n )}\n\n {displayDefaultCover()}\n </div>\n )\n}\n\nfunction MerchantCardBrandedHeader({withLogo = false}: {withLogo?: boolean}) {\n const {shop, cardTheme} = useMerchantCardContext()\n const wordmarkImage = shop.visualTheme?.brandSettings?.headerTheme?.wordmark\n\n return (\n <div className=\"size-full relative\">\n {cardTheme.type === 'coverImage' && (\n <>\n <MerchantCardImage\n src={cardTheme.coverImageUrl}\n alt={shop.name}\n thumbhash={cardTheme.coverImageThumbhash ?? undefined}\n />\n\n <div className=\"absolute inset-0 z-[1] bg-black/20\" />\n\n <div\n className=\"absolute bottom-0 z-[1] size-full\"\n style={{\n background: `linear-gradient(to top, ${cardTheme.backgroundColor} 0%, ${cardTheme.backgroundColor}00 40%)`,\n }}\n />\n </>\n )}\n\n {withLogo && (\n <div className=\"absolute inset-0 z-[1] flex items-center justify-center\">\n {wordmarkImage ? (\n <img\n src={wordmarkImage.url}\n alt={wordmarkImage.altText || shop.name}\n className=\"max-h-16 min-h-10 max-w-28 object-contain\"\n data-testid=\"store-data-wordmark\"\n />\n ) : (\n <MerchantCardLogo />\n )}\n </div>\n )}\n </div>\n )\n}\n\ninterface MerchantCardHeaderProps {\n isDefault?: boolean\n withLogo?: boolean\n}\n\nfunction MerchantCardHeader({\n isDefault,\n withLogo,\n className,\n ...props\n}: React.ComponentProps<'div'> & MerchantCardHeaderProps) {\n const {cardTheme} = useMerchantCardContext()\n\n const isBranded =\n cardTheme.type === 'coverImage' || cardTheme.type === 'brandColor'\n\n return (\n <div\n className={cn('relative overflow-hidden flex-1 flex-wrap', className)}\n {...props}\n >\n {isBranded && !isDefault ? (\n <MerchantCardBrandedHeader withLogo={withLogo} />\n ) : (\n <MerchantCardDefaultHeader withLogo={withLogo} />\n )}\n </div>\n )\n}\n\nexport interface MerchantCardProps {\n shop: Shop\n touchable?: boolean\n featuredImagesLimit?: number\n children?: React.ReactNode\n}\n\nfunction MerchantCard({\n shop,\n touchable = true,\n featuredImagesLimit = 4,\n children,\n}: MerchantCardProps) {\n const {navigateToShop} = useShopNavigation()\n\n const {id, visualTheme} = shop\n\n const handleClick = useCallback(() => {\n if (!touchable) return\n navigateToShop({shopId: id})\n }, [navigateToShop, id, touchable])\n\n const cardTheme = useMemo(\n () => extractBrandTheme(visualTheme?.brandSettings),\n [visualTheme?.brandSettings]\n )\n\n const contextValue = useMemo<MerchantCardContextValue>(\n () => ({\n shop,\n cardTheme,\n touchable,\n featuredImagesLimit,\n onClick: handleClick,\n }),\n [shop, cardTheme, touchable, featuredImagesLimit, handleClick]\n )\n\n return (\n <MerchantCardContext.Provider value={contextValue}>\n {children ?? (\n <MerchantCardContainer>\n <MerchantCardHeader withLogo />\n <MerchantCardInfo>\n <MerchantCardName />\n <MerchantCardRating />\n </MerchantCardInfo>\n </MerchantCardContainer>\n )}\n </MerchantCardContext.Provider>\n )\n}\n\nexport {\n MerchantCard,\n MerchantCardContainer,\n MerchantCardHeader,\n MerchantCardInfo,\n MerchantCardName,\n MerchantCardRating,\n}\n"],"names":["MerchantCardContext","createContext","useMerchantCardContext","context","useContext","MerchantCardContainer","className","props","touchable","cardTheme","onClick","content","jsx","cn","Touchable","MerchantCardImage","src","alt","thumbhash","Image","MerchantCardLogo","shop","name","visualTheme","logoAverageColor","logoDominantColor","logoColor","logoBackgroundClassName","useMemo","isDarkColor","logoUrl","altText","MerchantCardInfo","textColor","MerchantCardName","children","nameContent","MerchantCardRating","averageRating","reviewCount","jsxs","Star","normalizeRating","formatReviewCount","MerchantCardDefaultHeader","withLogo","featuredImagesLimit","featuredImages","getFeaturedImages","numberOfFeaturedImages","heightClass","image","index","MerchantCardBrandedHeader","wordmarkImage","Fragment","MerchantCardHeader","isDefault","isBranded","MerchantCard","navigateToShop","useShopNavigation","id","handleClick","useCallback","extractBrandTheme","contextValue"],"mappings":"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"}