@shopify/shop-minis-react 0.0.29 → 0.0.30

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 (42) hide show
  1. package/dist/_virtual/index10.js +2 -2
  2. package/dist/_virtual/index2.js +4 -4
  3. package/dist/_virtual/index3.js +4 -4
  4. package/dist/_virtual/index5.js +3 -2
  5. package/dist/_virtual/index5.js.map +1 -1
  6. package/dist/_virtual/index6.js +2 -3
  7. package/dist/_virtual/index6.js.map +1 -1
  8. package/dist/_virtual/index7.js +2 -2
  9. package/dist/_virtual/index9.js +2 -2
  10. package/dist/components/atoms/list.js +37 -31
  11. package/dist/components/atoms/list.js.map +1 -1
  12. package/dist/components/commerce/search.js.map +1 -1
  13. package/dist/hooks/navigation/useNavigateWithTransition.js.map +1 -1
  14. package/dist/hooks/navigation/useShopNavigation.js.map +1 -1
  15. package/dist/hooks/user/useCurrentUser.js.map +1 -1
  16. package/dist/hooks/user/useFollowedShopsActions.js.map +1 -1
  17. package/dist/hooks/util/useImagePicker.js.map +1 -1
  18. package/dist/mocks.js +9 -9
  19. package/dist/mocks.js.map +1 -1
  20. 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
  21. package/dist/shop-minis-react/node_modules/.pnpm/@videojs_xhr@2.7.0/node_modules/@videojs/xhr/lib/index.js +1 -1
  22. package/dist/shop-minis-react/node_modules/.pnpm/@xmldom_xmldom@0.8.10/node_modules/@xmldom/xmldom/lib/index.js +1 -1
  23. package/dist/shop-minis-react/node_modules/.pnpm/mpd-parser@1.3.1/node_modules/mpd-parser/dist/mpd-parser.es.js +1 -1
  24. 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
  25. package/dist/shop-minis-react/node_modules/.pnpm/video.js@8.23.3/node_modules/video.js/dist/video.es.js +1 -1
  26. package/dist/utils/colors.js +1 -1
  27. package/package.json +1 -1
  28. package/src/components/atoms/list.tsx +24 -4
  29. package/src/components/commerce/search.tsx +1 -1
  30. package/src/hooks/navigation/useNavigateWithTransition.ts +6 -1
  31. package/src/hooks/navigation/useShopNavigation.ts +3 -1
  32. package/src/hooks/user/useCurrentUser.ts +3 -0
  33. package/src/hooks/user/useFollowedShopsActions.ts +2 -2
  34. package/src/hooks/util/{useImagePicker.tsx → useImagePicker.ts} +8 -2
  35. package/src/mocks.ts +3 -3
  36. package/src/stories/ImageContentWrapper.stories.tsx +68 -0
  37. package/src/stories/MerchantCard.stories.tsx +21 -0
  38. package/src/stories/ProductCard.stories.tsx +10 -3
  39. package/src/stories/ProductLink.stories.tsx +3 -3
  40. package/src/stories/QuantitySelector.stories.tsx +78 -0
  41. package/src/stories/VideoPlayer.stories.tsx +129 -0
  42. package/src/hooks/util/useImagePicker.doc.tsx +0 -41
@@ -1,5 +1,5 @@
1
- var e = { exports: {} };
1
+ var r = {};
2
2
  export {
3
- e as __module
3
+ r as __exports
4
4
  };
5
5
  //# sourceMappingURL=index10.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=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/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=index3.js.map
@@ -1,5 +1,6 @@
1
- var e = { exports: {} };
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
- e as __module
4
+ i as s
4
5
  };
5
6
  //# sourceMappingURL=index5.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index5.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
