@lime-bundles/react 7.1.0 → 7.3.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
@@ -1004,7 +1004,9 @@ function FixedProductRow({ bundle, product, currency, isOos, onVariantChange })
1004
1004
  src: thumbImage.url,
1005
1005
  alt: thumbImage.altText ?? product.title,
1006
1006
  className: "lb-bundle__product-image",
1007
- loading: "lazy"
1007
+ loading: "lazy",
1008
+ width: thumbImage.width ?? void 0,
1009
+ height: thumbImage.height ?? void 0
1008
1010
  }
1009
1011
  ),
1010
1012
  /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "lb-bundle__product-info", children: [
@@ -1610,7 +1612,9 @@ function MixMatchPickerRow({
1610
1612
  {
1611
1613
  src: thumbImage.url,
1612
1614
  alt: thumbImage.altText ?? product.title,
1613
- loading: "lazy"
1615
+ loading: "lazy",
1616
+ width: thumbImage.width ?? void 0,
1617
+ height: thumbImage.height ?? void 0
1614
1618
  }
1615
1619
  ),
1616
1620
  variantInBundle && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "lb-mix-match__modal-added-badge", children: "Added" })
@@ -2520,7 +2524,9 @@ function VolumeBundle(props) {
2520
2524
  src: thumbImage.url,
2521
2525
  alt: thumbImage.altText ?? product.title,
2522
2526
  className: "lb-bundle__product-image",
2523
- loading: "lazy"
2527
+ loading: "lazy",
2528
+ width: thumbImage.width ?? void 0,
2529
+ height: thumbImage.height ?? void 0
2524
2530
  }
2525
2531
  ),
2526
2532
  /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "lb-bundle__product-info", children: [
@@ -2964,7 +2970,9 @@ function BogoProductRow({ side, product, quantity, percent, badge, currency, onV
2964
2970
  src: thumbImage.url,
2965
2971
  alt: thumbImage.altText ?? product.title,
2966
2972
  className: "lb-bundle__product-image",
2967
- loading: "lazy"
2973
+ loading: "lazy",
2974
+ width: thumbImage.width ?? void 0,
2975
+ height: thumbImage.height ?? void 0
2968
2976
  }
2969
2977
  ),
2970
2978
  /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "lb-bundle__product-info", children: [
@@ -3137,6 +3145,17 @@ function MultiStepPicker({
3137
3145
  }
3138
3146
  return front.concat(back);
3139
3147
  }, [eligible, selectedAtLoad]);
3148
+ const autoAdvance = wc.multiStepAutoAdvance === true;
3149
+ const lastSeen = (0, import_react15.useRef)({ step: stepIndex, units: unitsInStep });
3150
+ (0, import_react15.useEffect)(() => {
3151
+ const prev = lastSeen.current;
3152
+ lastSeen.current = { step: stepIndex, units: unitsInStep };
3153
+ if (!autoAdvance || isLastStep || prev.step !== stepIndex) return;
3154
+ if (unitsInStep <= prev.units) return;
3155
+ if ((0, import_core13.stepHeadroom)(step?.maxQuantity ?? null, unitsInStep) === 0) {
3156
+ goToStep(stepIndex + 1);
3157
+ }
3158
+ });
3140
3159
  function goToStep(i) {
3141
3160
  const clamped = Math.max(0, Math.min(steps.length - 1, i));
3142
3161
  setStepIndex(clamped);
@@ -3516,7 +3535,9 @@ function MultiStepPickerRow({
3516
3535
  {
3517
3536
  src: thumbImage.url,
3518
3537
  alt: thumbImage.altText ?? product.title,
3519
- loading: "lazy"
3538
+ loading: "lazy",
3539
+ width: thumbImage.width ?? void 0,
3540
+ height: thumbImage.height ?? void 0
3520
3541
  }
3521
3542
  ),
3522
3543
  variantInStep && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "lb-mix-match__modal-added-badge", children: "Added" })
@@ -3810,6 +3831,9 @@ function MultiStepBundle(props) {
3810
3831
  const allSatisfied = steps.length > 0 && steps.every((_, i) => stepSatisfied(i));
3811
3832
  const valid = !!bundle && allSatisfied;
3812
3833
  const completedSteps = steps.filter((_, i) => stepSatisfied(i)).length;
3834
+ const firstUnsatisfied = steps.findIndex((_, i) => !stepSatisfied(i));
3835
+ const remainingSteps = steps.length - completedSteps;
3836
+ const anyPicks = selections.some((s) => s.length > 0);
3813
3837
  const summary = (0, import_react16.useMemo)(() => {
3814
3838
  let comparePrice = 0;
3815
3839
  let salePrice = 0;
@@ -4052,115 +4076,156 @@ function MultiStepBundle(props) {
4052
4076
  )
4053
4077
  ] })
4054
4078
  ] }),
