@gfed-medusa/sf-lib-products 1.7.0 → 1.8.1

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 (56) hide show
  1. package/dist/components/browse-product-preview/index.d.ts +2 -2
  2. package/dist/components/browse-product-preview/index.js +3 -3
  3. package/dist/components/browse-product-preview/index.js.map +1 -1
  4. package/dist/components/image-gallery/index.d.ts +2 -2
  5. package/dist/components/pagination/index.d.ts +16 -6
  6. package/dist/components/pagination/index.d.ts.map +1 -1
  7. package/dist/components/pagination/index.js +71 -54
  8. package/dist/components/pagination/index.js.map +1 -1
  9. package/dist/components/product-actions/index.d.ts +2 -2
  10. package/dist/components/product-actions/index.d.ts.map +1 -1
  11. package/dist/components/product-actions/index.js +6 -6
  12. package/dist/components/product-actions/index.js.map +1 -1
  13. package/dist/components/product-actions/mobile-actions.d.ts.map +1 -1
  14. package/dist/components/product-actions/mobile-actions.js +6 -21
  15. package/dist/components/product-actions/mobile-actions.js.map +1 -1
  16. package/dist/components/product-onboarding-cta/index.d.ts +2 -2
  17. package/dist/components/product-onboarding-cta/index.d.ts.map +1 -1
  18. package/dist/components/product-price/index.d.ts +2 -2
  19. package/dist/components/product-price/index.d.ts.map +1 -1
  20. package/dist/components/product-tabs/index.d.ts +2 -2
  21. package/dist/components/refinement-list/index.d.ts +2 -2
  22. package/dist/components/refinement-list/index.js +1 -1
  23. package/dist/components/refinement-list/sort-products/index.d.ts +2 -2
  24. package/dist/components/related-products/index.d.ts +2 -2
  25. package/dist/components/related-products/index.js +1 -1
  26. package/dist/components/related-products/index.js.map +1 -1
  27. package/dist/components/skeleton-product-grid/index.d.ts +2 -2
  28. package/dist/components/skeleton-product-grid/index.js +1 -1
  29. package/dist/components/skeleton-product-grid/index.js.map +1 -1
  30. package/dist/components/skeleton-product-preview/index.d.ts +2 -2
  31. package/dist/components/skeleton-product-preview/index.js +3 -3
  32. package/dist/components/skeleton-product-preview/index.js.map +1 -1
  33. package/dist/components/skeleton-related-products/index.d.ts +2 -2
  34. package/dist/components/skeleton-related-products/index.d.ts.map +1 -1
  35. package/dist/components/skeleton-related-products/index.js +1 -1
  36. package/dist/components/skeleton-related-products/index.js.map +1 -1
  37. package/dist/lib/gql/fragments/product.d.ts +16 -16
  38. package/dist/lib/gql/queries/cart.d.ts +2 -2
  39. package/dist/templates/paginated-products/client.d.ts +30 -0
  40. package/dist/templates/paginated-products/client.d.ts.map +1 -0
  41. package/dist/templates/paginated-products/client.js +212 -0
  42. package/dist/templates/paginated-products/client.js.map +1 -0
  43. package/dist/templates/paginated-products/index.d.ts +3 -3
  44. package/dist/templates/paginated-products/index.d.ts.map +1 -1
  45. package/dist/templates/paginated-products/index.js +27 -23
  46. package/dist/templates/paginated-products/index.js.map +1 -1
  47. package/dist/templates/product-actions-wrapper/index.d.ts +2 -2
  48. package/dist/templates/product-actions-wrapper/index.d.ts.map +1 -1
  49. package/dist/templates/product-info/index.d.ts +2 -2
  50. package/dist/templates/product-info/index.d.ts.map +1 -1
  51. package/dist/templates/product-template/index.js +1 -1
  52. package/dist/templates/store-template/index.d.ts +2 -2
  53. package/dist/templates/store-template/index.d.ts.map +1 -1
  54. package/dist/templates/store-template/index.js +1 -2
  55. package/dist/templates/store-template/index.js.map +1 -1
  56. package/package.json +2 -2
@@ -1,5 +1,5 @@
1
1
  import { BrowseProductHitFragment } from "../../types/graphql.js";
2
- import * as react_jsx_runtime6 from "react/jsx-runtime";
2
+ import * as react_jsx_runtime0 from "react/jsx-runtime";
3
3
 
4
4
  //#region src/components/browse-product-preview/index.d.ts
5
5
  type BrowseProductPreviewProps = {
@@ -13,7 +13,7 @@ declare const BrowseProductPreview: ({
13
13
  isFeatured,
14
14
  imagePriority,
15
15
  imageFetchPriority
16
- }: BrowseProductPreviewProps) => react_jsx_runtime6.JSX.Element;
16
+ }: BrowseProductPreviewProps) => react_jsx_runtime0.JSX.Element;
17
17
  //#endregion
18
18
  export { BrowseProductPreview };
19
19
  //# sourceMappingURL=index.d.ts.map
@@ -42,13 +42,13 @@ const BrowseProductPreview = ({ product, isFeatured, imagePriority = false, imag
42
42
  imagePriority,
43
43
  imageFetchPriority
44
44
  }), /* @__PURE__ */ jsxs("div", {
45
- className: "txt-compact-medium mt-4 flex items-start justify-between gap-x-4",
45
+ className: "txt-compact-medium mt-4 flex min-w-0 flex-col items-start gap-y-1 text-left",
46
46
  children: [/* @__PURE__ */ jsx(Text, {
47
- className: "text-ui-fg-subtle flex-1",
47
+ className: "text-ui-fg-subtle w-full min-w-0 overflow-hidden break-words whitespace-normal [display:-webkit-box] [-webkit-box-orient:vertical] [-webkit-line-clamp:2]",
48
48
  "data-testid": "product-title",
49
49
  children: product.title
50
50
  }), /* @__PURE__ */ jsx("div", {
51
- className: "flex shrink-0 items-start gap-x-2",
51
+ className: "flex w-full min-w-0 flex-wrap items-baseline gap-x-2 gap-y-1 text-left",
52
52
  children: price && /* @__PURE__ */ jsx(PreviewPrice, { price })
53
53
  })]
54
54
  })]
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/browse-product-preview/index.tsx"],"sourcesContent":["import { LocalizedClientLink } from '@gfed-medusa/sf-lib-common/components/localized-client-link';\nimport { PreviewPrice } from '@gfed-medusa/sf-lib-common/components/preview-price';\nimport { Thumbnail } from '@gfed-medusa/sf-lib-common/components/thumbnail';\nimport { getPercentageDiff } from '@gfed-medusa/sf-lib-common/lib/utils/get-percentage-diff';\nimport { convertToLocale } from '@gfed-medusa/sf-lib-common/lib/utils/money';\nimport type { VariantPrice } from '@gfed-medusa/sf-lib-common/types/prices';\nimport { Text } from '@medusajs/ui';\n\nimport type { BrowseProductHitFragment } from '@/types/graphql';\n\ntype BrowseProductPreviewProps = {\n product: BrowseProductHitFragment;\n isFeatured?: boolean;\n imagePriority?: boolean;\n imageFetchPriority?: 'auto' | 'high' | 'low';\n};\n\nconst getBrowseProductPrice = (\n product: BrowseProductHitFragment\n): VariantPrice | null => {\n if (\n typeof product.priceAmount !== 'number' ||\n !product.currencyCode ||\n !product.currencyCode.trim()\n ) {\n return null;\n }\n\n const originalPrice = product.originalPriceAmount ?? product.priceAmount;\n const isSale =\n typeof originalPrice === 'number' && originalPrice > product.priceAmount;\n\n return {\n calculated_price_number: product.priceAmount,\n calculated_price: convertToLocale({\n amount: product.priceAmount,\n currency_code: product.currencyCode,\n }),\n original_price_number: originalPrice,\n original_price: convertToLocale({\n amount: originalPrice,\n currency_code: product.currencyCode,\n }),\n currency_code: product.currencyCode,\n price_type: isSale ? 'sale' : 'default',\n percentage_diff:\n isSale && originalPrice > 0\n ? getPercentageDiff(originalPrice, product.priceAmount)\n : '0',\n };\n};\n\nconst BrowseProductPreview = ({\n product,\n isFeatured,\n imagePriority = false,\n imageFetchPriority,\n}: BrowseProductPreviewProps) => {\n const price = getBrowseProductPrice(product);\n\n return (\n <LocalizedClientLink href={`/products/${product.handle}`} className=\"group\">\n <div data-testid=\"product-wrapper\">\n <Thumbnail\n thumbnail={product.thumbnail}\n images={[]}\n size=\"full\"\n isFeatured={isFeatured}\n imagePriority={imagePriority}\n imageFetchPriority={imageFetchPriority}\n />\n <div className=\"txt-compact-medium mt-4 flex items-start justify-between gap-x-4\">\n <Text\n className=\"text-ui-fg-subtle flex-1\"\n data-testid=\"product-title\"\n >\n {product.title}\n </Text>\n <div className=\"flex shrink-0 items-start gap-x-2\">\n {price && <PreviewPrice price={price} />}\n </div>\n </div>\n </div>\n </LocalizedClientLink>\n );\n};\n\nexport { BrowseProductPreview };\n"],"mappings":";;;;;;;;;AAiBA,MAAM,yBACJ,YACwB;AACxB,KACE,OAAO,QAAQ,gBAAgB,YAC/B,CAAC,QAAQ,gBACT,CAAC,QAAQ,aAAa,MAAM,CAE5B,QAAO;CAGT,MAAM,gBAAgB,QAAQ,uBAAuB,QAAQ;CAC7D,MAAM,SACJ,OAAO,kBAAkB,YAAY,gBAAgB,QAAQ;AAE/D,QAAO;EACL,yBAAyB,QAAQ;EACjC,kBAAkB,gBAAgB;GAChC,QAAQ,QAAQ;GAChB,eAAe,QAAQ;GACxB,CAAC;EACF,uBAAuB;EACvB,gBAAgB,gBAAgB;GAC9B,QAAQ;GACR,eAAe,QAAQ;GACxB,CAAC;EACF,eAAe,QAAQ;EACvB,YAAY,SAAS,SAAS;EAC9B,iBACE,UAAU,gBAAgB,IACtB,kBAAkB,eAAe,QAAQ,YAAY,GACrD;EACP;;AAGH,MAAM,wBAAwB,EAC5B,SACA,YACA,gBAAgB,OAChB,yBAC+B;CAC/B,MAAM,QAAQ,sBAAsB,QAAQ;AAE5C,QACE,oBAAC;EAAoB,MAAM,aAAa,QAAQ;EAAU,WAAU;YAClE,qBAAC;GAAI,eAAY;cACf,oBAAC;IACC,WAAW,QAAQ;IACnB,QAAQ,EAAE;IACV,MAAK;IACO;IACG;IACK;KACpB,EACF,qBAAC;IAAI,WAAU;eACb,oBAAC;KACC,WAAU;KACV,eAAY;eAEX,QAAQ;MACJ,EACP,oBAAC;KAAI,WAAU;eACZ,SAAS,oBAAC,gBAAoB,QAAS;MACpC;KACF;IACF;GACc"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/browse-product-preview/index.tsx"],"sourcesContent":["import { LocalizedClientLink } from '@gfed-medusa/sf-lib-common/components/localized-client-link';\nimport { PreviewPrice } from '@gfed-medusa/sf-lib-common/components/preview-price';\nimport { Thumbnail } from '@gfed-medusa/sf-lib-common/components/thumbnail';\nimport { getPercentageDiff } from '@gfed-medusa/sf-lib-common/lib/utils/get-percentage-diff';\nimport { convertToLocale } from '@gfed-medusa/sf-lib-common/lib/utils/money';\nimport type { VariantPrice } from '@gfed-medusa/sf-lib-common/types/prices';\nimport { Text } from '@medusajs/ui';\n\nimport type { BrowseProductHitFragment } from '@/types/graphql';\n\ntype BrowseProductPreviewProps = {\n product: BrowseProductHitFragment;\n isFeatured?: boolean;\n imagePriority?: boolean;\n imageFetchPriority?: 'auto' | 'high' | 'low';\n};\n\nconst getBrowseProductPrice = (\n product: BrowseProductHitFragment\n): VariantPrice | null => {\n if (\n typeof product.priceAmount !== 'number' ||\n !product.currencyCode ||\n !product.currencyCode.trim()\n ) {\n return null;\n }\n\n const originalPrice = product.originalPriceAmount ?? product.priceAmount;\n const isSale =\n typeof originalPrice === 'number' && originalPrice > product.priceAmount;\n\n return {\n calculated_price_number: product.priceAmount,\n calculated_price: convertToLocale({\n amount: product.priceAmount,\n currency_code: product.currencyCode,\n }),\n original_price_number: originalPrice,\n original_price: convertToLocale({\n amount: originalPrice,\n currency_code: product.currencyCode,\n }),\n currency_code: product.currencyCode,\n price_type: isSale ? 'sale' : 'default',\n percentage_diff:\n isSale && originalPrice > 0\n ? getPercentageDiff(originalPrice, product.priceAmount)\n : '0',\n };\n};\n\nconst BrowseProductPreview = ({\n product,\n isFeatured,\n imagePriority = false,\n imageFetchPriority,\n}: BrowseProductPreviewProps) => {\n const price = getBrowseProductPrice(product);\n\n return (\n <LocalizedClientLink href={`/products/${product.handle}`} className=\"group\">\n <div data-testid=\"product-wrapper\">\n <Thumbnail\n thumbnail={product.thumbnail}\n images={[]}\n size=\"full\"\n isFeatured={isFeatured}\n imagePriority={imagePriority}\n imageFetchPriority={imageFetchPriority}\n />\n <div className=\"txt-compact-medium mt-4 flex min-w-0 flex-col items-start gap-y-1 text-left\">\n <Text\n className=\"text-ui-fg-subtle w-full min-w-0 overflow-hidden break-words whitespace-normal [display:-webkit-box] [-webkit-box-orient:vertical] [-webkit-line-clamp:2]\"\n data-testid=\"product-title\"\n >\n {product.title}\n </Text>\n <div className=\"flex w-full min-w-0 flex-wrap items-baseline gap-x-2 gap-y-1 text-left\">\n {price && <PreviewPrice price={price} />}\n </div>\n </div>\n </div>\n </LocalizedClientLink>\n );\n};\n\nexport { BrowseProductPreview };\n"],"mappings":";;;;;;;;;AAiBA,MAAM,yBACJ,YACwB;AACxB,KACE,OAAO,QAAQ,gBAAgB,YAC/B,CAAC,QAAQ,gBACT,CAAC,QAAQ,aAAa,MAAM,CAE5B,QAAO;CAGT,MAAM,gBAAgB,QAAQ,uBAAuB,QAAQ;CAC7D,MAAM,SACJ,OAAO,kBAAkB,YAAY,gBAAgB,QAAQ;AAE/D,QAAO;EACL,yBAAyB,QAAQ;EACjC,kBAAkB,gBAAgB;GAChC,QAAQ,QAAQ;GAChB,eAAe,QAAQ;GACxB,CAAC;EACF,uBAAuB;EACvB,gBAAgB,gBAAgB;GAC9B,QAAQ;GACR,eAAe,QAAQ;GACxB,CAAC;EACF,eAAe,QAAQ;EACvB,YAAY,SAAS,SAAS;EAC9B,iBACE,UAAU,gBAAgB,IACtB,kBAAkB,eAAe,QAAQ,YAAY,GACrD;EACP;;AAGH,MAAM,wBAAwB,EAC5B,SACA,YACA,gBAAgB,OAChB,yBAC+B;CAC/B,MAAM,QAAQ,sBAAsB,QAAQ;AAE5C,QACE,oBAAC;EAAoB,MAAM,aAAa,QAAQ;EAAU,WAAU;YAClE,qBAAC;GAAI,eAAY;cACf,oBAAC;IACC,WAAW,QAAQ;IACnB,QAAQ,EAAE;IACV,MAAK;IACO;IACG;IACK;KACpB,EACF,qBAAC;IAAI,WAAU;eACb,oBAAC;KACC,WAAU;KACV,eAAY;eAEX,QAAQ;MACJ,EACP,oBAAC;KAAI,WAAU;eACZ,SAAS,oBAAC,gBAAoB,QAAS;MACpC;KACF;IACF;GACc"}
@@ -1,5 +1,5 @@
1
1
  import { ProductImage } from "../../types/graphql.js";
2
- import * as react_jsx_runtime5 from "react/jsx-runtime";
2
+ import * as react_jsx_runtime0 from "react/jsx-runtime";
3
3
 
4
4
  //#region src/components/image-gallery/index.d.ts
5
5
  type ImageGalleryProps = {
@@ -7,7 +7,7 @@ type ImageGalleryProps = {
7
7
  };
8
8
  declare const ImageGallery: ({
9
9
  images
10
- }: ImageGalleryProps) => react_jsx_runtime5.JSX.Element;
10
+ }: ImageGalleryProps) => react_jsx_runtime0.JSX.Element;
11
11
  //#endregion
