@lime-bundles/react 6.1.0 → 7.0.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/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/components/FixedBundle.tsx
2
- import { useCallback as useCallback5, useEffect as useEffect6, useMemo as useMemo4, useState as useState5 } from "react";
2
+ import { useCallback as useCallback5, useEffect as useEffect7, useMemo as useMemo4, useState as useState6 } from "react";
3
3
  import {
4
4
  formatMoney,
5
5
  formatUnitPrice,
@@ -81,13 +81,10 @@ async function fetchBundleDataWithWarnings(options) {
81
81
  // src/fetchShopSettings.ts
82
82
  import {
83
83
  createStorefrontClient as createStorefrontClient2,
84
- SHOP_SETTINGS_QUERY,
85
- DEFAULT_OUT_OF_STOCK_BEHAVIOR,
86
- parseOutOfStockBehavior
84
+ SHOP_SETTINGS_QUERY
87
85
  } from "@lime-bundles/core";
88
86
  var FALLBACK = {
89
- customCss: null,
90
- outOfStockBehavior: DEFAULT_OUT_OF_STOCK_BEHAVIOR
87
+ customCss: null
91
88
  };
92
89
  var cache = /* @__PURE__ */ new Map();
93
90
  async function fetchShopSettings(options) {
@@ -105,10 +102,7 @@ async function fetchShopSettings(options) {
105
102
  { signal: options.signal }
106
103
  );
107
104
  return {
108
- customCss: data.shop?.customCss?.value ?? null,
109
- outOfStockBehavior: parseOutOfStockBehavior(
110
- data.shop?.outOfStockBehavior?.value
111
- )
105
+ customCss: data.shop?.customCss?.value ?? null
112
106
  };
113
107
  })();
114
108
  cache.set(options.shopDomain, promise);
@@ -266,19 +260,25 @@ function useWidgetConfigVars(config) {
266
260
  import { useEffect as useEffect4, useMemo as useMemo2, useState as useState3, useCallback as useCallback3 } from "react";
267
261
  import { variants as variantsNs } from "@lime-bundles/core";
268
262
  var { findVariantByOptions, isOptionValueAvailable, toPickerVariant } = variantsNs;
269
- function defaultInitial(variants) {
270
- return variants.find((v) => v.availableForSale) ?? variants[0] ?? null;
271
- }
272
263
  function useVariantSelection({
273
264
  variants,
274
265
  optionNames,
275
266
  initialVariant,
276
- optionValuesByPosition
267
+ optionValuesByPosition,
268
+ requiredQtyFor
277
269
  }) {
278
- const seed = useMemo2(
279
- () => initialVariant ?? defaultInitial(variants),
280
- [initialVariant, variants]
270
+ const pickerVariants = useMemo2(
271
+ () => variants.map((v) => toPickerVariant(v, requiredQtyFor?.(v.id))),
272
+ [variants, requiredQtyFor]
281
273
  );
274
+ const seed = useMemo2(() => {
275
+ if (initialVariant) return initialVariant;
276
+ const covered = pickerVariants.find((p) => p.available);
277
+ if (covered) {
278
+ return variants.find((v) => v.id === covered.id) ?? null;
279
+ }
280
+ return variants.find((v) => v.availableForSale) ?? variants[0] ?? null;
281
+ }, [initialVariant, variants, pickerVariants]);
282
282
  const [selectedValues, setSelectedValues] = useState3(
283
283
  () => seed ? seed.selectedOptions.map((o) => o.value) : optionNames.map(() => "")
284
284
  );
@@ -286,10 +286,6 @@ function useVariantSelection({
286
286
  if (!seed) return;
287
287
  setSelectedValues(seed.selectedOptions.map((o) => o.value));
288
288
  }, [seed?.id]);
289
- const pickerVariants = useMemo2(
290
- () => variants.map((v) => toPickerVariant(v)),
291
- [variants]
292
- );
293
289
  const selectedVariant = useMemo2(() => {
294
290
  if (selectedValues.length !== optionNames.length) return null;
295
291
  const match = findVariantByOptions(pickerVariants, selectedValues);
@@ -659,8 +655,48 @@ function VariantDropdown({
659
655
  );
660
656
  }
661
657
 
662
- // src/components/FixedBundle.tsx
658
+ // src/components/BundleCountdown.tsx
659
+ import { useEffect as useEffect6, useState as useState5 } from "react";
663
660
  import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
661
+ function pad(n) {
662
+ return n < 10 ? "0" + n : String(n);
663
+ }
664
+ function formatRemaining(remaining) {
665
+ const days = Math.floor(remaining / 864e5);
666
+ const hours = Math.floor(remaining % 864e5 / 36e5);
667
+ const mins = Math.floor(remaining % 36e5 / 6e4);
668
+ const secs = Math.floor(remaining % 6e4 / 1e3);
669
+ return days > 0 ? days + "d " + pad(hours) + "h " + pad(mins) + "m " + pad(secs) + "s" : pad(hours) + "h " + pad(mins) + "m " + pad(secs) + "s";
670
+ }
671
+ function BundleCountdown({
672
+ endsAt,
673
+ widgetConfig,
674
+ label = "Limited time offer"
675
+ }) {
676
+ const enabled = !!endsAt && widgetConfig?.countdown?.showCountdown !== false;
677
+ const endTime = enabled ? new Date(endsAt).getTime() : NaN;
678
+ const [remaining, setRemaining] = useState5(null);
679
+ useEffect6(() => {
680
+ if (!enabled || isNaN(endTime)) {
681
+ setRemaining(null);
682
+ return;
683
+ }
684
+ const update = () => setRemaining(endTime - Date.now());
685
+ update();
686
+ const interval = setInterval(update, 1e3);
687
+ return () => clearInterval(interval);
688
+ }, [enabled, endTime]);
689
+ if (!enabled || isNaN(endTime) || remaining === null || remaining <= 0) {
690
+ return null;
691
+ }
692
+ return /* @__PURE__ */ jsxs2("div", { className: "lb-bundle-countdown", "data-countdown": true, children: [
693
+ /* @__PURE__ */ jsx2("div", { className: "lb-bundle-countdown__label", children: /* @__PURE__ */ jsx2("span", { children: label }) }),
694
+ /* @__PURE__ */ jsx2("span", { className: "lb-bundle-countdown__timer", "data-countdown-timer": true, children: formatRemaining(remaining) })
695
+ ] });
696
+ }
697
+
698
+ // src/components/FixedBundle.tsx
699
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
664
700
  function FixedBundle(props) {
665
701
  const {
666
702
  shopDomain,
@@ -684,9 +720,9 @@ function FixedBundle(props) {
684
720
  bundleType: "fixed",
685
721
  enabled: analyticsEnabled !== false
686
722
  });
687
- const [addingToCart, setAddingToCart] = useState5(false);
688
- const [cartError, setCartError] = useState5(null);
689
- const [selectedVariants, setSelectedVariants] = useState5({});
723
+ const [addingToCart, setAddingToCart] = useState6(false);
724
+ const [cartError, setCartError] = useState6(null);
725
+ const [selectedVariants, setSelectedVariants] = useState6({});
690
726
  const handleVariantChange = useCallback5(
691
727
  (productId, variant) => {
692
728
  setSelectedVariants((prev) => {
@@ -699,7 +735,7 @@ function FixedBundle(props) {
699
735
  const bundle = result.status === "success" && result.bundle.bundleType === "fixed" ? result.bundle : null;
700
736
  const setConfigVarsRef = useWidgetConfigVars(bundle?.widgetConfig);
701
737
  const productsEdgeFadeRef = useEdgeFade();
702
- useEffect6(() => {
738
+ useEffect7(() => {
703
739
  if (result.status === "error") {
704
740
  onError?.(result.error);
705
741
  return;
@@ -777,9 +813,9 @@ function FixedBundle(props) {
777
813
  }
778
814
  }, [bundle, onAddToCart, onError, trackAddToCart, selectedVariants]);
779
815
  if (result.status === "loading") {
780
- return /* @__PURE__ */ jsxs2("div", { className: `lb-bundle lb-bundle--loading ${className ?? ""}`, children: [
781
- /* @__PURE__ */ jsx2("div", { className: "lb-skeleton lb-skeleton--title" }),
782
- /* @__PURE__ */ jsx2("div", { className: "lb-skeleton lb-skeleton--products" })
816
+ return /* @__PURE__ */ jsxs3("div", { className: `lb-bundle lb-bundle--loading ${className ?? ""}`, children: [
817
+ /* @__PURE__ */ jsx3("div", { className: "lb-skeleton lb-skeleton--title" }),
818
+ /* @__PURE__ */ jsx3("div", { className: "lb-skeleton lb-skeleton--products" })
783
819
  ] });
784
820
  }
785
821
  if (result.status === "error") return null;
@@ -806,7 +842,7 @@ function FixedBundle(props) {
806
842
  const savingsPercent = comparePrice > 0 && savings > 0 ? Math.round(savings / comparePrice * 100) : 0;
807
843
  const showCompare = bundle.widgetConfig.pricing.showComparePrice && savings > 0;
808
844
  const showSavings = bundle.widgetConfig.savingsBar.visible && savings > 0;
809
- return /* @__PURE__ */ jsxs2(
845
+ return /* @__PURE__ */ jsxs3(
810
846
  "div",
811
847
  {
812
848
  ref: (el) => {
@@ -817,11 +853,18 @@ function FixedBundle(props) {
817
853
  role: "region",
818
854
  "aria-label": bundle.title,
819
855
  children: [
820
- /* @__PURE__ */ jsx2("div", { className: "lb-bundle-header", children: /* @__PURE__ */ jsxs2("div", { className: "lb-bundle-header__content", children: [
821
- /* @__PURE__ */ jsx2("h3", { className: "lb-bundle-title", children: bundle.title }),
822
- bundle.description && /* @__PURE__ */ jsx2("p", { className: "lb-bundle-subtitle", children: bundle.description })
856
+ /* @__PURE__ */ jsx3("div", { className: "lb-bundle-header", children: /* @__PURE__ */ jsxs3("div", { className: "lb-bundle-header__content", children: [
857
+ /* @__PURE__ */ jsx3("h3", { className: "lb-bundle-title", children: bundle.title }),
858
+ bundle.description && /* @__PURE__ */ jsx3("p", { className: "lb-bundle-subtitle", children: bundle.description })
823
859
  ] }) }),
824
- /* @__PURE__ */ jsx2("div", { className: "lb-bundle__products lb-edge-fade", ref: productsEdgeFadeRef, children: bundle.products.map((product) => /* @__PURE__ */ jsx2(
860
+ /* @__PURE__ */ jsx3(
861
+ BundleCountdown,
862
+ {
863
+ endsAt: bundle.endsAt,
864
+ widgetConfig: bundle.widgetConfig
865
+ }
866
+ ),
867
+ /* @__PURE__ */ jsx3("div", { className: "lb-bundle__products lb-edge-fade", ref: productsEdgeFadeRef, children: bundle.products.map((product) => /* @__PURE__ */ jsx3(
825
868
  FixedProductRow,
826
869
  {
827
870
  bundle,
@@ -832,29 +875,29 @@ function FixedBundle(props) {
832
875
  },
833
876
  product.id
834
877
  )) }),
835
- /* @__PURE__ */ jsx2("div", { className: "lb-bundle-divider" }),
836
- /* @__PURE__ */ jsxs2("div", { className: "lb-bundle-summary", children: [
837
- /* @__PURE__ */ jsxs2("div", { className: "lb-bundle-summary__text", children: [
838
- /* @__PURE__ */ jsx2("span", { className: "lb-bundle-summary__label", children: "Bundle price" }),
839
- showSavings && /* @__PURE__ */ jsxs2("p", { className: "lb-bundle-savings-line", "data-savings-bar": true, children: [
878
+ /* @__PURE__ */ jsx3("div", { className: "lb-bundle-divider" }),
879
+ /* @__PURE__ */ jsxs3("div", { className: "lb-bundle-summary", children: [
880
+ /* @__PURE__ */ jsxs3("div", { className: "lb-bundle-summary__text", children: [
881
+ /* @__PURE__ */ jsx3("span", { className: "lb-bundle-summary__label", children: "Bundle total" }),
882
+ showSavings && /* @__PURE__ */ jsxs3("p", { className: "lb-bundle-savings-line", "data-savings-bar": true, children: [
840
883
  "You save",
841
884
  " ",
842
- /* @__PURE__ */ jsx2("span", { "data-savings-amount": true, children: formatMoney(savings, currency) }),
885
+ /* @__PURE__ */ jsx3("span", { "data-savings-amount": true, children: formatMoney(savings, currency) }),
843
886
  " ",
844
- /* @__PURE__ */ jsxs2("span", { "data-savings-percent": true, children: [
887
+ /* @__PURE__ */ jsxs3("span", { "data-savings-percent": true, children: [
845
888
  "(",
846
889
  savingsPercent,
847
890
  "%)"
848
891
  ] })
849
892
  ] })
850
893
  ] }),
851
- /* @__PURE__ */ jsxs2("span", { className: "lb-bundle-summary__prices", children: [
852
- showCompare && /* @__PURE__ */ jsx2("span", { className: "lb-bundle-compare-price", "data-compare-price": true, children: formatMoney(comparePrice, currency) }),
853
- /* @__PURE__ */ jsx2("span", { className: "lb-bundle-sale-price", "data-sale-price": true, children: formatMoney(salePrice, currency) })
894
+ /* @__PURE__ */ jsxs3("span", { className: "lb-bundle-summary__prices", children: [
895
+ showCompare && /* @__PURE__ */ jsx3("span", { className: "lb-bundle-compare-price", "data-compare-price": true, children: formatMoney(comparePrice, currency) }),
896
+ /* @__PURE__ */ jsx3("span", { className: "lb-bundle-sale-price", "data-sale-price": true, children: formatMoney(salePrice, currency) })
854
897
  ] })
855
898
  ] }),
856
- cartError && /* @__PURE__ */ jsx2("p", { className: "lb-bundle__error", role: "alert", children: cartError }),
857
- /* @__PURE__ */ jsx2(
899
+ cartError && /* @__PURE__ */ jsx3("p", { className: "lb-bundle__error", role: "alert", children: cartError }),
900
+ /* @__PURE__ */ jsx3(
858
901
  "button",
859
902
  {
860
903
  className: "lb-bundle__cta",
@@ -877,9 +920,13 @@ function FixedProductRow({ bundle, product, currency, isOos, onVariantChange })
877
920
  const showPicker = variants.length > 1 && optionNames.length > 0;
878
921
  const { selectedValues, selectedVariant, setOptionValue, optionsFor } = useVariantSelection({
879
922
  variants,
880
- optionNames
923
+ optionNames,
924
+ // Quantity-aware dropdown: a variant that can't cover this row's
925
+ // bundle quantity greys out instead of walking the shopper into a
926
+ // cart Shopify caps at add time.
927
+ requiredQtyFor: (variantId) => resolveBundleQty(bundle, product.id, variantId)
881
928
  });
882
- useEffect6(() => {
929
+ useEffect7(() => {
883
930
  onVariantChange(product.id, selectedVariant ?? null);
884
931
  }, [selectedVariant, product.id, onVariantChange]);
885
932
  const displayVariant = selectedVariant ?? variants.find(
@@ -900,15 +947,15 @@ function FixedProductRow({ bundle, product, currency, isOos, onVariantChange })
900
947
  bundle.widgetConfig.lowStockThreshold,
901
948
  bundle.widgetConfig.showLowStockBadge
902
949
  );
903
- return /* @__PURE__ */ jsxs2(
950
+ return /* @__PURE__ */ jsxs3(
904
951
  "div",
905
952
  {
906
953
  className: isOos ? "lb-bundle-product-row lb-bundle-product-row--oos" : "lb-bundle-product-row",
907
954
  "aria-disabled": isOos || void 0,
908
955
  part: "product",
909
956
  children: [
910
- isOos && /* @__PURE__ */ jsx2("span", { className: "lb-bundle-product-row__oos", children: "Out of stock" }),
911
- thumbImage && /* @__PURE__ */ jsx2(
957
+ isOos && /* @__PURE__ */ jsx3("span", { className: "lb-bundle-product-row__oos", children: "Out of stock" }),
958
+ thumbImage && /* @__PURE__ */ jsx3(
912
959
  "img",
913
960
  {
914
961
  src: thumbImage.url,
@@ -917,11 +964,11 @@ function FixedProductRow({ bundle, product, currency, isOos, onVariantChange })
917
964
  loading: "lazy"
918
965
  }
919
966
  ),
920
- /* @__PURE__ */ jsxs2("div", { className: "lb-bundle__product-info", children: [
921
- /* @__PURE__ */ jsx2("p", { className: "lb-bundle__product-title", children: product.title }),
922
- !showPicker && displayVariant && variants.length > 1 && /* @__PURE__ */ jsx2("span", { className: "lb-bundle-variant-badge", children: displayVariant.title }),
923
- /* @__PURE__ */ jsxs2("span", { className: "lb-bundle-product-prices", children: [
924
- compareAt && /* @__PURE__ */ jsx2(
967
+ /* @__PURE__ */ jsxs3("div", { className: "lb-bundle__product-info", children: [
968
+ /* @__PURE__ */ jsx3("p", { className: "lb-bundle__product-title", children: product.title }),
969
+ !showPicker && displayVariant && variants.length > 1 && /* @__PURE__ */ jsx3("span", { className: "lb-bundle-variant-badge", children: displayVariant.title }),
970
+ /* @__PURE__ */ jsxs3("span", { className: "lb-bundle-product-prices", children: [
971
+ compareAt && /* @__PURE__ */ jsx3(
925
972
  "span",
926
973
  {
927
974
  className: "lb-bundle-product-compare-price",
@@ -929,9 +976,9 @@ function FixedProductRow({ bundle, product, currency, isOos, onVariantChange })
929
976
  children: compareAt
930
977
  }
931
978
  ),
932
- /* @__PURE__ */ jsx2("span", { className: "lb-bundle__product-price", "data-product-price": true, children: priceText })
979
+ /* @__PURE__ */ jsx3("span", { className: "lb-bundle__product-price", "data-product-price": true, children: priceText })
933
980
  ] }),
934
- unitPriceText && /* @__PURE__ */ jsx2(
981
+ unitPriceText && /* @__PURE__ */ jsx3(
935
982
  "span",
936
983
  {
937
984
  className: "lb-bundle__product-unit-price",
@@ -939,18 +986,18 @@ function FixedProductRow({ bundle, product, currency, isOos, onVariantChange })
939
986
  children: unitPriceText
940
987
  }
941
988
  ),
942
- showLowStock && /* @__PURE__ */ jsxs2("span", { className: "lb-bundle-low-stock-badge", children: [
989
+ showLowStock && /* @__PURE__ */ jsxs3("span", { className: "lb-bundle-low-stock-badge", children: [
943
990
  "Only ",
944
991
  displayVariant.quantityAvailable,
945
992
  " left"
946
993
  ] }),
947
- showPicker && /* @__PURE__ */ jsx2("div", { className: "lb-bundle__product-variant-pickers", children: optionNames.map((optionName, optionIndex) => {
994
+ showPicker && /* @__PURE__ */ jsx3("div", { className: "lb-bundle__product-variant-pickers", children: optionNames.map((optionName, optionIndex) => {
948
995
  const dropdownOptions = optionsFor(optionIndex).map((o) => ({
949
996
  value: o.value,
950
997
  label: o.value,
951
998
  disabled: o.disabled
952
999
  }));
953
- return /* @__PURE__ */ jsx2(
1000
+ return /* @__PURE__ */ jsx3(
954
1001
  VariantDropdown,
955
1002
  {
956
1003
  options: dropdownOptions,
@@ -962,7 +1009,7 @@ function FixedProductRow({ bundle, product, currency, isOos, onVariantChange })
962
1009
  );
963
1010
  }) })
964
1011
  ] }),
965
- displayVariant && /* @__PURE__ */ jsxs2("span", { className: "lb-bundle-qty-chip", "data-qty-inline": true, children: [
1012
+ displayVariant && /* @__PURE__ */ jsxs3("span", { className: "lb-bundle-qty-chip", "data-qty-inline": true, children: [
966
1013
  "\xD7",
967
1014
  displayQty
968
1015
  ] })
@@ -981,33 +1028,6 @@ import {
981
1028
  DEFAULT_PRODUCT_RULE as DEFAULT_PRODUCT_RULE2
982
1029
  } from "@lime-bundles/core";
983
1030
 
984
- // src/hooks/useShopSettings.ts
985
- import { useEffect as useEffect7, useState as useState6 } from "react";
986
- import {
987
- DEFAULT_OUT_OF_STOCK_BEHAVIOR as DEFAULT_OUT_OF_STOCK_BEHAVIOR2
988
- } from "@lime-bundles/core";
989
- function useShopSettings(options) {
990
- const [outOfStockBehavior, setOutOfStockBehavior] = useState6(DEFAULT_OUT_OF_STOCK_BEHAVIOR2);
991
- const { shopDomain, storefrontAccessToken } = options;
992
- useEffect7(() => {
993
- const controller = new AbortController();
994
- let active = true;
995
- fetchShopSettingsOrDefault({
996
- shopDomain,
997
- storefrontAccessToken,
998
- signal: controller.signal
999
- }).then((settings) => {
1000
- if (!active || controller.signal.aborted) return;
1001
- setOutOfStockBehavior(settings.outOfStockBehavior);
1002
- });
1003
- return () => {
1004
- active = false;
1005
- controller.abort();
1006
- };
1007
- }, [shopDomain, storefrontAccessToken]);
1008
- return { outOfStockBehavior };
1009
- }
1010
-
1011
1031
  // src/components/MixMatchPicker.tsx
1012
1032
  import {
1013
1033
  useEffect as useEffect10,
@@ -1085,6 +1105,7 @@ function useFocusTrap({
1085
1105
  active,
1086
1106
  containerRef,
1087
1107
  onEscape,
1108
+ initialFocusRef,
1088
1109
  returnFocusRef
1089
1110
  }) {
1090
1111
  const previouslyFocused = useRef5(null);
@@ -1092,7 +1113,8 @@ function useFocusTrap({
1092
1113
  if (!active) return;
1093
1114
  const container = containerRef.current;
1094
1115
  previouslyFocused.current = document.activeElement ?? null;
1095
- container?.focus();
1116
+ const initial = initialFocusRef?.current ?? container;
1117
+ initial?.focus();
1096
1118
  function onKeyDown(e) {
1097
1119
  if (e.key === "Escape") {
1098
1120
  e.preventDefault();
@@ -1130,7 +1152,7 @@ function useFocusTrap({
1130
1152
  }
1131
1153
 
1132
1154
  // src/components/MixMatchPicker.tsx
1133
- import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
1155
+ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
1134
1156
  function ruleFor(bundle, productId, variantId) {
1135
1157
  if (variantId) {
1136
1158
  const vRule = bundle.variantRules[variantId];
@@ -1144,7 +1166,7 @@ function variantRuleFor(bundle, variantId) {
1144
1166
  function sanitizeId(gid) {
1145
1167
  return gid.replace(/[^a-zA-Z0-9_-]/g, "-");
1146
1168
  }
1147
- function buildEligibleProducts(bundle, oosBehavior) {
1169
+ function buildEligibleProducts(bundle) {
1148
1170
  const result = [];
1149
1171
  const seen = /* @__PURE__ */ new Set();
1150
1172
  for (const product of bundle.products) {
@@ -1155,7 +1177,6 @@ function buildEligibleProducts(bundle, oosBehavior) {
1155
1177
  (v) => isVariantFulfillable2(v, rule.min)
1156
1178
  );
1157
1179
  const isOos = available.length === 0;
1158
- if (isOos && oosBehavior === "hide") continue;
1159
1180
  result.push({
1160
1181
  product,
1161
1182
  variants: product.variants.nodes,
@@ -1170,7 +1191,6 @@ function normalizeText(str) {
1170
1191
  }
1171
1192
  var FILTERS_ALL = "__all__";
1172
1193
  function MixMatchPicker({
1173
- outOfStockBehavior,
1174
1194
  bundle,
1175
1195
  currency,
1176
1196
  requiredQty,
@@ -1188,13 +1208,14 @@ function MixMatchPicker({
1188
1208
  const wc = bundle.widgetConfig;
1189
1209
  const overlayRef = useRef6(null);
1190
1210
  const dialogRef = useRef6(null);
1211
+ const closeBtnRef = useRef6(null);
1191
1212
  const mouseDownTarget = useRef6(null);
1192
1213
  const [open, setOpen] = useState7(false);
1193
1214
  const [query, setQuery] = useState7("");
1194
1215
  const [activeType, setActiveType] = useState7(FILTERS_ALL);
1195
1216
  const eligible = useMemo5(
1196
- () => buildEligibleProducts(bundle, outOfStockBehavior),
1197
- [bundle, outOfStockBehavior]
1217
+ () => buildEligibleProducts(bundle),
1218
+ [bundle]
1198
1219
  );
1199
1220
  const productTypes = useMemo5(() => {
1200
1221
  const types = [];
@@ -1220,6 +1241,7 @@ function MixMatchPicker({
1220
1241
  useFocusTrap({
1221
1242
  active: true,
1222
1243
  containerRef: dialogRef,
1244
+ initialFocusRef: closeBtnRef,
1223
1245
  onEscape: onClose
1224
1246
  });
1225
1247
  const remaining = Math.max(0, requiredQty - shownUnits);
@@ -1228,14 +1250,25 @@ function MixMatchPicker({
1228
1250
  const pct = bundle.discountConfig.discountType === "percentage" && bundle.discountConfig.discountValue ? Math.round(bundle.discountConfig.discountValue) : 0;
1229
1251
  return pct > 0 ? `Choose ${remaining} more to unlock ${pct}% off` : `Choose ${remaining} more to complete your bundle`;
1230
1252
  })();
1253
+ const [selectedAtOpen] = useState7(
1254
+ () => new Set(selections.map((s) => s.productId))
1255
+ );
1256
+ const ordered = useMemo5(() => {
1257
+ const front = [];
1258
+ const back = [];
1259
+ for (const ep of eligible) {
1260
+ (selectedAtOpen.has(ep.product.id) ? back : front).push(ep);
1261
+ }
1262
+ return front.concat(back);
1263
+ }, [eligible, selectedAtOpen]);
1231
1264
  const filtered = useMemo5(() => {
1232
1265
  const nq = normalizeText(query.trim());
1233
- return eligible.filter((ep) => {
1266
+ return ordered.filter((ep) => {
1234
1267
  const matchesQuery = !nq || normalizeText(ep.product.title).includes(nq);
1235
1268
  const matchesType = activeType === FILTERS_ALL || (ep.product.productType ?? "") === activeType;
1236
1269
  return matchesQuery && matchesType;
1237
1270
  });
1238
- }, [eligible, query, activeType]);
1271
+ }, [ordered, query, activeType]);
1239
1272
  const showEmpty = filtered.length === 0 && query.trim().length > 0;
1240
1273
  function onOverlayMouseDown(e) {
1241
1274
  mouseDownTarget.current = e.target;
@@ -1253,7 +1286,7 @@ function MixMatchPicker({
1253
1286
  // inside carries the interactive role + focus trap. So the static-element
1254
1287
  // interaction lint does not apply to this backdrop.
1255
1288
  // eslint-disable-next-line jsx-a11y/no-static-element-interactions
1256
- /* @__PURE__ */ jsx3(
1289
+ /* @__PURE__ */ jsx4(
1257
1290
  "div",
1258
1291
  {
1259
1292
  ref: (el) => {
@@ -1265,7 +1298,7 @@ function MixMatchPicker({
1265
1298
  "data-bundle-gid": bundle.id,
1266
1299
  onMouseDown: onOverlayMouseDown,
1267
1300
  onMouseUp: onOverlayMouseUp,
1268
- children: /* @__PURE__ */ jsxs3(
1301
+ children: /* @__PURE__ */ jsxs4(
1269
1302
  "div",
1270
1303
  {
1271
1304
  ref: dialogRef,
@@ -1275,30 +1308,31 @@ function MixMatchPicker({
1275
1308
  "aria-labelledby": titleId,
1276
1309
  tabIndex: -1,
1277
1310
  children: [
1278
- /* @__PURE__ */ jsxs3("div", { className: "lb-mix-match__modal-header", children: [
1279
- /* @__PURE__ */ jsxs3("div", { className: "lb-mix-match__modal-header-top", children: [
1280
- /* @__PURE__ */ jsxs3("div", { className: "lb-mix-match__modal-heading", children: [
1281
- /* @__PURE__ */ jsx3("h4", { className: "lb-mix-match__modal-title", id: titleId, children: "Add to your bundle" }),
1282
- /* @__PURE__ */ jsx3("p", { className: "lb-mix-match__modal-subtitle", "data-modal-subtitle": true, children: subtitle })
1311
+ /* @__PURE__ */ jsxs4("div", { className: "lb-mix-match__modal-header", children: [
1312
+ /* @__PURE__ */ jsxs4("div", { className: "lb-mix-match__modal-header-top", children: [
1313
+ /* @__PURE__ */ jsxs4("div", { className: "lb-mix-match__modal-heading", children: [
1314
+ /* @__PURE__ */ jsx4("h4", { className: "lb-mix-match__modal-title", id: titleId, children: "Add to your bundle" }),
1315
+ /* @__PURE__ */ jsx4("p", { className: "lb-mix-match__modal-subtitle", "data-modal-subtitle": true, children: subtitle })
1283
1316
  ] }),
1284
- /* @__PURE__ */ jsx3(
1317
+ /* @__PURE__ */ jsx4(
1285
1318
  "button",
1286
1319
  {
1320
+ ref: closeBtnRef,
1287
1321
  type: "button",
1288
1322
  className: "lb-mix-match__modal-close",
1289
1323
  "data-modal-close": true,
1290
1324
  "aria-label": "Close",
1291
1325
  onClick: onClose,
1292
- children: /* @__PURE__ */ jsx3(CloseIcon, {})
1326
+ children: /* @__PURE__ */ jsx4(CloseIcon, {})
1293
1327
  }
1294
1328
  )
1295
1329
  ] }),
1296
- /* @__PURE__ */ jsx3(
1330
+ /* @__PURE__ */ jsx4(
1297
1331
  "div",
1298
1332
  {
1299
1333
  className: "lb-mix-match__progress lb-mix-match__modal-progress",
1300
1334
  "data-progress": true,
1301
- children: /* @__PURE__ */ jsx3(
1335
+ children: /* @__PURE__ */ jsx4(
1302
1336
  "div",
1303
1337
  {
1304
1338
  className: "lb-mix-match__progress-segments",
@@ -1306,7 +1340,7 @@ function MixMatchPicker({
1306
1340
  "aria-valuenow": shownUnits,
1307
1341
  "aria-valuemin": 0,
1308
1342
  "aria-valuemax": requiredQty,
1309
- children: Array.from({ length: requiredQty }).map((_, i) => /* @__PURE__ */ jsx3(
1343
+ children: Array.from({ length: requiredQty }).map((_, i) => /* @__PURE__ */ jsx4(
1310
1344
  "span",
1311
1345
  {
1312
1346
  className: `lb-mix-match__progress-segment${i < shownUnits ? " lb-mix-match__progress-segment--filled" : ""}`,
@@ -1319,8 +1353,8 @@ function MixMatchPicker({
1319
1353
  }
1320
1354
  )
1321
1355
  ] }),
1322
- wc.showSearch && /* @__PURE__ */ jsxs3("div", { className: "lb-mix-match__modal-search", children: [
1323
- /* @__PURE__ */ jsx3(
1356
+ wc.showSearch && /* @__PURE__ */ jsxs4("div", { className: "lb-mix-match__modal-search", children: [
1357
+ /* @__PURE__ */ jsx4(
1324
1358
  "input",
1325
1359
  {
1326
1360
  type: "text",
@@ -1334,7 +1368,7 @@ function MixMatchPicker({
1334
1368
  onChange: (e) => setQuery(e.target.value)
1335
1369
  }
1336
1370
  ),
1337
- query.length > 0 && /* @__PURE__ */ jsx3(
1371
+ query.length > 0 && /* @__PURE__ */ jsx4(
1338
1372
  "button",
1339
1373
  {
1340
1374
  type: "button",
@@ -1342,11 +1376,11 @@ function MixMatchPicker({
1342
1376
  "data-modal-search-clear": true,
1343
1377
  "aria-label": "Clear search",
1344
1378
  onClick: () => setQuery(""),
1345
- children: /* @__PURE__ */ jsx3(SearchClearIcon, {})
1379
+ children: /* @__PURE__ */ jsx4(SearchClearIcon, {})
1346
1380
  }
1347
1381
  )
1348
1382
  ] }),
1349
- showFilters && /* @__PURE__ */ jsx3(
1383
+ showFilters && /* @__PURE__ */ jsx4(
1350
1384
  "div",
1351
1385
  {
1352
1386
  className: "lb-mix-match__filters",
@@ -1355,7 +1389,7 @@ function MixMatchPicker({
1355
1389
  "aria-label": "Filter by product type",
1356
1390
  children: [FILTERS_ALL, ...productTypes].map((value) => {
1357
1391
  const isActive = value === activeType;
1358
- return /* @__PURE__ */ jsx3(
1392
+ return /* @__PURE__ */ jsx4(
1359
1393
  "button",
1360
1394
  {
1361
1395
  type: "button",
@@ -1370,7 +1404,7 @@ function MixMatchPicker({
1370
1404
  })
1371
1405
  }
1372
1406
  ),
1373
- /* @__PURE__ */ jsx3("div", { className: "lb-mix-match__modal-list", "data-modal-list": true, children: filtered.map((ep) => /* @__PURE__ */ jsx3(
1407
+ /* @__PURE__ */ jsx4("div", { className: "lb-mix-match__modal-list", "data-modal-list": true, children: filtered.map((ep) => /* @__PURE__ */ jsx4(
1374
1408
  MixMatchPickerRow,
1375
1409
  {
1376
1410
  bundle,
@@ -1389,10 +1423,10 @@ function MixMatchPicker({
1389
1423
  },
1390
1424
  ep.product.id
1391
1425
  )) }),
1392
- showEmpty && /* @__PURE__ */ jsx3("div", { className: "lb-mix-match__modal-empty", "data-modal-empty": true, children: /* @__PURE__ */ jsx3("p", { children: "No products match your search" }) }),
1393
- /* @__PURE__ */ jsx3("span", { "data-modal-live": true, "aria-live": "polite", className: "lb-visually-hidden", children: `${filtered.length} products shown` }),
1394
- /* @__PURE__ */ jsxs3("div", { className: "lb-mix-match__modal-footer", children: [
1395
- /* @__PURE__ */ jsx3(
1426
+ showEmpty && /* @__PURE__ */ jsx4("div", { className: "lb-mix-match__modal-empty", "data-modal-empty": true, children: /* @__PURE__ */ jsx4("p", { children: "No products match your search" }) }),
1427
+ /* @__PURE__ */ jsx4("span", { "data-modal-live": true, "aria-live": "polite", className: "lb-visually-hidden", children: `${filtered.length} products shown` }),
1428
+ /* @__PURE__ */ jsxs4("div", { className: "lb-mix-match__modal-footer", children: [
1429
+ /* @__PURE__ */ jsx4(
1396
1430
  "span",
1397
1431
  {
1398
1432
  className: "lb-mix-match__modal-footer-count",
@@ -1401,7 +1435,7 @@ function MixMatchPicker({
1401
1435
  children: `${shownUnits} of ${requiredQty} added`
1402
1436
  }
1403
1437
  ),
1404
- /* @__PURE__ */ jsx3(
1438
+ /* @__PURE__ */ jsx4(
1405
1439
  "button",
1406
1440
  {
1407
1441
  type: "button",
@@ -1535,7 +1569,7 @@ function MixMatchPickerRow({
1535
1569
  }
1536
1570
  const priceCents = parseFloat(currentVariant.price.amount);
1537
1571
  const compareCents = currentVariant.compareAtPrice ? parseFloat(currentVariant.compareAtPrice.amount) : null;
1538
- return /* @__PURE__ */ jsxs3(
1572
+ return /* @__PURE__ */ jsxs4(
1539
1573
  "div",
1540
1574
  {
1541
1575
  className: `lb-mix-match__modal-product${isOos ? " lb-mix-match__modal-product--sold-out" : ""}${variantInBundle ? " lb-mix-match__modal-product--in-bundle" : ""}`,
@@ -1544,8 +1578,8 @@ function MixMatchPickerRow({
1544
1578
  "data-type": product.productType ?? "",
1545
1579
  "aria-disabled": isOos || void 0,
1546
1580
  children: [
1547
- /* @__PURE__ */ jsxs3("div", { className: "lb-mix-match__modal-product-thumb", children: [
1548
- thumbImage && /* @__PURE__ */ jsx3(
1581
+ /* @__PURE__ */ jsxs4("div", { className: "lb-mix-match__modal-product-thumb", children: [
1582
+ thumbImage && /* @__PURE__ */ jsx4(
1549
1583
  "img",
1550
1584
  {
1551
1585
  src: thumbImage.url,
@@ -1553,10 +1587,10 @@ function MixMatchPickerRow({
1553
1587
  loading: "lazy"
1554
1588
  }
1555
1589
  ),
1556
- variantInBundle && /* @__PURE__ */ jsx3("span", { className: "lb-mix-match__modal-added-badge", children: "Added" })
1590
+ variantInBundle && /* @__PURE__ */ jsx4("span", { className: "lb-mix-match__modal-added-badge", children: "Added" })
1557
1591
  ] }),
1558
- /* @__PURE__ */ jsxs3("div", { className: "lb-mix-match__modal-product-info", children: [
1559
- /* @__PURE__ */ jsx3("p", { className: "lb-mix-match__modal-product-title", children: /* @__PURE__ */ jsx3(
1592
+ /* @__PURE__ */ jsxs4("div", { className: "lb-mix-match__modal-product-info", children: [
1593
+ /* @__PURE__ */ jsx4("p", { className: "lb-mix-match__modal-product-title", children: /* @__PURE__ */ jsx4(
1560
1594
  "a",
1561
1595
  {
1562
1596
  href: `/products/${product.handle}`,
@@ -1565,24 +1599,24 @@ function MixMatchPickerRow({
1565
1599
  children: product.title
1566
1600
  }
1567
1601
  ) }),
1568
- /* @__PURE__ */ jsxs3("p", { className: "lb-mix-match__modal-product-price", children: [
1569
- /* @__PURE__ */ jsx3("span", { "data-row-price-sale": true, children: formatMoney2(priceCents, currency) }),
1570
- compareCents !== null && compareCents > priceCents && /* @__PURE__ */ jsx3("s", { className: "lb-mix-match__modal-product-compare", "data-row-compare": true, children: formatMoney2(compareCents, currency) })
1602
+ /* @__PURE__ */ jsxs4("p", { className: "lb-mix-match__modal-product-price", children: [
1603
+ /* @__PURE__ */ jsx4("span", { "data-row-price-sale": true, children: formatMoney2(priceCents, currency) }),
1604
+ compareCents !== null && compareCents > priceCents && /* @__PURE__ */ jsx4("s", { className: "lb-mix-match__modal-product-compare", "data-row-compare": true, children: formatMoney2(compareCents, currency) })
1571
1605
  ] }),
1572
- unitPriceText && /* @__PURE__ */ jsx3("p", { className: "lb-mix-match__modal-product-unit-price lb-bundle-product-unit-price", children: unitPriceText }),
1573
- showPicker && /* @__PURE__ */ jsx3("div", { className: "lb-bundle-variant-option-groups", children: optionNames.map((optionName, optionIndex) => {
1606
+ unitPriceText && /* @__PURE__ */ jsx4("p", { className: "lb-mix-match__modal-product-unit-price lb-bundle-product-unit-price", children: unitPriceText }),
1607
+ showPicker && /* @__PURE__ */ jsx4("div", { className: "lb-bundle-variant-option-groups", children: optionNames.map((optionName, optionIndex) => {
1574
1608
  const dropdownOptions = optionsFor(optionIndex).map((o) => ({
1575
1609
  value: o.value,
1576
1610
  label: o.value,
1577
1611
  disabled: o.disabled
1578
1612
  }));
1579
- return /* @__PURE__ */ jsxs3(
1613
+ return /* @__PURE__ */ jsxs4(
1580
1614
  "div",
1581
1615
  {
1582
1616
  className: "lb-bundle-variant-option-group",
1583
1617
  children: [
1584
- /* @__PURE__ */ jsx3("span", { className: "lb-bundle-variant-option-label", children: optionName }),
1585
- /* @__PURE__ */ jsx3(
1618
+ /* @__PURE__ */ jsx4("span", { className: "lb-bundle-variant-option-label", children: optionName }),
1619
+ /* @__PURE__ */ jsx4(
1586
1620
  VariantDropdown,
1587
1621
  {
1588
1622
  className: "lb-mix-match__variant-select-dropdown",
@@ -1597,17 +1631,17 @@ function MixMatchPickerRow({
1597
1631
  optionName
1598
1632
  );
1599
1633
  }) }),
1600
- !showPicker && variants.length === 1 && currentVariant.title !== "Default Title" && /* @__PURE__ */ jsx3("span", { className: "lb-mix-match__filled-variant", children: currentVariant.title }),
1601
- !isOos && needsMoreSpots && remainingUnits > 0 && /* @__PURE__ */ jsx3("span", { className: "lb-mix-match__modal-needs-spots", children: rule.min === 1 ? "Needs 1 spot" : `Needs ${rule.min} spots` }),
1602
- isOos ? /* @__PURE__ */ jsx3("span", { className: "lb-mix-match__modal-sold-out-label", children: "Sold out" }) : /* @__PURE__ */ jsxs3("div", { className: "lb-mix-match__modal-product-actions", children: [
1603
- showStepper && /* @__PURE__ */ jsx3("div", { className: "lb-bundle-variant-option-group lb-mix-match__qty-stepper-group", children: /* @__PURE__ */ jsxs3(
1634
+ !showPicker && variants.length === 1 && currentVariant.title !== "Default Title" && /* @__PURE__ */ jsx4("span", { className: "lb-mix-match__filled-variant", children: currentVariant.title }),
1635
+ !isOos && needsMoreSpots && remainingUnits > 0 && /* @__PURE__ */ jsx4("span", { className: "lb-mix-match__modal-needs-spots", children: rule.min === 1 ? "Needs 1 spot" : `Needs ${rule.min} spots` }),
1636
+ isOos ? /* @__PURE__ */ jsx4("span", { className: "lb-mix-match__modal-sold-out-label", children: "Sold out" }) : /* @__PURE__ */ jsxs4("div", { className: "lb-mix-match__modal-product-actions", children: [
1637
+ showStepper && /* @__PURE__ */ jsx4("div", { className: "lb-bundle-variant-option-group lb-mix-match__qty-stepper-group", children: /* @__PURE__ */ jsxs4(
1604
1638
  "div",
1605
1639
  {
1606
1640
  className: "lb-mix-match__qty-stepper",
1607
1641
  role: "group",
1608
1642
  "aria-label": "Quantity",
1609
1643
  children: [
1610
- /* @__PURE__ */ jsx3(
1644
+ /* @__PURE__ */ jsx4(
1611
1645
  "button",
1612
1646
  {
1613
1647
  type: "button",
@@ -1628,7 +1662,7 @@ function MixMatchPickerRow({
1628
1662
  children: "\u2212"
1629
1663
  }
1630
1664
  ),
1631
- /* @__PURE__ */ jsx3(
1665
+ /* @__PURE__ */ jsx4(
1632
1666
  "span",
1633
1667
  {
1634
1668
  className: "lb-mix-match__qty-stepper-value",
@@ -1637,7 +1671,7 @@ function MixMatchPickerRow({
1637
1671
  children: shownQty
1638
1672
  }
1639
1673
  ),
1640
- /* @__PURE__ */ jsx3(
1674
+ /* @__PURE__ */ jsx4(
1641
1675
  "button",
1642
1676
  {
1643
1677
  type: "button",
@@ -1661,7 +1695,7 @@ function MixMatchPickerRow({
1661
1695
  ]
1662
1696
  }
1663
1697
  ) }),
1664
- /* @__PURE__ */ jsx3(
1698
+ /* @__PURE__ */ jsx4(
1665
1699
  "button",
1666
1700
  {
1667
1701
  type: "button",
@@ -1680,7 +1714,7 @@ function MixMatchPickerRow({
1680
1714
  );
1681
1715
  }
1682
1716
  function CloseIcon() {
1683
- return /* @__PURE__ */ jsxs3(
1717
+ return /* @__PURE__ */ jsxs4(
1684
1718
  "svg",
1685
1719
  {
1686
1720
  width: "20",
@@ -1690,14 +1724,14 @@ function CloseIcon() {
1690
1724
  xmlns: "http://www.w3.org/2000/svg",
1691
1725
  "aria-hidden": "true",
1692
1726
  children: [
1693
- /* @__PURE__ */ jsx3("line", { x1: "5", y1: "5", x2: "15", y2: "15", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }),
1694
- /* @__PURE__ */ jsx3("line", { x1: "15", y1: "5", x2: "5", y2: "15", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" })
1727
+ /* @__PURE__ */ jsx4("line", { x1: "5", y1: "5", x2: "15", y2: "15", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }),
1728
+ /* @__PURE__ */ jsx4("line", { x1: "15", y1: "5", x2: "5", y2: "15", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" })
1695
1729
  ]
1696
1730
  }
1697
1731
  );
1698
1732
  }
1699
1733
  function SearchClearIcon() {
1700
- return /* @__PURE__ */ jsx3(
1734
+ return /* @__PURE__ */ jsx4(
1701
1735
  "svg",
1702
1736
  {
1703
1737
  width: "16",
@@ -1706,13 +1740,13 @@ function SearchClearIcon() {
1706
1740
  fill: "currentColor",
1707
1741
  xmlns: "http://www.w3.org/2000/svg",
1708
1742
  "aria-hidden": "true",
1709
- children: /* @__PURE__ */ jsx3("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" })
1743
+ children: /* @__PURE__ */ jsx4("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" })
1710
1744
  }
1711
1745
  );
1712
1746
  }
1713
1747
 
1714
1748
  // src/components/MixMatchBundle.tsx
1715
- import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
1749
+ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
1716
1750
  function ruleFor2(bundle, productId, variantId) {
1717
1751
  if (variantId) {
1718
1752
  const vRule = bundle.variantRules[variantId];
@@ -1745,17 +1779,14 @@ function MixMatchBundle(props) {
1745
1779
  analyticsEnabled,
1746
1780
  onAddToCart,
1747
1781
  onError,
1748
- className
1782
+ className,
1783
+ productHandle
1749
1784
  } = props;
1750
1785
  const result = useBundleData({
1751
1786
  shopDomain,
1752
1787
  storefrontAccessToken,
1753
1788
  bundleGid
1754
1789
  });
1755
- const { outOfStockBehavior } = useShopSettings({
1756
- shopDomain,
1757
- storefrontAccessToken
1758
- });
1759
1790
  const { elementRef, trackAddToCart } = useAnalytics({
1760
1791
  shopDomain,
1761
1792
  appUrl: appUrl ?? `https://${shopDomain}`,
@@ -1789,33 +1820,60 @@ function MixMatchBundle(props) {
1789
1820
  if (!bundle || seededFor === bundle.id) return;
1790
1821
  setSeededFor(bundle.id);
1791
1822
  const seedCurrency = bundle.products[0]?.priceRange.minVariantPrice.currencyCode ?? "USD";
1823
+ const pick = (product, variant, quantity) => ({
1824
+ productId: product.id,
1825
+ variantId: variant.id,
1826
+ title: product.title,
1827
+ url: `/products/${product.handle}`,
1828
+ variantTitle: variant.title,
1829
+ featuredImage: variant.image?.url ?? product.featuredImage?.url ?? null,
1830
+ price: parseFloat(variant.price.amount),
1831
+ compareAtPrice: variant.compareAtPrice ? parseFloat(variant.compareAtPrice.amount) : null,
1832
+ unitPrice: formatUnitPrice3(
1833
+ variant.unitPrice,
1834
+ variant.unitPriceMeasurement,
1835
+ seedCurrency
1836
+ ),
1837
+ quantity
1838
+ });
1792
1839
  const seeds = [];
1793
- for (const [pid, rule] of Object.entries(bundle.productRules)) {
1794
- if (!rule.required) continue;
1795
- const product = bundle.products.find((p) => p.id === pid);
1796
- const variant = product?.variants.nodes.find(
1840
+ for (const product of bundle.products) {
1841
+ let seededVariant = false;
1842
+ for (const variant2 of product.variants.nodes) {
1843
+ const vRule = bundle.variantRules[variant2.id];
1844
+ if (!vRule?.required) continue;
1845
+ if (!isVariantFulfillable3(variant2, Math.max(1, vRule.min))) continue;
1846
+ seeds.push(pick(product, variant2, Math.max(1, vRule.min)));
1847
+ seededVariant = true;
1848
+ }
1849
+ if (seededVariant) continue;
1850
+ const rule = bundle.productRules[product.id];
1851
+ if (!rule?.required) continue;
1852
+ const variant = product.variants.nodes.find(
1797
1853
  (v) => isVariantFulfillable3(v, rule.min)
1798
1854
  );
1799
- if (!product || !variant) continue;
1800
- seeds.push({
1801
- productId: product.id,
1802
- variantId: variant.id,
1803
- title: product.title,
1804
- url: `/products/${product.handle}`,
1805
- variantTitle: variant.title,
1806
- featuredImage: variant.image?.url ?? product.featuredImage?.url ?? null,
1807
- price: parseFloat(variant.price.amount),
1808
- compareAtPrice: variant.compareAtPrice ? parseFloat(variant.compareAtPrice.amount) : null,
1809
- unitPrice: formatUnitPrice3(
1810
- variant.unitPrice,
1811
- variant.unitPriceMeasurement,
1812
- seedCurrency
1813
- ),
1814
- quantity: rule.min
1815
- });
1855
+ if (!variant) continue;
1856
+ seeds.push(pick(product, variant, rule.min));
1857
+ }
1858
+ if (seeds.length === 0 && productHandle) {
1859
+ const requiredUnits2 = bundle.minQuantity ?? 0;
1860
+ const qualifies = (p) => {
1861
+ const min = bundle.productRules[p.id]?.min ?? 1;
1862
+ return min <= requiredUnits2 && p.variants.nodes.some((v) => isVariantFulfillable3(v, min));
1863
+ };
1864
+ const seed = bundle.products.find(
1865
+ (p) => p.handle === productHandle && qualifies(p)
1866
+ ) ?? bundle.products.find(qualifies);
1867
+ if (seed) {
1868
+ const min = bundle.productRules[seed.id]?.min ?? 1;
1869
+ const variant = seed.variants.nodes.find(
1870
+ (v) => isVariantFulfillable3(v, min)
1871
+ );
1872
+ if (variant) seeds.push(pick(seed, variant, min));
1873
+ }
1816
1874
  }
1817
1875
  if (seeds.length > 0) setSelections(seeds);
1818
- }, [bundle, seededFor]);
1876
+ }, [bundle, seededFor, productHandle]);
1819
1877
  const showStepper = bundle?.widgetConfig.mixMatchShowQuantitySelector !== false;
1820
1878
  const requiredUnits = bundle?.minQuantity ?? 0;
1821
1879
  const totalQuantity = useMemo6(
@@ -1975,9 +2033,9 @@ function MixMatchBundle(props) {
1975
2033
  }
1976
2034
  }, [bundle, selections, valid, onAddToCart, onError, trackAddToCart, totalQuantity]);
1977
2035
  if (result.status === "loading") {
1978
- return /* @__PURE__ */ jsxs4("div", { className: `lb-bundle lb-bundle--loading ${className ?? ""}`, children: [
1979
- /* @__PURE__ */ jsx4("div", { className: "lb-skeleton lb-skeleton--title" }),
1980
- /* @__PURE__ */ jsx4("div", { className: "lb-skeleton lb-skeleton--products" })
2036
+ return /* @__PURE__ */ jsxs5("div", { className: `lb-bundle lb-bundle--loading ${className ?? ""}`, children: [
2037
+ /* @__PURE__ */ jsx5("div", { className: "lb-skeleton lb-skeleton--title" }),
2038
+ /* @__PURE__ */ jsx5("div", { className: "lb-skeleton lb-skeleton--products" })
1981
2039
  ] });
1982
2040
  }
1983
2041
  if (result.status === "error") return null;
@@ -1996,7 +2054,7 @@ function MixMatchBundle(props) {
1996
2054
  if (requiredBlocked) return null;
1997
2055
  const currency = bundle.products[0]?.priceRange.minVariantPrice.currencyCode ?? "USD";
1998
2056
  const ctaLabel = addingToCart ? "Adding..." : bundle.widgetConfig.cta.ctaText || "Add to cart";
1999
- return /* @__PURE__ */ jsxs4(
2057
+ return /* @__PURE__ */ jsxs5(
2000
2058
  "div",
2001
2059
  {
2002
2060
  ref: (el) => {
@@ -2008,12 +2066,19 @@ function MixMatchBundle(props) {
2008
2066
  "aria-label": bundle.title,
2009
2067
  "data-required-quantity": requiredUnits,
2010
2068
  children: [
2011
- /* @__PURE__ */ jsx4("div", { className: "lb-bundle-header", children: /* @__PURE__ */ jsxs4("div", { className: "lb-bundle-header__content", children: [
2012
- /* @__PURE__ */ jsx4("h3", { className: "lb-bundle-title", children: bundle.title }),
2013
- bundle.description && /* @__PURE__ */ jsx4("p", { className: "lb-bundle-subtitle", children: bundle.description })
2069
+ /* @__PURE__ */ jsx5("div", { className: "lb-bundle-header", children: /* @__PURE__ */ jsxs5("div", { className: "lb-bundle-header__content", children: [
2070
+ /* @__PURE__ */ jsx5("h3", { className: "lb-bundle-title", children: bundle.title }),
2071
+ bundle.description && /* @__PURE__ */ jsx5("p", { className: "lb-bundle-subtitle", children: bundle.description })
2014
2072
  ] }) }),
2015
- /* @__PURE__ */ jsxs4("div", { className: "lb-mix-match__progress", "data-progress": true, children: [
2016
- /* @__PURE__ */ jsx4(
2073
+ /* @__PURE__ */ jsx5(
2074
+ BundleCountdown,
2075
+ {
2076
+ endsAt: bundle.endsAt,
2077
+ widgetConfig: bundle.widgetConfig
2078
+ }
2079
+ ),
2080
+ /* @__PURE__ */ jsxs5("div", { className: "lb-mix-match__progress", "data-progress": true, children: [
2081
+ /* @__PURE__ */ jsx5(
2017
2082
  "div",
2018
2083
  {
2019
2084
  className: "lb-mix-match__progress-segments",
@@ -2021,7 +2086,7 @@ function MixMatchBundle(props) {
2021
2086
  "aria-valuenow": shownUnits,
2022
2087
  "aria-valuemin": 0,
2023
2088
  "aria-valuemax": requiredUnits,
2024
- children: Array.from({ length: requiredUnits }).map((_, i) => /* @__PURE__ */ jsx4(
2089
+ children: Array.from({ length: requiredUnits }).map((_, i) => /* @__PURE__ */ jsx5(
2025
2090
  "span",
2026
2091
  {
2027
2092
  className: `lb-mix-match__progress-segment${i < shownUnits ? " lb-mix-match__progress-segment--filled" : ""}`,
@@ -2031,8 +2096,8 @@ function MixMatchBundle(props) {
2031
2096
  ))
2032
2097
  }
2033
2098
  ),
2034
- /* @__PURE__ */ jsxs4("div", { className: "lb-mix-match__progress-labels", children: [
2035
- /* @__PURE__ */ jsx4(
2099
+ /* @__PURE__ */ jsxs5("div", { className: "lb-mix-match__progress-labels", children: [
2100
+ /* @__PURE__ */ jsx5(
2036
2101
  "span",
2037
2102
  {
2038
2103
  className: "lb-mix-match__progress-count",
@@ -2041,7 +2106,7 @@ function MixMatchBundle(props) {
2041
2106
  children: `${shownUnits} of ${requiredUnits} added`
2042
2107
  }
2043
2108
  ),
2044
- /* @__PURE__ */ jsx4(
2109
+ /* @__PURE__ */ jsx5(
2045
2110
  "span",
2046
2111
  {
2047
2112
  className: "lb-mix-match__progress-remaining",
@@ -2052,7 +2117,7 @@ function MixMatchBundle(props) {
2052
2117
  )
2053
2118
  ] })
2054
2119
  ] }),
2055
- /* @__PURE__ */ jsx4(
2120
+ /* @__PURE__ */ jsx5(
2056
2121
  "div",
2057
2122
  {
2058
2123
  className: "lb-mix-match__slots lb-edge-fade",
@@ -2063,15 +2128,15 @@ function MixMatchBundle(props) {
2063
2128
  button provides the keyboard/AT path (its activation bubbles
2064
2129
  here); × stops propagation. */
2065
2130
  // 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
2066
- /* @__PURE__ */ jsxs4(
2131
+ /* @__PURE__ */ jsxs5(
2067
2132
  "div",
2068
2133
  {
2069
2134
  className: "lb-mix-match__slot lb-mix-match__slot--filled",
2070
2135
  onClick: () => setPickerOpen(true),
2071
2136
  children: [
2072
- item.featuredImage && /* @__PURE__ */ jsx4("div", { className: "lb-bundle-thumbnail", children: /* @__PURE__ */ jsx4("img", { src: item.featuredImage, alt: item.title, loading: "lazy" }) }),
2073
- /* @__PURE__ */ jsxs4("div", { className: "lb-mix-match__filled-info", children: [
2074
- /* @__PURE__ */ jsx4(
2137
+ item.featuredImage && /* @__PURE__ */ jsx5("div", { className: "lb-bundle-thumbnail", children: /* @__PURE__ */ jsx5("img", { src: item.featuredImage, alt: item.title, loading: "lazy" }) }),
2138
+ /* @__PURE__ */ jsxs5("div", { className: "lb-mix-match__filled-info", children: [
2139
+ /* @__PURE__ */ jsx5(
2075
2140
  "button",
2076
2141
  {
2077
2142
  type: "button",
@@ -2080,15 +2145,15 @@ function MixMatchBundle(props) {
2080
2145
  children: item.title
2081
2146
  }
2082
2147
  ),
2083
- item.variantTitle && item.variantTitle !== "Default Title" && /* @__PURE__ */ jsx4("span", { className: "lb-mix-match__filled-variant", children: item.variantTitle }),
2084
- /* @__PURE__ */ jsxs4("span", { className: "lb-mix-match__filled-price", children: [
2085
- item.compareAtPrice !== null && item.compareAtPrice > item.price && /* @__PURE__ */ jsx4("s", { className: "lb-mix-match__filled-compare", children: formatMoney3(item.compareAtPrice, currency) }),
2086
- /* @__PURE__ */ jsx4("span", { className: "lb-bundle-product-price", children: formatMoney3(item.price, currency) }),
2087
- /* @__PURE__ */ jsx4("span", { className: "lb-bundle-qty-inline", children: `\xD7${item.quantity}` })
2148
+ item.variantTitle && item.variantTitle !== "Default Title" && /* @__PURE__ */ jsx5("span", { className: "lb-mix-match__filled-variant", children: item.variantTitle }),
2149
+ /* @__PURE__ */ jsxs5("span", { className: "lb-mix-match__filled-price", children: [
2150
+ item.compareAtPrice !== null && item.compareAtPrice > item.price && /* @__PURE__ */ jsx5("s", { className: "lb-mix-match__filled-compare", children: formatMoney3(item.compareAtPrice, currency) }),
2151
+ /* @__PURE__ */ jsx5("span", { className: "lb-bundle-product-price", children: formatMoney3(item.price, currency) }),
2152
+ /* @__PURE__ */ jsx5("span", { className: "lb-bundle-qty-inline", children: `\xD7${item.quantity}` })
2088
2153
  ] }),
2089
- item.unitPrice && /* @__PURE__ */ jsx4("span", { className: "lb-bundle-product-unit-price", children: item.unitPrice })
2154
+ item.unitPrice && /* @__PURE__ */ jsx5("span", { className: "lb-bundle-product-unit-price", children: item.unitPrice })
2090
2155
  ] }),
2091
- canRemoveItem(bundle, selections, item) ? /* @__PURE__ */ jsx4(
2156
+ canRemoveItem(bundle, selections, item) ? /* @__PURE__ */ jsx5(
2092
2157
  "button",
2093
2158
  {
2094
2159
  type: "button",
@@ -2098,13 +2163,13 @@ function MixMatchBundle(props) {
2098
2163
  e.stopPropagation();
2099
2164
  removeSlot(index);
2100
2165
  },
2101
- children: /* @__PURE__ */ jsx4(CloseIcon2, {})
2166
+ children: /* @__PURE__ */ jsx5(CloseIcon2, {})
2102
2167
  }
2103
2168
  ) : (
2104
2169
  /* Required pick at its floor — quiet state chip instead of
2105
2170
  the ×; removal returns once another slot covers the
2106
2171
  product's minimum (variant swap flow). */
2107
- /* @__PURE__ */ jsx4("span", { className: "lb-mix-match__slot-required", children: "Required" })
2172
+ /* @__PURE__ */ jsx5("span", { className: "lb-mix-match__slot-required", children: "Required" })
2108
2173
  )
2109
2174
  ]
2110
2175
  },
@@ -2113,7 +2178,7 @@ function MixMatchBundle(props) {
2113
2178
  ))
2114
2179
  }
2115
2180
  ),
2116
- totalQuantity < requiredUnits && /* @__PURE__ */ jsxs4(
2181
+ totalQuantity < requiredUnits && /* @__PURE__ */ jsxs5(
2117
2182
  "button",
2118
2183
  {
2119
2184
  type: "button",
@@ -2121,34 +2186,34 @@ function MixMatchBundle(props) {
2121
2186
  "data-add-product-trigger": true,
2122
2187
  onClick: () => setPickerOpen(true),
2123
2188
  children: [
2124
- /* @__PURE__ */ jsx4("span", { className: "lb-mix-match__add-product-icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx4(PlusIcon, {}) }),
2125
- /* @__PURE__ */ jsx4("span", { className: "lb-mix-match__add-product-label", children: "Add a product" })
2189
+ /* @__PURE__ */ jsx5("span", { className: "lb-mix-match__add-product-icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx5(PlusIcon, {}) }),
2190
+ /* @__PURE__ */ jsx5("span", { className: "lb-mix-match__add-product-label", children: "Add a product" })
2126
2191
  ]
2127
2192
  }
2128
2193
  ),
2129
- /* @__PURE__ */ jsx4("div", { className: "lb-bundle-divider" }),
2130
- selections.length > 0 && /* @__PURE__ */ jsxs4("div", { className: "lb-bundle-summary", "data-pricing-section": true, children: [
2131
- /* @__PURE__ */ jsxs4("div", { className: "lb-bundle-summary__text", children: [
2132
- /* @__PURE__ */ jsx4("span", { className: "lb-bundle-summary__label", children: "Bundle total" }),
2133
- bundle.widgetConfig.savingsBar.visible && summary.savings > 0 && /* @__PURE__ */ jsxs4("p", { className: "lb-bundle-savings-line", "data-savings-bar": true, children: [
2194
+ /* @__PURE__ */ jsx5("div", { className: "lb-bundle-divider" }),
2195
+ selections.length > 0 && /* @__PURE__ */ jsxs5("div", { className: "lb-bundle-summary", "data-pricing-section": true, children: [
2196
+ /* @__PURE__ */ jsxs5("div", { className: "lb-bundle-summary__text", children: [
2197
+ /* @__PURE__ */ jsx5("span", { className: "lb-bundle-summary__label", children: "Bundle total" }),
2198
+ bundle.widgetConfig.savingsBar.visible && summary.savings > 0 && /* @__PURE__ */ jsxs5("p", { className: "lb-bundle-savings-line", "data-savings-bar": true, children: [
2134
2199
  "You save",
2135
2200
  " ",
2136
- /* @__PURE__ */ jsx4("span", { "data-savings-amount": true, children: formatMoney3(summary.savings, currency) }),
2201
+ /* @__PURE__ */ jsx5("span", { "data-savings-amount": true, children: formatMoney3(summary.savings, currency) }),
2137
2202
  " ",
2138
- /* @__PURE__ */ jsxs4("span", { "data-savings-percent": true, children: [
2203
+ /* @__PURE__ */ jsxs5("span", { "data-savings-percent": true, children: [
2139
2204
  "(",
2140
2205
  summary.savingsPercent,
2141
2206
  "%)"
2142
2207
  ] })
2143
2208
  ] })
2144
2209
  ] }),
2145
- /* @__PURE__ */ jsxs4("span", { className: "lb-bundle-summary__prices", children: [
2146
- bundle.widgetConfig.pricing.showComparePrice && summary.savings > 0 && /* @__PURE__ */ jsx4("span", { className: "lb-bundle-compare-price", "data-compare-price": true, children: formatMoney3(summary.comparePrice, currency) }),
2147
- /* @__PURE__ */ jsx4("span", { className: "lb-bundle-sale-price", "data-sale-price": true, children: formatMoney3(summary.salePrice, currency) })
2210
+ /* @__PURE__ */ jsxs5("span", { className: "lb-bundle-summary__prices", children: [
2211
+ bundle.widgetConfig.pricing.showComparePrice && summary.savings > 0 && /* @__PURE__ */ jsx5("span", { className: "lb-bundle-compare-price", "data-compare-price": true, children: formatMoney3(summary.comparePrice, currency) }),
2212
+ /* @__PURE__ */ jsx5("span", { className: "lb-bundle-sale-price", "data-sale-price": true, children: formatMoney3(summary.salePrice, currency) })
2148
2213
  ] })
2149
2214
  ] }),
2150
- cartError && /* @__PURE__ */ jsx4("p", { className: "lb-bundle__error", role: "alert", children: cartError }),
2151
- /* @__PURE__ */ jsx4(
2215
+ cartError && /* @__PURE__ */ jsx5("p", { className: "lb-bundle__error", role: "alert", children: cartError }),
2216
+ /* @__PURE__ */ jsx5(
2152
2217
  "button",
2153
2218
  {
2154
2219
  className: "lb-bundle__cta",
@@ -2158,10 +2223,9 @@ function MixMatchBundle(props) {
2158
2223
  children: ctaLabel
2159
2224
  }
2160
2225
  ),
2161
- pickerOpen && /* @__PURE__ */ jsx4(
2226
+ pickerOpen && /* @__PURE__ */ jsx5(
2162
2227
  MixMatchPicker,
2163
2228
  {
2164
- outOfStockBehavior,
2165
2229
  bundle,
2166
2230
  currency,
2167
2231
  requiredQty: requiredUnits,
@@ -2199,7 +2263,7 @@ function countInStockProducts(bundle) {
2199
2263
  return count;
2200
2264
  }
2201
2265
  function PlusIcon() {
2202
- return /* @__PURE__ */ jsxs4(
2266
+ return /* @__PURE__ */ jsxs5(
2203
2267
  "svg",
2204
2268
  {
2205
2269
  width: "18",
@@ -2209,14 +2273,14 @@ function PlusIcon() {
2209
2273
  xmlns: "http://www.w3.org/2000/svg",
2210
2274
  "aria-hidden": "true",
2211
2275
  children: [
2212
- /* @__PURE__ */ jsx4("line", { x1: "9", y1: "3", x2: "9", y2: "15", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }),
2213
- /* @__PURE__ */ jsx4("line", { x1: "3", y1: "9", x2: "15", y2: "9", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" })
2276
+ /* @__PURE__ */ jsx5("line", { x1: "9", y1: "3", x2: "9", y2: "15", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }),
2277
+ /* @__PURE__ */ jsx5("line", { x1: "3", y1: "9", x2: "15", y2: "9", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" })
2214
2278
  ]
2215
2279
  }
2216
2280
  );
2217
2281
  }
2218
2282
  function CloseIcon2() {
2219
- return /* @__PURE__ */ jsxs4(
2283
+ return /* @__PURE__ */ jsxs5(
2220
2284
  "svg",
2221
2285
  {
2222
2286
  width: "16",
@@ -2226,8 +2290,8 @@ function CloseIcon2() {
2226
2290
  xmlns: "http://www.w3.org/2000/svg",
2227
2291
  "aria-hidden": "true",
2228
2292
  children: [
2229
- /* @__PURE__ */ jsx4("line", { x1: "5", y1: "5", x2: "15", y2: "15", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }),
2230
- /* @__PURE__ */ jsx4("line", { x1: "15", y1: "5", x2: "5", y2: "15", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" })
2293
+ /* @__PURE__ */ jsx5("line", { x1: "5", y1: "5", x2: "15", y2: "15", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }),
2294
+ /* @__PURE__ */ jsx5("line", { x1: "15", y1: "5", x2: "5", y2: "15", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" })
2231
2295
  ]
2232
2296
  }
2233
2297
  );
@@ -2241,10 +2305,13 @@ import {
2241
2305
  calculateTierSavings,
2242
2306
  getActiveTier,
2243
2307
  getMinTierQuantity,
2308
+ bestValueTierIndex,
2309
+ resolveDefaultTierIndex,
2310
+ resolvePopularTierIndex,
2244
2311
  isVariantFulfillable as isVariantFulfillable4,
2245
2312
  shouldShowLowStockBadge as shouldShowLowStockBadge2
2246
2313
  } from "@lime-bundles/core";
2247
- import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
2314
+ import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
2248
2315
  function VolumeBundle(props) {
2249
2316
  const {
2250
2317
  shopDomain,
@@ -2271,7 +2338,24 @@ function VolumeBundle(props) {
2271
2338
  const [quantity, setQuantity] = useState9(1);
2272
2339
  const [addingToCart, setAddingToCart] = useState9(false);
2273
2340
  const [cartError, setCartError] = useState9(null);
2341
+ const [seededFor, setSeededFor] = useState9(null);
2274
2342
  const bundle = result.status === "success" && result.bundle.bundleType === "volume" ? result.bundle : null;
2343
+ useEffect12(() => {
2344
+ if (!bundle || seededFor === bundle.id) return;
2345
+ setSeededFor(bundle.id);
2346
+ const tiers = bundle.volumeTiers;
2347
+ if (tiers.length === 0) return;
2348
+ const best = bestValueTierIndex(
2349
+ tiers,
2350
+ bundle.discountConfig.discountType
2351
+ );
2352
+ const idx = resolveDefaultTierIndex(
2353
+ bundle.widgetConfig.defaultTier,
2354
+ tiers.length,
2355
+ best
2356
+ );
2357
+ setQuantity(tiers[idx].minQuantity);
2358
+ }, [bundle, seededFor]);
2275
2359
  const setConfigVarsRef = useWidgetConfigVars(bundle?.widgetConfig);
2276
2360
  const tiersEdgeFadeRef = useEdgeFade();
2277
2361
  useEffect12(() => {
@@ -2298,6 +2382,11 @@ function VolumeBundle(props) {
2298
2382
  const minTierQty = bundle ? getMinTierQuantity(bundle.volumeTiers) : 1;
2299
2383
  const isSoldOut = variants.length > 0 && !variants.some((v) => isVariantFulfillable4(v, minTierQty));
2300
2384
  const displayVariant = selectedVariant ?? variants.find((v) => isVariantFulfillable4(v, minTierQty)) ?? variants[0];
2385
+ const tierAvailable = useCallback7(
2386
+ (tierQty) => Boolean(displayVariant && isVariantFulfillable4(displayVariant, tierQty)),
2387
+ [displayVariant]
2388
+ );
2389
+ const selectedTierUnavailable = !isSoldOut && !tierAvailable(quantity);
2301
2390
  const basePrice = displayVariant ? parseFloat(displayVariant.price.amount) : product ? parseFloat(product.priceRange.minVariantPrice.amount) : 0;
2302
2391
  const currency = product?.priceRange.minVariantPrice.currencyCode ?? "USD";
2303
2392
  const thumbImage = displayVariant?.image ?? product?.featuredImage ?? null;
@@ -2317,19 +2406,16 @@ function VolumeBundle(props) {
2317
2406
  );
2318
2407
  const activeTier = bundle ? getActiveTier(bundle.volumeTiers, quantity) : null;
2319
2408
  const popularTierIndex = useMemo7(() => {
2320
- if (!bundle?.widgetConfig.popularBadge.visible || tierSavings.length === 0) {
2321
- return -1;
2322
- }
2323
- const pinned = bundle.widgetConfig.popularBadge.tierIndex;
2324
- if (pinned !== void 0) {
2325
- return Math.min(Math.max(pinned, 0), tierSavings.length - 1);
2326
- }
2327
- let best = 0;
2328
- for (let i = 1; i < tierSavings.length; i++) {
2329
- if (tierSavings[i].savings > tierSavings[best].savings) best = i;
2330
- }
2331
- return best;
2332
- }, [bundle, tierSavings]);
2409
+ if (!bundle || bundle.volumeTiers.length === 0) return -1;
2410
+ return resolvePopularTierIndex(
2411
+ bundle.widgetConfig.popularBadge.tierIndex,
2412
+ bundle.widgetConfig.popularBadge.visible !== false,
2413
+ bestValueTierIndex(
2414
+ bundle.volumeTiers,
2415
+ bundle.discountConfig.discountType
2416
+ )
2417
+ );
2418
+ }, [bundle]);
2333
2419
  const activeUnitPrice = tierSavings.find((ts) => ts.tier === activeTier)?.unitPrice ?? basePrice;
2334
2420
  const undiscountedTotal = basePrice * quantity;
2335
2421
  const volumeTotal = activeUnitPrice * quantity;
@@ -2381,15 +2467,15 @@ function VolumeBundle(props) {
2381
2467
  tierSavings
2382
2468
  ]);
2383
2469
  if (result.status === "loading") {
2384
- return /* @__PURE__ */ jsxs5("div", { className: `lb-bundle lb-bundle--loading ${className ?? ""}`, children: [
2385
- /* @__PURE__ */ jsx5("div", { className: "lb-skeleton lb-skeleton--title" }),
2386
- /* @__PURE__ */ jsx5("div", { className: "lb-skeleton lb-skeleton--tiers" })
2470
+ return /* @__PURE__ */ jsxs6("div", { className: `lb-bundle lb-bundle--loading ${className ?? ""}`, children: [
2471
+ /* @__PURE__ */ jsx6("div", { className: "lb-skeleton lb-skeleton--title" }),
2472
+ /* @__PURE__ */ jsx6("div", { className: "lb-skeleton lb-skeleton--tiers" })
2387
2473
  ] });
2388
2474
  }
2389
2475
  if (result.status === "error") return null;
2390
2476
  if (!bundle) return null;
2391
2477
  if (!product) return null;
2392
- return /* @__PURE__ */ jsxs5(
2478
+ return /* @__PURE__ */ jsxs6(
2393
2479
  "div",
2394
2480
  {
2395
2481
  ref: (el) => {
@@ -2400,12 +2486,19 @@ function VolumeBundle(props) {
2400
2486
  role: "region",
2401
2487
  "aria-label": bundle.title,
2402
2488
  children: [
2403
- /* @__PURE__ */ jsx5("div", { className: "lb-bundle-header", children: /* @__PURE__ */ jsxs5("div", { className: "lb-bundle-header__content", children: [
2404
- /* @__PURE__ */ jsx5("h3", { className: "lb-bundle-title", children: bundle.title }),
2405
- bundle.description && /* @__PURE__ */ jsx5("p", { className: "lb-bundle-subtitle", children: bundle.description })
2489
+ /* @__PURE__ */ jsx6("div", { className: "lb-bundle-header", children: /* @__PURE__ */ jsxs6("div", { className: "lb-bundle-header__content", children: [
2490
+ /* @__PURE__ */ jsx6("h3", { className: "lb-bundle-title", children: bundle.title }),
2491
+ bundle.description && /* @__PURE__ */ jsx6("p", { className: "lb-bundle-subtitle", children: bundle.description })
2406
2492
  ] }) }),
2407
- /* @__PURE__ */ jsxs5("div", { className: "lb-bundle-product-row lb-bundle-product-row--volume", children: [
2408
- thumbImage && /* @__PURE__ */ jsx5(
2493
+ /* @__PURE__ */ jsx6(
2494
+ BundleCountdown,
2495
+ {
2496
+ endsAt: bundle.endsAt,
2497
+ widgetConfig: bundle.widgetConfig
2498
+ }
2499
+ ),
2500
+ /* @__PURE__ */ jsxs6("div", { className: "lb-bundle-product-row lb-bundle-product-row--volume", children: [
2501
+ thumbImage && /* @__PURE__ */ jsx6(
2409
2502
  "img",
2410
2503
  {
2411
2504
  src: thumbImage.url,
@@ -2414,20 +2507,20 @@ function VolumeBundle(props) {
2414
2507
  loading: "lazy"
2415
2508
  }
2416
2509
  ),
2417
- /* @__PURE__ */ jsxs5("div", { className: "lb-bundle__product-info", children: [
2418
- /* @__PURE__ */ jsx5("p", { className: "lb-bundle__product-title", children: product.title }),
2419
- /* @__PURE__ */ jsxs5("p", { className: "lb-bundle__product-price", children: [
2510
+ /* @__PURE__ */ jsxs6("div", { className: "lb-bundle__product-info", children: [
2511
+ /* @__PURE__ */ jsx6("p", { className: "lb-bundle__product-title", children: product.title }),
2512
+ /* @__PURE__ */ jsxs6("p", { className: "lb-bundle__product-price", children: [
2420
2513
  formatMoney4(basePrice, currency),
2421
2514
  " each"
2422
2515
  ] }),
2423
- unitPriceText && /* @__PURE__ */ jsx5("p", { className: "lb-bundle__product-unit-price", children: unitPriceText }),
2424
- showPicker && /* @__PURE__ */ jsx5("div", { className: "lb-bundle__product-variant-pickers", children: optionNames.map((optionName, optionIndex) => {
2516
+ unitPriceText && /* @__PURE__ */ jsx6("p", { className: "lb-bundle__product-unit-price", children: unitPriceText }),
2517
+ showPicker && /* @__PURE__ */ jsx6("div", { className: "lb-bundle__product-variant-pickers", children: optionNames.map((optionName, optionIndex) => {
2425
2518
  const dropdownOptions = optionsFor(optionIndex).map((o) => ({
2426
2519
  value: o.value,
2427
2520
  label: o.value,
2428
2521
  disabled: o.disabled
2429
2522
  }));
2430
- return /* @__PURE__ */ jsx5(
2523
+ return /* @__PURE__ */ jsx6(
2431
2524
  VariantDropdown,
2432
2525
  {
2433
2526
  options: dropdownOptions,
@@ -2440,37 +2533,51 @@ function VolumeBundle(props) {
2440
2533
  }) })
2441
2534
  ] })
2442
2535
  ] }),
2443
- /* @__PURE__ */ jsx5(
2536
+ /* @__PURE__ */ jsx6(
2444
2537
  "div",
2445
2538
  {
2446
2539
  className: "lb-bundle__tiers lb-edge-fade",
2447
- role: "table",
2448
- "aria-label": "Volume discounts",
2540
+ role: "radiogroup",
2541
+ "aria-label": "Select quantity",
2449
2542
  ref: tiersEdgeFadeRef,
2450
2543
  children: tierSavings.map((ts, tierIndex) => {
2451
2544
  const savingsPercent = Math.round(ts.savingsPercent);
2452
2545
  const showCompare = bundle.widgetConfig.pricing.showComparePrice && ts.savings > 0;
2453
- return /* @__PURE__ */ jsxs5(
2546
+ const isChecked = activeTier === ts.tier;
2547
+ const available = tierAvailable(ts.tier.minQuantity);
2548
+ return /* @__PURE__ */ jsxs6(
2454
2549
  "div",
2455
2550
  {
2456
- className: `lb-bundle__tier ${ts.isActive ? "lb-bundle__tier--active" : ""}`,
2457
- role: "row",
2551
+ className: `lb-bundle__tier ${ts.isActive ? "lb-bundle__tier--active" : ""} ${available ? "" : "lb-bundle__tier--oos"}`,
2552
+ role: "radio",
2553
+ "aria-checked": isChecked,
2554
+ "aria-disabled": available ? void 0 : true,
2555
+ tabIndex: isChecked ? 0 : -1,
2556
+ onClick: () => {
2557
+ if (available) setQuantity(ts.tier.minQuantity);
2558
+ },
2559
+ onKeyDown: (e) => {
2560
+ if ((e.key === "Enter" || e.key === " ") && available) {
2561
+ e.preventDefault();
2562
+ setQuantity(ts.tier.minQuantity);
2563
+ }
2564
+ },
2458
2565
  children: [
2459
- /* @__PURE__ */ jsx5("span", { className: "lb-bundle__tier-radio", "aria-hidden": "true", children: /* @__PURE__ */ jsx5("span", { className: "lb-bundle__tier-radio-dot" }) }),
2460
- /* @__PURE__ */ jsxs5("span", { className: "lb-bundle__tier-info", role: "cell", children: [
2461
- /* @__PURE__ */ jsxs5("span", { className: "lb-bundle__tier-label", children: [
2566
+ /* @__PURE__ */ jsx6("span", { className: "lb-bundle__tier-radio", "aria-hidden": "true", children: /* @__PURE__ */ jsx6("span", { className: "lb-bundle__tier-radio-dot" }) }),
2567
+ /* @__PURE__ */ jsxs6("span", { className: "lb-bundle__tier-info", children: [
2568
+ /* @__PURE__ */ jsxs6("span", { className: "lb-bundle__tier-label", children: [
2462
2569
  "Buy ",
2463
2570
  ts.tier.minQuantity
2464
2571
  ] }),
2465
- /* @__PURE__ */ jsxs5("span", { className: "lb-bundle__tier-price", children: [
2466
- showCompare && /* @__PURE__ */ jsx5("span", { className: "lb-bundle__tier-compare", children: formatMoney4(basePrice, currency) }),
2467
- /* @__PURE__ */ jsx5("span", { children: formatMoney4(ts.unitPrice, currency) }),
2468
- /* @__PURE__ */ jsx5("span", { className: "lb-bundle__tier-unit", children: "each" })
2572
+ /* @__PURE__ */ jsxs6("span", { className: "lb-bundle__tier-price", children: [
2573
+ showCompare && /* @__PURE__ */ jsx6("span", { className: "lb-bundle__tier-compare", children: formatMoney4(basePrice, currency) }),
2574
+ /* @__PURE__ */ jsx6("span", { children: formatMoney4(ts.unitPrice, currency) }),
2575
+ /* @__PURE__ */ jsx6("span", { className: "lb-bundle__tier-unit", children: "each" })
2469
2576
  ] })
2470
2577
  ] }),
2471
- (tierIndex === popularTierIndex || savingsPercent > 0) && /* @__PURE__ */ jsxs5("span", { className: "lb-bundle__tier-right", role: "cell", children: [
2472
- tierIndex === popularTierIndex && /* @__PURE__ */ jsx5("span", { className: "lb-bundle__tier-badge", children: bundle.widgetConfig.popularBadge.text }),
2473
- savingsPercent > 0 && /* @__PURE__ */ jsxs5("span", { className: "lb-bundle__tier-savings", children: [
2578
+ (tierIndex === popularTierIndex || savingsPercent > 0) && /* @__PURE__ */ jsxs6("span", { className: "lb-bundle__tier-right", children: [
2579
+ tierIndex === popularTierIndex && /* @__PURE__ */ jsx6("span", { className: "lb-bundle__tier-badge", children: bundle.widgetConfig.popularBadge.text }),
2580
+ savingsPercent > 0 && /* @__PURE__ */ jsxs6("span", { className: "lb-bundle__tier-savings", children: [
2474
2581
  "Save ",
2475
2582
  savingsPercent,
2476
2583
  "%"
@@ -2483,10 +2590,10 @@ function VolumeBundle(props) {
2483
2590
  })
2484
2591
  }
2485
2592
  ),
2486
- /* @__PURE__ */ jsxs5("div", { className: "lb-bundle__quantity-selector", children: [
2487
- /* @__PURE__ */ jsx5("label", { htmlFor: `lb-qty-${bundle.id}`, children: "Quantity" }),
2488
- /* @__PURE__ */ jsxs5("div", { className: "lb-bundle__quantity-control", children: [
2489
- /* @__PURE__ */ jsx5(
2593
+ /* @__PURE__ */ jsxs6("div", { className: "lb-bundle__quantity-selector", children: [
2594
+ /* @__PURE__ */ jsx6("label", { htmlFor: `lb-qty-${bundle.id}`, children: "Quantity" }),
2595
+ /* @__PURE__ */ jsxs6("div", { className: "lb-bundle__quantity-control", children: [
2596
+ /* @__PURE__ */ jsx6(
2490
2597
  "button",
2491
2598
  {
2492
2599
  "aria-label": "Decrease quantity",
@@ -2494,7 +2601,7 @@ function VolumeBundle(props) {
2494
2601
  children: "\u2212"
2495
2602
  }
2496
2603
  ),
2497
- /* @__PURE__ */ jsx5(
2604
+ /* @__PURE__ */ jsx6(
2498
2605
  "input",
2499
2606
  {
2500
2607
  id: `lb-qty-${bundle.id}`,
@@ -2508,7 +2615,7 @@ function VolumeBundle(props) {
2508
2615
  className: "lb-bundle__quantity-input"
2509
2616
  }
2510
2617
  ),
2511
- /* @__PURE__ */ jsx5(
2618
+ /* @__PURE__ */ jsx6(
2512
2619
  "button",
2513
2620
  {
2514
2621
  "aria-label": "Increase quantity",
@@ -2518,23 +2625,23 @@ function VolumeBundle(props) {
2518
2625
  )
2519
2626
  ] })
2520
2627
  ] }),
2521
- cartError && /* @__PURE__ */ jsx5("p", { className: "lb-bundle__error", role: "alert", children: cartError }),
2628
+ cartError && /* @__PURE__ */ jsx6("p", { className: "lb-bundle__error", role: "alert", children: cartError }),
2522
2629
  bundle && displayVariant && shouldShowLowStockBadge2(
2523
2630
  displayVariant,
2524
2631
  minTierQty,
2525
2632
  bundle.widgetConfig.lowStockThreshold,
2526
2633
  bundle.widgetConfig.showLowStockBadge
2527
- ) && /* @__PURE__ */ jsxs5("span", { className: "lb-bundle-low-stock-badge", children: [
2634
+ ) && /* @__PURE__ */ jsxs6("span", { className: "lb-bundle-low-stock-badge", children: [
2528
2635
  "Only ",
2529
2636
  displayVariant.quantityAvailable,
2530
2637
  " left"
2531
2638
  ] }),
2532
- /* @__PURE__ */ jsx5("div", { className: "lb-bundle-divider" }),
2533
- /* @__PURE__ */ jsxs5("div", { className: "lb-bundle-summary", children: [
2534
- /* @__PURE__ */ jsxs5("div", { className: "lb-bundle-summary__text", children: [
2535
- /* @__PURE__ */ jsxs5("span", { className: "lb-bundle-summary__label", "data-total-label": true, children: [
2639
+ /* @__PURE__ */ jsx6("div", { className: "lb-bundle-divider" }),
2640
+ /* @__PURE__ */ jsxs6("div", { className: "lb-bundle-summary", children: [
2641
+ /* @__PURE__ */ jsxs6("div", { className: "lb-bundle-summary__text", children: [
2642
+ /* @__PURE__ */ jsxs6("span", { className: "lb-bundle-summary__label", "data-total-label": true, children: [
2536
2643
  "Total",
2537
- bundle.widgetConfig.pricing.showItemCount && /* @__PURE__ */ jsxs5("span", { "data-item-count": true, children: [
2644
+ bundle.widgetConfig.pricing.showItemCount && /* @__PURE__ */ jsxs6("span", { "data-item-count": true, children: [
2538
2645
  " ",
2539
2646
  "(",
2540
2647
  quantity,
@@ -2543,31 +2650,31 @@ function VolumeBundle(props) {
2543
2650
  ")"
2544
2651
  ] })
2545
2652
  ] }),
2546
- bundle.widgetConfig.savingsBar.visible && volumeSavings > 0 && /* @__PURE__ */ jsxs5("p", { className: "lb-bundle-savings-line", "data-savings-bar": true, children: [
2653
+ bundle.widgetConfig.savingsBar.visible && volumeSavings > 0 && /* @__PURE__ */ jsxs6("p", { className: "lb-bundle-savings-line", "data-savings-bar": true, children: [
2547
2654
  "You save",
2548
2655
  " ",
2549
- /* @__PURE__ */ jsx5("span", { "data-savings-amount": true, children: formatMoney4(volumeSavings, currency) }),
2656
+ /* @__PURE__ */ jsx6("span", { "data-savings-amount": true, children: formatMoney4(volumeSavings, currency) }),
2550
2657
  " ",
2551
- /* @__PURE__ */ jsxs5("span", { "data-savings-percent": true, children: [
2658
+ /* @__PURE__ */ jsxs6("span", { "data-savings-percent": true, children: [
2552
2659
  "(",
2553
2660
  volumeSavingsPercent,
2554
2661
  "%)"
2555
2662
  ] })
2556
2663
  ] })
2557
2664
  ] }),
2558
- /* @__PURE__ */ jsxs5("span", { className: "lb-bundle-summary__prices", children: [
2559
- bundle.widgetConfig.pricing.showComparePrice && volumeSavings > 0 && /* @__PURE__ */ jsx5("span", { className: "lb-bundle-compare-price", "data-compare-price": true, children: formatMoney4(undiscountedTotal, currency) }),
2560
- /* @__PURE__ */ jsx5("span", { className: "lb-bundle-sale-price", "data-total-price": true, children: formatMoney4(volumeTotal, currency) })
2665
+ /* @__PURE__ */ jsxs6("span", { className: "lb-bundle-summary__prices", children: [
2666
+ bundle.widgetConfig.pricing.showComparePrice && volumeSavings > 0 && /* @__PURE__ */ jsx6("span", { className: "lb-bundle-compare-price", "data-compare-price": true, children: formatMoney4(undiscountedTotal, currency) }),
2667
+ /* @__PURE__ */ jsx6("span", { className: "lb-bundle-sale-price", "data-total-price": true, children: formatMoney4(volumeTotal, currency) })
2561
2668
  ] })
2562
2669
  ] }),
2563
- /* @__PURE__ */ jsx5(
2670
+ /* @__PURE__ */ jsx6(
2564
2671
  "button",
2565
2672
  {
2566
2673
  className: "lb-bundle__cta",
2567
2674
  onClick: handleAddToCart,
2568
- disabled: addingToCart || isSoldOut,
2675
+ disabled: addingToCart || isSoldOut || selectedTierUnavailable,
2569
2676
  "aria-busy": addingToCart,
2570
- children: addingToCart ? "Adding..." : isSoldOut ? "Sold out" : bundle.widgetConfig.cta.ctaText ?? `Add ${quantity} to Cart`
2677
+ children: addingToCart ? "Adding..." : isSoldOut || selectedTierUnavailable ? "Sold out" : bundle.widgetConfig.cta.ctaText ?? `Add ${quantity} to Cart`
2571
2678
  }
2572
2679
  )
2573
2680
  ]
@@ -2582,7 +2689,7 @@ import {
2582
2689
  formatUnitPrice as formatUnitPrice5,
2583
2690
  isVariantFulfillable as isVariantFulfillable5
2584
2691
  } from "@lime-bundles/core";
2585
- import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
2692
+ import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
2586
2693
  function discountedUnit(price, percent) {
2587
2694
  const cents = Math.round(price * 100);
2588
2695
  const discounted = cents - Math.floor(cents * percent / 100);
@@ -2706,9 +2813,9 @@ function BogoBundle(props) {
2706
2813
  }
2707
2814
  }, [bundle, buyProduct, getProduct, selectedVariants, resolveVariant, onAddToCart, onError, trackAddToCart, percent]);
2708
2815
  if (result.status === "loading") {
2709
- return /* @__PURE__ */ jsxs6("div", { className: `lb-bundle lb-bundle--loading ${className ?? ""}`, children: [
2710
- /* @__PURE__ */ jsx6("div", { className: "lb-skeleton lb-skeleton--title" }),
2711
- /* @__PURE__ */ jsx6("div", { className: "lb-skeleton lb-skeleton--products" })
2816
+ return /* @__PURE__ */ jsxs7("div", { className: `lb-bundle lb-bundle--loading ${className ?? ""}`, children: [
2817
+ /* @__PURE__ */ jsx7("div", { className: "lb-skeleton lb-skeleton--title" }),
2818
+ /* @__PURE__ */ jsx7("div", { className: "lb-skeleton lb-skeleton--products" })
2712
2819
  ] });
2713
2820
  }
2714
2821
  if (result.status === "error") return null;
@@ -2725,7 +2832,7 @@ function BogoBundle(props) {
2725
2832
  const showCompare = bundle.widgetConfig.pricing.showComparePrice && savings > 0;
2726
2833
  const showSavings = bundle.widgetConfig.savingsBar.visible && savings > 0;
2727
2834
  const badge = percent === 100 ? "Free" : `${percent}% off`;
2728
- return /* @__PURE__ */ jsxs6(
2835
+ return /* @__PURE__ */ jsxs7(
2729
2836
  "div",
2730
2837
  {
2731
2838
  ref: (el) => {
@@ -2736,12 +2843,19 @@ function BogoBundle(props) {
2736
2843
  role: "region",
2737
2844
  "aria-label": bundle.title,
2738
2845
  children: [
2739
- /* @__PURE__ */ jsx6("div", { className: "lb-bundle-header", children: /* @__PURE__ */ jsxs6("div", { className: "lb-bundle-header__content", children: [
2740
- /* @__PURE__ */ jsx6("h3", { className: "lb-bundle-title", children: bundle.title }),
2741
- bundle.description && /* @__PURE__ */ jsx6("p", { className: "lb-bundle-subtitle", children: bundle.description })
2846
+ /* @__PURE__ */ jsx7("div", { className: "lb-bundle-header", children: /* @__PURE__ */ jsxs7("div", { className: "lb-bundle-header__content", children: [
2847
+ /* @__PURE__ */ jsx7("h3", { className: "lb-bundle-title", children: bundle.title }),
2848
+ bundle.description && /* @__PURE__ */ jsx7("p", { className: "lb-bundle-subtitle", children: bundle.description })
2742
2849
  ] }) }),
2743
- /* @__PURE__ */ jsxs6("div", { className: "lb-bundle__products", children: [
2744
- /* @__PURE__ */ jsx6(
2850
+ /* @__PURE__ */ jsx7(
2851
+ BundleCountdown,
2852
+ {
2853
+ endsAt: bundle.endsAt,
2854
+ widgetConfig: bundle.widgetConfig
2855
+ }
2856
+ ),
2857
+ /* @__PURE__ */ jsxs7("div", { className: "lb-bundle__products", children: [
2858
+ /* @__PURE__ */ jsx7(
2745
2859
  BogoProductRow,
2746
2860
  {
2747
2861
  side: "buy",
@@ -2753,11 +2867,11 @@ function BogoBundle(props) {
2753
2867
  onVariantChange: handleVariantChange
2754
2868
  }
2755
2869
  ),
2756
- /* @__PURE__ */ jsx6("div", { className: "lb-bogo__plus", "aria-hidden": "true", children: /* @__PURE__ */ jsxs6("svg", { width: "12", height: "12", viewBox: "0 0 18 18", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
2757
- /* @__PURE__ */ jsx6("line", { x1: "9", y1: "3", x2: "9", y2: "15", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }),
2758
- /* @__PURE__ */ jsx6("line", { x1: "3", y1: "9", x2: "15", y2: "9", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" })
2870
+ /* @__PURE__ */ jsx7("div", { className: "lb-bogo__plus", "aria-hidden": "true", children: /* @__PURE__ */ jsxs7("svg", { width: "12", height: "12", viewBox: "0 0 18 18", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
2871
+ /* @__PURE__ */ jsx7("line", { x1: "9", y1: "3", x2: "9", y2: "15", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }),
2872
+ /* @__PURE__ */ jsx7("line", { x1: "3", y1: "9", x2: "15", y2: "9", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" })
2759
2873
  ] }) }),
2760
- /* @__PURE__ */ jsx6(
2874
+ /* @__PURE__ */ jsx7(
2761
2875
  BogoProductRow,
2762
2876
  {
2763
2877
  side: "get",
@@ -2770,29 +2884,29 @@ function BogoBundle(props) {
2770
2884
  }
2771
2885
  )
2772
2886
  ] }),
2773
- /* @__PURE__ */ jsx6("div", { className: "lb-bundle-divider" }),
2774
- /* @__PURE__ */ jsxs6("div", { className: "lb-bundle-summary", children: [
2775
- /* @__PURE__ */ jsxs6("div", { className: "lb-bundle-summary__text", children: [
2776
- /* @__PURE__ */ jsx6("span", { className: "lb-bundle-summary__label", children: "Bundle price" }),
2777
- showSavings && /* @__PURE__ */ jsxs6("p", { className: "lb-bundle-savings-line", "data-savings-bar": true, children: [
2887
+ /* @__PURE__ */ jsx7("div", { className: "lb-bundle-divider" }),
2888
+ /* @__PURE__ */ jsxs7("div", { className: "lb-bundle-summary", children: [
2889
+ /* @__PURE__ */ jsxs7("div", { className: "lb-bundle-summary__text", children: [
2890
+ /* @__PURE__ */ jsx7("span", { className: "lb-bundle-summary__label", children: "Bundle total" }),
2891
+ showSavings && /* @__PURE__ */ jsxs7("p", { className: "lb-bundle-savings-line", "data-savings-bar": true, children: [
2778
2892
  "You save",
2779
2893
  " ",
2780
- /* @__PURE__ */ jsx6("span", { "data-savings-amount": true, children: formatMoney5(savings, currency) }),
2894
+ /* @__PURE__ */ jsx7("span", { "data-savings-amount": true, children: formatMoney5(savings, currency) }),
2781
2895
  " ",
2782
- /* @__PURE__ */ jsxs6("span", { "data-savings-percent": true, children: [
2896
+ /* @__PURE__ */ jsxs7("span", { "data-savings-percent": true, children: [
2783
2897
  "(",
2784
2898
  savingsPercent,
2785
2899
  "%)"
2786
2900
  ] })
2787
2901
  ] })
2788
2902
  ] }),
2789
- /* @__PURE__ */ jsxs6("span", { className: "lb-bundle-summary__prices", children: [
2790
- showCompare && /* @__PURE__ */ jsx6("span", { className: "lb-bundle-compare-price", "data-compare-price": true, children: formatMoney5(comparePrice, currency) }),
2791
- /* @__PURE__ */ jsx6("span", { className: "lb-bundle-sale-price", "data-sale-price": true, children: formatMoney5(salePrice, currency) })
2903
+ /* @__PURE__ */ jsxs7("span", { className: "lb-bundle-summary__prices", children: [
2904
+ showCompare && /* @__PURE__ */ jsx7("span", { className: "lb-bundle-compare-price", "data-compare-price": true, children: formatMoney5(comparePrice, currency) }),
2905
+ /* @__PURE__ */ jsx7("span", { className: "lb-bundle-sale-price", "data-sale-price": true, children: formatMoney5(salePrice, currency) })
2792
2906
  ] })
2793
2907
  ] }),
2794
- cartError && /* @__PURE__ */ jsx6("p", { className: "lb-bundle__error", role: "alert", children: cartError }),
2795
- /* @__PURE__ */ jsx6(
2908
+ cartError && /* @__PURE__ */ jsx7("p", { className: "lb-bundle__error", role: "alert", children: cartError }),
2909
+ /* @__PURE__ */ jsx7(
2796
2910
  "button",
2797
2911
  {
2798
2912
  className: "lb-bundle__cta",
@@ -2831,8 +2945,8 @@ function BogoProductRow({ side, product, quantity, percent, badge, currency, onV
2831
2945
  currency
2832
2946
  ) : null;
2833
2947
  const thumbImage = displayVariant?.image ?? product.featuredImage;
2834
- return /* @__PURE__ */ jsxs6("div", { className: "lb-bundle-product-row", part: "product", "data-bogo-role": side, children: [
2835
- thumbImage && /* @__PURE__ */ jsx6(
2948
+ return /* @__PURE__ */ jsxs7("div", { className: "lb-bundle-product-row", part: "product", "data-bogo-role": side, children: [
2949
+ thumbImage && /* @__PURE__ */ jsx7(
2836
2950
  "img",
2837
2951
  {
2838
2952
  src: thumbImage.url,
@@ -2841,11 +2955,11 @@ function BogoProductRow({ side, product, quantity, percent, badge, currency, onV
2841
2955
  loading: "lazy"
2842
2956
  }
2843
2957
  ),
2844
- /* @__PURE__ */ jsxs6("div", { className: "lb-bundle__product-info", children: [
2845
- /* @__PURE__ */ jsx6("p", { className: "lb-bundle__product-title", children: product.title }),
2846
- !showPicker && displayVariant && variants.length > 1 && /* @__PURE__ */ jsx6("span", { className: "lb-bundle-variant-badge", children: displayVariant.title }),
2847
- /* @__PURE__ */ jsxs6("span", { className: "lb-bundle-product-prices", children: [
2848
- compareAt && /* @__PURE__ */ jsx6(
2958
+ /* @__PURE__ */ jsxs7("div", { className: "lb-bundle__product-info", children: [
2959
+ /* @__PURE__ */ jsx7("p", { className: "lb-bundle__product-title", children: product.title }),
2960
+ !showPicker && displayVariant && variants.length > 1 && /* @__PURE__ */ jsx7("span", { className: "lb-bundle-variant-badge", children: displayVariant.title }),
2961
+ /* @__PURE__ */ jsxs7("span", { className: "lb-bundle-product-prices", children: [
2962
+ compareAt && /* @__PURE__ */ jsx7(
2849
2963
  "span",
2850
2964
  {
2851
2965
  className: "lb-bundle-product-compare-price",
@@ -2853,13 +2967,13 @@ function BogoProductRow({ side, product, quantity, percent, badge, currency, onV
2853
2967
  children: compareAt
2854
2968
  }
2855
2969
  ),
2856
- /* @__PURE__ */ jsx6("span", { className: "lb-bundle__product-price", "data-product-price": true, children: priceText }),
2857
- /* @__PURE__ */ jsxs6("span", { className: "lb-bundle-qty-inline", "data-qty-inline": true, children: [
2970
+ /* @__PURE__ */ jsx7("span", { className: "lb-bundle__product-price", "data-product-price": true, children: priceText }),
2971
+ /* @__PURE__ */ jsxs7("span", { className: "lb-bundle-qty-inline", "data-qty-inline": true, children: [
2858
2972
  "\xD7",
2859
2973
  quantity
2860
2974
  ] })
2861
2975
  ] }),
2862
- unitPriceText && /* @__PURE__ */ jsx6(
2976
+ unitPriceText && /* @__PURE__ */ jsx7(
2863
2977
  "span",
2864
2978
  {
2865
2979
  className: "lb-bundle__product-unit-price",
@@ -2867,13 +2981,13 @@ function BogoProductRow({ side, product, quantity, percent, badge, currency, onV
2867
2981
  children: unitPriceText
2868
2982
  }
2869
2983
  ),
2870
- showPicker && /* @__PURE__ */ jsx6("div", { className: "lb-bundle__product-variant-pickers", children: optionNames.map((optionName, optionIndex) => {
2984
+ showPicker && /* @__PURE__ */ jsx7("div", { className: "lb-bundle__product-variant-pickers", children: optionNames.map((optionName, optionIndex) => {
2871
2985
  const dropdownOptions = optionsFor(optionIndex).map((o) => ({
2872
2986
  value: o.value,
2873
2987
  label: o.value,
2874
2988
  disabled: o.disabled
2875
2989
  }));
2876
- return /* @__PURE__ */ jsx6(
2990
+ return /* @__PURE__ */ jsx7(
2877
2991
  VariantDropdown,
2878
2992
  {
2879
2993
  options: dropdownOptions,
@@ -2885,7 +2999,7 @@ function BogoProductRow({ side, product, quantity, percent, badge, currency, onV
2885
2999
  );
2886
3000
  }) })
2887
3001
  ] }),
2888
- badge && /* @__PURE__ */ jsx6("span", { className: "lb-bogo__badge", children: badge })
3002
+ badge && /* @__PURE__ */ jsx7("span", { className: "lb-bogo__badge", children: badge })
2889
3003
  ] });
2890
3004
  }
2891
3005
 
@@ -2918,7 +3032,7 @@ import {
2918
3032
  stepHeadroom,
2919
3033
  DEFAULT_PRODUCT_RULE as DEFAULT_PRODUCT_RULE3
2920
3034
  } from "@lime-bundles/core";
2921
- import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
3035
+ import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
2922
3036
  function ruleFor3(bundle, productId, variantId) {
2923
3037
  if (variantId) {
2924
3038
  const vRule = bundle.variantRules[variantId];
@@ -2932,7 +3046,7 @@ function variantRuleFor3(bundle, variantId) {
2932
3046
  function sanitizeId2(gid) {
2933
3047
  return gid.replace(/[^a-zA-Z0-9_-]/g, "-");
2934
3048
  }
2935
- function buildEligibleProducts2(bundle, stepIndex, oosBehavior) {
3049
+ function buildEligibleProducts2(bundle, stepIndex) {
2936
3050
  const result = [];
2937
3051
  for (const product of productsForStep(bundle, stepIndex)) {
2938
3052
  const rule = ruleFor3(bundle, product.id);
@@ -2940,7 +3054,6 @@ function buildEligibleProducts2(bundle, stepIndex, oosBehavior) {
2940
3054
  (v) => isVariantFulfillable6(v, rule.min)
2941
3055
  );
2942
3056
  const isOos = available.length === 0;
2943
- if (isOos && oosBehavior === "hide") continue;
2944
3057
  result.push({
2945
3058
  product,
2946
3059
  variants: product.variants.nodes,
@@ -2955,7 +3068,6 @@ function normalizeText2(str) {
2955
3068
  }
2956
3069
  var FILTERS_ALL2 = "__all__";
2957
3070
  function MultiStepPicker({
2958
- outOfStockBehavior,
2959
3071
  bundle,
2960
3072
  currency,
2961
3073
  initialStep,
@@ -2975,6 +3087,8 @@ function MultiStepPicker({
2975
3087
  const overlayRef = useRef7(null);
2976
3088
  const dialogRef = useRef7(null);
2977
3089
  const titleRef = useRef7(null);
3090
+ const closeBtnRef = useRef7(null);
3091
+ const listRef = useRef7(null);
2978
3092
  const mouseDownTarget = useRef7(null);
2979
3093
  const [open, setOpen] = useState11(false);
2980
3094
  const [stepIndex, setStepIndex] = useState11(
@@ -2991,8 +3105,8 @@ function MultiStepPicker({
2991
3105
  const isLastStep = stepIndex === steps.length - 1;
2992
3106
  const shownUnits = Math.min(unitsInStep, stepMin);
2993
3107
  const eligible = useMemo9(
2994
- () => buildEligibleProducts2(bundle, stepIndex, outOfStockBehavior),
2995
- [bundle, stepIndex, outOfStockBehavior]
3108
+ () => buildEligibleProducts2(bundle, stepIndex),
3109
+ [bundle, stepIndex]
2996
3110
  );
2997
3111
  const productTypes = useMemo9(() => {
2998
3112
  const types = [];
@@ -3015,8 +3129,23 @@ function MultiStepPicker({
3015
3129
  useFocusTrap({
3016
3130
  active: true,
3017
3131
  containerRef: dialogRef,
3132
+ initialFocusRef: closeBtnRef,
3018
3133
  onEscape: onClose
3019
3134
  });
3135
+ useEffect14(() => {
3136
+ if (listRef.current) listRef.current.scrollTop = 0;
3137
+ }, [stepIndex]);
3138
+ const [selectedAtLoad, setSelectedAtLoad] = useState11(
3139
+ () => new Set((selections[stepIndex] ?? []).map((s) => s.productId))
3140
+ );
3141
+ const ordered = useMemo9(() => {
3142
+ const front = [];
3143
+ const back = [];
3144
+ for (const ep of eligible) {
3145
+ (selectedAtLoad.has(ep.product.id) ? back : front).push(ep);
3146
+ }
3147
+ return front.concat(back);
3148
+ }, [eligible, selectedAtLoad]);
3020
3149
  function goToStep(i) {
3021
3150
  const clamped = Math.max(0, Math.min(steps.length - 1, i));
3022
3151
  setStepIndex(clamped);
@@ -3024,6 +3153,7 @@ function MultiStepPicker({
3024
3153
  setActiveType(FILTERS_ALL2);
3025
3154
  const target = steps[clamped];
3026
3155
  const targetPicks = selections[clamped] ?? [];
3156
+ setSelectedAtLoad(new Set(targetPicks.map((s) => s.productId)));
3027
3157
  const targetUnits = targetPicks.reduce((sum, s) => sum + s.quantity, 0);
3028
3158
  setAnnouncement(
3029
3159
  `Step ${clamped + 1} of ${steps.length}. ${target.name}. ${Math.min(targetUnits, target.minQuantity)} of ${target.minQuantity} added`
@@ -3033,12 +3163,12 @@ function MultiStepPicker({
3033
3163
  const subtitle = `Step ${stepIndex + 1} of ${steps.length} \xB7 ${step?.name ?? ""}`;
3034
3164
  const filtered = useMemo9(() => {
3035
3165
  const nq = normalizeText2(query.trim());
3036
- return eligible.filter((ep) => {
3166
+ return ordered.filter((ep) => {
3037
3167
  const matchesQuery = !nq || normalizeText2(ep.product.title).includes(nq);
3038
3168
  const matchesType = activeType === FILTERS_ALL2 || (ep.product.productType ?? "") === activeType;
3039
3169
  return matchesQuery && matchesType;
3040
3170
  });
3041
- }, [eligible, query, activeType]);
3171
+ }, [ordered, query, activeType]);
3042
3172
  const showEmpty = filtered.length === 0 && query.trim().length > 0;
3043
3173
  function onOverlayMouseDown(e) {
3044
3174
  mouseDownTarget.current = e.target;
@@ -3056,7 +3186,7 @@ function MultiStepPicker({
3056
3186
  // inside carries the interactive role + focus trap. So the static-element
3057
3187
  // interaction lint does not apply to this backdrop.
3058
3188
  // eslint-disable-next-line jsx-a11y/no-static-element-interactions
3059
- /* @__PURE__ */ jsx7(
3189
+ /* @__PURE__ */ jsx8(
3060
3190
  "div",
3061
3191
  {
3062
3192
  ref: (el) => {
@@ -3068,7 +3198,7 @@ function MultiStepPicker({
3068
3198
  "data-bundle-gid": bundle.id,
3069
3199
  onMouseDown: onOverlayMouseDown,
3070
3200
  onMouseUp: onOverlayMouseUp,
3071
- children: /* @__PURE__ */ jsxs7(
3201
+ children: /* @__PURE__ */ jsxs8(
3072
3202
  "div",
3073
3203
  {
3074
3204
  ref: dialogRef,
@@ -3078,10 +3208,10 @@ function MultiStepPicker({
3078
3208
  "aria-labelledby": titleId,
3079
3209
  tabIndex: -1,
3080
3210
  children: [
3081
- /* @__PURE__ */ jsxs7("div", { className: "lb-mix-match__modal-header", children: [
3082
- /* @__PURE__ */ jsxs7("div", { className: "lb-mix-match__modal-header-top", children: [
3083
- /* @__PURE__ */ jsxs7("div", { className: "lb-mix-match__modal-heading", children: [
3084
- /* @__PURE__ */ jsx7(
3211
+ /* @__PURE__ */ jsxs8("div", { className: "lb-mix-match__modal-header", children: [
3212
+ /* @__PURE__ */ jsxs8("div", { className: "lb-mix-match__modal-header-top", children: [
3213
+ /* @__PURE__ */ jsxs8("div", { className: "lb-mix-match__modal-heading", children: [
3214
+ /* @__PURE__ */ jsx8(
3085
3215
  "h4",
3086
3216
  {
3087
3217
  className: "lb-mix-match__modal-title",
@@ -3091,26 +3221,27 @@ function MultiStepPicker({
3091
3221
  children: "Add to your bundle"
3092
3222
  }
3093
3223
  ),
3094
- /* @__PURE__ */ jsx7("p", { className: "lb-mix-match__modal-subtitle", "data-modal-subtitle": true, children: subtitle })
3224
+ /* @__PURE__ */ jsx8("p", { className: "lb-mix-match__modal-subtitle", "data-modal-subtitle": true, children: subtitle })
3095
3225
  ] }),
3096
- /* @__PURE__ */ jsx7(
3226
+ /* @__PURE__ */ jsx8(
3097
3227
  "button",
3098
3228
  {
3229
+ ref: closeBtnRef,
3099
3230
  type: "button",
3100
3231
  className: "lb-mix-match__modal-close",
3101
3232
  "data-modal-close": true,
3102
3233
  "aria-label": "Close",
3103
3234
  onClick: onClose,
3104
- children: /* @__PURE__ */ jsx7(CloseIcon3, {})
3235
+ children: /* @__PURE__ */ jsx8(CloseIcon3, {})
3105
3236
  }
3106
3237
  )
3107
3238
  ] }),
3108
- /* @__PURE__ */ jsx7(
3239
+ /* @__PURE__ */ jsx8(
3109
3240
  "div",
3110
3241
  {
3111
3242
  className: "lb-mix-match__progress lb-mix-match__modal-progress",
3112
3243
  "data-progress": true,
3113
- children: /* @__PURE__ */ jsx7(
3244
+ children: /* @__PURE__ */ jsx8(
3114
3245
  "div",
3115
3246
  {
3116
3247
  className: "lb-mix-match__progress-segments",
@@ -3119,7 +3250,7 @@ function MultiStepPicker({
3119
3250
  "aria-valuenow": shownUnits,
3120
3251
  "aria-valuemin": 0,
3121
3252
  "aria-valuemax": stepMin,
3122
- children: Array.from({ length: stepMin }).map((_, i) => /* @__PURE__ */ jsx7(
3253
+ children: Array.from({ length: stepMin }).map((_, i) => /* @__PURE__ */ jsx8(
3123
3254
  "span",
3124
3255
  {
3125
3256
  className: `lb-mix-match__progress-segment${i < shownUnits ? " lb-mix-match__progress-segment--filled" : ""}`,
@@ -3132,8 +3263,8 @@ function MultiStepPicker({
3132
3263
  }
3133
3264
  )
3134
3265
  ] }),
3135
- wc.showSearch && /* @__PURE__ */ jsxs7("div", { className: "lb-mix-match__modal-search", children: [
3136
- /* @__PURE__ */ jsx7(
3266
+ wc.showSearch && /* @__PURE__ */ jsxs8("div", { className: "lb-mix-match__modal-search", children: [
3267
+ /* @__PURE__ */ jsx8(
3137
3268
  "input",
3138
3269
  {
3139
3270
  type: "text",
@@ -3147,7 +3278,7 @@ function MultiStepPicker({
3147
3278
  onChange: (e) => setQuery(e.target.value)
3148
3279
  }
3149
3280
  ),
3150
- query.length > 0 && /* @__PURE__ */ jsx7(
3281
+ query.length > 0 && /* @__PURE__ */ jsx8(
3151
3282
  "button",
3152
3283
  {
3153
3284
  type: "button",
@@ -3155,11 +3286,11 @@ function MultiStepPicker({
3155
3286
  "data-modal-search-clear": true,
3156
3287
  "aria-label": "Clear search",
3157
3288
  onClick: () => setQuery(""),
3158
- children: /* @__PURE__ */ jsx7(SearchClearIcon2, {})
3289
+ children: /* @__PURE__ */ jsx8(SearchClearIcon2, {})
3159
3290
  }
3160
3291
  )
3161
3292
  ] }),
3162
- showFilters && /* @__PURE__ */ jsx7(
3293
+ showFilters && /* @__PURE__ */ jsx8(
3163
3294
  "div",
3164
3295
  {
3165
3296
  className: "lb-mix-match__filters",
@@ -3168,7 +3299,7 @@ function MultiStepPicker({
3168
3299
  "aria-label": "Filter by product type",
3169
3300
  children: [FILTERS_ALL2, ...productTypes].map((value) => {
3170
3301
  const isActive = value === activeType;
3171
- return /* @__PURE__ */ jsx7(
3302
+ return /* @__PURE__ */ jsx8(
3172
3303
  "button",
3173
3304
  {
3174
3305
  type: "button",
@@ -3183,7 +3314,7 @@ function MultiStepPicker({
3183
3314
  })
3184
3315
  }
3185
3316
  ),
3186
- /* @__PURE__ */ jsx7("div", { className: "lb-mix-match__modal-list", "data-modal-list": true, children: filtered.map((ep) => /* @__PURE__ */ jsx7(
3317
+ /* @__PURE__ */ jsx8("div", { className: "lb-mix-match__modal-list", "data-modal-list": true, ref: listRef, children: filtered.map((ep) => /* @__PURE__ */ jsx8(
3187
3318
  MultiStepPickerRow,
3188
3319
  {
3189
3320
  bundle,
@@ -3201,10 +3332,10 @@ function MultiStepPicker({
3201
3332
  },
3202
3333
  `${stepIndex}:${ep.product.id}`
3203
3334
  )) }),
3204
- showEmpty && /* @__PURE__ */ jsx7("div", { className: "lb-mix-match__modal-empty", "data-modal-empty": true, children: /* @__PURE__ */ jsx7("p", { children: "No products match your search" }) }),
3205
- /* @__PURE__ */ jsx7("span", { "data-modal-live": true, "aria-live": "polite", className: "lb-visually-hidden", children: announcement || (query.trim() ? `${filtered.length} products shown` : "") }),
3206
- /* @__PURE__ */ jsxs7("div", { className: "lb-mix-match__modal-footer lb-multi-step__modal-footer", children: [
3207
- stepIndex > 0 && /* @__PURE__ */ jsx7(
3335
+ showEmpty && /* @__PURE__ */ jsx8("div", { className: "lb-mix-match__modal-empty", "data-modal-empty": true, children: /* @__PURE__ */ jsx8("p", { children: "No products match your search" }) }),
3336
+ /* @__PURE__ */ jsx8("span", { "data-modal-live": true, "aria-live": "polite", className: "lb-visually-hidden", children: announcement || (query.trim() ? `${filtered.length} products shown` : "") }),
3337
+ /* @__PURE__ */ jsxs8("div", { className: "lb-mix-match__modal-footer lb-multi-step__modal-footer", children: [
3338
+ stepIndex > 0 && /* @__PURE__ */ jsx8(
3208
3339
  "button",
3209
3340
  {
3210
3341
  type: "button",
@@ -3214,7 +3345,7 @@ function MultiStepPicker({
3214
3345
  children: "Back"
3215
3346
  }
3216
3347
  ),
3217
- /* @__PURE__ */ jsx7(
3348
+ /* @__PURE__ */ jsx8(
3218
3349
  "span",
3219
3350
  {
3220
3351
  className: "lb-mix-match__modal-footer-count",
@@ -3223,7 +3354,7 @@ function MultiStepPicker({
3223
3354
  children: `${shownUnits} of ${stepMin} added`
3224
3355
  }
3225
3356
  ),
3226
- !isLastStep && /* @__PURE__ */ jsx7(
3357
+ !isLastStep && /* @__PURE__ */ jsx8(
3227
3358
  "button",
3228
3359
  {
3229
3360
  type: "button",
@@ -3236,7 +3367,7 @@ function MultiStepPicker({
3236
3367
  children: "Next"
3237
3368
  }
3238
3369
  ),
3239
- isLastStep && /* @__PURE__ */ jsx7(
3370
+ isLastStep && /* @__PURE__ */ jsx8(
3240
3371
  "button",
3241
3372
  {
3242
3373
  type: "button",
@@ -3379,7 +3510,7 @@ function MultiStepPickerRow({
3379
3510
  }
3380
3511
  const priceCents = parseFloat(currentVariant.price.amount);
3381
3512
  const compareCents = currentVariant.compareAtPrice ? parseFloat(currentVariant.compareAtPrice.amount) : null;
3382
- return /* @__PURE__ */ jsxs7(
3513
+ return /* @__PURE__ */ jsxs8(
3383
3514
  "div",
3384
3515
  {
3385
3516
  className: `lb-mix-match__modal-product${isOos ? " lb-mix-match__modal-product--sold-out" : ""}${variantInStep ? " lb-mix-match__modal-product--in-bundle" : ""}`,
@@ -3388,8 +3519,8 @@ function MultiStepPickerRow({
3388
3519
  "data-type": product.productType ?? "",
3389
3520
  "aria-disabled": isOos || void 0,
3390
3521
  children: [
3391
- /* @__PURE__ */ jsxs7("div", { className: "lb-mix-match__modal-product-thumb", children: [
3392
- thumbImage && /* @__PURE__ */ jsx7(
3522
+ /* @__PURE__ */ jsxs8("div", { className: "lb-mix-match__modal-product-thumb", children: [
3523
+ thumbImage && /* @__PURE__ */ jsx8(
3393
3524
  "img",
3394
3525
  {
3395
3526
  src: thumbImage.url,
@@ -3397,10 +3528,10 @@ function MultiStepPickerRow({
3397
3528
  loading: "lazy"
3398
3529
  }
3399
3530
  ),
3400
- variantInStep && /* @__PURE__ */ jsx7("span", { className: "lb-mix-match__modal-added-badge", children: "Added" })
3531
+ variantInStep && /* @__PURE__ */ jsx8("span", { className: "lb-mix-match__modal-added-badge", children: "Added" })
3401
3532
  ] }),
3402
- /* @__PURE__ */ jsxs7("div", { className: "lb-mix-match__modal-product-info", children: [
3403
- /* @__PURE__ */ jsx7("p", { className: "lb-mix-match__modal-product-title", children: /* @__PURE__ */ jsx7(
3533
+ /* @__PURE__ */ jsxs8("div", { className: "lb-mix-match__modal-product-info", children: [
3534
+ /* @__PURE__ */ jsx8("p", { className: "lb-mix-match__modal-product-title", children: /* @__PURE__ */ jsx8(
3404
3535
  "a",
3405
3536
  {
3406
3537
  href: `/products/${product.handle}`,
@@ -3409,24 +3540,24 @@ function MultiStepPickerRow({
3409
3540
  children: product.title
3410
3541
  }
3411
3542
  ) }),
3412
- /* @__PURE__ */ jsxs7("p", { className: "lb-mix-match__modal-product-price", children: [
3413
- /* @__PURE__ */ jsx7("span", { "data-row-price-sale": true, children: formatMoney6(priceCents, currency) }),
3414
- compareCents !== null && compareCents > priceCents && /* @__PURE__ */ jsx7("s", { className: "lb-mix-match__modal-product-compare", "data-row-compare": true, children: formatMoney6(compareCents, currency) })
3543
+ /* @__PURE__ */ jsxs8("p", { className: "lb-mix-match__modal-product-price", children: [
3544
+ /* @__PURE__ */ jsx8("span", { "data-row-price-sale": true, children: formatMoney6(priceCents, currency) }),
3545
+ compareCents !== null && compareCents > priceCents && /* @__PURE__ */ jsx8("s", { className: "lb-mix-match__modal-product-compare", "data-row-compare": true, children: formatMoney6(compareCents, currency) })
3415
3546
  ] }),
3416
- unitPriceText && /* @__PURE__ */ jsx7("p", { className: "lb-mix-match__modal-product-unit-price lb-bundle-product-unit-price", children: unitPriceText }),
3417
- showPicker && /* @__PURE__ */ jsx7("div", { className: "lb-bundle-variant-option-groups", children: optionNames.map((optionName, optionIndex) => {
3547
+ unitPriceText && /* @__PURE__ */ jsx8("p", { className: "lb-mix-match__modal-product-unit-price lb-bundle-product-unit-price", children: unitPriceText }),
3548
+ showPicker && /* @__PURE__ */ jsx8("div", { className: "lb-bundle-variant-option-groups", children: optionNames.map((optionName, optionIndex) => {
3418
3549
  const dropdownOptions = optionsFor(optionIndex).map((o) => ({
3419
3550
  value: o.value,
3420
3551
  label: o.value,
3421
3552
  disabled: o.disabled
3422
3553
  }));
3423
- return /* @__PURE__ */ jsxs7(
3554
+ return /* @__PURE__ */ jsxs8(
3424
3555
  "div",
3425
3556
  {
3426
3557
  className: "lb-bundle-variant-option-group",
3427
3558
  children: [
3428
- /* @__PURE__ */ jsx7("span", { className: "lb-bundle-variant-option-label", children: optionName }),
3429
- /* @__PURE__ */ jsx7(
3559
+ /* @__PURE__ */ jsx8("span", { className: "lb-bundle-variant-option-label", children: optionName }),
3560
+ /* @__PURE__ */ jsx8(
3430
3561
  VariantDropdown,
3431
3562
  {
3432
3563
  className: "lb-mix-match__variant-select-dropdown",
@@ -3441,17 +3572,17 @@ function MultiStepPickerRow({
3441
3572
  optionName
3442
3573
  );
3443
3574
  }) }),
3444
- !showPicker && variants.length === 1 && currentVariant.title !== "Default Title" && /* @__PURE__ */ jsx7("span", { className: "lb-mix-match__filled-variant", children: currentVariant.title }),
3445
- !isOos && needsMoreSpots && room > 0 && /* @__PURE__ */ jsx7("span", { className: "lb-mix-match__modal-needs-spots", children: vRule.min === 1 ? "Needs 1 spot" : `Needs ${vRule.min} spots` }),
3446
- isOos ? /* @__PURE__ */ jsx7("span", { className: "lb-mix-match__modal-sold-out-label", children: "Sold out" }) : /* @__PURE__ */ jsxs7("div", { className: "lb-mix-match__modal-product-actions", children: [
3447
- showStepper && /* @__PURE__ */ jsx7("div", { className: "lb-bundle-variant-option-group lb-mix-match__qty-stepper-group", children: /* @__PURE__ */ jsxs7(
3575
+ !showPicker && variants.length === 1 && currentVariant.title !== "Default Title" && /* @__PURE__ */ jsx8("span", { className: "lb-mix-match__filled-variant", children: currentVariant.title }),
3576
+ !isOos && needsMoreSpots && room > 0 && /* @__PURE__ */ jsx8("span", { className: "lb-mix-match__modal-needs-spots", children: vRule.min === 1 ? "Needs 1 spot" : `Needs ${vRule.min} spots` }),
3577
+ isOos ? /* @__PURE__ */ jsx8("span", { className: "lb-mix-match__modal-sold-out-label", children: "Sold out" }) : /* @__PURE__ */ jsxs8("div", { className: "lb-mix-match__modal-product-actions", children: [
3578
+ showStepper && /* @__PURE__ */ jsx8("div", { className: "lb-bundle-variant-option-group lb-mix-match__qty-stepper-group", children: /* @__PURE__ */ jsxs8(
3448
3579
  "div",
3449
3580
  {
3450
3581
  className: "lb-mix-match__qty-stepper",
3451
3582
  role: "group",
3452
3583
  "aria-label": "Quantity",
3453
3584
  children: [
3454
- /* @__PURE__ */ jsx7(
3585
+ /* @__PURE__ */ jsx8(
3455
3586
  "button",
3456
3587
  {
3457
3588
  type: "button",
@@ -3473,7 +3604,7 @@ function MultiStepPickerRow({
3473
3604
  children: "\u2212"
3474
3605
  }
3475
3606
  ),
3476
- /* @__PURE__ */ jsx7(
3607
+ /* @__PURE__ */ jsx8(
3477
3608
  "span",
3478
3609
  {
3479
3610
  className: "lb-mix-match__qty-stepper-value",
@@ -3482,7 +3613,7 @@ function MultiStepPickerRow({
3482
3613
  children: shownQty
3483
3614
  }
3484
3615
  ),
3485
- /* @__PURE__ */ jsx7(
3616
+ /* @__PURE__ */ jsx8(
3486
3617
  "button",
3487
3618
  {
3488
3619
  type: "button",
@@ -3507,7 +3638,7 @@ function MultiStepPickerRow({
3507
3638
  ]
3508
3639
  }
3509
3640
  ) }),
3510
- /* @__PURE__ */ jsx7(
3641
+ /* @__PURE__ */ jsx8(
3511
3642
  "button",
3512
3643
  {
3513
3644
  type: "button",
@@ -3526,7 +3657,7 @@ function MultiStepPickerRow({
3526
3657
  );
3527
3658
  }
3528
3659
  function CloseIcon3() {
3529
- return /* @__PURE__ */ jsxs7(
3660
+ return /* @__PURE__ */ jsxs8(
3530
3661
  "svg",
3531
3662
  {
3532
3663
  width: "20",
@@ -3536,14 +3667,14 @@ function CloseIcon3() {
3536
3667
  xmlns: "http://www.w3.org/2000/svg",
3537
3668
  "aria-hidden": "true",
3538
3669
  children: [
3539
- /* @__PURE__ */ jsx7("line", { x1: "5", y1: "5", x2: "15", y2: "15", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }),
3540
- /* @__PURE__ */ jsx7("line", { x1: "15", y1: "5", x2: "5", y2: "15", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" })
3670
+ /* @__PURE__ */ jsx8("line", { x1: "5", y1: "5", x2: "15", y2: "15", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }),
3671
+ /* @__PURE__ */ jsx8("line", { x1: "15", y1: "5", x2: "5", y2: "15", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" })
3541
3672
  ]
3542
3673
  }
3543
3674
  );
3544
3675
  }
3545
3676
  function SearchClearIcon2() {
3546
- return /* @__PURE__ */ jsx7(
3677
+ return /* @__PURE__ */ jsx8(
3547
3678
  "svg",
3548
3679
  {
3549
3680
  width: "16",
@@ -3552,13 +3683,13 @@ function SearchClearIcon2() {
3552
3683
  fill: "currentColor",
3553
3684
  xmlns: "http://www.w3.org/2000/svg",
3554
3685
  "aria-hidden": "true",
3555
- children: /* @__PURE__ */ jsx7("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" })
3686
+ children: /* @__PURE__ */ jsx8("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" })
3556
3687
  }
3557
3688
  );
3558
3689
  }
3559
3690
 
3560
3691
  // src/components/MultiStepBundle.tsx
3561
- import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
3692
+ import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
3562
3693
  function ruleFor4(bundle, productId, variantId) {
3563
3694
  if (variantId) {
3564
3695
  const vRule = bundle.variantRules[variantId];
@@ -3606,10 +3737,6 @@ function MultiStepBundle(props) {
3606
3737
  storefrontAccessToken,
3607
3738
  bundleGid
3608
3739
  });
3609
- const { outOfStockBehavior } = useShopSettings({
3610
- shopDomain,
3611
- storefrontAccessToken
3612
- });
3613
3740
  const { elementRef, trackAddToCart } = useAnalytics({
3614
3741
  shopDomain,
3615
3742
  appUrl: appUrl ?? `https://${shopDomain}`,
@@ -3848,9 +3975,9 @@ function MultiStepBundle(props) {
3848
3975
  }
3849
3976
  }, [bundle, selections, valid, onAddToCart, onError, trackAddToCart, totalQuantity, steps]);
3850
3977
  if (result.status === "loading") {
3851
- return /* @__PURE__ */ jsxs8("div", { className: `lb-bundle lb-bundle--loading ${className ?? ""}`, children: [
3852
- /* @__PURE__ */ jsx8("div", { className: "lb-skeleton lb-skeleton--title" }),
3853
- /* @__PURE__ */ jsx8("div", { className: "lb-skeleton lb-skeleton--products" })
3978
+ return /* @__PURE__ */ jsxs9("div", { className: `lb-bundle lb-bundle--loading ${className ?? ""}`, children: [
3979
+ /* @__PURE__ */ jsx9("div", { className: "lb-skeleton lb-skeleton--title" }),
3980
+ /* @__PURE__ */ jsx9("div", { className: "lb-skeleton lb-skeleton--products" })
3854
3981
  ] });
3855
3982
  }
3856
3983
  if (result.status === "error") return null;
@@ -3871,7 +3998,7 @@ function MultiStepBundle(props) {
3871
3998
  if (requiredBlocked) return null;
3872
3999
  const currency = bundle.products[0]?.priceRange.minVariantPrice.currencyCode ?? "USD";
3873
4000
  const ctaLabel = addingToCart ? "Adding..." : bundle.widgetConfig.cta.ctaText || "Add to cart";
3874
- return /* @__PURE__ */ jsxs8(
4001
+ return /* @__PURE__ */ jsxs9(
3875
4002
  "div",
3876
4003
  {
3877
4004
  ref: (el) => {
@@ -3883,12 +4010,19 @@ function MultiStepBundle(props) {
3883
4010
  "aria-label": bundle.title,
3884
4011
  "data-required-quantity": totalMin,
3885
4012
  children: [
3886
- /* @__PURE__ */ jsx8("div", { className: "lb-bundle-header", children: /* @__PURE__ */ jsxs8("div", { className: "lb-bundle-header__content", children: [
3887
- /* @__PURE__ */ jsx8("h3", { className: "lb-bundle-title", children: bundle.title }),
3888
- bundle.description && /* @__PURE__ */ jsx8("p", { className: "lb-bundle-subtitle", children: bundle.description })
4013
+ /* @__PURE__ */ jsx9("div", { className: "lb-bundle-header", children: /* @__PURE__ */ jsxs9("div", { className: "lb-bundle-header__content", children: [
4014
+ /* @__PURE__ */ jsx9("h3", { className: "lb-bundle-title", children: bundle.title }),
4015
+ bundle.description && /* @__PURE__ */ jsx9("p", { className: "lb-bundle-subtitle", children: bundle.description })
3889
4016
  ] }) }),
3890
- /* @__PURE__ */ jsxs8("div", { className: "lb-mix-match__progress", "data-progress": true, children: [
3891
- /* @__PURE__ */ jsx8(
4017
+ /* @__PURE__ */ jsx9(
4018
+ BundleCountdown,
4019
+ {
4020
+ endsAt: bundle.endsAt,
4021
+ widgetConfig: bundle.widgetConfig
4022
+ }
4023
+ ),
4024
+ /* @__PURE__ */ jsxs9("div", { className: "lb-mix-match__progress", "data-progress": true, children: [
4025
+ /* @__PURE__ */ jsx9(
3892
4026
  "div",
3893
4027
  {
3894
4028
  className: "lb-mix-match__progress-segments",
@@ -3896,7 +4030,7 @@ function MultiStepBundle(props) {
3896
4030
  "aria-valuenow": completedSteps,
3897
4031
  "aria-valuemin": 0,
3898
4032
  "aria-valuemax": steps.length,
3899
- children: Array.from({ length: steps.length }).map((_, i) => /* @__PURE__ */ jsx8(
4033
+ children: Array.from({ length: steps.length }).map((_, i) => /* @__PURE__ */ jsx9(
3900
4034
  "span",
3901
4035
  {
3902
4036
  className: `lb-mix-match__progress-segment${i < completedSteps ? " lb-mix-match__progress-segment--filled" : ""}`,
@@ -3906,8 +4040,8 @@ function MultiStepBundle(props) {
3906
4040
  ))
3907
4041
  }
3908
4042
  ),
3909
- /* @__PURE__ */ jsxs8("div", { className: "lb-mix-match__progress-labels", children: [
3910
- /* @__PURE__ */ jsx8(
4043
+ /* @__PURE__ */ jsxs9("div", { className: "lb-mix-match__progress-labels", children: [
4044
+ /* @__PURE__ */ jsx9(
3911
4045
  "span",
3912
4046
  {
3913
4047
  className: "lb-mix-match__progress-count",
@@ -3916,7 +4050,7 @@ function MultiStepBundle(props) {
3916
4050
  children: `${completedSteps} of ${steps.length} steps completed`
3917
4051
  }
3918
4052
  ),
3919
- /* @__PURE__ */ jsx8(
4053
+ /* @__PURE__ */ jsx9(
3920
4054
  "span",
3921
4055
  {
3922
4056
  className: "lb-mix-match__progress-remaining",
@@ -3927,15 +4061,15 @@ function MultiStepBundle(props) {
3927
4061
  )
3928
4062
  ] })
3929
4063
  ] }),
3930
- /* @__PURE__ */ jsx8("div", { className: "lb-multi-step__groups", "data-step-groups": true, children: steps.map((step, i) => /* @__PURE__ */ jsxs8(
4064
+ /* @__PURE__ */ jsx9("div", { className: "lb-multi-step__groups", "data-step-groups": true, children: steps.map((step, i) => /* @__PURE__ */ jsxs9(
3931
4065
  "section",
3932
4066
  {
3933
4067
  className: "lb-multi-step__group",
3934
4068
  "data-step-group": i,
3935
4069
  children: [
3936
- /* @__PURE__ */ jsxs8("div", { className: "lb-multi-step__group-heading", children: [
3937
- /* @__PURE__ */ jsx8("span", { className: "lb-multi-step__group-name", children: step.name }),
3938
- /* @__PURE__ */ jsx8(
4070
+ /* @__PURE__ */ jsxs9("div", { className: "lb-multi-step__group-heading", children: [
4071
+ /* @__PURE__ */ jsx9("span", { className: "lb-multi-step__group-name", children: step.name }),
4072
+ /* @__PURE__ */ jsx9(
3939
4073
  "span",
3940
4074
  {
3941
4075
  className: `lb-multi-step__group-count${stepSatisfied(i) ? " lb-multi-step__group-count--met" : ""}`,
@@ -3944,7 +4078,7 @@ function MultiStepBundle(props) {
3944
4078
  }
3945
4079
  )
3946
4080
  ] }),
3947
- /* @__PURE__ */ jsx8(
4081
+ /* @__PURE__ */ jsx9(
3948
4082
  "div",
3949
4083
  {
3950
4084
  className: "lb-mix-match__slots lb-edge-fade lb-multi-step__group-slots",
@@ -3954,13 +4088,13 @@ function MultiStepBundle(props) {
3954
4088
  title button provides the keyboard/AT path (its
3955
4089
  activation bubbles here); × stops propagation. */
3956
4090
  // 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
3957
- /* @__PURE__ */ jsxs8(
4091
+ /* @__PURE__ */ jsxs9(
3958
4092
  "div",
3959
4093
  {
3960
4094
  className: "lb-mix-match__slot lb-mix-match__slot--filled",
3961
4095
  onClick: () => setPickerOpenAt(i),
3962
4096
  children: [
3963
- item.featuredImage && /* @__PURE__ */ jsx8("div", { className: "lb-bundle-thumbnail", children: /* @__PURE__ */ jsx8(
4097
+ item.featuredImage && /* @__PURE__ */ jsx9("div", { className: "lb-bundle-thumbnail", children: /* @__PURE__ */ jsx9(
3964
4098
  "img",
3965
4099
  {
3966
4100
  src: item.featuredImage,
@@ -3968,8 +4102,8 @@ function MultiStepBundle(props) {
3968
4102
  loading: "lazy"
3969
4103
  }
3970
4104
  ) }),
3971
- /* @__PURE__ */ jsxs8("div", { className: "lb-mix-match__filled-info", children: [
3972
- /* @__PURE__ */ jsx8(
4105
+ /* @__PURE__ */ jsxs9("div", { className: "lb-mix-match__filled-info", children: [
4106
+ /* @__PURE__ */ jsx9(
3973
4107
  "button",
3974
4108
  {
3975
4109
  type: "button",
@@ -3978,15 +4112,15 @@ function MultiStepBundle(props) {
3978
4112
  children: item.title
3979
4113
  }
3980
4114
  ),
3981
- item.variantTitle && item.variantTitle !== "Default Title" && /* @__PURE__ */ jsx8("span", { className: "lb-mix-match__filled-variant", children: item.variantTitle }),
3982
- /* @__PURE__ */ jsxs8("span", { className: "lb-mix-match__filled-price", children: [
3983
- item.compareAtPrice !== null && item.compareAtPrice > item.price && /* @__PURE__ */ jsx8("s", { className: "lb-mix-match__filled-compare", children: formatMoney7(item.compareAtPrice, currency) }),
3984
- /* @__PURE__ */ jsx8("span", { className: "lb-bundle-product-price", children: formatMoney7(item.price, currency) }),
3985
- /* @__PURE__ */ jsx8("span", { className: "lb-bundle-qty-inline", children: `\xD7${item.quantity}` })
4115
+ item.variantTitle && item.variantTitle !== "Default Title" && /* @__PURE__ */ jsx9("span", { className: "lb-mix-match__filled-variant", children: item.variantTitle }),
4116
+ /* @__PURE__ */ jsxs9("span", { className: "lb-mix-match__filled-price", children: [
4117
+ item.compareAtPrice !== null && item.compareAtPrice > item.price && /* @__PURE__ */ jsx9("s", { className: "lb-mix-match__filled-compare", children: formatMoney7(item.compareAtPrice, currency) }),
4118
+ /* @__PURE__ */ jsx9("span", { className: "lb-bundle-product-price", children: formatMoney7(item.price, currency) }),
4119
+ /* @__PURE__ */ jsx9("span", { className: "lb-bundle-qty-inline", children: `\xD7${item.quantity}` })
3986
4120
  ] }),
3987
- item.unitPrice && /* @__PURE__ */ jsx8("span", { className: "lb-bundle-product-unit-price", children: item.unitPrice })
4121
+ item.unitPrice && /* @__PURE__ */ jsx9("span", { className: "lb-bundle-product-unit-price", children: item.unitPrice })
3988
4122
  ] }),
3989
- canRemoveItem2(bundle, selections, item) ? /* @__PURE__ */ jsx8(
4123
+ canRemoveItem2(bundle, selections, item) ? /* @__PURE__ */ jsx9(
3990
4124
  "button",
3991
4125
  {
3992
4126
  type: "button",
@@ -3996,13 +4130,13 @@ function MultiStepBundle(props) {
3996
4130
  e.stopPropagation();
3997
4131
  removeSlot(i, index);
3998
4132
  },
3999
- children: /* @__PURE__ */ jsx8(CloseIcon4, {})
4133
+ children: /* @__PURE__ */ jsx9(CloseIcon4, {})
4000
4134
  }
4001
4135
  ) : (
4002
4136
  /* Required pick at its floor — quiet state chip instead
4003
4137
  of the ×; removal returns once another slot covers
4004
4138
  the product's minimum (variant swap flow). */
4005
- /* @__PURE__ */ jsx8("span", { className: "lb-mix-match__slot-required", children: "Required" })
4139
+ /* @__PURE__ */ jsx9("span", { className: "lb-mix-match__slot-required", children: "Required" })
4006
4140
  )
4007
4141
  ]
4008
4142
  },
@@ -4011,7 +4145,7 @@ function MultiStepBundle(props) {
4011
4145
  ))
4012
4146
  }
4013
4147
  ),
4014
- stepHeadroom2(step.maxQuantity, unitsByStep[i] ?? 0) !== 0 && /* @__PURE__ */ jsxs8(
4148
+ stepHeadroom2(step.maxQuantity, unitsByStep[i] ?? 0) !== 0 && /* @__PURE__ */ jsxs9(
4015
4149
  "button",
4016
4150
  {
4017
4151
  type: "button",
@@ -4020,15 +4154,15 @@ function MultiStepBundle(props) {
4020
4154
  "aria-label": `${step.minQuantity === 1 && step.maxQuantity === 1 ? "Choose a product" : "Choose products"}: ${step.name}`,
4021
4155
  onClick: () => setPickerOpenAt(i),
4022
4156
  children: [
4023
- /* @__PURE__ */ jsx8(
4157
+ /* @__PURE__ */ jsx9(
4024
4158
  "span",
4025
4159
  {
4026
4160
  className: "lb-mix-match__add-product-icon",
4027
4161
  "aria-hidden": "true",
4028
- children: /* @__PURE__ */ jsx8(PlusIcon2, {})
4162
+ children: /* @__PURE__ */ jsx9(PlusIcon2, {})
4029
4163
  }
4030
4164
  ),
4031
- /* @__PURE__ */ jsx8("span", { className: "lb-mix-match__add-product-label", children: step.minQuantity === 1 && step.maxQuantity === 1 ? "Choose a product" : "Choose products" })
4165
+ /* @__PURE__ */ jsx9("span", { className: "lb-mix-match__add-product-label", children: step.minQuantity === 1 && step.maxQuantity === 1 ? "Choose a product" : "Choose products" })
4032
4166
  ]
4033
4167
  }
4034
4168
  )
@@ -4036,29 +4170,29 @@ function MultiStepBundle(props) {
4036
4170
  },
4037
4171
  i
4038
4172
  )) }),
4039
- /* @__PURE__ */ jsx8("div", { className: "lb-bundle-divider" }),
4040
- allSatisfied && /* @__PURE__ */ jsxs8("div", { className: "lb-bundle-summary", "data-pricing-section": true, children: [
4041
- /* @__PURE__ */ jsxs8("div", { className: "lb-bundle-summary__text", children: [
4042
- /* @__PURE__ */ jsx8("span", { className: "lb-bundle-summary__label", children: "Bundle total" }),
4043
- bundle.widgetConfig.savingsBar.visible && summary.savings > 0 && /* @__PURE__ */ jsxs8("p", { className: "lb-bundle-savings-line", "data-savings-bar": true, children: [
4173
+ /* @__PURE__ */ jsx9("div", { className: "lb-bundle-divider" }),
4174
+ allSatisfied && /* @__PURE__ */ jsxs9("div", { className: "lb-bundle-summary", "data-pricing-section": true, children: [
4175
+ /* @__PURE__ */ jsxs9("div", { className: "lb-bundle-summary__text", children: [
4176
+ /* @__PURE__ */ jsx9("span", { className: "lb-bundle-summary__label", children: "Bundle total" }),
4177
+ bundle.widgetConfig.savingsBar.visible && summary.savings > 0 && /* @__PURE__ */ jsxs9("p", { className: "lb-bundle-savings-line", "data-savings-bar": true, children: [
4044
4178
  "You save",
4045
4179
  " ",
4046
- /* @__PURE__ */ jsx8("span", { "data-savings-amount": true, children: formatMoney7(summary.savings, currency) }),
4180
+ /* @__PURE__ */ jsx9("span", { "data-savings-amount": true, children: formatMoney7(summary.savings, currency) }),
4047
4181
  " ",
4048
- /* @__PURE__ */ jsxs8("span", { "data-savings-percent": true, children: [
4182
+ /* @__PURE__ */ jsxs9("span", { "data-savings-percent": true, children: [
4049
4183
  "(",
4050
4184
  summary.savingsPercent,
4051
4185
  "%)"
4052
4186
  ] })
4053
4187
  ] })
4054
4188
  ] }),
4055
- /* @__PURE__ */ jsxs8("span", { className: "lb-bundle-summary__prices", children: [
4056
- bundle.widgetConfig.pricing.showComparePrice && summary.savings > 0 && /* @__PURE__ */ jsx8("span", { className: "lb-bundle-compare-price", "data-compare-price": true, children: formatMoney7(summary.comparePrice, currency) }),
4057
- /* @__PURE__ */ jsx8("span", { className: "lb-bundle-sale-price", "data-sale-price": true, children: formatMoney7(summary.salePrice, currency) })
4189
+ /* @__PURE__ */ jsxs9("span", { className: "lb-bundle-summary__prices", children: [
4190
+ bundle.widgetConfig.pricing.showComparePrice && summary.savings > 0 && /* @__PURE__ */ jsx9("span", { className: "lb-bundle-compare-price", "data-compare-price": true, children: formatMoney7(summary.comparePrice, currency) }),
4191
+ /* @__PURE__ */ jsx9("span", { className: "lb-bundle-sale-price", "data-sale-price": true, children: formatMoney7(summary.salePrice, currency) })
4058
4192
  ] })
4059
4193
  ] }),
4060
- cartError && /* @__PURE__ */ jsx8("p", { className: "lb-bundle__error", role: "alert", children: cartError }),
4061
- /* @__PURE__ */ jsx8(
4194
+ cartError && /* @__PURE__ */ jsx9("p", { className: "lb-bundle__error", role: "alert", children: cartError }),
4195
+ /* @__PURE__ */ jsx9(
4062
4196
  "button",
4063
4197
  {
4064
4198
  className: "lb-bundle__cta",
@@ -4068,10 +4202,9 @@ function MultiStepBundle(props) {
4068
4202
  children: ctaLabel
4069
4203
  }
4070
4204
  ),
4071
- pickerOpenAt !== null && /* @__PURE__ */ jsx8(
4205
+ pickerOpenAt !== null && /* @__PURE__ */ jsx9(
4072
4206
  MultiStepPicker,
4073
4207
  {
4074
- outOfStockBehavior,
4075
4208
  bundle,
4076
4209
  currency,
4077
4210
  initialStep: pickerOpenAt,
@@ -4104,7 +4237,7 @@ function stepHasInStockProduct(bundle, stepIndex) {
4104
4237
  });
4105
4238
  }
4106
4239
  function PlusIcon2() {
4107
- return /* @__PURE__ */ jsxs8(
4240
+ return /* @__PURE__ */ jsxs9(
4108
4241
  "svg",
4109
4242
  {
4110
4243
  width: "18",
@@ -4114,14 +4247,14 @@ function PlusIcon2() {
4114
4247
  xmlns: "http://www.w3.org/2000/svg",
4115
4248
  "aria-hidden": "true",
4116
4249
  children: [
4117
- /* @__PURE__ */ jsx8("line", { x1: "9", y1: "3", x2: "9", y2: "15", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }),
4118
- /* @__PURE__ */ jsx8("line", { x1: "3", y1: "9", x2: "15", y2: "9", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" })
4250
+ /* @__PURE__ */ jsx9("line", { x1: "9", y1: "3", x2: "9", y2: "15", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }),
4251
+ /* @__PURE__ */ jsx9("line", { x1: "3", y1: "9", x2: "15", y2: "9", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" })
4119
4252
  ]
4120
4253
  }
4121
4254
  );
4122
4255
  }
4123
4256
  function CloseIcon4() {
4124
- return /* @__PURE__ */ jsxs8(
4257
+ return /* @__PURE__ */ jsxs9(
4125
4258
  "svg",
4126
4259
  {
4127
4260
  width: "16",
@@ -4131,8 +4264,8 @@ function CloseIcon4() {
4131
4264
  xmlns: "http://www.w3.org/2000/svg",
4132
4265
  "aria-hidden": "true",
4133
4266
  children: [
4134
- /* @__PURE__ */ jsx8("line", { x1: "5", y1: "5", x2: "15", y2: "15", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }),
4135
- /* @__PURE__ */ jsx8("line", { x1: "15", y1: "5", x2: "5", y2: "15", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" })
4267
+ /* @__PURE__ */ jsx9("line", { x1: "5", y1: "5", x2: "15", y2: "15", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }),
4268
+ /* @__PURE__ */ jsx9("line", { x1: "15", y1: "5", x2: "5", y2: "15", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" })
4136
4269
  ]
4137
4270
  }
4138
4271
  );
@@ -4233,16 +4366,14 @@ import {
4233
4366
  parseMetaobjectBundleStrict as parseMetaobjectBundleStrict2,
4234
4367
  BUNDLE_METAOBJECT_QUERY as BUNDLE_METAOBJECT_QUERY2,
4235
4368
  BUNDLES_FOR_PRODUCT_QUERY,
4236
- SHOP_SETTINGS_QUERY as SHOP_SETTINGS_QUERY2,
4237
- DEFAULT_OUT_OF_STOCK_BEHAVIOR as DEFAULT_OUT_OF_STOCK_BEHAVIOR3,
4238
- parseOutOfStockBehavior as parseOutOfStockBehavior2
4369
+ SHOP_SETTINGS_QUERY as SHOP_SETTINGS_QUERY2
4239
4370
  } from "@lime-bundles/core";
4240
4371
  export {
4241
4372
  BUNDLES_FOR_PRODUCT_QUERY,
4242
4373
  BUNDLE_METAOBJECT_QUERY2 as BUNDLE_METAOBJECT_QUERY,
4243
4374
  BogoBundle,
4375
+ BundleCountdown,
4244
4376
  BundleParseError2 as BundleParseError,
4245
- DEFAULT_OUT_OF_STOCK_BEHAVIOR3 as DEFAULT_OUT_OF_STOCK_BEHAVIOR,
4246
4377
  FixedBundle,
4247
4378
  MixMatchBundle,
4248
4379
  MultiStepBundle,
@@ -4273,7 +4404,6 @@ export {
4273
4404
  parseCents,
4274
4405
  parseMetaobjectBundle,
4275
4406
  parseMetaobjectBundleStrict2 as parseMetaobjectBundleStrict,
4276
- parseOutOfStockBehavior2 as parseOutOfStockBehavior,
4277
4407
  percentageDiscountUnit,
4278
4408
  productsForStep3 as productsForStep,
4279
4409
  reportAddToCart2 as reportAddToCart,
@@ -4285,7 +4415,6 @@ export {
4285
4415
  useAnalytics,
4286
4416
  useBundleData,
4287
4417
  useBundlesForProduct,
4288
- useShopSettings,
4289
4418
  useVariantSelection,
4290
4419
  useWidgetConfigVars,
4291
4420
  validateQuantity