@shopify/shop-minis-react 0.0.27 → 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.
Files changed (40) hide show
  1. package/dist/_virtual/index2.js +4 -4
  2. package/dist/_virtual/index3.js +4 -4
  3. package/dist/components/atoms/content-monitor.js +22 -0
  4. package/dist/components/atoms/content-monitor.js.map +1 -0
  5. package/dist/components/atoms/content-wrapper.js +18 -0
  6. package/dist/components/atoms/content-wrapper.js.map +1 -0
  7. package/dist/components/atoms/long-press-detector.js +33 -0
  8. package/dist/components/atoms/long-press-detector.js.map +1 -0
  9. package/dist/components/commerce/product-link.js +117 -113
  10. package/dist/components/commerce/product-link.js.map +1 -1
  11. package/dist/components/commerce/search.js +26 -17
  12. package/dist/components/commerce/search.js.map +1 -1
  13. package/dist/components/content/image-content-wrapper.js +27 -0
  14. package/dist/components/content/image-content-wrapper.js.map +1 -0
  15. package/dist/components/navigation/minis-router.js +14 -0
  16. package/dist/components/navigation/minis-router.js.map +1 -0
  17. package/dist/index.js +214 -212
  18. package/dist/index.js.map +1 -1
  19. package/dist/shop-minis-react/node_modules/.pnpm/react-router@7.7.0_react-dom@19.1.0_react@19.1.0__react@19.1.0/node_modules/react-router/dist/development/chunk-EF7DTUVF.js +764 -567
  20. package/dist/shop-minis-react/node_modules/.pnpm/react-router@7.7.0_react-dom@19.1.0_react@19.1.0__react@19.1.0/node_modules/react-router/dist/development/chunk-EF7DTUVF.js.map +1 -1
  21. package/dist/shop-minis-react/node_modules/.pnpm/video.js@8.23.3/node_modules/video.js/dist/video.es.js +1 -1
  22. package/dist/utils/colors.js +1 -1
  23. package/package.json +1 -1
  24. package/src/components/atoms/content-monitor.tsx +25 -0
  25. package/src/components/{content → atoms}/content-wrapper.tsx +1 -0
  26. package/src/components/atoms/long-press-detector.tsx +52 -0
  27. package/src/components/commerce/product-link.tsx +10 -4
  28. package/src/components/commerce/search.tsx +8 -1
  29. package/src/components/content/image-content-wrapper.tsx +42 -0
  30. package/src/components/index.ts +3 -2
  31. package/src/components/navigation/minis-router.tsx +23 -0
  32. package/src/index.css +1 -0
  33. package/src/stories/Search.stories.tsx +37 -0
  34. package/src/styles/fonts.css +26 -0
  35. package/src/styles/theme.css +26 -0
  36. package/dist/components/content/content-monitor.js +0 -17
  37. package/dist/components/content/content-monitor.js.map +0 -1
  38. package/dist/components/content/content-wrapper.js +0 -17
  39. package/dist/components/content/content-wrapper.js.map +0 -1
  40. package/src/components/content/content-monitor.tsx +0 -23
@@ -1,8 +1,8 @@
1
1
  import { getDefaultExportFromCjs as r } from "./_commonjsHelpers.js";
2
- import { __require as o } from "../shop-minis-react/node_modules/.pnpm/color@4.2.3/node_modules/color/index.js";
3
- var t = /* @__PURE__ */ o();
4
- const l = /* @__PURE__ */ r(t);
2
+ import { __require as o } from "../shop-minis-react/node_modules/.pnpm/@videojs_xhr@2.7.0/node_modules/@videojs/xhr/lib/index.js";
3
+ var t = o();
4
+ const a = /* @__PURE__ */ r(t);
5
5
  export {
6
- l as default
6
+ a as default
7
7
  };
8
8
  //# sourceMappingURL=index2.js.map
@@ -1,8 +1,8 @@
1
1
  import { getDefaultExportFromCjs as r } from "./_commonjsHelpers.js";
2
- import { __require as o } from "../shop-minis-react/node_modules/.pnpm/@videojs_xhr@2.7.0/node_modules/@videojs/xhr/lib/index.js";
3
- var t = o();
4
- const a = /* @__PURE__ */ r(t);
2
+ import { __require as o } from "../shop-minis-react/node_modules/.pnpm/color@4.2.3/node_modules/color/index.js";
3
+ var t = /* @__PURE__ */ o();
4
+ const l = /* @__PURE__ */ r(t);
5
5
  export {
6
- a as default
6
+ l as default
7
7
  };
8
8
  //# sourceMappingURL=index3.js.map