12
12
  export { ImageGallery as default };
13
13
  //# sourceMappingURL=index.d.ts.map
@@ -1,15 +1,25 @@
1
- import * as react_jsx_runtime13 from "react/jsx-runtime";
1
+ import * as react_jsx_runtime1 from "react/jsx-runtime";
2
2
 
3
3
  //#region src/components/pagination/index.d.ts
4
4
  declare function Pagination({
5
- page,
6
- totalPages,
5
+ loadedCount,
6
+ totalItems,
7
+ itemsPerPage,
8
+ hasNextPage,
9
+ disabled,
10
+ isLoading,
11
+ onLoadMore,
7
12
  'data-testid': dataTestid
8
13
  }: {
9
- page: number;
10
- totalPages: number;
14
+ loadedCount: number;
15
+ totalItems: number;
16
+ itemsPerPage: number;
17
+ hasNextPage: boolean;
18
+ disabled?: boolean;
19
+ isLoading?: boolean;
20
+ onLoadMore: () => void;
11
21
  'data-testid'?: string;
12
- }): react_jsx_runtime13.JSX.Element;
22
+ }): react_jsx_runtime1.JSX.Element;
13
23
  //#endregion
14
24
  export { Pagination };
15
25
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/components/pagination/index.tsx"],"sourcesContent":[],"mappings":";;;iBAMgB,UAAA;;;iBAGC;;;;EAHD,aAAU,CAAA,EAAA,MAAA;CACxB,CAAA,EAOD,mBAAA,CAAA,GAAA,CAAA,OAPC"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/components/pagination/index.tsx"],"sourcesContent":[],"mappings":";;;iBAKgB,UAAA;;;;;;;;iBAQC;;;;EARD,YAAA,EAAU,MAAA;EACxB,WAAA,EAAA,OAAA;EACA,QAAA,CAAA,EAAA,OAAA;EACA,SAAA,CAAA,EAAA,OAAA;EACA,UAAA,EAAA,GAAA,GAAA,IAAA;EACA,aAAA,CAAA,EAAA,MAAA;CACA,CAAA,EAYD,kBAAA,CAAA,GAAA,CAAA,OAZC"}
@@ -1,63 +1,80 @@
1
1
  'use client';
2
2
 
3
- import { clx } from "@medusajs/ui";
4
- import { jsx } from "react/jsx-runtime";
5
- import { usePathname, useRouter, useSearchParams } from "next/navigation";
3
+ import { Button, clx } from "@medusajs/ui";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ import { ArrowUpMini } from "@medusajs/icons";
6
6
 
7
7
  //#region src/components/pagination/index.tsx