4055
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "lb-multi-step__groups", "data-step-groups": true, children: steps.map((step, i) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
4056
- "section",
4057
- {
4058
- className: "lb-multi-step__group",
4059
- "data-step-group": i,
4060
- children: [
4061
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "lb-multi-step__group-heading", children: [
4062
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "lb-multi-step__group-name", children: step.name }),
4079
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "lb-multi-step__groups", "data-step-groups": true, children: steps.map((step, i) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react16.Fragment, { children: [
4080
+ i === firstUnsatisfied && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
4081
+ "button",
4082
+ {
4083
+ type: "button",
4084
+ className: "lb-mix-match__add-product lb-multi-step__door",
4085
+ "data-step-door": firstUnsatisfied,
4086
+ "aria-label": `${anyPicks ? "Continue building" : "Choose your products"}: ${step.name}`,
4087
+ onClick: () => setPickerOpenAt(firstUnsatisfied),
4088
+ children: [
4063
4089
  /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4064
4090
  "span",
4065
4091
  {
4066
- className: `lb-multi-step__group-count${stepSatisfied(i) ? " lb-multi-step__group-count--met" : ""}`,
4067
- "data-step-count": i,
4068
- children: `${Math.min(unitsByStep[i] ?? 0, step.minQuantity)} of ${step.minQuantity} added`
4092
+ className: "lb-mix-match__add-product-icon",
4093
+ "aria-hidden": "true",
4094
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(PlusIcon2, {})
4069
4095
  }
4070
- )
4071
- ] }),
4072
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4073
- "div",
4074
- {
4075
- className: "lb-mix-match__slots lb-edge-fade lb-multi-step__group-slots",
4076
- "data-step-slots": i,
4077
- children: (selections[i] ?? []).map((item, index) => (
4078
- /* Whole card reopens the wizard AT this step. The inner
4079
- title button provides the keyboard/AT path (its
4080
- activation bubbles here); × stops propagation. */
4081
- // 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
4082
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
4083
- "div",
4084
- {
4085
- className: "lb-mix-match__slot lb-mix-match__slot--filled",
4086
- onClick: () => setPickerOpenAt(i),
4087
- children: [
4088
- item.featuredImage && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "lb-bundle-thumbnail", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4089
- "img",
4090
- {
4091
- src: item.featuredImage,
4092
- alt: item.title,
4093
- loading: "lazy"
4094
- }
4095
- ) }),
4096
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "lb-mix-match__filled-info", children: [
4097
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4098
- "button",
4099
- {
4100
- type: "button",
4101
- className: "lb-mix-match__filled-title",
4102
- "aria-label": `Edit selection: ${item.title}`,
4103
- children: item.title
4104
- }
4105
- ),
4106
- item.variantTitle && item.variantTitle !== "Default Title" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "lb-mix-match__filled-variant", children: item.variantTitle }),
4107
- /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "lb-mix-match__filled-price", children: [
4108
- item.compareAtPrice !== null && item.compareAtPrice > item.price && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("s", { className: "lb-mix-match__filled-compare", children: (0, import_core14.formatMoney)(item.compareAtPrice, currency) }),
4109
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "lb-bundle-product-price", children: (0, import_core14.formatMoney)(item.price, currency) }),
4110
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "lb-bundle-qty-inline", children: `\xD7${item.quantity}` })
4111
- ] }),
4112
- item.unitPrice && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "lb-bundle-product-unit-price", children: item.unitPrice })
4113
- ] }),
4114
- canRemoveItem2(bundle, selections, item) ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4115
- "button",
4116
- {
4117
- type: "button",
4118
- className: "lb-mix-match__slot-remove",
4119
- "aria-label": `Remove ${item.title}`,
4120
- onClick: (e) => {
4121
- e.stopPropagation();
4122
- removeSlot(i, index);
4123
- },
4124
- children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(CloseIcon4, {})
4125
- }
4126
- ) : (
4127
- /* Required pick at its floor — quiet state chip instead
4128
- of the ×; removal returns once another slot covers
4129
- the product's minimum (variant swap flow). */
4130
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "lb-mix-match__slot-required", children: "Required" })
4131
- )
4132
- ]
4133
- },
4134
- `${item.productId}:${item.variantId}:${index}`
4135
- )
4136
- ))
4137
- }
4138
- ),
4139
- (0, import_core14.stepHeadroom)(step.maxQuantity, unitsByStep[i] ?? 0) !== 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
4096
+ ),
4097
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "lb-multi-step__door-copy", children: [
4098
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "lb-mix-match__add-product-label", children: anyPicks ? "Continue building" : "Choose your products" }),
4099
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "lb-multi-step__door-sub", children: anyPicks ? `${remainingSteps} ${remainingSteps === 1 ? "step" : "steps"} to go` : `${steps.length} quick ${steps.length === 1 ? "step" : "steps"}` })
4100
+ ] })
4101
+ ]
4102
+ }
4103
+ ),
4104
+ (selections[i] ?? []).length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4105
+ "section",
4106
+ {
4107
+ className: "lb-multi-step__group",
4108
+ "data-step-group": i,
4109
+ "data-step-mode": "row",
4110
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
4140
4111
  "button",
4141
4112
  {
4142
4113
  type: "button",
4143
- className: "lb-mix-match__add-product lb-multi-step__step-trigger",
4144
- "data-step-trigger": i,
4114
+ className: "lb-multi-step__step-row",
4115
+ "data-step-row": i,
4145
4116
  "aria-label": `${step.minQuantity === 1 && step.maxQuantity === 1 ? "Choose a product" : "Choose products"}: ${step.name}`,
4146
4117
  onClick: () => setPickerOpenAt(i),
4147
4118
  children: [
4148
4119
  /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4149
4120
  "span",
4150
4121
  {
4151
- className: "lb-mix-match__add-product-icon",
4122
+ className: "lb-multi-step__step-ix",
4152
4123
  "aria-hidden": "true",
4153
- children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(PlusIcon2, {})
4124
+ children: i + 1
4154
4125
  }
4155
4126
  ),
4156
- /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "lb-mix-match__add-product-label", children: step.minQuantity === 1 && step.maxQuantity === 1 ? "Choose a product" : "Choose products" })
4127
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "lb-multi-step__group-name", children: step.name }),
4128
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4129
+ "span",
4130
+ {
4131
+ className: `lb-multi-step__group-count${stepSatisfied(i) ? " lb-multi-step__group-count--met" : ""}`,
4132
+ "data-step-count": i,
4133
+ children: `${Math.min(unitsByStep[i] ?? 0, step.minQuantity)} of ${step.minQuantity} added`
4134
+ }
4135
+ )
4157
4136
  ]
