@shopify/shop-minis-react 0.0.28 → 0.0.29

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.
@@ -1,16 +1,16 @@
1
- import { jsxs as c, jsx as t, Fragment as F } from "react/jsx-runtime";
1
+ import { jsxs as c, jsx as t, Fragment as j } from "react/jsx-runtime";
2
2
  import * as w from "react";
3
- import { cva as j } 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 { useSavedProductsActions as M } from "../../hooks/user/useSavedProductsActions.js";
6
- import { formatMoney as A } from "../../lib/formatMoney.js";
3
+ import { cva as O } 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 M } from "../../hooks/navigation/useShopNavigation.js";
5
+ import { useSavedProductsActions as D } from "../../hooks/user/useSavedProductsActions.js";
6
+ import { formatMoney as z } from "../../lib/formatMoney.js";
7
7
  import { cn as n } from "../../lib/utils.js";
8
- import { FavoriteButton as D } from "../atoms/favorite-button.js";
9
- import { Touchable as z } from "../atoms/touchable.js";
10
- import { Card as q, CardContent as B, CardAction as U } from "../ui/card.js";
11
- import _ 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";
12
- import { Root as E } 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";
13
- const G = j("", {
8
+ import { FavoriteButton as q } from "../atoms/favorite-button.js";
9
+ import { Touchable as T } from "../atoms/touchable.js";
10
+ import { Card as B, CardContent as U, CardAction as _ } from "../ui/card.js";
11
+ 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";
12
+ 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";
13
+ const H = O("", {
14
14
  variants: {
15
15
  layout: {
16
16
  horizontal: "w-full !flex-row items-center gap-3 px-4 py-3",
@@ -27,16 +27,16 @@ const G = j("", {
27
27
  discount: "none"
28
28
  }
29
29
  });
30
- function H({
31
- className: o,
32
- layout: e,
30
+ function J({
31
+ className: e,
32
+ layout: o,
33
33
  discount: r,
34
- asChild: i = !1,
34
+ asChild: a = !1,
35
35
  onPress: l,
36
- ...a
36
+ ...s
37
37
  }) {
38
38
  return /* @__PURE__ */ t(
39
- z,
39
+ T,
40
40
  {
41
41
  onClick: l,
42
42
  whileTap: { opacity: 0.7 },
@@ -44,22 +44,22 @@ function H({
44
44
  opacity: { type: "tween", duration: 0.08, ease: "easeInOut" }
45
45
  },
46
46
  children: /* @__PURE__ */ t(
47
- i ? E : q,
47
+ a ? G : B,
48
48
  {
49
49
  className: n(
50
- G({ layout: e, discount: r }),
50
+ H({ layout: o, discount: r }),
51
51
  "border-0 bg-white rounded-xl shadow-lg shadow-black/10",
52
- o
52
+ e
53
53
  ),
54
- ...a
54
+ ...s
55
55
  }
56
56
  )
57
57
  }
58
58
  );
59
59
  }
60
- function J({
61
- className: o,
62
- layout: e = "horizontal",
60
+ function K({
61
+ className: e,
62
+ layout: o = "horizontal",
63
63
  ...r
64
64
  }) {
65
65
  return /* @__PURE__ */ t(
@@ -68,32 +68,32 @@ function J({
68
68
  "data-slot": "product-link-image",
69
69
  className: n(
70
70
  "overflow-hidden rounded-md bg-muted",
71
- e === "horizontal" ? "h-16 w-16 flex-shrink-0" : "aspect-square w-full",
72
- o
71
+ o === "horizontal" ? "h-16 w-16 flex-shrink-0" : "aspect-square w-full",
72
+ e
73
73
  ),
74
74
  ...r
75
75
  }
76
76
  );
77
77
  }
78
- function K({
79
- className: o,
80
- layout: e = "horizontal",
78
+ function Q({
79
+ className: e,
80
+ layout: o = "horizontal",
81
81
  ...r
82
82
  }) {
83
83
  return /* @__PURE__ */ t(
84
- B,
84
+ U,
85
85
  {
86
86
  className: n(
87
- e === "horizontal" ? "flex-1 min-w-0 space-y-1 px-0 py-0" : "space-y-2",
88
- o
87
+ o === "horizontal" ? "flex-1 min-w-0 space-y-1 px-0 py-0" : "space-y-2",
88
+ e
89
89
  ),
90
90
  ...r
91
91
  }
92
92
  );
93
93
  }
94
- function Q({
95
- className: o,
96
- children: e,
94
+ function W({
95
+ className: e,
96
+ children: o,
97
97
  ...r
98
98
  }) {
99
99
  return /* @__PURE__ */ t(
@@ -102,188 +102,192 @@ function Q({
102
102
  "data-slot": "product-link-title",
103
103
  className: n(
104
104
  "text-sm font-medium leading-tight text-gray-900 truncate overflow-hidden whitespace-nowrap text-ellipsis",
105
- o
105
+ e
106
106
  ),
107
107
  ...r,
108
- children: e
108
+ children: o
109
109
  }
110
110
  );
111
111
  }
112
- function W({ className: o, ...e }) {
112
+ function X({ className: e, ...o }) {
113
113
  return /* @__PURE__ */ t(
114
114
  "div",
115
115
  {
116
116
  "data-slot": "product-link-price",
117
- className: n("flex items-center gap-2", o),
118
- ...e
117
+ className: n("flex items-center gap-2", e),
118
+ ...o
119
119
  }
120
120
  );
121
121
  }
122
- function X({
123
- className: o,
124
- ...e
122
+ function Y({
123
+ className: e,
124
+ ...o
125
125
  }) {
126
126
  return /* @__PURE__ */ t(
127
127
  "span",
128
128
  {
129
129
  "data-slot": "product-link-current-price",
130
- className: n("text-sm font-semibold text-gray-900", o),
131
- ...e
130
+ className: n("text-sm font-semibold text-gray-900", e),
131
+ ...o
132
132
  }
133
133
  );
134
134
  }
135
- function Y({
136
- className: o,
137
- ...e
135
+ function Z({
136
+ className: e,
137
+ ...o
138
138
  }) {
139
139
  return /* @__PURE__ */ t(
140
140
  "span",
141
141
  {
142
142
  "data-slot": "product-link-original-price",
143
- className: n("text-sm text-gray-500 line-through", o),
144
- ...e
143
+ className: n("text-sm text-gray-500 line-through", e),
144
+ ...o
145
145
  }
146
146
  );
147
147
  }
148
- function Z({
149
- className: o,
150
- ...e
148
+ function $({
149
+ className: e,
150
+ ...o
151
151
  }) {
152
152
  return /* @__PURE__ */ t(
153
153
  "span",
154
154
  {
155
155
  "data-slot": "product-link-discount-price",
156
- className: n("text-sm font-semibold text-red-600", o),
157
- ...e
156
+ className: n("text-sm font-semibold text-red-600", e),
157
+ ...o
158
158
  }
159
159
  );
160
160
  }
161
- function $({ className: o, ...e }) {
161
+ function tt({ className: e, ...o }) {
162
162
  return /* @__PURE__ */ t(
163
163
  "div",
164
164
  {
165
165
  "data-slot": "product-link-rating",
166
166
  className: n(
167
167
  "flex items-center gap-1 text-xs text-muted-foreground",
168
- o
168
+ e
169
169
  ),
170
- ...e
170
+ ...o
171
171
  }
172
172
  );
173
173
  }
174
- function tt({
175
- className: o,
176
- onPress: e,
174
+ function et({
175
+ className: e,
176
+ onPress: o,
177
177
  filled: r = !1,
178
- ...i
178
+ ...a
179
179
  }) {
180
180
  return /* @__PURE__ */ t(
181
- U,
181
+ _,
182
182
  {
183
- className: n("flex-shrink-0 self-center px-0 py-0", o),
184
- ...i,
183
+ className: n("flex-shrink-0 self-center px-0 py-0", e),
184
+ ...a,
185
185
  children: /* @__PURE__ */ t(
186
- z,
186
+ T,
187
187
  {
188
188
  stopPropagation: !0,
189
- onClick: e,
189
+ onClick: o,
190
190
  whileTap: { opacity: 0.7, scale: 0.95 },
191
191
  transition: {
192
192
  opacity: { type: "tween", duration: 0.08, ease: "easeInOut" },
193
193
  scale: { type: "tween", duration: 0.08, ease: "easeInOut" }
194
194
  },
195
- children: /* @__PURE__ */ t(D, { filled: r, onClick: e })
195
+ children: /* @__PURE__ */ t(q, { filled: r, onClick: o })
196
196
  }
197
197
  )
198
198
  }
199
199
  );
200
200
  }
201
- function mt({ product: o, hideFavoriteAction: e = !1 }) {
202
- const { navigateToProduct: r } = O(), { saveProduct: i, unsaveProduct: l } = M(), {
203
- id: a,
204
- title: u,
205
- featuredImage: P,
201
+ function pt({
202
+ product: e,
203
+ hideFavoriteAction: o = !1,
204
+ onClick: r
205
+ }) {
206
+ const { navigateToProduct: a } = M(), { saveProduct: l, unsaveProduct: s } = D(), {
207
+ id: i,
208
+ title: P,
209
+ featuredImage: N,
206
210
  reviewAnalytics: C,
207
211
  price: m,
208
212
  compareAtPrice: p,
209
- isFavorited: T,
213
+ isFavorited: R,
210
214
  selectedVariant: f,
211
215
  defaultVariantId: h,
212
216
  shop: g
213
- } = o, [x, N] = w.useState(T), y = C?.averageRating, I = C?.reviewCount, v = m?.amount ? A(m?.amount, m?.currencyCode) : void 0, L = P?.url, R = P?.altText || u, k = p?.amount ? A(p?.amount, p?.currencyCode) : void 0, b = k && k !== v, S = w.useCallback(() => {
214
- r({
215
- productId: a
216
- });
217
- }, [r, a]), V = w.useCallback(async () => {
218
- const s = x;
219
- N(!s);
217
+ } = e, [x, I] = w.useState(R), y = C?.averageRating, L = C?.reviewCount, v = m?.amount ? z(m?.amount, m?.currencyCode) : void 0, b = N?.url, S = N?.altText || P, k = p?.amount ? z(p?.amount, p?.currencyCode) : void 0, A = k && k !== v, V = w.useCallback(() => {
218
+ a({
219
+ productId: i
220
+ }), r?.(e);
221
+ }, [a, i, r, e]), F = w.useCallback(async () => {
222
+ const d = x;
223
+ I(!d);
220
224
  try {
221
- s ? await l({
222
- productId: a,
225
+ d ? await s({
226
+ productId: i,
223
227
  shopId: g.id,
224
228
  productVariantId: f?.id || h
225
- }) : await i({
226
- productId: a,
229
+ }) : await l({
230
+ productId: i,
227
231
  shopId: g.id,
228
232
  productVariantId: f?.id || h
229
233
  });
230
234
  } catch {
231
- N(s);
235
+ I(d);
232
236
  }
233
237
  }, [
234
238
  x,
235
- a,
239
+ i,
236
240
  g.id,
237
241
  f?.id,
238
242
  h,
239
- i,
240
- l
243
+ l,
244
+ s
241
245
  ]);
242
246
  return /* @__PURE__ */ c(
243
- H,
247
+ J,
244
248
  {
245
249
  layout: "horizontal",
246
- discount: b ? "small" : "none",
247
- onPress: S,
250
+ discount: A ? "small" : "none",
251
+ onPress: V,
248
252
  children: [
249
- /* @__PURE__ */ t(J, { layout: "horizontal", children: L ? /* @__PURE__ */ t(
253
+ /* @__PURE__ */ t(K, { layout: "horizontal", children: b ? /* @__PURE__ */ t(
250
254
  "img",
251
255
  {
252
- src: L,
253
- alt: R,
256
+ src: b,
257
+ alt: S,
254
258
  className: "h-full w-full object-cover"
255
259
  }
256
260
  ) : /* @__PURE__ */ t("div", { className: "h-full w-full bg-muted flex items-center justify-center text-muted-foreground text-xs", children: "No Image" }) }),
257
- /* @__PURE__ */ c(K, { layout: "horizontal", children: [
258
- /* @__PURE__ */ t(Q, { children: u }),
259
- I && y && /* @__PURE__ */ t($, { children: /* @__PURE__ */ c("div", { className: "flex items-center gap-1", children: [
260
- Array.from({ length: 5 }, (s, d) => /* @__PURE__ */ t(
261
- _,
261
+ /* @__PURE__ */ c(Q, { layout: "horizontal", children: [
262
+ /* @__PURE__ */ t(W, { children: P }),
263
+ L && y ? /* @__PURE__ */ t(tt, { children: /* @__PURE__ */ c("div", { className: "flex items-center gap-1", children: [
264
+ Array.from({ length: 5 }, (d, u) => /* @__PURE__ */ t(
265
+ E,
262
266
  {
263
- fill: d < Math.floor(y) ? "currentColor" : "none",
267
+ fill: u < Math.floor(y) ? "currentColor" : "none",
264
268
  className: n(
265
269
  "h-3 w-3",
266
- d < Math.floor(y) ? "text-primary" : "text-gray-300"
270
+ u < Math.floor(y) ? "text-primary" : "text-gray-300"
267
271
  )
268
272
  },
269
- d
273
+ u
270
274
  )),
271
275
  /* @__PURE__ */ c("span", { className: "text-xs text-gray-600 ml-1", children: [
272
276
  "(",
273
- I,
277
+ L,
274
278
  ")"
275
279
  ] })
276
- ] }) }),
277
- /* @__PURE__ */ t(W, { children: b ? /* @__PURE__ */ c(F, { children: [
278
- /* @__PURE__ */ t(Z, { children: v }),
279
- /* @__PURE__ */ t(Y, { children: k })
280
- ] }) : /* @__PURE__ */ t(X, { children: v }) })
280
+ ] }) }) : null,
281
+ /* @__PURE__ */ t(X, { children: A ? /* @__PURE__ */ c(j, { children: [
282
+ /* @__PURE__ */ t($, { children: v }),
283
+ /* @__PURE__ */ t(Z, { children: k })
284
+ ] }) : /* @__PURE__ */ t(Y, { children: v }) })
281
285
  ] }),
282
- e ? null : /* @__PURE__ */ t(
283
- tt,
286
+ o ? null : /* @__PURE__ */ t(
287
+ et,
284
288
  {
285
289
  filled: x,
286
- onPress: V
290
+ onPress: F
287
291
  }
288
292
  )
289
293
  ]
@@ -291,6 +295,6 @@ function mt({ product: o, hideFavoriteAction: e = !1 }) {
291
295
  );
292
296
  }
293
297
  export {
294
- mt as ProductLink
298
+ pt as ProductLink
295
299
  };
296
300
  //# sourceMappingURL=product-link.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"product-link.js","sources":["../../../src/components/commerce/product-link.tsx"],"sourcesContent":["import * as React from 'react'\n\nimport {type Product} 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 {useSavedProductsActions} from '../../hooks/user/useSavedProductsActions'\nimport {formatMoney} from '../../lib/formatMoney'\nimport {cn} from '../../lib/utils'\nimport {FavoriteButton} from '../atoms/favorite-button'\nimport {Touchable} from '../atoms/touchable'\nimport {Card, CardContent, CardAction} from '../ui/card'\n\nconst productLinkVariants = cva('', {\n variants: {\n layout: {\n horizontal: 'w-full !flex-row items-center gap-3 px-4 py-3',\n vertical: 'flex-col',\n },\n discount: {\n none: '',\n small: '',\n large: '',\n },\n },\n defaultVariants: {\n layout: 'horizontal',\n discount: 'none',\n },\n})\n\n// Primitive components (building blocks)\nexport interface ProductLinkRootProps\n extends React.ComponentProps<typeof Card>,\n VariantProps<typeof productLinkVariants> {\n layout?: 'horizontal' | 'vertical'\n asChild?: boolean\n onPress?: () => void\n}\n\nfunction ProductLinkRoot({\n className,\n layout,\n discount,\n asChild = false,\n onPress,\n ...props\n}: ProductLinkRootProps) {\n const Comp = asChild ? SlotPrimitive.Root : Card\n\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 <Comp\n className={cn(\n productLinkVariants({layout, discount}),\n 'border-0 bg-white rounded-xl shadow-lg shadow-black/10',\n className\n )}\n {...props}\n />\n </Touchable>\n )\n}\n\nfunction ProductLinkImage({\n className,\n layout = 'horizontal',\n ...props\n}: React.ComponentProps<'div'> & {layout?: 'horizontal' | 'vertical'}) {\n return (\n <div\n data-slot=\"product-link-image\"\n className={cn(\n 'overflow-hidden rounded-md bg-muted',\n layout === 'horizontal'\n ? 'h-16 w-16 flex-shrink-0'\n : 'aspect-square w-full',\n className\n )}\n {...props}\n />\n )\n}\n\nfunction ProductLinkInfo({\n className,\n layout = 'horizontal',\n ...props\n}: React.ComponentProps<typeof CardContent> & {\n layout?: 'horizontal' | 'vertical'\n}) {\n return (\n <CardContent\n className={cn(\n layout === 'horizontal'\n ? 'flex-1 min-w-0 space-y-1 px-0 py-0'\n : 'space-y-2',\n className\n )}\n {...props}\n />\n )\n}\n\nfunction ProductLinkTitle({\n className,\n children,\n ...props\n}: React.ComponentProps<'h3'>) {\n return (\n <h3\n data-slot=\"product-link-title\"\n className={cn(\n 'text-sm font-medium leading-tight text-gray-900 truncate overflow-hidden whitespace-nowrap text-ellipsis',\n className\n )}\n {...props}\n >\n {children}\n </h3>\n )\n}\n\nfunction ProductLinkPrice({className, ...props}: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"product-link-price\"\n className={cn('flex items-center gap-2', className)}\n {...props}\n />\n )\n}\n\nfunction ProductLinkCurrentPrice({\n className,\n ...props\n}: React.ComponentProps<'span'>) {\n return (\n <span\n data-slot=\"product-link-current-price\"\n className={cn('text-sm font-semibold text-gray-900', className)}\n {...props}\n />\n )\n}\n\nfunction ProductLinkOriginalPrice({\n className,\n ...props\n}: React.ComponentProps<'span'>) {\n return (\n <span\n data-slot=\"product-link-original-price\"\n className={cn('text-sm text-gray-500 line-through', className)}\n {...props}\n />\n )\n}\n\nfunction ProductLinkDiscountPrice({\n className,\n ...props\n}: React.ComponentProps<'span'>) {\n return (\n <span\n data-slot=\"product-link-discount-price\"\n className={cn('text-sm font-semibold text-red-600', className)}\n {...props}\n />\n )\n}\n\nfunction ProductLinkRating({className, ...props}: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"product-link-rating\"\n className={cn(\n 'flex items-center gap-1 text-xs text-muted-foreground',\n className\n )}\n {...props}\n />\n )\n}\n\nfunction ProductLinkActions({\n className,\n onPress,\n filled = false,\n ...props\n}: React.ComponentProps<typeof CardAction> & {\n onPress?: () => void\n filled?: boolean\n}) {\n return (\n <CardAction\n className={cn('flex-shrink-0 self-center px-0 py-0', className)}\n {...props}\n >\n <Touchable\n stopPropagation\n onClick={onPress}\n whileTap={{opacity: 0.7, scale: 0.95}}\n transition={{\n opacity: {type: 'tween', duration: 0.08, ease: 'easeInOut'},\n scale: {type: 'tween', duration: 0.08, ease: 'easeInOut'},\n }}\n >\n <FavoriteButton filled={filled} onClick={onPress} />\n </Touchable>\n </CardAction>\n )\n}\n\nexport interface ProductLinkProps {\n product: Product\n hideFavoriteAction?: boolean\n}\n\n// Composed ProductLink component\nfunction ProductLink({product, hideFavoriteAction = false}: ProductLinkProps) {\n const {navigateToProduct} = useShopNavigation()\n const {saveProduct, unsaveProduct} = useSavedProductsActions()\n\n const {\n id,\n title,\n featuredImage,\n reviewAnalytics,\n price,\n compareAtPrice,\n isFavorited,\n selectedVariant,\n defaultVariantId,\n shop,\n } = product\n\n // Local state for optimistic UI updates\n const [isFavoritedLocal, setIsFavoritedLocal] = React.useState(isFavorited)\n\n const averageRating = reviewAnalytics?.averageRating\n const reviewCount = reviewAnalytics?.reviewCount\n const amount = price?.amount\n ? formatMoney(price?.amount, price?.currencyCode)\n : undefined\n const imageUrl = featuredImage?.url\n const imageAltText = featuredImage?.altText || title\n const compareAtPriceAmount = compareAtPrice?.amount\n ? formatMoney(compareAtPrice?.amount, compareAtPrice?.currencyCode)\n : undefined\n const hasDiscount = compareAtPriceAmount && compareAtPriceAmount !== amount\n\n const handlePress = React.useCallback(() => {\n navigateToProduct({\n productId: id,\n })\n }, [navigateToProduct, id])\n\n const handleActionPress = React.useCallback(async () => {\n const previousState = isFavoritedLocal\n\n // Optimistic update\n setIsFavoritedLocal(!previousState)\n\n try {\n if (previousState) {\n await unsaveProduct({\n productId: id,\n shopId: shop.id,\n productVariantId: selectedVariant?.id || defaultVariantId,\n })\n } else {\n await saveProduct({\n productId: id,\n shopId: shop.id,\n productVariantId: selectedVariant?.id || defaultVariantId,\n })\n }\n } catch (error) {\n // Revert optimistic update on error\n setIsFavoritedLocal(previousState)\n }\n }, [\n isFavoritedLocal,\n id,\n shop.id,\n selectedVariant?.id,\n defaultVariantId,\n saveProduct,\n unsaveProduct,\n ])\n\n return (\n <ProductLinkRoot\n layout=\"horizontal\"\n discount={hasDiscount ? 'small' : 'none'}\n onPress={handlePress}\n >\n <ProductLinkImage layout=\"horizontal\">\n {imageUrl ? (\n <img\n src={imageUrl}\n alt={imageAltText}\n className=\"h-full w-full object-cover\"\n />\n ) : (\n <div className=\"h-full w-full bg-muted flex items-center justify-center text-muted-foreground text-xs\">\n No Image\n </div>\n )}\n </ProductLinkImage>\n\n <ProductLinkInfo layout=\"horizontal\">\n <ProductLinkTitle>{title}</ProductLinkTitle>\n\n {reviewCount && averageRating && (\n <ProductLinkRating>\n <div className=\"flex items-center gap-1\">\n {Array.from({length: 5}, (_, i) => (\n <Star\n key={i}\n fill={\n i < Math.floor(averageRating!) ? 'currentColor' : 'none'\n }\n className={cn(\n 'h-3 w-3',\n i < Math.floor(averageRating!)\n ? 'text-primary'\n : 'text-gray-300'\n )}\n />\n ))}\n <span className=\"text-xs text-gray-600 ml-1\">\n ({reviewCount})\n </span>\n </div>\n </ProductLinkRating>\n )}\n\n <ProductLinkPrice>\n {hasDiscount ? (\n <>\n <ProductLinkDiscountPrice>{amount}</ProductLinkDiscountPrice>\n <ProductLinkOriginalPrice>\n {compareAtPriceAmount}\n </ProductLinkOriginalPrice>\n </>\n ) : (\n <ProductLinkCurrentPrice>{amount}</ProductLinkCurrentPrice>\n )}\n </ProductLinkPrice>\n </ProductLinkInfo>\n\n {hideFavoriteAction ? null : (\n <ProductLinkActions\n filled={isFavoritedLocal}\n onPress={handleActionPress}\n />\n )}\n </ProductLinkRoot>\n )\n}\n\nexport {ProductLink}\n"],"names":["productLinkVariants","cva","ProductLinkRoot","className","layout","discount","asChild","onPress","props","jsx","Touchable","SlotPrimitive.Root","Card","cn","ProductLinkImage","ProductLinkInfo","CardContent","ProductLinkTitle","children","ProductLinkPrice","ProductLinkCurrentPrice","ProductLinkOriginalPrice","ProductLinkDiscountPrice","ProductLinkRating","ProductLinkActions","filled","CardAction","FavoriteButton","ProductLink","product","hideFavoriteAction","navigateToProduct","useShopNavigation","saveProduct","unsaveProduct","useSavedProductsActions","id","title","featuredImage","reviewAnalytics","price","compareAtPrice","isFavorited","selectedVariant","defaultVariantId","shop","isFavoritedLocal","setIsFavoritedLocal","React","averageRating","reviewCount","amount","formatMoney","imageUrl","imageAltText","compareAtPriceAmount","hasDiscount","handlePress","handleActionPress","previousState","jsxs","_","i","Star","Fragment"],"mappings":"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"}
1
+ {"version":3,"file":"product-link.js","sources":["../../../src/components/commerce/product-link.tsx"],"sourcesContent":["import * as React from 'react'\n\nimport {type Product} 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 {useSavedProductsActions} from '../../hooks/user/useSavedProductsActions'\nimport {formatMoney} from '../../lib/formatMoney'\nimport {cn} from '../../lib/utils'\nimport {FavoriteButton} from '../atoms/favorite-button'\nimport {Touchable} from '../atoms/touchable'\nimport {Card, CardContent, CardAction} from '../ui/card'\n\nconst productLinkVariants = cva('', {\n variants: {\n layout: {\n horizontal: 'w-full !flex-row items-center gap-3 px-4 py-3',\n vertical: 'flex-col',\n },\n discount: {\n none: '',\n small: '',\n large: '',\n },\n },\n defaultVariants: {\n layout: 'horizontal',\n discount: 'none',\n },\n})\n\n// Primitive components (building blocks)\nexport interface ProductLinkRootProps\n extends React.ComponentProps<typeof Card>,\n VariantProps<typeof productLinkVariants> {\n layout?: 'horizontal' | 'vertical'\n asChild?: boolean\n onPress?: () => void\n}\n\nfunction ProductLinkRoot({\n className,\n layout,\n discount,\n asChild = false,\n onPress,\n ...props\n}: ProductLinkRootProps) {\n const Comp = asChild ? SlotPrimitive.Root : Card\n\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 <Comp\n className={cn(\n productLinkVariants({layout, discount}),\n 'border-0 bg-white rounded-xl shadow-lg shadow-black/10',\n className\n )}\n {...props}\n />\n </Touchable>\n )\n}\n\nfunction ProductLinkImage({\n className,\n layout = 'horizontal',\n ...props\n}: React.ComponentProps<'div'> & {layout?: 'horizontal' | 'vertical'}) {\n return (\n <div\n data-slot=\"product-link-image\"\n className={cn(\n 'overflow-hidden rounded-md bg-muted',\n layout === 'horizontal'\n ? 'h-16 w-16 flex-shrink-0'\n : 'aspect-square w-full',\n className\n )}\n {...props}\n />\n )\n}\n\nfunction ProductLinkInfo({\n className,\n layout = 'horizontal',\n ...props\n}: React.ComponentProps<typeof CardContent> & {\n layout?: 'horizontal' | 'vertical'\n}) {\n return (\n <CardContent\n className={cn(\n layout === 'horizontal'\n ? 'flex-1 min-w-0 space-y-1 px-0 py-0'\n : 'space-y-2',\n className\n )}\n {...props}\n />\n )\n}\n\nfunction ProductLinkTitle({\n className,\n children,\n ...props\n}: React.ComponentProps<'h3'>) {\n return (\n <h3\n data-slot=\"product-link-title\"\n className={cn(\n 'text-sm font-medium leading-tight text-gray-900 truncate overflow-hidden whitespace-nowrap text-ellipsis',\n className\n )}\n {...props}\n >\n {children}\n </h3>\n )\n}\n\nfunction ProductLinkPrice({className, ...props}: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"product-link-price\"\n className={cn('flex items-center gap-2', className)}\n {...props}\n />\n )\n}\n\nfunction ProductLinkCurrentPrice({\n className,\n ...props\n}: React.ComponentProps<'span'>) {\n return (\n <span\n data-slot=\"product-link-current-price\"\n className={cn('text-sm font-semibold text-gray-900', className)}\n {...props}\n />\n )\n}\n\nfunction ProductLinkOriginalPrice({\n className,\n ...props\n}: React.ComponentProps<'span'>) {\n return (\n <span\n data-slot=\"product-link-original-price\"\n className={cn('text-sm text-gray-500 line-through', className)}\n {...props}\n />\n )\n}\n\nfunction ProductLinkDiscountPrice({\n className,\n ...props\n}: React.ComponentProps<'span'>) {\n return (\n <span\n data-slot=\"product-link-discount-price\"\n className={cn('text-sm font-semibold text-red-600', className)}\n {...props}\n />\n )\n}\n\nfunction ProductLinkRating({className, ...props}: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"product-link-rating\"\n className={cn(\n 'flex items-center gap-1 text-xs text-muted-foreground',\n className\n )}\n {...props}\n />\n )\n}\n\nfunction ProductLinkActions({\n className,\n onPress,\n filled = false,\n ...props\n}: React.ComponentProps<typeof CardAction> & {\n onPress?: () => void\n filled?: boolean\n}) {\n return (\n <CardAction\n className={cn('flex-shrink-0 self-center px-0 py-0', className)}\n {...props}\n >\n <Touchable\n stopPropagation\n onClick={onPress}\n whileTap={{opacity: 0.7, scale: 0.95}}\n transition={{\n opacity: {type: 'tween', duration: 0.08, ease: 'easeInOut'},\n scale: {type: 'tween', duration: 0.08, ease: 'easeInOut'},\n }}\n >\n <FavoriteButton filled={filled} onClick={onPress} />\n </Touchable>\n </CardAction>\n )\n}\n\nexport interface ProductLinkProps {\n product: Product\n hideFavoriteAction?: boolean\n onClick?: (product: Product) => void\n}\n\n// Composed ProductLink component\nfunction ProductLink({\n product,\n hideFavoriteAction = false,\n onClick,\n}: ProductLinkProps) {\n const {navigateToProduct} = useShopNavigation()\n const {saveProduct, unsaveProduct} = useSavedProductsActions()\n\n const {\n id,\n title,\n featuredImage,\n reviewAnalytics,\n price,\n compareAtPrice,\n isFavorited,\n selectedVariant,\n defaultVariantId,\n shop,\n } = product\n\n // Local state for optimistic UI updates\n const [isFavoritedLocal, setIsFavoritedLocal] = React.useState(isFavorited)\n\n const averageRating = reviewAnalytics?.averageRating\n const reviewCount = reviewAnalytics?.reviewCount\n const amount = price?.amount\n ? formatMoney(price?.amount, price?.currencyCode)\n : undefined\n const imageUrl = featuredImage?.url\n const imageAltText = featuredImage?.altText || title\n const compareAtPriceAmount = compareAtPrice?.amount\n ? formatMoney(compareAtPrice?.amount, compareAtPrice?.currencyCode)\n : undefined\n const hasDiscount = compareAtPriceAmount && compareAtPriceAmount !== amount\n\n const handlePress = React.useCallback(() => {\n navigateToProduct({\n productId: id,\n })\n onClick?.(product)\n }, [navigateToProduct, id, onClick, product])\n\n const handleActionPress = React.useCallback(async () => {\n const previousState = isFavoritedLocal\n\n // Optimistic update\n setIsFavoritedLocal(!previousState)\n\n try {\n if (previousState) {\n await unsaveProduct({\n productId: id,\n shopId: shop.id,\n productVariantId: selectedVariant?.id || defaultVariantId,\n })\n } else {\n await saveProduct({\n productId: id,\n shopId: shop.id,\n productVariantId: selectedVariant?.id || defaultVariantId,\n })\n }\n } catch (error) {\n // Revert optimistic update on error\n setIsFavoritedLocal(previousState)\n }\n }, [\n isFavoritedLocal,\n id,\n shop.id,\n selectedVariant?.id,\n defaultVariantId,\n saveProduct,\n unsaveProduct,\n ])\n\n return (\n <ProductLinkRoot\n layout=\"horizontal\"\n discount={hasDiscount ? 'small' : 'none'}\n onPress={handlePress}\n >\n <ProductLinkImage layout=\"horizontal\">\n {imageUrl ? (\n <img\n src={imageUrl}\n alt={imageAltText}\n className=\"h-full w-full object-cover\"\n />\n ) : (\n <div className=\"h-full w-full bg-muted flex items-center justify-center text-muted-foreground text-xs\">\n No Image\n </div>\n )}\n </ProductLinkImage>\n\n <ProductLinkInfo layout=\"horizontal\">\n <ProductLinkTitle>{title}</ProductLinkTitle>\n\n {reviewCount && averageRating ? (\n <ProductLinkRating>\n <div className=\"flex items-center gap-1\">\n {Array.from({length: 5}, (_, i) => (\n <Star\n key={i}\n fill={\n i < Math.floor(averageRating!) ? 'currentColor' : 'none'\n }\n className={cn(\n 'h-3 w-3',\n i < Math.floor(averageRating!)\n ? 'text-primary'\n : 'text-gray-300'\n )}\n />\n ))}\n <span className=\"text-xs text-gray-600 ml-1\">\n ({reviewCount})\n </span>\n </div>\n </ProductLinkRating>\n ) : null}\n\n <ProductLinkPrice>\n {hasDiscount ? (\n <>\n <ProductLinkDiscountPrice>{amount}</ProductLinkDiscountPrice>\n <ProductLinkOriginalPrice>\n {compareAtPriceAmount}\n </ProductLinkOriginalPrice>\n </>\n ) : (\n <ProductLinkCurrentPrice>{amount}</ProductLinkCurrentPrice>\n )}\n </ProductLinkPrice>\n </ProductLinkInfo>\n\n {hideFavoriteAction ? null : (\n <ProductLinkActions\n filled={isFavoritedLocal}\n onPress={handleActionPress}\n />\n )}\n </ProductLinkRoot>\n )\n}\n\nexport {ProductLink}\n"],"names":["productLinkVariants","cva","ProductLinkRoot","className","layout","discount","asChild","onPress","props","jsx","Touchable","SlotPrimitive.Root","Card","cn","ProductLinkImage","ProductLinkInfo","CardContent","ProductLinkTitle","children","ProductLinkPrice","ProductLinkCurrentPrice","ProductLinkOriginalPrice","ProductLinkDiscountPrice","ProductLinkRating","ProductLinkActions","filled","CardAction","FavoriteButton","ProductLink","product","hideFavoriteAction","onClick","navigateToProduct","useShopNavigation","saveProduct","unsaveProduct","useSavedProductsActions","id","title","featuredImage","reviewAnalytics","price","compareAtPrice","isFavorited","selectedVariant","defaultVariantId","shop","isFavoritedLocal","setIsFavoritedLocal","React","averageRating","reviewCount","amount","formatMoney","imageUrl","imageAltText","compareAtPriceAmount","hasDiscount","handlePress","handleActionPress","previousState","jsxs","_","i","Star","Fragment"],"mappings":"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"}
@@ -1,15 +1,15 @@
1
1
  import { jsx as e, jsxs as g } from "react/jsx-runtime";
2
- import { useState as P, useCallback as y, createContext as k, useContext as L } from "react";
2
+ import { useState as k, useCallback as y, createContext as P, useContext as L } from "react";
3
3
  import { useProductSearch as T } from "../../hooks/product/useProductSearch.js";
4
4
  import { cn as p } from "../../lib/utils.js";
5
5
  import { IconButton as E } from "../atoms/icon-button.js";
6
6
  import { List as _ } from "../atoms/list.js";
7
7
  import { Input as j } from "../ui/input.js";
8
8
  import { ProductLink as v } from "./product-link.js";
9
- import { ProductLinkSkeleton as u } from "./product-link-skeleton.js";
9
+ import { ProductLinkSkeleton as m } from "./product-link-skeleton.js";
10
10
  import z from "../../shop-minis-react/node_modules/.pnpm/lucide-react@0.513.0_react@19.1.0/node_modules/lucide-react/dist/esm/icons/search.js";
11
11
  import M from "../../shop-minis-react/node_modules/.pnpm/lucide-react@0.513.0_react@19.1.0/node_modules/lucide-react/dist/esm/icons/x.js";
12
- const Q = 100, S = k(null);
12
+ const Q = 100, S = P(null);
13
13
  function N() {
14
14
  const t = L(S);
15
15
  if (!t)
@@ -17,20 +17,20 @@ function N() {
17
17
  return t;
18
18
  }
19
19
  function q({ initialQuery: t = "", children: i }) {
20
- const [r, a] = P(t), { products: o, loading: s, error: n, fetchMore: c, hasNextPage: l, isTyping: d } = T({
20
+ const [r, a] = k(t), { products: o, loading: s, error: n, fetchMore: c, hasNextPage: d, isTyping: l } = T({
21
21
  query: r,
22
22
  fetchPolicy: "network-only"
23
- }), m = y((f) => {
23
+ }), u = y((f) => {
24
24
  a(f);
25
25
  }, []), h = {
26
26
  query: r,
27
- setQuery: m,
27
+ setQuery: u,
28
28
  products: o,
29
29
  loading: s,
30
30
  error: n,
31
31
  fetchMore: c,
32
- hasNextPage: l,
33
- isTyping: d
32
+ hasNextPage: d,
33
+ isTyping: l
34
34
  };
35
35
  return /* @__PURE__ */ e(S.Provider, { value: h, children: i });
36
36
  }
@@ -92,12 +92,12 @@ function F({
92
92
  showScrollbar: o,
93
93
  overscanCount: s = 5
94
94
  }) {
95
- const { query: n, products: c, loading: l, fetchMore: d, hasNextPage: m, isTyping: h } = N(), f = (x, I) => i ? i(x, I) : /* @__PURE__ */ e("div", { className: "p-2", children: /* @__PURE__ */ e(v, { product: x, hideFavoriteAction: !0 }, x.id) }), b = n.trim().length === 0, w = (!c || c.length === 0) && (l || h), C = (!c || c.length === 0) && !l;
95
+ const { query: n, products: c, loading: d, fetchMore: l, hasNextPage: u, isTyping: h } = N(), f = (x, I) => i ? i(x, I) : /* @__PURE__ */ e("div", { className: "p-2", children: /* @__PURE__ */ e(v, { product: x, hideFavoriteAction: !0 }, x.id) }), b = n.trim().length === 0, w = (!c || c.length === 0) && (d || h), C = (!c || c.length === 0) && !d;
96
96
  return b ? a || /* @__PURE__ */ e("div", { className: "flex items-center justify-center h-32 text-gray-500", children: "Start typing to search for products" }) : w ? /* @__PURE__ */ g("div", { className: "flex flex-col px-4 py-4", children: [
97
- /* @__PURE__ */ e(u, { className: "mb-4" }),
98
- /* @__PURE__ */ e(u, { className: "mb-4" }),
99
- /* @__PURE__ */ e(u, { className: "mb-4" }),
100
- /* @__PURE__ */ e(u, { className: "mb-4" })
97
+ /* @__PURE__ */ e(m, { className: "mb-4" }),
98
+ /* @__PURE__ */ e(m, { className: "mb-4" }),
99
+ /* @__PURE__ */ e(m, { className: "mb-4" }),
100
+ /* @__PURE__ */ e(m, { className: "mb-4" })
101
101
  ] }) : C ? /* @__PURE__ */ e("div", { className: "flex items-center justify-center h-32 text-gray-500", children: `No products found for "${n}"` }) : /* @__PURE__ */ e(
102
102
  _,
103
103
  {
@@ -105,7 +105,7 @@ function F({
105
105
  height: t,
106
106
  renderItem: f,
107
107
  itemSizeForRow: () => r,
108
- fetchMore: m ? d : void 0,
108
+ fetchMore: u ? l : void 0,
109
109
  showScrollbar: o,
110
110
  overscanCount: s
111
111
  }
@@ -118,9 +118,18 @@ function J({
118
118
  height: a,
119
119
  className: o,
120
120
  renderItem: s,
121
- itemHeight: n
121
+ itemHeight: n,
122
+ onProductClick: c
122
123
  }) {
123
- const c = (l, d) => s ? s(l, d) : /* @__PURE__ */ e("div", { className: "p-2", children: /* @__PURE__ */ e(v, { product: l, hideFavoriteAction: !0 }, l.id) });
124
+ const d = (l, u) => s ? s(l, u) : /* @__PURE__ */ e("div", { className: "p-2", children: /* @__PURE__ */ e(
125
+ v,
126
+ {
127
+ product: l,
128
+ hideFavoriteAction: !0,
129
+ onClick: c
130
+ },
131
+ l.id
132
+ ) });
124
133
  return /* @__PURE__ */ e(q, { initialQuery: t, children: /* @__PURE__ */ g("div", { className: p("flex flex-col ", o), children: [
125
134
  /* @__PURE__ */ e("div", { className: "fixed top-0 left-0 right-0 p-4 w-full z-20 bg-background", children: /* @__PURE__ */ e(A, { placeholder: i, inputProps: r }) }),
126
135
  /* @__PURE__ */ e("div", { className: "h-14" }),
@@ -128,7 +137,7 @@ function J({
128
137
  F,
129
138
  {
130
139
  height: a,
131
- renderItem: c,
140
+ renderItem: d,
132
141
  itemHeight: n,
133
142
  showScrollbar: !0
134
143
  }