8
- function Pagination({ page, totalPages, "data-testid": dataTestid }) {
9
- const router = useRouter();
10
- const pathname = usePathname();
11
- const searchParams = useSearchParams();
12
- const arrayRange = (start, stop) => Array.from({ length: stop - start + 1 }, (_, index) => start + index);
13
- const handlePageChange = (newPage) => {
14
- const params = new URLSearchParams(searchParams);
15
- params.set("page", newPage.toString());
16
- router.push(`${pathname}?${params.toString()}`);
17
- };
18
- const renderPageButton = (p, label, isCurrent) => /* @__PURE__ */ jsx("button", {
19
- type: "button",
20
- "aria-current": isCurrent ? "page" : void 0,
21
- "aria-label": isCurrent ? `Page ${p}, current page` : `Go to page ${p}`,
22
- className: clx("txt-xlarge-plus inline-flex h-12 min-w-12 items-center justify-center rounded-full px-2 text-ui-fg-muted transition-colors", {
23
- "border-ui-border-base text-ui-fg-base cursor-default border": isCurrent,
24
- "cursor-pointer hover:bg-ui-bg-subtle hover:text-ui-fg-base": !isCurrent
25
- }),
26
- disabled: isCurrent,
27
- onClick: () => handlePageChange(p),
28
- children: label
29
- }, p);
30
- const renderEllipsis = (key) => /* @__PURE__ */ jsx("span", {
31
- className: "txt-xlarge-plus text-ui-fg-muted inline-flex h-12 items-center justify-center px-1",
32
- children: "..."
33
- }, key);
34
- const renderPageButtons = () => {
35
- const buttons = [];
36
- if (totalPages <= 7) buttons.push(...arrayRange(1, totalPages).map((p) => renderPageButton(p, p, p === page)));
37
- else if (page <= 4) {
38
- buttons.push(...arrayRange(1, 5).map((p) => renderPageButton(p, p, p === page)));
39
- buttons.push(renderEllipsis("ellipsis1"));
40
- buttons.push(renderPageButton(totalPages, totalPages, totalPages === page));
41
- } else if (page >= totalPages - 3) {
42
- buttons.push(renderPageButton(1, 1, 1 === page));
43
- buttons.push(renderEllipsis("ellipsis2"));
44
- buttons.push(...arrayRange(totalPages - 4, totalPages).map((p) => renderPageButton(p, p, p === page)));
45
- } else {
46
- buttons.push(renderPageButton(1, 1, 1 === page));
47
- buttons.push(renderEllipsis("ellipsis3"));
48
- buttons.push(...arrayRange(page - 1, page + 1).map((p) => renderPageButton(p, p, p === page)));
49
- buttons.push(renderEllipsis("ellipsis4"));
50
- buttons.push(renderPageButton(totalPages, totalPages, totalPages === page));
51
- }
52
- return buttons;
8
+ function Pagination({ loadedCount, totalItems, itemsPerPage, hasNextPage, disabled = false, isLoading = false, onLoadMore, "data-testid": dataTestid }) {
9
+ const visibleItemsCount = Math.min(loadedCount, totalItems);
10
+ const productsLabel = totalItems === 1 ? "product" : "products";
11
+ const formattedTotalItems = new Intl.NumberFormat().format(totalItems);
12
+ const formattedVisibleItems = new Intl.NumberFormat().format(visibleItemsCount);
13
+ const progressValue = totalItems > 0 ? Math.round(visibleItemsCount / totalItems * 100) : 0;
14
+ const scrollToTop = () => {
15
+ window.scrollTo({
16
+ top: 0,
17
+ behavior: "smooth"
18
+ });
53
19
  };
54
20
  return /* @__PURE__ */ jsx("nav", {
55
- "aria-label": "Pagination",
56
- className: "mt-12 flex w-full justify-center",
57
- children: /* @__PURE__ */ jsx("div", {
58
- className: "flex items-center gap-3",
59
- "data-testid": dataTestid,
60
- children: renderPageButtons()
21
+ "aria-label": "Load more products",
22
+ className: "mt-12 w-full",
23
+ "data-testid": dataTestid,
24
+ children: /* @__PURE__ */ jsxs("div", {
25
+ className: "mx-auto flex w-full flex-col items-center gap-3 text-center",
26
+ children: [
27
+ /* @__PURE__ */ jsxs("div", {
28
+ className: "xsmall:w-[300px] w-full space-y-2",
29
+ children: [/* @__PURE__ */ jsxs("p", {
30
+ className: "text-small-regular text-ui-fg-subtle",
31
+ "aria-live": "polite",
32
+ children: [
33
+ "Showing ",
34
+ formattedVisibleItems,
35
+ " of ",
36
+ formattedTotalItems,
37
+ " ",
38
+ productsLabel
39
+ ]
40
+ }), /* @__PURE__ */ jsx("div", {
41
+ "aria-label": "Loaded products progress",
42
+ "aria-valuemax": totalItems,
43
+ "aria-valuemin": 0,
44
+ "aria-valuenow": visibleItemsCount,
45
+ className: "border-ui-border-base bg-ui-bg-subtle h-2 w-full overflow-hidden rounded-full border",
46
+ role: "progressbar",
47
+ children: /* @__PURE__ */ jsx("div", {
48
+ className: "bg-ui-fg-base h-full rounded-full transition-[width] duration-300 ease-out",
49
+ style: { width: `${progressValue}%` }
50
+ })
51
+ })]
52
+ }),
53
+ hasNextPage && /* @__PURE__ */ jsx(Button, {
54
+ type: "button",
55
+ variant: "secondary",
56
+ className: "xsmall:w-[300px] h-[45px] w-full justify-center rounded-md px-6",
57
+ disabled: disabled || isLoading,
58
+ isLoading,
59
+ "aria-label": `Load ${Math.min(itemsPerPage, totalItems - visibleItemsCount)} more ${productsLabel}`,
60
+ onClick: onLoadMore,
61
+ children: "Load more"
62
+ }),
63
+ /* @__PURE__ */ jsxs("button", {
64
+ type: "button",
65
+ "aria-label": "Scroll back to the top of the page",
66
+ className: clx("text-small-regular text-ui-fg-subtle hover:text-ui-fg-base mt-8 inline-flex items-center gap-2 transition-colors"),
67
+ onClick: scrollToTop,
68
+ children: [/* @__PURE__ */ jsx("span", {
69
+ "aria-hidden": "true",
70
+ className: "flex h-4 w-4 items-center justify-center",
71
+ children: /* @__PURE__ */ jsx(ArrowUpMini, {
72
+ className: "h-4 w-4",
73
+ color: "currentColor"
74
+ })
75
+ }), /* @__PURE__ */ jsx("span", { children: "Scroll to top" })]
76
+ })
77
+ ]
61
78
  })
62
79
  });
63
80
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/pagination/index.tsx"],"sourcesContent":["'use client';\n\nimport { usePathname, useRouter, useSearchParams } from 'next/navigation';\n\nimport { clx } from '@medusajs/ui';\n\nexport function Pagination({\n page,\n totalPages,\n 'data-testid': dataTestid,\n}: {\n page: number;\n totalPages: number;\n 'data-testid'?: string;\n}) {\n const router = useRouter();\n const pathname = usePathname();\n const searchParams = useSearchParams();\n\n // Helper function to generate an array of numbers within a range\n const arrayRange = (start: number, stop: number) =>\n Array.from({ length: stop - start + 1 }, (_, index) => start + index);\n\n // Function to handle page changes\n const handlePageChange = (newPage: number) => {\n const params = new URLSearchParams(searchParams);\n params.set('page', newPage.toString());\n router.push(`${pathname}?${params.toString()}`);\n };\n\n // Function to render a page button\n const renderPageButton = (\n p: number,\n label: string | number,\n isCurrent: boolean\n ) => (\n <button\n type=\"button\"\n key={p}\n aria-current={isCurrent ? 'page' : undefined}\n aria-label={isCurrent ? `Page ${p}, current page` : `Go to page ${p}`}\n className={clx(\n 'txt-xlarge-plus inline-flex h-12 min-w-12 items-center justify-center rounded-full px-2 text-ui-fg-muted transition-colors',\n {\n 'border-ui-border-base text-ui-fg-base cursor-default border':\n isCurrent,\n 'cursor-pointer hover:bg-ui-bg-subtle hover:text-ui-fg-base':\n !isCurrent,\n }\n )}\n disabled={isCurrent}\n onClick={() => handlePageChange(p)}\n >\n {label}\n </button>\n );\n\n // Function to render ellipsis\n const renderEllipsis = (key: string) => (\n <span\n key={key}\n className=\"txt-xlarge-plus text-ui-fg-muted inline-flex h-12 items-center justify-center px-1\"\n >\n ...\n </span>\n );\n\n // Function to render page buttons based on the current page and total pages\n const renderPageButtons = () => {\n const buttons = [];\n\n if (totalPages <= 7) {\n // Show all pages\n buttons.push(\n ...arrayRange(1, totalPages).map((p) =>\n renderPageButton(p, p, p === page)\n )\n );\n } else {\n // Handle different cases for displaying pages and ellipses\n if (page <= 4) {\n // Show 1, 2, 3, 4, 5, ..., lastpage\n buttons.push(\n ...arrayRange(1, 5).map((p) => renderPageButton(p, p, p === page))\n );\n buttons.push(renderEllipsis('ellipsis1'));\n buttons.push(\n renderPageButton(totalPages, totalPages, totalPages === page)\n );\n } else if (page >= totalPages - 3) {\n // Show 1, ..., lastpage - 4, lastpage - 3, lastpage - 2, lastpage - 1, lastpage\n buttons.push(renderPageButton(1, 1, 1 === page));\n buttons.push(renderEllipsis('ellipsis2'));\n buttons.push(\n ...arrayRange(totalPages - 4, totalPages).map((p) =>\n renderPageButton(p, p, p === page)\n )\n );\n } else {\n // Show 1, ..., page - 1, page, page + 1, ..., lastpage\n buttons.push(renderPageButton(1, 1, 1 === page));\n buttons.push(renderEllipsis('ellipsis3'));\n buttons.push(\n ...arrayRange(page - 1, page + 1).map((p) =>\n renderPageButton(p, p, p === page)\n )\n );\n buttons.push(renderEllipsis('ellipsis4'));\n buttons.push(\n renderPageButton(totalPages, totalPages, totalPages === page)\n );\n }\n }\n\n return buttons;\n };\n\n // Render the component\n return (\n <nav aria-label=\"Pagination\" className=\"mt-12 flex w-full justify-center\">\n <div className=\"flex items-center gap-3\" data-testid={dataTestid}>\n {renderPageButtons()}\n </div>\n </nav>\n );\n}\n"],"mappings":";;;;;;;AAMA,SAAgB,WAAW,EACzB,MACA,YACA,eAAe,cAKd;CACD,MAAM,SAAS,WAAW;CAC1B,MAAM,WAAW,aAAa;CAC9B,MAAM,eAAe,iBAAiB;CAGtC,MAAM,cAAc,OAAe,SACjC,MAAM,KAAK,EAAE,QAAQ,OAAO,QAAQ,GAAG,GAAG,GAAG,UAAU,QAAQ,MAAM;CAGvE,MAAM,oBAAoB,YAAoB;EAC5C,MAAM,SAAS,IAAI,gBAAgB,aAAa;AAChD,SAAO,IAAI,QAAQ,QAAQ,UAAU,CAAC;AACtC,SAAO,KAAK,GAAG,SAAS,GAAG,OAAO,UAAU,GAAG;;CAIjD,MAAM,oBACJ,GACA,OACA,cAEA,oBAAC;EACC,MAAK;EAEL,gBAAc,YAAY,SAAS;EACnC,cAAY,YAAY,QAAQ,EAAE,kBAAkB,cAAc;EAClE,WAAW,IACT,8HACA;GACE,+DACE;GACF,8DACE,CAAC;GACJ,CACF;EACD,UAAU;EACV,eAAe,iBAAiB,EAAE;YAEjC;IAfI,EAgBE;CAIX,MAAM,kBAAkB,QACtB,oBAAC;EAEC,WAAU;YACX;IAFM,IAIA;CAIT,MAAM,0BAA0B;EAC9B,MAAM,UAAU,EAAE;AAElB,MAAI,cAAc,EAEhB,SAAQ,KACN,GAAG,WAAW,GAAG,WAAW,CAAC,KAAK,MAChC,iBAAiB,GAAG,GAAG,MAAM,KAAK,CACnC,CACF;WAGG,QAAQ,GAAG;AAEb,WAAQ,KACN,GAAG,WAAW,GAAG,EAAE,CAAC,KAAK,MAAM,iBAAiB,GAAG,GAAG,MAAM,KAAK,CAAC,CACnE;AACD,WAAQ,KAAK,eAAe,YAAY,CAAC;AACzC,WAAQ,KACN,iBAAiB,YAAY,YAAY,eAAe,KAAK,CAC9D;aACQ,QAAQ,aAAa,GAAG;AAEjC,WAAQ,KAAK,iBAAiB,GAAG,GAAG,MAAM,KAAK,CAAC;AAChD,WAAQ,KAAK,eAAe,YAAY,CAAC;AACzC,WAAQ,KACN,GAAG,WAAW,aAAa,GAAG,WAAW,CAAC,KAAK,MAC7C,iBAAiB,GAAG,GAAG,MAAM,KAAK,CACnC,CACF;SACI;AAEL,WAAQ,KAAK,iBAAiB,GAAG,GAAG,MAAM,KAAK,CAAC;AAChD,WAAQ,KAAK,eAAe,YAAY,CAAC;AACzC,WAAQ,KACN,GAAG,WAAW,OAAO,GAAG,OAAO,EAAE,CAAC,KAAK,MACrC,iBAAiB,GAAG,GAAG,MAAM,KAAK,CACnC,CACF;AACD,WAAQ,KAAK,eAAe,YAAY,CAAC;AACzC,WAAQ,KACN,iBAAiB,YAAY,YAAY,eAAe,KAAK,CAC9D;;AAIL,SAAO;;AAIT,QACE,oBAAC;EAAI,cAAW;EAAa,WAAU;YACrC,oBAAC;GAAI,WAAU;GAA0B,eAAa;aACnD,mBAAmB;IAChB;GACF"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/components/pagination/index.tsx"],"sourcesContent":["'use client';\n\nimport { ArrowUpMini } from '@medusajs/icons';\nimport { Button, clx } from '@medusajs/ui';\n\nexport function Pagination({\n loadedCount,\n totalItems,\n itemsPerPage,\n hasNextPage,\n disabled = false,\n isLoading = false,\n onLoadMore,\n 'data-testid': dataTestid,\n}: {\n loadedCount: number;\n totalItems: number;\n itemsPerPage: number;\n hasNextPage: boolean;\n disabled?: boolean;\n isLoading?: boolean;\n onLoadMore: () => void;\n 'data-testid'?: string;\n}) {\n const visibleItemsCount = Math.min(loadedCount, totalItems);\n const productsLabel = totalItems === 1 ? 'product' : 'products';\n const formattedTotalItems = new Intl.NumberFormat().format(totalItems);\n const formattedVisibleItems = new Intl.NumberFormat().format(\n visibleItemsCount\n );\n const progressValue =\n totalItems > 0 ? Math.round((visibleItemsCount / totalItems) * 100) : 0;\n\n const scrollToTop = () => {\n window.scrollTo({ top: 0, behavior: 'smooth' });\n };\n\n return (\n <nav\n aria-label=\"Load more products\"\n className=\"mt-12 w-full\"\n data-testid={dataTestid}\n >\n <div className=\"mx-auto flex w-full flex-col items-center gap-3 text-center\">\n <div className=\"xsmall:w-[300px] w-full space-y-2\">\n <p\n className=\"text-small-regular text-ui-fg-subtle\"\n aria-live=\"polite\"\n >\n Showing {formattedVisibleItems} of {formattedTotalItems}{' '}\n {productsLabel}\n </p>\n <div\n aria-label=\"Loaded products progress\"\n aria-valuemax={totalItems}\n aria-valuemin={0}\n aria-valuenow={visibleItemsCount}\n className=\"border-ui-border-base bg-ui-bg-subtle h-2 w-full overflow-hidden rounded-full border\"\n role=\"progressbar\"\n >\n <div\n className=\"bg-ui-fg-base h-full rounded-full transition-[width] duration-300 ease-out\"\n style={{ width: `${progressValue}%` }}\n />\n </div>\n </div>\n {hasNextPage && (\n <Button\n type=\"button\"\n variant=\"secondary\"\n className=\"xsmall:w-[300px] h-[45px] w-full justify-center rounded-md px-6\"\n disabled={disabled || isLoading}\n isLoading={isLoading}\n aria-label={`Load ${Math.min(itemsPerPage, totalItems - visibleItemsCount)} more ${productsLabel}`}\n onClick={onLoadMore}\n >\n Load more\n </Button>\n )}\n <button\n type=\"button\"\n aria-label=\"Scroll back to the top of the page\"\n className={clx(\n 'text-small-regular text-ui-fg-subtle hover:text-ui-fg-base mt-8 inline-flex items-center gap-2 transition-colors'\n )}\n onClick={scrollToTop}\n >\n <span\n aria-hidden=\"true\"\n className=\"flex h-4 w-4 items-center justify-center\"\n >\n <ArrowUpMini className=\"h-4 w-4\" color=\"currentColor\" />\n </span>\n <span>Scroll to top</span>\n </button>\n </div>\n </nav>\n );\n}\n"],"mappings":";;;;;;;AAKA,SAAgB,WAAW,EACzB,aACA,YACA,cACA,aACA,WAAW,OACX,YAAY,OACZ,YACA,eAAe,cAUd;CACD,MAAM,oBAAoB,KAAK,IAAI,aAAa,WAAW;CAC3D,MAAM,gBAAgB,eAAe,IAAI,YAAY;CACrD,MAAM,sBAAsB,IAAI,KAAK,cAAc,CAAC,OAAO,WAAW;CACtE,MAAM,wBAAwB,IAAI,KAAK,cAAc,CAAC,OACpD,kBACD;CACD,MAAM,gBACJ,aAAa,IAAI,KAAK,MAAO,oBAAoB,aAAc,IAAI,GAAG;CAExE,MAAM,oBAAoB;AACxB,SAAO,SAAS;GAAE,KAAK;GAAG,UAAU;GAAU,CAAC;;AAGjD,QACE,oBAAC;EACC,cAAW;EACX,WAAU;EACV,eAAa;YAEb,qBAAC;GAAI,WAAU;;IACb,qBAAC;KAAI,WAAU;gBACb,qBAAC;MACC,WAAU;MACV,aAAU;;OACX;OACU;OAAsB;OAAK;OAAqB;OACxD;;OACC,EACJ,oBAAC;MACC,cAAW;MACX,iBAAe;MACf,iBAAe;MACf,iBAAe;MACf,WAAU;MACV,MAAK;gBAEL,oBAAC;OACC,WAAU;OACV,OAAO,EAAE,OAAO,GAAG,cAAc,IAAI;QACrC;OACE;MACF;IACL,eACC,oBAAC;KACC,MAAK;KACL,SAAQ;KACR,WAAU;KACV,UAAU,YAAY;KACX;KACX,cAAY,QAAQ,KAAK,IAAI,cAAc,aAAa,kBAAkB,CAAC,QAAQ;KACnF,SAAS;eACV;MAEQ;IAEX,qBAAC;KACC,MAAK;KACL,cAAW;KACX,WAAW,IACT,mHACD;KACD,SAAS;gBAET,oBAAC;MACC,eAAY;MACZ,WAAU;gBAEV,oBAAC;OAAY,WAAU;OAAU,OAAM;QAAiB;OACnD,EACP,oBAAC,oBAAK,kBAAoB;MACnB;;IACL;GACF"}
@@ -1,5 +1,5 @@
1
1
  import { ProductActionsProduct } from "../../types/index.js";
2
- import * as react_jsx_runtime12 from "react/jsx-runtime";
2
+ import * as react_jsx_runtime2 from "react/jsx-runtime";
3
3
 
4
4
  //#region src/components/product-actions/index.d.ts
5
5
  type ProductActionsProps = {
@@ -13,7 +13,7 @@ declare function ProductActions({
13
13
  regionId,
14
14
  disabled,
15
15
  enableMobileActions
16
- }: ProductActionsProps): react_jsx_runtime12.JSX.Element;
16
+ }: ProductActionsProps): react_jsx_runtime2.JSX.Element;
17
17
  //#endregion
18
18
  export { ProductActionsProps, ProductActions as default };
19
19
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/components/product-actions/index.tsx"],"sourcesContent":[],"mappings":";;;;KAyBY,mBAAA;WACD;;EADC,QAAA,CAAA,EAAA,OAAA;EA2BY,mBAAc,CAAA,EAAA,OAAA;CACpC;AACA,iBAFsB,cAAA,CAEtB;EAAA,OAAA;EAAA,QAAA;EAAA,QAAA;EAAA;AAAA,CAAA,EAGC,mBAHD,CAAA,EAGoB,mBAAA,CAAA,GAAA,CAAA,OAHpB"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/components/product-actions/index.tsx"],"sourcesContent":[],"mappings":";;;;KAyBY,mBAAA;WACD;;EADC,QAAA,CAAA,EAAA,OAAA;EA2BY,mBAAc,CAAA,EAAA,OAAA;CACpC;AACA,iBAFsB,cAAA,CAEtB;EAAA,OAAA;EAAA,QAAA;EAAA,QAAA;EAAA;AAAA,CAAA,EAGC,mBAHD,CAAA,EAGoB,kBAAA,CAAA,GAAA,CAAA,OAHpB"}
@@ -2,17 +2,17 @@
2
2
 
3
3
  import option_select_default from "./option-select.js";
4
4
  import { addToCart } from "../../lib/data/cart.js";
5
- import { useProductPrice } from "../../lib/hooks/use-product-price.js";
6
5
  import { useIntersection } from "../../lib/hooks/use-intersection.js";
6
+ import { useProductPrice } from "../../lib/hooks/use-product-price.js";
7
7
  import { mergeProductPricing } from "../../lib/utils/merge-product-pricing.js";
8
- import ProductPrice from "../product-price/index.js";
9
8
  import mobile_actions_default from "./mobile-actions.js";
10
9
  import { Button } from "@medusajs/ui";
11
10
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
12
- import { useParams } from "next/navigation";
13
11
  import { useEffect, useMemo, useRef, useState } from "react";
12
+ import { useParams } from "next/navigation";
14
13
  import { isEqual } from "lodash";
15
14
  import { ErrorMessage } from "@gfed-medusa/sf-lib-common/components/error-message";
15
+ import { WebComponent } from "@gfed-medusa/sf-lib-common/components/web-component";
16
16
  import { mutateCart } from "@gfed-medusa/sf-lib-common/lib/hooks/use-cart";
17
17
  import { Divider } from "@gfed-medusa/sf-lib-ui/components/divider";
18
18
 
@@ -109,9 +109,9 @@ function ProductActions({ product, regionId, disabled, enableMobileActions = tru
109
109
  }) }, option.id);
110
110
  }), /* @__PURE__ */ jsx(Divider, {})]
