@lime-bundles/react 6.0.0 → 6.1.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 CHANGED
@@ -1155,9 +1155,16 @@ function useFocusTrap({
1155
1155
 
1156
1156
  // src/components/MixMatchPicker.tsx
1157
1157
  var import_jsx_runtime3 = require("react/jsx-runtime");
1158
- function ruleFor(bundle, productId) {
1158
+ function ruleFor(bundle, productId, variantId) {
1159
+ if (variantId) {
1160
+ const vRule = bundle.variantRules[variantId];
1161
+ if (vRule) return vRule;
1162
+ }
1159
1163
  return bundle.productRules[productId] ?? import_core10.DEFAULT_PRODUCT_RULE;
1160
1164
  }
1165
+ function variantRuleFor(bundle, variantId) {
1166
+ return variantId ? bundle.variantRules[variantId] : void 0;
1167
+ }
1161
1168
  function sanitizeId(gid) {
1162
1169
  return gid.replace(/[^a-zA-Z0-9_-]/g, "-");
1163
1170
  }
@@ -1462,6 +1469,8 @@ function MixMatchPickerRow({
1462
1469
  const showPicker = variants.length > 1 && optionNames.length > 0;
1463
1470
  const { selectedValues, selectedVariant, setOptionValue, optionsFor } = useVariantSelection({ variants, optionNames });
1464
1471
  const currentVariant = selectedVariant ?? variants.find((v) => (0, import_core10.isVariantFulfillable)(v, rule.min)) ?? eligible.firstAvailableVariant ?? variants[0] ?? null;
1472
+ const vRule = ruleFor(bundle, product.id, currentVariant?.id);
1473
+ const variantMax = variantRuleFor(bundle, currentVariant?.id)?.max;
1465
1474
  const alreadyInBundle = (0, import_react11.useMemo)(() => {
1466
1475
  if (!currentVariant) return 0;
1467
1476
  let sum = 0;
@@ -1489,22 +1498,26 @@ function MixMatchPickerRow({
1489
1498
  return sum;
1490
1499
  }, [selections, product.id, currentVariant]);
1491
1500
  const swapUnits = currentVariant ? swapUnitsFor?.(product.id, currentVariant.id) ?? 0 : 0;
1492
- const inSwapState = swapUnits >= rule.min;
1493
- const spotCeiling = inSwapState ? swapUnits : Math.min(rule.max - productOtherUnits, committedQty + remainingUnits);
1501
+ const inSwapState = swapUnits >= vRule.min;
1502
+ const spotCeiling = inSwapState ? swapUnits : Math.min(
1503
+ rule.max - productOtherUnits,
1504
+ committedQty + remainingUnits,
1505
+ variantMax ?? Infinity
1506
+ );
1494
1507
  const cap = currentVariant ? (0, import_core10.maxAddableQuantity)(
1495
1508
  currentVariant,
1496
1509
  spotCeiling,
1497
1510
  Math.max(0, alreadyInBundle - committedQty)
1498
1511
  ) : 0;
1499
- const stepperMax = Math.max(rule.min, cap);
1500
- const [qty, setQty] = (0, import_react11.useState)(rule.min);
1512
+ const stepperMax = Math.max(vRule.min, cap);
1513
+ const [qty, setQty] = (0, import_react11.useState)(vRule.min);
1501
1514
  (0, import_react11.useEffect)(() => {
1502
- setQty((prev) => Math.max(rule.min, Math.min(prev, stepperMax)));
1503
- }, [stepperMax, rule.min]);
1515
+ setQty((prev) => Math.max(vRule.min, Math.min(prev, stepperMax)));
1516
+ }, [stepperMax, vRule.min]);
1504
1517
  const currentVariantId = currentVariant?.id ?? null;
1505
1518
  (0, import_react11.useEffect)(() => {
1506
- if (!variantInBundle) setQty(rule.min);
1507
- }, [variantInBundle, currentVariantId, rule.min]);
1519
+ if (!variantInBundle) setQty(vRule.min);
1520
+ }, [variantInBundle, currentVariantId, vRule.min]);
1508
1521
  if (!currentVariant) return null;
1509
1522
  const thumbImage = currentVariant.image ?? product.featuredImage ?? null;
1510
1523
  const unitPriceText = (0, import_core10.formatUnitPrice)(
@@ -1512,8 +1525,8 @@ function MixMatchPickerRow({
1512
1525
  currentVariant.unitPriceMeasurement,
1513
1526
  currency
1514
1527
  );
1515
- const noStock = cap < rule.min;
1516
- const needsMoreSpots = !variantInBundle && !inSwapState && rule.min > remainingUnits;
1528
+ const noStock = cap < vRule.min;
1529
+ const needsMoreSpots = !variantInBundle && !inSwapState && vRule.min > remainingUnits;
1517
1530
  const addDisabled = !variantInBundle && (inSwapState ? noStock : atCapacity || noStock || needsMoreSpots);
1518
1531
  const lockedRequired = variantInBundle && currentVariant != null && !(canRemoveVariant?.(currentVariant.id) ?? true);
1519
1532
  const stepperDisabled = isOos || !variantInBundle && addDisabled;
@@ -1524,7 +1537,7 @@ function MixMatchPickerRow({
1524
1537
  return;
1525
1538
  }
1526
1539
  if (!currentVariant || noStock) return;
1527
- const pickedQty = showStepper ? qty : rule.min;
1540
+ const pickedQty = showStepper ? qty : vRule.min;
1528
1541
  const item = {
1529
1542
  productId: product.id,
1530
1543
  variantId: currentVariant.id,
@@ -1724,10 +1737,18 @@ function SearchClearIcon() {
1724
1737
 
1725
1738
  // src/components/MixMatchBundle.tsx
1726
1739
  var import_jsx_runtime4 = require("react/jsx-runtime");
1727
- function ruleFor2(bundle, productId) {
1740
+ function ruleFor2(bundle, productId, variantId) {
1741
+ if (variantId) {
1742
+ const vRule = bundle.variantRules[variantId];
1743
+ if (vRule) return vRule;
1744
+ }
1728
1745
  return bundle.productRules[productId] ?? import_core11.DEFAULT_PRODUCT_RULE;
1729
1746
  }
1747
+ function variantRuleFor2(bundle, variantId) {
1748
+ return variantId ? bundle.variantRules[variantId] : void 0;
1749
+ }
1730
1750
  function canRemoveItem(bundle, selections, item) {
1751
+ if (variantRuleFor2(bundle, item.variantId)?.required) return false;
1731
1752
  const rule = ruleFor2(bundle, item.productId);
1732
1753
  if (!rule.required) return true;
1733
1754
  const unitsElsewhere = selections.filter((s) => s.productId === item.productId && s !== item).reduce((sum, s) => sum + s.quantity, 0);
@@ -2889,9 +2910,16 @@ var import_react15 = require("react");
2889
2910
  var import_react_dom2 = require("react-dom");
2890
2911
  var import_core14 = require("@lime-bundles/core");
2891
2912
  var import_jsx_runtime7 = require("react/jsx-runtime");
2892
- function ruleFor3(bundle, productId) {
2913
+ function ruleFor3(bundle, productId, variantId) {
2914
+ if (variantId) {
2915
+ const vRule = bundle.variantRules[variantId];
2916
+ if (vRule) return vRule;
2917
+ }
2893
2918
  return bundle.productRules[productId] ?? import_core14.DEFAULT_PRODUCT_RULE;
2894
2919
  }
2920
+ function variantRuleFor3(bundle, variantId) {
2921
+ return variantId ? bundle.variantRules[variantId] : void 0;
2922
+ }
2895
2923
  function sanitizeId2(gid) {
2896
2924
  return gid.replace(/[^a-zA-Z0-9_-]/g, "-");
2897
2925
  }
@@ -3244,6 +3272,8 @@ function MultiStepPickerRow({
3244
3272
  const showPicker = variants.length > 1 && optionNames.length > 0;
3245
3273
  const { selectedValues, selectedVariant, setOptionValue, optionsFor } = useVariantSelection({ variants, optionNames });
3246
3274
  const currentVariant = selectedVariant ?? variants.find((v) => (0, import_core14.isVariantFulfillable)(v, rule.min)) ?? eligible.firstAvailableVariant ?? variants[0] ?? null;
3275
+ const vRule = ruleFor3(bundle, product.id, currentVariant?.id);
3276
+ const variantMax = variantRuleFor3(bundle, currentVariant?.id)?.max;
3247
3277
  const stepPicks = (0, import_react15.useMemo)(
3248
3278
  () => selections[stepIndex] ?? [],
3249
3279
  [selections, stepIndex]
@@ -3278,24 +3308,27 @@ function MultiStepPickerRow({
3278
3308
  return Math.max(0, sum - committedQty);
3279
3309
  }, [selections, currentVariant, committedQty]);
3280
3310
  const swapUnits = currentVariant ? swapUnitsFor?.(stepIndex, product.id, currentVariant.id) ?? 0 : 0;
3281
- const inSwapState = swapUnits >= rule.min;
3311
+ const inSwapState = swapUnits >= vRule.min;
3282
3312
  const room = (0, import_core14.stepHeadroom)(step?.maxQuantity ?? null, unitsInStep);
3283
- const productHeadroom = rule.max - productOtherUnits;
3313
+ const productHeadroom = Math.min(
3314
+ rule.max - productOtherUnits,
3315
+ variantMax ?? Infinity
3316
+ );
3284
3317
  const spotCeiling = inSwapState ? swapUnits : Math.min(
3285
3318
  productHeadroom,
3286
3319
  room === Number.POSITIVE_INFINITY ? productHeadroom : committedQty + room
3287
3320
  );
3288
3321
  const stockRemaining = currentVariant ? (0, import_core14.maxAddableQuantity)(currentVariant, Number.MAX_SAFE_INTEGER, variantOtherUnits) : 0;
3289
3322
  const cap = Math.max(0, Math.min(spotCeiling, stockRemaining));
3290
- const stepperMax = Math.max(rule.min, cap);
3291
- const [qty, setQty] = (0, import_react15.useState)(rule.min);
3323
+ const stepperMax = Math.max(vRule.min, cap);
3324
+ const [qty, setQty] = (0, import_react15.useState)(vRule.min);
3292
3325
  (0, import_react15.useEffect)(() => {
3293
- setQty((prev) => Math.max(rule.min, Math.min(prev, stepperMax)));
3294
- }, [stepperMax, rule.min]);
3326
+ setQty((prev) => Math.max(vRule.min, Math.min(prev, stepperMax)));
3327
+ }, [stepperMax, vRule.min]);
3295
3328
  const currentVariantId = currentVariant?.id ?? null;
3296
3329
  (0, import_react15.useEffect)(() => {
3297
- if (!variantInStep) setQty(rule.min);
3298
- }, [variantInStep, currentVariantId, rule.min]);
3330
+ if (!variantInStep) setQty(vRule.min);
3331
+ }, [variantInStep, currentVariantId, vRule.min]);
3299
3332
  if (!currentVariant || !step) return null;
3300
3333
  const thumbImage = currentVariant.image ?? product.featuredImage ?? null;
3301
3334
  const unitPriceText = (0, import_core14.formatUnitPrice)(
@@ -3303,8 +3336,8 @@ function MultiStepPickerRow({
3303
3336
  currentVariant.unitPriceMeasurement,
3304
3337
  currency
3305
3338
  );
3306
- const noStock = cap < rule.min;
3307
- const needsMoreSpots = !variantInStep && !inSwapState && room !== Number.POSITIVE_INFINITY && rule.min > room;
3339
+ const noStock = cap < vRule.min;
3340
+ const needsMoreSpots = !variantInStep && !inSwapState && room !== Number.POSITIVE_INFINITY && vRule.min > room;
3308
3341
  const addDisabled = !variantInStep && (inSwapState ? noStock : noStock || needsMoreSpots);
3309
3342
  const lockedRequired = variantInStep && currentVariant != null && !(canRemoveVariant?.(currentVariant.id) ?? true);
3310
3343
  const stepperDisabled = isOos || !variantInStep && addDisabled;
@@ -3315,7 +3348,7 @@ function MultiStepPickerRow({
3315
3348
  return;
3316
3349
  }
3317
3350
  if (!currentVariant || noStock) return;
3318
- const pickedQty = showStepper ? qty : rule.min;
3351
+ const pickedQty = showStepper ? qty : vRule.min;
3319
3352
  const item = {
3320
3353
  productId: product.id,
3321
3354
  variantId: currentVariant.id,
@@ -3400,7 +3433,7 @@ function MultiStepPickerRow({
3400
3433
  );
3401
3434
  }) }),
3402
3435
  !showPicker && variants.length === 1 && currentVariant.title !== "Default Title" && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "lb-mix-match__filled-variant", children: currentVariant.title }),
3403
- !isOos && needsMoreSpots && room > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "lb-mix-match__modal-needs-spots", children: rule.min === 1 ? "Needs 1 spot" : `Needs ${rule.min} spots` }),
3436
+ !isOos && needsMoreSpots && room > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "lb-mix-match__modal-needs-spots", children: vRule.min === 1 ? "Needs 1 spot" : `Needs ${vRule.min} spots` }),
3404
3437
  isOos ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "lb-mix-match__modal-sold-out-label", children: "Sold out" }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "lb-mix-match__modal-product-actions", children: [
3405
3438
  showStepper && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "lb-bundle-variant-option-group lb-mix-match__qty-stepper-group", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
3406
3439
  "div",
@@ -3415,17 +3448,17 @@ function MultiStepPickerRow({
3415
3448
  type: "button",
3416
3449
  className: "lb-mix-match__qty-stepper-button lb-mix-match__qty-stepper-button--minus",
3417
3450
  "aria-label": "Decrease quantity",
3418
- disabled: stepperDisabled || shownQty <= rule.min,
3451
+ disabled: stepperDisabled || shownQty <= vRule.min,
3419
3452
  onClick: () => {
3420
3453
  if (variantInStep && currentVariant) {
3421
3454
  onUpdateQuantity(
3422
3455
  stepIndex,
3423
3456
  product.id,
3424
3457
  currentVariant.id,
3425
- Math.max(rule.min, committedQty - 1)
3458
+ Math.max(vRule.min, committedQty - 1)
3426
3459
  );
3427
3460
  } else {
3428
- setQty((q) => Math.max(rule.min, q - 1));
3461
+ setQty((q) => Math.max(vRule.min, q - 1));
3429
3462
  }
3430
3463
  },
3431
3464
  children: "\u2212"
@@ -3517,10 +3550,18 @@ function SearchClearIcon2() {
3517
3550
 
3518
3551
  // src/components/MultiStepBundle.tsx
3519
3552
  var import_jsx_runtime8 = require("react/jsx-runtime");
3520
- function ruleFor4(bundle, productId) {
3553
+ function ruleFor4(bundle, productId, variantId) {
3554
+ if (variantId) {
3555
+ const vRule = bundle.variantRules[variantId];
3556
+ if (vRule) return vRule;
3557
+ }
3521
3558
  return bundle.productRules[productId] ?? import_core15.DEFAULT_PRODUCT_RULE;
3522
3559
  }
3560
+ function variantRuleFor4(bundle, variantId) {
3561
+ return variantId ? bundle.variantRules[variantId] : void 0;
3562
+ }
3523
3563
  function canRemoveItem2(bundle, selections, item) {
3564
+ if (variantRuleFor4(bundle, item.variantId)?.required) return false;
3524
3565
  const rule = ruleFor4(bundle, item.productId);
3525
3566
  if (!rule.required) return true;
3526
3567
  let unitsElsewhere = 0;