@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.cjs +65 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +74 -12
- package/dist/index.js.map +1 -1
- package/docs/css-variables.md +11 -0
- package/package.json +2 -2
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(
|
|
598
|
-
|
|
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(
|
|
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(
|
|
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: !
|
|
1024
|
-
children:
|
|
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
|
|
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(
|
|
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
|
{
|