111
111
  }) }),
112
- /* @__PURE__ */ jsx(ProductPrice, {
113
- product: pricedProduct,
114
- variant: selectedVariant
112
+ /* @__PURE__ */ jsx(WebComponent, {
113
+ tag: "mfe-product-price",
114
+ "data-props": JSON.stringify({ selectedVariantId: selectedVariant?.id ?? "" })
115
115
  }),
116
116
  status === AddToCartStatus.ERROR && /* @__PURE__ */ jsx(ErrorMessage, { error: "Failed adding product to cart. Please try again." }),
117
117
  status === AddToCartStatus.SUCCESS && /* @__PURE__ */ jsx("div", {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["OptionSelect","MobileActions"],"sources":["../../../src/components/product-actions/index.tsx"],"sourcesContent":["'use client';\n\nimport { useEffect, useMemo, useRef, useState } from 'react';\n\nimport { useParams } from 'next/navigation';\n\nimport { isEqual } from 'lodash';\n\nimport { ErrorMessage } from '@gfed-medusa/sf-lib-common/components/error-message';\nimport { mutateCart } from '@gfed-medusa/sf-lib-common/lib/hooks/use-cart';\nimport { Divider } from '@gfed-medusa/sf-lib-ui/components/divider';\nimport { HttpTypes } from '@medusajs/types';\nimport { Button } from '@medusajs/ui';\n\nimport OptionSelect from '@/components/product-actions/option-select';\nimport { addToCart } from '@/lib/data/cart';\nimport { useProductPrice } from '@/lib/hooks/use-product-price';\nimport { useIntersection } from '@/lib/hooks/use-intersection';\nimport { mergeProductPricing } from '@/lib/utils/merge-product-pricing';\nimport { ProductActionsProduct } from '@/types';\nimport { ProductVariant } from '@/types/graphql';\n\nimport ProductPrice from '../product-price';\nimport MobileActions from './mobile-actions';\n\nexport type ProductActionsProps = {\n product: ProductActionsProduct;\n regionId?: string;\n disabled?: boolean;\n enableMobileActions?: boolean;\n};\n\nenum AddToCartStatus {\n IDLE = 'idle',\n ADDING = 'adding',\n SUCCESS = 'success',\n ERROR = 'error',\n}\n\nconst optionsAsKeymap = (\n variantOptions:\n | HttpTypes.StoreProductVariant['options']\n | ProductVariant['options']\n | null\n | undefined\n) => {\n return variantOptions?.reduce((acc: Record<string, string>, varopt: any) => {\n acc[varopt.optionId] = varopt.value;\n return acc;\n }, {});\n};\n\nexport default function ProductActions({\n product,\n regionId,\n disabled,\n enableMobileActions = true,\n}: ProductActionsProps) {\n const [options, setOptions] = useState<Record<string, string | undefined>>(\n {}\n );\n const [status, setStatus] = useState<AddToCartStatus>(AddToCartStatus.IDLE);\n const countryCode = useParams().countryCode as string;\n const { product: pricingProduct } = useProductPrice(product.id, regionId);\n const pricedProduct = useMemo(\n () => mergeProductPricing(product, pricingProduct),\n [product, pricingProduct]\n );\n\n // If there is only 1 variant, preselect the options\n useEffect(() => {\n if (pricedProduct?.variants && pricedProduct.variants.length === 1) {\n const variantOptions = optionsAsKeymap(\n pricedProduct.variants[0]?.options || null\n );\n setOptions(variantOptions ?? {});\n }\n }, [pricedProduct.variants]);\n\n const selectedVariant = useMemo(() => {\n if (!pricedProduct.variants || pricedProduct.variants.length === 0) {\n return;\n }\n\n return pricedProduct.variants.find((v) => {\n const variantOptions = optionsAsKeymap(v.options);\n return isEqual(variantOptions, options);\n });\n }, [pricedProduct.variants, options]);\n\n // update the options when a variant is selected\n const setOptionValue = (optionId: string, value: string) => {\n setOptions((prev) => ({\n ...prev,\n [optionId]: value,\n }));\n };\n\n //check if the selected options produce a valid variant\n const isValidVariant = useMemo(() => {\n return pricedProduct.variants?.some((v) => {\n const variantOptions = optionsAsKeymap(v.options);\n return isEqual(variantOptions, options);\n });\n }, [pricedProduct.variants, options]);\n\n const stockStatus = useMemo(() => {\n if (!selectedVariant) {\n return 'unknown' as const;\n }\n\n if (!selectedVariant.manageInventory) {\n return 'in_stock' as const;\n }\n\n if (selectedVariant.allowBackorder) {\n return 'in_stock' as const;\n }\n\n const qty = selectedVariant.inventoryQuantity;\n\n if (typeof qty !== 'number') {\n return 'in_stock' as const;\n }\n\n return qty > 0 ? ('in_stock' as const) : ('out_of_stock' as const);\n }, [selectedVariant]);\n\n const inStock = useMemo(() => {\n // If we don't manage inventory, we can always add to cart\n if (selectedVariant && !selectedVariant.manageInventory) {\n return true;\n }\n\n // If we allow back orders on the variant, we can add to cart\n if (selectedVariant?.allowBackorder) {\n return true;\n }\n\n if (selectedVariant?.manageInventory) {\n const qty = selectedVariant.inventoryQuantity;\n if (typeof qty === 'number') {\n return qty > 0;\n }\n // If we don't have a numeric quantity, don't block add-to-cart\n return true;\n }\n\n // Otherwise, we can't add to cart\n return false;\n }, [selectedVariant]);\n\n const actionsRef = useRef<HTMLDivElement>(null);\n\n const inView = useIntersection(actionsRef, '0px');\n\n // add the selected variant to the cart\n const handleAddToCart = async () => {\n if (!selectedVariant?.id) return null;\n\n setStatus(AddToCartStatus.ADDING);\n\n try {\n await addToCart({\n variantId: selectedVariant.id,\n quantity: 1,\n countryCode,\n });\n\n mutateCart();\n\n setStatus(AddToCartStatus.SUCCESS);\n } catch (error) {\n console.log(error);\n setStatus(AddToCartStatus.ERROR);\n }\n };\n\n return (\n <>\n <div className=\"flex flex-col gap-y-2\" ref={actionsRef}>\n <div>\n {(product.variants?.length ?? 0) > 1 && (\n <div className=\"flex flex-col gap-y-4\">\n {(product.options || []).map((option) => {\n return (\n <div key={option.id}>\n <OptionSelect\n option={option}\n current={options[option.id]}\n updateOption={setOptionValue}\n title={option.title ?? ''}\n data-testid=\"product-options\"\n disabled={!!disabled || status === AddToCartStatus.ADDING}\n />\n </div>\n );\n })}\n <Divider />\n </div>\n )}\n </div>\n\n <ProductPrice product={pricedProduct} variant={selectedVariant} />\n\n {status === AddToCartStatus.ERROR && (\n <ErrorMessage error=\"Failed adding product to cart. Please try again.\" />\n )}\n {status === AddToCartStatus.SUCCESS && (\n <div className=\"text-small-regular pt-2 text-green-700\">\n Successfully added product to cart\n </div>\n )}\n <Button\n onClick={handleAddToCart}\n disabled={\n !inStock ||\n !selectedVariant ||\n !!disabled ||\n status === AddToCartStatus.ADDING ||\n !isValidVariant\n }\n variant=\"primary\"\n className=\"h-10 w-full\"\n isLoading={status === AddToCartStatus.ADDING}\n data-testid=\"add-product-button\"\n >\n {!selectedVariant\n ? 'Add to cart'\n : !inStock || !isValidVariant\n ? 'Out of stock'\n : 'Add to cart'}\n </Button>\n {enableMobileActions && (\n <MobileActions\n product={pricedProduct}\n variant={selectedVariant}\n options={options}\n updateOptions={setOptionValue}\n stockStatus={stockStatus}\n handleAddToCart={handleAddToCart}\n isAdding={status === AddToCartStatus.ADDING}\n show={!inView}\n optionsDisabled={!!disabled || status === AddToCartStatus.ADDING}\n />\n )}\n </div>\n </>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAgCA,IAAK,8DAAL;AACE;AACA;AACA;AACA;;EAJG;AAOL,MAAM,mBACJ,mBAKG;AACH,QAAO,gBAAgB,QAAQ,KAA6B,WAAgB;AAC1E,MAAI,OAAO,YAAY,OAAO;AAC9B,SAAO;IACN,EAAE,CAAC;;AAGR,SAAwB,eAAe,EACrC,SACA,UACA,UACA,sBAAsB,QACA;CACtB,MAAM,CAAC,SAAS,cAAc,SAC5B,EAAE,CACH;CACD,MAAM,CAAC,QAAQ,aAAa,SAA0B,gBAAgB,KAAK;CAC3E,MAAM,cAAc,WAAW,CAAC;CAChC,MAAM,EAAE,SAAS,mBAAmB,gBAAgB,QAAQ,IAAI,SAAS;CACzE,MAAM,gBAAgB,cACd,oBAAoB,SAAS,eAAe,EAClD,CAAC,SAAS,eAAe,CAC1B;AAGD,iBAAgB;AACd,MAAI,eAAe,YAAY,cAAc,SAAS,WAAW,EAI/D,YAHuB,gBACrB,cAAc,SAAS,IAAI,WAAW,KACvC,IAC4B,EAAE,CAAC;IAEjC,CAAC,cAAc,SAAS,CAAC;CAE5B,MAAM,kBAAkB,cAAc;AACpC,MAAI,CAAC,cAAc,YAAY,cAAc,SAAS,WAAW,EAC/D;AAGF,SAAO,cAAc,SAAS,MAAM,MAAM;AAExC,UAAO,QADgB,gBAAgB,EAAE,QAAQ,EAClB,QAAQ;IACvC;IACD,CAAC,cAAc,UAAU,QAAQ,CAAC;CAGrC,MAAM,kBAAkB,UAAkB,UAAkB;AAC1D,cAAY,UAAU;GACpB,GAAG;IACF,WAAW;GACb,EAAE;;CAIL,MAAM,iBAAiB,cAAc;AACnC,SAAO,cAAc,UAAU,MAAM,MAAM;AAEzC,UAAO,QADgB,gBAAgB,EAAE,QAAQ,EAClB,QAAQ;IACvC;IACD,CAAC,cAAc,UAAU,QAAQ,CAAC;CAErC,MAAM,cAAc,cAAc;AAChC,MAAI,CAAC,gBACH,QAAO;AAGT,MAAI,CAAC,gBAAgB,gBACnB,QAAO;AAGT,MAAI,gBAAgB,eAClB,QAAO;EAGT,MAAM,MAAM,gBAAgB;AAE5B,MAAI,OAAO,QAAQ,SACjB,QAAO;AAGT,SAAO,MAAM,IAAK,aAAwB;IACzC,CAAC,gBAAgB,CAAC;CAErB,MAAM,UAAU,cAAc;AAE5B,MAAI,mBAAmB,CAAC,gBAAgB,gBACtC,QAAO;AAIT,MAAI,iBAAiB,eACnB,QAAO;AAGT,MAAI,iBAAiB,iBAAiB;GACpC,MAAM,MAAM,gBAAgB;AAC5B,OAAI,OAAO,QAAQ,SACjB,QAAO,MAAM;AAGf,UAAO;;AAIT,SAAO;IACN,CAAC,gBAAgB,CAAC;CAErB,MAAM,aAAa,OAAuB,KAAK;CAE/C,MAAM,SAAS,gBAAgB,YAAY,MAAM;CAGjD,MAAM,kBAAkB,YAAY;AAClC,MAAI,CAAC,iBAAiB,GAAI,QAAO;AAEjC,YAAU,gBAAgB,OAAO;AAEjC,MAAI;AACF,SAAM,UAAU;IACd,WAAW,gBAAgB;IAC3B,UAAU;IACV;IACD,CAAC;AAEF,eAAY;AAEZ,aAAU,gBAAgB,QAAQ;WAC3B,OAAO;AACd,WAAQ,IAAI,MAAM;AAClB,aAAU,gBAAgB,MAAM;;;AAIpC,QACE,0CACE,qBAAC;EAAI,WAAU;EAAwB,KAAK;;GAC1C,oBAAC,oBACG,QAAQ,UAAU,UAAU,KAAK,KACjC,qBAAC;IAAI,WAAU;gBACX,QAAQ,WAAW,EAAE,EAAE,KAAK,WAAW;AACvC,YACE,oBAAC,mBACC,oBAACA;MACS;MACR,SAAS,QAAQ,OAAO;MACxB,cAAc;MACd,OAAO,OAAO,SAAS;MACvB,eAAY;MACZ,UAAU,CAAC,CAAC,YAAY,WAAW,gBAAgB;OACnD,IARM,OAAO,GASX;MAER,EACF,oBAAC,YAAU;KACP,GAEJ;GAEN,oBAAC;IAAa,SAAS;IAAe,SAAS;KAAmB;GAEjE,WAAW,gBAAgB,SAC1B,oBAAC,gBAAa,OAAM,qDAAqD;GAE1E,WAAW,gBAAgB,WAC1B,oBAAC;IAAI,WAAU;cAAyC;KAElD;GAER,oBAAC;IACC,SAAS;IACT,UACE,CAAC,WACD,CAAC,mBACD,CAAC,CAAC,YACF,WAAW,gBAAgB,UAC3B,CAAC;IAEH,SAAQ;IACR,WAAU;IACV,WAAW,WAAW,gBAAgB;IACtC,eAAY;cAEX,CAAC,kBACE,gBACA,CAAC,WAAW,CAAC,iBACX,iBACA;KACC;GACR,uBACC,oBAACC;IACC,SAAS;IACT,SAAS;IACA;IACT,eAAe;IACF;IACI;IACjB,UAAU,WAAW,gBAAgB;IACrC,MAAM,CAAC;IACP,iBAAiB,CAAC,CAAC,YAAY,WAAW,gBAAgB;KAC1D;;GAEA,GACL"}
1
+ {"version":3,"file":"index.js","names":["OptionSelect","MobileActions"],"sources":["../../../src/components/product-actions/index.tsx"],"sourcesContent":["'use client';\n\nimport { useEffect, useMemo, useRef, useState } from 'react';\n\nimport { useParams } from 'next/navigation';\n\nimport { isEqual } from 'lodash';\n\nimport { ErrorMessage } from '@gfed-medusa/sf-lib-common/components/error-message';\nimport { WebComponent } from '@gfed-medusa/sf-lib-common/components/web-component';\nimport { mutateCart } from '@gfed-medusa/sf-lib-common/lib/hooks/use-cart';\nimport { Divider } from '@gfed-medusa/sf-lib-ui/components/divider';\nimport { HttpTypes } from '@medusajs/types';\nimport { Button } from '@medusajs/ui';\n\nimport OptionSelect from '@/components/product-actions/option-select';\nimport { addToCart } from '@/lib/data/cart';\nimport { useIntersection } from '@/lib/hooks/use-intersection';\nimport { useProductPrice } from '@/lib/hooks/use-product-price';\nimport { mergeProductPricing } from '@/lib/utils/merge-product-pricing';\nimport { ProductActionsProduct } from '@/types';\nimport { ProductVariant } from '@/types/graphql';\n\nimport MobileActions from './mobile-actions';\n\nexport type ProductActionsProps = {\n product: ProductActionsProduct;\n regionId?: string;\n disabled?: boolean;\n enableMobileActions?: boolean;\n};\n\nenum AddToCartStatus {\n IDLE = 'idle',\n ADDING = 'adding',\n SUCCESS = 'success',\n ERROR = 'error',\n}\n\nconst optionsAsKeymap = (\n variantOptions:\n | HttpTypes.StoreProductVariant['options']\n | ProductVariant['options']\n | null\n | undefined\n) => {\n return variantOptions?.reduce((acc: Record<string, string>, varopt: any) => {\n acc[varopt.optionId] = varopt.value;\n return acc;\n }, {});\n};\n\nexport default function ProductActions({\n product,\n regionId,\n disabled,\n enableMobileActions = true,\n}: ProductActionsProps) {\n const [options, setOptions] = useState<Record<string, string | undefined>>(\n {}\n );\n const [status, setStatus] = useState<AddToCartStatus>(AddToCartStatus.IDLE);\n const countryCode = useParams().countryCode as string;\n const { product: pricingProduct } = useProductPrice(product.id, regionId);\n const pricedProduct = useMemo(\n () => mergeProductPricing(product, pricingProduct),\n [product, pricingProduct]\n );\n\n // If there is only 1 variant, preselect the options\n useEffect(() => {\n if (pricedProduct?.variants && pricedProduct.variants.length === 1) {\n const variantOptions = optionsAsKeymap(\n pricedProduct.variants[0]?.options || null\n );\n setOptions(variantOptions ?? {});\n }\n }, [pricedProduct.variants]);\n\n const selectedVariant = useMemo(() => {\n if (!pricedProduct.variants || pricedProduct.variants.length === 0) {\n return;\n }\n\n return pricedProduct.variants.find((v) => {\n const variantOptions = optionsAsKeymap(v.options);\n return isEqual(variantOptions, options);\n });\n }, [pricedProduct.variants, options]);\n\n // update the options when a variant is selected\n const setOptionValue = (optionId: string, value: string) => {\n setOptions((prev) => ({\n ...prev,\n [optionId]: value,\n }));\n };\n\n //check if the selected options produce a valid variant\n const isValidVariant = useMemo(() => {\n return pricedProduct.variants?.some((v) => {\n const variantOptions = optionsAsKeymap(v.options);\n return isEqual(variantOptions, options);\n });\n }, [pricedProduct.variants, options]);\n\n const stockStatus = useMemo(() => {\n if (!selectedVariant) {\n return 'unknown' as const;\n }\n\n if (!selectedVariant.manageInventory) {\n return 'in_stock' as const;\n }\n\n if (selectedVariant.allowBackorder) {\n return 'in_stock' as const;\n }\n\n const qty = selectedVariant.inventoryQuantity;\n\n if (typeof qty !== 'number') {\n return 'in_stock' as const;\n }\n\n return qty > 0 ? ('in_stock' as const) : ('out_of_stock' as const);\n }, [selectedVariant]);\n\n const inStock = useMemo(() => {\n // If we don't manage inventory, we can always add to cart\n if (selectedVariant && !selectedVariant.manageInventory) {\n return true;\n }\n\n // If we allow back orders on the variant, we can add to cart\n if (selectedVariant?.allowBackorder) {\n return true;\n }\n\n if (selectedVariant?.manageInventory) {\n const qty = selectedVariant.inventoryQuantity;\n if (typeof qty === 'number') {\n return qty > 0;\n }\n // If we don't have a numeric quantity, don't block add-to-cart\n return true;\n }\n\n // Otherwise, we can't add to cart\n return false;\n }, [selectedVariant]);\n\n const actionsRef = useRef<HTMLDivElement>(null);\n\n const inView = useIntersection(actionsRef, '0px');\n\n // add the selected variant to the cart\n const handleAddToCart = async () => {\n if (!selectedVariant?.id) return null;\n\n setStatus(AddToCartStatus.ADDING);\n\n try {\n await addToCart({\n variantId: selectedVariant.id,\n quantity: 1,\n countryCode,\n });\n\n mutateCart();\n\n setStatus(AddToCartStatus.SUCCESS);\n } catch (error) {\n console.log(error);\n setStatus(AddToCartStatus.ERROR);\n }\n };\n\n return (\n <>\n <div className=\"flex flex-col gap-y-2\" ref={actionsRef}>\n <div>\n {(product.variants?.length ?? 0) > 1 && (\n <div className=\"flex flex-col gap-y-4\">\n {(product.options || []).map((option) => {\n return (\n <div key={option.id}>\n <OptionSelect\n option={option}\n current={options[option.id]}\n updateOption={setOptionValue}\n title={option.title ?? ''}\n data-testid=\"product-options\"\n disabled={!!disabled || status === AddToCartStatus.ADDING}\n />\n </div>\n );\n })}\n <Divider />\n </div>\n )}\n </div>\n\n <WebComponent\n tag=\"mfe-product-price\"\n data-props={JSON.stringify({\n selectedVariantId: selectedVariant?.id ?? '',\n })}\n />\n\n {status === AddToCartStatus.ERROR && (\n <ErrorMessage error=\"Failed adding product to cart. Please try again.\" />\n )}\n {status === AddToCartStatus.SUCCESS && (\n <div className=\"text-small-regular pt-2 text-green-700\">\n Successfully added product to cart\n </div>\n )}\n <Button\n onClick={handleAddToCart}\n disabled={\n !inStock ||\n !selectedVariant ||\n !!disabled ||\n status === AddToCartStatus.ADDING ||\n !isValidVariant\n }\n variant=\"primary\"\n className=\"h-10 w-full\"\n isLoading={status === AddToCartStatus.ADDING}\n data-testid=\"add-product-button\"\n >\n {!selectedVariant\n ? 'Add to cart'\n : !inStock || !isValidVariant\n ? 'Out of stock'\n : 'Add to cart'}\n </Button>\n {enableMobileActions && (\n <MobileActions\n product={pricedProduct}\n variant={selectedVariant}\n options={options}\n updateOptions={setOptionValue}\n stockStatus={stockStatus}\n handleAddToCart={handleAddToCart}\n isAdding={status === AddToCartStatus.ADDING}\n show={!inView}\n optionsDisabled={!!disabled || status === AddToCartStatus.ADDING}\n />\n )}\n </div>\n </>\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"mobile-actions.d.ts","names":[],"sources":["../../../src/components/product-actions/mobile-actions.tsx"],"sourcesContent":[],"mappings":";;;;;KAiBK,kBAAA;WACM;EADN,OAAA,CAAA,EAEO,cAFW;EACZ,OAAA,EAEA,MAFA,CAAA,MAAA,EAAA,MAAA,GAAA,SAAA,CAAA;EACC,aAAA,EAAA,CAAA,KAAA,EAAA,MAAA,EAAA,KAAA,EAAA,MAAA,EAAA,GAAA,IAAA;EACD,WAAA,CAAA,EAAA,SAAA,GAAA,UAAA,GAAA,cAAA;EAAM,eAAA,EAAA,GAAA,GAAA,IAAA;EAuBX,QAAA,CAAA,EAAA,OAmML;;;;cAnMK,eAAe,KAAA,CAAM,GAAG"}
1
+ {"version":3,"file":"mobile-actions.d.ts","names":[],"sources":["../../../src/components/product-actions/mobile-actions.tsx"],"sourcesContent":[],"mappings":";;;;;KAiBK,kBAAA;WACM;EADN,OAAA,CAAA,EAEO,cAFW;EACZ,OAAA,EAEA,MAFA,CAAA,MAAA,EAAA,MAAA,GAAA,SAAA,CAAA;EACC,aAAA,EAAA,CAAA,KAAA,EAAA,MAAA,EAAA,KAAA,EAAA,MAAA,EAAA,GAAA,IAAA;EACD,WAAA,CAAA,EAAA,SAAA,GAAA,UAAA,GAAA,cAAA;EAAM,eAAA,EAAA,GAAA,GAAA,IAAA;EAuBX,QAAA,CAAA,EAAA,OAqKL;;;;cArKK,eAAe,KAAA,CAAM,GAAG"}
@@ -2,9 +2,9 @@ import option_select_default from "./option-select.js";
2
2
  import { isSimpleProduct } from "../../lib/utils/product.js";
3
3
  import { Button, clx } from "@medusajs/ui";
4
4
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
5
- import React, { Fragment as Fragment$1, useMemo } from "react";
5
+ import React, { Fragment as Fragment$1 } from "react";
6
6
  import { isEqual } from "lodash";
7
- import { getProductPrice } from "@gfed-medusa/sf-lib-common/lib/utils/get-product-price";
7
+ import { WebComponent } from "@gfed-medusa/sf-lib-common/components/web-component";
8
8
  import useToggleState from "@gfed-medusa/sf-lib-common/lib/hooks/use-toggle-state";
9
9
  import { ChevronDown } from "@gfed-medusa/sf-lib-ui/icons/chevron-down";
10
10
  import { X } from "@gfed-medusa/sf-lib-ui/icons/x";
@@ -20,15 +20,6 @@ const optionsAsKeymap = (variantOptions) => {
20
20
  };
21
21
  const MobileActions = ({ product, variant, options, updateOptions, stockStatus, handleAddToCart, isAdding, show, optionsDisabled }) => {
22
22
  const { state, open, close } = useToggleState();
23
- const price = getProductPrice({
24
- product,
25
- variantId: variant?.id
26
- });
27
- const selectedPrice = useMemo(() => {
28
- if (!price) return null;
29
- const { variantPrice, cheapestPrice } = price;
30
- return (variant ? variantPrice : cheapestPrice) || null;
31
- }, [price, variant]);
32
23
  const isSimple = isSimpleProduct(product);
33
24
  const handleUpdateOption = (optionId, value) => {
34
25
  updateOptions(optionId, value);
@@ -58,16 +49,10 @@ const MobileActions = ({ product, variant, options, updateOptions, stockStatus,
58
49
  className: "flex-1 text-left",
59
50
  "data-testid": "mobile-title",
60
51
  children: product.title
61
- }), selectedPrice ? /* @__PURE__ */ jsxs("div", {
62
- className: "text-ui-fg-base flex shrink-0 items-start gap-x-2 self-start",
63
- children: [selectedPrice.price_type === "sale" && /* @__PURE__ */ jsx("p", { children: /* @__PURE__ */ jsx("span", {
64
- className: "text-small-regular line-through",
65
- children: selectedPrice.original_price
66
- }) }), /* @__PURE__ */ jsxs("span", {
67
- className: clx({ "text-ui-fg-interactive": selectedPrice.price_type === "sale" }),
68
- children: [!variant && "From ", selectedPrice.calculated_price]
69
- })]
70
- }) : /* @__PURE__ */ jsx("div", { className: "h-5 w-24 shrink-0 self-start animate-pulse bg-gray-100" })]
52
+ }), /* @__PURE__ */ jsx(WebComponent, {
53
+ tag: "mfe-product-price",
54
+ "data-props": JSON.stringify({ selectedVariantId: variant?.id ?? "" })
55
+ })]
71
56
  }), /* @__PURE__ */ jsxs("div", {
72
57
  className: clx("grid w-full grid-cols-2 gap-x-4", { "!grid-cols-1": isSimple }),
73
58
  children: [!isSimple && /* @__PURE__ */ jsx(Button, {
@@ -1 +1 @@
1
- {"version":3,"file":"mobile-actions.js","names":["MobileActions: React.FC<MobileActionsProps>","Fragment","OptionSelect"],"sources":["../../../src/components/product-actions/mobile-actions.tsx"],"sourcesContent":["import React, { Fragment, useMemo } from 'react';\n\nimport { isEqual } from 'lodash';\n\nimport useToggleState from '@gfed-medusa/sf-lib-common/lib/hooks/use-toggle-state';\nimport { getProductPrice } from '@gfed-medusa/sf-lib-common/lib/utils/get-product-price';\nimport { ChevronDown } from '@gfed-medusa/sf-lib-ui/icons/chevron-down';\nimport { X } from '@gfed-medusa/sf-lib-ui/icons/x';\nimport { Dialog, Transition } from '@headlessui/react';\nimport { Button, clx } from '@medusajs/ui';\n\nimport { isSimpleProduct } from '@/lib/utils/product';\nimport { ProductActionsProduct } from '@/types';\nimport { ProductVariant } from '@/types/graphql';\n\nimport OptionSelect from './option-select';\n\ntype MobileActionsProps = {\n product: ProductActionsProduct;\n variant?: ProductVariant;\n options: Record<string, string | undefined>;\n updateOptions: (title: string, value: string) => void;\n stockStatus?: 'unknown' | 'in_stock' | 'out_of_stock';\n handleAddToCart: () => void;\n isAdding?: boolean;\n show: boolean;\n optionsDisabled: boolean;\n};\n\nconst optionsAsKeymap = (\n variantOptions: ProductVariant['options'] | null | undefined\n) => {\n return variantOptions?.reduce<Record<string, string>>((acc, varopt) => {\n if (!varopt) {\n return acc;\n }\n\n acc[varopt.optionId] = varopt.value;\n\n return acc;\n }, {});\n};\n\nconst MobileActions: React.FC<MobileActionsProps> = ({\n product,\n variant,\n options,\n updateOptions,\n stockStatus,\n handleAddToCart,\n isAdding,\n show,\n optionsDisabled,\n}) => {\n const { state, open, close } = useToggleState();\n\n const price = getProductPrice({\n product,\n variantId: variant?.id,\n });\n\n const selectedPrice = useMemo(() => {\n if (!price) {\n return null;\n }\n const { variantPrice, cheapestPrice } = price;\n\n return (variant ? variantPrice : cheapestPrice) || null;\n }, [price, variant]);\n\n const isSimple = isSimpleProduct(product);\n const handleUpdateOption = (optionId: string, value: string) => {\n updateOptions(optionId, value);\n\n const nextOptions = {\n ...options,\n [optionId]: value,\n };\n\n const hasMatchingVariant = (product.variants ?? []).some((productVariant) =>\n isEqual(optionsAsKeymap(productVariant.options), nextOptions)\n );\n\n if (hasMatchingVariant) {\n close();\n }\n };\n\n return (\n <>\n <div\n className={clx('fixed inset-x-0 bottom-0 z-40 lg:hidden', {\n 'pointer-events-none': !show,\n })}\n >\n <Transition\n as={Fragment}\n show={show}\n enter=\"ease-in-out duration-300\"\n enterFrom=\"opacity-0\"\n enterTo=\"opacity-100\"\n leave=\"ease-in duration-300\"\n leaveFrom=\"opacity-100\"\n leaveTo=\"opacity-0\"\n >\n <div\n className=\"text-large-regular flex h-full w-full flex-col items-center justify-center gap-y-3 border-t border-gray-200 bg-white p-4\"\n data-testid=\"mobile-actions\"\n >\n <div className=\"flex w-full items-start justify-between gap-x-4\">\n <span className=\"flex-1 text-left\" data-testid=\"mobile-title\">\n {product.title}\n </span>\n {selectedPrice ? (\n <div className=\"text-ui-fg-base flex shrink-0 items-start gap-x-2 self-start\">\n {selectedPrice.price_type === 'sale' && (\n <p>\n <span className=\"text-small-regular line-through\">\n {selectedPrice.original_price}\n </span>\n </p>\n )}\n <span\n className={clx({\n 'text-ui-fg-interactive':\n selectedPrice.price_type === 'sale',\n })}\n >\n {!variant && 'From '}\n {selectedPrice.calculated_price}\n </span>\n </div>\n ) : (\n <div className=\"h-5 w-24 shrink-0 self-start animate-pulse bg-gray-100\" />\n )}\n </div>\n <div\n className={clx('grid w-full grid-cols-2 gap-x-4', {\n '!grid-cols-1': isSimple,\n })}\n >\n {!isSimple && (\n <Button\n onClick={open}\n variant=\"secondary\"\n className=\"w-full\"\n data-testid=\"mobile-actions-button\"\n >\n <div className=\"flex w-full items-center justify-between\">\n <span>\n {variant\n ? Object.values(options).join(' / ')\n : 'Select Size'}\n </span>\n <ChevronDown />\n </div>\n </Button>\n )}\n <Button\n onClick={handleAddToCart}\n disabled={!variant || stockStatus === 'out_of_stock'}\n className=\"w-full\"\n isLoading={isAdding}\n data-testid=\"mobile-cart-button\"\n >\n {stockStatus === 'out_of_stock'\n ? 'Out of stock'\n : 'Add to cart'}\n </Button>\n </div>\n </div>\n </Transition>\n </div>\n <Transition appear show={state} as={Fragment}>\n <Dialog as=\"div\" className=\"relative z-[100]\" onClose={close}>\n <Transition.Child\n as={Fragment}\n enter=\"ease-out duration-300\"\n enterFrom=\"opacity-0\"\n enterTo=\"opacity-100\"\n leave=\"ease-in duration-200\"\n leaveFrom=\"opacity-100\"\n leaveTo=\"opacity-0\"\n >\n <div className=\"fixed inset-0 h-screen bg-black/20 backdrop-blur-sm\" />\n </Transition.Child>\n\n <div className=\"fixed inset-x-0 bottom-0\">\n <div className=\"flex h-full min-h-full items-center justify-center text-center\">\n <Transition.Child\n as={Fragment}\n enter=\"ease-out duration-300\"\n enterFrom=\"opacity-0\"\n enterTo=\"opacity-100\"\n leave=\"ease-in duration-200\"\n leaveFrom=\"opacity-100\"\n leaveTo=\"opacity-0\"\n >\n <Dialog.Panel\n className=\"pointer-events-none flex w-full transform flex-col gap-y-3 text-left\"\n data-testid=\"mobile-actions-modal\"\n >\n <div className=\"flex w-full justify-end pr-6\">\n <button\n onClick={close}\n className=\"text-ui-fg-base pointer-events-auto flex h-12 w-12 items-center justify-center rounded-full bg-white\"\n data-testid=\"close-modal-button\"\n >\n <X />\n </button>\n </div>\n <div className=\"pointer-events-auto bg-white px-6 py-12\">\n {(product.variants?.length ?? 0) > 1 && (\n <div className=\"flex flex-col gap-y-6\">\n {(product.options || []).map((option) => {\n return (\n <div key={option.id}>\n <OptionSelect\n option={option}\n current={options[option.id]}\n updateOption={handleUpdateOption}\n title={option.title ?? ''}\n disabled={optionsDisabled}\n />\n </div>\n );\n })}\n </div>\n )}\n </div>\n </Dialog.Panel>\n </Transition.Child>\n </div>\n </div>\n </Dialog>\n </Transition>\n </>\n );\n};\n\nexport default MobileActions;\n"],"mappings":"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"}
1
+ {"version":3,"file":"mobile-actions.js","names":["MobileActions: React.FC<MobileActionsProps>","Fragment","OptionSelect"],"sources":["../../../src/components/product-actions/mobile-actions.tsx"],"sourcesContent":["import React, { Fragment } from 'react';\n\nimport { isEqual } from 'lodash';\n\nimport { WebComponent } from '@gfed-medusa/sf-lib-common/components/web-component';\nimport useToggleState from '@gfed-medusa/sf-lib-common/lib/hooks/use-toggle-state';\nimport { ChevronDown } from '@gfed-medusa/sf-lib-ui/icons/chevron-down';\nimport { X } from '@gfed-medusa/sf-lib-ui/icons/x';\nimport { Dialog, Transition } from '@headlessui/react';\nimport { Button, clx } from '@medusajs/ui';\n\nimport { isSimpleProduct } from '@/lib/utils/product';\nimport { ProductActionsProduct } from '@/types';\nimport { ProductVariant } from '@/types/graphql';\n\nimport OptionSelect from './option-select';\n\ntype MobileActionsProps = {\n product: ProductActionsProduct;\n variant?: ProductVariant;\n options: Record<string, string | undefined>;\n updateOptions: (title: string, value: string) => void;\n stockStatus?: 'unknown' | 'in_stock' | 'out_of_stock';\n handleAddToCart: () => void;\n isAdding?: boolean;\n show: boolean;\n optionsDisabled: boolean;\n};\n\nconst optionsAsKeymap = (\n variantOptions: ProductVariant['options'] | null | undefined\n) => {\n return variantOptions?.reduce<Record<string, string>>((acc, varopt) => {\n if (!varopt) {\n return acc;\n }\n\n acc[varopt.optionId] = varopt.value;\n\n return acc;\n }, {});\n};\n\nconst MobileActions: React.FC<MobileActionsProps> = ({\n product,\n variant,\n options,\n updateOptions,\n stockStatus,\n handleAddToCart,\n isAdding,\n show,\n optionsDisabled,\n}) => {\n const { state, open, close } = useToggleState();\n\n const isSimple = isSimpleProduct(product);\n const handleUpdateOption = (optionId: string, value: string) => {\n updateOptions(optionId, value);\n\n const nextOptions = {\n ...options,\n [optionId]: value,\n };\n\n const hasMatchingVariant = (product.variants ?? []).some((productVariant) =>\n isEqual(optionsAsKeymap(productVariant.options), nextOptions)\n );\n\n if (hasMatchingVariant) {\n close();\n }\n };\n\n return (\n <>\n <div\n className={clx('fixed inset-x-0 bottom-0 z-40 lg:hidden', {\n 'pointer-events-none': !show,\n })}\n >\n <Transition\n as={Fragment}\n show={show}\n enter=\"ease-in-out duration-300\"\n enterFrom=\"opacity-0\"\n enterTo=\"opacity-100\"\n leave=\"ease-in duration-300\"\n leaveFrom=\"opacity-100\"\n leaveTo=\"opacity-0\"\n >\n <div\n className=\"text-large-regular flex h-full w-full flex-col items-center justify-center gap-y-3 border-t border-gray-200 bg-white p-4\"\n data-testid=\"mobile-actions\"\n >\n <div className=\"flex w-full items-start justify-between gap-x-4\">\n <span className=\"flex-1 text-left\" data-testid=\"mobile-title\">\n {product.title}\n </span>\n <WebComponent\n tag=\"mfe-product-price\"\n data-props={JSON.stringify({\n selectedVariantId: variant?.id ?? '',\n })}\n />\n </div>\n <div\n className={clx('grid w-full grid-cols-2 gap-x-4', {\n '!grid-cols-1': isSimple,\n })}\n >\n {!isSimple && (\n <Button\n onClick={open}\n variant=\"secondary\"\n className=\"w-full\"\n data-testid=\"mobile-actions-button\"\n >\n <div className=\"flex w-full items-center justify-between\">\n <span>\n {variant\n ? Object.values(options).join(' / ')\n : 'Select Size'}\n </span>\n <ChevronDown />\n </div>\n </Button>\n )}\n <Button\n onClick={handleAddToCart}\n disabled={!variant || stockStatus === 'out_of_stock'}\n className=\"w-full\"\n isLoading={isAdding}\n data-testid=\"mobile-cart-button\"\n >\n {stockStatus === 'out_of_stock'\n ? 'Out of stock'\n : 'Add to cart'}\n </Button>\n </div>\n </div>\n </Transition>\n </div>\n <Transition appear show={state} as={Fragment}>\n <Dialog as=\"div\" className=\"relative z-[100]\" onClose={close}>\n <Transition.Child\n as={Fragment}\n enter=\"ease-out duration-300\"\n enterFrom=\"opacity-0\"\n enterTo=\"opacity-100\"\n leave=\"ease-in duration-200\"\n leaveFrom=\"opacity-100\"\n leaveTo=\"opacity-0\"\n >\n <div className=\"fixed inset-0 h-screen bg-black/20 backdrop-blur-sm\" />\n </Transition.Child>\n\n <div className=\"fixed inset-x-0 bottom-0\">\n <div className=\"flex h-full min-h-full items-center justify-center text-center\">\n <Transition.Child\n as={Fragment}\n enter=\"ease-out duration-300\"\n enterFrom=\"opacity-0\"\n enterTo=\"opacity-100\"\n leave=\"ease-in duration-200\"\n leaveFrom=\"opacity-100\"\n leaveTo=\"opacity-0\"\n >\n <Dialog.Panel\n className=\"pointer-events-none flex w-full transform flex-col gap-y-3 text-left\"\n data-testid=\"mobile-actions-modal\"\n >\n <div className=\"flex w-full justify-end pr-6\">\n <button\n onClick={close}\n className=\"text-ui-fg-base pointer-events-auto flex h-12 w-12 items-center justify-center rounded-full bg-white\"\n data-testid=\"close-modal-button\"\n >\n <X />\n </button>\n </div>\n <div className=\"pointer-events-auto bg-white px-6 py-12\">\n {(product.variants?.length ?? 0) > 1 && (\n <div className=\"flex flex-col gap-y-6\">\n {(product.options || []).map((option) => {\n return (\n <div key={option.id}>\n <OptionSelect\n option={option}\n current={options[option.id]}\n updateOption={handleUpdateOption}\n title={option.title ?? ''}\n disabled={optionsDisabled}\n />\n </div>\n );\n })}\n </div>\n )}\n </div>\n </Dialog.Panel>\n </Transition.Child>\n </div>\n </div>\n </Dialog>\n </Transition>\n </>\n );\n};\n\nexport default MobileActions;\n"],"mappings":";;;;;;;;;;;;;AA6BA,MAAM,mBACJ,mBACG;AACH,QAAO,gBAAgB,QAAgC,KAAK,WAAW;AACrE,MAAI,CAAC,OACH,QAAO;AAGT,MAAI,OAAO,YAAY,OAAO;AAE9B,SAAO;IACN,EAAE,CAAC;;AAGR,MAAMA,iBAA+C,EACnD,SACA,SACA,SACA,eACA,aACA,iBACA,UACA,MACA,sBACI;CACJ,MAAM,EAAE,OAAO,MAAM,UAAU,gBAAgB;CAE/C,MAAM,WAAW,gBAAgB,QAAQ;CACzC,MAAM,sBAAsB,UAAkB,UAAkB;AAC9D,gBAAc,UAAU,MAAM;EAE9B,MAAM,cAAc;GAClB,GAAG;IACF,WAAW;GACb;AAMD,OAJ4B,QAAQ,YAAY,EAAE,EAAE,MAAM,mBACxD,QAAQ,gBAAgB,eAAe,QAAQ,EAAE,YAAY,CAC9D,CAGC,QAAO;;AAIX,QACE,4CACE,oBAAC;EACC,WAAW,IAAI,2CAA2C,EACxD,uBAAuB,CAAC,MACzB,CAAC;YAEF,oBAAC;GACC,IAAIC;GACE;GACN,OAAM;GACN,WAAU;GACV,SAAQ;GACR,OAAM;GACN,WAAU;GACV,SAAQ;aAER,qBAAC;IACC,WAAU;IACV,eAAY;eAEZ,qBAAC;KAAI,WAAU;gBACb,oBAAC;MAAK,WAAU;MAAmB,eAAY;gBAC5C,QAAQ;OACJ,EACP,oBAAC;MACC,KAAI;MACJ,cAAY,KAAK,UAAU,EACzB,mBAAmB,SAAS,MAAM,IACnC,CAAC;OACF;MACE,EACN,qBAAC;KACC,WAAW,IAAI,mCAAmC,EAChD,gBAAgB,UACjB,CAAC;gBAED,CAAC,YACA,oBAAC;MACC,SAAS;MACT,SAAQ;MACR,WAAU;MACV,eAAY;gBAEZ,qBAAC;OAAI,WAAU;kBACb,oBAAC,oBACE,UACG,OAAO,OAAO,QAAQ,CAAC,KAAK,MAAM,GAClC,gBACC,EACP,oBAAC,gBAAc;QACX;OACC,EAEX,oBAAC;MACC,SAAS;MACT,UAAU,CAAC,WAAW,gBAAgB;MACtC,WAAU;MACV,WAAW;MACX,eAAY;gBAEX,gBAAgB,iBACb,iBACA;OACG;MACL;KACF;IACK;GACT,EACN,oBAAC;EAAW;EAAO,MAAM;EAAO,IAAIA;YAClC,qBAAC;GAAO,IAAG;GAAM,WAAU;GAAmB,SAAS;cACrD,oBAAC,WAAW;IACV,IAAIA;IACJ,OAAM;IACN,WAAU;IACV,SAAQ;IACR,OAAM;IACN,WAAU;IACV,SAAQ;cAER,oBAAC,SAAI,WAAU,wDAAwD;KACtD,EAEnB,oBAAC;IAAI,WAAU;cACb,oBAAC;KAAI,WAAU;eACb,oBAAC,WAAW;MACV,IAAIA;MACJ,OAAM;MACN,WAAU;MACV,SAAQ;MACR,OAAM;MACN,WAAU;MACV,SAAQ;gBAER,qBAAC,OAAO;OACN,WAAU;OACV,eAAY;kBAEZ,oBAAC;QAAI,WAAU;kBACb,oBAAC;SACC,SAAS;SACT,WAAU;SACV,eAAY;mBAEZ,oBAAC,MAAI;UACE;SACL,EACN,oBAAC;QAAI,WAAU;mBACX,QAAQ,UAAU,UAAU,KAAK,KACjC,oBAAC;SAAI,WAAU;oBACX,QAAQ,WAAW,EAAE,EAAE,KAAK,WAAW;AACvC,iBACE,oBAAC,mBACC,oBAACC;WACS;WACR,SAAS,QAAQ,OAAO;WACxB,cAAc;WACd,OAAO,OAAO,SAAS;WACvB,UAAU;YACV,IAPM,OAAO,GAQX;WAER;UACE;SAEJ;QACO;OACE;MACf;KACF;IACC;GACE,IACZ;;AAIP,6BAAe"}
@@ -1,7 +1,7 @@
1
- import * as react_jsx_runtime14 from "react/jsx-runtime";
1
+ import * as react_jsx_runtime4 from "react/jsx-runtime";
2
2
 
3
3
  //#region src/components/product-onboarding-cta/index.d.ts
4
- declare function ProductOnboardingCta(): Promise<react_jsx_runtime14.JSX.Element | null>;
4
+ declare function ProductOnboardingCta(): Promise<react_jsx_runtime4.JSX.Element | null>;
5
5
  //#endregion
6
6
  export { ProductOnboardingCta as default };
7
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/components/product-onboarding-cta/index.tsx"],"sourcesContent":[],"mappings":";;;iBAIe,oBAAA,CAAA,GAAoB,QAAA,mBAAA,CAAA,GAAA,CAAA,OAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/components/product-onboarding-cta/index.tsx"],"sourcesContent":[],"mappings":";;;iBAIe,oBAAA,CAAA,GAAoB,QAAA,kBAAA,CAAA,GAAA,CAAA,OAAA"}
@@ -1,6 +1,6 @@
1
1
  import { ProductVariant } from "../../types/graphql.js";
2
2
  import { ProductActionsProduct } from "../../types/index.js";
3
- import * as react_jsx_runtime15 from "react/jsx-runtime";
3
+ import * as react_jsx_runtime3 from "react/jsx-runtime";
4
4
 
5
5
  //#region src/components/product-price/index.d.ts
6
6
  declare function ProductPrice({
@@ -9,7 +9,7 @@ declare function ProductPrice({
9
9
  }: {
10
10
  product: ProductActionsProduct;
11
11
  variant?: ProductVariant;
12
- }): react_jsx_runtime15.JSX.Element;
12
+ }): react_jsx_runtime3.JSX.Element;
13
13
  //#endregion
14
14
  export { ProductPrice as default };
15
15
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/components/product-price/index.tsx"],"sourcesContent":[],"mappings":";;;;;iBAOwB,YAAA;;;AAFyB;WAMtC;YACC;AAPqC,CAAA,CAAA,EAQhD,mBAAA,CAAA,GAAA,CAAA,OANmC"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../../../src/components/product-price/index.tsx"],"sourcesContent":[],"mappings":";;;;;iBAOwB,YAAA;;;AAFyB;WAMtC;YACC;AAPqC,CAAA,CAAA,EAQhD,kBAAA,CAAA,GAAA,CAAA,OANmC"}
@@ -1,5 +1,5 @@
1
1
  import { Product } from "../../types/graphql.js";
2
- import * as react_jsx_runtime0 from "react/jsx-runtime";
2
+ import * as react_jsx_runtime5 from "react/jsx-runtime";
3
3
 
4
4
  //#region src/components/product-tabs/index.d.ts
5
5
  type ProductTabsProps = {
@@ -7,7 +7,7 @@ type ProductTabsProps = {
7
7
  };
8
8
  declare const ProductTabs: ({
9
9
  product
10
- }: ProductTabsProps) => react_jsx_runtime0.JSX.Element;
10
+ }: ProductTabsProps) => react_jsx_runtime5.JSX.Element;
11
11
  //#endregion
12
12
  export { ProductTabs as default };
13
13
  //# sourceMappingURL=index.d.ts.map
@@ -1,5 +1,5 @@
1
1
  import { SortOptions } from "./sort-products/index.js";
2
- import * as react_jsx_runtime0 from "react/jsx-runtime";
2
+ import * as react_jsx_runtime7 from "react/jsx-runtime";
3
3
 
4
4
  //#region src/components/refinement-list/index.d.ts
5
5
  type RefinementListProps = {
@@ -12,7 +12,7 @@ declare const RefinementList: ({
12
12
  sortBy,
13
13
  "data-testid": dataTestId,
14
14
  className
15
- }: RefinementListProps) => react_jsx_runtime0.JSX.Element;
15
+ }: RefinementListProps) => react_jsx_runtime7.JSX.Element;
16
16
  //#endregion
17
17
  export { RefinementList as default };
18
18
  //# sourceMappingURL=index.d.ts.map
@@ -3,8 +3,8 @@
3
3
  import sort_products_default from "./sort-products/index.js";
4
4
  import { clx } from "@medusajs/ui";
5
5
  import { jsx, jsxs } from "react/jsx-runtime";
6
- import { usePathname, useRouter, useSearchParams } from "next/navigation";
7
6
  import { useCallback } from "react";
7
+ import { usePathname, useRouter, useSearchParams } from "next/navigation";
8
8
 
9
9
  //#region src/components/refinement-list/index.tsx
10
10
  const RefinementList = ({ sortBy, "data-testid": dataTestId, className }) => {
@@ -1,4 +1,4 @@
1
- import * as react_jsx_runtime11 from "react/jsx-runtime";
1
+ import * as react_jsx_runtime14 from "react/jsx-runtime";
2
2
 
3
3
  //#region src/components/refinement-list/sort-products/index.d.ts
4
4
  type SortOptions = 'price_asc' | 'price_desc' | 'created_at';
@@ -13,7 +13,7 @@ declare const SortProducts: ({
13
13
  sortBy,
14
14
  setQueryParams,
15
15
  variant
16
- }: SortProductsProps) => react_jsx_runtime11.JSX.Element;
16
+ }: SortProductsProps) => react_jsx_runtime14.JSX.Element;
17
17
  //#endregion
18
18
  export { SortOptions, SortProducts as default };
19
19
  //# sourceMappingURL=index.d.ts.map