@lime-bundles/react 2.4.0 → 2.5.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
@@ -4,7 +4,9 @@ import {
4
4
  formatMoney,
5
5
  formatUnitPrice,
6
6
  calculateDiscount,
7
- resolveBundleQty
7
+ resolveBundleQty,
8
+ isVariantFulfillable,
9
+ shouldShowLowStockBadge
8
10
  } from "@lime-bundles/core";
9
11
 
10
12
  // src/hooks/useBundleData.ts
@@ -594,8 +596,14 @@ function FixedBundle(props) {
594
596
  }, [result, onError]);
595
597
  const handleAddToCart = useCallback4(async () => {
596
598
  if (!bundle) return;
597
- const bundleLines = bundle.products.filter((p) => p.variants.nodes.some((v) => v.availableForSale)).map((p) => {
598
- const variant = selectedVariants[p.id] ?? p.variants.nodes.find((v) => v.availableForSale);
599
+ const bundleLines = bundle.products.filter(
600
+ (p) => p.variants.nodes.some(
601
+ (v) => isVariantFulfillable(v, resolveBundleQty(bundle, p.id, v.id))
602
+ )
603
+ ).map((p) => {
604
+ const variant = selectedVariants[p.id] ?? p.variants.nodes.find(
605
+ (v) => isVariantFulfillable(v, resolveBundleQty(bundle, p.id, v.id))
606
+ );
599
607
  return {
600
608
  productId: p.id,
601
609
  variant,
@@ -665,6 +673,7 @@ function FixedBundle(props) {
665
673
  /* @__PURE__ */ jsx2("div", { className: "lb-bundle__products", children: bundle.products.map((product) => /* @__PURE__ */ jsx2(
666
674
  FixedProductRow,
667
675
  {
676
+ bundle,
668
677
  product,
669
678
  currency,
670
679
  onVariantChange: handleVariantChange
@@ -686,7 +695,7 @@ function FixedBundle(props) {
686
695
  }
687
696
  );
688
697
  }
689
- function FixedProductRow({ product, currency, onVariantChange }) {
698
+ function FixedProductRow({ bundle, product, currency, onVariantChange }) {
690
699
  const variants = product.variants.nodes;
691
700
  const optionNames = useMemo4(() => {
692
701
  const first = variants[0];
@@ -700,7 +709,9 @@ function FixedProductRow({ product, currency, onVariantChange }) {
700
709
  useEffect6(() => {
701
710
  onVariantChange(product.id, selectedVariant ?? null);
702
711
  }, [selectedVariant, product.id, onVariantChange]);
703
- const displayVariant = selectedVariant ?? variants.find((v) => v.availableForSale) ?? variants[0];
712
+ const displayVariant = selectedVariant ?? variants.find(
713
+ (v) => isVariantFulfillable(v, resolveBundleQty(bundle, product.id, v.id))
714
+ ) ?? variants[0];
704
715
  const priceText = displayVariant ? formatMoney(displayVariant.price.amount, currency) : formatMoney(product.priceRange.minVariantPrice.amount, currency);
705
716
  const unitPriceText = displayVariant ? formatUnitPrice(
706
717
  displayVariant.unitPrice,
@@ -708,6 +719,12 @@ function FixedProductRow({ product, currency, onVariantChange }) {
708
719
  currency
709
720
  ) : null;
710
721
  const thumbImage = displayVariant?.image ?? product.featuredImage;
722
+ const showLowStock = !!displayVariant && shouldShowLowStockBadge(
723
+ displayVariant,
724
+ resolveBundleQty(bundle, product.id, displayVariant.id),
725
+ bundle.widgetConfig.lowStockThreshold,
726
+ bundle.widgetConfig.showLowStockBadge
727
+ );
711
728
  return /* @__PURE__ */ jsxs2("div", { className: "lb-bundle__product", part: "product", children: [
712
729
  thumbImage && /* @__PURE__ */ jsx2(
713
730
  "img",
@@ -722,6 +739,11 @@ function FixedProductRow({ product, currency, onVariantChange }) {
722
739
  /* @__PURE__ */ jsx2("p", { className: "lb-bundle__product-title", children: product.title }),
723
740
  /* @__PURE__ */ jsx2("p", { className: "lb-bundle__product-price", children: priceText }),
724
741
  unitPriceText && /* @__PURE__ */ jsx2("p", { className: "lb-bundle__product-unit-price", children: unitPriceText }),
742
+ showLowStock && /* @__PURE__ */ jsxs2("span", { className: "lb-bundle-low-stock-badge", children: [
743
+ "Only ",
744
+ displayVariant.quantityAvailable,
745
+ " left"
746
+ ] }),
725
747
  showPicker && /* @__PURE__ */ jsx2("div", { className: "lb-bundle__product-variant-pickers", children: optionNames.map((optionName, optionIndex) => {
726
748
  const dropdownOptions = optionsFor(optionIndex).map((o) => ({
727
749
  value: o.value,
@@ -749,7 +771,9 @@ import {
749
771
  formatMoney as formatMoney2,
750
772
  formatUnitPrice as formatUnitPrice2,
751
773
  validateQuantity,
752
- resolveBundleQty as resolveBundleQty2
774
+ resolveBundleQty as resolveBundleQty2,
775
+ isVariantFulfillable as isVariantFulfillable2,
776
+ shouldShowLowStockBadge as shouldShowLowStockBadge2
753
777
  } from "@lime-bundles/core";
754
778
  import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
755
779
  function MixMatchBundle(props) {
@@ -905,6 +929,7 @@ function MixMatchBundle(props) {
905
929
  /* @__PURE__ */ jsx3("div", { className: "lb-bundle__products lb-bundle__products--selectable", children: bundle.products.map((product) => /* @__PURE__ */ jsx3(
906
930
  MixMatchProductRow,
907
931
  {
932
+ bundle,
908
933
  product,
909
934
  currency,
910
935
  selections,
@@ -930,6 +955,7 @@ function MixMatchBundle(props) {
930
955
  );
931
956
  }
932
957
  function MixMatchProductRow({
958
+ bundle,
933
959
  product,
934
960
  currency,
935
961
  selections,
@@ -943,8 +969,19 @@ function MixMatchProductRow({
943
969
  }, [variants]);
944
970
  const showPicker = variants.length > 1 && optionNames.length > 0;
945
971
  const { selectedValues, selectedVariant, setOptionValue, optionsFor } = useVariantSelection({ variants, optionNames });
946
- const displayVariant = selectedVariant ?? variants.find((v) => v.availableForSale) ?? variants[0] ?? null;
972
+ const displayVariant = selectedVariant ?? variants.find(
973
+ (v) => isVariantFulfillable2(v, resolveBundleQty2(bundle, product.id, v.id))
974
+ ) ?? variants[0] ?? null;
947
975
  if (!displayVariant) return null;
976
+ const displayVariantQty = resolveBundleQty2(
977
+ bundle,
978
+ product.id,
979
+ displayVariant.id
980
+ );
981
+ const displayVariantFulfillable = isVariantFulfillable2(
982
+ displayVariant,
983
+ displayVariantQty
984
+ );
948
985
  const key = `${product.id}:${displayVariant.id}`;
949
986
  const selected = selections.get(key);
950
987
  const thumbImage = displayVariant.image ?? product.featuredImage;
@@ -971,6 +1008,16 @@ function MixMatchProductRow({
971
1008
  /* @__PURE__ */ jsx3("p", { className: "lb-bundle__product-title", children: product.title }),
972
1009
  /* @__PURE__ */ jsx3("p", { className: "lb-bundle__product-price", children: formatMoney2(displayVariant.price.amount, currency) }),
973
1010
  unitPriceText && /* @__PURE__ */ jsx3("p", { className: "lb-bundle__product-unit-price", children: unitPriceText }),
1011
+ shouldShowLowStockBadge2(
1012
+ displayVariant,
1013
+ displayVariantQty,
1014
+ bundle.widgetConfig.lowStockThreshold,
1015
+ bundle.widgetConfig.showLowStockBadge
1016
+ ) && /* @__PURE__ */ jsxs3("span", { className: "lb-bundle-low-stock-badge", children: [
1017
+ "Only ",
1018
+ displayVariant.quantityAvailable,
1019
+ " left"
1020
+ ] }),
974
1021
  showPicker && !selected && /* @__PURE__ */ jsx3("div", { className: "lb-bundle__product-variant-pickers", children: optionNames.map((optionName, optionIndex) => {
975
1022
  const dropdownOptions = optionsFor(optionIndex).map((o) => ({
976
1023
  value: o.value,
@@ -1020,8 +1067,8 @@ function MixMatchProductRow({
1020
1067
  {
1021
1068
  className: "lb-bundle__select-btn",
1022
1069
  onClick: () => onToggle(product.id, displayVariant),
1023
- disabled: !displayVariant.availableForSale,
1024
- children: displayVariant.availableForSale ? "Select" : "Sold out"
1070
+ disabled: !displayVariantFulfillable,
1071
+ children: displayVariantFulfillable ? "Select" : "Sold out"
1025
1072
  }
1026
1073
  ) })
1027
1074
  ]
@@ -1035,7 +1082,9 @@ import {
1035
1082
  formatMoney as formatMoney3,
1036
1083
  formatUnitPrice as formatUnitPrice3,
1037
1084
  calculateTierSavings,
1038
- getActiveTier
1085
+ getActiveTier,
1086
+ isVariantFulfillable as isVariantFulfillable3,
1087
+ shouldShowLowStockBadge as shouldShowLowStockBadge3
1039
1088
  } from "@lime-bundles/core";
1040
1089
  import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
1041
1090
  function VolumeBundle(props) {
@@ -1087,7 +1136,8 @@ function VolumeBundle(props) {
1087
1136
  }, [variants]);
1088
1137
  const showPicker = variants.length > 1 && optionNames.length > 0;
1089
1138
  const { selectedValues, selectedVariant, setOptionValue, optionsFor } = useVariantSelection({ variants, optionNames });
1090
- const displayVariant = selectedVariant ?? variants.find((v) => v.availableForSale) ?? variants[0];
1139
+ const minTierQty = bundle?.volumeTiers[0]?.minQuantity ?? 1;
1140
+ const displayVariant = selectedVariant ?? variants.find((v) => isVariantFulfillable3(v, minTierQty)) ?? variants[0];
1091
1141
  const basePrice = displayVariant ? parseFloat(displayVariant.price.amount) : product ? parseFloat(product.priceRange.minVariantPrice.amount) : 0;
1092
1142
  const currency = product?.priceRange.minVariantPrice.currencyCode ?? "USD";
1093
1143
  const thumbImage = displayVariant?.image ?? product?.featuredImage ?? null;
@@ -1108,7 +1158,9 @@ function VolumeBundle(props) {
1108
1158
  const activeTier = bundle ? getActiveTier(bundle.volumeTiers, quantity) : null;
1109
1159
  const handleAddToCart = useCallback6(async () => {
1110
1160
  if (!bundle || !product) return;
1111
- const variant = selectedVariant ?? product.variants.nodes.find((v) => v.availableForSale);
1161
+ const variant = selectedVariant ?? product.variants.nodes.find(
1162
+ (v) => isVariantFulfillable3(v, quantity)
1163
+ );
1112
1164
  if (!variant) return;
1113
1165
  const lines = [
1114
1166
  {
@@ -1273,6 +1325,16 @@ function VolumeBundle(props) {
1273
1325
  ] })
1274
1326
  ] }),
1275
1327
  cartError && /* @__PURE__ */ jsx4("p", { className: "lb-bundle__error", role: "alert", children: cartError }),
1328
+ bundle && displayVariant && shouldShowLowStockBadge3(
1329
+ displayVariant,
1330
+ minTierQty,
1331
+ bundle.widgetConfig.lowStockThreshold,
1332
+ bundle.widgetConfig.showLowStockBadge
1333
+ ) && /* @__PURE__ */ jsxs4("span", { className: "lb-bundle-low-stock-badge", children: [
1334
+ "Only ",
1335
+ displayVariant.quantityAvailable,
1336
+ " left"
1337
+ ] }),
1276
1338
  /* @__PURE__ */ jsx4(
1277
1339
  "button",
1278
1340
  {