@shopify/shop-minis-react 0.0.25 → 0.0.26
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.
- package/dist/_virtual/index10.js +2 -2
- package/dist/_virtual/index4.js +2 -3
- package/dist/_virtual/index4.js.map +1 -1
- package/dist/_virtual/index7.js +3 -2
- package/dist/_virtual/index7.js.map +1 -1
- package/dist/_virtual/index9.js +2 -2
- package/dist/components/atoms/product-variant-price.js +61 -0
- package/dist/components/atoms/product-variant-price.js.map +1 -0
- package/dist/components/commerce/product-card.js +120 -153
- package/dist/components/commerce/product-card.js.map +1 -1
- package/dist/components/commerce/product-link.js +12 -16
- package/dist/components/commerce/product-link.js.map +1 -1
- package/dist/components/content/content-monitor.js +17 -0
- package/dist/components/content/content-monitor.js.map +1 -0
- package/dist/components/content/content-wrapper.js +17 -0
- package/dist/components/content/content-wrapper.js.map +1 -0
- package/dist/hooks/content/useContent.js +24 -0
- package/dist/hooks/content/useContent.js.map +1 -0
- package/dist/hooks/content/useCreateImageContent.js +21 -18
- package/dist/hooks/content/useCreateImageContent.js.map +1 -1
- package/dist/index.js +227 -223
- package/dist/index.js.map +1 -1
- package/dist/mocks.js +21 -6
- package/dist/mocks.js.map +1 -1
- package/dist/shop-minis-platform/src/types/content.js +5 -0
- package/dist/shop-minis-platform/src/types/content.js.map +1 -0
- 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
- package/dist/shop-minis-react/node_modules/.pnpm/@xmldom_xmldom@0.8.10/node_modules/@xmldom/xmldom/lib/index.js +1 -1
- package/dist/shop-minis-react/node_modules/.pnpm/querystringify@2.2.0/node_modules/querystringify/index.js +1 -1
- package/dist/shop-minis-react/node_modules/.pnpm/use-sync-external-store@1.5.0_react@19.1.0/node_modules/use-sync-external-store/shim/index.js +1 -1
- package/package.json +5 -4
- package/src/components/atoms/product-variant-price.tsx +74 -0
- package/src/components/commerce/product-card.tsx +7 -56
- package/src/components/commerce/product-link.tsx +0 -2
- package/src/components/content/content-monitor.tsx +23 -0
- package/src/components/content/content-wrapper.tsx +56 -0
- package/src/components/index.ts +2 -0
- package/src/hooks/content/useContent.ts +50 -0
- package/src/hooks/content/useCreateImageContent.ts +20 -5
- package/src/mocks.ts +15 -0
- package/src/stories/ProductVariantPrice.stories.tsx +73 -0
- package/src/stories/Toaster.stories.tsx +2 -2
package/dist/_virtual/index10.js
CHANGED
package/dist/_virtual/index4.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
var i = r();
|
|
1
|
+
var r = {};
|
|
3
2
|
export {
|
|
4
|
-
|
|
3
|
+
r as __exports
|
|
5
4
|
};
|
|
6
5
|
//# sourceMappingURL=index4.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index4.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index4.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|
package/dist/_virtual/index7.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
import { __require as r } from "../shop-minis-react/node_modules/.pnpm/use-sync-external-store@1.5.0_react@19.1.0/node_modules/use-sync-external-store/shim/index.js";
|
|
2
|
+
var i = r();
|
|
2
3
|
export {
|
|
3
|
-
|
|
4
|
+
i as s
|
|
4
5
|
};
|
|
5
6
|
//# sourceMappingURL=index7.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index7.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index7.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
|
package/dist/_virtual/index9.js
CHANGED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { jsx as n, jsxs as d, Fragment as c } from "react/jsx-runtime";
|
|
2
|
+
import { formatMoney as a } from "../../lib/formatMoney.js";
|
|
3
|
+
import { cn as i } from "../../lib/utils.js";
|
|
4
|
+
function b({
|
|
5
|
+
amount: r,
|
|
6
|
+
currencyCode: t,
|
|
7
|
+
compareAtPriceAmount: s,
|
|
8
|
+
compareAtPriceCurrencyCode: o,
|
|
9
|
+
currentPriceClassName: e,
|
|
10
|
+
originalPriceClassName: m,
|
|
11
|
+
containerClassName: x,
|
|
12
|
+
className: f
|
|
13
|
+
}) {
|
|
14
|
+
if (!r || !t)
|
|
15
|
+
return null;
|
|
16
|
+
const g = s && s !== r, l = String(r), h = s ? String(s) : void 0;
|
|
17
|
+
return /* @__PURE__ */ n(
|
|
18
|
+
"div",
|
|
19
|
+
{
|
|
20
|
+
className: i("flex items-center gap-2", x, f),
|
|
21
|
+
children: g ? /* @__PURE__ */ d(c, { children: [
|
|
22
|
+
/* @__PURE__ */ n(
|
|
23
|
+
"span",
|
|
24
|
+
{
|
|
25
|
+
className: i(
|
|
26
|
+
"text-sm font-semibold text-gray-900",
|
|
27
|
+
e
|
|
28
|
+
),
|
|
29
|
+
children: a(l, t)
|
|
30
|
+
}
|
|
31
|
+
),
|
|
32
|
+
/* @__PURE__ */ n(
|
|
33
|
+
"span",
|
|
34
|
+
{
|
|
35
|
+
className: i(
|
|
36
|
+
"text-sm text-gray-500 line-through",
|
|
37
|
+
m
|
|
38
|
+
),
|
|
39
|
+
children: a(
|
|
40
|
+
h,
|
|
41
|
+
o || t
|
|
42
|
+
)
|
|
43
|
+
}
|
|
44
|
+
)
|
|
45
|
+
] }) : /* @__PURE__ */ n(
|
|
46
|
+
"span",
|
|
47
|
+
{
|
|
48
|
+
className: i(
|
|
49
|
+
"text-sm font-semibold text-gray-900",
|
|
50
|
+
e
|
|
51
|
+
),
|
|
52
|
+
children: a(l, t)
|
|
53
|
+
}
|
|
54
|
+
)
|
|
55
|
+
}
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
export {
|
|
59
|
+
b as ProductVariantPrice
|
|
60
|
+
};
|
|
61
|
+
//# sourceMappingURL=product-variant-price.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"product-variant-price.js","sources":["../../../src/components/atoms/product-variant-price.tsx"],"sourcesContent":["import {formatMoney} from '../../lib/formatMoney'\nimport {cn} from '../../lib/utils'\n\nexport interface ProductVariantPriceProps {\n amount: number | string\n currencyCode?: string\n compareAtPriceAmount?: number | string\n compareAtPriceCurrencyCode?: string\n currentPriceClassName?: string\n originalPriceClassName?: string\n containerClassName?: string\n className?: string\n}\n\nexport function ProductVariantPrice({\n amount,\n currencyCode,\n compareAtPriceAmount,\n compareAtPriceCurrencyCode,\n currentPriceClassName,\n originalPriceClassName,\n containerClassName,\n className,\n}: ProductVariantPriceProps) {\n if (!amount || !currencyCode) {\n return null\n }\n\n const hasDiscount = compareAtPriceAmount && compareAtPriceAmount !== amount\n\n const amountStr = String(amount)\n const compareAtPriceAmountStr = compareAtPriceAmount\n ? String(compareAtPriceAmount)\n : undefined\n\n return (\n <div\n className={cn('flex items-center gap-2', containerClassName, className)}\n >\n {hasDiscount ? (\n <>\n <span\n className={cn(\n 'text-sm font-semibold text-gray-900',\n currentPriceClassName\n )}\n >\n {formatMoney(amountStr, currencyCode)}\n </span>\n <span\n className={cn(\n 'text-sm text-gray-500 line-through',\n originalPriceClassName\n )}\n >\n {formatMoney(\n compareAtPriceAmountStr!,\n compareAtPriceCurrencyCode || currencyCode\n )}\n </span>\n </>\n ) : (\n <span\n className={cn(\n 'text-sm font-semibold text-gray-900',\n currentPriceClassName\n )}\n >\n {formatMoney(amountStr, currencyCode)}\n </span>\n )}\n </div>\n )\n}\n"],"names":["ProductVariantPrice","amount","currencyCode","compareAtPriceAmount","compareAtPriceCurrencyCode","currentPriceClassName","originalPriceClassName","containerClassName","className","hasDiscount","amountStr","compareAtPriceAmountStr","jsx","cn","jsxs","Fragment","formatMoney"],"mappings":";;;AAcO,SAASA,EAAoB;AAAA,EAClC,QAAAC;AAAA,EACA,cAAAC;AAAA,EACA,sBAAAC;AAAA,EACA,4BAAAC;AAAA,EACA,uBAAAC;AAAA,EACA,wBAAAC;AAAA,EACA,oBAAAC;AAAA,EACA,WAAAC;AACF,GAA6B;AACvB,MAAA,CAACP,KAAU,CAACC;AACP,WAAA;AAGH,QAAAO,IAAcN,KAAwBA,MAAyBF,GAE/DS,IAAY,OAAOT,CAAM,GACzBU,IAA0BR,IAC5B,OAAOA,CAAoB,IAC3B;AAGF,SAAA,gBAAAS;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAWC,EAAG,2BAA2BN,GAAoBC,CAAS;AAAA,MAErE,cAEG,gBAAAM,EAAAC,GAAA,EAAA,UAAA;AAAA,QAAA,gBAAAH;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAWC;AAAA,cACT;AAAA,cACAR;AAAA,YACF;AAAA,YAEC,UAAAW,EAAYN,GAAWR,CAAY;AAAA,UAAA;AAAA,QACtC;AAAA,QACA,gBAAAU;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAWC;AAAA,cACT;AAAA,cACAP;AAAA,YACF;AAAA,YAEC,UAAAU;AAAA,cACCL;AAAA,cACAP,KAA8BF;AAAA,YAAA;AAAA,UAChC;AAAA,QAAA;AAAA,MACF,EAAA,CACF,IAEA,gBAAAU;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAWC;AAAA,YACT;AAAA,YACAR;AAAA,UACF;AAAA,UAEC,UAAAW,EAAYN,GAAWR,CAAY;AAAA,QAAA;AAAA,MAAA;AAAA,IACtC;AAAA,EAEJ;AAEJ;"}
|
|
@@ -1,17 +1,18 @@
|
|
|
1
|
-
import { jsxs as
|
|
2
|
-
import * as
|
|
3
|
-
import { useCallback as
|
|
4
|
-
import { cva as
|
|
5
|
-
import { useShopNavigation as
|
|
6
|
-
import { useSavedProductsActions as
|
|
7
|
-
import { formatMoney as
|
|
1
|
+
import { jsxs as y, jsx as e } from "react/jsx-runtime";
|
|
2
|
+
import * as g from "react";
|
|
3
|
+
import { useCallback as L } from "react";
|
|
4
|
+
import { cva as q } from "../../shop-minis-react/node_modules/.pnpm/class-variance-authority@0.7.1/node_modules/class-variance-authority/dist/index.js";
|
|
5
|
+
import { useShopNavigation as E } from "../../hooks/navigation/useShopNavigation.js";
|
|
6
|
+
import { useSavedProductsActions as M } from "../../hooks/user/useSavedProductsActions.js";
|
|
7
|
+
import { formatMoney as U } from "../../lib/formatMoney.js";
|
|
8
8
|
import { cn as c } from "../../lib/utils.js";
|
|
9
|
-
import { FavoriteButton as
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
|
|
9
|
+
import { FavoriteButton as V } from "../atoms/favorite-button.js";
|
|
10
|
+
import { ProductVariantPrice as D } from "../atoms/product-variant-price.js";
|
|
11
|
+
import { ThumbhashImage as G } from "../atoms/thumbhash-image.js";
|
|
12
|
+
import { Touchable as H } from "../atoms/touchable.js";
|
|
13
|
+
import { Badge as J } from "../ui/badge.js";
|
|
14
|
+
import { Root as K } 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";
|
|
15
|
+
const Q = q(
|
|
15
16
|
"relative w-full overflow-hidden rounded-xl border border-gray-200",
|
|
16
17
|
{
|
|
17
18
|
variants: {
|
|
@@ -31,27 +32,27 @@ const X = U(
|
|
|
31
32
|
}
|
|
32
33
|
}
|
|
33
34
|
);
|
|
34
|
-
function
|
|
35
|
-
className:
|
|
35
|
+
function W({
|
|
36
|
+
className: o,
|
|
36
37
|
variant: t,
|
|
37
|
-
touchable:
|
|
38
|
+
touchable: r = !0,
|
|
38
39
|
asChild: a = !1,
|
|
39
40
|
onPress: i,
|
|
40
41
|
...d
|
|
41
42
|
}) {
|
|
42
|
-
const n = /* @__PURE__ */
|
|
43
|
-
a ?
|
|
43
|
+
const n = /* @__PURE__ */ e(
|
|
44
|
+
a ? K : "div",
|
|
44
45
|
{
|
|
45
46
|
className: c(
|
|
46
|
-
|
|
47
|
+
Q({ variant: t, touchable: r }),
|
|
47
48
|
"border-0",
|
|
48
|
-
|
|
49
|
+
o
|
|
49
50
|
),
|
|
50
51
|
...d
|
|
51
52
|
}
|
|
52
53
|
);
|
|
53
|
-
return
|
|
54
|
-
|
|
54
|
+
return r && i ? /* @__PURE__ */ e(
|
|
55
|
+
H,
|
|
55
56
|
{
|
|
56
57
|
onClick: i,
|
|
57
58
|
whileTap: { opacity: 0.7 },
|
|
@@ -62,12 +63,12 @@ function Y({
|
|
|
62
63
|
}
|
|
63
64
|
) : n;
|
|
64
65
|
}
|
|
65
|
-
function
|
|
66
|
-
className:
|
|
66
|
+
function X({
|
|
67
|
+
className: o,
|
|
67
68
|
variant: t = "default",
|
|
68
|
-
...
|
|
69
|
+
...r
|
|
69
70
|
}) {
|
|
70
|
-
return /* @__PURE__ */
|
|
71
|
+
return /* @__PURE__ */ e(
|
|
71
72
|
"div",
|
|
72
73
|
{
|
|
73
74
|
"data-slot": "product-card-image-container",
|
|
@@ -77,237 +78,203 @@ function Z({
|
|
|
77
78
|
"relative overflow-hidden rounded-xl border border-gray-200",
|
|
78
79
|
"w-full aspect-square",
|
|
79
80
|
t === "compact" ? "min-h-[104px]" : "min-h-[134px]",
|
|
80
|
-
|
|
81
|
+
o
|
|
81
82
|
),
|
|
82
|
-
...
|
|
83
|
+
...r
|
|
83
84
|
}
|
|
84
85
|
);
|
|
85
86
|
}
|
|
86
|
-
function
|
|
87
|
-
className:
|
|
87
|
+
function Y({
|
|
88
|
+
className: o,
|
|
88
89
|
src: t,
|
|
89
|
-
alt:
|
|
90
|
+
alt: r,
|
|
90
91
|
aspectRatio: a,
|
|
91
92
|
thumbhash: i,
|
|
92
93
|
...d
|
|
93
94
|
}) {
|
|
94
|
-
const s =
|
|
95
|
-
(n) => i ? /* @__PURE__ */
|
|
96
|
-
|
|
95
|
+
const s = L(
|
|
96
|
+
(n) => i ? /* @__PURE__ */ e(
|
|
97
|
+
G,
|
|
97
98
|
{
|
|
98
99
|
"data-slot": "product-card-image",
|
|
99
100
|
src: n,
|
|
100
|
-
alt:
|
|
101
|
+
alt: r,
|
|
101
102
|
aspectRatio: a,
|
|
102
103
|
thumbhash: i,
|
|
103
|
-
className: c("w-full h-full object-cover",
|
|
104
|
+
className: c("w-full h-full object-cover", o),
|
|
104
105
|
...d
|
|
105
106
|
}
|
|
106
|
-
) : /* @__PURE__ */
|
|
107
|
+
) : /* @__PURE__ */ e(
|
|
107
108
|
"img",
|
|
108
109
|
{
|
|
109
110
|
"data-slot": "product-card-image",
|
|
110
111
|
src: n,
|
|
111
|
-
alt:
|
|
112
|
-
className: c("w-full h-full",
|
|
112
|
+
alt: r,
|
|
113
|
+
className: c("w-full h-full", o),
|
|
113
114
|
...d
|
|
114
115
|
}
|
|
115
116
|
),
|
|
116
|
-
[
|
|
117
|
+
[r, a, o, d, i]
|
|
117
118
|
);
|
|
118
|
-
return /* @__PURE__ */
|
|
119
|
+
return /* @__PURE__ */ e("div", { className: "bg-gray-100 flex items-center justify-center w-full h-full", children: t ? s(t) : /* @__PURE__ */ e("div", { className: "text-gray-400 text-sm w-full text-center", children: "No Image" }) });
|
|
119
120
|
}
|
|
120
|
-
function
|
|
121
|
-
className:
|
|
121
|
+
function k({
|
|
122
|
+
className: o,
|
|
122
123
|
position: t = "bottom-left",
|
|
123
|
-
children:
|
|
124
|
+
children: r,
|
|
124
125
|
...a
|
|
125
126
|
}) {
|
|
126
|
-
return /* @__PURE__ */
|
|
127
|
+
return /* @__PURE__ */ e(
|
|
127
128
|
"div",
|
|
128
129
|
{
|
|
129
130
|
className: c(
|
|
130
131
|
"absolute z-10",
|
|
131
132
|
t === "top-left" ? "top-3 left-3" : "bottom-2 left-2"
|
|
132
133
|
),
|
|
133
|
-
children: /* @__PURE__ */
|
|
134
|
-
|
|
134
|
+
children: /* @__PURE__ */ e(
|
|
135
|
+
J,
|
|
135
136
|
{
|
|
136
|
-
className: c("bg-black/50 text-white rounded",
|
|
137
|
+
className: c("bg-black/50 text-white rounded", o),
|
|
137
138
|
...a,
|
|
138
|
-
children:
|
|
139
|
+
children: r
|
|
139
140
|
}
|
|
140
141
|
)
|
|
141
142
|
}
|
|
142
143
|
);
|
|
143
144
|
}
|
|
144
|
-
function
|
|
145
|
-
className:
|
|
145
|
+
function Z({
|
|
146
|
+
className: o,
|
|
146
147
|
onPress: t,
|
|
147
|
-
filled:
|
|
148
|
+
filled: r = !1,
|
|
148
149
|
...a
|
|
149
150
|
}) {
|
|
150
|
-
return /* @__PURE__ */
|
|
151
|
+
return /* @__PURE__ */ e("div", { className: c("absolute bottom-3 right-3 z-10", o), ...a, children: /* @__PURE__ */ e(V, { onClick: t, filled: r }) });
|
|
151
152
|
}
|
|
152
|
-
function
|
|
153
|
-
className:
|
|
153
|
+
function _({
|
|
154
|
+
className: o,
|
|
154
155
|
variant: t = "default",
|
|
155
|
-
...
|
|
156
|
+
...r
|
|
156
157
|
}) {
|
|
157
|
-
return t !== "default" ? null : /* @__PURE__ */
|
|
158
|
+
return t !== "default" ? null : /* @__PURE__ */ e(
|
|
158
159
|
"div",
|
|
159
160
|
{
|
|
160
161
|
"data-slot": "product-card-info",
|
|
161
|
-
className: c("px-1 pt-2 pb-0 space-y-1",
|
|
162
|
-
...
|
|
162
|
+
className: c("px-1 pt-2 pb-0 space-y-1", o),
|
|
163
|
+
...r
|
|
163
164
|
}
|
|
164
165
|
);
|
|
165
166
|
}
|
|
166
|
-
function
|
|
167
|
-
className:
|
|
167
|
+
function $({
|
|
168
|
+
className: o,
|
|
168
169
|
children: t,
|
|
169
|
-
...
|
|
170
|
+
...r
|
|
170
171
|
}) {
|
|
171
|
-
return /* @__PURE__ */
|
|
172
|
+
return /* @__PURE__ */ e(
|
|
172
173
|
"h3",
|
|
173
174
|
{
|
|
174
175
|
"data-slot": "product-card-title",
|
|
175
176
|
className: c(
|
|
176
177
|
"text-sm font-medium leading-tight text-gray-900",
|
|
177
178
|
"truncate overflow-hidden whitespace-nowrap text-ellipsis",
|
|
178
|
-
|
|
179
|
+
o
|
|
179
180
|
),
|
|
180
|
-
...
|
|
181
|
+
...r,
|
|
181
182
|
children: t
|
|
182
183
|
}
|
|
183
184
|
);
|
|
184
185
|
}
|
|
185
|
-
function
|
|
186
|
-
|
|
187
|
-
"div",
|
|
188
|
-
{
|
|
189
|
-
"data-slot": "product-card-price",
|
|
190
|
-
className: c("flex items-center gap-2", e),
|
|
191
|
-
...t
|
|
192
|
-
}
|
|
193
|
-
);
|
|
194
|
-
}
|
|
195
|
-
function S({
|
|
196
|
-
className: e,
|
|
197
|
-
...t
|
|
198
|
-
}) {
|
|
199
|
-
return /* @__PURE__ */ r(
|
|
200
|
-
"span",
|
|
201
|
-
{
|
|
202
|
-
"data-slot": "product-card-current-price",
|
|
203
|
-
className: c("text-sm font-semibold text-gray-900", e),
|
|
204
|
-
...t
|
|
205
|
-
}
|
|
206
|
-
);
|
|
207
|
-
}
|
|
208
|
-
function ot({
|
|
209
|
-
className: e,
|
|
210
|
-
...t
|
|
211
|
-
}) {
|
|
212
|
-
return /* @__PURE__ */ r(
|
|
213
|
-
"span",
|
|
214
|
-
{
|
|
215
|
-
"data-slot": "product-card-original-price",
|
|
216
|
-
className: c("text-sm text-gray-500 line-through", e),
|
|
217
|
-
...t
|
|
218
|
-
}
|
|
219
|
-
);
|
|
220
|
-
}
|
|
221
|
-
function vt({
|
|
222
|
-
product: e,
|
|
186
|
+
function pt({
|
|
187
|
+
product: o,
|
|
223
188
|
selectedProductVariant: t,
|
|
224
|
-
variant:
|
|
189
|
+
variant: r = "default",
|
|
225
190
|
touchable: a = !0,
|
|
226
191
|
badgeText: i,
|
|
227
192
|
badgeVariant: d = "secondary",
|
|
228
193
|
onFavoriteToggled: s
|
|
229
194
|
}) {
|
|
230
|
-
const { navigateToProduct: n } =
|
|
195
|
+
const { navigateToProduct: n } = E(), { saveProduct: C, unsaveProduct: b } = M(), {
|
|
231
196
|
id: l,
|
|
232
|
-
title:
|
|
233
|
-
featuredImage:
|
|
234
|
-
price:
|
|
235
|
-
compareAtPrice:
|
|
236
|
-
isFavorited:
|
|
237
|
-
defaultVariantId:
|
|
238
|
-
shop:
|
|
239
|
-
} =
|
|
197
|
+
title: x,
|
|
198
|
+
featuredImage: I,
|
|
199
|
+
price: j,
|
|
200
|
+
compareAtPrice: S,
|
|
201
|
+
isFavorited: B,
|
|
202
|
+
defaultVariantId: m,
|
|
203
|
+
shop: f
|
|
204
|
+
} = o, P = t?.image || I, w = t?.price || j, N = t?.compareAtPrice || S, [p, A] = g.useState(B), h = w?.currencyCode, v = w?.amount, F = P?.url, T = P?.altText || x, O = N?.amount, R = g.useCallback(() => {
|
|
240
205
|
a && n({
|
|
241
206
|
productId: l
|
|
242
207
|
});
|
|
243
|
-
}, [n, l, a]),
|
|
244
|
-
const
|
|
245
|
-
|
|
208
|
+
}, [n, l, a]), z = g.useCallback(async () => {
|
|
209
|
+
const u = p;
|
|
210
|
+
A(!u), s?.(!u);
|
|
246
211
|
try {
|
|
247
|
-
|
|
212
|
+
u ? await b({
|
|
248
213
|
productId: l,
|
|
249
|
-
shopId:
|
|
250
|
-
productVariantId: t?.id ||
|
|
251
|
-
}) : await
|
|
214
|
+
shopId: f.id,
|
|
215
|
+
productVariantId: t?.id || m
|
|
216
|
+
}) : await C({
|
|
252
217
|
productId: l,
|
|
253
|
-
shopId:
|
|
254
|
-
productVariantId: t?.id ||
|
|
218
|
+
shopId: f.id,
|
|
219
|
+
productVariantId: t?.id || m
|
|
255
220
|
});
|
|
256
221
|
} catch {
|
|
257
|
-
|
|
222
|
+
A(u), s?.(u);
|
|
258
223
|
}
|
|
259
224
|
}, [
|
|
260
|
-
|
|
225
|
+
p,
|
|
261
226
|
l,
|
|
262
|
-
|
|
227
|
+
f.id,
|
|
263
228
|
t?.id,
|
|
264
|
-
|
|
265
|
-
|
|
229
|
+
m,
|
|
230
|
+
C,
|
|
266
231
|
b,
|
|
267
232
|
s
|
|
268
233
|
]);
|
|
269
|
-
return /* @__PURE__ */
|
|
270
|
-
|
|
234
|
+
return /* @__PURE__ */ y(
|
|
235
|
+
W,
|
|
271
236
|
{
|
|
272
|
-
variant:
|
|
237
|
+
variant: r,
|
|
273
238
|
touchable: a,
|
|
274
|
-
onPress:
|
|
239
|
+
onPress: R,
|
|
275
240
|
children: [
|
|
276
|
-
/* @__PURE__ */
|
|
277
|
-
/* @__PURE__ */
|
|
278
|
-
|
|
241
|
+
/* @__PURE__ */ y(X, { variant: r, children: [
|
|
242
|
+
/* @__PURE__ */ e(
|
|
243
|
+
Y,
|
|
279
244
|
{
|
|
280
|
-
src:
|
|
281
|
-
alt:
|
|
245
|
+
src: F,
|
|
246
|
+
alt: T,
|
|
282
247
|
aspectRatio: 1,
|
|
283
|
-
thumbhash:
|
|
248
|
+
thumbhash: I?.thumbhash ?? void 0
|
|
284
249
|
}
|
|
285
250
|
),
|
|
286
|
-
|
|
287
|
-
i && /* @__PURE__ */
|
|
288
|
-
/* @__PURE__ */
|
|
289
|
-
|
|
251
|
+
r === "priceOverlay" && h && v && /* @__PURE__ */ e(k, { position: "top-left", children: U(v, h) }),
|
|
252
|
+
i && /* @__PURE__ */ e(k, { position: "bottom-left", variant: d, children: i }),
|
|
253
|
+
/* @__PURE__ */ e(
|
|
254
|
+
Z,
|
|
290
255
|
{
|
|
291
|
-
filled:
|
|
292
|
-
onPress:
|
|
256
|
+
filled: p,
|
|
257
|
+
onPress: z
|
|
293
258
|
}
|
|
294
259
|
)
|
|
295
260
|
] }),
|
|
296
|
-
/* @__PURE__ */
|
|
297
|
-
/* @__PURE__ */
|
|
298
|
-
/* @__PURE__ */
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
261
|
+
/* @__PURE__ */ y(_, { variant: r, children: [
|
|
262
|
+
/* @__PURE__ */ e($, { children: x }),
|
|
263
|
+
/* @__PURE__ */ e(
|
|
264
|
+
D,
|
|
265
|
+
{
|
|
266
|
+
amount: v,
|
|
267
|
+
currencyCode: h,
|
|
268
|
+
compareAtPriceAmount: O,
|
|
269
|
+
compareAtPriceCurrencyCode: N?.currencyCode
|
|
270
|
+
}
|
|
271
|
+
)
|
|
305
272
|
] })
|
|
306
273
|
]
|
|
307
274
|
}
|
|
308
275
|
);
|
|
309
276
|
}
|
|
310
277
|
export {
|
|
311
|
-
|
|
278
|
+
pt as ProductCard
|
|
312
279
|
};
|
|
313
280
|
//# sourceMappingURL=product-card.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"product-card.js","sources":["../../../src/components/commerce/product-card.tsx"],"sourcesContent":["import * as React from 'react'\nimport {useCallback} from 'react'\n\nimport {type Product, type ProductVariant} from '@shopify/shop-minis-platform'\nimport {cva, type VariantProps} from 'class-variance-authority'\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 {ThumbhashImage} from '../atoms/thumbhash-image'\nimport {Touchable} from '../atoms/touchable'\nimport {Badge} from '../ui/badge'\n\nconst productCardVariants = cva(\n 'relative w-full overflow-hidden rounded-xl border border-gray-200',\n {\n variants: {\n variant: {\n default: '',\n priceOverlay: '',\n compact: '',\n },\n touchable: {\n true: 'cursor-pointer',\n false: '',\n },\n },\n defaultVariants: {\n variant: 'default',\n touchable: true,\n },\n }\n)\n\n// Primitive components (building blocks)\nexport interface ProductCardRootProps\n extends React.ComponentProps<'div'>,\n VariantProps<typeof productCardVariants> {\n variant?: 'default' | 'priceOverlay' | 'compact'\n touchable?: boolean\n asChild?: boolean\n onPress?: () => void\n}\n\nfunction ProductCardRoot({\n className,\n variant,\n touchable = true,\n asChild = false,\n onPress,\n ...props\n}: ProductCardRootProps) {\n const Comp = asChild ? SlotPrimitive.Slot : 'div'\n\n const content = (\n <Comp\n className={cn(\n productCardVariants({variant, touchable}),\n 'border-0',\n className\n )}\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 ProductCardImageContainer({\n className,\n variant = 'default',\n ...props\n}: React.ComponentProps<'div'> & {\n variant?: 'default' | 'priceOverlay' | 'compact'\n}) {\n return (\n <div\n data-slot=\"product-card-image-container\"\n className={cn(\n // Ensure the product image is stretched to the full size of the container (can't use width/height: 100% because of flex)\n 'flex justify-stretch items-stretch',\n 'relative overflow-hidden rounded-xl border border-gray-200',\n 'w-full aspect-square',\n variant === 'compact' ? 'min-h-[104px]' : 'min-h-[134px]',\n className\n )}\n {...props}\n />\n )\n}\n\nfunction ProductCardImage({\n className,\n src,\n alt,\n aspectRatio,\n thumbhash,\n ...props\n}: React.ComponentProps<'img'> & {\n src?: string\n alt?: string\n aspectRatio?: number\n thumbhash?: string\n}) {\n const renderImageElement = useCallback(\n (src: string) => {\n if (thumbhash) {\n return (\n <ThumbhashImage\n data-slot=\"product-card-image\"\n src={src}\n alt={alt}\n aspectRatio={aspectRatio}\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=\"product-card-image\"\n src={src}\n alt={alt}\n className={cn('w-full h-full', className)}\n {...props}\n />\n )\n },\n [alt, aspectRatio, className, props, thumbhash]\n )\n\n return (\n <div className=\"bg-gray-100 flex items-center justify-center w-full h-full\">\n {src ? (\n renderImageElement(src)\n ) : (\n <div className=\"text-gray-400 text-sm w-full text-center\">No Image</div>\n )}\n </div>\n )\n}\n\nfunction ProductCardBadge({\n className,\n position = 'bottom-left',\n children,\n ...props\n}: React.ComponentProps<typeof Badge> & {\n position?: 'top-left' | 'bottom-left'\n}) {\n return (\n <div\n className={cn(\n 'absolute z-10',\n position === 'top-left' ? 'top-3 left-3' : 'bottom-2 left-2'\n )}\n >\n <Badge\n className={cn('bg-black/50 text-white rounded', className)}\n {...props}\n >\n {children}\n </Badge>\n </div>\n )\n}\n\nfunction ProductCardFavoriteButton({\n className,\n onPress,\n filled = false,\n ...props\n}: React.ComponentProps<'div'> & {\n onPress?: () => void\n filled?: boolean\n}) {\n return (\n <div className={cn('absolute bottom-3 right-3 z-10', className)} {...props}>\n <FavoriteButton onClick={onPress} filled={filled} />\n </div>\n )\n}\n\nfunction ProductCardInfo({\n className,\n variant = 'default',\n ...props\n}: React.ComponentProps<'div'> & {\n variant?: 'default' | 'priceOverlay' | 'compact'\n}) {\n if (variant !== 'default') {\n return null\n }\n\n return (\n <div\n data-slot=\"product-card-info\"\n className={cn('px-1 pt-2 pb-0 space-y-1', className)}\n {...props}\n />\n )\n}\n\nfunction ProductCardTitle({\n className,\n children,\n ...props\n}: React.ComponentProps<'h3'>) {\n return (\n <h3\n data-slot=\"product-card-title\"\n className={cn(\n 'text-sm font-medium leading-tight text-gray-900',\n 'truncate overflow-hidden whitespace-nowrap text-ellipsis',\n className\n )}\n {...props}\n >\n {children}\n </h3>\n )\n}\n\nfunction ProductCardPrice({className, ...props}: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"product-card-price\"\n className={cn('flex items-center gap-2', className)}\n {...props}\n />\n )\n}\n\nfunction ProductCardCurrentPrice({\n className,\n ...props\n}: React.ComponentProps<'span'>) {\n return (\n <span\n data-slot=\"product-card-current-price\"\n className={cn('text-sm font-semibold text-gray-900', className)}\n {...props}\n />\n )\n}\n\nfunction ProductCardOriginalPrice({\n className,\n ...props\n}: React.ComponentProps<'span'>) {\n return (\n <span\n data-slot=\"product-card-original-price\"\n className={cn('text-sm text-gray-500 line-through', className)}\n {...props}\n />\n )\n}\n\nexport interface ProductCardProps {\n /** The product to display in the card */\n product: Product\n /** Optional selected variant of the product to show specific variant data */\n selectedProductVariant?: ProductVariant\n /** Visual style variant of the card */\n variant?: 'default' | 'priceOverlay' | 'compact'\n /** Whether the card can be clicked/tapped to navigate to product details */\n touchable?: boolean\n /** Optional text to display in a badge on the card */\n badgeText?: string\n /** Visual style variant for the badge */\n badgeVariant?: 'default' | 'secondary' | 'destructive' | 'outline'\n /** Callback fired when the favorite button is toggled */\n onFavoriteToggled?: (isFavorited: boolean) => void\n /** Optional ID for the section containing this card */\n sectionId?: string\n}\n\n// Composed ProductCard component\nfunction ProductCard({\n product,\n selectedProductVariant,\n variant = 'default',\n touchable = true,\n badgeText,\n badgeVariant = 'secondary',\n onFavoriteToggled,\n}: ProductCardProps) {\n const {navigateToProduct} = useShopNavigation()\n const {saveProduct, unsaveProduct} = useSavedProductsActions()\n\n const {\n id,\n title,\n featuredImage,\n price,\n compareAtPrice,\n isFavorited,\n defaultVariantId,\n shop,\n } = product\n\n // Use selected variant data if available\n const displayImage = selectedProductVariant?.image || featuredImage\n const displayPrice = selectedProductVariant?.price || price\n const displayCompareAtPrice =\n selectedProductVariant?.compareAtPrice || compareAtPrice\n\n // Local state for optimistic UI updates\n const [isFavoritedLocal, setIsFavoritedLocal] = React.useState(isFavorited)\n\n const currencyCode = displayPrice?.currencyCode\n const amount = displayPrice?.amount\n const imageUrl = displayImage?.url\n const imageAltText = displayImage?.altText || title\n const compareAtPriceAmount = displayCompareAtPrice?.amount\n const hasDiscount = compareAtPriceAmount && compareAtPriceAmount !== amount\n\n const handlePress = React.useCallback(() => {\n if (!touchable) return\n\n navigateToProduct({\n productId: id,\n })\n }, [navigateToProduct, id, touchable])\n\n const handleFavoritePress = React.useCallback(async () => {\n const previousState = isFavoritedLocal\n\n // Optimistic update\n setIsFavoritedLocal(!previousState)\n onFavoriteToggled?.(!previousState)\n\n try {\n if (previousState) {\n await unsaveProduct({\n productId: id,\n shopId: shop.id,\n productVariantId: selectedProductVariant?.id || defaultVariantId,\n })\n } else {\n await saveProduct({\n productId: id,\n shopId: shop.id,\n productVariantId: selectedProductVariant?.id || defaultVariantId,\n })\n }\n } catch (error) {\n // Revert optimistic update on error\n setIsFavoritedLocal(previousState)\n onFavoriteToggled?.(previousState)\n }\n }, [\n isFavoritedLocal,\n id,\n shop.id,\n selectedProductVariant?.id,\n defaultVariantId,\n saveProduct,\n unsaveProduct,\n onFavoriteToggled,\n ])\n\n return (\n <ProductCardRoot\n variant={variant}\n touchable={touchable}\n onPress={handlePress}\n >\n <ProductCardImageContainer variant={variant}>\n <ProductCardImage\n src={imageUrl}\n alt={imageAltText}\n aspectRatio={1}\n thumbhash={featuredImage?.thumbhash ?? undefined}\n />\n\n {/* Price overlay badge for priceOverlay variant */}\n {variant === 'priceOverlay' && currencyCode && amount && (\n <ProductCardBadge position=\"top-left\">\n {formatMoney(amount, currencyCode)}\n </ProductCardBadge>\n )}\n\n {/* Custom badge */}\n {badgeText && (\n <ProductCardBadge position=\"bottom-left\" variant={badgeVariant}>\n {badgeText}\n </ProductCardBadge>\n )}\n\n {/* Favorite button */}\n <ProductCardFavoriteButton\n filled={isFavoritedLocal}\n onPress={handleFavoritePress}\n />\n </ProductCardImageContainer>\n\n {/* Product info for default variant */}\n <ProductCardInfo variant={variant}>\n <ProductCardTitle>{title}</ProductCardTitle>\n\n <ProductCardPrice>\n {hasDiscount ? (\n <>\n <ProductCardCurrentPrice>\n {formatMoney(amount, currencyCode)}\n </ProductCardCurrentPrice>\n <ProductCardOriginalPrice>\n {formatMoney(\n compareAtPriceAmount,\n displayCompareAtPrice?.currencyCode || currencyCode\n )}\n </ProductCardOriginalPrice>\n </>\n ) : (\n <ProductCardCurrentPrice>\n {formatMoney(amount, currencyCode)}\n </ProductCardCurrentPrice>\n )}\n </ProductCardPrice>\n </ProductCardInfo>\n </ProductCardRoot>\n )\n}\n\nexport {ProductCard}\n"],"names":["productCardVariants","cva","ProductCardRoot","className","variant","touchable","asChild","onPress","props","content","jsx","SlotPrimitive.Slot","cn","Touchable","ProductCardImageContainer","ProductCardImage","src","alt","aspectRatio","thumbhash","renderImageElement","useCallback","ThumbhashImage","ProductCardBadge","position","children","Badge","ProductCardFavoriteButton","filled","FavoriteButton","ProductCardInfo","ProductCardTitle","ProductCardPrice","ProductCardCurrentPrice","ProductCardOriginalPrice","ProductCard","product","selectedProductVariant","badgeText","badgeVariant","onFavoriteToggled","navigateToProduct","useShopNavigation","saveProduct","unsaveProduct","useSavedProductsActions","id","title","featuredImage","price","compareAtPrice","isFavorited","defaultVariantId","shop","displayImage","displayPrice","displayCompareAtPrice","isFavoritedLocal","setIsFavoritedLocal","React","currencyCode","amount","imageUrl","imageAltText","compareAtPriceAmount","hasDiscount","handlePress","handleFavoritePress","previousState","jsxs","formatMoney","Fragment"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"product-card.js","sources":["../../../src/components/commerce/product-card.tsx"],"sourcesContent":["import * as React from 'react'\nimport {useCallback} from 'react'\n\nimport {type Product, type ProductVariant} from '@shopify/shop-minis-platform'\nimport {cva, type VariantProps} from 'class-variance-authority'\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 {ProductVariantPrice} from '../atoms/product-variant-price'\nimport {ThumbhashImage} from '../atoms/thumbhash-image'\nimport {Touchable} from '../atoms/touchable'\nimport {Badge} from '../ui/badge'\n\nconst productCardVariants = cva(\n 'relative w-full overflow-hidden rounded-xl border border-gray-200',\n {\n variants: {\n variant: {\n default: '',\n priceOverlay: '',\n compact: '',\n },\n touchable: {\n true: 'cursor-pointer',\n false: '',\n },\n },\n defaultVariants: {\n variant: 'default',\n touchable: true,\n },\n }\n)\n\n// Primitive components (building blocks)\nexport interface ProductCardRootProps\n extends React.ComponentProps<'div'>,\n VariantProps<typeof productCardVariants> {\n variant?: 'default' | 'priceOverlay' | 'compact'\n touchable?: boolean\n asChild?: boolean\n onPress?: () => void\n}\n\nfunction ProductCardRoot({\n className,\n variant,\n touchable = true,\n asChild = false,\n onPress,\n ...props\n}: ProductCardRootProps) {\n const Comp = asChild ? SlotPrimitive.Slot : 'div'\n\n const content = (\n <Comp\n className={cn(\n productCardVariants({variant, touchable}),\n 'border-0',\n className\n )}\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 ProductCardImageContainer({\n className,\n variant = 'default',\n ...props\n}: React.ComponentProps<'div'> & {\n variant?: 'default' | 'priceOverlay' | 'compact'\n}) {\n return (\n <div\n data-slot=\"product-card-image-container\"\n className={cn(\n // Ensure the product image is stretched to the full size of the container (can't use width/height: 100% because of flex)\n 'flex justify-stretch items-stretch',\n 'relative overflow-hidden rounded-xl border border-gray-200',\n 'w-full aspect-square',\n variant === 'compact' ? 'min-h-[104px]' : 'min-h-[134px]',\n className\n )}\n {...props}\n />\n )\n}\n\nfunction ProductCardImage({\n className,\n src,\n alt,\n aspectRatio,\n thumbhash,\n ...props\n}: React.ComponentProps<'img'> & {\n src?: string\n alt?: string\n aspectRatio?: number\n thumbhash?: string\n}) {\n const renderImageElement = useCallback(\n (src: string) => {\n if (thumbhash) {\n return (\n <ThumbhashImage\n data-slot=\"product-card-image\"\n src={src}\n alt={alt}\n aspectRatio={aspectRatio}\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=\"product-card-image\"\n src={src}\n alt={alt}\n className={cn('w-full h-full', className)}\n {...props}\n />\n )\n },\n [alt, aspectRatio, className, props, thumbhash]\n )\n\n return (\n <div className=\"bg-gray-100 flex items-center justify-center w-full h-full\">\n {src ? (\n renderImageElement(src)\n ) : (\n <div className=\"text-gray-400 text-sm w-full text-center\">No Image</div>\n )}\n </div>\n )\n}\n\nfunction ProductCardBadge({\n className,\n position = 'bottom-left',\n children,\n ...props\n}: React.ComponentProps<typeof Badge> & {\n position?: 'top-left' | 'bottom-left'\n}) {\n return (\n <div\n className={cn(\n 'absolute z-10',\n position === 'top-left' ? 'top-3 left-3' : 'bottom-2 left-2'\n )}\n >\n <Badge\n className={cn('bg-black/50 text-white rounded', className)}\n {...props}\n >\n {children}\n </Badge>\n </div>\n )\n}\n\nfunction ProductCardFavoriteButton({\n className,\n onPress,\n filled = false,\n ...props\n}: React.ComponentProps<'div'> & {\n onPress?: () => void\n filled?: boolean\n}) {\n return (\n <div className={cn('absolute bottom-3 right-3 z-10', className)} {...props}>\n <FavoriteButton onClick={onPress} filled={filled} />\n </div>\n )\n}\n\nfunction ProductCardInfo({\n className,\n variant = 'default',\n ...props\n}: React.ComponentProps<'div'> & {\n variant?: 'default' | 'priceOverlay' | 'compact'\n}) {\n if (variant !== 'default') {\n return null\n }\n\n return (\n <div\n data-slot=\"product-card-info\"\n className={cn('px-1 pt-2 pb-0 space-y-1', className)}\n {...props}\n />\n )\n}\n\nfunction ProductCardTitle({\n className,\n children,\n ...props\n}: React.ComponentProps<'h3'>) {\n return (\n <h3\n data-slot=\"product-card-title\"\n className={cn(\n 'text-sm font-medium leading-tight text-gray-900',\n 'truncate overflow-hidden whitespace-nowrap text-ellipsis',\n className\n )}\n {...props}\n >\n {children}\n </h3>\n )\n}\n\nexport interface ProductCardProps {\n /** The product to display in the card */\n product: Product\n /** Optional selected variant of the product to show specific variant data */\n selectedProductVariant?: ProductVariant\n /** Visual style variant of the card */\n variant?: 'default' | 'priceOverlay' | 'compact'\n /** Whether the card can be clicked/tapped to navigate to product details */\n touchable?: boolean\n /** Optional text to display in a badge on the card */\n badgeText?: string\n /** Visual style variant for the badge */\n badgeVariant?: 'default' | 'secondary' | 'destructive' | 'outline'\n /** Callback fired when the favorite button is toggled */\n onFavoriteToggled?: (isFavorited: boolean) => void\n /** Optional ID for the section containing this card */\n sectionId?: string\n}\n\n// Composed ProductCard component\nfunction ProductCard({\n product,\n selectedProductVariant,\n variant = 'default',\n touchable = true,\n badgeText,\n badgeVariant = 'secondary',\n onFavoriteToggled,\n}: ProductCardProps) {\n const {navigateToProduct} = useShopNavigation()\n const {saveProduct, unsaveProduct} = useSavedProductsActions()\n\n const {\n id,\n title,\n featuredImage,\n price,\n compareAtPrice,\n isFavorited,\n defaultVariantId,\n shop,\n } = product\n\n // Use selected variant data if available\n const displayImage = selectedProductVariant?.image || featuredImage\n const displayPrice = selectedProductVariant?.price || price\n const displayCompareAtPrice =\n selectedProductVariant?.compareAtPrice || compareAtPrice\n\n // Local state for optimistic UI updates\n const [isFavoritedLocal, setIsFavoritedLocal] = React.useState(isFavorited)\n\n const currencyCode = displayPrice?.currencyCode\n const amount = displayPrice?.amount\n const imageUrl = displayImage?.url\n const imageAltText = displayImage?.altText || title\n const compareAtPriceAmount = displayCompareAtPrice?.amount\n\n const handlePress = React.useCallback(() => {\n if (!touchable) return\n\n navigateToProduct({\n productId: id,\n })\n }, [navigateToProduct, id, touchable])\n\n const handleFavoritePress = React.useCallback(async () => {\n const previousState = isFavoritedLocal\n\n // Optimistic update\n setIsFavoritedLocal(!previousState)\n onFavoriteToggled?.(!previousState)\n\n try {\n if (previousState) {\n await unsaveProduct({\n productId: id,\n shopId: shop.id,\n productVariantId: selectedProductVariant?.id || defaultVariantId,\n })\n } else {\n await saveProduct({\n productId: id,\n shopId: shop.id,\n productVariantId: selectedProductVariant?.id || defaultVariantId,\n })\n }\n } catch (error) {\n // Revert optimistic update on error\n setIsFavoritedLocal(previousState)\n onFavoriteToggled?.(previousState)\n }\n }, [\n isFavoritedLocal,\n id,\n shop.id,\n selectedProductVariant?.id,\n defaultVariantId,\n saveProduct,\n unsaveProduct,\n onFavoriteToggled,\n ])\n\n return (\n <ProductCardRoot\n variant={variant}\n touchable={touchable}\n onPress={handlePress}\n >\n <ProductCardImageContainer variant={variant}>\n <ProductCardImage\n src={imageUrl}\n alt={imageAltText}\n aspectRatio={1}\n thumbhash={featuredImage?.thumbhash ?? undefined}\n />\n\n {/* Price overlay badge for priceOverlay variant */}\n {variant === 'priceOverlay' && currencyCode && amount && (\n <ProductCardBadge position=\"top-left\">\n {formatMoney(amount, currencyCode)}\n </ProductCardBadge>\n )}\n\n {/* Custom badge */}\n {badgeText && (\n <ProductCardBadge position=\"bottom-left\" variant={badgeVariant}>\n {badgeText}\n </ProductCardBadge>\n )}\n\n {/* Favorite button */}\n <ProductCardFavoriteButton\n filled={isFavoritedLocal}\n onPress={handleFavoritePress}\n />\n </ProductCardImageContainer>\n\n {/* Product info for default variant */}\n <ProductCardInfo variant={variant}>\n <ProductCardTitle>{title}</ProductCardTitle>\n\n <ProductVariantPrice\n amount={amount}\n currencyCode={currencyCode}\n compareAtPriceAmount={compareAtPriceAmount}\n compareAtPriceCurrencyCode={displayCompareAtPrice?.currencyCode}\n />\n </ProductCardInfo>\n </ProductCardRoot>\n )\n}\n\nexport {ProductCard}\n"],"names":["productCardVariants","cva","ProductCardRoot","className","variant","touchable","asChild","onPress","props","content","jsx","SlotPrimitive.Slot","cn","Touchable","ProductCardImageContainer","ProductCardImage","src","alt","aspectRatio","thumbhash","renderImageElement","useCallback","ThumbhashImage","ProductCardBadge","position","children","Badge","ProductCardFavoriteButton","filled","FavoriteButton","ProductCardInfo","ProductCardTitle","ProductCard","product","selectedProductVariant","badgeText","badgeVariant","onFavoriteToggled","navigateToProduct","useShopNavigation","saveProduct","unsaveProduct","useSavedProductsActions","id","title","featuredImage","price","compareAtPrice","isFavorited","defaultVariantId","shop","displayImage","displayPrice","displayCompareAtPrice","isFavoritedLocal","setIsFavoritedLocal","React","currencyCode","amount","imageUrl","imageAltText","compareAtPriceAmount","handlePress","handleFavoritePress","previousState","jsxs","formatMoney","ProductVariantPrice"],"mappings":"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"}
|