@lime-bundles/react 6.1.0 → 6.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -1
- package/dist/index.cjs +620 -491
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +22 -3
- package/dist/index.d.ts +22 -3
- package/dist/index.js +565 -434
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1901 -0
- package/docs/hydrogen.md +28 -3
- package/docs/react-nextjs.md +23 -3
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -23,6 +23,7 @@ __export(index_exports, {
|
|
|
23
23
|
BUNDLES_FOR_PRODUCT_QUERY: () => import_core18.BUNDLES_FOR_PRODUCT_QUERY,
|
|
24
24
|
BUNDLE_METAOBJECT_QUERY: () => import_core18.BUNDLE_METAOBJECT_QUERY,
|
|
25
25
|
BogoBundle: () => BogoBundle,
|
|
26
|
+
BundleCountdown: () => BundleCountdown,
|
|
26
27
|
BundleParseError: () => import_core17.BundleParseError,
|
|
27
28
|
DEFAULT_OUT_OF_STOCK_BEHAVIOR: () => import_core18.DEFAULT_OUT_OF_STOCK_BEHAVIOR,
|
|
28
29
|
FixedBundle: () => FixedBundle,
|
|
@@ -75,7 +76,7 @@ __export(index_exports, {
|
|
|
75
76
|
module.exports = __toCommonJS(index_exports);
|
|
76
77
|
|
|
77
78
|
// src/components/FixedBundle.tsx
|
|
78
|
-
var
|
|
79
|
+
var import_react8 = require("react");
|
|
79
80
|
var import_core8 = require("@lime-bundles/core");
|
|
80
81
|
|
|
81
82
|
// src/hooks/useBundleData.ts
|
|
@@ -702,8 +703,48 @@ function VariantDropdown({
|
|
|
702
703
|
);
|
|
703
704
|
}
|
|
704
705
|
|
|
705
|
-
// src/components/
|
|
706
|
+
// src/components/BundleCountdown.tsx
|
|
707
|
+
var import_react7 = require("react");
|
|
706
708
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
709
|
+
function pad(n) {
|
|
710
|
+
return n < 10 ? "0" + n : String(n);
|
|
711
|
+
}
|
|
712
|
+
function formatRemaining(remaining) {
|
|
713
|
+
const days = Math.floor(remaining / 864e5);
|
|
714
|
+
const hours = Math.floor(remaining % 864e5 / 36e5);
|
|
715
|
+
const mins = Math.floor(remaining % 36e5 / 6e4);
|
|
716
|
+
const secs = Math.floor(remaining % 6e4 / 1e3);
|
|
717
|
+
return days > 0 ? days + "d " + pad(hours) + "h " + pad(mins) + "m " + pad(secs) + "s" : pad(hours) + "h " + pad(mins) + "m " + pad(secs) + "s";
|
|
718
|
+
}
|
|
719
|
+
function BundleCountdown({
|
|
720
|
+
endsAt,
|
|
721
|
+
widgetConfig,
|
|
722
|
+
label = "Limited time offer"
|
|
723
|
+
}) {
|
|
724
|
+
const enabled = !!endsAt && widgetConfig?.countdown?.showCountdown !== false;
|
|
725
|
+
const endTime = enabled ? new Date(endsAt).getTime() : NaN;
|
|
726
|
+
const [remaining, setRemaining] = (0, import_react7.useState)(null);
|
|
727
|
+
(0, import_react7.useEffect)(() => {
|
|
728
|
+
if (!enabled || isNaN(endTime)) {
|
|
729
|
+
setRemaining(null);
|
|
730
|
+
return;
|
|
731
|
+
}
|
|
732
|
+
const update = () => setRemaining(endTime - Date.now());
|
|
733
|
+
update();
|
|
734
|
+
const interval = setInterval(update, 1e3);
|
|
735
|
+
return () => clearInterval(interval);
|
|
736
|
+
}, [enabled, endTime]);
|
|
737
|
+
if (!enabled || isNaN(endTime) || remaining === null || remaining <= 0) {
|
|
738
|
+
return null;
|
|
739
|
+
}
|
|
740
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "lb-bundle-countdown", "data-countdown": true, children: [
|
|
741
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "lb-bundle-countdown__label", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: label }) }),
|
|
742
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "lb-bundle-countdown__timer", "data-countdown-timer": true, children: formatRemaining(remaining) })
|
|
743
|
+
] });
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
// src/components/FixedBundle.tsx
|
|
747
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
707
748
|
function FixedBundle(props) {
|
|
708
749
|
const {
|
|
709
750
|
shopDomain,
|
|
@@ -727,10 +768,10 @@ function FixedBundle(props) {
|
|
|
727
768
|
bundleType: "fixed",
|
|
728
769
|
enabled: analyticsEnabled !== false
|
|
729
770
|
});
|
|
730
|
-
const [addingToCart, setAddingToCart] = (0,
|
|
731
|
-
const [cartError, setCartError] = (0,
|
|
732
|
-
const [selectedVariants, setSelectedVariants] = (0,
|
|
733
|
-
const handleVariantChange = (0,
|
|
771
|
+
const [addingToCart, setAddingToCart] = (0, import_react8.useState)(false);
|
|
772
|
+
const [cartError, setCartError] = (0, import_react8.useState)(null);
|
|
773
|
+
const [selectedVariants, setSelectedVariants] = (0, import_react8.useState)({});
|
|
774
|
+
const handleVariantChange = (0, import_react8.useCallback)(
|
|
734
775
|
(productId, variant) => {
|
|
735
776
|
setSelectedVariants((prev) => {
|
|
736
777
|
if (prev[productId] === variant) return prev;
|
|
@@ -742,7 +783,7 @@ function FixedBundle(props) {
|
|
|
742
783
|
const bundle = result.status === "success" && result.bundle.bundleType === "fixed" ? result.bundle : null;
|
|
743
784
|
const setConfigVarsRef = useWidgetConfigVars(bundle?.widgetConfig);
|
|
744
785
|
const productsEdgeFadeRef = useEdgeFade();
|
|
745
|
-
(0,
|
|
786
|
+
(0, import_react8.useEffect)(() => {
|
|
746
787
|
if (result.status === "error") {
|
|
747
788
|
onError?.(result.error);
|
|
748
789
|
return;
|
|
@@ -755,7 +796,7 @@ function FixedBundle(props) {
|
|
|
755
796
|
);
|
|
756
797
|
}
|
|
757
798
|
}, [result, onError]);
|
|
758
|
-
const oosProductIds = (0,
|
|
799
|
+
const oosProductIds = (0, import_react8.useMemo)(() => {
|
|
759
800
|
if (!bundle) return /* @__PURE__ */ new Set();
|
|
760
801
|
return new Set(
|
|
761
802
|
bundle.products.filter(
|
|
@@ -765,7 +806,7 @@ function FixedBundle(props) {
|
|
|
765
806
|
).map((p) => p.id)
|
|
766
807
|
);
|
|
767
808
|
}, [bundle]);
|
|
768
|
-
const handleAddToCart = (0,
|
|
809
|
+
const handleAddToCart = (0, import_react8.useCallback)(async () => {
|
|
769
810
|
if (!bundle) return;
|
|
770
811
|
const bundleLines = bundle.products.filter(
|
|
771
812
|
(p) => p.variants.nodes.some(
|
|
@@ -820,9 +861,9 @@ function FixedBundle(props) {
|
|
|
820
861
|
}
|
|
821
862
|
}, [bundle, onAddToCart, onError, trackAddToCart, selectedVariants]);
|
|
822
863
|
if (result.status === "loading") {
|
|
823
|
-
return /* @__PURE__ */ (0,
|
|
824
|
-
/* @__PURE__ */ (0,
|
|
825
|
-
/* @__PURE__ */ (0,
|
|
864
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: `lb-bundle lb-bundle--loading ${className ?? ""}`, children: [
|
|
865
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "lb-skeleton lb-skeleton--title" }),
|
|
866
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "lb-skeleton lb-skeleton--products" })
|
|
826
867
|
] });
|
|
827
868
|
}
|
|
828
869
|
if (result.status === "error") return null;
|
|
@@ -849,7 +890,7 @@ function FixedBundle(props) {
|
|
|
849
890
|
const savingsPercent = comparePrice > 0 && savings > 0 ? Math.round(savings / comparePrice * 100) : 0;
|
|
850
891
|
const showCompare = bundle.widgetConfig.pricing.showComparePrice && savings > 0;
|
|
851
892
|
const showSavings = bundle.widgetConfig.savingsBar.visible && savings > 0;
|
|
852
|
-
return /* @__PURE__ */ (0,
|
|
893
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
853
894
|
"div",
|
|
854
895
|
{
|
|
855
896
|
ref: (el) => {
|
|
@@ -860,11 +901,18 @@ function FixedBundle(props) {
|
|
|
860
901
|
role: "region",
|
|
861
902
|
"aria-label": bundle.title,
|
|
862
903
|
children: [
|
|
863
|
-
/* @__PURE__ */ (0,
|
|
864
|
-
/* @__PURE__ */ (0,
|
|
865
|
-
bundle.description && /* @__PURE__ */ (0,
|
|
904
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "lb-bundle-header", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "lb-bundle-header__content", children: [
|
|
905
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { className: "lb-bundle-title", children: bundle.title }),
|
|
906
|
+
bundle.description && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "lb-bundle-subtitle", children: bundle.description })
|
|
866
907
|
] }) }),
|
|
867
|
-
/* @__PURE__ */ (0,
|
|
908
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
909
|
+
BundleCountdown,
|
|
910
|
+
{
|
|
911
|
+
endsAt: bundle.endsAt,
|
|
912
|
+
widgetConfig: bundle.widgetConfig
|
|
913
|
+
}
|
|
914
|
+
),
|
|
915
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "lb-bundle__products lb-edge-fade", ref: productsEdgeFadeRef, children: bundle.products.map((product) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
868
916
|
FixedProductRow,
|
|
869
917
|
{
|
|
870
918
|
bundle,
|
|
@@ -875,29 +923,29 @@ function FixedBundle(props) {
|
|
|
875
923
|
},
|
|
876
924
|
product.id
|
|
877
925
|
)) }),
|
|
878
|
-
/* @__PURE__ */ (0,
|
|
879
|
-
/* @__PURE__ */ (0,
|
|
880
|
-
/* @__PURE__ */ (0,
|
|
881
|
-
/* @__PURE__ */ (0,
|
|
882
|
-
showSavings && /* @__PURE__ */ (0,
|
|
926
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "lb-bundle-divider" }),
|
|
927
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "lb-bundle-summary", children: [
|
|
928
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "lb-bundle-summary__text", children: [
|
|
929
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "lb-bundle-summary__label", children: "Bundle total" }),
|
|
930
|
+
showSavings && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("p", { className: "lb-bundle-savings-line", "data-savings-bar": true, children: [
|
|
883
931
|
"You save",
|
|
884
932
|
" ",
|
|
885
|
-
/* @__PURE__ */ (0,
|
|
933
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { "data-savings-amount": true, children: (0, import_core8.formatMoney)(savings, currency) }),
|
|
886
934
|
" ",
|
|
887
|
-
/* @__PURE__ */ (0,
|
|
935
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { "data-savings-percent": true, children: [
|
|
888
936
|
"(",
|
|
889
937
|
savingsPercent,
|
|
890
938
|
"%)"
|
|
891
939
|
] })
|
|
892
940
|
] })
|
|
893
941
|
] }),
|
|
894
|
-
/* @__PURE__ */ (0,
|
|
895
|
-
showCompare && /* @__PURE__ */ (0,
|
|
896
|
-
/* @__PURE__ */ (0,
|
|
942
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "lb-bundle-summary__prices", children: [
|
|
943
|
+
showCompare && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "lb-bundle-compare-price", "data-compare-price": true, children: (0, import_core8.formatMoney)(comparePrice, currency) }),
|
|
944
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "lb-bundle-sale-price", "data-sale-price": true, children: (0, import_core8.formatMoney)(salePrice, currency) })
|
|
897
945
|
] })
|
|
898
946
|
] }),
|
|
899
|
-
cartError && /* @__PURE__ */ (0,
|
|
900
|
-
/* @__PURE__ */ (0,
|
|
947
|
+
cartError && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "lb-bundle__error", role: "alert", children: cartError }),
|
|
948
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
901
949
|
"button",
|
|
902
950
|
{
|
|
903
951
|
className: "lb-bundle__cta",
|
|
@@ -913,7 +961,7 @@ function FixedBundle(props) {
|
|
|
913
961
|
}
|
|
914
962
|
function FixedProductRow({ bundle, product, currency, isOos, onVariantChange }) {
|
|
915
963
|
const variants = product.variants.nodes;
|
|
916
|
-
const optionNames = (0,
|
|
964
|
+
const optionNames = (0, import_react8.useMemo)(() => {
|
|
917
965
|
const first = variants[0];
|
|
918
966
|
return first ? first.selectedOptions.map((o) => o.name) : [];
|
|
919
967
|
}, [variants]);
|
|
@@ -922,7 +970,7 @@ function FixedProductRow({ bundle, product, currency, isOos, onVariantChange })
|
|
|
922
970
|
variants,
|
|
923
971
|
optionNames
|
|
924
972
|
});
|
|
925
|
-
(0,
|
|
973
|
+
(0, import_react8.useEffect)(() => {
|
|
926
974
|
onVariantChange(product.id, selectedVariant ?? null);
|
|
927
975
|
}, [selectedVariant, product.id, onVariantChange]);
|
|
928
976
|
const displayVariant = selectedVariant ?? variants.find(
|
|
@@ -943,15 +991,15 @@ function FixedProductRow({ bundle, product, currency, isOos, onVariantChange })
|
|
|
943
991
|
bundle.widgetConfig.lowStockThreshold,
|
|
944
992
|
bundle.widgetConfig.showLowStockBadge
|
|
945
993
|
);
|
|
946
|
-
return /* @__PURE__ */ (0,
|
|
994
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
947
995
|
"div",
|
|
948
996
|
{
|
|
949
997
|
className: isOos ? "lb-bundle-product-row lb-bundle-product-row--oos" : "lb-bundle-product-row",
|
|
950
998
|
"aria-disabled": isOos || void 0,
|
|
951
999
|
part: "product",
|
|
952
1000
|
children: [
|
|
953
|
-
isOos && /* @__PURE__ */ (0,
|
|
954
|
-
thumbImage && /* @__PURE__ */ (0,
|
|
1001
|
+
isOos && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "lb-bundle-product-row__oos", children: "Out of stock" }),
|
|
1002
|
+
thumbImage && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
955
1003
|
"img",
|
|
956
1004
|
{
|
|
957
1005
|
src: thumbImage.url,
|
|
@@ -960,11 +1008,11 @@ function FixedProductRow({ bundle, product, currency, isOos, onVariantChange })
|
|
|
960
1008
|
loading: "lazy"
|
|
961
1009
|
}
|
|
962
1010
|
),
|
|
963
|
-
/* @__PURE__ */ (0,
|
|
964
|
-
/* @__PURE__ */ (0,
|
|
965
|
-
!showPicker && displayVariant && variants.length > 1 && /* @__PURE__ */ (0,
|
|
966
|
-
/* @__PURE__ */ (0,
|
|
967
|
-
compareAt && /* @__PURE__ */ (0,
|
|
1011
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "lb-bundle__product-info", children: [
|
|
1012
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "lb-bundle__product-title", children: product.title }),
|
|
1013
|
+
!showPicker && displayVariant && variants.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "lb-bundle-variant-badge", children: displayVariant.title }),
|
|
1014
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "lb-bundle-product-prices", children: [
|
|
1015
|
+
compareAt && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
968
1016
|
"span",
|
|
969
1017
|
{
|
|
970
1018
|
className: "lb-bundle-product-compare-price",
|
|
@@ -972,9 +1020,9 @@ function FixedProductRow({ bundle, product, currency, isOos, onVariantChange })
|
|
|
972
1020
|
children: compareAt
|
|
973
1021
|
}
|
|
974
1022
|
),
|
|
975
|
-
/* @__PURE__ */ (0,
|
|
1023
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "lb-bundle__product-price", "data-product-price": true, children: priceText })
|
|
976
1024
|
] }),
|
|
977
|
-
unitPriceText && /* @__PURE__ */ (0,
|
|
1025
|
+
unitPriceText && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
978
1026
|
"span",
|
|
979
1027
|
{
|
|
980
1028
|
className: "lb-bundle__product-unit-price",
|
|
@@ -982,18 +1030,18 @@ function FixedProductRow({ bundle, product, currency, isOos, onVariantChange })
|
|
|
982
1030
|
children: unitPriceText
|
|
983
1031
|
}
|
|
984
1032
|
),
|
|
985
|
-
showLowStock && /* @__PURE__ */ (0,
|
|
1033
|
+
showLowStock && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "lb-bundle-low-stock-badge", children: [
|
|
986
1034
|
"Only ",
|
|
987
1035
|
displayVariant.quantityAvailable,
|
|
988
1036
|
" left"
|
|
989
1037
|
] }),
|
|
990
|
-
showPicker && /* @__PURE__ */ (0,
|
|
1038
|
+
showPicker && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "lb-bundle__product-variant-pickers", children: optionNames.map((optionName, optionIndex) => {
|
|
991
1039
|
const dropdownOptions = optionsFor(optionIndex).map((o) => ({
|
|
992
1040
|
value: o.value,
|
|
993
1041
|
label: o.value,
|
|
994
1042
|
disabled: o.disabled
|
|
995
1043
|
}));
|
|
996
|
-
return /* @__PURE__ */ (0,
|
|
1044
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
997
1045
|
VariantDropdown,
|
|
998
1046
|
{
|
|
999
1047
|
options: dropdownOptions,
|
|
@@ -1005,7 +1053,7 @@ function FixedProductRow({ bundle, product, currency, isOos, onVariantChange })
|
|
|
1005
1053
|
);
|
|
1006
1054
|
}) })
|
|
1007
1055
|
] }),
|
|
1008
|
-
displayVariant && /* @__PURE__ */ (0,
|
|
1056
|
+
displayVariant && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "lb-bundle-qty-chip", "data-qty-inline": true, children: [
|
|
1009
1057
|
"\xD7",
|
|
1010
1058
|
displayQty
|
|
1011
1059
|
] })
|
|
@@ -1015,16 +1063,16 @@ function FixedProductRow({ bundle, product, currency, isOos, onVariantChange })
|
|
|
1015
1063
|
}
|
|
1016
1064
|
|
|
1017
1065
|
// src/components/MixMatchBundle.tsx
|
|
1018
|
-
var
|
|
1066
|
+
var import_react13 = require("react");
|
|
1019
1067
|
var import_core11 = require("@lime-bundles/core");
|
|
1020
1068
|
|
|
1021
1069
|
// src/hooks/useShopSettings.ts
|
|
1022
|
-
var
|
|
1070
|
+
var import_react9 = require("react");
|
|
1023
1071
|
var import_core9 = require("@lime-bundles/core");
|
|
1024
1072
|
function useShopSettings(options) {
|
|
1025
|
-
const [outOfStockBehavior, setOutOfStockBehavior] = (0,
|
|
1073
|
+
const [outOfStockBehavior, setOutOfStockBehavior] = (0, import_react9.useState)(import_core9.DEFAULT_OUT_OF_STOCK_BEHAVIOR);
|
|
1026
1074
|
const { shopDomain, storefrontAccessToken } = options;
|
|
1027
|
-
(0,
|
|
1075
|
+
(0, import_react9.useEffect)(() => {
|
|
1028
1076
|
const controller = new AbortController();
|
|
1029
1077
|
let active = true;
|
|
1030
1078
|
fetchShopSettingsOrDefault({
|
|
@@ -1044,12 +1092,12 @@ function useShopSettings(options) {
|
|
|
1044
1092
|
}
|
|
1045
1093
|
|
|
1046
1094
|
// src/components/MixMatchPicker.tsx
|
|
1047
|
-
var
|
|
1095
|
+
var import_react12 = require("react");
|
|
1048
1096
|
var import_react_dom = require("react-dom");
|
|
1049
1097
|
var import_core10 = require("@lime-bundles/core");
|
|
1050
1098
|
|
|
1051
1099
|
// src/hooks/useScrollLock.ts
|
|
1052
|
-
var
|
|
1100
|
+
var import_react10 = require("react");
|
|
1053
1101
|
var lockCount = 0;
|
|
1054
1102
|
var savedY = 0;
|
|
1055
1103
|
function lock() {
|
|
@@ -1078,7 +1126,7 @@ function unlock() {
|
|
|
1078
1126
|
window.scrollTo(0, savedY);
|
|
1079
1127
|
}
|
|
1080
1128
|
function useScrollLock(active) {
|
|
1081
|
-
(0,
|
|
1129
|
+
(0, import_react10.useEffect)(() => {
|
|
1082
1130
|
if (!active) return;
|
|
1083
1131
|
lock();
|
|
1084
1132
|
return unlock;
|
|
@@ -1086,7 +1134,7 @@ function useScrollLock(active) {
|
|
|
1086
1134
|
}
|
|
1087
1135
|
|
|
1088
1136
|
// src/hooks/useFocusTrap.ts
|
|
1089
|
-
var
|
|
1137
|
+
var import_react11 = require("react");
|
|
1090
1138
|
var FOCUSABLE_SELECTOR = [
|
|
1091
1139
|
"a[href]",
|
|
1092
1140
|
"button:not([disabled])",
|
|
@@ -1111,8 +1159,8 @@ function useFocusTrap({
|
|
|
1111
1159
|
onEscape,
|
|
1112
1160
|
returnFocusRef
|
|
1113
1161
|
}) {
|
|
1114
|
-
const previouslyFocused = (0,
|
|
1115
|
-
(0,
|
|
1162
|
+
const previouslyFocused = (0, import_react11.useRef)(null);
|
|
1163
|
+
(0, import_react11.useEffect)(() => {
|
|
1116
1164
|
if (!active) return;
|
|
1117
1165
|
const container = containerRef.current;
|
|
1118
1166
|
previouslyFocused.current = document.activeElement ?? null;
|
|
@@ -1154,7 +1202,7 @@ function useFocusTrap({
|
|
|
1154
1202
|
}
|
|
1155
1203
|
|
|
1156
1204
|
// src/components/MixMatchPicker.tsx
|
|
1157
|
-
var
|
|
1205
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
1158
1206
|
function ruleFor(bundle, productId, variantId) {
|
|
1159
1207
|
if (variantId) {
|
|
1160
1208
|
const vRule = bundle.variantRules[variantId];
|
|
@@ -1210,17 +1258,17 @@ function MixMatchPicker({
|
|
|
1210
1258
|
styleVarsRef
|
|
1211
1259
|
}) {
|
|
1212
1260
|
const wc = bundle.widgetConfig;
|
|
1213
|
-
const overlayRef = (0,
|
|
1214
|
-
const dialogRef = (0,
|
|
1215
|
-
const mouseDownTarget = (0,
|
|
1216
|
-
const [open, setOpen] = (0,
|
|
1217
|
-
const [query, setQuery] = (0,
|
|
1218
|
-
const [activeType, setActiveType] = (0,
|
|
1219
|
-
const eligible = (0,
|
|
1261
|
+
const overlayRef = (0, import_react12.useRef)(null);
|
|
1262
|
+
const dialogRef = (0, import_react12.useRef)(null);
|
|
1263
|
+
const mouseDownTarget = (0, import_react12.useRef)(null);
|
|
1264
|
+
const [open, setOpen] = (0, import_react12.useState)(false);
|
|
1265
|
+
const [query, setQuery] = (0, import_react12.useState)("");
|
|
1266
|
+
const [activeType, setActiveType] = (0, import_react12.useState)(FILTERS_ALL);
|
|
1267
|
+
const eligible = (0, import_react12.useMemo)(
|
|
1220
1268
|
() => buildEligibleProducts(bundle, outOfStockBehavior),
|
|
1221
1269
|
[bundle, outOfStockBehavior]
|
|
1222
1270
|
);
|
|
1223
|
-
const productTypes = (0,
|
|
1271
|
+
const productTypes = (0, import_react12.useMemo)(() => {
|
|
1224
1272
|
const types = [];
|
|
1225
1273
|
const seen = /* @__PURE__ */ new Set();
|
|
1226
1274
|
for (const ep of eligible) {
|
|
@@ -1236,7 +1284,7 @@ function MixMatchPicker({
|
|
|
1236
1284
|
const totalUnits = selections.reduce((sum, s) => sum + s.quantity, 0);
|
|
1237
1285
|
const atCapacity = totalUnits >= requiredQty;
|
|
1238
1286
|
const shownUnits = Math.min(totalUnits, requiredQty);
|
|
1239
|
-
(0,
|
|
1287
|
+
(0, import_react12.useEffect)(() => {
|
|
1240
1288
|
const id = requestAnimationFrame(() => setOpen(true));
|
|
1241
1289
|
return () => cancelAnimationFrame(id);
|
|
1242
1290
|
}, []);
|
|
@@ -1252,7 +1300,7 @@ function MixMatchPicker({
|
|
|
1252
1300
|
const pct = bundle.discountConfig.discountType === "percentage" && bundle.discountConfig.discountValue ? Math.round(bundle.discountConfig.discountValue) : 0;
|
|
1253
1301
|
return pct > 0 ? `Choose ${remaining} more to unlock ${pct}% off` : `Choose ${remaining} more to complete your bundle`;
|
|
1254
1302
|
})();
|
|
1255
|
-
const filtered = (0,
|
|
1303
|
+
const filtered = (0, import_react12.useMemo)(() => {
|
|
1256
1304
|
const nq = normalizeText(query.trim());
|
|
1257
1305
|
return eligible.filter((ep) => {
|
|
1258
1306
|
const matchesQuery = !nq || normalizeText(ep.product.title).includes(nq);
|
|
@@ -1277,7 +1325,7 @@ function MixMatchPicker({
|
|
|
1277
1325
|
// inside carries the interactive role + focus trap. So the static-element
|
|
1278
1326
|
// interaction lint does not apply to this backdrop.
|
|
1279
1327
|
// eslint-disable-next-line jsx-a11y/no-static-element-interactions
|
|
1280
|
-
/* @__PURE__ */ (0,
|
|
1328
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1281
1329
|
"div",
|
|
1282
1330
|
{
|
|
1283
1331
|
ref: (el) => {
|
|
@@ -1289,7 +1337,7 @@ function MixMatchPicker({
|
|
|
1289
1337
|
"data-bundle-gid": bundle.id,
|
|
1290
1338
|
onMouseDown: onOverlayMouseDown,
|
|
1291
1339
|
onMouseUp: onOverlayMouseUp,
|
|
1292
|
-
children: /* @__PURE__ */ (0,
|
|
1340
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
1293
1341
|
"div",
|
|
1294
1342
|
{
|
|
1295
1343
|
ref: dialogRef,
|
|
@@ -1299,13 +1347,13 @@ function MixMatchPicker({
|
|
|
1299
1347
|
"aria-labelledby": titleId,
|
|
1300
1348
|
tabIndex: -1,
|
|
1301
1349
|
children: [
|
|
1302
|
-
/* @__PURE__ */ (0,
|
|
1303
|
-
/* @__PURE__ */ (0,
|
|
1304
|
-
/* @__PURE__ */ (0,
|
|
1305
|
-
/* @__PURE__ */ (0,
|
|
1306
|
-
/* @__PURE__ */ (0,
|
|
1350
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "lb-mix-match__modal-header", children: [
|
|
1351
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "lb-mix-match__modal-header-top", children: [
|
|
1352
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "lb-mix-match__modal-heading", children: [
|
|
1353
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h4", { className: "lb-mix-match__modal-title", id: titleId, children: "Add to your bundle" }),
|
|
1354
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "lb-mix-match__modal-subtitle", "data-modal-subtitle": true, children: subtitle })
|
|
1307
1355
|
] }),
|
|
1308
|
-
/* @__PURE__ */ (0,
|
|
1356
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1309
1357
|
"button",
|
|
1310
1358
|
{
|
|
1311
1359
|
type: "button",
|
|
@@ -1313,16 +1361,16 @@ function MixMatchPicker({
|
|
|
1313
1361
|
"data-modal-close": true,
|
|
1314
1362
|
"aria-label": "Close",
|
|
1315
1363
|
onClick: onClose,
|
|
1316
|
-
children: /* @__PURE__ */ (0,
|
|
1364
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CloseIcon, {})
|
|
1317
1365
|
}
|
|
1318
1366
|
)
|
|
1319
1367
|
] }),
|
|
1320
|
-
/* @__PURE__ */ (0,
|
|
1368
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1321
1369
|
"div",
|
|
1322
1370
|
{
|
|
1323
1371
|
className: "lb-mix-match__progress lb-mix-match__modal-progress",
|
|
1324
1372
|
"data-progress": true,
|
|
1325
|
-
children: /* @__PURE__ */ (0,
|
|
1373
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1326
1374
|
"div",
|
|
1327
1375
|
{
|
|
1328
1376
|
className: "lb-mix-match__progress-segments",
|
|
@@ -1330,7 +1378,7 @@ function MixMatchPicker({
|
|
|
1330
1378
|
"aria-valuenow": shownUnits,
|
|
1331
1379
|
"aria-valuemin": 0,
|
|
1332
1380
|
"aria-valuemax": requiredQty,
|
|
1333
|
-
children: Array.from({ length: requiredQty }).map((_, i) => /* @__PURE__ */ (0,
|
|
1381
|
+
children: Array.from({ length: requiredQty }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1334
1382
|
"span",
|
|
1335
1383
|
{
|
|
1336
1384
|
className: `lb-mix-match__progress-segment${i < shownUnits ? " lb-mix-match__progress-segment--filled" : ""}`,
|
|
@@ -1343,8 +1391,8 @@ function MixMatchPicker({
|
|
|
1343
1391
|
}
|
|
1344
1392
|
)
|
|
1345
1393
|
] }),
|
|
1346
|
-
wc.showSearch && /* @__PURE__ */ (0,
|
|
1347
|
-
/* @__PURE__ */ (0,
|
|
1394
|
+
wc.showSearch && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "lb-mix-match__modal-search", children: [
|
|
1395
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1348
1396
|
"input",
|
|
1349
1397
|
{
|
|
1350
1398
|
type: "text",
|
|
@@ -1358,7 +1406,7 @@ function MixMatchPicker({
|
|
|
1358
1406
|
onChange: (e) => setQuery(e.target.value)
|
|
1359
1407
|
}
|
|
1360
1408
|
),
|
|
1361
|
-
query.length > 0 && /* @__PURE__ */ (0,
|
|
1409
|
+
query.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1362
1410
|
"button",
|
|
1363
1411
|
{
|
|
1364
1412
|
type: "button",
|
|
@@ -1366,11 +1414,11 @@ function MixMatchPicker({
|
|
|
1366
1414
|
"data-modal-search-clear": true,
|
|
1367
1415
|
"aria-label": "Clear search",
|
|
1368
1416
|
onClick: () => setQuery(""),
|
|
1369
|
-
children: /* @__PURE__ */ (0,
|
|
1417
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(SearchClearIcon, {})
|
|
1370
1418
|
}
|
|
1371
1419
|
)
|
|
1372
1420
|
] }),
|
|
1373
|
-
showFilters && /* @__PURE__ */ (0,
|
|
1421
|
+
showFilters && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1374
1422
|
"div",
|
|
1375
1423
|
{
|
|
1376
1424
|
className: "lb-mix-match__filters",
|
|
@@ -1379,7 +1427,7 @@ function MixMatchPicker({
|
|
|
1379
1427
|
"aria-label": "Filter by product type",
|
|
1380
1428
|
children: [FILTERS_ALL, ...productTypes].map((value) => {
|
|
1381
1429
|
const isActive = value === activeType;
|
|
1382
|
-
return /* @__PURE__ */ (0,
|
|
1430
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1383
1431
|
"button",
|
|
1384
1432
|
{
|
|
1385
1433
|
type: "button",
|
|
@@ -1394,7 +1442,7 @@ function MixMatchPicker({
|
|
|
1394
1442
|
})
|
|
1395
1443
|
}
|
|
1396
1444
|
),
|
|
1397
|
-
/* @__PURE__ */ (0,
|
|
1445
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "lb-mix-match__modal-list", "data-modal-list": true, children: filtered.map((ep) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1398
1446
|
MixMatchPickerRow,
|
|
1399
1447
|
{
|
|
1400
1448
|
bundle,
|
|
@@ -1413,10 +1461,10 @@ function MixMatchPicker({
|
|
|
1413
1461
|
},
|
|
1414
1462
|
ep.product.id
|
|
1415
1463
|
)) }),
|
|
1416
|
-
showEmpty && /* @__PURE__ */ (0,
|
|
1417
|
-
/* @__PURE__ */ (0,
|
|
1418
|
-
/* @__PURE__ */ (0,
|
|
1419
|
-
/* @__PURE__ */ (0,
|
|
1464
|
+
showEmpty && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "lb-mix-match__modal-empty", "data-modal-empty": true, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { children: "No products match your search" }) }),
|
|
1465
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { "data-modal-live": true, "aria-live": "polite", className: "lb-visually-hidden", children: `${filtered.length} products shown` }),
|
|
1466
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "lb-mix-match__modal-footer", children: [
|
|
1467
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1420
1468
|
"span",
|
|
1421
1469
|
{
|
|
1422
1470
|
className: "lb-mix-match__modal-footer-count",
|
|
@@ -1425,7 +1473,7 @@ function MixMatchPicker({
|
|
|
1425
1473
|
children: `${shownUnits} of ${requiredQty} added`
|
|
1426
1474
|
}
|
|
1427
1475
|
),
|
|
1428
|
-
/* @__PURE__ */ (0,
|
|
1476
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1429
1477
|
"button",
|
|
1430
1478
|
{
|
|
1431
1479
|
type: "button",
|
|
@@ -1462,7 +1510,7 @@ function MixMatchPickerRow({
|
|
|
1462
1510
|
}) {
|
|
1463
1511
|
const { product, variants, isOos } = eligible;
|
|
1464
1512
|
const rule = ruleFor(bundle, product.id);
|
|
1465
|
-
const optionNames = (0,
|
|
1513
|
+
const optionNames = (0, import_react12.useMemo)(() => {
|
|
1466
1514
|
const first = variants[0];
|
|
1467
1515
|
return first ? first.selectedOptions.map((o) => o.name) : [];
|
|
1468
1516
|
}, [variants]);
|
|
@@ -1471,7 +1519,7 @@ function MixMatchPickerRow({
|
|
|
1471
1519
|
const currentVariant = selectedVariant ?? variants.find((v) => (0, import_core10.isVariantFulfillable)(v, rule.min)) ?? eligible.firstAvailableVariant ?? variants[0] ?? null;
|
|
1472
1520
|
const vRule = ruleFor(bundle, product.id, currentVariant?.id);
|
|
1473
1521
|
const variantMax = variantRuleFor(bundle, currentVariant?.id)?.max;
|
|
1474
|
-
const alreadyInBundle = (0,
|
|
1522
|
+
const alreadyInBundle = (0, import_react12.useMemo)(() => {
|
|
1475
1523
|
if (!currentVariant) return 0;
|
|
1476
1524
|
let sum = 0;
|
|
1477
1525
|
for (const s of selections) {
|
|
@@ -1481,13 +1529,13 @@ function MixMatchPickerRow({
|
|
|
1481
1529
|
}
|
|
1482
1530
|
return sum;
|
|
1483
1531
|
}, [selections, product.id, currentVariant]);
|
|
1484
|
-
const committedSelection = (0,
|
|
1532
|
+
const committedSelection = (0, import_react12.useMemo)(
|
|
1485
1533
|
() => currentVariant ? selections.find((s) => s.variantId === currentVariant.id) ?? null : null,
|
|
1486
1534
|
[selections, currentVariant]
|
|
1487
1535
|
);
|
|
1488
1536
|
const variantInBundle = committedSelection !== null;
|
|
1489
1537
|
const committedQty = committedSelection?.quantity ?? 0;
|
|
1490
|
-
const productOtherUnits = (0,
|
|
1538
|
+
const productOtherUnits = (0, import_react12.useMemo)(() => {
|
|
1491
1539
|
if (!currentVariant) return 0;
|
|
1492
1540
|
let sum = 0;
|
|
1493
1541
|
for (const s of selections) {
|
|
@@ -1510,12 +1558,12 @@ function MixMatchPickerRow({
|
|
|
1510
1558
|
Math.max(0, alreadyInBundle - committedQty)
|
|
1511
1559
|
) : 0;
|
|
1512
1560
|
const stepperMax = Math.max(vRule.min, cap);
|
|
1513
|
-
const [qty, setQty] = (0,
|
|
1514
|
-
(0,
|
|
1561
|
+
const [qty, setQty] = (0, import_react12.useState)(vRule.min);
|
|
1562
|
+
(0, import_react12.useEffect)(() => {
|
|
1515
1563
|
setQty((prev) => Math.max(vRule.min, Math.min(prev, stepperMax)));
|
|
1516
1564
|
}, [stepperMax, vRule.min]);
|
|
1517
1565
|
const currentVariantId = currentVariant?.id ?? null;
|
|
1518
|
-
(0,
|
|
1566
|
+
(0, import_react12.useEffect)(() => {
|
|
1519
1567
|
if (!variantInBundle) setQty(vRule.min);
|
|
1520
1568
|
}, [variantInBundle, currentVariantId, vRule.min]);
|
|
1521
1569
|
if (!currentVariant) return null;
|
|
@@ -1559,7 +1607,7 @@ function MixMatchPickerRow({
|
|
|
1559
1607
|
}
|
|
1560
1608
|
const priceCents = parseFloat(currentVariant.price.amount);
|
|
1561
1609
|
const compareCents = currentVariant.compareAtPrice ? parseFloat(currentVariant.compareAtPrice.amount) : null;
|
|
1562
|
-
return /* @__PURE__ */ (0,
|
|
1610
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
1563
1611
|
"div",
|
|
1564
1612
|
{
|
|
1565
1613
|
className: `lb-mix-match__modal-product${isOos ? " lb-mix-match__modal-product--sold-out" : ""}${variantInBundle ? " lb-mix-match__modal-product--in-bundle" : ""}`,
|
|
@@ -1568,8 +1616,8 @@ function MixMatchPickerRow({
|
|
|
1568
1616
|
"data-type": product.productType ?? "",
|
|
1569
1617
|
"aria-disabled": isOos || void 0,
|
|
1570
1618
|
children: [
|
|
1571
|
-
/* @__PURE__ */ (0,
|
|
1572
|
-
thumbImage && /* @__PURE__ */ (0,
|
|
1619
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "lb-mix-match__modal-product-thumb", children: [
|
|
1620
|
+
thumbImage && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1573
1621
|
"img",
|
|
1574
1622
|
{
|
|
1575
1623
|
src: thumbImage.url,
|
|
@@ -1577,10 +1625,10 @@ function MixMatchPickerRow({
|
|
|
1577
1625
|
loading: "lazy"
|
|
1578
1626
|
}
|
|
1579
1627
|
),
|
|
1580
|
-
variantInBundle && /* @__PURE__ */ (0,
|
|
1628
|
+
variantInBundle && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "lb-mix-match__modal-added-badge", children: "Added" })
|
|
1581
1629
|
] }),
|
|
1582
|
-
/* @__PURE__ */ (0,
|
|
1583
|
-
/* @__PURE__ */ (0,
|
|
1630
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "lb-mix-match__modal-product-info", children: [
|
|
1631
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "lb-mix-match__modal-product-title", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1584
1632
|
"a",
|
|
1585
1633
|
{
|
|
1586
1634
|
href: `/products/${product.handle}`,
|
|
@@ -1589,24 +1637,24 @@ function MixMatchPickerRow({
|
|
|
1589
1637
|
children: product.title
|
|
1590
1638
|
}
|
|
1591
1639
|
) }),
|
|
1592
|
-
/* @__PURE__ */ (0,
|
|
1593
|
-
/* @__PURE__ */ (0,
|
|
1594
|
-
compareCents !== null && compareCents > priceCents && /* @__PURE__ */ (0,
|
|
1640
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "lb-mix-match__modal-product-price", children: [
|
|
1641
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { "data-row-price-sale": true, children: (0, import_core10.formatMoney)(priceCents, currency) }),
|
|
1642
|
+
compareCents !== null && compareCents > priceCents && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("s", { className: "lb-mix-match__modal-product-compare", "data-row-compare": true, children: (0, import_core10.formatMoney)(compareCents, currency) })
|
|
1595
1643
|
] }),
|
|
1596
|
-
unitPriceText && /* @__PURE__ */ (0,
|
|
1597
|
-
showPicker && /* @__PURE__ */ (0,
|
|
1644
|
+
unitPriceText && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "lb-mix-match__modal-product-unit-price lb-bundle-product-unit-price", children: unitPriceText }),
|
|
1645
|
+
showPicker && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "lb-bundle-variant-option-groups", children: optionNames.map((optionName, optionIndex) => {
|
|
1598
1646
|
const dropdownOptions = optionsFor(optionIndex).map((o) => ({
|
|
1599
1647
|
value: o.value,
|
|
1600
1648
|
label: o.value,
|
|
1601
1649
|
disabled: o.disabled
|
|
1602
1650
|
}));
|
|
1603
|
-
return /* @__PURE__ */ (0,
|
|
1651
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
1604
1652
|
"div",
|
|
1605
1653
|
{
|
|
1606
1654
|
className: "lb-bundle-variant-option-group",
|
|
1607
1655
|
children: [
|
|
1608
|
-
/* @__PURE__ */ (0,
|
|
1609
|
-
/* @__PURE__ */ (0,
|
|
1656
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "lb-bundle-variant-option-label", children: optionName }),
|
|
1657
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1610
1658
|
VariantDropdown,
|
|
1611
1659
|
{
|
|
1612
1660
|
className: "lb-mix-match__variant-select-dropdown",
|
|
@@ -1621,17 +1669,17 @@ function MixMatchPickerRow({
|
|
|
1621
1669
|
optionName
|
|
1622
1670
|
);
|
|
1623
1671
|
}) }),
|
|
1624
|
-
!showPicker && variants.length === 1 && currentVariant.title !== "Default Title" && /* @__PURE__ */ (0,
|
|
1625
|
-
!isOos && needsMoreSpots && remainingUnits > 0 && /* @__PURE__ */ (0,
|
|
1626
|
-
isOos ? /* @__PURE__ */ (0,
|
|
1627
|
-
showStepper && /* @__PURE__ */ (0,
|
|
1672
|
+
!showPicker && variants.length === 1 && currentVariant.title !== "Default Title" && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "lb-mix-match__filled-variant", children: currentVariant.title }),
|
|
1673
|
+
!isOos && needsMoreSpots && remainingUnits > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "lb-mix-match__modal-needs-spots", children: rule.min === 1 ? "Needs 1 spot" : `Needs ${rule.min} spots` }),
|
|
1674
|
+
isOos ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "lb-mix-match__modal-sold-out-label", children: "Sold out" }) : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "lb-mix-match__modal-product-actions", children: [
|
|
1675
|
+
showStepper && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "lb-bundle-variant-option-group lb-mix-match__qty-stepper-group", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
1628
1676
|
"div",
|
|
1629
1677
|
{
|
|
1630
1678
|
className: "lb-mix-match__qty-stepper",
|
|
1631
1679
|
role: "group",
|
|
1632
1680
|
"aria-label": "Quantity",
|
|
1633
1681
|
children: [
|
|
1634
|
-
/* @__PURE__ */ (0,
|
|
1682
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1635
1683
|
"button",
|
|
1636
1684
|
{
|
|
1637
1685
|
type: "button",
|
|
@@ -1652,7 +1700,7 @@ function MixMatchPickerRow({
|
|
|
1652
1700
|
children: "\u2212"
|
|
1653
1701
|
}
|
|
1654
1702
|
),
|
|
1655
|
-
/* @__PURE__ */ (0,
|
|
1703
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1656
1704
|
"span",
|
|
1657
1705
|
{
|
|
1658
1706
|
className: "lb-mix-match__qty-stepper-value",
|
|
@@ -1661,7 +1709,7 @@ function MixMatchPickerRow({
|
|
|
1661
1709
|
children: shownQty
|
|
1662
1710
|
}
|
|
1663
1711
|
),
|
|
1664
|
-
/* @__PURE__ */ (0,
|
|
1712
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1665
1713
|
"button",
|
|
1666
1714
|
{
|
|
1667
1715
|
type: "button",
|
|
@@ -1685,7 +1733,7 @@ function MixMatchPickerRow({
|
|
|
1685
1733
|
]
|
|
1686
1734
|
}
|
|
1687
1735
|
) }),
|
|
1688
|
-
/* @__PURE__ */ (0,
|
|
1736
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1689
1737
|
"button",
|
|
1690
1738
|
{
|
|
1691
1739
|
type: "button",
|
|
@@ -1704,7 +1752,7 @@ function MixMatchPickerRow({
|
|
|
1704
1752
|
);
|
|
1705
1753
|
}
|
|
1706
1754
|
function CloseIcon() {
|
|
1707
|
-
return /* @__PURE__ */ (0,
|
|
1755
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
1708
1756
|
"svg",
|
|
1709
1757
|
{
|
|
1710
1758
|
width: "20",
|
|
@@ -1714,14 +1762,14 @@ function CloseIcon() {
|
|
|
1714
1762
|
xmlns: "http://www.w3.org/2000/svg",
|
|
1715
1763
|
"aria-hidden": "true",
|
|
1716
1764
|
children: [
|
|
1717
|
-
/* @__PURE__ */ (0,
|
|
1718
|
-
/* @__PURE__ */ (0,
|
|
1765
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("line", { x1: "5", y1: "5", x2: "15", y2: "15", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }),
|
|
1766
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("line", { x1: "15", y1: "5", x2: "5", y2: "15", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" })
|
|
1719
1767
|
]
|
|
1720
1768
|
}
|
|
1721
1769
|
);
|
|
1722
1770
|
}
|
|
1723
1771
|
function SearchClearIcon() {
|
|
1724
|
-
return /* @__PURE__ */ (0,
|
|
1772
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1725
1773
|
"svg",
|
|
1726
1774
|
{
|
|
1727
1775
|
width: "16",
|
|
@@ -1730,13 +1778,13 @@ function SearchClearIcon() {
|
|
|
1730
1778
|
fill: "currentColor",
|
|
1731
1779
|
xmlns: "http://www.w3.org/2000/svg",
|
|
1732
1780
|
"aria-hidden": "true",
|
|
1733
|
-
children: /* @__PURE__ */ (0,
|
|
1781
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M14.348 5.652a.5.5 0 0 0-.707 0L10 9.293 6.36 5.652a.5.5 0 1 0-.708.707L9.293 10l-3.641 3.641a.5.5 0 0 0 .708.707L10 10.707l3.641 3.641a.5.5 0 0 0 .707-.707L10.707 10l3.641-3.641a.5.5 0 0 0 0-.707z" })
|
|
1734
1782
|
}
|
|
1735
1783
|
);
|
|
1736
1784
|
}
|
|
1737
1785
|
|
|
1738
1786
|
// src/components/MixMatchBundle.tsx
|
|
1739
|
-
var
|
|
1787
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
1740
1788
|
function ruleFor2(bundle, productId, variantId) {
|
|
1741
1789
|
if (variantId) {
|
|
1742
1790
|
const vRule = bundle.variantRules[variantId];
|
|
@@ -1769,7 +1817,8 @@ function MixMatchBundle(props) {
|
|
|
1769
1817
|
analyticsEnabled,
|
|
1770
1818
|
onAddToCart,
|
|
1771
1819
|
onError,
|
|
1772
|
-
className
|
|
1820
|
+
className,
|
|
1821
|
+
productHandle
|
|
1773
1822
|
} = props;
|
|
1774
1823
|
const result = useBundleData({
|
|
1775
1824
|
shopDomain,
|
|
@@ -1787,16 +1836,16 @@ function MixMatchBundle(props) {
|
|
|
1787
1836
|
bundleType: "mix_match",
|
|
1788
1837
|
enabled: analyticsEnabled !== false
|
|
1789
1838
|
});
|
|
1790
|
-
const [selections, setSelections] = (0,
|
|
1791
|
-
const [seededFor, setSeededFor] = (0,
|
|
1792
|
-
const [pickerOpen, setPickerOpen] = (0,
|
|
1793
|
-
const [addingToCart, setAddingToCart] = (0,
|
|
1794
|
-
const [cartError, setCartError] = (0,
|
|
1839
|
+
const [selections, setSelections] = (0, import_react13.useState)([]);
|
|
1840
|
+
const [seededFor, setSeededFor] = (0, import_react13.useState)(null);
|
|
1841
|
+
const [pickerOpen, setPickerOpen] = (0, import_react13.useState)(false);
|
|
1842
|
+
const [addingToCart, setAddingToCart] = (0, import_react13.useState)(false);
|
|
1843
|
+
const [cartError, setCartError] = (0, import_react13.useState)(null);
|
|
1795
1844
|
const bundle = result.status === "success" && result.bundle.bundleType === "mix_match" ? result.bundle : null;
|
|
1796
1845
|
const setConfigVarsRef = useWidgetConfigVars(bundle?.widgetConfig);
|
|
1797
1846
|
const setModalConfigVarsRef = useWidgetConfigVars(bundle?.widgetConfig);
|
|
1798
1847
|
const slotsEdgeFadeRef = useEdgeFade();
|
|
1799
|
-
(0,
|
|
1848
|
+
(0, import_react13.useEffect)(() => {
|
|
1800
1849
|
if (result.status === "error") {
|
|
1801
1850
|
onError?.(result.error);
|
|
1802
1851
|
return;
|
|
@@ -1809,40 +1858,67 @@ function MixMatchBundle(props) {
|
|
|
1809
1858
|
);
|
|
1810
1859
|
}
|
|
1811
1860
|
}, [result, onError]);
|
|
1812
|
-
(0,
|
|
1861
|
+
(0, import_react13.useEffect)(() => {
|
|
1813
1862
|
if (!bundle || seededFor === bundle.id) return;
|
|
1814
1863
|
setSeededFor(bundle.id);
|
|
1815
1864
|
const seedCurrency = bundle.products[0]?.priceRange.minVariantPrice.currencyCode ?? "USD";
|
|
1865
|
+
const pick = (product, variant, quantity) => ({
|
|
1866
|
+
productId: product.id,
|
|
1867
|
+
variantId: variant.id,
|
|
1868
|
+
title: product.title,
|
|
1869
|
+
url: `/products/${product.handle}`,
|
|
1870
|
+
variantTitle: variant.title,
|
|
1871
|
+
featuredImage: variant.image?.url ?? product.featuredImage?.url ?? null,
|
|
1872
|
+
price: parseFloat(variant.price.amount),
|
|
1873
|
+
compareAtPrice: variant.compareAtPrice ? parseFloat(variant.compareAtPrice.amount) : null,
|
|
1874
|
+
unitPrice: (0, import_core11.formatUnitPrice)(
|
|
1875
|
+
variant.unitPrice,
|
|
1876
|
+
variant.unitPriceMeasurement,
|
|
1877
|
+
seedCurrency
|
|
1878
|
+
),
|
|
1879
|
+
quantity
|
|
1880
|
+
});
|
|
1816
1881
|
const seeds = [];
|
|
1817
|
-
for (const
|
|
1818
|
-
|
|
1819
|
-
const
|
|
1820
|
-
|
|
1882
|
+
for (const product of bundle.products) {
|
|
1883
|
+
let seededVariant = false;
|
|
1884
|
+
for (const variant2 of product.variants.nodes) {
|
|
1885
|
+
const vRule = bundle.variantRules[variant2.id];
|
|
1886
|
+
if (!vRule?.required) continue;
|
|
1887
|
+
if (!(0, import_core11.isVariantFulfillable)(variant2, Math.max(1, vRule.min))) continue;
|
|
1888
|
+
seeds.push(pick(product, variant2, Math.max(1, vRule.min)));
|
|
1889
|
+
seededVariant = true;
|
|
1890
|
+
}
|
|
1891
|
+
if (seededVariant) continue;
|
|
1892
|
+
const rule = bundle.productRules[product.id];
|
|
1893
|
+
if (!rule?.required) continue;
|
|
1894
|
+
const variant = product.variants.nodes.find(
|
|
1821
1895
|
(v) => (0, import_core11.isVariantFulfillable)(v, rule.min)
|
|
1822
1896
|
);
|
|
1823
|
-
if (!
|
|
1824
|
-
seeds.push(
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
|
|
1832
|
-
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1897
|
+
if (!variant) continue;
|
|
1898
|
+
seeds.push(pick(product, variant, rule.min));
|
|
1899
|
+
}
|
|
1900
|
+
if (seeds.length === 0 && productHandle) {
|
|
1901
|
+
const requiredUnits2 = bundle.minQuantity ?? 0;
|
|
1902
|
+
const qualifies = (p) => {
|
|
1903
|
+
const min = bundle.productRules[p.id]?.min ?? 1;
|
|
1904
|
+
return min <= requiredUnits2 && p.variants.nodes.some((v) => (0, import_core11.isVariantFulfillable)(v, min));
|
|
1905
|
+
};
|
|
1906
|
+
const seed = bundle.products.find(
|
|
1907
|
+
(p) => p.handle === productHandle && qualifies(p)
|
|
1908
|
+
) ?? bundle.products.find(qualifies);
|
|
1909
|
+
if (seed) {
|
|
1910
|
+
const min = bundle.productRules[seed.id]?.min ?? 1;
|
|
1911
|
+
const variant = seed.variants.nodes.find(
|
|
1912
|
+
(v) => (0, import_core11.isVariantFulfillable)(v, min)
|
|
1913
|
+
);
|
|
1914
|
+
if (variant) seeds.push(pick(seed, variant, min));
|
|
1915
|
+
}
|
|
1840
1916
|
}
|
|
1841
1917
|
if (seeds.length > 0) setSelections(seeds);
|
|
1842
|
-
}, [bundle, seededFor]);
|
|
1918
|
+
}, [bundle, seededFor, productHandle]);
|
|
1843
1919
|
const showStepper = bundle?.widgetConfig.mixMatchShowQuantitySelector !== false;
|
|
1844
1920
|
const requiredUnits = bundle?.minQuantity ?? 0;
|
|
1845
|
-
const totalQuantity = (0,
|
|
1921
|
+
const totalQuantity = (0, import_react13.useMemo)(
|
|
1846
1922
|
() => selections.reduce((sum, s) => sum + s.quantity, 0),
|
|
1847
1923
|
[selections]
|
|
1848
1924
|
);
|
|
@@ -1850,7 +1926,7 @@ function MixMatchBundle(props) {
|
|
|
1850
1926
|
const valid = !!bundle && meetsMinUnits;
|
|
1851
1927
|
const shownUnits = Math.min(totalQuantity, requiredUnits);
|
|
1852
1928
|
const remaining = Math.max(0, requiredUnits - shownUnits);
|
|
1853
|
-
const summary = (0,
|
|
1929
|
+
const summary = (0, import_react13.useMemo)(() => {
|
|
1854
1930
|
let comparePrice = 0;
|
|
1855
1931
|
let salePrice = 0;
|
|
1856
1932
|
for (const sel of selections) {
|
|
@@ -1868,7 +1944,7 @@ function MixMatchBundle(props) {
|
|
|
1868
1944
|
const savingsPercent = comparePrice > 0 && savings > 0 ? Math.round(savings / comparePrice * 100) : 0;
|
|
1869
1945
|
return { comparePrice, salePrice, savings, savingsPercent };
|
|
1870
1946
|
}, [selections, bundle]);
|
|
1871
|
-
const addSelection = (0,
|
|
1947
|
+
const addSelection = (0, import_react13.useCallback)(
|
|
1872
1948
|
(item) => {
|
|
1873
1949
|
setSelections((prev) => {
|
|
1874
1950
|
const units = prev.reduce((sum, s) => sum + s.quantity, 0);
|
|
@@ -1879,7 +1955,7 @@ function MixMatchBundle(props) {
|
|
|
1879
1955
|
},
|
|
1880
1956
|
[requiredUnits]
|
|
1881
1957
|
);
|
|
1882
|
-
const updateQuantity = (0,
|
|
1958
|
+
const updateQuantity = (0, import_react13.useCallback)(
|
|
1883
1959
|
(productId, variantId, quantity) => {
|
|
1884
1960
|
setSelections((prev) => {
|
|
1885
1961
|
const idx = prev.findIndex(
|
|
@@ -1902,7 +1978,7 @@ function MixMatchBundle(props) {
|
|
|
1902
1978
|
},
|
|
1903
1979
|
[requiredUnits]
|
|
1904
1980
|
);
|
|
1905
|
-
const swapSelection = (0,
|
|
1981
|
+
const swapSelection = (0, import_react13.useCallback)(
|
|
1906
1982
|
(item) => {
|
|
1907
1983
|
setSelections((prev) => {
|
|
1908
1984
|
if (!bundle) return prev;
|
|
@@ -1934,7 +2010,7 @@ function MixMatchBundle(props) {
|
|
|
1934
2010
|
},
|
|
1935
2011
|
[bundle]
|
|
1936
2012
|
);
|
|
1937
|
-
const removeVariant = (0,
|
|
2013
|
+
const removeVariant = (0, import_react13.useCallback)(
|
|
1938
2014
|
(variantId) => {
|
|
1939
2015
|
setSelections((prev) => {
|
|
1940
2016
|
const idx = prev.findIndex((s) => s.variantId === variantId);
|
|
@@ -1947,7 +2023,7 @@ function MixMatchBundle(props) {
|
|
|
1947
2023
|
},
|
|
1948
2024
|
[bundle]
|
|
1949
2025
|
);
|
|
1950
|
-
const removeSlot = (0,
|
|
2026
|
+
const removeSlot = (0, import_react13.useCallback)(
|
|
1951
2027
|
(index) => {
|
|
1952
2028
|
setSelections((prev) => {
|
|
1953
2029
|
if (index < 0 || index >= prev.length) return prev;
|
|
@@ -1959,7 +2035,7 @@ function MixMatchBundle(props) {
|
|
|
1959
2035
|
},
|
|
1960
2036
|
[bundle]
|
|
1961
2037
|
);
|
|
1962
|
-
const handleAddToCart = (0,
|
|
2038
|
+
const handleAddToCart = (0, import_react13.useCallback)(async () => {
|
|
1963
2039
|
if (!bundle || !valid) return;
|
|
1964
2040
|
const grouped = /* @__PURE__ */ new Map();
|
|
1965
2041
|
for (const sel of selections) {
|
|
@@ -1999,9 +2075,9 @@ function MixMatchBundle(props) {
|
|
|
1999
2075
|
}
|
|
2000
2076
|
}, [bundle, selections, valid, onAddToCart, onError, trackAddToCart, totalQuantity]);
|
|
2001
2077
|
if (result.status === "loading") {
|
|
2002
|
-
return /* @__PURE__ */ (0,
|
|
2003
|
-
/* @__PURE__ */ (0,
|
|
2004
|
-
/* @__PURE__ */ (0,
|
|
2078
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: `lb-bundle lb-bundle--loading ${className ?? ""}`, children: [
|
|
2079
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "lb-skeleton lb-skeleton--title" }),
|
|
2080
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "lb-skeleton lb-skeleton--products" })
|
|
2005
2081
|
] });
|
|
2006
2082
|
}
|
|
2007
2083
|
if (result.status === "error") return null;
|
|
@@ -2020,7 +2096,7 @@ function MixMatchBundle(props) {
|
|
|
2020
2096
|
if (requiredBlocked) return null;
|
|
2021
2097
|
const currency = bundle.products[0]?.priceRange.minVariantPrice.currencyCode ?? "USD";
|
|
2022
2098
|
const ctaLabel = addingToCart ? "Adding..." : bundle.widgetConfig.cta.ctaText || "Add to cart";
|
|
2023
|
-
return /* @__PURE__ */ (0,
|
|
2099
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
2024
2100
|
"div",
|
|
2025
2101
|
{
|
|
2026
2102
|
ref: (el) => {
|
|
@@ -2032,12 +2108,19 @@ function MixMatchBundle(props) {
|
|
|
2032
2108
|
"aria-label": bundle.title,
|
|
2033
2109
|
"data-required-quantity": requiredUnits,
|
|
2034
2110
|
children: [
|
|
2035
|
-
/* @__PURE__ */ (0,
|
|
2036
|
-
/* @__PURE__ */ (0,
|
|
2037
|
-
bundle.description && /* @__PURE__ */ (0,
|
|
2111
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "lb-bundle-header", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "lb-bundle-header__content", children: [
|
|
2112
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("h3", { className: "lb-bundle-title", children: bundle.title }),
|
|
2113
|
+
bundle.description && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "lb-bundle-subtitle", children: bundle.description })
|
|
2038
2114
|
] }) }),
|
|
2039
|
-
/* @__PURE__ */ (0,
|
|
2040
|
-
|
|
2115
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2116
|
+
BundleCountdown,
|
|
2117
|
+
{
|
|
2118
|
+
endsAt: bundle.endsAt,
|
|
2119
|
+
widgetConfig: bundle.widgetConfig
|
|
2120
|
+
}
|
|
2121
|
+
),
|
|
2122
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "lb-mix-match__progress", "data-progress": true, children: [
|
|
2123
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2041
2124
|
"div",
|
|
2042
2125
|
{
|
|
2043
2126
|
className: "lb-mix-match__progress-segments",
|
|
@@ -2045,7 +2128,7 @@ function MixMatchBundle(props) {
|
|
|
2045
2128
|
"aria-valuenow": shownUnits,
|
|
2046
2129
|
"aria-valuemin": 0,
|
|
2047
2130
|
"aria-valuemax": requiredUnits,
|
|
2048
|
-
children: Array.from({ length: requiredUnits }).map((_, i) => /* @__PURE__ */ (0,
|
|
2131
|
+
children: Array.from({ length: requiredUnits }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2049
2132
|
"span",
|
|
2050
2133
|
{
|
|
2051
2134
|
className: `lb-mix-match__progress-segment${i < shownUnits ? " lb-mix-match__progress-segment--filled" : ""}`,
|
|
@@ -2055,8 +2138,8 @@ function MixMatchBundle(props) {
|
|
|
2055
2138
|
))
|
|
2056
2139
|
}
|
|
2057
2140
|
),
|
|
2058
|
-
/* @__PURE__ */ (0,
|
|
2059
|
-
/* @__PURE__ */ (0,
|
|
2141
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "lb-mix-match__progress-labels", children: [
|
|
2142
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2060
2143
|
"span",
|
|
2061
2144
|
{
|
|
2062
2145
|
className: "lb-mix-match__progress-count",
|
|
@@ -2065,7 +2148,7 @@ function MixMatchBundle(props) {
|
|
|
2065
2148
|
children: `${shownUnits} of ${requiredUnits} added`
|
|
2066
2149
|
}
|
|
2067
2150
|
),
|
|
2068
|
-
/* @__PURE__ */ (0,
|
|
2151
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2069
2152
|
"span",
|
|
2070
2153
|
{
|
|
2071
2154
|
className: "lb-mix-match__progress-remaining",
|
|
@@ -2076,7 +2159,7 @@ function MixMatchBundle(props) {
|
|
|
2076
2159
|
)
|
|
2077
2160
|
] })
|
|
2078
2161
|
] }),
|
|
2079
|
-
/* @__PURE__ */ (0,
|
|
2162
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2080
2163
|
"div",
|
|
2081
2164
|
{
|
|
2082
2165
|
className: "lb-mix-match__slots lb-edge-fade",
|
|
@@ -2087,15 +2170,15 @@ function MixMatchBundle(props) {
|
|
|
2087
2170
|
button provides the keyboard/AT path (its activation bubbles
|
|
2088
2171
|
here); × stops propagation. */
|
|
2089
2172
|
// eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions -- keyboard path is the inner "Edit selection" title button whose activation bubbles to this handler
|
|
2090
|
-
/* @__PURE__ */ (0,
|
|
2173
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
2091
2174
|
"div",
|
|
2092
2175
|
{
|
|
2093
2176
|
className: "lb-mix-match__slot lb-mix-match__slot--filled",
|
|
2094
2177
|
onClick: () => setPickerOpen(true),
|
|
2095
2178
|
children: [
|
|
2096
|
-
item.featuredImage && /* @__PURE__ */ (0,
|
|
2097
|
-
/* @__PURE__ */ (0,
|
|
2098
|
-
/* @__PURE__ */ (0,
|
|
2179
|
+
item.featuredImage && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "lb-bundle-thumbnail", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("img", { src: item.featuredImage, alt: item.title, loading: "lazy" }) }),
|
|
2180
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "lb-mix-match__filled-info", children: [
|
|
2181
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2099
2182
|
"button",
|
|
2100
2183
|
{
|
|
2101
2184
|
type: "button",
|
|
@@ -2104,15 +2187,15 @@ function MixMatchBundle(props) {
|
|
|
2104
2187
|
children: item.title
|
|
2105
2188
|
}
|
|
2106
2189
|
),
|
|
2107
|
-
item.variantTitle && item.variantTitle !== "Default Title" && /* @__PURE__ */ (0,
|
|
2108
|
-
/* @__PURE__ */ (0,
|
|
2109
|
-
item.compareAtPrice !== null && item.compareAtPrice > item.price && /* @__PURE__ */ (0,
|
|
2110
|
-
/* @__PURE__ */ (0,
|
|
2111
|
-
/* @__PURE__ */ (0,
|
|
2190
|
+
item.variantTitle && item.variantTitle !== "Default Title" && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "lb-mix-match__filled-variant", children: item.variantTitle }),
|
|
2191
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "lb-mix-match__filled-price", children: [
|
|
2192
|
+
item.compareAtPrice !== null && item.compareAtPrice > item.price && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("s", { className: "lb-mix-match__filled-compare", children: (0, import_core11.formatMoney)(item.compareAtPrice, currency) }),
|
|
2193
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "lb-bundle-product-price", children: (0, import_core11.formatMoney)(item.price, currency) }),
|
|
2194
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "lb-bundle-qty-inline", children: `\xD7${item.quantity}` })
|
|
2112
2195
|
] }),
|
|
2113
|
-
item.unitPrice && /* @__PURE__ */ (0,
|
|
2196
|
+
item.unitPrice && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "lb-bundle-product-unit-price", children: item.unitPrice })
|
|
2114
2197
|
] }),
|
|
2115
|
-
canRemoveItem(bundle, selections, item) ? /* @__PURE__ */ (0,
|
|
2198
|
+
canRemoveItem(bundle, selections, item) ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2116
2199
|
"button",
|
|
2117
2200
|
{
|
|
2118
2201
|
type: "button",
|
|
@@ -2122,13 +2205,13 @@ function MixMatchBundle(props) {
|
|
|
2122
2205
|
e.stopPropagation();
|
|
2123
2206
|
removeSlot(index);
|
|
2124
2207
|
},
|
|
2125
|
-
children: /* @__PURE__ */ (0,
|
|
2208
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(CloseIcon2, {})
|
|
2126
2209
|
}
|
|
2127
2210
|
) : (
|
|
2128
2211
|
/* Required pick at its floor — quiet state chip instead of
|
|
2129
2212
|
the ×; removal returns once another slot covers the
|
|
2130
2213
|
product's minimum (variant swap flow). */
|
|
2131
|
-
/* @__PURE__ */ (0,
|
|
2214
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "lb-mix-match__slot-required", children: "Required" })
|
|
2132
2215
|
)
|
|
2133
2216
|
]
|
|
2134
2217
|
},
|
|
@@ -2137,7 +2220,7 @@ function MixMatchBundle(props) {
|
|
|
2137
2220
|
))
|
|
2138
2221
|
}
|
|
2139
2222
|
),
|
|
2140
|
-
totalQuantity < requiredUnits && /* @__PURE__ */ (0,
|
|
2223
|
+
totalQuantity < requiredUnits && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
2141
2224
|
"button",
|
|
2142
2225
|
{
|
|
2143
2226
|
type: "button",
|
|
@@ -2145,34 +2228,34 @@ function MixMatchBundle(props) {
|
|
|
2145
2228
|
"data-add-product-trigger": true,
|
|
2146
2229
|
onClick: () => setPickerOpen(true),
|
|
2147
2230
|
children: [
|
|
2148
|
-
/* @__PURE__ */ (0,
|
|
2149
|
-
/* @__PURE__ */ (0,
|
|
2231
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "lb-mix-match__add-product-icon", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(PlusIcon, {}) }),
|
|
2232
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "lb-mix-match__add-product-label", children: "Add a product" })
|
|
2150
2233
|
]
|
|
2151
2234
|
}
|
|
2152
2235
|
),
|
|
2153
|
-
/* @__PURE__ */ (0,
|
|
2154
|
-
selections.length > 0 && /* @__PURE__ */ (0,
|
|
2155
|
-
/* @__PURE__ */ (0,
|
|
2156
|
-
/* @__PURE__ */ (0,
|
|
2157
|
-
bundle.widgetConfig.savingsBar.visible && summary.savings > 0 && /* @__PURE__ */ (0,
|
|
2236
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "lb-bundle-divider" }),
|
|
2237
|
+
selections.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "lb-bundle-summary", "data-pricing-section": true, children: [
|
|
2238
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "lb-bundle-summary__text", children: [
|
|
2239
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "lb-bundle-summary__label", children: "Bundle total" }),
|
|
2240
|
+
bundle.widgetConfig.savingsBar.visible && summary.savings > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("p", { className: "lb-bundle-savings-line", "data-savings-bar": true, children: [
|
|
2158
2241
|
"You save",
|
|
2159
2242
|
" ",
|
|
2160
|
-
/* @__PURE__ */ (0,
|
|
2243
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { "data-savings-amount": true, children: (0, import_core11.formatMoney)(summary.savings, currency) }),
|
|
2161
2244
|
" ",
|
|
2162
|
-
/* @__PURE__ */ (0,
|
|
2245
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { "data-savings-percent": true, children: [
|
|
2163
2246
|
"(",
|
|
2164
2247
|
summary.savingsPercent,
|
|
2165
2248
|
"%)"
|
|
2166
2249
|
] })
|
|
2167
2250
|
] })
|
|
2168
2251
|
] }),
|
|
2169
|
-
/* @__PURE__ */ (0,
|
|
2170
|
-
bundle.widgetConfig.pricing.showComparePrice && summary.savings > 0 && /* @__PURE__ */ (0,
|
|
2171
|
-
/* @__PURE__ */ (0,
|
|
2252
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "lb-bundle-summary__prices", children: [
|
|
2253
|
+
bundle.widgetConfig.pricing.showComparePrice && summary.savings > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "lb-bundle-compare-price", "data-compare-price": true, children: (0, import_core11.formatMoney)(summary.comparePrice, currency) }),
|
|
2254
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "lb-bundle-sale-price", "data-sale-price": true, children: (0, import_core11.formatMoney)(summary.salePrice, currency) })
|
|
2172
2255
|
] })
|
|
2173
2256
|
] }),
|
|
2174
|
-
cartError && /* @__PURE__ */ (0,
|
|
2175
|
-
/* @__PURE__ */ (0,
|
|
2257
|
+
cartError && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "lb-bundle__error", role: "alert", children: cartError }),
|
|
2258
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2176
2259
|
"button",
|
|
2177
2260
|
{
|
|
2178
2261
|
className: "lb-bundle__cta",
|
|
@@ -2182,7 +2265,7 @@ function MixMatchBundle(props) {
|
|
|
2182
2265
|
children: ctaLabel
|
|
2183
2266
|
}
|
|
2184
2267
|
),
|
|
2185
|
-
pickerOpen && /* @__PURE__ */ (0,
|
|
2268
|
+
pickerOpen && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
2186
2269
|
MixMatchPicker,
|
|
2187
2270
|
{
|
|
2188
2271
|
outOfStockBehavior,
|
|
@@ -2223,7 +2306,7 @@ function countInStockProducts(bundle) {
|
|
|
2223
2306
|
return count;
|
|
2224
2307
|
}
|
|
2225
2308
|
function PlusIcon() {
|
|
2226
|
-
return /* @__PURE__ */ (0,
|
|
2309
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
2227
2310
|
"svg",
|
|
2228
2311
|
{
|
|
2229
2312
|
width: "18",
|
|
@@ -2233,14 +2316,14 @@ function PlusIcon() {
|
|
|
2233
2316
|
xmlns: "http://www.w3.org/2000/svg",
|
|
2234
2317
|
"aria-hidden": "true",
|
|
2235
2318
|
children: [
|
|
2236
|
-
/* @__PURE__ */ (0,
|
|
2237
|
-
/* @__PURE__ */ (0,
|
|
2319
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("line", { x1: "9", y1: "3", x2: "9", y2: "15", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }),
|
|
2320
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("line", { x1: "3", y1: "9", x2: "15", y2: "9", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" })
|
|
2238
2321
|
]
|
|
2239
2322
|
}
|
|
2240
2323
|
);
|
|
2241
2324
|
}
|
|
2242
2325
|
function CloseIcon2() {
|
|
2243
|
-
return /* @__PURE__ */ (0,
|
|
2326
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
2244
2327
|
"svg",
|
|
2245
2328
|
{
|
|
2246
2329
|
width: "16",
|
|
@@ -2250,17 +2333,17 @@ function CloseIcon2() {
|
|
|
2250
2333
|
xmlns: "http://www.w3.org/2000/svg",
|
|
2251
2334
|
"aria-hidden": "true",
|
|
2252
2335
|
children: [
|
|
2253
|
-
/* @__PURE__ */ (0,
|
|
2254
|
-
/* @__PURE__ */ (0,
|
|
2336
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("line", { x1: "5", y1: "5", x2: "15", y2: "15", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }),
|
|
2337
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("line", { x1: "15", y1: "5", x2: "5", y2: "15", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" })
|
|
2255
2338
|
]
|
|
2256
2339
|
}
|
|
2257
2340
|
);
|
|
2258
2341
|
}
|
|
2259
2342
|
|
|
2260
2343
|
// src/components/VolumeBundle.tsx
|
|
2261
|
-
var
|
|
2344
|
+
var import_react14 = require("react");
|
|
2262
2345
|
var import_core12 = require("@lime-bundles/core");
|
|
2263
|
-
var
|
|
2346
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
2264
2347
|
function VolumeBundle(props) {
|
|
2265
2348
|
const {
|
|
2266
2349
|
shopDomain,
|
|
@@ -2284,13 +2367,30 @@ function VolumeBundle(props) {
|
|
|
2284
2367
|
bundleType: "volume",
|
|
2285
2368
|
enabled: analyticsEnabled !== false
|
|
2286
2369
|
});
|
|
2287
|
-
const [quantity, setQuantity] = (0,
|
|
2288
|
-
const [addingToCart, setAddingToCart] = (0,
|
|
2289
|
-
const [cartError, setCartError] = (0,
|
|
2370
|
+
const [quantity, setQuantity] = (0, import_react14.useState)(1);
|
|
2371
|
+
const [addingToCart, setAddingToCart] = (0, import_react14.useState)(false);
|
|
2372
|
+
const [cartError, setCartError] = (0, import_react14.useState)(null);
|
|
2373
|
+
const [seededFor, setSeededFor] = (0, import_react14.useState)(null);
|
|
2290
2374
|
const bundle = result.status === "success" && result.bundle.bundleType === "volume" ? result.bundle : null;
|
|
2375
|
+
(0, import_react14.useEffect)(() => {
|
|
2376
|
+
if (!bundle || seededFor === bundle.id) return;
|
|
2377
|
+
setSeededFor(bundle.id);
|
|
2378
|
+
const tiers = bundle.volumeTiers;
|
|
2379
|
+
if (tiers.length === 0) return;
|
|
2380
|
+
const best = (0, import_core12.bestValueTierIndex)(
|
|
2381
|
+
tiers,
|
|
2382
|
+
bundle.discountConfig.discountType
|
|
2383
|
+
);
|
|
2384
|
+
const idx = (0, import_core12.resolveDefaultTierIndex)(
|
|
2385
|
+
bundle.widgetConfig.defaultTier,
|
|
2386
|
+
tiers.length,
|
|
2387
|
+
best
|
|
2388
|
+
);
|
|
2389
|
+
setQuantity(tiers[idx].minQuantity);
|
|
2390
|
+
}, [bundle, seededFor]);
|
|
2291
2391
|
const setConfigVarsRef = useWidgetConfigVars(bundle?.widgetConfig);
|
|
2292
2392
|
const tiersEdgeFadeRef = useEdgeFade();
|
|
2293
|
-
(0,
|
|
2393
|
+
(0, import_react14.useEffect)(() => {
|
|
2294
2394
|
if (result.status === "error") {
|
|
2295
2395
|
onError?.(result.error);
|
|
2296
2396
|
return;
|
|
@@ -2304,8 +2404,8 @@ function VolumeBundle(props) {
|
|
|
2304
2404
|
}
|
|
2305
2405
|
}, [result, onError]);
|
|
2306
2406
|
const product = bundle?.products[0];
|
|
2307
|
-
const variants = (0,
|
|
2308
|
-
const optionNames = (0,
|
|
2407
|
+
const variants = (0, import_react14.useMemo)(() => product?.variants.nodes ?? [], [product]);
|
|
2408
|
+
const optionNames = (0, import_react14.useMemo)(() => {
|
|
2309
2409
|
const first = variants[0];
|
|
2310
2410
|
return first ? first.selectedOptions.map((o) => o.name) : [];
|
|
2311
2411
|
}, [variants]);
|
|
@@ -2322,7 +2422,7 @@ function VolumeBundle(props) {
|
|
|
2322
2422
|
displayVariant.unitPriceMeasurement,
|
|
2323
2423
|
currency
|
|
2324
2424
|
) : null;
|
|
2325
|
-
const tierSavings = (0,
|
|
2425
|
+
const tierSavings = (0, import_react14.useMemo)(
|
|
2326
2426
|
() => bundle ? (0, import_core12.calculateTierSavings)(
|
|
2327
2427
|
bundle.volumeTiers,
|
|
2328
2428
|
basePrice,
|
|
@@ -2332,26 +2432,23 @@ function VolumeBundle(props) {
|
|
|
2332
2432
|
[bundle, basePrice, quantity]
|
|
2333
2433
|
);
|
|
2334
2434
|
const activeTier = bundle ? (0, import_core12.getActiveTier)(bundle.volumeTiers, quantity) : null;
|
|
2335
|
-
const popularTierIndex = (0,
|
|
2336
|
-
if (!bundle
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
}
|
|
2347
|
-
return best;
|
|
2348
|
-
}, [bundle, tierSavings]);
|
|
2435
|
+
const popularTierIndex = (0, import_react14.useMemo)(() => {
|
|
2436
|
+
if (!bundle || bundle.volumeTiers.length === 0) return -1;
|
|
2437
|
+
return (0, import_core12.resolvePopularTierIndex)(
|
|
2438
|
+
bundle.widgetConfig.popularBadge.tierIndex,
|
|
2439
|
+
bundle.widgetConfig.popularBadge.visible !== false,
|
|
2440
|
+
(0, import_core12.bestValueTierIndex)(
|
|
2441
|
+
bundle.volumeTiers,
|
|
2442
|
+
bundle.discountConfig.discountType
|
|
2443
|
+
)
|
|
2444
|
+
);
|
|
2445
|
+
}, [bundle]);
|
|
2349
2446
|
const activeUnitPrice = tierSavings.find((ts) => ts.tier === activeTier)?.unitPrice ?? basePrice;
|
|
2350
2447
|
const undiscountedTotal = basePrice * quantity;
|
|
2351
2448
|
const volumeTotal = activeUnitPrice * quantity;
|
|
2352
2449
|
const volumeSavings = Math.max(0, undiscountedTotal - volumeTotal);
|
|
2353
2450
|
const volumeSavingsPercent = undiscountedTotal > 0 && volumeSavings > 0 ? Math.round(volumeSavings / undiscountedTotal * 100) : 0;
|
|
2354
|
-
const handleAddToCart = (0,
|
|
2451
|
+
const handleAddToCart = (0, import_react14.useCallback)(async () => {
|
|
2355
2452
|
if (!bundle || !product) return;
|
|
2356
2453
|
const variant = selectedVariant ?? product.variants.nodes.find(
|
|
2357
2454
|
(v) => (0, import_core12.isVariantFulfillable)(v, quantity)
|
|
@@ -2397,15 +2494,15 @@ function VolumeBundle(props) {
|
|
|
2397
2494
|
tierSavings
|
|
2398
2495
|
]);
|
|
2399
2496
|
if (result.status === "loading") {
|
|
2400
|
-
return /* @__PURE__ */ (0,
|
|
2401
|
-
/* @__PURE__ */ (0,
|
|
2402
|
-
/* @__PURE__ */ (0,
|
|
2497
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: `lb-bundle lb-bundle--loading ${className ?? ""}`, children: [
|
|
2498
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "lb-skeleton lb-skeleton--title" }),
|
|
2499
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "lb-skeleton lb-skeleton--tiers" })
|
|
2403
2500
|
] });
|
|
2404
2501
|
}
|
|
2405
2502
|
if (result.status === "error") return null;
|
|
2406
2503
|
if (!bundle) return null;
|
|
2407
2504
|
if (!product) return null;
|
|
2408
|
-
return /* @__PURE__ */ (0,
|
|
2505
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
2409
2506
|
"div",
|
|
2410
2507
|
{
|
|
2411
2508
|
ref: (el) => {
|
|
@@ -2416,12 +2513,19 @@ function VolumeBundle(props) {
|
|
|
2416
2513
|
role: "region",
|
|
2417
2514
|
"aria-label": bundle.title,
|
|
2418
2515
|
children: [
|
|
2419
|
-
/* @__PURE__ */ (0,
|
|
2420
|
-
/* @__PURE__ */ (0,
|
|
2421
|
-
bundle.description && /* @__PURE__ */ (0,
|
|
2516
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "lb-bundle-header", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "lb-bundle-header__content", children: [
|
|
2517
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h3", { className: "lb-bundle-title", children: bundle.title }),
|
|
2518
|
+
bundle.description && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "lb-bundle-subtitle", children: bundle.description })
|
|
2422
2519
|
] }) }),
|
|
2423
|
-
/* @__PURE__ */ (0,
|
|
2424
|
-
|
|
2520
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2521
|
+
BundleCountdown,
|
|
2522
|
+
{
|
|
2523
|
+
endsAt: bundle.endsAt,
|
|
2524
|
+
widgetConfig: bundle.widgetConfig
|
|
2525
|
+
}
|
|
2526
|
+
),
|
|
2527
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "lb-bundle-product-row lb-bundle-product-row--volume", children: [
|
|
2528
|
+
thumbImage && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2425
2529
|
"img",
|
|
2426
2530
|
{
|
|
2427
2531
|
src: thumbImage.url,
|
|
@@ -2430,20 +2534,20 @@ function VolumeBundle(props) {
|
|
|
2430
2534
|
loading: "lazy"
|
|
2431
2535
|
}
|
|
2432
2536
|
),
|
|
2433
|
-
/* @__PURE__ */ (0,
|
|
2434
|
-
/* @__PURE__ */ (0,
|
|
2435
|
-
/* @__PURE__ */ (0,
|
|
2537
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "lb-bundle__product-info", children: [
|
|
2538
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "lb-bundle__product-title", children: product.title }),
|
|
2539
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("p", { className: "lb-bundle__product-price", children: [
|
|
2436
2540
|
(0, import_core12.formatMoney)(basePrice, currency),
|
|
2437
2541
|
" each"
|
|
2438
2542
|
] }),
|
|
2439
|
-
unitPriceText && /* @__PURE__ */ (0,
|
|
2440
|
-
showPicker && /* @__PURE__ */ (0,
|
|
2543
|
+
unitPriceText && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "lb-bundle__product-unit-price", children: unitPriceText }),
|
|
2544
|
+
showPicker && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "lb-bundle__product-variant-pickers", children: optionNames.map((optionName, optionIndex) => {
|
|
2441
2545
|
const dropdownOptions = optionsFor(optionIndex).map((o) => ({
|
|
2442
2546
|
value: o.value,
|
|
2443
2547
|
label: o.value,
|
|
2444
2548
|
disabled: o.disabled
|
|
2445
2549
|
}));
|
|
2446
|
-
return /* @__PURE__ */ (0,
|
|
2550
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2447
2551
|
VariantDropdown,
|
|
2448
2552
|
{
|
|
2449
2553
|
options: dropdownOptions,
|
|
@@ -2456,37 +2560,47 @@ function VolumeBundle(props) {
|
|
|
2456
2560
|
}) })
|
|
2457
2561
|
] })
|
|
2458
2562
|
] }),
|
|
2459
|
-
/* @__PURE__ */ (0,
|
|
2563
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2460
2564
|
"div",
|
|
2461
2565
|
{
|
|
2462
2566
|
className: "lb-bundle__tiers lb-edge-fade",
|
|
2463
|
-
role: "
|
|
2464
|
-
"aria-label": "
|
|
2567
|
+
role: "radiogroup",
|
|
2568
|
+
"aria-label": "Select quantity",
|
|
2465
2569
|
ref: tiersEdgeFadeRef,
|
|
2466
2570
|
children: tierSavings.map((ts, tierIndex) => {
|
|
2467
2571
|
const savingsPercent = Math.round(ts.savingsPercent);
|
|
2468
2572
|
const showCompare = bundle.widgetConfig.pricing.showComparePrice && ts.savings > 0;
|
|
2469
|
-
|
|
2573
|
+
const isChecked = activeTier === ts.tier;
|
|
2574
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
|
|
2470
2575
|
"div",
|
|
2471
2576
|
{
|
|
2472
2577
|
className: `lb-bundle__tier ${ts.isActive ? "lb-bundle__tier--active" : ""}`,
|
|
2473
|
-
role: "
|
|
2578
|
+
role: "radio",
|
|
2579
|
+
"aria-checked": isChecked,
|
|
2580
|
+
tabIndex: isChecked ? 0 : -1,
|
|
2581
|
+
onClick: () => setQuantity(ts.tier.minQuantity),
|
|
2582
|
+
onKeyDown: (e) => {
|
|
2583
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
2584
|
+
e.preventDefault();
|
|
2585
|
+
setQuantity(ts.tier.minQuantity);
|
|
2586
|
+
}
|
|
2587
|
+
},
|
|
2474
2588
|
children: [
|
|
2475
|
-
/* @__PURE__ */ (0,
|
|
2476
|
-
/* @__PURE__ */ (0,
|
|
2477
|
-
/* @__PURE__ */ (0,
|
|
2589
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "lb-bundle__tier-radio", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "lb-bundle__tier-radio-dot" }) }),
|
|
2590
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "lb-bundle__tier-info", children: [
|
|
2591
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "lb-bundle__tier-label", children: [
|
|
2478
2592
|
"Buy ",
|
|
2479
2593
|
ts.tier.minQuantity
|
|
2480
2594
|
] }),
|
|
2481
|
-
/* @__PURE__ */ (0,
|
|
2482
|
-
showCompare && /* @__PURE__ */ (0,
|
|
2483
|
-
/* @__PURE__ */ (0,
|
|
2484
|
-
/* @__PURE__ */ (0,
|
|
2595
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "lb-bundle__tier-price", children: [
|
|
2596
|
+
showCompare && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "lb-bundle__tier-compare", children: (0, import_core12.formatMoney)(basePrice, currency) }),
|
|
2597
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: (0, import_core12.formatMoney)(ts.unitPrice, currency) }),
|
|
2598
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "lb-bundle__tier-unit", children: "each" })
|
|
2485
2599
|
] })
|
|
2486
2600
|
] }),
|
|
2487
|
-
(tierIndex === popularTierIndex || savingsPercent > 0) && /* @__PURE__ */ (0,
|
|
2488
|
-
tierIndex === popularTierIndex && /* @__PURE__ */ (0,
|
|
2489
|
-
savingsPercent > 0 && /* @__PURE__ */ (0,
|
|
2601
|
+
(tierIndex === popularTierIndex || savingsPercent > 0) && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "lb-bundle__tier-right", children: [
|
|
2602
|
+
tierIndex === popularTierIndex && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "lb-bundle__tier-badge", children: bundle.widgetConfig.popularBadge.text }),
|
|
2603
|
+
savingsPercent > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "lb-bundle__tier-savings", children: [
|
|
2490
2604
|
"Save ",
|
|
2491
2605
|
savingsPercent,
|
|
2492
2606
|
"%"
|
|
@@ -2499,10 +2613,10 @@ function VolumeBundle(props) {
|
|
|
2499
2613
|
})
|
|
2500
2614
|
}
|
|
2501
2615
|
),
|
|
2502
|
-
/* @__PURE__ */ (0,
|
|
2503
|
-
/* @__PURE__ */ (0,
|
|
2504
|
-
/* @__PURE__ */ (0,
|
|
2505
|
-
/* @__PURE__ */ (0,
|
|
2616
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "lb-bundle__quantity-selector", children: [
|
|
2617
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("label", { htmlFor: `lb-qty-${bundle.id}`, children: "Quantity" }),
|
|
2618
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "lb-bundle__quantity-control", children: [
|
|
2619
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2506
2620
|
"button",
|
|
2507
2621
|
{
|
|
2508
2622
|
"aria-label": "Decrease quantity",
|
|
@@ -2510,7 +2624,7 @@ function VolumeBundle(props) {
|
|
|
2510
2624
|
children: "\u2212"
|
|
2511
2625
|
}
|
|
2512
2626
|
),
|
|
2513
|
-
/* @__PURE__ */ (0,
|
|
2627
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2514
2628
|
"input",
|
|
2515
2629
|
{
|
|
2516
2630
|
id: `lb-qty-${bundle.id}`,
|
|
@@ -2524,7 +2638,7 @@ function VolumeBundle(props) {
|
|
|
2524
2638
|
className: "lb-bundle__quantity-input"
|
|
2525
2639
|
}
|
|
2526
2640
|
),
|
|
2527
|
-
/* @__PURE__ */ (0,
|
|
2641
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2528
2642
|
"button",
|
|
2529
2643
|
{
|
|
2530
2644
|
"aria-label": "Increase quantity",
|
|
@@ -2534,23 +2648,23 @@ function VolumeBundle(props) {
|
|
|
2534
2648
|
)
|
|
2535
2649
|
] })
|
|
2536
2650
|
] }),
|
|
2537
|
-
cartError && /* @__PURE__ */ (0,
|
|
2651
|
+
cartError && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "lb-bundle__error", role: "alert", children: cartError }),
|
|
2538
2652
|
bundle && displayVariant && (0, import_core12.shouldShowLowStockBadge)(
|
|
2539
2653
|
displayVariant,
|
|
2540
2654
|
minTierQty,
|
|
2541
2655
|
bundle.widgetConfig.lowStockThreshold,
|
|
2542
2656
|
bundle.widgetConfig.showLowStockBadge
|
|
2543
|
-
) && /* @__PURE__ */ (0,
|
|
2657
|
+
) && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "lb-bundle-low-stock-badge", children: [
|
|
2544
2658
|
"Only ",
|
|
2545
2659
|
displayVariant.quantityAvailable,
|
|
2546
2660
|
" left"
|
|
2547
2661
|
] }),
|
|
2548
|
-
/* @__PURE__ */ (0,
|
|
2549
|
-
/* @__PURE__ */ (0,
|
|
2550
|
-
/* @__PURE__ */ (0,
|
|
2551
|
-
/* @__PURE__ */ (0,
|
|
2662
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "lb-bundle-divider" }),
|
|
2663
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "lb-bundle-summary", children: [
|
|
2664
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "lb-bundle-summary__text", children: [
|
|
2665
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "lb-bundle-summary__label", "data-total-label": true, children: [
|
|
2552
2666
|
"Total",
|
|
2553
|
-
bundle.widgetConfig.pricing.showItemCount && /* @__PURE__ */ (0,
|
|
2667
|
+
bundle.widgetConfig.pricing.showItemCount && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { "data-item-count": true, children: [
|
|
2554
2668
|
" ",
|
|
2555
2669
|
"(",
|
|
2556
2670
|
quantity,
|
|
@@ -2559,24 +2673,24 @@ function VolumeBundle(props) {
|
|
|
2559
2673
|
")"
|
|
2560
2674
|
] })
|
|
2561
2675
|
] }),
|
|
2562
|
-
bundle.widgetConfig.savingsBar.visible && volumeSavings > 0 && /* @__PURE__ */ (0,
|
|
2676
|
+
bundle.widgetConfig.savingsBar.visible && volumeSavings > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("p", { className: "lb-bundle-savings-line", "data-savings-bar": true, children: [
|
|
2563
2677
|
"You save",
|
|
2564
2678
|
" ",
|
|
2565
|
-
/* @__PURE__ */ (0,
|
|
2679
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { "data-savings-amount": true, children: (0, import_core12.formatMoney)(volumeSavings, currency) }),
|
|
2566
2680
|
" ",
|
|
2567
|
-
/* @__PURE__ */ (0,
|
|
2681
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { "data-savings-percent": true, children: [
|
|
2568
2682
|
"(",
|
|
2569
2683
|
volumeSavingsPercent,
|
|
2570
2684
|
"%)"
|
|
2571
2685
|
] })
|
|
2572
2686
|
] })
|
|
2573
2687
|
] }),
|
|
2574
|
-
/* @__PURE__ */ (0,
|
|
2575
|
-
bundle.widgetConfig.pricing.showComparePrice && volumeSavings > 0 && /* @__PURE__ */ (0,
|
|
2576
|
-
/* @__PURE__ */ (0,
|
|
2688
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "lb-bundle-summary__prices", children: [
|
|
2689
|
+
bundle.widgetConfig.pricing.showComparePrice && volumeSavings > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "lb-bundle-compare-price", "data-compare-price": true, children: (0, import_core12.formatMoney)(undiscountedTotal, currency) }),
|
|
2690
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "lb-bundle-sale-price", "data-total-price": true, children: (0, import_core12.formatMoney)(volumeTotal, currency) })
|
|
2577
2691
|
] })
|
|
2578
2692
|
] }),
|
|
2579
|
-
/* @__PURE__ */ (0,
|
|
2693
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
2580
2694
|
"button",
|
|
2581
2695
|
{
|
|
2582
2696
|
className: "lb-bundle__cta",
|
|
@@ -2592,9 +2706,9 @@ function VolumeBundle(props) {
|
|
|
2592
2706
|
}
|
|
2593
2707
|
|
|
2594
2708
|
// src/components/BogoBundle.tsx
|
|
2595
|
-
var
|
|
2709
|
+
var import_react15 = require("react");
|
|
2596
2710
|
var import_core13 = require("@lime-bundles/core");
|
|
2597
|
-
var
|
|
2711
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
2598
2712
|
function discountedUnit(price, percent) {
|
|
2599
2713
|
const cents = Math.round(price * 100);
|
|
2600
2714
|
const discounted = cents - Math.floor(cents * percent / 100);
|
|
@@ -2623,10 +2737,10 @@ function BogoBundle(props) {
|
|
|
2623
2737
|
bundleType: "bogo",
|
|
2624
2738
|
enabled: analyticsEnabled !== false
|
|
2625
2739
|
});
|
|
2626
|
-
const [addingToCart, setAddingToCart] = (0,
|
|
2627
|
-
const [cartError, setCartError] = (0,
|
|
2628
|
-
const [selectedVariants, setSelectedVariants] = (0,
|
|
2629
|
-
const handleVariantChange = (0,
|
|
2740
|
+
const [addingToCart, setAddingToCart] = (0, import_react15.useState)(false);
|
|
2741
|
+
const [cartError, setCartError] = (0, import_react15.useState)(null);
|
|
2742
|
+
const [selectedVariants, setSelectedVariants] = (0, import_react15.useState)({ buy: null, get: null });
|
|
2743
|
+
const handleVariantChange = (0, import_react15.useCallback)(
|
|
2630
2744
|
(role, variant) => {
|
|
2631
2745
|
setSelectedVariants((prev) => {
|
|
2632
2746
|
if (prev[role] === variant) return prev;
|
|
@@ -2637,7 +2751,7 @@ function BogoBundle(props) {
|
|
|
2637
2751
|
);
|
|
2638
2752
|
const bundle = result.status === "success" && result.bundle.bundleType === "bogo" ? result.bundle : null;
|
|
2639
2753
|
const setConfigVarsRef = useWidgetConfigVars(bundle?.widgetConfig);
|
|
2640
|
-
(0,
|
|
2754
|
+
(0, import_react15.useEffect)(() => {
|
|
2641
2755
|
if (result.status === "error") {
|
|
2642
2756
|
onError?.(result.error);
|
|
2643
2757
|
return;
|
|
@@ -2650,28 +2764,28 @@ function BogoBundle(props) {
|
|
|
2650
2764
|
);
|
|
2651
2765
|
}
|
|
2652
2766
|
}, [result, onError]);
|
|
2653
|
-
const buyProduct = (0,
|
|
2767
|
+
const buyProduct = (0, import_react15.useMemo)(
|
|
2654
2768
|
() => bundle?.products.find((p) => p.id === bundle.buyProductId) ?? null,
|
|
2655
2769
|
[bundle]
|
|
2656
2770
|
);
|
|
2657
|
-
const getProduct = (0,
|
|
2771
|
+
const getProduct = (0, import_react15.useMemo)(
|
|
2658
2772
|
() => bundle?.products.find((p) => p.id === bundle.getProductId) ?? null,
|
|
2659
2773
|
[bundle]
|
|
2660
2774
|
);
|
|
2661
2775
|
const percent = bundle ? Math.min(100, Math.max(0, bundle.discountConfig.discountValue)) : 0;
|
|
2662
|
-
const resolveVariant = (0,
|
|
2776
|
+
const resolveVariant = (0, import_react15.useCallback)(
|
|
2663
2777
|
(product, selected, qty) => {
|
|
2664
2778
|
if (!product) return null;
|
|
2665
2779
|
return selected ?? product.variants.nodes.find((v) => (0, import_core13.isVariantFulfillable)(v, qty)) ?? product.variants.nodes[0] ?? null;
|
|
2666
2780
|
},
|
|
2667
2781
|
[]
|
|
2668
2782
|
);
|
|
2669
|
-
const oosSides = (0,
|
|
2783
|
+
const oosSides = (0, import_react15.useMemo)(() => {
|
|
2670
2784
|
if (!bundle) return 0;
|
|
2671
2785
|
const short = (product, qty) => !!product && !product.variants.nodes.some((v) => (0, import_core13.isVariantFulfillable)(v, qty));
|
|
2672
2786
|
return (short(buyProduct, bundle.buyQuantity) ? 1 : 0) + (short(getProduct, bundle.getQuantity) ? 1 : 0);
|
|
2673
2787
|
}, [bundle, buyProduct, getProduct]);
|
|
2674
|
-
const handleAddToCart = (0,
|
|
2788
|
+
const handleAddToCart = (0, import_react15.useCallback)(async () => {
|
|
2675
2789
|
if (!bundle || !buyProduct || !getProduct) return;
|
|
2676
2790
|
const buyVariant2 = resolveVariant(buyProduct, selectedVariants.buy, bundle.buyQuantity);
|
|
2677
2791
|
const getVariant2 = resolveVariant(getProduct, selectedVariants.get, bundle.getQuantity);
|
|
@@ -2718,9 +2832,9 @@ function BogoBundle(props) {
|
|
|
2718
2832
|
}
|
|
2719
2833
|
}, [bundle, buyProduct, getProduct, selectedVariants, resolveVariant, onAddToCart, onError, trackAddToCart, percent]);
|
|
2720
2834
|
if (result.status === "loading") {
|
|
2721
|
-
return /* @__PURE__ */ (0,
|
|
2722
|
-
/* @__PURE__ */ (0,
|
|
2723
|
-
/* @__PURE__ */ (0,
|
|
2835
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: `lb-bundle lb-bundle--loading ${className ?? ""}`, children: [
|
|
2836
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "lb-skeleton lb-skeleton--title" }),
|
|
2837
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "lb-skeleton lb-skeleton--products" })
|
|
2724
2838
|
] });
|
|
2725
2839
|
}
|
|
2726
2840
|
if (result.status === "error") return null;
|
|
@@ -2737,7 +2851,7 @@ function BogoBundle(props) {
|
|
|
2737
2851
|
const showCompare = bundle.widgetConfig.pricing.showComparePrice && savings > 0;
|
|
2738
2852
|
const showSavings = bundle.widgetConfig.savingsBar.visible && savings > 0;
|
|
2739
2853
|
const badge = percent === 100 ? "Free" : `${percent}% off`;
|
|
2740
|
-
return /* @__PURE__ */ (0,
|
|
2854
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
2741
2855
|
"div",
|
|
2742
2856
|
{
|
|
2743
2857
|
ref: (el) => {
|
|
@@ -2748,12 +2862,19 @@ function BogoBundle(props) {
|
|
|
2748
2862
|
role: "region",
|
|
2749
2863
|
"aria-label": bundle.title,
|
|
2750
2864
|
children: [
|
|
2751
|
-
/* @__PURE__ */ (0,
|
|
2752
|
-
/* @__PURE__ */ (0,
|
|
2753
|
-
bundle.description && /* @__PURE__ */ (0,
|
|
2865
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "lb-bundle-header", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "lb-bundle-header__content", children: [
|
|
2866
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h3", { className: "lb-bundle-title", children: bundle.title }),
|
|
2867
|
+
bundle.description && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "lb-bundle-subtitle", children: bundle.description })
|
|
2754
2868
|
] }) }),
|
|
2755
|
-
/* @__PURE__ */ (0,
|
|
2756
|
-
|
|
2869
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2870
|
+
BundleCountdown,
|
|
2871
|
+
{
|
|
2872
|
+
endsAt: bundle.endsAt,
|
|
2873
|
+
widgetConfig: bundle.widgetConfig
|
|
2874
|
+
}
|
|
2875
|
+
),
|
|
2876
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "lb-bundle__products", children: [
|
|
2877
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2757
2878
|
BogoProductRow,
|
|
2758
2879
|
{
|
|
2759
2880
|
side: "buy",
|
|
@@ -2765,11 +2886,11 @@ function BogoBundle(props) {
|
|
|
2765
2886
|
onVariantChange: handleVariantChange
|
|
2766
2887
|
}
|
|
2767
2888
|
),
|
|
2768
|
-
/* @__PURE__ */ (0,
|
|
2769
|
-
/* @__PURE__ */ (0,
|
|
2770
|
-
/* @__PURE__ */ (0,
|
|
2889
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "lb-bogo__plus", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("svg", { width: "12", height: "12", viewBox: "0 0 18 18", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
|
|
2890
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("line", { x1: "9", y1: "3", x2: "9", y2: "15", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }),
|
|
2891
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("line", { x1: "3", y1: "9", x2: "15", y2: "9", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" })
|
|
2771
2892
|
] }) }),
|
|
2772
|
-
/* @__PURE__ */ (0,
|
|
2893
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2773
2894
|
BogoProductRow,
|
|
2774
2895
|
{
|
|
2775
2896
|
side: "get",
|
|
@@ -2782,29 +2903,29 @@ function BogoBundle(props) {
|
|
|
2782
2903
|
}
|
|
2783
2904
|
)
|
|
2784
2905
|
] }),
|
|
2785
|
-
/* @__PURE__ */ (0,
|
|
2786
|
-
/* @__PURE__ */ (0,
|
|
2787
|
-
/* @__PURE__ */ (0,
|
|
2788
|
-
/* @__PURE__ */ (0,
|
|
2789
|
-
showSavings && /* @__PURE__ */ (0,
|
|
2906
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "lb-bundle-divider" }),
|
|
2907
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "lb-bundle-summary", children: [
|
|
2908
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "lb-bundle-summary__text", children: [
|
|
2909
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "lb-bundle-summary__label", children: "Bundle total" }),
|
|
2910
|
+
showSavings && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("p", { className: "lb-bundle-savings-line", "data-savings-bar": true, children: [
|
|
2790
2911
|
"You save",
|
|
2791
2912
|
" ",
|
|
2792
|
-
/* @__PURE__ */ (0,
|
|
2913
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { "data-savings-amount": true, children: (0, import_core13.formatMoney)(savings, currency) }),
|
|
2793
2914
|
" ",
|
|
2794
|
-
/* @__PURE__ */ (0,
|
|
2915
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { "data-savings-percent": true, children: [
|
|
2795
2916
|
"(",
|
|
2796
2917
|
savingsPercent,
|
|
2797
2918
|
"%)"
|
|
2798
2919
|
] })
|
|
2799
2920
|
] })
|
|
2800
2921
|
] }),
|
|
2801
|
-
/* @__PURE__ */ (0,
|
|
2802
|
-
showCompare && /* @__PURE__ */ (0,
|
|
2803
|
-
/* @__PURE__ */ (0,
|
|
2922
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "lb-bundle-summary__prices", children: [
|
|
2923
|
+
showCompare && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "lb-bundle-compare-price", "data-compare-price": true, children: (0, import_core13.formatMoney)(comparePrice, currency) }),
|
|
2924
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "lb-bundle-sale-price", "data-sale-price": true, children: (0, import_core13.formatMoney)(salePrice, currency) })
|
|
2804
2925
|
] })
|
|
2805
2926
|
] }),
|
|
2806
|
-
cartError && /* @__PURE__ */ (0,
|
|
2807
|
-
/* @__PURE__ */ (0,
|
|
2927
|
+
cartError && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "lb-bundle__error", role: "alert", children: cartError }),
|
|
2928
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2808
2929
|
"button",
|
|
2809
2930
|
{
|
|
2810
2931
|
className: "lb-bundle__cta",
|
|
@@ -2820,7 +2941,7 @@ function BogoBundle(props) {
|
|
|
2820
2941
|
}
|
|
2821
2942
|
function BogoProductRow({ side, product, quantity, percent, badge, currency, onVariantChange }) {
|
|
2822
2943
|
const variants = product.variants.nodes;
|
|
2823
|
-
const optionNames = (0,
|
|
2944
|
+
const optionNames = (0, import_react15.useMemo)(() => {
|
|
2824
2945
|
const first = variants[0];
|
|
2825
2946
|
return first ? first.selectedOptions.map((o) => o.name) : [];
|
|
2826
2947
|
}, [variants]);
|
|
@@ -2829,7 +2950,7 @@ function BogoProductRow({ side, product, quantity, percent, badge, currency, onV
|
|
|
2829
2950
|
variants,
|
|
2830
2951
|
optionNames
|
|
2831
2952
|
});
|
|
2832
|
-
(0,
|
|
2953
|
+
(0, import_react15.useEffect)(() => {
|
|
2833
2954
|
onVariantChange(side, selectedVariant ?? null);
|
|
2834
2955
|
}, [selectedVariant, side, onVariantChange]);
|
|
2835
2956
|
const displayVariant = selectedVariant ?? variants.find((v) => (0, import_core13.isVariantFulfillable)(v, quantity)) ?? variants[0];
|
|
@@ -2843,8 +2964,8 @@ function BogoProductRow({ side, product, quantity, percent, badge, currency, onV
|
|
|
2843
2964
|
currency
|
|
2844
2965
|
) : null;
|
|
2845
2966
|
const thumbImage = displayVariant?.image ?? product.featuredImage;
|
|
2846
|
-
return /* @__PURE__ */ (0,
|
|
2847
|
-
thumbImage && /* @__PURE__ */ (0,
|
|
2967
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "lb-bundle-product-row", part: "product", "data-bogo-role": side, children: [
|
|
2968
|
+
thumbImage && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2848
2969
|
"img",
|
|
2849
2970
|
{
|
|
2850
2971
|
src: thumbImage.url,
|
|
@@ -2853,11 +2974,11 @@ function BogoProductRow({ side, product, quantity, percent, badge, currency, onV
|
|
|
2853
2974
|
loading: "lazy"
|
|
2854
2975
|
}
|
|
2855
2976
|
),
|
|
2856
|
-
/* @__PURE__ */ (0,
|
|
2857
|
-
/* @__PURE__ */ (0,
|
|
2858
|
-
!showPicker && displayVariant && variants.length > 1 && /* @__PURE__ */ (0,
|
|
2859
|
-
/* @__PURE__ */ (0,
|
|
2860
|
-
compareAt && /* @__PURE__ */ (0,
|
|
2977
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "lb-bundle__product-info", children: [
|
|
2978
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "lb-bundle__product-title", children: product.title }),
|
|
2979
|
+
!showPicker && displayVariant && variants.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "lb-bundle-variant-badge", children: displayVariant.title }),
|
|
2980
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "lb-bundle-product-prices", children: [
|
|
2981
|
+
compareAt && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2861
2982
|
"span",
|
|
2862
2983
|
{
|
|
2863
2984
|
className: "lb-bundle-product-compare-price",
|
|
@@ -2865,13 +2986,13 @@ function BogoProductRow({ side, product, quantity, percent, badge, currency, onV
|
|
|
2865
2986
|
children: compareAt
|
|
2866
2987
|
}
|
|
2867
2988
|
),
|
|
2868
|
-
/* @__PURE__ */ (0,
|
|
2869
|
-
/* @__PURE__ */ (0,
|
|
2989
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "lb-bundle__product-price", "data-product-price": true, children: priceText }),
|
|
2990
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "lb-bundle-qty-inline", "data-qty-inline": true, children: [
|
|
2870
2991
|
"\xD7",
|
|
2871
2992
|
quantity
|
|
2872
2993
|
] })
|
|
2873
2994
|
] }),
|
|
2874
|
-
unitPriceText && /* @__PURE__ */ (0,
|
|
2995
|
+
unitPriceText && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2875
2996
|
"span",
|
|
2876
2997
|
{
|
|
2877
2998
|
className: "lb-bundle__product-unit-price",
|
|
@@ -2879,13 +3000,13 @@ function BogoProductRow({ side, product, quantity, percent, badge, currency, onV
|
|
|
2879
3000
|
children: unitPriceText
|
|
2880
3001
|
}
|
|
2881
3002
|
),
|
|
2882
|
-
showPicker && /* @__PURE__ */ (0,
|
|
3003
|
+
showPicker && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "lb-bundle__product-variant-pickers", children: optionNames.map((optionName, optionIndex) => {
|
|
2883
3004
|
const dropdownOptions = optionsFor(optionIndex).map((o) => ({
|
|
2884
3005
|
value: o.value,
|
|
2885
3006
|
label: o.value,
|
|
2886
3007
|
disabled: o.disabled
|
|
2887
3008
|
}));
|
|
2888
|
-
return /* @__PURE__ */ (0,
|
|
3009
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
2889
3010
|
VariantDropdown,
|
|
2890
3011
|
{
|
|
2891
3012
|
options: dropdownOptions,
|
|
@@ -2897,19 +3018,19 @@ function BogoProductRow({ side, product, quantity, percent, badge, currency, onV
|
|
|
2897
3018
|
);
|
|
2898
3019
|
}) })
|
|
2899
3020
|
] }),
|
|
2900
|
-
badge && /* @__PURE__ */ (0,
|
|
3021
|
+
badge && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "lb-bogo__badge", children: badge })
|
|
2901
3022
|
] });
|
|
2902
3023
|
}
|
|
2903
3024
|
|
|
2904
3025
|
// src/components/MultiStepBundle.tsx
|
|
2905
|
-
var
|
|
3026
|
+
var import_react17 = require("react");
|
|
2906
3027
|
var import_core15 = require("@lime-bundles/core");
|
|
2907
3028
|
|
|
2908
3029
|
// src/components/MultiStepPicker.tsx
|
|
2909
|
-
var
|
|
3030
|
+
var import_react16 = require("react");
|
|
2910
3031
|
var import_react_dom2 = require("react-dom");
|
|
2911
3032
|
var import_core14 = require("@lime-bundles/core");
|
|
2912
|
-
var
|
|
3033
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
2913
3034
|
function ruleFor3(bundle, productId, variantId) {
|
|
2914
3035
|
if (variantId) {
|
|
2915
3036
|
const vRule = bundle.variantRules[variantId];
|
|
@@ -2963,17 +3084,17 @@ function MultiStepPicker({
|
|
|
2963
3084
|
}) {
|
|
2964
3085
|
const wc = bundle.widgetConfig;
|
|
2965
3086
|
const steps = bundle.steps;
|
|
2966
|
-
const overlayRef = (0,
|
|
2967
|
-
const dialogRef = (0,
|
|
2968
|
-
const titleRef = (0,
|
|
2969
|
-
const mouseDownTarget = (0,
|
|
2970
|
-
const [open, setOpen] = (0,
|
|
2971
|
-
const [stepIndex, setStepIndex] = (0,
|
|
3087
|
+
const overlayRef = (0, import_react16.useRef)(null);
|
|
3088
|
+
const dialogRef = (0, import_react16.useRef)(null);
|
|
3089
|
+
const titleRef = (0, import_react16.useRef)(null);
|
|
3090
|
+
const mouseDownTarget = (0, import_react16.useRef)(null);
|
|
3091
|
+
const [open, setOpen] = (0, import_react16.useState)(false);
|
|
3092
|
+
const [stepIndex, setStepIndex] = (0, import_react16.useState)(
|
|
2972
3093
|
() => Math.max(0, Math.min(steps.length - 1, initialStep))
|
|
2973
3094
|
);
|
|
2974
|
-
const [query, setQuery] = (0,
|
|
2975
|
-
const [activeType, setActiveType] = (0,
|
|
2976
|
-
const [announcement, setAnnouncement] = (0,
|
|
3095
|
+
const [query, setQuery] = (0, import_react16.useState)("");
|
|
3096
|
+
const [activeType, setActiveType] = (0, import_react16.useState)(FILTERS_ALL2);
|
|
3097
|
+
const [announcement, setAnnouncement] = (0, import_react16.useState)("");
|
|
2977
3098
|
const step = steps[stepIndex];
|
|
2978
3099
|
const stepMin = step?.minQuantity ?? 1;
|
|
2979
3100
|
const stepPicks = selections[stepIndex] ?? [];
|
|
@@ -2981,11 +3102,11 @@ function MultiStepPicker({
|
|
|
2981
3102
|
const stepIsSatisfied = unitsInStep >= stepMin;
|
|
2982
3103
|
const isLastStep = stepIndex === steps.length - 1;
|
|
2983
3104
|
const shownUnits = Math.min(unitsInStep, stepMin);
|
|
2984
|
-
const eligible = (0,
|
|
3105
|
+
const eligible = (0, import_react16.useMemo)(
|
|
2985
3106
|
() => buildEligibleProducts2(bundle, stepIndex, outOfStockBehavior),
|
|
2986
3107
|
[bundle, stepIndex, outOfStockBehavior]
|
|
2987
3108
|
);
|
|
2988
|
-
const productTypes = (0,
|
|
3109
|
+
const productTypes = (0, import_react16.useMemo)(() => {
|
|
2989
3110
|
const types = [];
|
|
2990
3111
|
const seen = /* @__PURE__ */ new Set();
|
|
2991
3112
|
for (const ep of eligible) {
|
|
@@ -2998,7 +3119,7 @@ function MultiStepPicker({
|
|
|
2998
3119
|
return types;
|
|
2999
3120
|
}, [eligible]);
|
|
3000
3121
|
const showFilters = wc.mixMatchShowTypeFilters && productTypes.length >= 2;
|
|
3001
|
-
(0,
|
|
3122
|
+
(0, import_react16.useEffect)(() => {
|
|
3002
3123
|
const id = requestAnimationFrame(() => setOpen(true));
|
|
3003
3124
|
return () => cancelAnimationFrame(id);
|
|
3004
3125
|
}, []);
|
|
@@ -3022,7 +3143,7 @@ function MultiStepPicker({
|
|
|
3022
3143
|
titleRef.current?.focus();
|
|
3023
3144
|
}
|
|
3024
3145
|
const subtitle = `Step ${stepIndex + 1} of ${steps.length} \xB7 ${step?.name ?? ""}`;
|
|
3025
|
-
const filtered = (0,
|
|
3146
|
+
const filtered = (0, import_react16.useMemo)(() => {
|
|
3026
3147
|
const nq = normalizeText2(query.trim());
|
|
3027
3148
|
return eligible.filter((ep) => {
|
|
3028
3149
|
const matchesQuery = !nq || normalizeText2(ep.product.title).includes(nq);
|
|
@@ -3047,7 +3168,7 @@ function MultiStepPicker({
|
|
|
3047
3168
|
// inside carries the interactive role + focus trap. So the static-element
|
|
3048
3169
|
// interaction lint does not apply to this backdrop.
|
|
3049
3170
|
// eslint-disable-next-line jsx-a11y/no-static-element-interactions
|
|
3050
|
-
/* @__PURE__ */ (0,
|
|
3171
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3051
3172
|
"div",
|
|
3052
3173
|
{
|
|
3053
3174
|
ref: (el) => {
|
|
@@ -3059,7 +3180,7 @@ function MultiStepPicker({
|
|
|
3059
3180
|
"data-bundle-gid": bundle.id,
|
|
3060
3181
|
onMouseDown: onOverlayMouseDown,
|
|
3061
3182
|
onMouseUp: onOverlayMouseUp,
|
|
3062
|
-
children: /* @__PURE__ */ (0,
|
|
3183
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
3063
3184
|
"div",
|
|
3064
3185
|
{
|
|
3065
3186
|
ref: dialogRef,
|
|
@@ -3069,10 +3190,10 @@ function MultiStepPicker({
|
|
|
3069
3190
|
"aria-labelledby": titleId,
|
|
3070
3191
|
tabIndex: -1,
|
|
3071
3192
|
children: [
|
|
3072
|
-
/* @__PURE__ */ (0,
|
|
3073
|
-
/* @__PURE__ */ (0,
|
|
3074
|
-
/* @__PURE__ */ (0,
|
|
3075
|
-
/* @__PURE__ */ (0,
|
|
3193
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "lb-mix-match__modal-header", children: [
|
|
3194
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "lb-mix-match__modal-header-top", children: [
|
|
3195
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "lb-mix-match__modal-heading", children: [
|
|
3196
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3076
3197
|
"h4",
|
|
3077
3198
|
{
|
|
3078
3199
|
className: "lb-mix-match__modal-title",
|
|
@@ -3082,9 +3203,9 @@ function MultiStepPicker({
|
|
|
3082
3203
|
children: "Add to your bundle"
|
|
3083
3204
|
}
|
|
3084
3205
|
),
|
|
3085
|
-
/* @__PURE__ */ (0,
|
|
3206
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "lb-mix-match__modal-subtitle", "data-modal-subtitle": true, children: subtitle })
|
|
3086
3207
|
] }),
|
|
3087
|
-
/* @__PURE__ */ (0,
|
|
3208
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3088
3209
|
"button",
|
|
3089
3210
|
{
|
|
3090
3211
|
type: "button",
|
|
@@ -3092,16 +3213,16 @@ function MultiStepPicker({
|
|
|
3092
3213
|
"data-modal-close": true,
|
|
3093
3214
|
"aria-label": "Close",
|
|
3094
3215
|
onClick: onClose,
|
|
3095
|
-
children: /* @__PURE__ */ (0,
|
|
3216
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CloseIcon3, {})
|
|
3096
3217
|
}
|
|
3097
3218
|
)
|
|
3098
3219
|
] }),
|
|
3099
|
-
/* @__PURE__ */ (0,
|
|
3220
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3100
3221
|
"div",
|
|
3101
3222
|
{
|
|
3102
3223
|
className: "lb-mix-match__progress lb-mix-match__modal-progress",
|
|
3103
3224
|
"data-progress": true,
|
|
3104
|
-
children: /* @__PURE__ */ (0,
|
|
3225
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3105
3226
|
"div",
|
|
3106
3227
|
{
|
|
3107
3228
|
className: "lb-mix-match__progress-segments",
|
|
@@ -3110,7 +3231,7 @@ function MultiStepPicker({
|
|
|
3110
3231
|
"aria-valuenow": shownUnits,
|
|
3111
3232
|
"aria-valuemin": 0,
|
|
3112
3233
|
"aria-valuemax": stepMin,
|
|
3113
|
-
children: Array.from({ length: stepMin }).map((_, i) => /* @__PURE__ */ (0,
|
|
3234
|
+
children: Array.from({ length: stepMin }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3114
3235
|
"span",
|
|
3115
3236
|
{
|
|
3116
3237
|
className: `lb-mix-match__progress-segment${i < shownUnits ? " lb-mix-match__progress-segment--filled" : ""}`,
|
|
@@ -3123,8 +3244,8 @@ function MultiStepPicker({
|
|
|
3123
3244
|
}
|
|
3124
3245
|
)
|
|
3125
3246
|
] }),
|
|
3126
|
-
wc.showSearch && /* @__PURE__ */ (0,
|
|
3127
|
-
/* @__PURE__ */ (0,
|
|
3247
|
+
wc.showSearch && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "lb-mix-match__modal-search", children: [
|
|
3248
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3128
3249
|
"input",
|
|
3129
3250
|
{
|
|
3130
3251
|
type: "text",
|
|
@@ -3138,7 +3259,7 @@ function MultiStepPicker({
|
|
|
3138
3259
|
onChange: (e) => setQuery(e.target.value)
|
|
3139
3260
|
}
|
|
3140
3261
|
),
|
|
3141
|
-
query.length > 0 && /* @__PURE__ */ (0,
|
|
3262
|
+
query.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3142
3263
|
"button",
|
|
3143
3264
|
{
|
|
3144
3265
|
type: "button",
|
|
@@ -3146,11 +3267,11 @@ function MultiStepPicker({
|
|
|
3146
3267
|
"data-modal-search-clear": true,
|
|
3147
3268
|
"aria-label": "Clear search",
|
|
3148
3269
|
onClick: () => setQuery(""),
|
|
3149
|
-
children: /* @__PURE__ */ (0,
|
|
3270
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(SearchClearIcon2, {})
|
|
3150
3271
|
}
|
|
3151
3272
|
)
|
|
3152
3273
|
] }),
|
|
3153
|
-
showFilters && /* @__PURE__ */ (0,
|
|
3274
|
+
showFilters && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3154
3275
|
"div",
|
|
3155
3276
|
{
|
|
3156
3277
|
className: "lb-mix-match__filters",
|
|
@@ -3159,7 +3280,7 @@ function MultiStepPicker({
|
|
|
3159
3280
|
"aria-label": "Filter by product type",
|
|
3160
3281
|
children: [FILTERS_ALL2, ...productTypes].map((value) => {
|
|
3161
3282
|
const isActive = value === activeType;
|
|
3162
|
-
return /* @__PURE__ */ (0,
|
|
3283
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3163
3284
|
"button",
|
|
3164
3285
|
{
|
|
3165
3286
|
type: "button",
|
|
@@ -3174,7 +3295,7 @@ function MultiStepPicker({
|
|
|
3174
3295
|
})
|
|
3175
3296
|
}
|
|
3176
3297
|
),
|
|
3177
|
-
/* @__PURE__ */ (0,
|
|
3298
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "lb-mix-match__modal-list", "data-modal-list": true, children: filtered.map((ep) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3178
3299
|
MultiStepPickerRow,
|
|
3179
3300
|
{
|
|
3180
3301
|
bundle,
|
|
@@ -3192,10 +3313,10 @@ function MultiStepPicker({
|
|
|
3192
3313
|
},
|
|
3193
3314
|
`${stepIndex}:${ep.product.id}`
|
|
3194
3315
|
)) }),
|
|
3195
|
-
showEmpty && /* @__PURE__ */ (0,
|
|
3196
|
-
/* @__PURE__ */ (0,
|
|
3197
|
-
/* @__PURE__ */ (0,
|
|
3198
|
-
stepIndex > 0 && /* @__PURE__ */ (0,
|
|
3316
|
+
showEmpty && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "lb-mix-match__modal-empty", "data-modal-empty": true, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { children: "No products match your search" }) }),
|
|
3317
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { "data-modal-live": true, "aria-live": "polite", className: "lb-visually-hidden", children: announcement || (query.trim() ? `${filtered.length} products shown` : "") }),
|
|
3318
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "lb-mix-match__modal-footer lb-multi-step__modal-footer", children: [
|
|
3319
|
+
stepIndex > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3199
3320
|
"button",
|
|
3200
3321
|
{
|
|
3201
3322
|
type: "button",
|
|
@@ -3205,7 +3326,7 @@ function MultiStepPicker({
|
|
|
3205
3326
|
children: "Back"
|
|
3206
3327
|
}
|
|
3207
3328
|
),
|
|
3208
|
-
/* @__PURE__ */ (0,
|
|
3329
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3209
3330
|
"span",
|
|
3210
3331
|
{
|
|
3211
3332
|
className: "lb-mix-match__modal-footer-count",
|
|
@@ -3214,7 +3335,7 @@ function MultiStepPicker({
|
|
|
3214
3335
|
children: `${shownUnits} of ${stepMin} added`
|
|
3215
3336
|
}
|
|
3216
3337
|
),
|
|
3217
|
-
!isLastStep && /* @__PURE__ */ (0,
|
|
3338
|
+
!isLastStep && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3218
3339
|
"button",
|
|
3219
3340
|
{
|
|
3220
3341
|
type: "button",
|
|
@@ -3227,7 +3348,7 @@ function MultiStepPicker({
|
|
|
3227
3348
|
children: "Next"
|
|
3228
3349
|
}
|
|
3229
3350
|
),
|
|
3230
|
-
isLastStep && /* @__PURE__ */ (0,
|
|
3351
|
+
isLastStep && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3231
3352
|
"button",
|
|
3232
3353
|
{
|
|
3233
3354
|
type: "button",
|
|
@@ -3265,7 +3386,7 @@ function MultiStepPickerRow({
|
|
|
3265
3386
|
const { product, variants, isOos } = eligible;
|
|
3266
3387
|
const rule = ruleFor3(bundle, product.id);
|
|
3267
3388
|
const step = bundle.steps[stepIndex];
|
|
3268
|
-
const optionNames = (0,
|
|
3389
|
+
const optionNames = (0, import_react16.useMemo)(() => {
|
|
3269
3390
|
const first = variants[0];
|
|
3270
3391
|
return first ? first.selectedOptions.map((o) => o.name) : [];
|
|
3271
3392
|
}, [variants]);
|
|
@@ -3274,18 +3395,18 @@ function MultiStepPickerRow({
|
|
|
3274
3395
|
const currentVariant = selectedVariant ?? variants.find((v) => (0, import_core14.isVariantFulfillable)(v, rule.min)) ?? eligible.firstAvailableVariant ?? variants[0] ?? null;
|
|
3275
3396
|
const vRule = ruleFor3(bundle, product.id, currentVariant?.id);
|
|
3276
3397
|
const variantMax = variantRuleFor3(bundle, currentVariant?.id)?.max;
|
|
3277
|
-
const stepPicks = (0,
|
|
3398
|
+
const stepPicks = (0, import_react16.useMemo)(
|
|
3278
3399
|
() => selections[stepIndex] ?? [],
|
|
3279
3400
|
[selections, stepIndex]
|
|
3280
3401
|
);
|
|
3281
3402
|
const unitsInStep = stepPicks.reduce((sum, s) => sum + s.quantity, 0);
|
|
3282
|
-
const committedSelection = (0,
|
|
3403
|
+
const committedSelection = (0, import_react16.useMemo)(
|
|
3283
3404
|
() => currentVariant ? stepPicks.find((s) => s.variantId === currentVariant.id) ?? null : null,
|
|
3284
3405
|
[stepPicks, currentVariant]
|
|
3285
3406
|
);
|
|
3286
3407
|
const variantInStep = committedSelection !== null;
|
|
3287
3408
|
const committedQty = committedSelection?.quantity ?? 0;
|
|
3288
|
-
const productOtherUnits = (0,
|
|
3409
|
+
const productOtherUnits = (0, import_react16.useMemo)(() => {
|
|
3289
3410
|
if (!currentVariant) return 0;
|
|
3290
3411
|
let sum = 0;
|
|
3291
3412
|
for (let i = 0; i < selections.length; i++) {
|
|
@@ -3297,7 +3418,7 @@ function MultiStepPickerRow({
|
|
|
3297
3418
|
}
|
|
3298
3419
|
return sum;
|
|
3299
3420
|
}, [selections, product.id, currentVariant, stepIndex]);
|
|
3300
|
-
const variantOtherUnits = (0,
|
|
3421
|
+
const variantOtherUnits = (0, import_react16.useMemo)(() => {
|
|
3301
3422
|
if (!currentVariant) return 0;
|
|
3302
3423
|
let sum = 0;
|
|
3303
3424
|
for (const picks of selections) {
|
|
@@ -3321,12 +3442,12 @@ function MultiStepPickerRow({
|
|
|
3321
3442
|
const stockRemaining = currentVariant ? (0, import_core14.maxAddableQuantity)(currentVariant, Number.MAX_SAFE_INTEGER, variantOtherUnits) : 0;
|
|
3322
3443
|
const cap = Math.max(0, Math.min(spotCeiling, stockRemaining));
|
|
3323
3444
|
const stepperMax = Math.max(vRule.min, cap);
|
|
3324
|
-
const [qty, setQty] = (0,
|
|
3325
|
-
(0,
|
|
3445
|
+
const [qty, setQty] = (0, import_react16.useState)(vRule.min);
|
|
3446
|
+
(0, import_react16.useEffect)(() => {
|
|
3326
3447
|
setQty((prev) => Math.max(vRule.min, Math.min(prev, stepperMax)));
|
|
3327
3448
|
}, [stepperMax, vRule.min]);
|
|
3328
3449
|
const currentVariantId = currentVariant?.id ?? null;
|
|
3329
|
-
(0,
|
|
3450
|
+
(0, import_react16.useEffect)(() => {
|
|
3330
3451
|
if (!variantInStep) setQty(vRule.min);
|
|
3331
3452
|
}, [variantInStep, currentVariantId, vRule.min]);
|
|
3332
3453
|
if (!currentVariant || !step) return null;
|
|
@@ -3370,7 +3491,7 @@ function MultiStepPickerRow({
|
|
|
3370
3491
|
}
|
|
3371
3492
|
const priceCents = parseFloat(currentVariant.price.amount);
|
|
3372
3493
|
const compareCents = currentVariant.compareAtPrice ? parseFloat(currentVariant.compareAtPrice.amount) : null;
|
|
3373
|
-
return /* @__PURE__ */ (0,
|
|
3494
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
3374
3495
|
"div",
|
|
3375
3496
|
{
|
|
3376
3497
|
className: `lb-mix-match__modal-product${isOos ? " lb-mix-match__modal-product--sold-out" : ""}${variantInStep ? " lb-mix-match__modal-product--in-bundle" : ""}`,
|
|
@@ -3379,8 +3500,8 @@ function MultiStepPickerRow({
|
|
|
3379
3500
|
"data-type": product.productType ?? "",
|
|
3380
3501
|
"aria-disabled": isOos || void 0,
|
|
3381
3502
|
children: [
|
|
3382
|
-
/* @__PURE__ */ (0,
|
|
3383
|
-
thumbImage && /* @__PURE__ */ (0,
|
|
3503
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "lb-mix-match__modal-product-thumb", children: [
|
|
3504
|
+
thumbImage && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3384
3505
|
"img",
|
|
3385
3506
|
{
|
|
3386
3507
|
src: thumbImage.url,
|
|
@@ -3388,10 +3509,10 @@ function MultiStepPickerRow({
|
|
|
3388
3509
|
loading: "lazy"
|
|
3389
3510
|
}
|
|
3390
3511
|
),
|
|
3391
|
-
variantInStep && /* @__PURE__ */ (0,
|
|
3512
|
+
variantInStep && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "lb-mix-match__modal-added-badge", children: "Added" })
|
|
3392
3513
|
] }),
|
|
3393
|
-
/* @__PURE__ */ (0,
|
|
3394
|
-
/* @__PURE__ */ (0,
|
|
3514
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "lb-mix-match__modal-product-info", children: [
|
|
3515
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "lb-mix-match__modal-product-title", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3395
3516
|
"a",
|
|
3396
3517
|
{
|
|
3397
3518
|
href: `/products/${product.handle}`,
|
|
@@ -3400,24 +3521,24 @@ function MultiStepPickerRow({
|
|
|
3400
3521
|
children: product.title
|
|
3401
3522
|
}
|
|
3402
3523
|
) }),
|
|
3403
|
-
/* @__PURE__ */ (0,
|
|
3404
|
-
/* @__PURE__ */ (0,
|
|
3405
|
-
compareCents !== null && compareCents > priceCents && /* @__PURE__ */ (0,
|
|
3524
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("p", { className: "lb-mix-match__modal-product-price", children: [
|
|
3525
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { "data-row-price-sale": true, children: (0, import_core14.formatMoney)(priceCents, currency) }),
|
|
3526
|
+
compareCents !== null && compareCents > priceCents && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("s", { className: "lb-mix-match__modal-product-compare", "data-row-compare": true, children: (0, import_core14.formatMoney)(compareCents, currency) })
|
|
3406
3527
|
] }),
|
|
3407
|
-
unitPriceText && /* @__PURE__ */ (0,
|
|
3408
|
-
showPicker && /* @__PURE__ */ (0,
|
|
3528
|
+
unitPriceText && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "lb-mix-match__modal-product-unit-price lb-bundle-product-unit-price", children: unitPriceText }),
|
|
3529
|
+
showPicker && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "lb-bundle-variant-option-groups", children: optionNames.map((optionName, optionIndex) => {
|
|
3409
3530
|
const dropdownOptions = optionsFor(optionIndex).map((o) => ({
|
|
3410
3531
|
value: o.value,
|
|
3411
3532
|
label: o.value,
|
|
3412
3533
|
disabled: o.disabled
|
|
3413
3534
|
}));
|
|
3414
|
-
return /* @__PURE__ */ (0,
|
|
3535
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
3415
3536
|
"div",
|
|
3416
3537
|
{
|
|
3417
3538
|
className: "lb-bundle-variant-option-group",
|
|
3418
3539
|
children: [
|
|
3419
|
-
/* @__PURE__ */ (0,
|
|
3420
|
-
/* @__PURE__ */ (0,
|
|
3540
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "lb-bundle-variant-option-label", children: optionName }),
|
|
3541
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3421
3542
|
VariantDropdown,
|
|
3422
3543
|
{
|
|
3423
3544
|
className: "lb-mix-match__variant-select-dropdown",
|
|
@@ -3432,17 +3553,17 @@ function MultiStepPickerRow({
|
|
|
3432
3553
|
optionName
|
|
3433
3554
|
);
|
|
3434
3555
|
}) }),
|
|
3435
|
-
!showPicker && variants.length === 1 && currentVariant.title !== "Default Title" && /* @__PURE__ */ (0,
|
|
3436
|
-
!isOos && needsMoreSpots && room > 0 && /* @__PURE__ */ (0,
|
|
3437
|
-
isOos ? /* @__PURE__ */ (0,
|
|
3438
|
-
showStepper && /* @__PURE__ */ (0,
|
|
3556
|
+
!showPicker && variants.length === 1 && currentVariant.title !== "Default Title" && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "lb-mix-match__filled-variant", children: currentVariant.title }),
|
|
3557
|
+
!isOos && needsMoreSpots && room > 0 && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "lb-mix-match__modal-needs-spots", children: vRule.min === 1 ? "Needs 1 spot" : `Needs ${vRule.min} spots` }),
|
|
3558
|
+
isOos ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "lb-mix-match__modal-sold-out-label", children: "Sold out" }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "lb-mix-match__modal-product-actions", children: [
|
|
3559
|
+
showStepper && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "lb-bundle-variant-option-group lb-mix-match__qty-stepper-group", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
3439
3560
|
"div",
|
|
3440
3561
|
{
|
|
3441
3562
|
className: "lb-mix-match__qty-stepper",
|
|
3442
3563
|
role: "group",
|
|
3443
3564
|
"aria-label": "Quantity",
|
|
3444
3565
|
children: [
|
|
3445
|
-
/* @__PURE__ */ (0,
|
|
3566
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3446
3567
|
"button",
|
|
3447
3568
|
{
|
|
3448
3569
|
type: "button",
|
|
@@ -3464,7 +3585,7 @@ function MultiStepPickerRow({
|
|
|
3464
3585
|
children: "\u2212"
|
|
3465
3586
|
}
|
|
3466
3587
|
),
|
|
3467
|
-
/* @__PURE__ */ (0,
|
|
3588
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3468
3589
|
"span",
|
|
3469
3590
|
{
|
|
3470
3591
|
className: "lb-mix-match__qty-stepper-value",
|
|
@@ -3473,7 +3594,7 @@ function MultiStepPickerRow({
|
|
|
3473
3594
|
children: shownQty
|
|
3474
3595
|
}
|
|
3475
3596
|
),
|
|
3476
|
-
/* @__PURE__ */ (0,
|
|
3597
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3477
3598
|
"button",
|
|
3478
3599
|
{
|
|
3479
3600
|
type: "button",
|
|
@@ -3498,7 +3619,7 @@ function MultiStepPickerRow({
|
|
|
3498
3619
|
]
|
|
3499
3620
|
}
|
|
3500
3621
|
) }),
|
|
3501
|
-
/* @__PURE__ */ (0,
|
|
3622
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3502
3623
|
"button",
|
|
3503
3624
|
{
|
|
3504
3625
|
type: "button",
|
|
@@ -3517,7 +3638,7 @@ function MultiStepPickerRow({
|
|
|
3517
3638
|
);
|
|
3518
3639
|
}
|
|
3519
3640
|
function CloseIcon3() {
|
|
3520
|
-
return /* @__PURE__ */ (0,
|
|
3641
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
3521
3642
|
"svg",
|
|
3522
3643
|
{
|
|
3523
3644
|
width: "20",
|
|
@@ -3527,14 +3648,14 @@ function CloseIcon3() {
|
|
|
3527
3648
|
xmlns: "http://www.w3.org/2000/svg",
|
|
3528
3649
|
"aria-hidden": "true",
|
|
3529
3650
|
children: [
|
|
3530
|
-
/* @__PURE__ */ (0,
|
|
3531
|
-
/* @__PURE__ */ (0,
|
|
3651
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("line", { x1: "5", y1: "5", x2: "15", y2: "15", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }),
|
|
3652
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)("line", { x1: "15", y1: "5", x2: "5", y2: "15", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" })
|
|
3532
3653
|
]
|
|
3533
3654
|
}
|
|
3534
3655
|
);
|
|
3535
3656
|
}
|
|
3536
3657
|
function SearchClearIcon2() {
|
|
3537
|
-
return /* @__PURE__ */ (0,
|
|
3658
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
3538
3659
|
"svg",
|
|
3539
3660
|
{
|
|
3540
3661
|
width: "16",
|
|
@@ -3543,13 +3664,13 @@ function SearchClearIcon2() {
|
|
|
3543
3664
|
fill: "currentColor",
|
|
3544
3665
|
xmlns: "http://www.w3.org/2000/svg",
|
|
3545
3666
|
"aria-hidden": "true",
|
|
3546
|
-
children: /* @__PURE__ */ (0,
|
|
3667
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("path", { d: "M14.348 5.652a.5.5 0 0 0-.707 0L10 9.293 6.36 5.652a.5.5 0 1 0-.708.707L9.293 10l-3.641 3.641a.5.5 0 0 0 .708.707L10 10.707l3.641 3.641a.5.5 0 0 0 .707-.707L10.707 10l3.641-3.641a.5.5 0 0 0 0-.707z" })
|
|
3547
3668
|
}
|
|
3548
3669
|
);
|
|
3549
3670
|
}
|
|
3550
3671
|
|
|
3551
3672
|
// src/components/MultiStepBundle.tsx
|
|
3552
|
-
var
|
|
3673
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
3553
3674
|
function ruleFor4(bundle, productId, variantId) {
|
|
3554
3675
|
if (variantId) {
|
|
3555
3676
|
const vRule = bundle.variantRules[variantId];
|
|
@@ -3608,14 +3729,14 @@ function MultiStepBundle(props) {
|
|
|
3608
3729
|
bundleType: "multi_step",
|
|
3609
3730
|
enabled: analyticsEnabled !== false
|
|
3610
3731
|
});
|
|
3611
|
-
const [selections, setSelections] = (0,
|
|
3612
|
-
const [pickerOpenAt, setPickerOpenAt] = (0,
|
|
3613
|
-
const [addingToCart, setAddingToCart] = (0,
|
|
3614
|
-
const [cartError, setCartError] = (0,
|
|
3732
|
+
const [selections, setSelections] = (0, import_react17.useState)([]);
|
|
3733
|
+
const [pickerOpenAt, setPickerOpenAt] = (0, import_react17.useState)(null);
|
|
3734
|
+
const [addingToCart, setAddingToCart] = (0, import_react17.useState)(false);
|
|
3735
|
+
const [cartError, setCartError] = (0, import_react17.useState)(null);
|
|
3615
3736
|
const bundle = result.status === "success" && result.bundle.bundleType === "multi_step" ? result.bundle : null;
|
|
3616
3737
|
const setConfigVarsRef = useWidgetConfigVars(bundle?.widgetConfig);
|
|
3617
3738
|
const setModalConfigVarsRef = useWidgetConfigVars(bundle?.widgetConfig);
|
|
3618
|
-
(0,
|
|
3739
|
+
(0, import_react17.useEffect)(() => {
|
|
3619
3740
|
if (result.status === "error") {
|
|
3620
3741
|
onError?.(result.error);
|
|
3621
3742
|
return;
|
|
@@ -3628,8 +3749,8 @@ function MultiStepBundle(props) {
|
|
|
3628
3749
|
);
|
|
3629
3750
|
}
|
|
3630
3751
|
}, [result, onError]);
|
|
3631
|
-
const steps = (0,
|
|
3632
|
-
(0,
|
|
3752
|
+
const steps = (0, import_react17.useMemo)(() => bundle?.steps ?? [], [bundle]);
|
|
3753
|
+
(0, import_react17.useEffect)(() => {
|
|
3633
3754
|
const seeded = steps.map(() => []);
|
|
3634
3755
|
if (bundle) {
|
|
3635
3756
|
const seedCurrency = bundle.products[0]?.priceRange.minVariantPrice.currencyCode ?? "USD";
|
|
@@ -3664,26 +3785,26 @@ function MultiStepBundle(props) {
|
|
|
3664
3785
|
setSelections(seeded);
|
|
3665
3786
|
}, [bundle, steps]);
|
|
3666
3787
|
const showStepper = bundle?.widgetConfig.mixMatchShowQuantitySelector !== false;
|
|
3667
|
-
const totalMin = (0,
|
|
3788
|
+
const totalMin = (0, import_react17.useMemo)(
|
|
3668
3789
|
() => steps.reduce((sum, s) => sum + s.minQuantity, 0),
|
|
3669
3790
|
[steps]
|
|
3670
3791
|
);
|
|
3671
|
-
const unitsByStep = (0,
|
|
3792
|
+
const unitsByStep = (0, import_react17.useMemo)(
|
|
3672
3793
|
() => selections.map((picks) => picks.reduce((sum, s) => sum + s.quantity, 0)),
|
|
3673
3794
|
[selections]
|
|
3674
3795
|
);
|
|
3675
|
-
const totalQuantity = (0,
|
|
3796
|
+
const totalQuantity = (0, import_react17.useMemo)(
|
|
3676
3797
|
() => unitsByStep.reduce((sum, u) => sum + u, 0),
|
|
3677
3798
|
[unitsByStep]
|
|
3678
3799
|
);
|
|
3679
|
-
const stepSatisfied = (0,
|
|
3800
|
+
const stepSatisfied = (0, import_react17.useCallback)(
|
|
3680
3801
|
(i) => (unitsByStep[i] ?? 0) >= (steps[i]?.minQuantity ?? 1),
|
|
3681
3802
|
[unitsByStep, steps]
|
|
3682
3803
|
);
|
|
3683
3804
|
const allSatisfied = steps.length > 0 && steps.every((_, i) => stepSatisfied(i));
|
|
3684
3805
|
const valid = !!bundle && allSatisfied;
|
|
3685
3806
|
const completedSteps = steps.filter((_, i) => stepSatisfied(i)).length;
|
|
3686
|
-
const summary = (0,
|
|
3807
|
+
const summary = (0, import_react17.useMemo)(() => {
|
|
3687
3808
|
let comparePrice = 0;
|
|
3688
3809
|
let salePrice = 0;
|
|
3689
3810
|
for (const stepPicks of selections) {
|
|
@@ -3703,7 +3824,7 @@ function MultiStepBundle(props) {
|
|
|
3703
3824
|
const savingsPercent = comparePrice > 0 && savings > 0 ? Math.round(savings / comparePrice * 100) : 0;
|
|
3704
3825
|
return { comparePrice, salePrice, savings, savingsPercent };
|
|
3705
3826
|
}, [selections, bundle]);
|
|
3706
|
-
const addSelection = (0,
|
|
3827
|
+
const addSelection = (0, import_react17.useCallback)((step, item) => {
|
|
3707
3828
|
setSelections((prev) => {
|
|
3708
3829
|
if (step < 0 || step >= prev.length) return prev;
|
|
3709
3830
|
if (prev[step].some((s) => s.variantId === item.variantId)) return prev;
|
|
@@ -3712,7 +3833,7 @@ function MultiStepBundle(props) {
|
|
|
3712
3833
|
return next;
|
|
3713
3834
|
});
|
|
3714
3835
|
}, []);
|
|
3715
|
-
const swapSelection = (0,
|
|
3836
|
+
const swapSelection = (0, import_react17.useCallback)(
|
|
3716
3837
|
(step, item) => {
|
|
3717
3838
|
setSelections((prev) => {
|
|
3718
3839
|
if (!bundle || step < 0 || step >= prev.length) return prev;
|
|
@@ -3747,7 +3868,7 @@ function MultiStepBundle(props) {
|
|
|
3747
3868
|
},
|
|
3748
3869
|
[bundle]
|
|
3749
3870
|
);
|
|
3750
|
-
const updateQuantity = (0,
|
|
3871
|
+
const updateQuantity = (0, import_react17.useCallback)(
|
|
3751
3872
|
(step, productId, variantId, quantity) => {
|
|
3752
3873
|
setSelections((prev) => {
|
|
3753
3874
|
if (step < 0 || step >= prev.length) return prev;
|
|
@@ -3766,7 +3887,7 @@ function MultiStepBundle(props) {
|
|
|
3766
3887
|
},
|
|
3767
3888
|
[]
|
|
3768
3889
|
);
|
|
3769
|
-
const removeVariant = (0,
|
|
3890
|
+
const removeVariant = (0, import_react17.useCallback)(
|
|
3770
3891
|
(step, variantId) => {
|
|
3771
3892
|
setSelections((prev) => {
|
|
3772
3893
|
if (step < 0 || step >= prev.length) return prev;
|
|
@@ -3782,7 +3903,7 @@ function MultiStepBundle(props) {
|
|
|
3782
3903
|
},
|
|
3783
3904
|
[bundle]
|
|
3784
3905
|
);
|
|
3785
|
-
const removeSlot = (0,
|
|
3906
|
+
const removeSlot = (0, import_react17.useCallback)(
|
|
3786
3907
|
(step, index) => {
|
|
3787
3908
|
setSelections((prev) => {
|
|
3788
3909
|
if (step < 0 || step >= prev.length) return prev;
|
|
@@ -3798,7 +3919,7 @@ function MultiStepBundle(props) {
|
|
|
3798
3919
|
},
|
|
3799
3920
|
[bundle]
|
|
3800
3921
|
);
|
|
3801
|
-
const handleAddToCart = (0,
|
|
3922
|
+
const handleAddToCart = (0, import_react17.useCallback)(async () => {
|
|
3802
3923
|
if (!bundle || !valid) return;
|
|
3803
3924
|
const grouped = /* @__PURE__ */ new Map();
|
|
3804
3925
|
for (const stepPicks of selections) {
|
|
@@ -3839,9 +3960,9 @@ function MultiStepBundle(props) {
|
|
|
3839
3960
|
}
|
|
3840
3961
|
}, [bundle, selections, valid, onAddToCart, onError, trackAddToCart, totalQuantity, steps]);
|
|
3841
3962
|
if (result.status === "loading") {
|
|
3842
|
-
return /* @__PURE__ */ (0,
|
|
3843
|
-
/* @__PURE__ */ (0,
|
|
3844
|
-
/* @__PURE__ */ (0,
|
|
3963
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: `lb-bundle lb-bundle--loading ${className ?? ""}`, children: [
|
|
3964
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "lb-skeleton lb-skeleton--title" }),
|
|
3965
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "lb-skeleton lb-skeleton--products" })
|
|
3845
3966
|
] });
|
|
3846
3967
|
}
|
|
3847
3968
|
if (result.status === "error") return null;
|
|
@@ -3862,7 +3983,7 @@ function MultiStepBundle(props) {
|
|
|
3862
3983
|
if (requiredBlocked) return null;
|
|
3863
3984
|
const currency = bundle.products[0]?.priceRange.minVariantPrice.currencyCode ?? "USD";
|
|
3864
3985
|
const ctaLabel = addingToCart ? "Adding..." : bundle.widgetConfig.cta.ctaText || "Add to cart";
|
|
3865
|
-
return /* @__PURE__ */ (0,
|
|
3986
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
3866
3987
|
"div",
|
|
3867
3988
|
{
|
|
3868
3989
|
ref: (el) => {
|
|
@@ -3874,12 +3995,19 @@ function MultiStepBundle(props) {
|
|
|
3874
3995
|
"aria-label": bundle.title,
|
|
3875
3996
|
"data-required-quantity": totalMin,
|
|
3876
3997
|
children: [
|
|
3877
|
-
/* @__PURE__ */ (0,
|
|
3878
|
-
/* @__PURE__ */ (0,
|
|
3879
|
-
bundle.description && /* @__PURE__ */ (0,
|
|
3998
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "lb-bundle-header", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "lb-bundle-header__content", children: [
|
|
3999
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("h3", { className: "lb-bundle-title", children: bundle.title }),
|
|
4000
|
+
bundle.description && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "lb-bundle-subtitle", children: bundle.description })
|
|
3880
4001
|
] }) }),
|
|
3881
|
-
/* @__PURE__ */ (0,
|
|
3882
|
-
|
|
4002
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4003
|
+
BundleCountdown,
|
|
4004
|
+
{
|
|
4005
|
+
endsAt: bundle.endsAt,
|
|
4006
|
+
widgetConfig: bundle.widgetConfig
|
|
4007
|
+
}
|
|
4008
|
+
),
|
|
4009
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "lb-mix-match__progress", "data-progress": true, children: [
|
|
4010
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3883
4011
|
"div",
|
|
3884
4012
|
{
|
|
3885
4013
|
className: "lb-mix-match__progress-segments",
|
|
@@ -3887,7 +4015,7 @@ function MultiStepBundle(props) {
|
|
|
3887
4015
|
"aria-valuenow": completedSteps,
|
|
3888
4016
|
"aria-valuemin": 0,
|
|
3889
4017
|
"aria-valuemax": steps.length,
|
|
3890
|
-
children: Array.from({ length: steps.length }).map((_, i) => /* @__PURE__ */ (0,
|
|
4018
|
+
children: Array.from({ length: steps.length }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3891
4019
|
"span",
|
|
3892
4020
|
{
|
|
3893
4021
|
className: `lb-mix-match__progress-segment${i < completedSteps ? " lb-mix-match__progress-segment--filled" : ""}`,
|
|
@@ -3897,8 +4025,8 @@ function MultiStepBundle(props) {
|
|
|
3897
4025
|
))
|
|
3898
4026
|
}
|
|
3899
4027
|
),
|
|
3900
|
-
/* @__PURE__ */ (0,
|
|
3901
|
-
/* @__PURE__ */ (0,
|
|
4028
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "lb-mix-match__progress-labels", children: [
|
|
4029
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3902
4030
|
"span",
|
|
3903
4031
|
{
|
|
3904
4032
|
className: "lb-mix-match__progress-count",
|
|
@@ -3907,7 +4035,7 @@ function MultiStepBundle(props) {
|
|
|
3907
4035
|
children: `${completedSteps} of ${steps.length} steps completed`
|
|
3908
4036
|
}
|
|
3909
4037
|
),
|
|
3910
|
-
/* @__PURE__ */ (0,
|
|
4038
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3911
4039
|
"span",
|
|
3912
4040
|
{
|
|
3913
4041
|
className: "lb-mix-match__progress-remaining",
|
|
@@ -3918,15 +4046,15 @@ function MultiStepBundle(props) {
|
|
|
3918
4046
|
)
|
|
3919
4047
|
] })
|
|
3920
4048
|
] }),
|
|
3921
|
-
/* @__PURE__ */ (0,
|
|
4049
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "lb-multi-step__groups", "data-step-groups": true, children: steps.map((step, i) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
3922
4050
|
"section",
|
|
3923
4051
|
{
|
|
3924
4052
|
className: "lb-multi-step__group",
|
|
3925
4053
|
"data-step-group": i,
|
|
3926
4054
|
children: [
|
|
3927
|
-
/* @__PURE__ */ (0,
|
|
3928
|
-
/* @__PURE__ */ (0,
|
|
3929
|
-
/* @__PURE__ */ (0,
|
|
4055
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "lb-multi-step__group-heading", children: [
|
|
4056
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "lb-multi-step__group-name", children: step.name }),
|
|
4057
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3930
4058
|
"span",
|
|
3931
4059
|
{
|
|
3932
4060
|
className: `lb-multi-step__group-count${stepSatisfied(i) ? " lb-multi-step__group-count--met" : ""}`,
|
|
@@ -3935,7 +4063,7 @@ function MultiStepBundle(props) {
|
|
|
3935
4063
|
}
|
|
3936
4064
|
)
|
|
3937
4065
|
] }),
|
|
3938
|
-
/* @__PURE__ */ (0,
|
|
4066
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3939
4067
|
"div",
|
|
3940
4068
|
{
|
|
3941
4069
|
className: "lb-mix-match__slots lb-edge-fade lb-multi-step__group-slots",
|
|
@@ -3945,13 +4073,13 @@ function MultiStepBundle(props) {
|
|
|
3945
4073
|
title button provides the keyboard/AT path (its
|
|
3946
4074
|
activation bubbles here); × stops propagation. */
|
|
3947
4075
|
// eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions -- keyboard path is the inner "Edit selection" title button whose activation bubbles to this handler
|
|
3948
|
-
/* @__PURE__ */ (0,
|
|
4076
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
3949
4077
|
"div",
|
|
3950
4078
|
{
|
|
3951
4079
|
className: "lb-mix-match__slot lb-mix-match__slot--filled",
|
|
3952
4080
|
onClick: () => setPickerOpenAt(i),
|
|
3953
4081
|
children: [
|
|
3954
|
-
item.featuredImage && /* @__PURE__ */ (0,
|
|
4082
|
+
item.featuredImage && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "lb-bundle-thumbnail", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3955
4083
|
"img",
|
|
3956
4084
|
{
|
|
3957
4085
|
src: item.featuredImage,
|
|
@@ -3959,8 +4087,8 @@ function MultiStepBundle(props) {
|
|
|
3959
4087
|
loading: "lazy"
|
|
3960
4088
|
}
|
|
3961
4089
|
) }),
|
|
3962
|
-
/* @__PURE__ */ (0,
|
|
3963
|
-
/* @__PURE__ */ (0,
|
|
4090
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "lb-mix-match__filled-info", children: [
|
|
4091
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3964
4092
|
"button",
|
|
3965
4093
|
{
|
|
3966
4094
|
type: "button",
|
|
@@ -3969,15 +4097,15 @@ function MultiStepBundle(props) {
|
|
|
3969
4097
|
children: item.title
|
|
3970
4098
|
}
|
|
3971
4099
|
),
|
|
3972
|
-
item.variantTitle && item.variantTitle !== "Default Title" && /* @__PURE__ */ (0,
|
|
3973
|
-
/* @__PURE__ */ (0,
|
|
3974
|
-
item.compareAtPrice !== null && item.compareAtPrice > item.price && /* @__PURE__ */ (0,
|
|
3975
|
-
/* @__PURE__ */ (0,
|
|
3976
|
-
/* @__PURE__ */ (0,
|
|
4100
|
+
item.variantTitle && item.variantTitle !== "Default Title" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "lb-mix-match__filled-variant", children: item.variantTitle }),
|
|
4101
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "lb-mix-match__filled-price", children: [
|
|
4102
|
+
item.compareAtPrice !== null && item.compareAtPrice > item.price && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("s", { className: "lb-mix-match__filled-compare", children: (0, import_core15.formatMoney)(item.compareAtPrice, currency) }),
|
|
4103
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "lb-bundle-product-price", children: (0, import_core15.formatMoney)(item.price, currency) }),
|
|
4104
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "lb-bundle-qty-inline", children: `\xD7${item.quantity}` })
|
|
3977
4105
|
] }),
|
|
3978
|
-
item.unitPrice && /* @__PURE__ */ (0,
|
|
4106
|
+
item.unitPrice && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "lb-bundle-product-unit-price", children: item.unitPrice })
|
|
3979
4107
|
] }),
|
|
3980
|
-
canRemoveItem2(bundle, selections, item) ? /* @__PURE__ */ (0,
|
|
4108
|
+
canRemoveItem2(bundle, selections, item) ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
3981
4109
|
"button",
|
|
3982
4110
|
{
|
|
3983
4111
|
type: "button",
|
|
@@ -3987,13 +4115,13 @@ function MultiStepBundle(props) {
|
|
|
3987
4115
|
e.stopPropagation();
|
|
3988
4116
|
removeSlot(i, index);
|
|
3989
4117
|
},
|
|
3990
|
-
children: /* @__PURE__ */ (0,
|
|
4118
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(CloseIcon4, {})
|
|
3991
4119
|
}
|
|
3992
4120
|
) : (
|
|
3993
4121
|
/* Required pick at its floor — quiet state chip instead
|
|
3994
4122
|
of the ×; removal returns once another slot covers
|
|
3995
4123
|
the product's minimum (variant swap flow). */
|
|
3996
|
-
/* @__PURE__ */ (0,
|
|
4124
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "lb-mix-match__slot-required", children: "Required" })
|
|
3997
4125
|
)
|
|
3998
4126
|
]
|
|
3999
4127
|
},
|
|
@@ -4002,7 +4130,7 @@ function MultiStepBundle(props) {
|
|
|
4002
4130
|
))
|
|
4003
4131
|
}
|
|
4004
4132
|
),
|
|
4005
|
-
(0, import_core15.stepHeadroom)(step.maxQuantity, unitsByStep[i] ?? 0) !== 0 && /* @__PURE__ */ (0,
|
|
4133
|
+
(0, import_core15.stepHeadroom)(step.maxQuantity, unitsByStep[i] ?? 0) !== 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
4006
4134
|
"button",
|
|
4007
4135
|
{
|
|
4008
4136
|
type: "button",
|
|
@@ -4011,15 +4139,15 @@ function MultiStepBundle(props) {
|
|
|
4011
4139
|
"aria-label": `${step.minQuantity === 1 && step.maxQuantity === 1 ? "Choose a product" : "Choose products"}: ${step.name}`,
|
|
4012
4140
|
onClick: () => setPickerOpenAt(i),
|
|
4013
4141
|
children: [
|
|
4014
|
-
/* @__PURE__ */ (0,
|
|
4142
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4015
4143
|
"span",
|
|
4016
4144
|
{
|
|
4017
4145
|
className: "lb-mix-match__add-product-icon",
|
|
4018
4146
|
"aria-hidden": "true",
|
|
4019
|
-
children: /* @__PURE__ */ (0,
|
|
4147
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(PlusIcon2, {})
|
|
4020
4148
|
}
|
|
4021
4149
|
),
|
|
4022
|
-
/* @__PURE__ */ (0,
|
|
4150
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "lb-mix-match__add-product-label", children: step.minQuantity === 1 && step.maxQuantity === 1 ? "Choose a product" : "Choose products" })
|
|
4023
4151
|
]
|
|
4024
4152
|
}
|
|
4025
4153
|
)
|
|
@@ -4027,29 +4155,29 @@ function MultiStepBundle(props) {
|
|
|
4027
4155
|
},
|
|
4028
4156
|
i
|
|
4029
4157
|
)) }),
|
|
4030
|
-
/* @__PURE__ */ (0,
|
|
4031
|
-
allSatisfied && /* @__PURE__ */ (0,
|
|
4032
|
-
/* @__PURE__ */ (0,
|
|
4033
|
-
/* @__PURE__ */ (0,
|
|
4034
|
-
bundle.widgetConfig.savingsBar.visible && summary.savings > 0 && /* @__PURE__ */ (0,
|
|
4158
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "lb-bundle-divider" }),
|
|
4159
|
+
allSatisfied && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "lb-bundle-summary", "data-pricing-section": true, children: [
|
|
4160
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "lb-bundle-summary__text", children: [
|
|
4161
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "lb-bundle-summary__label", children: "Bundle total" }),
|
|
4162
|
+
bundle.widgetConfig.savingsBar.visible && summary.savings > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("p", { className: "lb-bundle-savings-line", "data-savings-bar": true, children: [
|
|
4035
4163
|
"You save",
|
|
4036
4164
|
" ",
|
|
4037
|
-
/* @__PURE__ */ (0,
|
|
4165
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { "data-savings-amount": true, children: (0, import_core15.formatMoney)(summary.savings, currency) }),
|
|
4038
4166
|
" ",
|
|
4039
|
-
/* @__PURE__ */ (0,
|
|
4167
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { "data-savings-percent": true, children: [
|
|
4040
4168
|
"(",
|
|
4041
4169
|
summary.savingsPercent,
|
|
4042
4170
|
"%)"
|
|
4043
4171
|
] })
|
|
4044
4172
|
] })
|
|
4045
4173
|
] }),
|
|
4046
|
-
/* @__PURE__ */ (0,
|
|
4047
|
-
bundle.widgetConfig.pricing.showComparePrice && summary.savings > 0 && /* @__PURE__ */ (0,
|
|
4048
|
-
/* @__PURE__ */ (0,
|
|
4174
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "lb-bundle-summary__prices", children: [
|
|
4175
|
+
bundle.widgetConfig.pricing.showComparePrice && summary.savings > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "lb-bundle-compare-price", "data-compare-price": true, children: (0, import_core15.formatMoney)(summary.comparePrice, currency) }),
|
|
4176
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "lb-bundle-sale-price", "data-sale-price": true, children: (0, import_core15.formatMoney)(summary.salePrice, currency) })
|
|
4049
4177
|
] })
|
|
4050
4178
|
] }),
|
|
4051
|
-
cartError && /* @__PURE__ */ (0,
|
|
4052
|
-
/* @__PURE__ */ (0,
|
|
4179
|
+
cartError && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: "lb-bundle__error", role: "alert", children: cartError }),
|
|
4180
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4053
4181
|
"button",
|
|
4054
4182
|
{
|
|
4055
4183
|
className: "lb-bundle__cta",
|
|
@@ -4059,7 +4187,7 @@ function MultiStepBundle(props) {
|
|
|
4059
4187
|
children: ctaLabel
|
|
4060
4188
|
}
|
|
4061
4189
|
),
|
|
4062
|
-
pickerOpenAt !== null && /* @__PURE__ */ (0,
|
|
4190
|
+
pickerOpenAt !== null && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
4063
4191
|
MultiStepPicker,
|
|
4064
4192
|
{
|
|
4065
4193
|
outOfStockBehavior,
|
|
@@ -4095,7 +4223,7 @@ function stepHasInStockProduct(bundle, stepIndex) {
|
|
|
4095
4223
|
});
|
|
4096
4224
|
}
|
|
4097
4225
|
function PlusIcon2() {
|
|
4098
|
-
return /* @__PURE__ */ (0,
|
|
4226
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
4099
4227
|
"svg",
|
|
4100
4228
|
{
|
|
4101
4229
|
width: "18",
|
|
@@ -4105,14 +4233,14 @@ function PlusIcon2() {
|
|
|
4105
4233
|
xmlns: "http://www.w3.org/2000/svg",
|
|
4106
4234
|
"aria-hidden": "true",
|
|
4107
4235
|
children: [
|
|
4108
|
-
/* @__PURE__ */ (0,
|
|
4109
|
-
/* @__PURE__ */ (0,
|
|
4236
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("line", { x1: "9", y1: "3", x2: "9", y2: "15", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }),
|
|
4237
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("line", { x1: "3", y1: "9", x2: "15", y2: "9", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" })
|
|
4110
4238
|
]
|
|
4111
4239
|
}
|
|
4112
4240
|
);
|
|
4113
4241
|
}
|
|
4114
4242
|
function CloseIcon4() {
|
|
4115
|
-
return /* @__PURE__ */ (0,
|
|
4243
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
4116
4244
|
"svg",
|
|
4117
4245
|
{
|
|
4118
4246
|
width: "16",
|
|
@@ -4122,8 +4250,8 @@ function CloseIcon4() {
|
|
|
4122
4250
|
xmlns: "http://www.w3.org/2000/svg",
|
|
4123
4251
|
"aria-hidden": "true",
|
|
4124
4252
|
children: [
|
|
4125
|
-
/* @__PURE__ */ (0,
|
|
4126
|
-
/* @__PURE__ */ (0,
|
|
4253
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("line", { x1: "5", y1: "5", x2: "15", y2: "15", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }),
|
|
4254
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("line", { x1: "15", y1: "5", x2: "5", y2: "15", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" })
|
|
4127
4255
|
]
|
|
4128
4256
|
}
|
|
4129
4257
|
);
|
|
@@ -4136,7 +4264,7 @@ async function fetchShopCustomCss(options) {
|
|
|
4136
4264
|
}
|
|
4137
4265
|
|
|
4138
4266
|
// src/hooks/useBundlesForProduct.ts
|
|
4139
|
-
var
|
|
4267
|
+
var import_react18 = require("react");
|
|
4140
4268
|
var import_core16 = require("@lime-bundles/core");
|
|
4141
4269
|
var INITIAL_STATE2 = {
|
|
4142
4270
|
status: "loading",
|
|
@@ -4144,10 +4272,10 @@ var INITIAL_STATE2 = {
|
|
|
4144
4272
|
error: null
|
|
4145
4273
|
};
|
|
4146
4274
|
function useBundlesForProduct(options) {
|
|
4147
|
-
const [state, setState] = (0,
|
|
4275
|
+
const [state, setState] = (0, import_react18.useState)(
|
|
4148
4276
|
INITIAL_STATE2
|
|
4149
4277
|
);
|
|
4150
|
-
(0,
|
|
4278
|
+
(0, import_react18.useEffect)(() => {
|
|
4151
4279
|
const controller = new AbortController();
|
|
4152
4280
|
setState(INITIAL_STATE2);
|
|
4153
4281
|
(0, import_core16.fetchBundlesForProduct)({
|
|
@@ -4196,6 +4324,7 @@ var import_core18 = require("@lime-bundles/core");
|
|
|
4196
4324
|
BUNDLES_FOR_PRODUCT_QUERY,
|
|
4197
4325
|
BUNDLE_METAOBJECT_QUERY,
|
|
4198
4326
|
BogoBundle,
|
|
4327
|
+
BundleCountdown,
|
|
4199
4328
|
BundleParseError,
|
|
4200
4329
|
DEFAULT_OUT_OF_STOCK_BEHAVIOR,
|
|
4201
4330
|
FixedBundle,
|