1
+ {"version":3,"file":"index5.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
@@ -1,6 +1,5 @@
1
- import { __require as r } from "../shop-minis-react/node_modules/.pnpm/@xmldom_xmldom@0.8.10/node_modules/@xmldom/xmldom/lib/index.js";
2
- var i = r();
1
+ var e = { exports: {} };
3
2
  export {
4
- i as l
3
+ e as __module
5
4
  };
6
5
  //# sourceMappingURL=index6.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index6.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
1
+ {"version":3,"file":"index6.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
@@ -1,6 +1,6 @@
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";
1
+ import { __require as r } from "../shop-minis-react/node_modules/.pnpm/@xmldom_xmldom@0.8.10/node_modules/@xmldom/xmldom/lib/index.js";
2
2
  var i = r();
3
3
  export {
4
- i as s
4
+ i as l
5
5
  };
6
6
  //# sourceMappingURL=index7.js.map
@@ -1,5 +1,5 @@
1
- var r = {};
1
+ var e = { exports: {} };
2
2
  export {
3
- r as __exports
3
+ e as __module
4
4
  };
5
5
  //# sourceMappingURL=index9.js.map
@@ -1,48 +1,54 @@
1
- import { jsxs as u, jsx as o } from "react/jsx-runtime";
2
- import { useCallback as f } from "react";
3
- import { VariableSizeList as V } from "../../shop-minis-react/node_modules/.pnpm/react-window@1.8.11_react-dom@19.1.0_react@19.1.0__react@19.1.0/node_modules/react-window/dist/index.esm.js";
1
+ import { jsxs as m, jsx as n } from "react/jsx-runtime";
2
+ import { useRef as V, useCallback as f } from "react";
3
+ import { VariableSizeList as _ } from "../../shop-minis-react/node_modules/.pnpm/react-window@1.8.11_react-dom@19.1.0_react@19.1.0__react@19.1.0/node_modules/react-window/dist/index.esm.js";
4
4
  import { cn as j } from "../../lib/utils.js";
5
5
  /* empty css */
6
6
  import { Pagination as C } from "./pagination.js";
7
- const N = V;
7
+ const N = _;
8
8
  function q({
9
- items: r,
9
+ items: t,
10
10
  height: p,
11
- renderItem: l,
12
- className: m,
13
- showScrollbar: v = !1,
14
- header: t,
15
- headerHeight: n,
16
- itemSizeForRow: s,
17
- fetchMore: a,
18
- overscanCount: b,
19
- ...L
11
+ renderItem: o,
12
+ className: v,
13
+ showScrollbar: b = !1,
14
+ header: i,
15
+ headerHeight: c,
16
+ itemSizeForRow: a,
17
+ fetchMore: l,
18
+ overscanCount: g,
19
+ ...h
20
20
  }) {
21
- const g = f(
22
- ({ index: i, style: c }) => t && i === 0 ? /* @__PURE__ */ u("div", { style: c, children: [
23
- t,
24
- /* @__PURE__ */ o("div", { style: { top: n }, children: l(r[0], 0) })
25
- ] }) : a && i === r.length - 1 ? /* @__PURE__ */ u("div", { style: c, children: [
26
- l(r[i], i),
27
- /* @__PURE__ */ o("div", { style: { bottom: 0 }, children: /* @__PURE__ */ o(C, { fetchMore: a }) })
28
- ] }) : /* @__PURE__ */ o("div", { style: c, children: l(r[i], i) }),
29
- [r, l, t, a, n]
21
+ const s = V(null), e = f(() => {
22
+ if (s.current) return;
23
+ const r = Promise.resolve(l?.()).finally(() => {
24
+ s.current === r && (s.current = null);
25
+ });
26
+ s.current = r;
27
+ }, [l]), L = f(
28
+ ({ index: r, style: u }) => i && r === 0 ? /* @__PURE__ */ m("div", { style: u, children: [
29
+ i,
30
+ /* @__PURE__ */ n("div", { style: { top: c }, children: o(t[0], 0) })
31
+ ] }) : l && r === t.length - 1 ? /* @__PURE__ */ m("div", { style: u, children: [
32
+ o(t[r], r),
33
+ /* @__PURE__ */ n("div", { style: { bottom: 0 }, children: /* @__PURE__ */ n(C, { fetchMore: e }) })
34
+ ] }) : /* @__PURE__ */ n("div", { style: u, children: o(t[r], r) }),
35
+ [t, o, i, c, e, l]
30
36
  ), z = f(
31
- (i) => t && i === 0 ? (n || 0) + s(i) : s(i),
32
- [s, t, n]
33
- ), S = j(v ? void 0 : "no-scrollbars", m);
34
- return /* @__PURE__ */ o(
37
+ (r) => i && r === 0 ? (c || 0) + a(r) : a(r),
38
+ [a, i, c]
39
+ ), S = j(b ? void 0 : "no-scrollbars", v);
40
+ return /* @__PURE__ */ n(
35
41
  N,
36
42
  {
37
43
  className: S,
38
44
  height: p,
39
45
  direction: "vertical",
40
46
  width: "100%",
41
- itemCount: r.length,
42
- overscanCount: b,
47
+ itemCount: t.length,
48
+ overscanCount: g,
43
49
  itemSize: z,
44
- ...L,
45
- children: g
50
+ ...h,
51
+ children: L
46
52
  }
47
53
  );
48
54
  }
@@ -1 +1 @@
1
- {"version":3,"file":"list.js","sources":["../../../src/components/atoms/list.tsx"],"sourcesContent":["import {ComponentType, useCallback} from 'react'\n\nimport {\n VariableSizeList as _VariableSizeList,\n VariableSizeListProps,\n} from 'react-window'\n\nimport {cn} from '../../lib/utils'\nimport '../../styles/utilities.css'\n\nimport {Pagination} from './pagination'\n\nconst VariableSizeList =\n _VariableSizeList as unknown as ComponentType<VariableSizeListProps>\n\ninterface Props<T = any>\n extends Omit<\n VariableSizeListProps<T>,\n 'children' | 'itemCount' | 'width' | 'itemSize' | 'direction'\n > {\n items: T[]\n renderItem: (item: T, index: number) => React.ReactNode\n itemSizeForRow: (index: number) => number\n showScrollbar?: boolean\n header?: React.ReactNode\n headerHeight?: number\n fetchMore?: () => void\n}\n\nexport function List<T = any>({\n items,\n height,\n renderItem,\n className,\n showScrollbar = false,\n header,\n headerHeight,\n itemSizeForRow,\n fetchMore,\n overscanCount,\n ...listProps\n}: Props<T>) {\n const rowRenderer = useCallback(\n ({index, style}: {index: number; style: React.CSSProperties}) => {\n // prepend the header to the first row if it exists\n if (header && index === 0) {\n return (\n <div style={style}>\n {header}\n <div style={{top: headerHeight}}>{renderItem(items[0], 0)}</div>\n </div>\n )\n }\n\n // append the pagination spinner to the last row if fetchMore exists\n if (fetchMore && index === items.length - 1) {\n return (\n <div style={style}>\n {renderItem(items[index], index)}\n <div style={{bottom: 0}}>\n <Pagination fetchMore={fetchMore} />\n </div>\n </div>\n )\n }\n\n return <div style={style}>{renderItem(items[index], index)}</div>\n },\n [items, renderItem, header, fetchMore, headerHeight]\n )\n\n const getItemSize = useCallback(\n (index: number) => {\n // include the header height in the first row height\n if (header && index === 0) {\n const _headerHeight = headerHeight || 0\n return _headerHeight + itemSizeForRow(index)\n }\n\n return itemSizeForRow(index)\n },\n [itemSizeForRow, header, headerHeight]\n )\n\n const classNames = cn(showScrollbar ? undefined : 'no-scrollbars', className)\n\n return (\n <VariableSizeList\n className={classNames}\n height={height}\n direction=\"vertical\"\n width=\"100%\"\n itemCount={items.length}\n overscanCount={overscanCount}\n itemSize={getItemSize}\n {...listProps}\n >\n {rowRenderer}\n </VariableSizeList>\n )\n}\n"],"names":["VariableSizeList","_VariableSizeList","List","items","height","renderItem","className","showScrollbar","header","headerHeight","itemSizeForRow","fetchMore","overscanCount","listProps","rowRenderer","useCallback","index","style","jsxs","jsx","Pagination","getItemSize","classNames","cn"],"mappings":";;;;;;AAYA,MAAMA,IACJC;AAgBK,SAASC,EAAc;AAAA,EAC5B,OAAAC;AAAA,EACA,QAAAC;AAAA,EACA,YAAAC;AAAA,EACA,WAAAC;AAAA,EACA,eAAAC,IAAgB;AAAA,EAChB,QAAAC;AAAA,EACA,cAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,WAAAC;AAAA,EACA,eAAAC;AAAA,EACA,GAAGC;AACL,GAAa;AACX,QAAMC,IAAcC;AAAA,IAClB,CAAC,EAAC,OAAAC,GAAO,OAAAC,QAEHT,KAAUQ,MAAU,IAEpB,gBAAAE,EAAC,SAAI,OAAAD,GACF,UAAA;AAAA,MAAAT;AAAA,MACA,gBAAAW,EAAA,OAAA,EAAI,OAAO,EAAC,KAAKV,EAAA,GAAgB,UAAAJ,EAAWF,EAAM,CAAC,GAAG,CAAC,EAAE,CAAA;AAAA,IAAA,GAC5D,IAKAQ,KAAaK,MAAUb,EAAM,SAAS,IAEtC,gBAAAe,EAAC,SAAI,OAAAD,GACF,UAAA;AAAA,MAAWZ,EAAAF,EAAMa,CAAK,GAAGA,CAAK;AAAA,MAC/B,gBAAAG,EAAC,OAAI,EAAA,OAAO,EAAC,QAAQ,KACnB,UAAA,gBAAAA,EAACC,GAAW,EAAA,WAAAT,EAAsB,CAAA,EACpC,CAAA;AAAA,IAAA,GACF,IAIG,gBAAAQ,EAAC,SAAI,OAAAF,GAAe,UAAAZ,EAAWF,EAAMa,CAAK,GAAGA,CAAK,GAAE;AAAA,IAE7D,CAACb,GAAOE,GAAYG,GAAQG,GAAWF,CAAY;AAAA,EACrD,GAEMY,IAAcN;AAAA,IAClB,CAACC,MAEKR,KAAUQ,MAAU,KACAP,KAAgB,KACfC,EAAeM,CAAK,IAGtCN,EAAeM,CAAK;AAAA,IAE7B,CAACN,GAAgBF,GAAQC,CAAY;AAAA,EACvC,GAEMa,IAAaC,EAAGhB,IAAgB,SAAY,iBAAiBD,CAAS;AAG1E,SAAA,gBAAAa;AAAA,IAACnB;AAAA,IAAA;AAAA,MACC,WAAWsB;AAAA,MACX,QAAAlB;AAAA,MACA,WAAU;AAAA,MACV,OAAM;AAAA,MACN,WAAWD,EAAM;AAAA,MACjB,eAAAS;AAAA,MACA,UAAUS;AAAA,MACT,GAAGR;AAAA,MAEH,UAAAC;AAAA,IAAA;AAAA,EACH;AAEJ;"}
1
+ {"version":3,"file":"list.js","sources":["../../../src/components/atoms/list.tsx"],"sourcesContent":["import {ComponentType, useCallback, useRef} from 'react'\n\nimport {\n VariableSizeList as _VariableSizeList,\n VariableSizeListProps,\n} from 'react-window'\n\nimport {cn} from '../../lib/utils'\nimport '../../styles/utilities.css'\n\nimport {Pagination} from './pagination'\n\nconst VariableSizeList =\n _VariableSizeList as unknown as ComponentType<VariableSizeListProps>\n\ninterface Props<T = any>\n extends Omit<\n VariableSizeListProps<T>,\n 'children' | 'itemCount' | 'width' | 'itemSize' | 'direction'\n > {\n items: T[]\n renderItem: (item: T, index: number) => React.ReactNode\n itemSizeForRow: (index: number) => number\n showScrollbar?: boolean\n header?: React.ReactNode\n headerHeight?: number\n fetchMore?: () => Promise<void>\n}\n\nexport function List<T = any>({\n items,\n height,\n renderItem,\n className,\n showScrollbar = false,\n header,\n headerHeight,\n itemSizeForRow,\n fetchMore,\n overscanCount,\n ...listProps\n}: Props<T>) {\n const inFlightFetchMoreRef = useRef<Promise<void> | null>(null)\n\n // This is workaround to prevent multiple calls to fetchMore\n // react-window re-renders the rows while scrolling,\n // and the TrackingPixel could be triggered multiple times\n\n const _fetchMore = useCallback(() => {\n // Dedupe concurrent calls by returning the same in-flight promise\n if (inFlightFetchMoreRef.current) return\n\n const current = Promise.resolve(fetchMore?.()).finally(() => {\n // Only clear if this is still the most recent promise\n if (inFlightFetchMoreRef.current === current) {\n inFlightFetchMoreRef.current = null\n }\n })\n\n inFlightFetchMoreRef.current = current\n }, [fetchMore])\n\n const rowRenderer = useCallback(\n ({index, style}: {index: number; style: React.CSSProperties}) => {\n // prepend the header to the first row if it exists\n if (header && index === 0) {\n return (\n <div style={style}>\n {header}\n <div style={{top: headerHeight}}>{renderItem(items[0], 0)}</div>\n </div>\n )\n }\n\n // append the pagination spinner to the last row if fetchMore exists\n if (fetchMore && index === items.length - 1) {\n return (\n <div style={style}>\n {renderItem(items[index], index)}\n <div style={{bottom: 0}}>\n <Pagination fetchMore={_fetchMore} />\n </div>\n </div>\n )\n }\n\n return <div style={style}>{renderItem(items[index], index)}</div>\n },\n [items, renderItem, header, headerHeight, _fetchMore, fetchMore]\n )\n\n const getItemSize = useCallback(\n (index: number) => {\n // include the header height in the first row height\n if (header && index === 0) {\n const _headerHeight = headerHeight || 0\n return _headerHeight + itemSizeForRow(index)\n }\n\n return itemSizeForRow(index)\n },\n [itemSizeForRow, header, headerHeight]\n )\n\n const classNames = cn(showScrollbar ? undefined : 'no-scrollbars', className)\n\n return (\n <VariableSizeList\n className={classNames}\n height={height}\n direction=\"vertical\"\n width=\"100%\"\n itemCount={items.length}\n overscanCount={overscanCount}\n itemSize={getItemSize}\n {...listProps}\n >\n {rowRenderer}\n </VariableSizeList>\n )\n}\n"],"names":["VariableSizeList","_VariableSizeList","List","items","height","renderItem","className","showScrollbar","header","headerHeight","itemSizeForRow","fetchMore","overscanCount","listProps","inFlightFetchMoreRef","useRef","_fetchMore","useCallback","current","rowRenderer","index","style","jsxs","jsx","Pagination","getItemSize","classNames","cn"],"mappings":";;;;;;AAYA,MAAMA,IACJC;AAgBK,SAASC,EAAc;AAAA,EAC5B,OAAAC;AAAA,EACA,QAAAC;AAAA,EACA,YAAAC;AAAA,EACA,WAAAC;AAAA,EACA,eAAAC,IAAgB;AAAA,EAChB,QAAAC;AAAA,EACA,cAAAC;AAAA,EACA,gBAAAC;AAAA,EACA,WAAAC;AAAA,EACA,eAAAC;AAAA,EACA,GAAGC;AACL,GAAa;AACL,QAAAC,IAAuBC,EAA6B,IAAI,GAMxDC,IAAaC,EAAY,MAAM;AAEnC,QAAIH,EAAqB,QAAS;AAElC,UAAMI,IAAU,QAAQ,QAAQP,IAAa,CAAA,EAAE,QAAQ,MAAM;AAEvD,MAAAG,EAAqB,YAAYI,MACnCJ,EAAqB,UAAU;AAAA,IACjC,CACD;AAED,IAAAA,EAAqB,UAAUI;AAAA,EAAA,GAC9B,CAACP,CAAS,CAAC,GAERQ,IAAcF;AAAA,IAClB,CAAC,EAAC,OAAAG,GAAO,OAAAC,QAEHb,KAAUY,MAAU,IAEpB,gBAAAE,EAAC,SAAI,OAAAD,GACF,UAAA;AAAA,MAAAb;AAAA,MACA,gBAAAe,EAAA,OAAA,EAAI,OAAO,EAAC,KAAKd,EAAA,GAAgB,UAAAJ,EAAWF,EAAM,CAAC,GAAG,CAAC,EAAE,CAAA;AAAA,IAAA,GAC5D,IAKAQ,KAAaS,MAAUjB,EAAM,SAAS,IAEtC,gBAAAmB,EAAC,SAAI,OAAAD,GACF,UAAA;AAAA,MAAWhB,EAAAF,EAAMiB,CAAK,GAAGA,CAAK;AAAA,MAC/B,gBAAAG,EAAC,OAAI,EAAA,OAAO,EAAC,QAAQ,EAAC,GACpB,UAAC,gBAAAA,EAAAC,GAAA,EAAW,WAAWR,EAAY,CAAA,EACrC,CAAA;AAAA,IAAA,GACF,IAIG,gBAAAO,EAAC,SAAI,OAAAF,GAAe,UAAAhB,EAAWF,EAAMiB,CAAK,GAAGA,CAAK,GAAE;AAAA,IAE7D,CAACjB,GAAOE,GAAYG,GAAQC,GAAcO,GAAYL,CAAS;AAAA,EACjE,GAEMc,IAAcR;AAAA,IAClB,CAACG,MAEKZ,KAAUY,MAAU,KACAX,KAAgB,KACfC,EAAeU,CAAK,IAGtCV,EAAeU,CAAK;AAAA,IAE7B,CAACV,GAAgBF,GAAQC,CAAY;AAAA,EACvC,GAEMiB,IAAaC,EAAGpB,IAAgB,SAAY,iBAAiBD,CAAS;AAG1E,SAAA,gBAAAiB;AAAA,IAACvB;AAAA,IAAA;AAAA,MACC,WAAW0B;AAAA,MACX,QAAAtB;AAAA,MACA,WAAU;AAAA,MACV,OAAM;AAAA,MACN,WAAWD,EAAM;AAAA,MACjB,eAAAS;AAAA,MACA,UAAUa;AAAA,MACT,GAAGZ;AAAA,MAEH,UAAAM;AAAA,IAAA;AAAA,EACH;AAEJ;"}
@@ -1 +1 @@
1
- {"version":3,"file":"search.js","sources":["../../../src/components/commerce/search.tsx"],"sourcesContent":["import * as React from 'react'\nimport {createContext, useContext, useState, useCallback} from 'react'\n\nimport {SearchIcon, X} from 'lucide-react'\n\nimport {useProductSearch} from '../../hooks/product/useProductSearch'\nimport {cn} from '../../lib/utils'\nimport {type Product} from '../../types'\nimport {IconButton} from '../atoms/icon-button'\nimport {List} from '../atoms/list'\nimport {Input} from '../ui/input'\n\nimport {ProductLink} from './product-link'\nimport {ProductLinkSkeleton} from './product-link-skeleton'\n\nconst ESTIMATED_PRODUCT_LINK_HEIGHT = 100\n\ninterface SearchContextValue {\n query: string\n setQuery: (query: string) => void\n products: Product[] | null\n loading: boolean\n error: Error | null\n fetchMore?: () => void\n hasNextPage: boolean\n isTyping: boolean\n}\n\nconst SearchContext = createContext<SearchContextValue | null>(null)\n\nfunction useSearchContext() {\n const context = useContext(SearchContext)\n if (!context) {\n throw new Error('useSearchContext must be used within a SearchProvider')\n }\n return context\n}\n\nexport interface SearchProviderProps {\n initialQuery?: string\n children: React.ReactNode\n}\n\nfunction SearchProvider({initialQuery = '', children}: SearchProviderProps) {\n const [query, setQueryState] = useState(initialQuery)\n\n const {products, loading, error, fetchMore, hasNextPage, isTyping} =\n useProductSearch({\n query,\n fetchPolicy: 'network-only',\n })\n\n const setQuery = useCallback((newQuery: string) => {\n setQueryState(newQuery)\n }, [])\n\n const contextValue: SearchContextValue = {\n query,\n setQuery,\n products,\n loading,\n error,\n fetchMore,\n hasNextPage,\n isTyping,\n }\n\n return (\n <SearchContext.Provider value={contextValue}>\n {children}\n </SearchContext.Provider>\n )\n}\n\nexport interface SearchInputProps {\n placeholder?: string\n className?: string\n inputProps?: React.ComponentProps<'input'>\n}\n\nfunction SearchInput({\n placeholder = 'Search products...',\n className,\n inputProps,\n}: SearchInputProps) {\n const {query, setQuery} = useSearchContext()\n\n const handleQueryChange = useCallback(\n (event: React.ChangeEvent<HTMLInputElement>) => {\n setQuery(event.target.value)\n inputProps?.onChange?.(event)\n },\n [inputProps, setQuery]\n )\n\n return (\n <div className=\"relative flex flex-1 items-center rounded-full pl-4 pr-2 py-1 bg-gray-100\">\n <div className=\"relative flex items-center\">\n <SearchIcon\n size={18}\n className={cn('text-accent-foreground opacity-60')}\n />\n </div>\n <div className=\"relative flex-1 flex items-center mx-2\">\n <Input\n name=\"search\"\n onChange={handleQueryChange}\n placeholder={placeholder}\n type=\"search\"\n role=\"searchbox\"\n autoComplete=\"off\"\n value={query}\n data-testid=\"search-input\"\n {...inputProps}\n className={cn(\n `w-full flex overflow-hidden rounded-radius-28 border-none py-4 px-0 text-text placeholder:text-text placeholder:opacity-60`,\n className\n )}\n />\n </div>\n <div className=\"relative flex items-center\">\n {query === '' ? null : (\n <IconButton\n Icon={X}\n size=\"sm\"\n filled={false}\n iconStyles=\"\"\n onClick={() => setQuery('')}\n buttonStyles=\"flex items-center rounded-radius-max bg-[var(--grayscale-l20)]\"\n />\n )}\n </div>\n </div>\n )\n}\n\nexport interface SearchResultsListProps {\n renderItem?: (product: Product, index: number) => React.ReactNode\n height?: number\n itemHeight?: number\n initialStateComponent?: React.JSX.Element\n showScrollbar?: boolean\n overscanCount?: number\n}\n\nfunction SearchResultsList({\n height = window.innerHeight,\n renderItem,\n itemHeight = ESTIMATED_PRODUCT_LINK_HEIGHT,\n initialStateComponent,\n showScrollbar,\n overscanCount = 5,\n}: SearchResultsListProps) {\n const {query, products, loading, fetchMore, hasNextPage, isTyping} =\n useSearchContext()\n\n const _renderItem = (product: Product, index: number) => {\n if (renderItem) {\n return renderItem(product, index)\n }\n\n return (\n <div className=\"p-2\">\n <ProductLink key={product.id} product={product} hideFavoriteAction />\n </div>\n )\n }\n\n const shouldShowStartingState = query.trim().length === 0\n const shouldShowLoading =\n (!products || products.length === 0) && (loading || isTyping)\n const shouldShowEmptyState = (!products || products.length === 0) && !loading\n\n if (shouldShowStartingState) {\n return (\n initialStateComponent || (\n <div className=\"flex items-center justify-center h-32 text-gray-500\">\n Start typing to search for products\n </div>\n )\n )\n }\n\n if (shouldShowLoading) {\n return (\n <div className=\"flex flex-col px-4 py-4\">\n <ProductLinkSkeleton className=\"mb-4\" />\n <ProductLinkSkeleton className=\"mb-4\" />\n <ProductLinkSkeleton className=\"mb-4\" />\n <ProductLinkSkeleton className=\"mb-4\" />\n </div>\n )\n }\n\n if (shouldShowEmptyState) {\n return (\n <div className=\"flex items-center justify-center h-32 text-gray-500\">\n {`No products found for \"${query}\"`}\n </div>\n )\n }\n\n return (\n <List\n items={products || []}\n height={height}\n renderItem={_renderItem}\n itemSizeForRow={() => itemHeight}\n fetchMore={hasNextPage ? fetchMore : undefined}\n showScrollbar={showScrollbar}\n overscanCount={overscanCount}\n />\n )\n}\n\ninterface SearchProviderPropsWithoutChildren\n extends Omit<SearchProviderProps, 'children'> {}\nexport interface SearchResultsProps\n extends SearchProviderPropsWithoutChildren,\n SearchInputProps,\n SearchResultsListProps {\n showSearchInput?: boolean\n onProductClick?: (product: Product) => void\n}\n\nfunction Search({\n initialQuery,\n placeholder,\n inputProps,\n height,\n className,\n renderItem,\n itemHeight,\n onProductClick,\n}: SearchResultsProps) {\n const _renderItem = (product: Product, index: number) => {\n if (renderItem) {\n return renderItem(product, index)\n }\n\n return (\n <div className=\"p-2\">\n <ProductLink\n key={product.id}\n product={product}\n hideFavoriteAction\n onClick={onProductClick}\n />\n </div>\n )\n }\n\n return (\n <SearchProvider initialQuery={initialQuery}>\n <div className={cn('flex flex-col ', className)}>\n <div className=\"fixed top-0 left-0 right-0 p-4 w-full z-20 bg-background\">\n <SearchInput placeholder={placeholder} inputProps={inputProps} />\n </div>\n <div className=\"h-14\" />\n <SearchResultsList\n height={height}\n renderItem={_renderItem}\n itemHeight={itemHeight}\n showScrollbar\n />\n </div>\n </SearchProvider>\n )\n}\n\nexport {SearchProvider, SearchInput, SearchResultsList, Search}\n"],"names":["ESTIMATED_PRODUCT_LINK_HEIGHT","SearchContext","createContext","useSearchContext","context","useContext","SearchProvider","initialQuery","children","query","setQueryState","useState","products","loading","error","fetchMore","hasNextPage","isTyping","useProductSearch","setQuery","useCallback","newQuery","contextValue","SearchInput","placeholder","className","inputProps","handleQueryChange","event","jsxs","jsx","SearchIcon","cn","Input","IconButton","X","SearchResultsList","height","renderItem","itemHeight","initialStateComponent","showScrollbar","overscanCount","_renderItem","product","index","ProductLink","shouldShowStartingState","shouldShowLoading","shouldShowEmptyState","ProductLinkSkeleton","List","Search","onProductClick"],"mappings":"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"}
1
+ {"version":3,"file":"search.js","sources":["../../../src/components/commerce/search.tsx"],"sourcesContent":["import * as React from 'react'\nimport {createContext, useContext, useState, useCallback} from 'react'\n\nimport {SearchIcon, X} from 'lucide-react'\n\nimport {useProductSearch} from '../../hooks/product/useProductSearch'\nimport {cn} from '../../lib/utils'\nimport {type Product} from '../../types'\nimport {IconButton} from '../atoms/icon-button'\nimport {List} from '../atoms/list'\nimport {Input} from '../ui/input'\n\nimport {ProductLink} from './product-link'\nimport {ProductLinkSkeleton} from './product-link-skeleton'\n\nconst ESTIMATED_PRODUCT_LINK_HEIGHT = 100\n\ninterface SearchContextValue {\n query: string\n setQuery: (query: string) => void\n products: Product[] | null\n loading: boolean\n error: Error | null\n fetchMore?: () => Promise<void>\n hasNextPage: boolean\n isTyping: boolean\n}\n\nconst SearchContext = createContext<SearchContextValue | null>(null)\n\nfunction useSearchContext() {\n const context = useContext(SearchContext)\n if (!context) {\n throw new Error('useSearchContext must be used within a SearchProvider')\n }\n return context\n}\n\nexport interface SearchProviderProps {\n initialQuery?: string\n children: React.ReactNode\n}\n\nfunction SearchProvider({initialQuery = '', children}: SearchProviderProps) {\n const [query, setQueryState] = useState(initialQuery)\n\n const {products, loading, error, fetchMore, hasNextPage, isTyping} =\n useProductSearch({\n query,\n fetchPolicy: 'network-only',\n })\n\n const setQuery = useCallback((newQuery: string) => {\n setQueryState(newQuery)\n }, [])\n\n const contextValue: SearchContextValue = {\n query,\n setQuery,\n products,\n loading,\n error,\n fetchMore,\n hasNextPage,\n isTyping,\n }\n\n return (\n <SearchContext.Provider value={contextValue}>\n {children}\n </SearchContext.Provider>\n )\n}\n\nexport interface SearchInputProps {\n placeholder?: string\n className?: string\n inputProps?: React.ComponentProps<'input'>\n}\n\nfunction SearchInput({\n placeholder = 'Search products...',\n className,\n inputProps,\n}: SearchInputProps) {\n const {query, setQuery} = useSearchContext()\n\n const handleQueryChange = useCallback(\n (event: React.ChangeEvent<HTMLInputElement>) => {\n setQuery(event.target.value)\n inputProps?.onChange?.(event)\n },\n [inputProps, setQuery]\n )\n\n return (\n <div className=\"relative flex flex-1 items-center rounded-full pl-4 pr-2 py-1 bg-gray-100\">\n <div className=\"relative flex items-center\">\n <SearchIcon\n size={18}\n className={cn('text-accent-foreground opacity-60')}\n />\n </div>\n <div className=\"relative flex-1 flex items-center mx-2\">\n <Input\n name=\"search\"\n onChange={handleQueryChange}\n placeholder={placeholder}\n type=\"search\"\n role=\"searchbox\"\n autoComplete=\"off\"\n value={query}\n data-testid=\"search-input\"\n {...inputProps}\n className={cn(\n `w-full flex overflow-hidden rounded-radius-28 border-none py-4 px-0 text-text placeholder:text-text placeholder:opacity-60`,\n className\n )}\n />\n </div>\n <div className=\"relative flex items-center\">\n {query === '' ? null : (\n <IconButton\n Icon={X}\n size=\"sm\"\n filled={false}\n iconStyles=\"\"\n onClick={() => setQuery('')}\n buttonStyles=\"flex items-center rounded-radius-max bg-[var(--grayscale-l20)]\"\n />\n )}\n </div>\n </div>\n )\n}\n\nexport interface SearchResultsListProps {\n renderItem?: (product: Product, index: number) => React.ReactNode\n height?: number\n itemHeight?: number\n initialStateComponent?: React.JSX.Element\n showScrollbar?: boolean\n overscanCount?: number\n}\n\nfunction SearchResultsList({\n height = window.innerHeight,\n renderItem,\n itemHeight = ESTIMATED_PRODUCT_LINK_HEIGHT,\n initialStateComponent,\n showScrollbar,\n overscanCount = 5,\n}: SearchResultsListProps) {\n const {query, products, loading, fetchMore, hasNextPage, isTyping} =\n useSearchContext()\n\n const _renderItem = (product: Product, index: number) => {\n if (renderItem) {\n return renderItem(product, index)\n }\n\n return (\n <div className=\"p-2\">\n <ProductLink key={product.id} product={product} hideFavoriteAction />\n </div>\n )\n }\n\n const shouldShowStartingState = query.trim().length === 0\n const shouldShowLoading =\n (!products || products.length === 0) && (loading || isTyping)\n const shouldShowEmptyState = (!products || products.length === 0) && !loading\n\n if (shouldShowStartingState) {\n return (\n initialStateComponent || (\n <div className=\"flex items-center justify-center h-32 text-gray-500\">\n Start typing to search for products\n </div>\n )\n )\n }\n\n if (shouldShowLoading) {\n return (\n <div className=\"flex flex-col px-4 py-4\">\n <ProductLinkSkeleton className=\"mb-4\" />\n <ProductLinkSkeleton className=\"mb-4\" />\n <ProductLinkSkeleton className=\"mb-4\" />\n <ProductLinkSkeleton className=\"mb-4\" />\n </div>\n )\n }\n\n if (shouldShowEmptyState) {\n return (\n <div className=\"flex items-center justify-center h-32 text-gray-500\">\n {`No products found for \"${query}\"`}\n </div>\n )\n }\n\n return (\n <List\n items={products || []}\n height={height}\n renderItem={_renderItem}\n itemSizeForRow={() => itemHeight}\n fetchMore={hasNextPage ? fetchMore : undefined}\n showScrollbar={showScrollbar}\n overscanCount={overscanCount}\n />\n )\n}\n\ninterface SearchProviderPropsWithoutChildren\n extends Omit<SearchProviderProps, 'children'> {}\nexport interface SearchResultsProps\n extends SearchProviderPropsWithoutChildren,\n SearchInputProps,\n SearchResultsListProps {\n showSearchInput?: boolean\n onProductClick?: (product: Product) => void\n}\n\nfunction Search({\n initialQuery,\n placeholder,\n inputProps,\n height,\n className,\n renderItem,\n itemHeight,\n onProductClick,\n}: SearchResultsProps) {\n const _renderItem = (product: Product, index: number) => {\n if (renderItem) {\n return renderItem(product, index)\n }\n\n return (\n <div className=\"p-2\">\n <ProductLink\n key={product.id}\n product={product}\n hideFavoriteAction\n onClick={onProductClick}\n />\n </div>\n )\n }\n\n return (\n <SearchProvider initialQuery={initialQuery}>\n <div className={cn('flex flex-col ', className)}>\n <div className=\"fixed top-0 left-0 right-0 p-4 w-full z-20 bg-background\">\n <SearchInput placeholder={placeholder} inputProps={inputProps} />\n </div>\n <div className=\"h-14\" />\n <SearchResultsList\n height={height}\n renderItem={_renderItem}\n itemHeight={itemHeight}\n showScrollbar\n />\n </div>\n </SearchProvider>\n )\n}\n\nexport {SearchProvider, SearchInput, SearchResultsList, Search}\n"],"names":["ESTIMATED_PRODUCT_LINK_HEIGHT","SearchContext","createContext","useSearchContext","context","useContext","SearchProvider","initialQuery","children","query","setQueryState","useState","products","loading","error","fetchMore","hasNextPage","isTyping","useProductSearch","setQuery","useCallback","newQuery","contextValue","SearchInput","placeholder","className","inputProps","handleQueryChange","event","jsxs","jsx","SearchIcon","cn","Input","IconButton","X","SearchResultsList","height","renderItem","itemHeight","initialStateComponent","showScrollbar","overscanCount","_renderItem","product","index","ProductLink","shouldShowStartingState","shouldShowLoading","shouldShowEmptyState","ProductLinkSkeleton","List","Search","onProductClick"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"useNavigateWithTransition.js","sources":["../../../src/hooks/navigation/useNavigateWithTransition.ts"],"sourcesContent":["import {useLocation, useNavigate, NavigateOptions} from 'react-router'\n\nimport {DATA_NAVIGATION_TYPE_ATTRIBUTE} from '../../types'\n\nexport function useNavigateWithTransition() {\n const navigate = useNavigate()\n const location = useLocation()\n\n const transitionNavigate = (\n to: string | number,\n options?: NavigateOptions\n ) => {\n if (typeof to === 'number') {\n // Delta navigation - no options parameter\n if (document.startViewTransition) {\n const transition = document.startViewTransition(() => {\n navigate(to)\n })\n\n transition.finished\n .then(() => {\n document.documentElement.removeAttribute(\n DATA_NAVIGATION_TYPE_ATTRIBUTE\n )\n })\n .catch(error => {\n console.error('View transition error:', error)\n })\n } else {\n return navigate(to)\n }\n return\n }\n\n const isSameRoute = to === location.pathname\n\n // Path navigation - with options\n if (document.startViewTransition) {\n const transition = document.startViewTransition(() => {\n navigate(to, {\n preventScrollReset: true,\n replace: isSameRoute,\n ...options,\n })\n })\n\n transition.finished\n .then(() => {\n document.documentElement.removeAttribute(\n DATA_NAVIGATION_TYPE_ATTRIBUTE\n )\n })\n .catch(error => {\n console.error('View transition error:', error)\n })\n } else {\n return navigate(to, options)\n }\n }\n\n return transitionNavigate\n}\n"],"names":["useNavigateWithTransition","navigate","useNavigate","location","useLocation","to","options","DATA_NAVIGATION_TYPE_ATTRIBUTE","error","isSameRoute"],"mappings":";;AAIO,SAASA,IAA4B;AAC1C,QAAMC,IAAWC,EAAY,GACvBC,IAAWC,EAAY;AAsDtB,SApDoB,CACzBC,GACAC,MACG;AACC,QAAA,OAAOD,KAAO,UAAU;AAE1B,UAAI,SAAS;AAKA,QAJQ,SAAS,oBAAoB,MAAM;AACpD,UAAAJ,EAASI,CAAE;AAAA,QAAA,CACZ,EAEU,SACR,KAAK,MAAM;AACV,mBAAS,gBAAgB;AAAA,YACvBE;AAAA,UACF;AAAA,QAAA,CACD,EACA,MAAM,CAASC,MAAA;AACN,kBAAA,MAAM,0BAA0BA,CAAK;AAAA,QAAA,CAC9C;AAAA;AAEH,eAAOP,EAASI,CAAE;AAEpB;AAAA,IAAA;AAGI,UAAAI,IAAcJ,MAAOF,EAAS;AAGpC,QAAI,SAAS;AASA,MARQ,SAAS,oBAAoB,MAAM;AACpD,QAAAF,EAASI,GAAI;AAAA,UACX,oBAAoB;AAAA,UACpB,SAASI;AAAA,UACT,GAAGH;AAAA,QAAA,CACJ;AAAA,MAAA,CACF,EAEU,SACR,KAAK,MAAM;AACV,iBAAS,gBAAgB;AAAA,UACvBC;AAAA,QACF;AAAA,MAAA,CACD,EACA,MAAM,CAASC,MAAA;AACN,gBAAA,MAAM,0BAA0BA,CAAK;AAAA,MAAA,CAC9C;AAAA;AAEI,aAAAP,EAASI,GAAIC,CAAO;AAAA,EAE/B;AAGF;"}
1
+ {"version":3,"file":"useNavigateWithTransition.js","sources":["../../../src/hooks/navigation/useNavigateWithTransition.ts"],"sourcesContent":["import {useLocation, useNavigate, NavigateOptions} from 'react-router'\n\nimport {DATA_NAVIGATION_TYPE_ATTRIBUTE} from '../../types'\n\ntype UseNavigateWithTransitionReturns = (\n to: string | number,\n options?: NavigateOptions\n) => void | Promise<void>\n\nexport function useNavigateWithTransition(): UseNavigateWithTransitionReturns {\n const navigate = useNavigate()\n const location = useLocation()\n\n const transitionNavigate = (\n to: string | number,\n options?: NavigateOptions\n ) => {\n if (typeof to === 'number') {\n // Delta navigation - no options parameter\n if (document.startViewTransition) {\n const transition = document.startViewTransition(() => {\n navigate(to)\n })\n\n transition.finished\n .then(() => {\n document.documentElement.removeAttribute(\n DATA_NAVIGATION_TYPE_ATTRIBUTE\n )\n })\n .catch(error => {\n console.error('View transition error:', error)\n })\n } else {\n return navigate(to)\n }\n return\n }\n\n const isSameRoute = to === location.pathname\n\n // Path navigation - with options\n if (document.startViewTransition) {\n const transition = document.startViewTransition(() => {\n navigate(to, {\n preventScrollReset: true,\n replace: isSameRoute,\n ...options,\n })\n })\n\n transition.finished\n .then(() => {\n document.documentElement.removeAttribute(\n DATA_NAVIGATION_TYPE_ATTRIBUTE\n )\n })\n .catch(error => {\n console.error('View transition error:', error)\n })\n } else {\n return navigate(to, options)\n }\n }\n\n return transitionNavigate\n}\n"],"names":["useNavigateWithTransition","navigate","useNavigate","location","useLocation","to","options","DATA_NAVIGATION_TYPE_ATTRIBUTE","error","isSameRoute"],"mappings":";;AASO,SAASA,IAA8D;AAC5E,QAAMC,IAAWC,EAAY,GACvBC,IAAWC,EAAY;AAsDtB,SApDoB,CACzBC,GACAC,MACG;AACC,QAAA,OAAOD,KAAO,UAAU;AAE1B,UAAI,SAAS;AAKA,QAJQ,SAAS,oBAAoB,MAAM;AACpD,UAAAJ,EAASI,CAAE;AAAA,QAAA,CACZ,EAEU,SACR,KAAK,MAAM;AACV,mBAAS,gBAAgB;AAAA,YACvBE;AAAA,UACF;AAAA,QAAA,CACD,EACA,MAAM,CAASC,MAAA;AACN,kBAAA,MAAM,0BAA0BA,CAAK;AAAA,QAAA,CAC9C;AAAA;AAEH,eAAOP,EAASI,CAAE;AAEpB;AAAA,IAAA;AAGI,UAAAI,IAAcJ,MAAOF,EAAS;AAGpC,QAAI,SAAS;AASA,MARQ,SAAS,oBAAoB,MAAM;AACpD,QAAAF,EAASI,GAAI;AAAA,UACX,oBAAoB;AAAA,UACpB,SAASI;AAAA,UACT,GAAGH;AAAA,QAAA,CACJ;AAAA,MAAA,CACF,EAEU,SACR,KAAK,MAAM;AACV,iBAAS,gBAAgB;AAAA,UACvBC;AAAA,QACF;AAAA,MAAA,CACD,EACA,MAAM,CAASC,MAAA;AACN,gBAAA,MAAM,0BAA0BA,CAAK;AAAA,MAAA,CAC9C;AAAA;AAEI,aAAAP,EAASI,GAAIC,CAAO;AAAA,EAE/B;AAGF;"}
@@ -1 +1 @@
1
- {"version":3,"file":"useShopNavigation.js","sources":["../../../src/hooks/navigation/useShopNavigation.ts"],"sourcesContent":["import {\n NavigateToCheckoutParams,\n NavigateToOrderParams,\n NavigateToProductParams,\n NavigateToShopParams,\n} from '@shopify/shop-minis-platform/actions'\n\nimport {useHandleAction} from '../../internal/useHandleAction'\nimport {useShopActions} from '../../internal/useShopActions'\n\ninterface UseShopNavigationReturns {\n /**\n * Navigates to a product.\n */\n navigateToProduct: (params: NavigateToProductParams) => Promise<void>\n /**\n * Navigates to a shop.\n */\n navigateToShop: (params: NavigateToShopParams) => Promise<void>\n /**\n * Navigates to an order.\n */\n navigateToOrder: (params: NavigateToOrderParams) => Promise<void>\n\n navigateToCheckout: (params: NavigateToCheckoutParams) => Promise<void>\n}\n\nexport const useShopNavigation = (): UseShopNavigationReturns => {\n const {\n navigateToProduct,\n navigateToShop,\n navigateToOrder,\n navigateToCheckout,\n } = useShopActions()\n\n return {\n navigateToProduct: useHandleAction(navigateToProduct),\n navigateToShop: useHandleAction(navigateToShop),\n navigateToOrder: useHandleAction(navigateToOrder),\n navigateToCheckout: useHandleAction(navigateToCheckout),\n }\n}\n"],"names":["useShopNavigation","navigateToProduct","navigateToShop","navigateToOrder","navigateToCheckout","useShopActions","useHandleAction"],"mappings":";;AA2BO,MAAMA,IAAoB,MAAgC;AACzD,QAAA;AAAA,IACJ,mBAAAC;AAAA,IACA,gBAAAC;AAAA,IACA,iBAAAC;AAAA,IACA,oBAAAC;AAAA,MACEC,EAAe;AAEZ,SAAA;AAAA,IACL,mBAAmBC,EAAgBL,CAAiB;AAAA,IACpD,gBAAgBK,EAAgBJ,CAAc;AAAA,IAC9C,iBAAiBI,EAAgBH,CAAe;AAAA,IAChD,oBAAoBG,EAAgBF,CAAkB;AAAA,EACxD;AACF;"}
1
+ {"version":3,"file":"useShopNavigation.js","sources":["../../../src/hooks/navigation/useShopNavigation.ts"],"sourcesContent":["import {\n NavigateToCheckoutParams,\n NavigateToOrderParams,\n NavigateToProductParams,\n NavigateToShopParams,\n} from '@shopify/shop-minis-platform/actions'\n\nimport {useHandleAction} from '../../internal/useHandleAction'\nimport {useShopActions} from '../../internal/useShopActions'\n\ninterface UseShopNavigationReturns {\n /**\n * Navigates to a product.\n */\n navigateToProduct: (params: NavigateToProductParams) => Promise<void>\n /**\n * Navigates to a shop.\n */\n navigateToShop: (params: NavigateToShopParams) => Promise<void>\n /**\n * Navigates to an order.\n */\n navigateToOrder: (params: NavigateToOrderParams) => Promise<void>\n /**\n * Navigates to a checkout.\n */\n navigateToCheckout: (params: NavigateToCheckoutParams) => Promise<void>\n}\n\nexport const useShopNavigation = (): UseShopNavigationReturns => {\n const {\n navigateToProduct,\n navigateToShop,\n navigateToOrder,\n navigateToCheckout,\n } = useShopActions()\n\n return {\n navigateToProduct: useHandleAction(navigateToProduct),\n navigateToShop: useHandleAction(navigateToShop),\n navigateToOrder: useHandleAction(navigateToOrder),\n navigateToCheckout: useHandleAction(navigateToCheckout),\n }\n}\n"],"names":["useShopNavigation","navigateToProduct","navigateToShop","navigateToOrder","navigateToCheckout","useShopActions","useHandleAction"],"mappings":";;AA6BO,MAAMA,IAAoB,MAAgC;AACzD,QAAA;AAAA,IACJ,mBAAAC;AAAA,IACA,gBAAAC;AAAA,IACA,iBAAAC;AAAA,IACA,oBAAAC;AAAA,MACEC,EAAe;AAEZ,SAAA;AAAA,IACL,mBAAmBC,EAAgBL,CAAiB;AAAA,IACpD,gBAAgBK,EAAgBJ,CAAc;AAAA,IAC9C,iBAAiBI,EAAgBH,CAAe;AAAA,IAChD,oBAAoBG,EAAgBF,CAAkB;AAAA,EACxD;AACF;"}
@@ -1 +1 @@
1
- {"version":3,"file":"useCurrentUser.js","sources":["../../../src/hooks/user/useCurrentUser.ts"],"sourcesContent":["import {useShopActions} from '../../internal/useShopActions'\nimport {useShopActionsDataFetching} from '../../internal/useShopActionsDataFetching'\nimport {\n DataHookOptionsBase,\n DataHookReturnsBase,\n UserProfile,\n} from '../../types'\n\nexport interface UseCurrentUserParams extends DataHookOptionsBase {}\n\nexport interface UseCurrentUserReturns extends DataHookReturnsBase {\n currentUser: UserProfile | null\n}\n\n/**\n * Hook to fetch the current user's profile.\n */\nexport const useCurrentUser = (\n params?: UseCurrentUserParams\n): UseCurrentUserReturns => {\n const {skip, ...shopActionParams} = params || {}\n const {getCurrentUser} = useShopActions()\n\n const {data, ...rest} = useShopActionsDataFetching(\n getCurrentUser,\n shopActionParams,\n {\n skip,\n hook: 'useCurrentUser',\n }\n )\n\n return {\n ...rest,\n currentUser: data,\n }\n}\n"],"names":["useCurrentUser","params","skip","shopActionParams","getCurrentUser","useShopActions","data","rest","useShopActionsDataFetching"],"mappings":";;AAiBa,MAAAA,IAAiB,CAC5BC,MAC0B;AAC1B,QAAM,EAAC,MAAAC,GAAM,GAAGC,EAAgB,IAAIF,KAAU,CAAC,GACzC,EAAC,gBAAAG,EAAc,IAAIC,EAAe,GAElC,EAAC,MAAAC,GAAM,GAAGC,EAAA,IAAQC;AAAA,IACtBJ;AAAA,IACAD;AAAA,IACA;AAAA,MACE,MAAAD;AAAA,MACA,MAAM;AAAA,IAAA;AAAA,EAEV;AAEO,SAAA;AAAA,IACL,GAAGK;AAAA,IACH,aAAaD;AAAA,EACf;AACF;"}
1
+ {"version":3,"file":"useCurrentUser.js","sources":["../../../src/hooks/user/useCurrentUser.ts"],"sourcesContent":["import {useShopActions} from '../../internal/useShopActions'\nimport {useShopActionsDataFetching} from '../../internal/useShopActionsDataFetching'\nimport {\n DataHookOptionsBase,\n DataHookReturnsBase,\n UserProfile,\n} from '../../types'\n\nexport interface UseCurrentUserParams extends DataHookOptionsBase {}\n\nexport interface UseCurrentUserReturns extends DataHookReturnsBase {\n /**\n * The current user logged into Shop.\n */\n currentUser: UserProfile | null\n}\n\n/**\n * Hook to fetch the current user's profile.\n */\nexport const useCurrentUser = (\n params?: UseCurrentUserParams\n): UseCurrentUserReturns => {\n const {skip, ...shopActionParams} = params || {}\n const {getCurrentUser} = useShopActions()\n\n const {data, ...rest} = useShopActionsDataFetching(\n getCurrentUser,\n shopActionParams,\n {\n skip,\n hook: 'useCurrentUser',\n }\n )\n\n return {\n ...rest,\n currentUser: data,\n }\n}\n"],"names":["useCurrentUser","params","skip","shopActionParams","getCurrentUser","useShopActions","data","rest","useShopActionsDataFetching"],"mappings":";;AAoBa,MAAAA,IAAiB,CAC5BC,MAC0B;AAC1B,QAAM,EAAC,MAAAC,GAAM,GAAGC,EAAgB,IAAIF,KAAU,CAAC,GACzC,EAAC,gBAAAG,EAAc,IAAIC,EAAe,GAElC,EAAC,MAAAC,GAAM,GAAGC,EAAA,IAAQC;AAAA,IACtBJ;AAAA,IACAD;AAAA,IACA;AAAA,MACE,MAAAD;AAAA,MACA,MAAM;AAAA,IAAA;AAAA,EAEV;AAEO,SAAA;AAAA,IACL,GAAGK;AAAA,IACH,aAAaD;AAAA,EACf;AACF;"}
@@ -1 +1 @@
1
- {"version":3,"file":"useFollowedShopsActions.js","sources":["../../../src/hooks/user/useFollowedShopsActions.ts"],"sourcesContent":["import {\n FollowShopParams,\n UnfollowShopParams,\n} from '@shopify/shop-minis-platform/actions'\n\nimport {useHandleAction} from '../../internal/useHandleAction'\nimport {useShopActions} from '../../internal/useShopActions'\n\ninterface UseFollowedShopsActionsReturns {\n /**\n * Follow a shop.\n */\n followShop: (params: FollowShopParams) => Promise<boolean>\n /**\n * Unfollow a shop.\n */\n unfollowShop: (params: UnfollowShopParams) => Promise<boolean>\n}\n\nexport const useFollowedShopsActions = (): UseFollowedShopsActionsReturns => {\n const {followShop, unfollowShop} = useShopActions()\n\n return {\n followShop: useHandleAction(followShop),\n unfollowShop: useHandleAction(unfollowShop),\n }\n}\n"],"names":["useFollowedShopsActions","followShop","unfollowShop","useShopActions","useHandleAction"],"mappings":";;AAmBO,MAAMA,IAA0B,MAAsC;AAC3E,QAAM,EAAC,YAAAC,GAAY,cAAAC,EAAY,IAAIC,EAAe;AAE3C,SAAA;AAAA,IACL,YAAYC,EAAgBH,CAAU;AAAA,IACtC,cAAcG,EAAgBF,CAAY;AAAA,EAC5C;AACF;"}
1
+ {"version":3,"file":"useFollowedShopsActions.js","sources":["../../../src/hooks/user/useFollowedShopsActions.ts"],"sourcesContent":["import {\n FollowShopParams,\n UnfollowShopParams,\n} from '@shopify/shop-minis-platform/actions'\n\nimport {useHandleAction} from '../../internal/useHandleAction'\nimport {useShopActions} from '../../internal/useShopActions'\n\ninterface UseFollowedShopsActionsReturns {\n /**\n * Follows a shop.\n */\n followShop: (params: FollowShopParams) => Promise<boolean>\n /**\n * Unfollows a shop.\n */\n unfollowShop: (params: UnfollowShopParams) => Promise<boolean>\n}\n\nexport const useFollowedShopsActions = (): UseFollowedShopsActionsReturns => {\n const {followShop, unfollowShop} = useShopActions()\n\n return {\n followShop: useHandleAction(followShop),\n unfollowShop: useHandleAction(unfollowShop),\n }\n}\n"],"names":["useFollowedShopsActions","followShop","unfollowShop","useShopActions","useHandleAction"],"mappings":";;AAmBO,MAAMA,IAA0B,MAAsC;AAC3E,QAAM,EAAC,YAAAC,GAAY,cAAAC,EAAY,IAAIC,EAAe;AAE3C,SAAA;AAAA,IACL,YAAYC,EAAgBH,CAAU;AAAA,IACtC,cAAcG,EAAgBF,CAAY;AAAA,EAC5C;AACF;"}
@@ -1 +1 @@
1
- {"version":3,"file":"useImagePicker.js","sources":["../../../src/hooks/util/useImagePicker.tsx"],"sourcesContent":["import {\n CameraFacing,\n useImagePickerContext,\n} from '../../providers/ImagePickerProvider'\n\ninterface UseImagePickerReturn {\n openCamera: (cameraFacing?: CameraFacing) => Promise<File>\n openGallery: () => Promise<File>\n}\n\nexport function useImagePicker(): UseImagePickerReturn {\n const {openCamera, openGallery} = useImagePickerContext()\n\n return {\n openCamera,\n openGallery,\n }\n}\n"],"names":["useImagePicker","openCamera","openGallery","useImagePickerContext"],"mappings":";AAUO,SAASA,IAAuC;AACrD,QAAM,EAAC,YAAAC,GAAY,aAAAC,EAAW,IAAIC,EAAsB;AAEjD,SAAA;AAAA,IACL,YAAAF;AAAA,IACA,aAAAC;AAAA,EACF;AACF;"}
1
+ {"version":3,"file":"useImagePicker.js","sources":["../../../src/hooks/util/useImagePicker.ts"],"sourcesContent":["import {\n CameraFacing,\n useImagePickerContext,\n} from '../../providers/ImagePickerProvider'\n\ninterface UseImagePickerReturns {\n /**\n * Opens the camera to take a photo.\n */\n openCamera: (cameraFacing?: CameraFacing) => Promise<File>\n /**\n * Opens the gallery to select an image.\n */\n openGallery: () => Promise<File>\n}\n\nexport function useImagePicker(): UseImagePickerReturns {\n const {openCamera, openGallery} = useImagePickerContext()\n\n return {\n openCamera,\n openGallery,\n }\n}\n"],"names":["useImagePicker","openCamera","openGallery","useImagePickerContext"],"mappings":";AAgBO,SAASA,IAAwC;AACtD,QAAM,EAAC,YAAAC,GAAY,aAAAC,EAAW,IAAIC,EAAsB;AAEjD,SAAA;AAAA,IACL,YAAAF;AAAA,IACA,aAAAC;AAAA,EACF;AACF;"}
package/dist/mocks.js CHANGED
@@ -1,23 +1,23 @@
1
- const e = (t, o, r = "99.99", n) => ({
1
+ const e = (t, o, r = "99.99", s) => ({
2
2
  id: t,
3
3
  title: o,
4
4
  price: { amount: r, currencyCode: "USD" },
5
- ...n && {
6
- compareAtPrice: { amount: n, currencyCode: "USD" }
5
+ ...s && {
6
+ compareAtPrice: { amount: s, currencyCode: "USD" }
7
7
  },
8
8
  reviewAnalytics: { averageRating: 4.5, reviewCount: 10 },
9
9
  shop: i("shop1", "Mock Shop"),
10
10
  defaultVariantId: `variant-${t}`,
11
11
  isFavorited: !1,
12
12
  featuredImage: {
13
- url: "https://cdn.shopify.com/s/files/1/0621/0463/3599/files/61ChhrRjK9L._AC_SL1000_1639abe8-4cd3-4bee-9867-73f26b0acf0a.jpg?v=1702559955",
13
+ url: "https://cdn.shopify.com/static/sample-images/teapot.jpg",
14
14
  altText: o
15
15
  }
16
16
  }), i = (t, o, r) => {
17
- const c = Array.from({ length: 3 }, (m, s) => ({
18
- url: `https://picsum.photos/400/400?random=${t}-${s}`,
17
+ const c = Array.from({ length: 3 }, (m, n) => ({
18
+ url: `https://picsum.photos/400/400?random=${t}-${n}`,
19
19
  sensitive: !1,
20
- altText: `${o} featured image ${s + 1}`
20
+ altText: `${o} featured image ${n + 1}`
21
21
  }));
22
22
  return {
23
23
  id: t,
@@ -274,7 +274,7 @@ function l() {
274
274
  externalId: null,
275
275
  image: {
276
276
  id: "img-123",
277
- url: "https://example.com/content-image.jpg",
277
+ url: "https://cdn.shopify.com/s/files/1/0633/6574/2742/files/Namnlosdesign-47.png?v=1740438079",
278
278
  width: 800,
279
279
  height: 600
280
280
  },
@@ -291,7 +291,7 @@ function l() {
291
291
  publicId: "content-123",
292
292
  image: {
293
293
  id: "img-123",
294
- url: "https://example.com/content-image.jpg",
294
+ url: "https://cdn.shopify.com/s/files/1/0633/6574/2742/files/Namnlosdesign-47.png?v=1740438079",
295
295
  width: 800,
296
296
  height: 600
297
297
  },
package/dist/mocks.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"mocks.js","sources":["../src/mocks.ts"],"sourcesContent":["import {Product, Gender} from '@shopify/shop-minis-platform'\nimport {ShopActions} from '@shopify/shop-minis-platform/actions'\n\n// Helper functions for common data structures\nexport const createProduct = (\n id: string,\n title: string,\n price = '99.99',\n compareAtPrice?: string\n): Product => ({\n id,\n title,\n price: {amount: price, currencyCode: 'USD'},\n ...(compareAtPrice && {\n compareAtPrice: {amount: compareAtPrice, currencyCode: 'USD'},\n }),\n reviewAnalytics: {averageRating: 4.5, reviewCount: 10},\n shop: createShop('shop1', 'Mock Shop'),\n defaultVariantId: `variant-${id}`,\n isFavorited: false,\n featuredImage: {\n url: `https://cdn.shopify.com/s/files/1/0621/0463/3599/files/61ChhrRjK9L._AC_SL1000_1639abe8-4cd3-4bee-9867-73f26b0acf0a.jpg?v=1702559955`,\n altText: title,\n },\n})\n\nexport const createShop = (\n id: string,\n name: string,\n options?: {\n themeType?: 'coverImage' | 'brandColor' | 'logoColor' | 'none'\n withBrandSettings?: boolean\n primaryColor?: string\n logoDominantColor?: string\n logoAverageColor?: string\n coverDominantColor?: string\n wordmarkUrl?: string\n coverImageUrl?: string\n featuredImagesLimit?: number\n }\n) => {\n // Determine theme configuration\n const themeType = options?.themeType || 'none'\n const shouldHaveBrandSettings =\n options?.withBrandSettings || themeType !== 'none'\n\n // Generate featured images\n const featuredImagesCount = options?.featuredImagesLimit || 3\n const featuredImages = Array.from({length: featuredImagesCount}, (_, i) => ({\n url: `https://picsum.photos/400/400?random=${id}-${i}`,\n sensitive: false,\n altText: `${name} featured image ${i + 1}`,\n }))\n\n // Configure colors based on theme type\n const getThemeColors = () => {\n switch (themeType) {\n case 'coverImage':\n return {\n primary: options?.primaryColor,\n logoDominant: options?.logoDominantColor,\n logoAverage: options?.logoAverageColor,\n coverDominant: options?.coverDominantColor || '#FF6B35',\n }\n case 'brandColor':\n return {\n primary: options?.primaryColor || '#27AE60',\n logoDominant: options?.logoDominantColor,\n logoAverage: options?.logoAverageColor,\n coverDominant: options?.coverDominantColor,\n }\n case 'logoColor':\n return {\n primary: options?.primaryColor,\n logoDominant: options?.logoDominantColor || '#E74C3C',\n logoAverage: options?.logoAverageColor,\n coverDominant: options?.coverDominantColor,\n }\n default:\n return {\n primary: options?.primaryColor,\n logoDominant: options?.logoDominantColor,\n logoAverage: options?.logoAverageColor,\n coverDominant: options?.coverDominantColor,\n }\n }\n }\n\n // Configure header theme\n const createHeaderTheme = () => {\n if (themeType === 'coverImage' || options?.coverImageUrl) {\n return {\n id: `header-theme-${id}`,\n coverImage: {\n url:\n options?.coverImageUrl ||\n 'https://images.unsplash.com/photo-1441986300917-64674bd600d8?w=800&h=400&fit=crop',\n altText: `${name} cover image`,\n sensitive: false,\n thumbhash: 'k9oGHQRnh493V4dIeHeXh4h3iIeI',\n },\n wordmark:\n options?.wordmarkUrl || themeType === 'coverImage'\n ? {\n url:\n options?.wordmarkUrl ||\n 'https://merrypeople.com/cdn/shop/files/Transparent_Background_1.png?v=1696465429&width=1024',\n altText: `${name} wordmark`,\n sensitive: false,\n }\n : undefined,\n }\n }\n\n if (options?.wordmarkUrl) {\n return {\n id: `header-theme-${id}`,\n wordmark: {\n url: options.wordmarkUrl,\n altText: `${name} wordmark`,\n sensitive: false,\n },\n }\n }\n\n return undefined\n }\n\n return {\n id,\n name,\n primaryDomain: {\n url: `https://${name.toLowerCase().replace(/\\s+/g, '-')}.com`,\n },\n reviewAnalytics: {averageRating: 4.3, reviewCount: 50},\n visualTheme: {\n id: `visual-theme-${id}`,\n featuredImages,\n logoImage: {\n url: `https://picsum.photos/100/100?random=${id}`,\n sensitive: false,\n },\n brandSettings: shouldHaveBrandSettings\n ? {\n id: `brand-settings-${id}`,\n colors: {\n id: `colors-${id}`,\n ...getThemeColors(),\n },\n headerTheme: createHeaderTheme(),\n }\n : undefined,\n },\n }\n}\n\nconst createPagination = (hasNext = false) => ({\n hasNextPage: hasNext,\n endCursor: hasNext ? 'cursor123' : null,\n})\n\nconst createProductList = (id: string, name: string, products: any[] = []) => ({\n id,\n publicId: `public-${id}`,\n name,\n products,\n})\n\n// Helper type to extract the data type from a ShopAction\ntype ShopActionDataType<T> = T extends (\n ...args: any[]\n) => Promise<{ok: true; data: infer R} | {ok: false; error: any}>\n ? R\n : never\n\nfunction makeMockMethod<K extends keyof ShopActions>(\n key: K,\n result: ShopActionDataType<ShopActions[K]>\n): ShopActions[K] {\n return ((params: Parameters<ShopActions[K]>[0]) => {\n console.log(`[Mock Action] ${String(key)}`, params)\n return Promise.resolve({ok: true as const, data: result})\n }) as ShopActions[K]\n}\n\nfunction makeMockActions(): ShopActions {\n const results: {\n [K in keyof ShopActions]: ShopActionDataType<ShopActions[K]>\n } = {\n followShop: true,\n unfollowShop: false,\n favorite: undefined,\n unfavorite: undefined,\n getShopAppInformation: {\n appVersion: '1.0.0',\n buildNumber: '12345',\n buildId: 'dev-build-123',\n },\n productRecommendationImpression: undefined,\n productRecommendationClick: undefined,\n hideEntryPoint: undefined,\n closeMini: undefined,\n getAccountInformation: {\n status: 'available',\n value: 'user@example.com',\n },\n getCurrentUser: {\n data: {\n displayName: 'John Doe',\n avatarImage: {url: 'https://example.com/avatar.jpg'},\n },\n },\n createOrderAttribution: undefined,\n addToCart: undefined,\n buyProduct: undefined,\n buyProducts: undefined,\n showErrorScreen: undefined,\n showErrorToast: undefined,\n getDeeplinkPaths: {\n matchers: ['/products', '/collections', '/cart'],\n },\n navigateToDeeplink: undefined,\n navigateToShop: undefined,\n navigateToProduct: undefined,\n navigateToOrder: undefined,\n navigateToCheckout: undefined,\n createImageUploadLink: {\n targets: [\n {\n url: 'https://example.com/upload',\n resourceUrl: 'https://example.com/resource',\n parameters: [{name: 'key', value: 'upload-123'}],\n },\n ],\n },\n completeImageUpload: {\n files: [\n {\n id: 'file-123',\n fileStatus: 'READY',\n image: {url: 'https://example.com/image.jpg'},\n },\n ],\n },\n getPersistedItem: 'stored-value',\n setPersistedItem: undefined,\n removePersistedItem: undefined,\n getAllPersistedKeys: ['key1', 'key2', 'key3'],\n clearPersistedItems: undefined,\n getInternalPersistedItem: 'internal-value',\n setInternalPersistedItem: undefined,\n removeInternalPersistedItem: undefined,\n getAllInternalPersistedKeys: ['internal-key1', 'internal-key2'],\n clearInternalPersistedItems: undefined,\n getSecret: 'secret-value',\n setSecret: undefined,\n removeSecret: undefined,\n reportInteraction: undefined,\n reportImpression: undefined,\n reportContentImpression: undefined,\n getProductLists: {\n data: [\n createProductList('list-1', 'Wishlist'),\n createProductList('list-2', 'Favorites'),\n ],\n pageInfo: createPagination(),\n },\n getProductList: {\n data: createProductList('list-1', 'Wishlist', [\n createProduct('prod-1', 'Sample Product'),\n ]),\n pageInfo: createPagination(),\n },\n addProductList: createProductList('list-3', 'New List'),\n removeProductList: undefined,\n renameProductList: createProductList('list-1', 'Updated Wishlist'),\n addProductListItem: undefined,\n removeProductListItem: undefined,\n getRecommendedProducts: {\n data: [\n createProduct('rec-1', 'Recommended Product 1', '79.99'),\n createProduct('rec-2', 'Recommended Product 2', '129.99'),\n createProduct('rec-3', 'Recommended Product 3', '129.99'),\n createProduct('rec-4', 'Recommended Product 4', '29.99'),\n createProduct('rec-5', 'Recommended Product 5', '39.99'),\n createProduct('rec-6', 'Recommended Product 6', '49.99'),\n createProduct('rec-7', 'Recommended Product 7', '59.99'),\n createProduct('rec-8', 'Recommended Product 8', '69.99'),\n createProduct('rec-9', 'Recommended Product 9', '129.99'),\n ],\n pageInfo: createPagination(),\n },\n getRecommendedShops: {\n data: [\n createShop('shop-1', 'Amazing Store'),\n createShop('shop-2', 'Best Deals Shop'),\n ],\n pageInfo: createPagination(),\n },\n searchProductsByShop: {\n data: [\n createProduct('search-1', 'Search Result 1', '59.99'),\n createProduct('search-2', 'Search Result 2', '89.99'),\n ],\n pageInfo: createPagination(),\n },\n getOrders: {\n data: [\n {\n id: 'order-1',\n name: '#1001',\n lineItems: [\n {\n productTitle: 'Sample Product',\n variantTitle: 'Medium',\n quantity: 2,\n product: null,\n },\n ],\n shop: createShop('shop-1', 'Sample Shop'),\n },\n ],\n pageInfo: createPagination(),\n },\n getBuyerAttributes: {\n data: {\n genderAffinity: 'NEUTRAL' as Gender,\n categoryAffinities: [\n {id: 'cat1', name: 'Electronics'},\n {id: 'cat2', name: 'Clothing'},\n ],\n },\n },\n showFeedbackSheet: undefined,\n getPopularProducts: {\n data: [\n createProduct('pop-1', 'The Hero Snowboard', '702.95'),\n createProduct('pop-2', 'Snow Jacket', '605.95', '702.00'),\n createProduct('pop-3', 'Winter Gloves', '89.95'),\n createProduct('pop-4', 'Summer Gloves', '89.95'),\n createProduct('pop-5', 'Spring Gloves', '89.95'),\n createProduct('pop-6', 'Playstation 5', '499.95'),\n createProduct('pop-7', 'Xbox Series X', '499.95'),\n createProduct('pop-8', 'Nintendo Switch', '299.95'),\n createProduct('pop-9', 'Playstation 4', '299.95'),\n createProduct('pop-10', 'Nintendo 3DS', '89.95'),\n ],\n pageInfo: createPagination(),\n },\n share: {\n message: 'Shared!',\n success: true,\n },\n getCuratedProducts: {\n data: [\n createProduct('cur-1', 'Curated Product 1', '79.99'),\n createProduct('cur-2', 'Curated Product 2', '129.99'),\n ],\n pageInfo: createPagination(),\n },\n getSavedProducts: {\n data: [createProduct('saved-1', 'Saved Product 1', '49.99')],\n pageInfo: createPagination(),\n },\n getRecentProducts: {\n data: [createProduct('recent-1', 'Recent Product 1', '59.99')],\n pageInfo: createPagination(),\n },\n getProductSearch: {\n data: [createProduct('search-3', 'Search Product 3', '39.99')],\n pageInfo: createPagination(),\n },\n getProducts: {data: [createProduct('prod-2', 'Product 2', '19.99')]},\n getProduct: {data: createProduct('prod-1', 'Sample Product')},\n getProductVariants: {\n data: [\n {\n id: 'variant-1',\n isFavorited: false,\n image: {url: 'https://example.com/variant-1.jpg'},\n price: {amount: '19.99', currencyCode: 'USD'},\n compareAtPrice: {amount: '29.99', currencyCode: 'USD'},\n },\n ],\n pageInfo: createPagination(),\n },\n getProductMedia: {\n data: [\n {\n id: 'media-1',\n image: {url: 'https://example.com/media-1.jpg'},\n mediaContentType: 'IMAGE',\n alt: 'Sample product image',\n },\n ],\n pageInfo: createPagination(),\n },\n getShop: {data: createShop('shop-1', 'Sample Shop')},\n getRecentShops: {\n data: [createShop('recent-shop-1', 'Recent Shop 1')],\n pageInfo: createPagination(),\n },\n getFollowedShops: {\n data: [createShop('followed-shop-1', 'Followed Shop 1')],\n pageInfo: createPagination(),\n },\n previewProductInAr: undefined,\n createContent: {\n data: {\n publicId: 'content-123',\n externalId: null,\n image: {\n id: 'img-123',\n url: 'https://example.com/content-image.jpg',\n width: 800,\n height: 600,\n },\n title: 'Mock Content',\n description: 'This is a mock content item',\n visibility: ['DISCOVERABLE'],\n shareableUrl: 'https://example.com/content/123',\n products: null,\n },\n },\n getContent: {\n data: [\n {\n publicId: 'content-123',\n image: {\n id: 'img-123',\n url: 'https://example.com/content-image.jpg',\n width: 800,\n height: 600,\n },\n title: 'Mock Content',\n visibility: ['DISCOVERABLE'],\n },\n ],\n },\n } as const\n\n const mock: Partial<ShopActions> = {}\n for (const key in results) {\n if (Object.prototype.hasOwnProperty.call(results, key)) {\n // @ts-expect-error: dynamic assignment is safe due to exhaustive mapping\n mock[key] = makeMockMethod(\n key as keyof ShopActions,\n results[key as keyof typeof results]\n )\n }\n }\n return mock as ShopActions\n}\n\n// Detect if running on a mobile device\nconst isMobile = (): boolean => {\n const userAgent = navigator.userAgent.toLowerCase()\n const isIOS = /iphone|ipad|ipod/.test(userAgent)\n const isAndroid = /android/.test(userAgent)\n\n return isIOS || isAndroid\n}\n\nexport const injectMocks = () => {\n // Only inject mocks if we aren't on a mobile device\n if (isMobile()) {\n return\n }\n\n if (!window.minisSDK) {\n window.minisSDK = makeMockActions()\n window.minisParams = {\n handle: 'mock-handle',\n initialUrl: '/mock-initial-url',\n platform: 'web',\n }\n }\n}\n"],"names":["createProduct","id","title","price","compareAtPrice","createShop","name","options","featuredImages","_","i","createPagination","hasNext","createProductList","products","makeMockMethod","key","result","params","makeMockActions","results","mock","isMobile","userAgent","isIOS","isAndroid","injectMocks"],"mappings":"AAIO,MAAMA,IAAgB,CAC3BC,GACAC,GACAC,IAAQ,SACRC,OACa;AAAA,EACb,IAAAH;AAAA,EACA,OAAAC;AAAA,EACA,OAAO,EAAC,QAAQC,GAAO,cAAc,MAAK;AAAA,EAC1C,GAAIC,KAAkB;AAAA,IACpB,gBAAgB,EAAC,QAAQA,GAAgB,cAAc,MAAK;AAAA,EAC9D;AAAA,EACA,iBAAiB,EAAC,eAAe,KAAK,aAAa,GAAE;AAAA,EACrD,MAAMC,EAAW,SAAS,WAAW;AAAA,EACrC,kBAAkB,WAAWJ,CAAE;AAAA,EAC/B,aAAa;AAAA,EACb,eAAe;AAAA,IACb,KAAK;AAAA,IACL,SAASC;AAAA,EAAA;AAEb,IAEaG,IAAa,CACxBJ,GACAK,GACAC,MAWG;AAQG,QAAAC,IAAiB,MAAM,KAAK,EAAC,QAAQ,EAAmB,GAAG,CAACC,GAAGC,OAAO;AAAA,IAC1E,KAAK,wCAAwCT,CAAE,IAAIS,CAAC;AAAA,IACpD,WAAW;AAAA,IACX,SAAS,GAAGJ,CAAI,mBAAmBI,IAAI,CAAC;AAAA,EAAA,EACxC;AA4EK,SAAA;AAAA,IACL,IAAAT;AAAA,IACA,MAAAK;AAAA,IACA,eAAe;AAAA,MACb,KAAK,WAAWA,EAAK,cAAc,QAAQ,QAAQ,GAAG,CAAC;AAAA,IACzD;AAAA,IACA,iBAAiB,EAAC,eAAe,KAAK,aAAa,GAAE;AAAA,IACrD,aAAa;AAAA,MACX,IAAI,gBAAgBL,CAAE;AAAA,MACtB,gBAAAO;AAAA,MACA,WAAW;AAAA,QACT,KAAK,wCAAwCP,CAAE;AAAA,QAC/C,WAAW;AAAA,MACb;AAAA,MACA,eASI;AAAA,IAAA;AAAA,EAER;AACF,GAEMU,IAAmB,CAACC,IAAU,QAAW;AAAA,EAC7C,aAAaA;AAAA,EACb,WAAWA,IAAU,cAAc;AACrC,IAEMC,IAAoB,CAACZ,GAAYK,GAAcQ,IAAkB,CAAA,OAAQ;AAAA,EAC7E,IAAAb;AAAA,EACA,UAAU,UAAUA,CAAE;AAAA,EACtB,MAAAK;AAAA,EACA,UAAAQ;AACF;AASA,SAASC,EACPC,GACAC,GACgB;AAChB,SAAQ,CAACC,OACP,QAAQ,IAAI,iBAAiB,OAAOF,CAAG,CAAC,IAAIE,CAAM,GAC3C,QAAQ,QAAQ,EAAC,IAAI,IAAe,MAAMD,GAAO;AAE5D;AAEA,SAASE,IAA+B;AACtC,QAAMC,IAEF;AAAA,IACF,YAAY;AAAA,IACZ,cAAc;AAAA,IACd,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,uBAAuB;AAAA,MACrB,YAAY;AAAA,MACZ,aAAa;AAAA,MACb,SAAS;AAAA,IACX;AAAA,IACA,iCAAiC;AAAA,IACjC,4BAA4B;AAAA,IAC5B,gBAAgB;AAAA,IAChB,WAAW;AAAA,IACX,uBAAuB;AAAA,MACrB,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,IACA,gBAAgB;AAAA,MACd,MAAM;AAAA,QACJ,aAAa;AAAA,QACb,aAAa,EAAC,KAAK,iCAAgC;AAAA,MAAA;AAAA,IAEvD;AAAA,IACA,wBAAwB;AAAA,IACxB,WAAW;AAAA,IACX,YAAY;AAAA,IACZ,aAAa;AAAA,IACb,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,kBAAkB;AAAA,MAChB,UAAU,CAAC,aAAa,gBAAgB,OAAO;AAAA,IACjD;AAAA,IACA,oBAAoB;AAAA,IACpB,gBAAgB;AAAA,IAChB,mBAAmB;AAAA,IACnB,iBAAiB;AAAA,IACjB,oBAAoB;AAAA,IACpB,uBAAuB;AAAA,MACrB,SAAS;AAAA,QACP;AAAA,UACE,KAAK;AAAA,UACL,aAAa;AAAA,UACb,YAAY,CAAC,EAAC,MAAM,OAAO,OAAO,aAAa,CAAA;AAAA,QAAA;AAAA,MACjD;AAAA,IAEJ;AAAA,IACA,qBAAqB;AAAA,MACnB,OAAO;AAAA,QACL;AAAA,UACE,IAAI;AAAA,UACJ,YAAY;AAAA,UACZ,OAAO,EAAC,KAAK,gCAA+B;AAAA,QAAA;AAAA,MAC9C;AAAA,IAEJ;AAAA,IACA,kBAAkB;AAAA,IAClB,kBAAkB;AAAA,IAClB,qBAAqB;AAAA,IACrB,qBAAqB,CAAC,QAAQ,QAAQ,MAAM;AAAA,IAC5C,qBAAqB;AAAA,IACrB,0BAA0B;AAAA,IAC1B,0BAA0B;AAAA,IAC1B,6BAA6B;AAAA,IAC7B,6BAA6B,CAAC,iBAAiB,eAAe;AAAA,IAC9D,6BAA6B;AAAA,IAC7B,WAAW;AAAA,IACX,WAAW;AAAA,IACX,cAAc;AAAA,IACd,mBAAmB;AAAA,IACnB,kBAAkB;AAAA,IAClB,yBAAyB;AAAA,IACzB,iBAAiB;AAAA,MACf,MAAM;AAAA,QACJP,EAAkB,UAAU,UAAU;AAAA,QACtCA,EAAkB,UAAU,WAAW;AAAA,MACzC;AAAA,MACA,UAAUF,EAAiB;AAAA,IAC7B;AAAA,IACA,gBAAgB;AAAA,MACd,MAAME,EAAkB,UAAU,YAAY;AAAA,QAC5Cb,EAAc,UAAU,gBAAgB;AAAA,MAAA,CACzC;AAAA,MACD,UAAUW,EAAiB;AAAA,IAC7B;AAAA,IACA,gBAAgBE,EAAkB,UAAU,UAAU;AAAA,IACtD,mBAAmB;AAAA,IACnB,mBAAmBA,EAAkB,UAAU,kBAAkB;AAAA,IACjE,oBAAoB;AAAA,IACpB,uBAAuB;AAAA,IACvB,wBAAwB;AAAA,MACtB,MAAM;AAAA,QACJb,EAAc,SAAS,yBAAyB,OAAO;AAAA,QACvDA,EAAc,SAAS,yBAAyB,QAAQ;AAAA,QACxDA,EAAc,SAAS,yBAAyB,QAAQ;AAAA,QACxDA,EAAc,SAAS,yBAAyB,OAAO;AAAA,QACvDA,EAAc,SAAS,yBAAyB,OAAO;AAAA,QACvDA,EAAc,SAAS,yBAAyB,OAAO;AAAA,QACvDA,EAAc,SAAS,yBAAyB,OAAO;AAAA,QACvDA,EAAc,SAAS,yBAAyB,OAAO;AAAA,QACvDA,EAAc,SAAS,yBAAyB,QAAQ;AAAA,MAC1D;AAAA,MACA,UAAUW,EAAiB;AAAA,IAC7B;AAAA,IACA,qBAAqB;AAAA,MACnB,MAAM;AAAA,QACJN,EAAW,UAAU,eAAe;AAAA,QACpCA,EAAW,UAAU,iBAAiB;AAAA,MACxC;AAAA,MACA,UAAUM,EAAiB;AAAA,IAC7B;AAAA,IACA,sBAAsB;AAAA,MACpB,MAAM;AAAA,QACJX,EAAc,YAAY,mBAAmB,OAAO;AAAA,QACpDA,EAAc,YAAY,mBAAmB,OAAO;AAAA,MACtD;AAAA,MACA,UAAUW,EAAiB;AAAA,IAC7B;AAAA,IACA,WAAW;AAAA,MACT,MAAM;AAAA,QACJ;AAAA,UACE,IAAI;AAAA,UACJ,MAAM;AAAA,UACN,WAAW;AAAA,YACT;AAAA,cACE,cAAc;AAAA,cACd,cAAc;AAAA,cACd,UAAU;AAAA,cACV,SAAS;AAAA,YAAA;AAAA,UAEb;AAAA,UACA,MAAMN,EAAW,UAAU,aAAa;AAAA,QAAA;AAAA,MAE5C;AAAA,MACA,UAAUM,EAAiB;AAAA,IAC7B;AAAA,IACA,oBAAoB;AAAA,MAClB,MAAM;AAAA,QACJ,gBAAgB;AAAA,QAChB,oBAAoB;AAAA,UAClB,EAAC,IAAI,QAAQ,MAAM,cAAa;AAAA,UAChC,EAAC,IAAI,QAAQ,MAAM,WAAU;AAAA,QAAA;AAAA,MAC/B;AAAA,IAEJ;AAAA,IACA,mBAAmB;AAAA,IACnB,oBAAoB;AAAA,MAClB,MAAM;AAAA,QACJX,EAAc,SAAS,sBAAsB,QAAQ;AAAA,QACrDA,EAAc,SAAS,eAAe,UAAU,QAAQ;AAAA,QACxDA,EAAc,SAAS,iBAAiB,OAAO;AAAA,QAC/CA,EAAc,SAAS,iBAAiB,OAAO;AAAA,QAC/CA,EAAc,SAAS,iBAAiB,OAAO;AAAA,QAC/CA,EAAc,SAAS,iBAAiB,QAAQ;AAAA,QAChDA,EAAc,SAAS,iBAAiB,QAAQ;AAAA,QAChDA,EAAc,SAAS,mBAAmB,QAAQ;AAAA,QAClDA,EAAc,SAAS,iBAAiB,QAAQ;AAAA,QAChDA,EAAc,UAAU,gBAAgB,OAAO;AAAA,MACjD;AAAA,MACA,UAAUW,EAAiB;AAAA,IAC7B;AAAA,IACA,OAAO;AAAA,MACL,SAAS;AAAA,MACT,SAAS;AAAA,IACX;AAAA,IACA,oBAAoB;AAAA,MAClB,MAAM;AAAA,QACJX,EAAc,SAAS,qBAAqB,OAAO;AAAA,QACnDA,EAAc,SAAS,qBAAqB,QAAQ;AAAA,MACtD;AAAA,MACA,UAAUW,EAAiB;AAAA,IAC7B;AAAA,IACA,kBAAkB;AAAA,MAChB,MAAM,CAACX,EAAc,WAAW,mBAAmB,OAAO,CAAC;AAAA,MAC3D,UAAUW,EAAiB;AAAA,IAC7B;AAAA,IACA,mBAAmB;AAAA,MACjB,MAAM,CAACX,EAAc,YAAY,oBAAoB,OAAO,CAAC;AAAA,MAC7D,UAAUW,EAAiB;AAAA,IAC7B;AAAA,IACA,kBAAkB;AAAA,MAChB,MAAM,CAACX,EAAc,YAAY,oBAAoB,OAAO,CAAC;AAAA,MAC7D,UAAUW,EAAiB;AAAA,IAC7B;AAAA,IACA,aAAa,EAAC,MAAM,CAACX,EAAc,UAAU,aAAa,OAAO,CAAC,EAAC;AAAA,IACnE,YAAY,EAAC,MAAMA,EAAc,UAAU,gBAAgB,EAAC;AAAA,IAC5D,oBAAoB;AAAA,MAClB,MAAM;AAAA,QACJ;AAAA,UACE,IAAI;AAAA,UACJ,aAAa;AAAA,UACb,OAAO,EAAC,KAAK,oCAAmC;AAAA,UAChD,OAAO,EAAC,QAAQ,SAAS,cAAc,MAAK;AAAA,UAC5C,gBAAgB,EAAC,QAAQ,SAAS,cAAc,MAAK;AAAA,QAAA;AAAA,MAEzD;AAAA,MACA,UAAUW,EAAiB;AAAA,IAC7B;AAAA,IACA,iBAAiB;AAAA,MACf,MAAM;AAAA,QACJ;AAAA,UACE,IAAI;AAAA,UACJ,OAAO,EAAC,KAAK,kCAAiC;AAAA,UAC9C,kBAAkB;AAAA,UAClB,KAAK;AAAA,QAAA;AAAA,MAET;AAAA,MACA,UAAUA,EAAiB;AAAA,IAC7B;AAAA,IACA,SAAS,EAAC,MAAMN,EAAW,UAAU,aAAa,EAAC;AAAA,IACnD,gBAAgB;AAAA,MACd,MAAM,CAACA,EAAW,iBAAiB,eAAe,CAAC;AAAA,MACnD,UAAUM,EAAiB;AAAA,IAC7B;AAAA,IACA,kBAAkB;AAAA,MAChB,MAAM,CAACN,EAAW,mBAAmB,iBAAiB,CAAC;AAAA,MACvD,UAAUM,EAAiB;AAAA,IAC7B;AAAA,IACA,oBAAoB;AAAA,IACpB,eAAe;AAAA,MACb,MAAM;AAAA,QACJ,UAAU;AAAA,QACV,YAAY;AAAA,QACZ,OAAO;AAAA,UACL,IAAI;AAAA,UACJ,KAAK;AAAA,UACL,OAAO;AAAA,UACP,QAAQ;AAAA,QACV;AAAA,QACA,OAAO;AAAA,QACP,aAAa;AAAA,QACb,YAAY,CAAC,cAAc;AAAA,QAC3B,cAAc;AAAA,QACd,UAAU;AAAA,MAAA;AAAA,IAEd;AAAA,IACA,YAAY;AAAA,MACV,MAAM;AAAA,QACJ;AAAA,UACE,UAAU;AAAA,UACV,OAAO;AAAA,YACL,IAAI;AAAA,YACJ,KAAK;AAAA,YACL,OAAO;AAAA,YACP,QAAQ;AAAA,UACV;AAAA,UACA,OAAO;AAAA,UACP,YAAY,CAAC,cAAc;AAAA,QAAA;AAAA,MAC7B;AAAA,IACF;AAAA,EAEJ,GAEMU,IAA6B,CAAC;AACpC,aAAWL,KAAOI;AAChB,IAAI,OAAO,UAAU,eAAe,KAAKA,GAASJ,CAAG,MAEnDK,EAAKL,CAAG,IAAID;AAAA,MACVC;AAAA,MACAI,EAAQJ,CAA2B;AAAA,IACrC;AAGG,SAAAK;AACT;AAGA,MAAMC,IAAW,MAAe;AACxB,QAAAC,IAAY,UAAU,UAAU,YAAY,GAC5CC,IAAQ,mBAAmB,KAAKD,CAAS,GACzCE,IAAY,UAAU,KAAKF,CAAS;AAE1C,SAAOC,KAASC;AAClB,GAEaC,IAAc,MAAM;AAE/B,EAAIJ,OAIC,OAAO,aACV,OAAO,WAAWH,EAAgB,GAClC,OAAO,cAAc;AAAA,IACnB,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,UAAU;AAAA,EACZ;AAEJ;"}
1
+ {"version":3,"file":"mocks.js","sources":["../src/mocks.ts"],"sourcesContent":["import {Product, Gender} from '@shopify/shop-minis-platform'\nimport {ShopActions} from '@shopify/shop-minis-platform/actions'\n\n// Helper functions for common data structures\nexport const createProduct = (\n id: string,\n title: string,\n price = '99.99',\n compareAtPrice?: string\n): Product => ({\n id,\n title,\n price: {amount: price, currencyCode: 'USD'},\n ...(compareAtPrice && {\n compareAtPrice: {amount: compareAtPrice, currencyCode: 'USD'},\n }),\n reviewAnalytics: {averageRating: 4.5, reviewCount: 10},\n shop: createShop('shop1', 'Mock Shop'),\n defaultVariantId: `variant-${id}`,\n isFavorited: false,\n featuredImage: {\n url: `https://cdn.shopify.com/static/sample-images/teapot.jpg`,\n altText: title,\n },\n})\n\nexport const createShop = (\n id: string,\n name: string,\n options?: {\n themeType?: 'coverImage' | 'brandColor' | 'logoColor' | 'none'\n withBrandSettings?: boolean\n primaryColor?: string\n logoDominantColor?: string\n logoAverageColor?: string\n coverDominantColor?: string\n wordmarkUrl?: string\n coverImageUrl?: string\n featuredImagesLimit?: number\n }\n) => {\n // Determine theme configuration\n const themeType = options?.themeType || 'none'\n const shouldHaveBrandSettings =\n options?.withBrandSettings || themeType !== 'none'\n\n // Generate featured images\n const featuredImagesCount = options?.featuredImagesLimit || 3\n const featuredImages = Array.from({length: featuredImagesCount}, (_, i) => ({\n url: `https://picsum.photos/400/400?random=${id}-${i}`,\n sensitive: false,\n altText: `${name} featured image ${i + 1}`,\n }))\n\n // Configure colors based on theme type\n const getThemeColors = () => {\n switch (themeType) {\n case 'coverImage':\n return {\n primary: options?.primaryColor,\n logoDominant: options?.logoDominantColor,\n logoAverage: options?.logoAverageColor,\n coverDominant: options?.coverDominantColor || '#FF6B35',\n }\n case 'brandColor':\n return {\n primary: options?.primaryColor || '#27AE60',\n logoDominant: options?.logoDominantColor,\n logoAverage: options?.logoAverageColor,\n coverDominant: options?.coverDominantColor,\n }\n case 'logoColor':\n return {\n primary: options?.primaryColor,\n logoDominant: options?.logoDominantColor || '#E74C3C',\n logoAverage: options?.logoAverageColor,\n coverDominant: options?.coverDominantColor,\n }\n default:\n return {\n primary: options?.primaryColor,\n logoDominant: options?.logoDominantColor,\n logoAverage: options?.logoAverageColor,\n coverDominant: options?.coverDominantColor,\n }\n }\n }\n\n // Configure header theme\n const createHeaderTheme = () => {\n if (themeType === 'coverImage' || options?.coverImageUrl) {\n return {\n id: `header-theme-${id}`,\n coverImage: {\n url:\n options?.coverImageUrl ||\n 'https://images.unsplash.com/photo-1441986300917-64674bd600d8?w=800&h=400&fit=crop',\n altText: `${name} cover image`,\n sensitive: false,\n thumbhash: 'k9oGHQRnh493V4dIeHeXh4h3iIeI',\n },\n wordmark:\n options?.wordmarkUrl || themeType === 'coverImage'\n ? {\n url:\n options?.wordmarkUrl ||\n 'https://merrypeople.com/cdn/shop/files/Transparent_Background_1.png?v=1696465429&width=1024',\n altText: `${name} wordmark`,\n sensitive: false,\n }\n : undefined,\n }\n }\n\n if (options?.wordmarkUrl) {\n return {\n id: `header-theme-${id}`,\n wordmark: {\n url: options.wordmarkUrl,\n altText: `${name} wordmark`,\n sensitive: false,\n },\n }\n }\n\n return undefined\n }\n\n return {\n id,\n name,\n primaryDomain: {\n url: `https://${name.toLowerCase().replace(/\\s+/g, '-')}.com`,\n },\n reviewAnalytics: {averageRating: 4.3, reviewCount: 50},\n visualTheme: {\n id: `visual-theme-${id}`,\n featuredImages,\n logoImage: {\n url: `https://picsum.photos/100/100?random=${id}`,\n sensitive: false,\n },\n brandSettings: shouldHaveBrandSettings\n ? {\n id: `brand-settings-${id}`,\n colors: {\n id: `colors-${id}`,\n ...getThemeColors(),\n },\n headerTheme: createHeaderTheme(),\n }\n : undefined,\n },\n }\n}\n\nconst createPagination = (hasNext = false) => ({\n hasNextPage: hasNext,\n endCursor: hasNext ? 'cursor123' : null,\n})\n\nconst createProductList = (id: string, name: string, products: any[] = []) => ({\n id,\n publicId: `public-${id}`,\n name,\n products,\n})\n\n// Helper type to extract the data type from a ShopAction\ntype ShopActionDataType<T> = T extends (\n ...args: any[]\n) => Promise<{ok: true; data: infer R} | {ok: false; error: any}>\n ? R\n : never\n\nfunction makeMockMethod<K extends keyof ShopActions>(\n key: K,\n result: ShopActionDataType<ShopActions[K]>\n): ShopActions[K] {\n return ((params: Parameters<ShopActions[K]>[0]) => {\n console.log(`[Mock Action] ${String(key)}`, params)\n return Promise.resolve({ok: true as const, data: result})\n }) as ShopActions[K]\n}\n\nfunction makeMockActions(): ShopActions {\n const results: {\n [K in keyof ShopActions]: ShopActionDataType<ShopActions[K]>\n } = {\n followShop: true,\n unfollowShop: false,\n favorite: undefined,\n unfavorite: undefined,\n getShopAppInformation: {\n appVersion: '1.0.0',\n buildNumber: '12345',\n buildId: 'dev-build-123',\n },\n productRecommendationImpression: undefined,\n productRecommendationClick: undefined,\n hideEntryPoint: undefined,\n closeMini: undefined,\n getAccountInformation: {\n status: 'available',\n value: 'user@example.com',\n },\n getCurrentUser: {\n data: {\n displayName: 'John Doe',\n avatarImage: {url: 'https://example.com/avatar.jpg'},\n },\n },\n createOrderAttribution: undefined,\n addToCart: undefined,\n buyProduct: undefined,\n buyProducts: undefined,\n showErrorScreen: undefined,\n showErrorToast: undefined,\n getDeeplinkPaths: {\n matchers: ['/products', '/collections', '/cart'],\n },\n navigateToDeeplink: undefined,\n navigateToShop: undefined,\n navigateToProduct: undefined,\n navigateToOrder: undefined,\n navigateToCheckout: undefined,\n createImageUploadLink: {\n targets: [\n {\n url: 'https://example.com/upload',\n resourceUrl: 'https://example.com/resource',\n parameters: [{name: 'key', value: 'upload-123'}],\n },\n ],\n },\n completeImageUpload: {\n files: [\n {\n id: 'file-123',\n fileStatus: 'READY',\n image: {url: 'https://example.com/image.jpg'},\n },\n ],\n },\n getPersistedItem: 'stored-value',\n setPersistedItem: undefined,\n removePersistedItem: undefined,\n getAllPersistedKeys: ['key1', 'key2', 'key3'],\n clearPersistedItems: undefined,\n getInternalPersistedItem: 'internal-value',\n setInternalPersistedItem: undefined,\n removeInternalPersistedItem: undefined,\n getAllInternalPersistedKeys: ['internal-key1', 'internal-key2'],\n clearInternalPersistedItems: undefined,\n getSecret: 'secret-value',\n setSecret: undefined,\n removeSecret: undefined,\n reportInteraction: undefined,\n reportImpression: undefined,\n reportContentImpression: undefined,\n getProductLists: {\n data: [\n createProductList('list-1', 'Wishlist'),\n createProductList('list-2', 'Favorites'),\n ],\n pageInfo: createPagination(),\n },\n getProductList: {\n data: createProductList('list-1', 'Wishlist', [\n createProduct('prod-1', 'Sample Product'),\n ]),\n pageInfo: createPagination(),\n },\n addProductList: createProductList('list-3', 'New List'),\n removeProductList: undefined,\n renameProductList: createProductList('list-1', 'Updated Wishlist'),\n addProductListItem: undefined,\n removeProductListItem: undefined,\n getRecommendedProducts: {\n data: [\n createProduct('rec-1', 'Recommended Product 1', '79.99'),\n createProduct('rec-2', 'Recommended Product 2', '129.99'),\n createProduct('rec-3', 'Recommended Product 3', '129.99'),\n createProduct('rec-4', 'Recommended Product 4', '29.99'),\n createProduct('rec-5', 'Recommended Product 5', '39.99'),\n createProduct('rec-6', 'Recommended Product 6', '49.99'),\n createProduct('rec-7', 'Recommended Product 7', '59.99'),\n createProduct('rec-8', 'Recommended Product 8', '69.99'),\n createProduct('rec-9', 'Recommended Product 9', '129.99'),\n ],\n pageInfo: createPagination(),\n },\n getRecommendedShops: {\n data: [\n createShop('shop-1', 'Amazing Store'),\n createShop('shop-2', 'Best Deals Shop'),\n ],\n pageInfo: createPagination(),\n },\n searchProductsByShop: {\n data: [\n createProduct('search-1', 'Search Result 1', '59.99'),\n createProduct('search-2', 'Search Result 2', '89.99'),\n ],\n pageInfo: createPagination(),\n },\n getOrders: {\n data: [\n {\n id: 'order-1',\n name: '#1001',\n lineItems: [\n {\n productTitle: 'Sample Product',\n variantTitle: 'Medium',\n quantity: 2,\n product: null,\n },\n ],\n shop: createShop('shop-1', 'Sample Shop'),\n },\n ],\n pageInfo: createPagination(),\n },\n getBuyerAttributes: {\n data: {\n genderAffinity: 'NEUTRAL' as Gender,\n categoryAffinities: [\n {id: 'cat1', name: 'Electronics'},\n {id: 'cat2', name: 'Clothing'},\n ],\n },\n },\n showFeedbackSheet: undefined,\n getPopularProducts: {\n data: [\n createProduct('pop-1', 'The Hero Snowboard', '702.95'),\n createProduct('pop-2', 'Snow Jacket', '605.95', '702.00'),\n createProduct('pop-3', 'Winter Gloves', '89.95'),\n createProduct('pop-4', 'Summer Gloves', '89.95'),\n createProduct('pop-5', 'Spring Gloves', '89.95'),\n createProduct('pop-6', 'Playstation 5', '499.95'),\n createProduct('pop-7', 'Xbox Series X', '499.95'),\n createProduct('pop-8', 'Nintendo Switch', '299.95'),\n createProduct('pop-9', 'Playstation 4', '299.95'),\n createProduct('pop-10', 'Nintendo 3DS', '89.95'),\n ],\n pageInfo: createPagination(),\n },\n share: {\n message: 'Shared!',\n success: true,\n },\n getCuratedProducts: {\n data: [\n createProduct('cur-1', 'Curated Product 1', '79.99'),\n createProduct('cur-2', 'Curated Product 2', '129.99'),\n ],\n pageInfo: createPagination(),\n },\n getSavedProducts: {\n data: [createProduct('saved-1', 'Saved Product 1', '49.99')],\n pageInfo: createPagination(),\n },\n getRecentProducts: {\n data: [createProduct('recent-1', 'Recent Product 1', '59.99')],\n pageInfo: createPagination(),\n },\n getProductSearch: {\n data: [createProduct('search-3', 'Search Product 3', '39.99')],\n pageInfo: createPagination(),\n },\n getProducts: {data: [createProduct('prod-2', 'Product 2', '19.99')]},\n getProduct: {data: createProduct('prod-1', 'Sample Product')},\n getProductVariants: {\n data: [\n {\n id: 'variant-1',\n isFavorited: false,\n image: {url: 'https://example.com/variant-1.jpg'},\n price: {amount: '19.99', currencyCode: 'USD'},\n compareAtPrice: {amount: '29.99', currencyCode: 'USD'},\n },\n ],\n pageInfo: createPagination(),\n },\n getProductMedia: {\n data: [\n {\n id: 'media-1',\n image: {url: 'https://example.com/media-1.jpg'},\n mediaContentType: 'IMAGE',\n alt: 'Sample product image',\n },\n ],\n pageInfo: createPagination(),\n },\n getShop: {data: createShop('shop-1', 'Sample Shop')},\n getRecentShops: {\n data: [createShop('recent-shop-1', 'Recent Shop 1')],\n pageInfo: createPagination(),\n },\n getFollowedShops: {\n data: [createShop('followed-shop-1', 'Followed Shop 1')],\n pageInfo: createPagination(),\n },\n previewProductInAr: undefined,\n createContent: {\n data: {\n publicId: 'content-123',\n externalId: null,\n image: {\n id: 'img-123',\n url: 'https://cdn.shopify.com/s/files/1/0633/6574/2742/files/Namnlosdesign-47.png?v=1740438079',\n width: 800,\n height: 600,\n },\n title: 'Mock Content',\n description: 'This is a mock content item',\n visibility: ['DISCOVERABLE'],\n shareableUrl: 'https://example.com/content/123',\n products: null,\n },\n },\n getContent: {\n data: [\n {\n publicId: 'content-123',\n image: {\n id: 'img-123',\n url: 'https://cdn.shopify.com/s/files/1/0633/6574/2742/files/Namnlosdesign-47.png?v=1740438079',\n width: 800,\n height: 600,\n },\n title: 'Mock Content',\n visibility: ['DISCOVERABLE'],\n },\n ],\n },\n } as const\n\n const mock: Partial<ShopActions> = {}\n for (const key in results) {\n if (Object.prototype.hasOwnProperty.call(results, key)) {\n // @ts-expect-error: dynamic assignment is safe due to exhaustive mapping\n mock[key] = makeMockMethod(\n key as keyof ShopActions,\n results[key as keyof typeof results]\n )\n }\n }\n return mock as ShopActions\n}\n\n// Detect if running on a mobile device\nconst isMobile = (): boolean => {\n const userAgent = navigator.userAgent.toLowerCase()\n const isIOS = /iphone|ipad|ipod/.test(userAgent)\n const isAndroid = /android/.test(userAgent)\n\n return isIOS || isAndroid\n}\n\nexport const injectMocks = () => {\n // Only inject mocks if we aren't on a mobile device\n if (isMobile()) {\n return\n }\n\n if (!window.minisSDK) {\n window.minisSDK = makeMockActions()\n window.minisParams = {\n handle: 'mock-handle',\n initialUrl: '/mock-initial-url',\n platform: 'web',\n }\n }\n}\n"],"names":["createProduct","id","title","price","compareAtPrice","createShop","name","options","featuredImages","_","i","createPagination","hasNext","createProductList","products","makeMockMethod","key","result","params","makeMockActions","results","mock","isMobile","userAgent","isIOS","isAndroid","injectMocks"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { s as r } from "../../../../../../../../_virtual/index7.js";
1
+ import { s as r } from "../../../../../../../../_virtual/index5.js";
2
2
  function s() {
3
3
  return r.useSyncExternalStore(
4
4
  e,
@@ -1,4 +1,4 @@
1
- import { __module as q } from "../../../../../../../../_virtual/index5.js";
1
+ import { __module as q } from "../../../../../../../../_virtual/index6.js";
2
2
  import { __require as F } from "../../../../../global@4.4.0/node_modules/global/window.js";
3
3
  import { __require as N } from "../../../../../@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/extends.js";
4
4
  import { __require as J } from "../../../../../is-function@1.0.2/node_modules/is-function/index.js";
@@ -1,4 +1,4 @@
1
- import { __exports as r } from "../../../../../../../../_virtual/index9.js";
1
+ import { __exports as r } from "../../../../../../../../_virtual/index10.js";
2
2
  import { __require as a } from "./dom.js";
3
3
  import { __require as o } from "./dom-parser.js";
4
4
  var i;
@@ -2,7 +2,7 @@ import L from "../../../../@videojs_vhs-utils@4.1.1/node_modules/@videojs/vhs-ut
2
2
  import T from "../../../../../../../_virtual/window.js";
3
3
  import { forEachMediaGroup as Z } from "../../../../@videojs_vhs-utils@4.1.1/node_modules/@videojs/vhs-utils/es/media-groups.js";
4
4
  import J from "../../../../@videojs_vhs-utils@4.1.1/node_modules/@videojs/vhs-utils/es/decode-b64-to-uint8-array.js";
5
- import { l as Q } from "../../../../../../../_virtual/index6.js";
5
+ import { l as Q } from "../../../../../../../_virtual/index7.js";
6
6
  /*! @name mpd-parser @version 1.3.1 @license Apache-2.0 */
7
7
  const w = (e) => !!e && typeof e == "object", E = (...e) => e.reduce((n, t) => (typeof t != "object" || Object.keys(t).forEach((r) => {
8
8
  Array.isArray(n[r]) && Array.isArray(t[r]) ? n[r] = n[r].concat(t[r]) : w(n[r]) && w(t[r]) ? n[r] = E(n[r], t[r]) : n[r] = t[r];
@@ -1,4 +1,4 @@
1
- import { __module as r } from "../../../../../../../_virtual/index10.js";
1
+ import { __module as r } from "../../../../../../../_virtual/index9.js";
2
2
  import { __require as o } from "../cjs/use-sync-external-store-shim.production.js";
3
3
  import { __require as i } from "../cjs/use-sync-external-store-shim.development.js";
4
4
  var e;
@@ -1,6 +1,6 @@
1
1
  import S from "../../../../../../../_virtual/window.js";
2
2
  import B from "../../../../../../../_virtual/document.js";
3
- import il from "../../../../../../../_virtual/index2.js";
3
+ import il from "../../../../../../../_virtual/index3.js";
4
4
  import ao from "../../../../../../../_virtual/browser-index.js";
5
5
  import xe from "../../../../@babel_runtime@7.27.6/node_modules/@babel/runtime/helpers/esm/extends.js";
6
6
  import Kc from "../../../../@videojs_vhs-utils@4.1.1/node_modules/@videojs/vhs-utils/es/resolve-url.js";
@@ -1,4 +1,4 @@
1
- import o from "../_virtual/index3.js";
1
+ import o from "../_virtual/index2.js";
2
2
  const a = (r) => o(r).darken(0.2).isDark();
3
3
  export {
4
4
  a as isDarkColor
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@shopify/shop-minis-react",
3
3
  "license": "SEE LICENSE IN LICENSE.txt",
4
- "version": "0.0.29",
4
+ "version": "0.0.30",
5
5
  "sideEffects": false,
6
6
  "type": "module",
7
7
  "engines": {
@@ -1,4 +1,4 @@
1
- import {ComponentType, useCallback} from 'react'
1
+ import {ComponentType, useCallback, useRef} from 'react'
2
2
 
3
3
  import {
4
4
  VariableSizeList as _VariableSizeList,
@@ -24,7 +24,7 @@ interface Props<T = any>
24
24
  showScrollbar?: boolean
25
25
  header?: React.ReactNode
26
26
  headerHeight?: number
27
- fetchMore?: () => void
27
+ fetchMore?: () => Promise<void>
28
28
  }
29
29
 
30
30
  export function List<T = any>({
@@ -40,6 +40,26 @@ export function List<T = any>({
40
40
  overscanCount,
41
41
  ...listProps
42
42
  }: Props<T>) {
43
+ const inFlightFetchMoreRef = useRef<Promise<void> | null>(null)
44
+
45
+ // This is workaround to prevent multiple calls to fetchMore
46
+ // react-window re-renders the rows while scrolling,
47
+ // and the TrackingPixel could be triggered multiple times
48
+
49
+ const _fetchMore = useCallback(() => {
50
+ // Dedupe concurrent calls by returning the same in-flight promise
51
+ if (inFlightFetchMoreRef.current) return
52
+
53
+ const current = Promise.resolve(fetchMore?.()).finally(() => {
54
+ // Only clear if this is still the most recent promise
55
+ if (inFlightFetchMoreRef.current === current) {
56
+ inFlightFetchMoreRef.current = null
57
+ }
58
+ })
59
+
60
+ inFlightFetchMoreRef.current = current
61
+ }, [fetchMore])
62
+
43
63
  const rowRenderer = useCallback(
44
64
  ({index, style}: {index: number; style: React.CSSProperties}) => {
45
65
  // prepend the header to the first row if it exists
@@ -58,7 +78,7 @@ export function List<T = any>({
58
78
  <div style={style}>
59
79
  {renderItem(items[index], index)}
60
80
  <div style={{bottom: 0}}>
61
- <Pagination fetchMore={fetchMore} />
81
+ <Pagination fetchMore={_fetchMore} />
62
82
  </div>
63
83
  </div>
64
84
  )
@@ -66,7 +86,7 @@ export function List<T = any>({
66
86
 
67
87
  return <div style={style}>{renderItem(items[index], index)}</div>
68
88
  },
69
- [items, renderItem, header, fetchMore, headerHeight]
89
+ [items, renderItem, header, headerHeight, _fetchMore, fetchMore]
70
90
  )
71
91
 
72
92
  const getItemSize = useCallback(
@@ -21,7 +21,7 @@ interface SearchContextValue {
21
21
  products: Product[] | null
22
22
  loading: boolean
23
23
  error: Error | null
24
- fetchMore?: () => void
24
+ fetchMore?: () => Promise<void>
25
25
  hasNextPage: boolean
26
26
  isTyping: boolean
27
27
  }
@@ -2,7 +2,12 @@ import {useLocation, useNavigate, NavigateOptions} from 'react-router'
2
2
 
3
3
  import {DATA_NAVIGATION_TYPE_ATTRIBUTE} from '../../types'
4
4
 
5
- export function useNavigateWithTransition() {
5
+ type UseNavigateWithTransitionReturns = (
6
+ to: string | number,
7
+ options?: NavigateOptions
8
+ ) => void | Promise<void>
9
+
10
+ export function useNavigateWithTransition(): UseNavigateWithTransitionReturns {
6
11
  const navigate = useNavigate()
7
12
  const location = useLocation()
8
13
 
@@ -21,7 +21,9 @@ interface UseShopNavigationReturns {
21
21
  * Navigates to an order.
22
22
  */
23
23
  navigateToOrder: (params: NavigateToOrderParams) => Promise<void>
24
-
24
+ /**
25
+ * Navigates to a checkout.
26
+ */
25
27
  navigateToCheckout: (params: NavigateToCheckoutParams) => Promise<void>
26
28
  }
27
29
 
@@ -9,6 +9,9 @@ import {
9
9
  export interface UseCurrentUserParams extends DataHookOptionsBase {}
10
10
 
11
11
  export interface UseCurrentUserReturns extends DataHookReturnsBase {
12
+ /**
13
+ * The current user logged into Shop.
14
+ */
12
15
  currentUser: UserProfile | null
13
16
  }
14
17
 
@@ -8,11 +8,11 @@ import {useShopActions} from '../../internal/useShopActions'
8
8
 
9
9
  interface UseFollowedShopsActionsReturns {
10
10
  /**
11
- * Follow a shop.
11
+ * Follows a shop.
12
12
  */
13
13
  followShop: (params: FollowShopParams) => Promise<boolean>
14
14
  /**
15
- * Unfollow a shop.
15
+ * Unfollows a shop.
16
16
  */
17
17
  unfollowShop: (params: UnfollowShopParams) => Promise<boolean>
18
18
  }
@@ -3,12 +3,18 @@ import {
3
3
  useImagePickerContext,
4
4
  } from '../../providers/ImagePickerProvider'
5
5
 
6
- interface UseImagePickerReturn {
6
+ interface UseImagePickerReturns {
7
+ /**
8
+ * Opens the camera to take a photo.
9
+ */
7
10
  openCamera: (cameraFacing?: CameraFacing) => Promise<File>
11
+ /**
12
+ * Opens the gallery to select an image.
13
+ */
8
14
  openGallery: () => Promise<File>
9
15
  }
10
16
 
11
- export function useImagePicker(): UseImagePickerReturn {
17
+ export function useImagePicker(): UseImagePickerReturns {
12
18
  const {openCamera, openGallery} = useImagePickerContext()
13
19
 
14
20
  return {
package/src/mocks.ts CHANGED
@@ -19,7 +19,7 @@ export const createProduct = (
19
19
  defaultVariantId: `variant-${id}`,
20
20
  isFavorited: false,
21
21
  featuredImage: {
22
- url: `https://cdn.shopify.com/s/files/1/0621/0463/3599/files/61ChhrRjK9L._AC_SL1000_1639abe8-4cd3-4bee-9867-73f26b0acf0a.jpg?v=1702559955`,
22
+ url: `https://cdn.shopify.com/static/sample-images/teapot.jpg`,
23
23
  altText: title,
24
24
  },
25
25
  })
@@ -411,7 +411,7 @@ function makeMockActions(): ShopActions {
411
411
  externalId: null,
412
412
  image: {
413
413
  id: 'img-123',
414
- url: 'https://example.com/content-image.jpg',
414
+ url: 'https://cdn.shopify.com/s/files/1/0633/6574/2742/files/Namnlosdesign-47.png?v=1740438079',
415
415
  width: 800,
416
416
  height: 600,
417
417
  },
@@ -428,7 +428,7 @@ function makeMockActions(): ShopActions {
428
428
  publicId: 'content-123',
429
429
  image: {
430
430
  id: 'img-123',
431
- url: 'https://example.com/content-image.jpg',
431
+ url: 'https://cdn.shopify.com/s/files/1/0633/6574/2742/files/Namnlosdesign-47.png?v=1740438079',
432
432
  width: 800,
433
433
  height: 600,
434
434
  },
@@ -0,0 +1,68 @@
1
+ import {fn} from 'storybook/test'
2
+
3
+ import {ImageContentWrapper} from '../components/content/image-content-wrapper'
4
+ import {injectMocks} from '../mocks'
5
+
6
+ import type {Meta, StoryObj} from '@storybook/react-vite'
7
+
8
+ const meta = {
9
+ title: 'Content/ImageContentWrapper',
10
+ component: ImageContentWrapper,
11
+ parameters: {
12
+ layout: 'padded',
13
+ },
14
+ args: {
15
+ onLoad: fn(),
16
+ },
17
+ argTypes: {
18
+ publicId: {
19
+ control: 'text',
20
+ },
21
+ externalId: {
22
+ control: 'text',
23
+ },
24
+ width: {
25
+ control: 'number',
26
+ },
27
+ height: {
28
+ control: 'number',
29
+ },
30
+ className: {
31
+ control: 'text',
32
+ },
33
+ Loader: {
34
+ control: 'text',
35
+ },
36
+ },
37
+ tags: ['autodocs'],
38
+ } satisfies Meta<typeof ImageContentWrapper>
39
+
40
+ export default meta
41
+ type Story = StoryObj<typeof meta>
42
+
43
+ injectMocks()
44
+
45
+ export const WithPublicId: Story = {
46
+ args: {
47
+ publicId: 'content-123',
48
+ width: 400,
49
+ height: 300,
50
+ },
51
+ }
52
+
53
+ export const WithExternalId: Story = {
54
+ args: {
55
+ externalId: 'external-123',
56
+ width: 400,
57
+ height: 300,
58
+ },
59
+ }
60
+
61
+ export const WithCustomLoader: Story = {
62
+ args: {
63
+ publicId: 'content-123',
64
+ width: 400,
65
+ height: 300,
66
+ Loader: 'Loading image...',
67
+ },
68
+ }
@@ -31,6 +31,13 @@ type Story = StoryObj<typeof meta>
31
31
  injectMocks()
32
32
 
33
33
  export const Default: Story = {
34
+ decorators: [
35
+ Story => (
36
+ <div style={{maxWidth: 200}}>
37
+ <Story />
38
+ </div>
39
+ ),
40
+ ],
34
41
  args: {
35
42
  shop: {
36
43
  ...createShop('shop1', 'Amazing Store'),
@@ -40,6 +47,13 @@ export const Default: Story = {
40
47
  }
41
48
 
42
49
  export const CoverImageDark: Story = {
50
+ decorators: [
51
+ Story => (
52
+ <div style={{maxWidth: 200}}>
53
+ <Story />
54
+ </div>
55
+ ),
56
+ ],
43
57
  name: 'Cover Image',
44
58
  args: {
45
59
  shop: createShop('cover3', 'Midnight Store', {
@@ -50,6 +64,13 @@ export const CoverImageDark: Story = {
50
64
  }
51
65
 
52
66
  export const BrandColorWordmark: Story = {
67
+ decorators: [
68
+ Story => (
69
+ <div style={{maxWidth: 200}}>
70
+ <Story />
71
+ </div>
72
+ ),
73
+ ],
53
74
  name: 'Brand Color + Wordmark',
54
75
  args: {
55
76
  shop: createShop('brand2', 'Amazing Store', {
@@ -34,10 +34,17 @@ type Story = StoryObj<typeof meta>
34
34
  injectMocks()
35
35
 
36
36
  export const Single: Story = {
37
+ decorators: [
38
+ Story => (
39
+ <div style={{maxWidth: 200}}>
40
+ <Story />
41
+ </div>
42
+ ),
43
+ ],
37
44
  args: {
38
45
  product: {
39
46
  id: '1',
40
- title: 'Product 1',
47
+ title: 'Teapot',
41
48
 
42
49
  price: {
43
50
  amount: '100',
@@ -61,7 +68,7 @@ export const Single: Story = {
61
68
  isFavorited: true,
62
69
 
63
70
  featuredImage: {
64
- url: 'https://picsum.photos/400/400',
71
+ url: 'https://cdn.shopify.com/static/sample-images/teapot.jpg',
65
72
  altText: 'Product 1',
66
73
  },
67
74
  },
@@ -80,6 +87,6 @@ export const Grid: Story = {
80
87
  ),
81
88
  ],
82
89
  args: {
83
- product: createProduct('1', 'Product 1', '100', '120'),
90
+ product: createProduct('1', 'Teapot', '100', '120'),
84
91
  },
85
92
  }
@@ -20,13 +20,13 @@ injectMocks()
20
20
 
21
21
  export const Default: Story = {
22
22
  args: {
23
- product: createProduct('1', 'Product 1', '100', '120'),
23
+ product: createProduct('1', 'Teapot', '100', '120'),
24
24
  },
25
25
  }
26
26
 
27
27
  export const WithDiscount: Story = {
28
28
  args: {
29
- product: createProduct('2', 'Product with Discount', '80', '120'),
29
+ product: createProduct('2', 'Discounted Teapot', '80', '120'),
30
30
  },
31
31
  }
32
32
 
@@ -41,6 +41,6 @@ export const List: Story = {
41
41
  ),
42
42
  ],
43
43
  args: {
44
- product: createProduct('1', 'Product 1', '100', '120'),
44
+ product: createProduct('1', 'Teapot', '100', '120'),
45
45
  },
46
46
  }
@@ -0,0 +1,78 @@
1
+ import {fn} from 'storybook/test'
2
+
3
+ import {QuantitySelector} from '../components/commerce/quantity-selector'
4
+
5
+ import type {Meta, StoryObj} from '@storybook/react-vite'
6
+
7
+ type QuantitySelectorProps = React.ComponentProps<typeof QuantitySelector>
8
+
9
+ const meta: Meta<QuantitySelectorProps> = {
10
+ title: 'Commerce/QuantitySelector',
11
+ component: QuantitySelector,
12
+ parameters: {},
13
+ tags: ['autodocs'],
14
+ argTypes: {
15
+ quantity: {
16
+ control: 'number',
17
+ description: 'Current quantity value',
18
+ },
19
+ onQuantityChange: {
20
+ action: 'quantity changed',
21
+ description: 'Callback fired when quantity changes',
22
+ },
23
+ maxQuantity: {
24
+ control: 'number',
25
+ description: 'Maximum allowed quantity',
26
+ },
27
+ minQuantity: {
28
+ control: 'number',
29
+ description: 'Minimum allowed quantity',
30
+ },
31
+ disabled: {
32
+ control: 'boolean',
33
+ description: 'Whether the selector is disabled',
34
+ },
35
+ },
36
+ args: {
37
+ onQuantityChange: fn(),
38
+ },
39
+ } satisfies Meta<QuantitySelectorProps>
40
+
41
+ export default meta
42
+ type Story = StoryObj<typeof meta>
43
+
44
+ export const Default: Story = {
45
+ args: {
46
+ quantity: 2,
47
+ maxQuantity: 10,
48
+ minQuantity: 1,
49
+ disabled: false,
50
+ },
51
+ }
52
+
53
+ export const AtMinimum: Story = {
54
+ args: {
55
+ quantity: 1,
56
+ maxQuantity: 10,
57
+ minQuantity: 1,
58
+ disabled: false,
59
+ },
60
+ }
61
+
62
+ export const AtMaximum: Story = {
63
+ args: {
64
+ quantity: 10,
65
+ maxQuantity: 10,
66
+ minQuantity: 1,
67
+ disabled: false,
68
+ },
69
+ }
70
+
71
+ export const Disabled: Story = {
72
+ args: {
73
+ quantity: 3,
74
+ maxQuantity: 10,
75
+ minQuantity: 1,
76
+ disabled: true,
77
+ },
78
+ }
@@ -0,0 +1,129 @@
1
+ import {useRef} from 'react'
2
+
3
+ import {fn} from 'storybook/test'
4
+
5
+ import {VideoPlayer, VideoPlayerRef} from '../components/atoms/video-player'
6
+
7
+ import type {Meta, StoryObj} from '@storybook/react-vite'
8
+
9
+ const meta: Meta<typeof VideoPlayer> = {
10
+ title: 'Atoms/VideoPlayer',
11
+ component: VideoPlayer,
12
+ parameters: {
13
+ layout: 'padded',
14
+ },
15
+ args: {
16
+ onPlay: fn(),
17
+ onPause: fn(),
18
+ onEnded: fn(),
19
+ onReady: fn(),
20
+ },
21
+ argTypes: {
22
+ src: {
23
+ control: 'text',
24
+ },
25
+ format: {
26
+ control: 'select',
27
+ options: ['video/mp4', 'video/webm', 'video/ogg'],
28
+ },
29
+ poster: {
30
+ control: 'text',
31
+ },
32
+ width: {
33
+ control: 'number',
34
+ },
35
+ height: {
36
+ control: 'number',
37
+ },
38
+ muted: {
39
+ control: 'boolean',
40
+ },
41
+ autoplay: {
42
+ control: 'boolean',
43
+ },
44
+ playButtonComponent: {
45
+ control: 'text',
46
+ },
47
+ },
48
+ tags: ['autodocs'],
49
+ }
50
+
51
+ export default meta
52
+ type Story = StoryObj<typeof meta>
53
+
54
+ const SAMPLE_VIDEO_MP4 =
55
+ 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4'
56
+ const SAMPLE_POSTER =
57
+ 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/images/BigBuckBunny.jpg'
58
+
59
+ export const FixedWidth: Story = {
60
+ args: {
61
+ src: SAMPLE_VIDEO_MP4,
62
+ width: 300,
63
+ },
64
+ }
65
+
66
+ export const FixedHeight: Story = {
67
+ args: {
68
+ src: SAMPLE_VIDEO_MP4,
69
+ height: 200,
70
+ },
71
+ }
72
+
73
+ export const WithPoster: Story = {
74
+ args: {
75
+ src: SAMPLE_VIDEO_MP4,
76
+ poster: SAMPLE_POSTER,
77
+ width: 300,
78
+ },
79
+ }
80
+
81
+ export const WithCustomPlayButton: Story = {
82
+ args: {
83
+ src: SAMPLE_VIDEO_MP4,
84
+ poster: SAMPLE_POSTER,
85
+ width: 300,
86
+ playButtonComponent: (
87
+ <div className="bg-blue-500 text-white rounded-full p-4 shadow-lg">
88
+ <svg viewBox="0 0 24 24" className="w-8 h-8" fill="currentColor">
89
+ <path d="M8 5v14l11-7z" />
90
+ </svg>
91
+ </div>
92
+ ),
93
+ },
94
+ }
95
+
96
+ const WithImperativeControlsComponent = (args: any) => {
97
+ const videoRef = useRef<VideoPlayerRef>(null)
98
+
99
+ return (
100
+ <div className="space-y-4 flex flex-col items-center">
101
+ <VideoPlayer ref={videoRef} {...args} />
102
+ <div className="flex gap-2">
103
+ <button
104
+ type="button"
105
+ className="px-4 py-2 bg-primary text-white rounded"
106
+ onClick={() => videoRef.current?.play()}
107
+ >
108
+ Play
109
+ </button>
110
+ <button
111
+ type="button"
112
+ className="px-4 py-2 bg-red-400 text-white rounded"
113
+ onClick={() => videoRef.current?.pause()}
114
+ >
115
+ Pause
116
+ </button>
117
+ </div>
118
+ </div>
119
+ )
120
+ }
121
+
122
+ export const WithImperativeControls: Story = {
123
+ render: WithImperativeControlsComponent,
124
+ args: {
125
+ src: SAMPLE_VIDEO_MP4,
126
+ poster: SAMPLE_POSTER,
127
+ width: 300,
128
+ },
129
+ }
@@ -1,41 +0,0 @@
1
- export const useImagePickerDoc = {
2
- name: 'useImagePicker',
3
- category: 'Utility',
4
- description:
5
- 'Hook for selecting images from camera or gallery in web-based mini apps',
6
- params: [
7
- {
8
- name: 'options',
9
- type: 'UseImagePickerOptions',
10
- description: 'Configuration options for the image picker',
11
- optional: true,
12
- properties: [
13
- {
14
- name: 'cameraFacing',
15
- type: "'user' | 'environment'",
16
- description: 'Which camera to use when opening camera',
17
- optional: true,
18
- default: "'environment'",
19
- },
20
- ],
21
- },
22
- ],
23
- returns: [
24
- {
25
- name: 'openCamera',
26
- type: '() => Promise<File>',
27
- description: 'Function to open the camera for capturing an image',
28
- },
29
- {
30
- name: 'openGallery',
31
- type: '() => Promise<File>',
32
- description: 'Function to open the gallery for selecting an image',
33
- },
34
- {
35
- name: 'ImagePickerInputs',
36
- type: 'React.FC',
37
- description:
38
- 'Component that renders hidden file inputs. Must be rendered in your component for the picker to work',
39
- },
40
- ],
41
- }