@lime-bundles/react 7.1.0 → 7.2.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
@@ -961,7 +961,9 @@ function FixedProductRow({ bundle, product, currency, isOos, onVariantChange })
961
961
  src: thumbImage.url,
962
962
  alt: thumbImage.altText ?? product.title,
963
963
  className: "lb-bundle__product-image",
964
- loading: "lazy"
964
+ loading: "lazy",
965
+ width: thumbImage.width ?? void 0,
966
+ height: thumbImage.height ?? void 0
965
967
  }
966
968
  ),
967
969
  /* @__PURE__ */ jsxs3("div", { className: "lb-bundle__product-info", children: [
@@ -1584,7 +1586,9 @@ function MixMatchPickerRow({
1584
1586
  {
1585
1587
  src: thumbImage.url,
1586
1588
  alt: thumbImage.altText ?? product.title,
1587
- loading: "lazy"
1589
+ loading: "lazy",
1590
+ width: thumbImage.width ?? void 0,
1591
+ height: thumbImage.height ?? void 0
1588
1592
  }
1589
1593
  ),
1590
1594
  variantInBundle && /* @__PURE__ */ jsx4("span", { className: "lb-mix-match__modal-added-badge", children: "Added" })
@@ -2506,7 +2510,9 @@ function VolumeBundle(props) {
2506
2510
  src: thumbImage.url,
2507
2511
  alt: thumbImage.altText ?? product.title,
2508
2512
  className: "lb-bundle__product-image",
2509
- loading: "lazy"
2513
+ loading: "lazy",
2514
+ width: thumbImage.width ?? void 0,
2515
+ height: thumbImage.height ?? void 0
2510
2516
  }
2511
2517
  ),
2512
2518
  /* @__PURE__ */ jsxs6("div", { className: "lb-bundle__product-info", children: [
@@ -2954,7 +2960,9 @@ function BogoProductRow({ side, product, quantity, percent, badge, currency, onV
2954
2960
  src: thumbImage.url,
2955
2961
  alt: thumbImage.altText ?? product.title,
2956
2962
  className: "lb-bundle__product-image",
2957
- loading: "lazy"
2963
+ loading: "lazy",
2964
+ width: thumbImage.width ?? void 0,
2965
+ height: thumbImage.height ?? void 0
2958
2966
  }
2959
2967
  ),
2960
2968
  /* @__PURE__ */ jsxs7("div", { className: "lb-bundle__product-info", children: [
@@ -3006,14 +3014,13 @@ function BogoProductRow({ side, product, quantity, percent, badge, currency, onV
3006
3014
  }
3007
3015
 
3008
3016
  // src/components/MultiStepBundle.tsx
3009
- import { useCallback as useCallback9, useEffect as useEffect15, useMemo as useMemo10, useState as useState12 } from "react";
3017
+ import { Fragment, useCallback as useCallback9, useEffect as useEffect15, useMemo as useMemo10, useState as useState12 } from "react";
3010
3018
  import {
3011
3019
  formatMoney as formatMoney7,
3012
3020
  formatUnitPrice as formatUnitPrice7,
3013
3021
  calculateDiscount as calculateDiscount3,
3014
3022
  isVariantFulfillable as isVariantFulfillable7,
3015
3023
  productsForStep as productsForStep2,
3016
- stepHeadroom as stepHeadroom2,
3017
3024
  DEFAULT_PRODUCT_RULE as DEFAULT_PRODUCT_RULE4
3018
3025
  } from "@lime-bundles/core";
3019
3026
 
@@ -3527,7 +3534,9 @@ function MultiStepPickerRow({
3527
3534
  {
3528
3535
  src: thumbImage.url,
3529
3536
  alt: thumbImage.altText ?? product.title,
3530
- loading: "lazy"
3537
+ loading: "lazy",
3538
+ width: thumbImage.width ?? void 0,
3539
+ height: thumbImage.height ?? void 0
3531
3540
  }
3532
3541
  ),
3533
3542
  variantInStep && /* @__PURE__ */ jsx8("span", { className: "lb-mix-match__modal-added-badge", children: "Added" })
@@ -3821,6 +3830,9 @@ function MultiStepBundle(props) {
3821
3830
  const allSatisfied = steps.length > 0 && steps.every((_, i) => stepSatisfied(i));
3822
3831
  const valid = !!bundle && allSatisfied;
3823
3832
  const completedSteps = steps.filter((_, i) => stepSatisfied(i)).length;
3833
+ const firstUnsatisfied = steps.findIndex((_, i) => !stepSatisfied(i));
3834
+ const remainingSteps = steps.length - completedSteps;
3835
+ const anyPicks = selections.some((s) => s.length > 0);
3824
3836
  const summary = useMemo10(() => {
3825
3837
  let comparePrice = 0;
3826
3838
  let salePrice = 0;
@@ -4063,115 +4075,156 @@ function MultiStepBundle(props) {
4063
4075
  )
4064
4076
  ] })
4065
4077
  ] }),
4066
- /* @__PURE__ */ jsx9("div", { className: "lb-multi-step__groups", "data-step-groups": true, children: steps.map((step, i) => /* @__PURE__ */ jsxs9(
4067
- "section",
4068
- {
4069
- className: "lb-multi-step__group",
4070
- "data-step-group": i,
4071
- children: [
4072
- /* @__PURE__ */ jsxs9("div", { className: "lb-multi-step__group-heading", children: [
4073
- /* @__PURE__ */ jsx9("span", { className: "lb-multi-step__group-name", children: step.name }),
4078
+ /* @__PURE__ */ jsx9("div", { className: "lb-multi-step__groups", "data-step-groups": true, children: steps.map((step, i) => /* @__PURE__ */ jsxs9(Fragment, { children: [
4079
+ i === firstUnsatisfied && /* @__PURE__ */ jsxs9(
4080
+ "button",
4081
+ {
4082
+ type: "button",
4083
+ className: "lb-mix-match__add-product lb-multi-step__door",
4084
+ "data-step-door": firstUnsatisfied,
4085
+ "aria-label": `${anyPicks ? "Continue building" : "Choose your products"}: ${step.name}`,
4086
+ onClick: () => setPickerOpenAt(firstUnsatisfied),
4087
+ children: [
4074
4088
  /* @__PURE__ */ jsx9(
4075
4089
  "span",
4076
4090
  {
4077
- className: `lb-multi-step__group-count${stepSatisfied(i) ? " lb-multi-step__group-count--met" : ""}`,
4078
- "data-step-count": i,
4079
- children: `${Math.min(unitsByStep[i] ?? 0, step.minQuantity)} of ${step.minQuantity} added`
4091
+ className: "lb-mix-match__add-product-icon",
4092
+ "aria-hidden": "true",
4093
+ children: /* @__PURE__ */ jsx9(PlusIcon2, {})
4080
4094
  }
4081
- )
4082
- ] }),
4083
- /* @__PURE__ */ jsx9(
4084
- "div",
4085
- {
4086
- className: "lb-mix-match__slots lb-edge-fade lb-multi-step__group-slots",
4087
- "data-step-slots": i,
4088
- children: (selections[i] ?? []).map((item, index) => (
4089
- /* Whole card reopens the wizard AT this step. The inner
4090
- title button provides the keyboard/AT path (its
4091
- activation bubbles here); × stops propagation. */
4092
- // 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
4093
- /* @__PURE__ */ jsxs9(
4094
- "div",
4095
- {
4096
- className: "lb-mix-match__slot lb-mix-match__slot--filled",
4097
- onClick: () => setPickerOpenAt(i),
4098
- children: [
4099
- item.featuredImage && /* @__PURE__ */ jsx9("div", { className: "lb-bundle-thumbnail", children: /* @__PURE__ */ jsx9(
4100
- "img",
4101
- {
4102
- src: item.featuredImage,
4103
- alt: item.title,
4104
- loading: "lazy"
4105
- }
4106
- ) }),
4107
- /* @__PURE__ */ jsxs9("div", { className: "lb-mix-match__filled-info", children: [
4108
- /* @__PURE__ */ jsx9(
4109
- "button",
4110
- {
4111
- type: "button",
4112
- className: "lb-mix-match__filled-title",
4113
- "aria-label": `Edit selection: ${item.title}`,
4114
- children: item.title
4115
- }
4116
- ),
4117
- item.variantTitle && item.variantTitle !== "Default Title" && /* @__PURE__ */ jsx9("span", { className: "lb-mix-match__filled-variant", children: item.variantTitle }),
4118
- /* @__PURE__ */ jsxs9("span", { className: "lb-mix-match__filled-price", children: [
4119
- item.compareAtPrice !== null && item.compareAtPrice > item.price && /* @__PURE__ */ jsx9("s", { className: "lb-mix-match__filled-compare", children: formatMoney7(item.compareAtPrice, currency) }),
4120
- /* @__PURE__ */ jsx9("span", { className: "lb-bundle-product-price", children: formatMoney7(item.price, currency) }),
4121
- /* @__PURE__ */ jsx9("span", { className: "lb-bundle-qty-inline", children: `\xD7${item.quantity}` })
4122
- ] }),
4123
- item.unitPrice && /* @__PURE__ */ jsx9("span", { className: "lb-bundle-product-unit-price", children: item.unitPrice })
4124
- ] }),
4125
- canRemoveItem2(bundle, selections, item) ? /* @__PURE__ */ jsx9(
4126
- "button",
4127
- {
4128
- type: "button",
4129
- className: "lb-mix-match__slot-remove",
4130
- "aria-label": `Remove ${item.title}`,
4131
- onClick: (e) => {
4132
- e.stopPropagation();
4133
- removeSlot(i, index);
4134
- },
4135
- children: /* @__PURE__ */ jsx9(CloseIcon4, {})
4136
- }
4137
- ) : (
4138
- /* Required pick at its floor — quiet state chip instead
4139
- of the ×; removal returns once another slot covers
4140
- the product's minimum (variant swap flow). */
4141
- /* @__PURE__ */ jsx9("span", { className: "lb-mix-match__slot-required", children: "Required" })
4142
- )
4143
- ]
4144
- },
4145
- `${item.productId}:${item.variantId}:${index}`
4146
- )
4147
- ))
4148
- }
4149
- ),
4150
- stepHeadroom2(step.maxQuantity, unitsByStep[i] ?? 0) !== 0 && /* @__PURE__ */ jsxs9(
4095
+ ),
4096
+ /* @__PURE__ */ jsxs9("span", { className: "lb-multi-step__door-copy", children: [
4097
+ /* @__PURE__ */ jsx9("span", { className: "lb-mix-match__add-product-label", children: anyPicks ? "Continue building" : "Choose your products" }),
4098
+ /* @__PURE__ */ jsx9("span", { className: "lb-multi-step__door-sub", children: anyPicks ? `${remainingSteps} ${remainingSteps === 1 ? "step" : "steps"} to go` : `${steps.length} quick ${steps.length === 1 ? "step" : "steps"}` })
4099
+ ] })
4100
+ ]
4101
+ }
4102
+ ),
4103
+ (selections[i] ?? []).length === 0 ? /* @__PURE__ */ jsx9(
4104
+ "section",
4105
+ {
4106
+ className: "lb-multi-step__group",
4107
+ "data-step-group": i,
4108
+ "data-step-mode": "row",
4109
+ children: /* @__PURE__ */ jsxs9(
4151
4110
  "button",
4152
4111
  {
4153
4112
  type: "button",
4154
- className: "lb-mix-match__add-product lb-multi-step__step-trigger",
4155
- "data-step-trigger": i,
4113
+ className: "lb-multi-step__step-row",
4114
+ "data-step-row": i,
4156
4115
  "aria-label": `${step.minQuantity === 1 && step.maxQuantity === 1 ? "Choose a product" : "Choose products"}: ${step.name}`,
4157
4116
  onClick: () => setPickerOpenAt(i),
4158
4117
  children: [
4159
4118
  /* @__PURE__ */ jsx9(
4160
4119
  "span",
4161
4120
  {
4162
- className: "lb-mix-match__add-product-icon",
4121
+ className: "lb-multi-step__step-ix",
4163
4122
  "aria-hidden": "true",
4164
- children: /* @__PURE__ */ jsx9(PlusIcon2, {})
4123
+ children: i + 1
4165
4124
  }
4166
4125
  ),
4167
- /* @__PURE__ */ jsx9("span", { className: "lb-mix-match__add-product-label", children: step.minQuantity === 1 && step.maxQuantity === 1 ? "Choose a product" : "Choose products" })
4126
+ /* @__PURE__ */ jsx9("span", { className: "lb-multi-step__group-name", children: step.name }),
4127
+ /* @__PURE__ */ jsx9(
4128
+ "span",
4129
+ {
4130
+ className: `lb-multi-step__group-count${stepSatisfied(i) ? " lb-multi-step__group-count--met" : ""}`,
4131
+ "data-step-count": i,
4132
+ children: `${Math.min(unitsByStep[i] ?? 0, step.minQuantity)} of ${step.minQuantity} added`
4133
+ }
4134
+ )
4168
4135
  ]
4169
4136
  }
4170
4137
  )
4171
- ]
4172
- },
4173
- i
4174
- )) }),
4138
+ }
4139
+ ) : /* @__PURE__ */ jsxs9(
4140
+ "section",
4141
+ {
4142
+ className: "lb-multi-step__group",
4143
+ "data-step-group": i,
4144
+ "data-step-mode": "open",
4145
+ children: [
4146
+ /* @__PURE__ */ jsxs9("div", { className: "lb-multi-step__group-heading", children: [
4147
+ /* @__PURE__ */ jsx9("span", { className: "lb-multi-step__group-name", children: step.name }),
4148
+ /* @__PURE__ */ jsx9(
4149
+ "span",
4150
+ {
4151
+ className: `lb-multi-step__group-count${stepSatisfied(i) ? " lb-multi-step__group-count--met" : ""}`,
4152
+ "data-step-count": i,
4153
+ children: `${Math.min(unitsByStep[i] ?? 0, step.minQuantity)} of ${step.minQuantity} added`
4154
+ }
4155
+ )
4156
+ ] }),
4157
+ /* @__PURE__ */ jsx9(
4158
+ "div",
4159
+ {
4160
+ className: "lb-mix-match__slots lb-edge-fade lb-multi-step__group-slots",
4161
+ "data-step-slots": i,
4162
+ children: (selections[i] ?? []).map((item, index) => (
4163
+ /* Whole card reopens the wizard AT this step. The inner
4164
+ title button provides the keyboard/AT path (its
4165
+ activation bubbles here); × stops propagation. */
4166
+ // 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
4167
+ /* @__PURE__ */ jsxs9(
4168
+ "div",
4169
+ {
4170
+ className: "lb-mix-match__slot lb-mix-match__slot--filled",
4171
+ onClick: () => setPickerOpenAt(i),
4172
+ children: [
4173
+ item.featuredImage && /* @__PURE__ */ jsx9("div", { className: "lb-bundle-thumbnail", children: /* @__PURE__ */ jsx9(
4174
+ "img",
4175
+ {
4176
+ src: item.featuredImage,
4177
+ alt: item.title,
4178
+ loading: "lazy"
4179
+ }
4180
+ ) }),
4181
+ /* @__PURE__ */ jsxs9("div", { className: "lb-mix-match__filled-info", children: [
4182
+ /* @__PURE__ */ jsx9(
4183
+ "button",
4184
+ {
4185
+ type: "button",
4186
+ className: "lb-mix-match__filled-title",
4187
+ "aria-label": `Edit selection: ${item.title}`,
4188
+ children: item.title
4189
+ }
4190
+ ),
4191
+ item.variantTitle && item.variantTitle !== "Default Title" && /* @__PURE__ */ jsx9("span", { className: "lb-mix-match__filled-variant", children: item.variantTitle }),
4192
+ /* @__PURE__ */ jsxs9("span", { className: "lb-mix-match__filled-price", children: [
4193
+ item.compareAtPrice !== null && item.compareAtPrice > item.price && /* @__PURE__ */ jsx9("s", { className: "lb-mix-match__filled-compare", children: formatMoney7(item.compareAtPrice, currency) }),
4194
+ /* @__PURE__ */ jsx9("span", { className: "lb-bundle-product-price", children: formatMoney7(item.price, currency) }),
4195
+ /* @__PURE__ */ jsx9("span", { className: "lb-bundle-qty-inline", children: `\xD7${item.quantity}` })
4196
+ ] }),
4197
+ item.unitPrice && /* @__PURE__ */ jsx9("span", { className: "lb-bundle-product-unit-price", children: item.unitPrice })
4198
+ ] }),
4199
+ canRemoveItem2(bundle, selections, item) ? /* @__PURE__ */ jsx9(
4200
+ "button",
4201
+ {
4202
+ type: "button",
4203
+ className: "lb-mix-match__slot-remove",
4204
+ "aria-label": `Remove ${item.title}`,
4205
+ onClick: (e) => {
4206
+ e.stopPropagation();
4207
+ removeSlot(i, index);
4208
+ },
4209
+ children: /* @__PURE__ */ jsx9(CloseIcon4, {})
4210
+ }
4211
+ ) : (
4212
+ /* Required pick at its floor — quiet state chip instead
4213
+ of the ×; removal returns once another slot covers
4214
+ the product's minimum (variant swap flow). */
4215
+ /* @__PURE__ */ jsx9("span", { className: "lb-mix-match__slot-required", children: "Required" })
4216
+ )
4217
+ ]
4218
+ },
4219
+ `${item.productId}:${item.variantId}:${index}`
4220
+ )
4221
+ ))
4222
+ }
4223
+ )
4224
+ ]
4225
+ }
4226
+ )
4227
+ ] }, i)) }),
4175
4228
  /* @__PURE__ */ jsx9("div", { className: "lb-bundle-divider" }),
4176
4229
  allSatisfied && /* @__PURE__ */ jsxs9("div", { className: "lb-bundle-summary", "data-pricing-section": true, children: [
4177
4230
  /* @__PURE__ */ jsxs9("div", { className: "lb-bundle-summary__text", children: [
@@ -4350,7 +4403,7 @@ import {
4350
4403
  calculateTierSavings as calculateTierSavings2,
4351
4404
  getActiveTier as getActiveTier2,
4352
4405
  productsForStep as productsForStep3,
4353
- stepHeadroom as stepHeadroom3,
4406
+ stepHeadroom as stepHeadroom2,
4354
4407
  validateQuantity,
4355
4408
  transformImageUrl,
4356
4409
  formatCountdown,
@@ -4411,7 +4464,7 @@ export {
4411
4464
  reportAddToCart2 as reportAddToCart,
4412
4465
  reportImpression2 as reportImpression,
4413
4466
  sanitizeCustomCss,
4414
- stepHeadroom3 as stepHeadroom,
4467
+ stepHeadroom2 as stepHeadroom,
4415
4468
  thumbnailRatioVars,
4416
4469
  transformImageUrl,
4417
4470
  useAnalytics,