4158
4137
  }
4159
4138
  )
4160
- ]
4161
- },
4162
- i
4163
- )) }),
4139
+ }
4140
+ ) : /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
4141
+ "section",
4142
+ {
4143
+ className: "lb-multi-step__group",
4144
+ "data-step-group": i,
4145
+ "data-step-mode": "open",
4146
+ children: [
4147
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "lb-multi-step__group-heading", children: [
4148
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "lb-multi-step__group-name", children: step.name }),
4149
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4150
+ "span",
4151
+ {
4152
+ className: `lb-multi-step__group-count${stepSatisfied(i) ? " lb-multi-step__group-count--met" : ""}`,
4153
+ "data-step-count": i,
4154
+ children: `${Math.min(unitsByStep[i] ?? 0, step.minQuantity)} of ${step.minQuantity} added`
4155
+ }
4156
+ )
4157
+ ] }),
4158
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4159
+ "div",
4160
+ {
4161
+ className: "lb-mix-match__slots lb-edge-fade lb-multi-step__group-slots",
4162
+ "data-step-slots": i,
4163
+ children: (selections[i] ?? []).map((item, index) => (
4164
+ /* Whole card reopens the wizard AT this step. The inner
4165
+ title button provides the keyboard/AT path (its
4166
+ activation bubbles here); × stops propagation. */
4167
+ // 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
4168
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
4169
+ "div",
4170
+ {
4171
+ className: "lb-mix-match__slot lb-mix-match__slot--filled",
4172
+ onClick: () => setPickerOpenAt(i),
4173
+ children: [
4174
+ item.featuredImage && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "lb-bundle-thumbnail", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4175
+ "img",
4176
+ {
4177
+ src: item.featuredImage,
4178
+ alt: item.title,
4179
+ loading: "lazy"
4180
+ }
4181
+ ) }),
4182
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "lb-mix-match__filled-info", children: [
4183
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4184
+ "button",
4185
+ {
4186
+ type: "button",
4187
+ className: "lb-mix-match__filled-title",
4188
+ "aria-label": `Edit selection: ${item.title}`,
4189
+ children: item.title
4190
+ }
4191
+ ),
4192
+ item.variantTitle && item.variantTitle !== "Default Title" && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "lb-mix-match__filled-variant", children: item.variantTitle }),
4193
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "lb-mix-match__filled-price", children: [
4194
+ item.compareAtPrice !== null && item.compareAtPrice > item.price && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("s", { className: "lb-mix-match__filled-compare", children: (0, import_core14.formatMoney)(item.compareAtPrice, currency) }),
4195
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "lb-bundle-product-price", children: (0, import_core14.formatMoney)(item.price, currency) }),
4196
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "lb-bundle-qty-inline", children: `\xD7${item.quantity}` })
4197
+ ] }),
4198
+ item.unitPrice && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "lb-bundle-product-unit-price", children: item.unitPrice })
4199
+ ] }),
4200
+ canRemoveItem2(bundle, selections, item) ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
4201
+ "button",
4202
+ {
4203
+ type: "button",
4204
+ className: "lb-mix-match__slot-remove",
4205
+ "aria-label": `Remove ${item.title}`,
4206
+ onClick: (e) => {
4207
+ e.stopPropagation();
4208
+ removeSlot(i, index);
4209
+ },
4210
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(CloseIcon4, {})
4211
+ }
4212
+ ) : (
4213
+ /* Required pick at its floor — quiet state chip instead
4214
+ of the ×; removal returns once another slot covers
4215
+ the product's minimum (variant swap flow). */
4216
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "lb-mix-match__slot-required", children: "Required" })
4217
+ )
4218
+ ]
4219
+ },
4220
+ `${item.productId}:${item.variantId}:${index}`
4221
+ )
4222
+ ))
4223
+ }
4224
+ )
4225
+ ]
4226
+ }
4227
+ )
4228
+ ] }, i)) }),
4164
4229
  /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: "lb-bundle-divider" }),
4165
4230
  allSatisfied && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "lb-bundle-summary", "data-pricing-section": true, children: [
4166
4231
  /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "lb-bundle-summary__text", children: [