@@ -0,0 +1,22 @@
1
+ import { jsx as e } from "react/jsx-runtime";
2
+ import { useShopActions as n } from "../../internal/useShopActions.js";
3
+ import { LongPressDetector as s } from "./long-press-detector.js";
4
+ function c({
5
+ publicId: o,
6
+ children: r
7
+ }) {
8
+ const { showFeedbackSheet: t } = n();
9
+ return /* @__PURE__ */ e(
10
+ s,
11
+ {
12
+ onLongPress: () => {
13
+ o && t({ publicId: o });
14
+ },
15
+ children: r
16
+ }
17
+ );
18
+ }
19
+ export {
20
+ c as ContentMonitor
21
+ };
22
+ //# sourceMappingURL=content-monitor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-monitor.js","sources":["../../../src/components/atoms/content-monitor.tsx"],"sourcesContent":["import {useShopActions} from '../../internal/useShopActions'\n\nimport {LongPressDetector} from './long-press-detector'\n\nexport function ContentMonitor({\n publicId,\n children,\n}: {\n publicId?: string\n children: React.ReactNode\n}) {\n const {showFeedbackSheet} = useShopActions()\n\n return (\n <LongPressDetector\n onLongPress={() => {\n if (!publicId) return\n\n showFeedbackSheet({publicId})\n }}\n >\n {children}\n </LongPressDetector>\n )\n}\n"],"names":["ContentMonitor","publicId","children","showFeedbackSheet","useShopActions","jsx","LongPressDetector"],"mappings":";;;AAIO,SAASA,EAAe;AAAA,EAC7B,UAAAC;AAAA,EACA,UAAAC;AACF,GAGG;AACK,QAAA,EAAC,mBAAAC,EAAiB,IAAIC,EAAe;AAGzC,SAAA,gBAAAC;AAAA,IAACC;AAAA,IAAA;AAAA,MACC,aAAa,MAAM;AACjB,QAAKL,KAEaE,EAAA,EAAC,UAAAF,GAAS;AAAA,MAC9B;AAAA,MAEC,UAAAC;AAAA,IAAA;AAAA,EACH;AAEJ;"}
@@ -0,0 +1,18 @@
1
+ import { jsx as p } from "react/jsx-runtime";
2
+ import { useContent as c } from "../../hooks/content/useContent.js";
3
+ import { ContentMonitor as m } from "./content-monitor.js";
4
+ function C({
5
+ publicId: o,
6
+ externalId: r,
7
+ children: e
8
+ }) {
9
+ const { content: i, loading: t } = c({
10
+ identifiers: [{ publicId: o, externalId: r }],
11
+ skip: !o && !r
12
+ }), n = i?.[0];
13
+ return t || !n ? e({ loading: t }) : /* @__PURE__ */ p(m, { publicId: n.publicId, children: e({ content: n, loading: t }) });
14
+ }
15
+ export {
16
+ C as ContentWrapper
17
+ };
18
+ //# sourceMappingURL=content-wrapper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-wrapper.js","sources":["../../../src/components/atoms/content-wrapper.tsx"],"sourcesContent":["import {useContent} from '../../hooks/content/useContent'\nimport {Content} from '../../types'\n\nimport {ContentMonitor} from './content-monitor'\n\ninterface BaseContentWrapperProps {\n children: ({\n content,\n loading,\n }: {\n content?: Content\n loading: boolean\n }) => JSX.Element | null\n}\n\ninterface PublicIdContentWrapperProps extends BaseContentWrapperProps {\n publicId: string\n externalId?: never\n}\n\ninterface ExternalIdContentWrapperProps extends BaseContentWrapperProps {\n externalId: string\n publicId?: never\n}\n\ntype ContentWrapperProps =\n | PublicIdContentWrapperProps\n | ExternalIdContentWrapperProps\n\n// It's too messy in the docs to show the complete types here so we show a simplified version\nexport interface ContentWrapperPropsForDocs extends BaseContentWrapperProps {\n publicId?: string\n externalId?: string\n}\n\nexport function ContentWrapper({\n publicId,\n externalId,\n children,\n}: ContentWrapperProps) {\n const {content, loading} = useContent({\n identifiers: [{publicId, externalId}],\n skip: !publicId && !externalId,\n })\n\n const contentItem = content?.[0]\n\n if (loading || !contentItem) {\n return children({loading})\n }\n\n return (\n <ContentMonitor publicId={contentItem.publicId}>\n {children({content: contentItem, loading})}\n </ContentMonitor>\n )\n}\n"],"names":["ContentWrapper","publicId","externalId","children","content","loading","useContent","contentItem","jsx","ContentMonitor"],"mappings":";;;AAmCO,SAASA,EAAe;AAAA,EAC7B,UAAAC;AAAA,EACA,YAAAC;AAAA,EACA,UAAAC;AACF,GAAwB;AACtB,QAAM,EAAC,SAAAC,GAAS,SAAAC,EAAO,IAAIC,EAAW;AAAA,IACpC,aAAa,CAAC,EAAC,UAAAL,GAAU,YAAAC,GAAW;AAAA,IACpC,MAAM,CAACD,KAAY,CAACC;AAAA,EAAA,CACrB,GAEKK,IAAcH,IAAU,CAAC;AAE3B,SAAAC,KAAW,CAACE,IACPJ,EAAS,EAAC,SAAAE,GAAQ,IAIzB,gBAAAG,EAACC,GAAe,EAAA,UAAUF,EAAY,UACnC,UAASJ,EAAA,EAAC,SAASI,GAAa,SAAAF,EAAO,CAAC,EAC3C,CAAA;AAEJ;"}
@@ -0,0 +1,33 @@
1
+ import { jsx as i } from "react/jsx-runtime";
2
+ import * as t from "react";
3
+ import { motion as s } from "../../shop-minis-react/node_modules/.pnpm/motion@12.17.3_react-dom@19.1.0_react@19.1.0__react@19.1.0/node_modules/motion/dist/es/framer-motion/dist/es/render/components/motion/proxy.js";
4
+ const l = ({
5
+ onLongPress: e,
6
+ delay: o = 500,
7
+ children: c,
8
+ ...a
9
+ }) => {
10
+ const r = t.useRef(void 0), u = t.useCallback(() => {
11
+ r.current = window.setTimeout(() => {
12
+ e(), r.current = void 0;
13
+ }, o);
14
+ }, [e, o]), n = t.useCallback(() => {
15
+ r.current && (clearTimeout(r.current), r.current = void 0);
16
+ }, []);
17
+ return t.useEffect(() => () => {
18
+ r.current && clearTimeout(r.current);
19
+ }, []), /* @__PURE__ */ i(
20
+ s.div,
21
+ {
22
+ onTapStart: u,
23
+ onTap: n,
24
+ onTapCancel: n,
25
+ ...a,
26
+ children: c
27
+ }
28
+ );
29
+ };
30
+ export {
31
+ l as LongPressDetector
32
+ };
33
+ //# sourceMappingURL=long-press-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"long-press-detector.js","sources":["../../../src/components/atoms/long-press-detector.tsx"],"sourcesContent":["import * as React from 'react'\n\nimport {motion, HTMLMotionProps} from 'motion/react'\n\ninterface LongPressDetectorProps extends HTMLMotionProps<'div'> {\n onLongPress: () => void\n delay?: number\n children: React.ReactNode\n}\n\nexport const LongPressDetector = ({\n onLongPress,\n delay = 500,\n children,\n ...motionProps\n}: LongPressDetectorProps) => {\n const longPressTimeoutRef = React.useRef<number | undefined>(undefined)\n\n const handleTapStart = React.useCallback(() => {\n longPressTimeoutRef.current = window.setTimeout(() => {\n onLongPress()\n longPressTimeoutRef.current = undefined\n }, delay)\n }, [onLongPress, delay])\n\n const handleTapEnd = React.useCallback(() => {\n if (longPressTimeoutRef.current) {\n clearTimeout(longPressTimeoutRef.current)\n longPressTimeoutRef.current = undefined\n }\n }, [])\n\n // Cleanup timer on unmount\n React.useEffect(() => {\n return () => {\n if (longPressTimeoutRef.current) {\n clearTimeout(longPressTimeoutRef.current)\n }\n }\n }, [])\n\n return (\n <motion.div\n onTapStart={handleTapStart}\n onTap={handleTapEnd}\n onTapCancel={handleTapEnd}\n {...motionProps}\n >\n {children}\n </motion.div>\n )\n}\n"],"names":["LongPressDetector","onLongPress","delay","children","motionProps","longPressTimeoutRef","React","handleTapStart","handleTapEnd","jsx","motion"],"mappings":";;;AAUO,MAAMA,IAAoB,CAAC;AAAA,EAChC,aAAAC;AAAA,EACA,OAAAC,IAAQ;AAAA,EACR,UAAAC;AAAA,EACA,GAAGC;AACL,MAA8B;AACtB,QAAAC,IAAsBC,EAAM,OAA2B,MAAS,GAEhEC,IAAiBD,EAAM,YAAY,MAAM;AACzB,IAAAD,EAAA,UAAU,OAAO,WAAW,MAAM;AACxC,MAAAJ,EAAA,GACZI,EAAoB,UAAU;AAAA,OAC7BH,CAAK;AAAA,EAAA,GACP,CAACD,GAAaC,CAAK,CAAC,GAEjBM,IAAeF,EAAM,YAAY,MAAM;AAC3C,IAAID,EAAoB,YACtB,aAAaA,EAAoB,OAAO,GACxCA,EAAoB,UAAU;AAAA,EAElC,GAAG,EAAE;AAGL,SAAAC,EAAM,UAAU,MACP,MAAM;AACX,IAAID,EAAoB,WACtB,aAAaA,EAAoB,OAAO;AAAA,EAE5C,GACC,EAAE,GAGH,gBAAAI;AAAA,IAACC,EAAO;AAAA,IAAP;AAAA,MACC,YAAYH;AAAA,MACZ,OAAOC;AAAA,MACP,aAAaA;AAAA,MACZ,GAAGJ;AAAA,MAEH,UAAAD;AAAA,IAAA;AAAA,EACH;AAEJ;"}
@@ -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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"}