@lime-bundles/react 2.3.1 → 2.4.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 +680 -237
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +50 -2
- package/dist/index.d.ts +50 -2
- package/dist/index.js +635 -187
- package/dist/index.js.map +1 -1
- package/docs/css-variables.md +3 -0
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -20,56 +20,58 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
-
BUNDLES_FOR_PRODUCT_QUERY: () =>
|
|
24
|
-
BUNDLE_METAOBJECT_QUERY: () =>
|
|
25
|
-
BundleParseError: () =>
|
|
23
|
+
BUNDLES_FOR_PRODUCT_QUERY: () => import_core13.BUNDLES_FOR_PRODUCT_QUERY,
|
|
24
|
+
BUNDLE_METAOBJECT_QUERY: () => import_core13.BUNDLE_METAOBJECT_QUERY,
|
|
25
|
+
BundleParseError: () => import_core12.BundleParseError,
|
|
26
26
|
FixedBundle: () => FixedBundle,
|
|
27
27
|
MixMatchBundle: () => MixMatchBundle,
|
|
28
|
-
SHOP_CUSTOM_CSS_QUERY: () =>
|
|
29
|
-
StorefrontApiError: () =>
|
|
28
|
+
SHOP_CUSTOM_CSS_QUERY: () => import_core13.SHOP_CUSTOM_CSS_QUERY,
|
|
29
|
+
StorefrontApiError: () => import_core12.StorefrontApiError,
|
|
30
|
+
VariantDropdown: () => VariantDropdown,
|
|
30
31
|
VolumeBundle: () => VolumeBundle,
|
|
31
|
-
WIDGET_CONFIG_DEFAULTS: () =>
|
|
32
|
-
applyABVariantB: () =>
|
|
33
|
-
applyWidgetConfigVars: () =>
|
|
34
|
-
calculateDiscount: () =>
|
|
35
|
-
calculateTierSavings: () =>
|
|
36
|
-
computeBundleSaleCents: () =>
|
|
37
|
-
computeFixedPricing: () =>
|
|
38
|
-
createStorefrontClient: () =>
|
|
32
|
+
WIDGET_CONFIG_DEFAULTS: () => import_core13.WIDGET_CONFIG_DEFAULTS,
|
|
33
|
+
applyABVariantB: () => import_core13.applyABVariantB,
|
|
34
|
+
applyWidgetConfigVars: () => import_core13.applyWidgetConfigVars,
|
|
35
|
+
calculateDiscount: () => import_core13.calculateDiscount,
|
|
36
|
+
calculateTierSavings: () => import_core13.calculateTierSavings,
|
|
37
|
+
computeBundleSaleCents: () => import_core13.computeBundleSaleCents,
|
|
38
|
+
computeFixedPricing: () => import_core13.computeFixedPricing,
|
|
39
|
+
createStorefrontClient: () => import_core13.createStorefrontClient,
|
|
39
40
|
fetchBundleData: () => fetchBundleData,
|
|
40
|
-
fetchBundlesForProduct: () =>
|
|
41
|
+
fetchBundlesForProduct: () => import_core13.fetchBundlesForProduct,
|
|
41
42
|
fetchShopCustomCss: () => fetchShopCustomCss,
|
|
42
|
-
formatCents: () =>
|
|
43
|
-
formatCountdown: () =>
|
|
44
|
-
formatMoney: () =>
|
|
45
|
-
formatUnitPrice: () =>
|
|
46
|
-
getABTestAssignment: () =>
|
|
47
|
-
getActiveTier: () =>
|
|
48
|
-
hasConsent: () =>
|
|
49
|
-
injectCustomCss: () =>
|
|
50
|
-
mergeWidgetConfig: () =>
|
|
51
|
-
observeImpression: () =>
|
|
52
|
-
parseCents: () =>
|
|
53
|
-
parseMetaobjectBundle: () =>
|
|
54
|
-
parseMetaobjectBundleStrict: () =>
|
|
55
|
-
percentageDiscountUnit: () =>
|
|
56
|
-
reportAddToCart: () =>
|
|
57
|
-
reportImpression: () =>
|
|
58
|
-
sanitizeCustomCss: () =>
|
|
59
|
-
setConsent: () =>
|
|
60
|
-
thumbnailRatioVars: () =>
|
|
61
|
-
transformImageUrl: () =>
|
|
43
|
+
formatCents: () => import_core13.formatCents,
|
|
44
|
+
formatCountdown: () => import_core13.formatCountdown,
|
|
45
|
+
formatMoney: () => import_core13.formatMoney,
|
|
46
|
+
formatUnitPrice: () => import_core13.formatUnitPrice,
|
|
47
|
+
getABTestAssignment: () => import_core13.getABTestAssignment,
|
|
48
|
+
getActiveTier: () => import_core13.getActiveTier,
|
|
49
|
+
hasConsent: () => import_core13.hasConsent,
|
|
50
|
+
injectCustomCss: () => import_core13.injectCustomCss,
|
|
51
|
+
mergeWidgetConfig: () => import_core13.mergeWidgetConfig,
|
|
52
|
+
observeImpression: () => import_core13.observeImpression,
|
|
53
|
+
parseCents: () => import_core13.parseCents,
|
|
54
|
+
parseMetaobjectBundle: () => import_core13.parseMetaobjectBundle,
|
|
55
|
+
parseMetaobjectBundleStrict: () => import_core13.parseMetaobjectBundleStrict,
|
|
56
|
+
percentageDiscountUnit: () => import_core13.percentageDiscountUnit,
|
|
57
|
+
reportAddToCart: () => import_core13.reportAddToCart,
|
|
58
|
+
reportImpression: () => import_core13.reportImpression,
|
|
59
|
+
sanitizeCustomCss: () => import_core13.sanitizeCustomCss,
|
|
60
|
+
setConsent: () => import_core13.setConsent,
|
|
61
|
+
thumbnailRatioVars: () => import_core13.thumbnailRatioVars,
|
|
62
|
+
transformImageUrl: () => import_core13.transformImageUrl,
|
|
62
63
|
useAnalytics: () => useAnalytics,
|
|
63
64
|
useBundleData: () => useBundleData,
|
|
64
65
|
useBundlesForProduct: () => useBundlesForProduct,
|
|
66
|
+
useVariantSelection: () => useVariantSelection,
|
|
65
67
|
useWidgetConfigVars: () => useWidgetConfigVars,
|
|
66
|
-
validateQuantity: () =>
|
|
68
|
+
validateQuantity: () => import_core13.validateQuantity
|
|
67
69
|
});
|
|
68
70
|
module.exports = __toCommonJS(index_exports);
|
|
69
71
|
|
|
70
72
|
// src/components/FixedBundle.tsx
|
|
71
|
-
var
|
|
72
|
-
var
|
|
73
|
+
var import_react6 = require("react");
|
|
74
|
+
var import_core8 = require("@lime-bundles/core");
|
|
73
75
|
|
|
74
76
|
// src/hooks/useBundleData.ts
|
|
75
77
|
var import_react = require("react");
|
|
@@ -260,8 +262,333 @@ function useWidgetConfigVars(config) {
|
|
|
260
262
|
);
|
|
261
263
|
}
|
|
262
264
|
|
|
263
|
-
// src/
|
|
265
|
+
// src/hooks/useVariantSelection.ts
|
|
266
|
+
var import_react4 = require("react");
|
|
267
|
+
var import_core6 = require("@lime-bundles/core");
|
|
268
|
+
var { findVariantByOptions, isOptionValueAvailable, toPickerVariant } = import_core6.variants;
|
|
269
|
+
function defaultInitial(variants) {
|
|
270
|
+
return variants.find((v) => v.availableForSale) ?? variants[0] ?? null;
|
|
271
|
+
}
|
|
272
|
+
function useVariantSelection({
|
|
273
|
+
variants,
|
|
274
|
+
optionNames,
|
|
275
|
+
initialVariant,
|
|
276
|
+
optionValuesByPosition
|
|
277
|
+
}) {
|
|
278
|
+
const seed = (0, import_react4.useMemo)(
|
|
279
|
+
() => initialVariant ?? defaultInitial(variants),
|
|
280
|
+
[initialVariant, variants]
|
|
281
|
+
);
|
|
282
|
+
const [selectedValues, setSelectedValues] = (0, import_react4.useState)(
|
|
283
|
+
() => seed ? seed.selectedOptions.map((o) => o.value) : optionNames.map(() => "")
|
|
284
|
+
);
|
|
285
|
+
(0, import_react4.useEffect)(() => {
|
|
286
|
+
if (!seed) return;
|
|
287
|
+
setSelectedValues(seed.selectedOptions.map((o) => o.value));
|
|
288
|
+
}, [seed?.id]);
|
|
289
|
+
const pickerVariants = (0, import_react4.useMemo)(
|
|
290
|
+
() => variants.map((v) => toPickerVariant(v)),
|
|
291
|
+
[variants]
|
|
292
|
+
);
|
|
293
|
+
const selectedVariant = (0, import_react4.useMemo)(() => {
|
|
294
|
+
if (selectedValues.length !== optionNames.length) return null;
|
|
295
|
+
const match = findVariantByOptions(pickerVariants, selectedValues);
|
|
296
|
+
if (!match) return null;
|
|
297
|
+
return variants.find((v) => v.id === match.id) ?? null;
|
|
298
|
+
}, [pickerVariants, selectedValues, variants, optionNames.length]);
|
|
299
|
+
const setOptionValue = (0, import_react4.useCallback)(
|
|
300
|
+
(optionIndex, value) => {
|
|
301
|
+
setSelectedValues((prev) => {
|
|
302
|
+
const next = prev.slice();
|
|
303
|
+
next[optionIndex] = value;
|
|
304
|
+
return next;
|
|
305
|
+
});
|
|
306
|
+
},
|
|
307
|
+
[]
|
|
308
|
+
);
|
|
309
|
+
const optionsByPosition = (0, import_react4.useMemo)(() => {
|
|
310
|
+
if (optionValuesByPosition) {
|
|
311
|
+
return optionValuesByPosition.map((values) => values.slice());
|
|
312
|
+
}
|
|
313
|
+
const out = optionNames.map(() => []);
|
|
314
|
+
for (const v of variants) {
|
|
315
|
+
v.selectedOptions.forEach((o, i) => {
|
|
316
|
+
if (i < out.length && !out[i].includes(o.value)) out[i].push(o.value);
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
return out;
|
|
320
|
+
}, [variants, optionNames, optionValuesByPosition]);
|
|
321
|
+
const optionsFor = (0, import_react4.useCallback)(
|
|
322
|
+
(optionIndex) => {
|
|
323
|
+
const values = optionsByPosition[optionIndex] ?? [];
|
|
324
|
+
return values.map((value) => ({
|
|
325
|
+
value,
|
|
326
|
+
disabled: !isOptionValueAvailable(
|
|
327
|
+
pickerVariants,
|
|
328
|
+
optionIndex,
|
|
329
|
+
value,
|
|
330
|
+
selectedValues
|
|
331
|
+
)
|
|
332
|
+
}));
|
|
333
|
+
},
|
|
334
|
+
[optionsByPosition, pickerVariants, selectedValues]
|
|
335
|
+
);
|
|
336
|
+
return {
|
|
337
|
+
selectedValues,
|
|
338
|
+
selectedVariant,
|
|
339
|
+
setOptionValue,
|
|
340
|
+
optionsFor
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// src/components/VariantDropdown.tsx
|
|
345
|
+
var import_react5 = require("react");
|
|
346
|
+
var import_core7 = require("@lime-bundles/core");
|
|
264
347
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
348
|
+
var { computePosition, emptyTypeAheadState, handleKey, pushTypeAheadChar } = import_core7.dropdown;
|
|
349
|
+
var ITEM_HEIGHT_PX = 32;
|
|
350
|
+
var LIST_PAD_Y = 8;
|
|
351
|
+
var MAX_VISIBLE_ITEMS = 8;
|
|
352
|
+
function VariantDropdown({
|
|
353
|
+
options,
|
|
354
|
+
value,
|
|
355
|
+
onChange,
|
|
356
|
+
ariaLabel,
|
|
357
|
+
className
|
|
358
|
+
}) {
|
|
359
|
+
const idBase = (0, import_react5.useId)();
|
|
360
|
+
const triggerRef = (0, import_react5.useRef)(null);
|
|
361
|
+
const listboxRef = (0, import_react5.useRef)(null);
|
|
362
|
+
const typeAheadRef = (0, import_react5.useRef)(emptyTypeAheadState());
|
|
363
|
+
const [isOpen, setIsOpen] = (0, import_react5.useState)(false);
|
|
364
|
+
const [activeIndex, setActiveIndex] = (0, import_react5.useState)(-1);
|
|
365
|
+
const [position, setPosition] = (0, import_react5.useState)(null);
|
|
366
|
+
const selectedIndex = (0, import_react5.useMemo)(
|
|
367
|
+
() => options.findIndex((o) => o.value === value),
|
|
368
|
+
[options, value]
|
|
369
|
+
);
|
|
370
|
+
const optionsState = (0, import_react5.useMemo)(
|
|
371
|
+
() => options.map((o) => ({ disabled: !!o.disabled, label: o.label })),
|
|
372
|
+
[options]
|
|
373
|
+
);
|
|
374
|
+
const selectedLabel = selectedIndex >= 0 ? options[selectedIndex].label : "";
|
|
375
|
+
function open() {
|
|
376
|
+
if (isOpen) return;
|
|
377
|
+
setIsOpen(true);
|
|
378
|
+
setActiveIndex(
|
|
379
|
+
selectedIndex >= 0 && !optionsState[selectedIndex]?.disabled ? selectedIndex : optionsState.findIndex((o) => !o.disabled)
|
|
380
|
+
);
|
|
381
|
+
}
|
|
382
|
+
function close(restoreFocus) {
|
|
383
|
+
setIsOpen(false);
|
|
384
|
+
setActiveIndex(-1);
|
|
385
|
+
if (restoreFocus) triggerRef.current?.focus();
|
|
386
|
+
}
|
|
387
|
+
function commit(index) {
|
|
388
|
+
const opt = options[index];
|
|
389
|
+
if (!opt || opt.disabled) return;
|
|
390
|
+
if (opt.value !== value) onChange(opt.value);
|
|
391
|
+
close(true);
|
|
392
|
+
}
|
|
393
|
+
(0, import_react5.useLayoutEffect)(() => {
|
|
394
|
+
if (!isOpen) return;
|
|
395
|
+
const trigger = triggerRef.current;
|
|
396
|
+
if (!trigger) return;
|
|
397
|
+
const rect = trigger.getBoundingClientRect();
|
|
398
|
+
if (rect.width === 0) return;
|
|
399
|
+
const visibleCount = Math.min(options.length || 1, MAX_VISIBLE_ITEMS);
|
|
400
|
+
const desiredHeight = visibleCount * ITEM_HEIGHT_PX + LIST_PAD_Y;
|
|
401
|
+
setPosition(
|
|
402
|
+
computePosition({
|
|
403
|
+
trigger: {
|
|
404
|
+
top: rect.top,
|
|
405
|
+
bottom: rect.bottom,
|
|
406
|
+
left: rect.left,
|
|
407
|
+
width: rect.width
|
|
408
|
+
},
|
|
409
|
+
viewportHeight: window.innerHeight,
|
|
410
|
+
desiredHeight
|
|
411
|
+
})
|
|
412
|
+
);
|
|
413
|
+
}, [isOpen, options.length]);
|
|
414
|
+
(0, import_react5.useEffect)(() => {
|
|
415
|
+
if (!isOpen) return;
|
|
416
|
+
const isInsideDropdown = (event) => {
|
|
417
|
+
const path = event.composedPath();
|
|
418
|
+
const trigger = triggerRef.current;
|
|
419
|
+
const listbox = listboxRef.current;
|
|
420
|
+
return trigger != null && path.includes(trigger) || listbox != null && path.includes(listbox);
|
|
421
|
+
};
|
|
422
|
+
const onPointerdown = (event) => {
|
|
423
|
+
if (isInsideDropdown(event)) return;
|
|
424
|
+
close(false);
|
|
425
|
+
};
|
|
426
|
+
const onScroll = (event) => {
|
|
427
|
+
if (isInsideDropdown(event)) return;
|
|
428
|
+
close(false);
|
|
429
|
+
};
|
|
430
|
+
const onResize = () => close(false);
|
|
431
|
+
document.addEventListener("pointerdown", onPointerdown, true);
|
|
432
|
+
window.addEventListener("scroll", onScroll, true);
|
|
433
|
+
window.addEventListener("resize", onResize);
|
|
434
|
+
return () => {
|
|
435
|
+
document.removeEventListener("pointerdown", onPointerdown, true);
|
|
436
|
+
window.removeEventListener("scroll", onScroll, true);
|
|
437
|
+
window.removeEventListener("resize", onResize);
|
|
438
|
+
};
|
|
439
|
+
}, [isOpen]);
|
|
440
|
+
(0, import_react5.useEffect)(() => {
|
|
441
|
+
if (!isOpen || activeIndex < 0) return;
|
|
442
|
+
const listbox = listboxRef.current;
|
|
443
|
+
if (!listbox) return;
|
|
444
|
+
const li = listbox.querySelector(
|
|
445
|
+
`#${CSS.escape(`${idBase}-opt-${activeIndex}`)}`
|
|
446
|
+
);
|
|
447
|
+
if (!li) return;
|
|
448
|
+
const liTop = li.offsetTop;
|
|
449
|
+
const liBottom = liTop + li.offsetHeight;
|
|
450
|
+
const visTop = listbox.scrollTop;
|
|
451
|
+
const visBottom = visTop + listbox.clientHeight;
|
|
452
|
+
if (liTop < visTop) {
|
|
453
|
+
listbox.scrollTop = liTop;
|
|
454
|
+
} else if (liBottom > visBottom) {
|
|
455
|
+
listbox.scrollTop = liBottom - listbox.clientHeight;
|
|
456
|
+
}
|
|
457
|
+
}, [activeIndex, isOpen, idBase]);
|
|
458
|
+
function onKeyDown(event) {
|
|
459
|
+
const action = handleKey(
|
|
460
|
+
{
|
|
461
|
+
key: event.key,
|
|
462
|
+
ctrlKey: event.ctrlKey,
|
|
463
|
+
metaKey: event.metaKey,
|
|
464
|
+
altKey: event.altKey,
|
|
465
|
+
shiftKey: event.shiftKey
|
|
466
|
+
},
|
|
467
|
+
{ isOpen, activeIndex, selectedIndex, options: optionsState }
|
|
468
|
+
);
|
|
469
|
+
if (action.preventDefault) event.preventDefault();
|
|
470
|
+
switch (action.type) {
|
|
471
|
+
case "open":
|
|
472
|
+
open();
|
|
473
|
+
if (action.activeIndex >= 0) setActiveIndex(action.activeIndex);
|
|
474
|
+
return;
|
|
475
|
+
case "close":
|
|
476
|
+
close(action.restoreFocus);
|
|
477
|
+
return;
|
|
478
|
+
case "move-active":
|
|
479
|
+
setActiveIndex(action.activeIndex);
|
|
480
|
+
return;
|
|
481
|
+
case "commit":
|
|
482
|
+
commit(action.index);
|
|
483
|
+
return;
|
|
484
|
+
case "type-ahead": {
|
|
485
|
+
const result = pushTypeAheadChar(
|
|
486
|
+
typeAheadRef.current,
|
|
487
|
+
action.char,
|
|
488
|
+
Date.now(),
|
|
489
|
+
optionsState
|
|
490
|
+
);
|
|
491
|
+
typeAheadRef.current = result.newState;
|
|
492
|
+
if (result.matchedIndex !== null) {
|
|
493
|
+
if (!isOpen) open();
|
|
494
|
+
setActiveIndex(result.matchedIndex);
|
|
495
|
+
}
|
|
496
|
+
return;
|
|
497
|
+
}
|
|
498
|
+
case "passthrough":
|
|
499
|
+
return;
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
function onShellBlur(event) {
|
|
503
|
+
const next = event.relatedTarget;
|
|
504
|
+
if (next && event.currentTarget.contains(next)) return;
|
|
505
|
+
setTimeout(() => {
|
|
506
|
+
if (!isOpen) return;
|
|
507
|
+
const active = document.activeElement;
|
|
508
|
+
if (!triggerRef.current?.contains(active) && !listboxRef.current?.contains(active)) {
|
|
509
|
+
close(false);
|
|
510
|
+
}
|
|
511
|
+
}, 0);
|
|
512
|
+
}
|
|
513
|
+
const listboxId = `${idBase}-listbox`;
|
|
514
|
+
const activeDescendantId = activeIndex >= 0 ? `${idBase}-opt-${activeIndex}` : void 0;
|
|
515
|
+
const panelStyle = position ? { maxHeight: position.maxHeight } : void 0;
|
|
516
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
517
|
+
"div",
|
|
518
|
+
{
|
|
519
|
+
className: `lb-dropdown${className ? ` ${className}` : ""}`,
|
|
520
|
+
"data-lb-dropdown": "",
|
|
521
|
+
onBlur: onShellBlur,
|
|
522
|
+
children: [
|
|
523
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
524
|
+
"button",
|
|
525
|
+
{
|
|
526
|
+
ref: triggerRef,
|
|
527
|
+
type: "button",
|
|
528
|
+
className: "lb-dropdown-trigger",
|
|
529
|
+
role: "combobox",
|
|
530
|
+
"aria-haspopup": "listbox",
|
|
531
|
+
"aria-expanded": isOpen,
|
|
532
|
+
"aria-controls": listboxId,
|
|
533
|
+
"aria-label": ariaLabel,
|
|
534
|
+
"aria-activedescendant": activeDescendantId,
|
|
535
|
+
onClick: (e) => {
|
|
536
|
+
e.preventDefault();
|
|
537
|
+
if (isOpen) close(false);
|
|
538
|
+
else open();
|
|
539
|
+
},
|
|
540
|
+
onKeyDown,
|
|
541
|
+
children: [
|
|
542
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "lb-dropdown-trigger-value", children: selectedLabel }),
|
|
543
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "lb-dropdown-chevron", "aria-hidden": "true" })
|
|
544
|
+
]
|
|
545
|
+
}
|
|
546
|
+
),
|
|
547
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
548
|
+
"ul",
|
|
549
|
+
{
|
|
550
|
+
ref: listboxRef,
|
|
551
|
+
id: listboxId,
|
|
552
|
+
className: "lb-dropdown-listbox",
|
|
553
|
+
role: "listbox",
|
|
554
|
+
"aria-label": ariaLabel,
|
|
555
|
+
hidden: !isOpen,
|
|
556
|
+
"data-placement": position?.placement,
|
|
557
|
+
style: panelStyle,
|
|
558
|
+
onMouseDown: (e) => e.preventDefault(),
|
|
559
|
+
children: options.map((opt, i) => (
|
|
560
|
+
// Keyboard activation lives on the trigger combobox via
|
|
561
|
+
// aria-activedescendant — the WAI-ARIA combobox pattern keeps
|
|
562
|
+
// focus on the button and tracks the active option by id, so
|
|
563
|
+
// the option <li> elements deliberately have no key handlers.
|
|
564
|
+
// eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-noninteractive-element-interactions
|
|
565
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
566
|
+
"li",
|
|
567
|
+
{
|
|
568
|
+
id: `${idBase}-opt-${i}`,
|
|
569
|
+
className: `lb-dropdown-option${i === activeIndex ? " is-active" : ""}`,
|
|
570
|
+
role: "option",
|
|
571
|
+
"aria-selected": i === selectedIndex,
|
|
572
|
+
"aria-disabled": opt.disabled || void 0,
|
|
573
|
+
"data-value": opt.value,
|
|
574
|
+
onClick: () => commit(i),
|
|
575
|
+
onMouseMove: () => {
|
|
576
|
+
if (!opt.disabled && i !== activeIndex) setActiveIndex(i);
|
|
577
|
+
},
|
|
578
|
+
children: opt.label
|
|
579
|
+
},
|
|
580
|
+
opt.value
|
|
581
|
+
)
|
|
582
|
+
))
|
|
583
|
+
}
|
|
584
|
+
)
|
|
585
|
+
]
|
|
586
|
+
}
|
|
587
|
+
);
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
// src/components/FixedBundle.tsx
|
|
591
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
265
592
|
function FixedBundle(props) {
|
|
266
593
|
const {
|
|
267
594
|
shopDomain,
|
|
@@ -285,11 +612,21 @@ function FixedBundle(props) {
|
|
|
285
612
|
bundleType: "fixed",
|
|
286
613
|
enabled: analyticsEnabled !== false
|
|
287
614
|
});
|
|
288
|
-
const [addingToCart, setAddingToCart] = (0,
|
|
289
|
-
const [cartError, setCartError] = (0,
|
|
615
|
+
const [addingToCart, setAddingToCart] = (0, import_react6.useState)(false);
|
|
616
|
+
const [cartError, setCartError] = (0, import_react6.useState)(null);
|
|
617
|
+
const [selectedVariants, setSelectedVariants] = (0, import_react6.useState)({});
|
|
618
|
+
const handleVariantChange = (0, import_react6.useCallback)(
|
|
619
|
+
(productId, variant) => {
|
|
620
|
+
setSelectedVariants((prev) => {
|
|
621
|
+
if (prev[productId] === variant) return prev;
|
|
622
|
+
return { ...prev, [productId]: variant };
|
|
623
|
+
});
|
|
624
|
+
},
|
|
625
|
+
[]
|
|
626
|
+
);
|
|
290
627
|
const bundle = result.status === "success" && result.bundle.bundleType === "fixed" ? result.bundle : null;
|
|
291
628
|
const setConfigVarsRef = useWidgetConfigVars(bundle?.widgetConfig);
|
|
292
|
-
(0,
|
|
629
|
+
(0, import_react6.useEffect)(() => {
|
|
293
630
|
if (result.status === "error") {
|
|
294
631
|
onError?.(result.error);
|
|
295
632
|
return;
|
|
@@ -302,14 +639,14 @@ function FixedBundle(props) {
|
|
|
302
639
|
);
|
|
303
640
|
}
|
|
304
641
|
}, [result, onError]);
|
|
305
|
-
const handleAddToCart = (0,
|
|
642
|
+
const handleAddToCart = (0, import_react6.useCallback)(async () => {
|
|
306
643
|
if (!bundle) return;
|
|
307
644
|
const bundleLines = bundle.products.filter((p) => p.variants.nodes.some((v) => v.availableForSale)).map((p) => {
|
|
308
|
-
const variant = p.variants.nodes.find((v) => v.availableForSale);
|
|
645
|
+
const variant = selectedVariants[p.id] ?? p.variants.nodes.find((v) => v.availableForSale);
|
|
309
646
|
return {
|
|
310
647
|
productId: p.id,
|
|
311
648
|
variant,
|
|
312
|
-
quantity: (0,
|
|
649
|
+
quantity: (0, import_core8.resolveBundleQty)(bundle, p.id, variant.id)
|
|
313
650
|
};
|
|
314
651
|
}).filter((line) => line.quantity > 0);
|
|
315
652
|
if (bundleLines.length === 0) return;
|
|
@@ -327,7 +664,7 @@ function FixedBundle(props) {
|
|
|
327
664
|
await onAddToCart(lines);
|
|
328
665
|
const totalPrice = bundleLines.reduce((sum, line) => {
|
|
329
666
|
const price = parseFloat(line.variant.price.amount);
|
|
330
|
-
const discounted = (0,
|
|
667
|
+
const discounted = (0, import_core8.calculateDiscount)(
|
|
331
668
|
price,
|
|
332
669
|
bundle.discountConfig.discountType,
|
|
333
670
|
bundle.discountConfig.discountValue
|
|
@@ -349,17 +686,17 @@ function FixedBundle(props) {
|
|
|
349
686
|
} finally {
|
|
350
687
|
setAddingToCart(false);
|
|
351
688
|
}
|
|
352
|
-
}, [bundle, onAddToCart, onError, trackAddToCart]);
|
|
689
|
+
}, [bundle, onAddToCart, onError, trackAddToCart, selectedVariants]);
|
|
353
690
|
if (result.status === "loading") {
|
|
354
|
-
return /* @__PURE__ */ (0,
|
|
355
|
-
/* @__PURE__ */ (0,
|
|
356
|
-
/* @__PURE__ */ (0,
|
|
691
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: `lb-bundle lb-bundle--loading ${className ?? ""}`, children: [
|
|
692
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "lb-skeleton lb-skeleton--title" }),
|
|
693
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "lb-skeleton lb-skeleton--products" })
|
|
357
694
|
] });
|
|
358
695
|
}
|
|
359
696
|
if (result.status === "error") return null;
|
|
360
697
|
if (!bundle) return null;
|
|
361
698
|
const currency = bundle.products[0]?.priceRange.minVariantPrice.currencyCode ?? "USD";
|
|
362
|
-
return /* @__PURE__ */ (0,
|
|
699
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
363
700
|
"div",
|
|
364
701
|
{
|
|
365
702
|
ref: (el) => {
|
|
@@ -370,38 +707,19 @@ function FixedBundle(props) {
|
|
|
370
707
|
role: "region",
|
|
371
708
|
"aria-label": bundle.title,
|
|
372
709
|
children: [
|
|
373
|
-
/* @__PURE__ */ (0,
|
|
374
|
-
bundle.discountLabel && /* @__PURE__ */ (0,
|
|
375
|
-
/* @__PURE__ */ (0,
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
product
|
|
379
|
-
currency
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "lb-bundle__product", part: "product", children: [
|
|
387
|
-
product.featuredImage && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
388
|
-
"img",
|
|
389
|
-
{
|
|
390
|
-
src: product.featuredImage.url,
|
|
391
|
-
alt: product.featuredImage.altText ?? product.title,
|
|
392
|
-
className: "lb-bundle__product-image",
|
|
393
|
-
loading: "lazy"
|
|
394
|
-
}
|
|
395
|
-
),
|
|
396
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "lb-bundle__product-info", children: [
|
|
397
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "lb-bundle__product-title", children: product.title }),
|
|
398
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "lb-bundle__product-price", children: priceText }),
|
|
399
|
-
unitPriceText && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "lb-bundle__product-unit-price", children: unitPriceText })
|
|
400
|
-
] })
|
|
401
|
-
] }, product.id);
|
|
402
|
-
}) }),
|
|
403
|
-
cartError && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "lb-bundle__error", role: "alert", children: cartError }),
|
|
404
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
710
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h3", { className: "lb-bundle__title", children: bundle.title }),
|
|
711
|
+
bundle.discountLabel && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "lb-bundle__discount-badge", children: bundle.discountLabel }),
|
|
712
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "lb-bundle__products", children: bundle.products.map((product) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
713
|
+
FixedProductRow,
|
|
714
|
+
{
|
|
715
|
+
product,
|
|
716
|
+
currency,
|
|
717
|
+
onVariantChange: handleVariantChange
|
|
718
|
+
},
|
|
719
|
+
product.id
|
|
720
|
+
)) }),
|
|
721
|
+
cartError && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "lb-bundle__error", role: "alert", children: cartError }),
|
|
722
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
405
723
|
"button",
|
|
406
724
|
{
|
|
407
725
|
className: "lb-bundle__cta",
|
|
@@ -415,11 +733,67 @@ function FixedBundle(props) {
|
|
|
415
733
|
}
|
|
416
734
|
);
|
|
417
735
|
}
|
|
736
|
+
function FixedProductRow({ product, currency, onVariantChange }) {
|
|
737
|
+
const variants = product.variants.nodes;
|
|
738
|
+
const optionNames = (0, import_react6.useMemo)(() => {
|
|
739
|
+
const first = variants[0];
|
|
740
|
+
return first ? first.selectedOptions.map((o) => o.name) : [];
|
|
741
|
+
}, [variants]);
|
|
742
|
+
const showPicker = variants.length > 1 && optionNames.length > 0;
|
|
743
|
+
const { selectedValues, selectedVariant, setOptionValue, optionsFor } = useVariantSelection({
|
|
744
|
+
variants,
|
|
745
|
+
optionNames
|
|
746
|
+
});
|
|
747
|
+
(0, import_react6.useEffect)(() => {
|
|
748
|
+
onVariantChange(product.id, selectedVariant ?? null);
|
|
749
|
+
}, [selectedVariant, product.id, onVariantChange]);
|
|
750
|
+
const displayVariant = selectedVariant ?? variants.find((v) => v.availableForSale) ?? variants[0];
|
|
751
|
+
const priceText = displayVariant ? (0, import_core8.formatMoney)(displayVariant.price.amount, currency) : (0, import_core8.formatMoney)(product.priceRange.minVariantPrice.amount, currency);
|
|
752
|
+
const unitPriceText = displayVariant ? (0, import_core8.formatUnitPrice)(
|
|
753
|
+
displayVariant.unitPrice,
|
|
754
|
+
displayVariant.unitPriceMeasurement,
|
|
755
|
+
currency
|
|
756
|
+
) : null;
|
|
757
|
+
const thumbImage = displayVariant?.image ?? product.featuredImage;
|
|
758
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "lb-bundle__product", part: "product", children: [
|
|
759
|
+
thumbImage && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
760
|
+
"img",
|
|
761
|
+
{
|
|
762
|
+
src: thumbImage.url,
|
|
763
|
+
alt: thumbImage.altText ?? product.title,
|
|
764
|
+
className: "lb-bundle__product-image",
|
|
765
|
+
loading: "lazy"
|
|
766
|
+
}
|
|
767
|
+
),
|
|
768
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "lb-bundle__product-info", children: [
|
|
769
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "lb-bundle__product-title", children: product.title }),
|
|
770
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "lb-bundle__product-price", children: priceText }),
|
|
771
|
+
unitPriceText && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "lb-bundle__product-unit-price", children: unitPriceText }),
|
|
772
|
+
showPicker && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "lb-bundle__product-variant-pickers", children: optionNames.map((optionName, optionIndex) => {
|
|
773
|
+
const dropdownOptions = optionsFor(optionIndex).map((o) => ({
|
|
774
|
+
value: o.value,
|
|
775
|
+
label: o.value,
|
|
776
|
+
disabled: o.disabled
|
|
777
|
+
}));
|
|
778
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
779
|
+
VariantDropdown,
|
|
780
|
+
{
|
|
781
|
+
options: dropdownOptions,
|
|
782
|
+
value: selectedValues[optionIndex] ?? null,
|
|
783
|
+
onChange: (v) => setOptionValue(optionIndex, v),
|
|
784
|
+
ariaLabel: optionName
|
|
785
|
+
},
|
|
786
|
+
optionName
|
|
787
|
+
);
|
|
788
|
+
}) })
|
|
789
|
+
] })
|
|
790
|
+
] });
|
|
791
|
+
}
|
|
418
792
|
|
|
419
793
|
// src/components/MixMatchBundle.tsx
|
|
420
|
-
var
|
|
421
|
-
var
|
|
422
|
-
var
|
|
794
|
+
var import_react7 = require("react");
|
|
795
|
+
var import_core9 = require("@lime-bundles/core");
|
|
796
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
423
797
|
function MixMatchBundle(props) {
|
|
424
798
|
const {
|
|
425
799
|
shopDomain,
|
|
@@ -443,14 +817,14 @@ function MixMatchBundle(props) {
|
|
|
443
817
|
bundleType: "mix_match",
|
|
444
818
|
enabled: analyticsEnabled !== false
|
|
445
819
|
});
|
|
446
|
-
const [selections, setSelections] = (0,
|
|
820
|
+
const [selections, setSelections] = (0, import_react7.useState)(
|
|
447
821
|
/* @__PURE__ */ new Map()
|
|
448
822
|
);
|
|
449
|
-
const [addingToCart, setAddingToCart] = (0,
|
|
450
|
-
const [cartError, setCartError] = (0,
|
|
823
|
+
const [addingToCart, setAddingToCart] = (0, import_react7.useState)(false);
|
|
824
|
+
const [cartError, setCartError] = (0, import_react7.useState)(null);
|
|
451
825
|
const bundle = result.status === "success" && result.bundle.bundleType === "mix_match" ? result.bundle : null;
|
|
452
826
|
const setConfigVarsRef = useWidgetConfigVars(bundle?.widgetConfig);
|
|
453
|
-
(0,
|
|
827
|
+
(0, import_react7.useEffect)(() => {
|
|
454
828
|
if (result.status === "error") {
|
|
455
829
|
onError?.(result.error);
|
|
456
830
|
return;
|
|
@@ -467,8 +841,8 @@ function MixMatchBundle(props) {
|
|
|
467
841
|
(sum, s) => sum + s.quantity,
|
|
468
842
|
0
|
|
469
843
|
);
|
|
470
|
-
const validation = bundle ? (0,
|
|
471
|
-
const toggleProduct = (0,
|
|
844
|
+
const validation = bundle ? (0, import_core9.validateQuantity)(totalQuantity, bundle.minQuantity, bundle.maxQuantity) : { valid: false, totalQuantity: 0, message: null };
|
|
845
|
+
const toggleProduct = (0, import_react7.useCallback)(
|
|
472
846
|
(productId, variant) => {
|
|
473
847
|
setSelections((prev) => {
|
|
474
848
|
const next = new Map(prev);
|
|
@@ -476,7 +850,7 @@ function MixMatchBundle(props) {
|
|
|
476
850
|
if (next.has(key)) {
|
|
477
851
|
next.delete(key);
|
|
478
852
|
} else {
|
|
479
|
-
const configuredQty = bundle ? (0,
|
|
853
|
+
const configuredQty = bundle ? (0, import_core9.resolveBundleQty)(bundle, productId, variant.id) : 1;
|
|
480
854
|
next.set(key, {
|
|
481
855
|
productId,
|
|
482
856
|
variantId: variant.id,
|
|
@@ -488,7 +862,7 @@ function MixMatchBundle(props) {
|
|
|
488
862
|
},
|
|
489
863
|
[bundle]
|
|
490
864
|
);
|
|
491
|
-
const updateQuantity = (0,
|
|
865
|
+
const updateQuantity = (0, import_react7.useCallback)(
|
|
492
866
|
(productId, variantId, quantity) => {
|
|
493
867
|
setSelections((prev) => {
|
|
494
868
|
const next = new Map(prev);
|
|
@@ -503,7 +877,7 @@ function MixMatchBundle(props) {
|
|
|
503
877
|
},
|
|
504
878
|
[]
|
|
505
879
|
);
|
|
506
|
-
const handleAddToCart = (0,
|
|
880
|
+
const handleAddToCart = (0, import_react7.useCallback)(async () => {
|
|
507
881
|
if (!bundle || !validation.valid) return;
|
|
508
882
|
const lines = Array.from(selections.values()).map((s) => ({
|
|
509
883
|
merchandiseId: s.variantId,
|
|
@@ -548,15 +922,15 @@ function MixMatchBundle(props) {
|
|
|
548
922
|
totalQuantity
|
|
549
923
|
]);
|
|
550
924
|
if (result.status === "loading") {
|
|
551
|
-
return /* @__PURE__ */ (0,
|
|
552
|
-
/* @__PURE__ */ (0,
|
|
553
|
-
/* @__PURE__ */ (0,
|
|
925
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: `lb-bundle lb-bundle--loading ${className ?? ""}`, children: [
|
|
926
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "lb-skeleton lb-skeleton--title" }),
|
|
927
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "lb-skeleton lb-skeleton--products" })
|
|
554
928
|
] });
|
|
555
929
|
}
|
|
556
930
|
if (result.status === "error") return null;
|
|
557
931
|
if (!bundle) return null;
|
|
558
932
|
const currency = bundle.products[0]?.priceRange.minVariantPrice.currencyCode ?? "USD";
|
|
559
|
-
return /* @__PURE__ */ (0,
|
|
933
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
560
934
|
"div",
|
|
561
935
|
{
|
|
562
936
|
ref: (el) => {
|
|
@@ -567,83 +941,23 @@ function MixMatchBundle(props) {
|
|
|
567
941
|
role: "region",
|
|
568
942
|
"aria-label": bundle.title,
|
|
569
943
|
children: [
|
|
570
|
-
/* @__PURE__ */ (0,
|
|
571
|
-
bundle.discountLabel && /* @__PURE__ */ (0,
|
|
572
|
-
/* @__PURE__ */ (0,
|
|
573
|
-
/* @__PURE__ */ (0,
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
alt: product.featuredImage.altText ?? product.title,
|
|
588
|
-
className: "lb-bundle__product-image",
|
|
589
|
-
loading: "lazy"
|
|
590
|
-
}
|
|
591
|
-
),
|
|
592
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "lb-bundle__product-info", children: [
|
|
593
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "lb-bundle__product-title", children: product.title }),
|
|
594
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "lb-bundle__product-price", children: (0, import_core7.formatMoney)(defaultVariant.price.amount, currency) }),
|
|
595
|
-
(() => {
|
|
596
|
-
const unitPriceText = (0, import_core7.formatUnitPrice)(
|
|
597
|
-
defaultVariant.unitPrice,
|
|
598
|
-
defaultVariant.unitPriceMeasurement,
|
|
599
|
-
currency
|
|
600
|
-
);
|
|
601
|
-
return unitPriceText ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "lb-bundle__product-unit-price", children: unitPriceText }) : null;
|
|
602
|
-
})()
|
|
603
|
-
] }),
|
|
604
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "lb-bundle__product-actions", children: selected ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "lb-bundle__quantity-control", children: [
|
|
605
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
606
|
-
"button",
|
|
607
|
-
{
|
|
608
|
-
"aria-label": `Decrease ${product.title}`,
|
|
609
|
-
onClick: () => updateQuantity(
|
|
610
|
-
product.id,
|
|
611
|
-
defaultVariant.id,
|
|
612
|
-
selected.quantity - 1
|
|
613
|
-
),
|
|
614
|
-
children: "\u2212"
|
|
615
|
-
}
|
|
616
|
-
),
|
|
617
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: selected.quantity }),
|
|
618
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
619
|
-
"button",
|
|
620
|
-
{
|
|
621
|
-
"aria-label": `Increase ${product.title}`,
|
|
622
|
-
onClick: () => updateQuantity(
|
|
623
|
-
product.id,
|
|
624
|
-
defaultVariant.id,
|
|
625
|
-
selected.quantity + 1
|
|
626
|
-
),
|
|
627
|
-
children: "+"
|
|
628
|
-
}
|
|
629
|
-
)
|
|
630
|
-
] }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
631
|
-
"button",
|
|
632
|
-
{
|
|
633
|
-
className: "lb-bundle__select-btn",
|
|
634
|
-
onClick: () => toggleProduct(product.id, defaultVariant),
|
|
635
|
-
disabled: !defaultVariant.availableForSale,
|
|
636
|
-
children: defaultVariant.availableForSale ? "Select" : "Sold out"
|
|
637
|
-
}
|
|
638
|
-
) })
|
|
639
|
-
]
|
|
640
|
-
},
|
|
641
|
-
product.id
|
|
642
|
-
);
|
|
643
|
-
}) }),
|
|
644
|
-
validation.message && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "lb-bundle__validation", role: "status", children: validation.message }),
|
|
645
|
-
cartError && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "lb-bundle__error", role: "alert", children: cartError }),
|
|
646
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
944
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h3", { className: "lb-bundle__title", children: bundle.title }),
|
|
945
|
+
bundle.discountLabel && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "lb-bundle__discount-badge", children: bundle.discountLabel }),
|
|
946
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "lb-bundle__instructions", children: bundle.minQuantity && bundle.maxQuantity ? `Select ${bundle.minQuantity}\u2013${bundle.maxQuantity} items` : bundle.minQuantity ? `Select at least ${bundle.minQuantity} items` : bundle.maxQuantity ? `Select up to ${bundle.maxQuantity} items` : "Select your items" }),
|
|
947
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "lb-bundle__products lb-bundle__products--selectable", children: bundle.products.map((product) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
948
|
+
MixMatchProductRow,
|
|
949
|
+
{
|
|
950
|
+
product,
|
|
951
|
+
currency,
|
|
952
|
+
selections,
|
|
953
|
+
onToggle: toggleProduct,
|
|
954
|
+
onUpdateQuantity: updateQuantity
|
|
955
|
+
},
|
|
956
|
+
product.id
|
|
957
|
+
)) }),
|
|
958
|
+
validation.message && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "lb-bundle__validation", role: "status", children: validation.message }),
|
|
959
|
+
cartError && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "lb-bundle__error", role: "alert", children: cartError }),
|
|
960
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
647
961
|
"button",
|
|
648
962
|
{
|
|
649
963
|
className: "lb-bundle__cta",
|
|
@@ -657,11 +971,110 @@ function MixMatchBundle(props) {
|
|
|
657
971
|
}
|
|
658
972
|
);
|
|
659
973
|
}
|
|
974
|
+
function MixMatchProductRow({
|
|
975
|
+
product,
|
|
976
|
+
currency,
|
|
977
|
+
selections,
|
|
978
|
+
onToggle,
|
|
979
|
+
onUpdateQuantity
|
|
980
|
+
}) {
|
|
981
|
+
const variants = product.variants.nodes;
|
|
982
|
+
const optionNames = (0, import_react7.useMemo)(() => {
|
|
983
|
+
const first = variants[0];
|
|
984
|
+
return first ? first.selectedOptions.map((o) => o.name) : [];
|
|
985
|
+
}, [variants]);
|
|
986
|
+
const showPicker = variants.length > 1 && optionNames.length > 0;
|
|
987
|
+
const { selectedValues, selectedVariant, setOptionValue, optionsFor } = useVariantSelection({ variants, optionNames });
|
|
988
|
+
const displayVariant = selectedVariant ?? variants.find((v) => v.availableForSale) ?? variants[0] ?? null;
|
|
989
|
+
if (!displayVariant) return null;
|
|
990
|
+
const key = `${product.id}:${displayVariant.id}`;
|
|
991
|
+
const selected = selections.get(key);
|
|
992
|
+
const thumbImage = displayVariant.image ?? product.featuredImage;
|
|
993
|
+
const unitPriceText = (0, import_core9.formatUnitPrice)(
|
|
994
|
+
displayVariant.unitPrice,
|
|
995
|
+
displayVariant.unitPriceMeasurement,
|
|
996
|
+
currency
|
|
997
|
+
);
|
|
998
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
999
|
+
"div",
|
|
1000
|
+
{
|
|
1001
|
+
className: `lb-bundle__product lb-bundle__product--selectable ${selected ? "lb-bundle__product--selected" : ""}`,
|
|
1002
|
+
children: [
|
|
1003
|
+
thumbImage && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1004
|
+
"img",
|
|
1005
|
+
{
|
|
1006
|
+
src: thumbImage.url,
|
|
1007
|
+
alt: thumbImage.altText ?? product.title,
|
|
1008
|
+
className: "lb-bundle__product-image",
|
|
1009
|
+
loading: "lazy"
|
|
1010
|
+
}
|
|
1011
|
+
),
|
|
1012
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "lb-bundle__product-info", children: [
|
|
1013
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "lb-bundle__product-title", children: product.title }),
|
|
1014
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "lb-bundle__product-price", children: (0, import_core9.formatMoney)(displayVariant.price.amount, currency) }),
|
|
1015
|
+
unitPriceText && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "lb-bundle__product-unit-price", children: unitPriceText }),
|
|
1016
|
+
showPicker && !selected && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "lb-bundle__product-variant-pickers", children: optionNames.map((optionName, optionIndex) => {
|
|
1017
|
+
const dropdownOptions = optionsFor(optionIndex).map((o) => ({
|
|
1018
|
+
value: o.value,
|
|
1019
|
+
label: o.value,
|
|
1020
|
+
disabled: o.disabled
|
|
1021
|
+
}));
|
|
1022
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1023
|
+
VariantDropdown,
|
|
1024
|
+
{
|
|
1025
|
+
options: dropdownOptions,
|
|
1026
|
+
value: selectedValues[optionIndex] ?? null,
|
|
1027
|
+
onChange: (v) => setOptionValue(optionIndex, v),
|
|
1028
|
+
ariaLabel: optionName
|
|
1029
|
+
},
|
|
1030
|
+
optionName
|
|
1031
|
+
);
|
|
1032
|
+
}) })
|
|
1033
|
+
] }),
|
|
1034
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "lb-bundle__product-actions", children: selected ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "lb-bundle__quantity-control", children: [
|
|
1035
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1036
|
+
"button",
|
|
1037
|
+
{
|
|
1038
|
+
"aria-label": `Decrease ${product.title}`,
|
|
1039
|
+
onClick: () => onUpdateQuantity(
|
|
1040
|
+
product.id,
|
|
1041
|
+
displayVariant.id,
|
|
1042
|
+
selected.quantity - 1
|
|
1043
|
+
),
|
|
1044
|
+
children: "\u2212"
|
|
1045
|
+
}
|
|
1046
|
+
),
|
|
1047
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: selected.quantity }),
|
|
1048
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1049
|
+
"button",
|
|
1050
|
+
{
|
|
1051
|
+
"aria-label": `Increase ${product.title}`,
|
|
1052
|
+
onClick: () => onUpdateQuantity(
|
|
1053
|
+
product.id,
|
|
1054
|
+
displayVariant.id,
|
|
1055
|
+
selected.quantity + 1
|
|
1056
|
+
),
|
|
1057
|
+
children: "+"
|
|
1058
|
+
}
|
|
1059
|
+
)
|
|
1060
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1061
|
+
"button",
|
|
1062
|
+
{
|
|
1063
|
+
className: "lb-bundle__select-btn",
|
|
1064
|
+
onClick: () => onToggle(product.id, displayVariant),
|
|
1065
|
+
disabled: !displayVariant.availableForSale,
|
|
1066
|
+
children: displayVariant.availableForSale ? "Select" : "Sold out"
|
|
1067
|
+
}
|
|
1068
|
+
) })
|
|
1069
|
+
]
|
|
1070
|
+
}
|
|
1071
|
+
);
|
|
1072
|
+
}
|
|
660
1073
|
|
|
661
1074
|
// src/components/VolumeBundle.tsx
|
|
662
|
-
var
|
|
663
|
-
var
|
|
664
|
-
var
|
|
1075
|
+
var import_react8 = require("react");
|
|
1076
|
+
var import_core10 = require("@lime-bundles/core");
|
|
1077
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
665
1078
|
function VolumeBundle(props) {
|
|
666
1079
|
const {
|
|
667
1080
|
shopDomain,
|
|
@@ -685,12 +1098,12 @@ function VolumeBundle(props) {
|
|
|
685
1098
|
bundleType: "volume",
|
|
686
1099
|
enabled: analyticsEnabled !== false
|
|
687
1100
|
});
|
|
688
|
-
const [quantity, setQuantity] = (0,
|
|
689
|
-
const [addingToCart, setAddingToCart] = (0,
|
|
690
|
-
const [cartError, setCartError] = (0,
|
|
1101
|
+
const [quantity, setQuantity] = (0, import_react8.useState)(1);
|
|
1102
|
+
const [addingToCart, setAddingToCart] = (0, import_react8.useState)(false);
|
|
1103
|
+
const [cartError, setCartError] = (0, import_react8.useState)(null);
|
|
691
1104
|
const bundle = result.status === "success" && result.bundle.bundleType === "volume" ? result.bundle : null;
|
|
692
1105
|
const setConfigVarsRef = useWidgetConfigVars(bundle?.widgetConfig);
|
|
693
|
-
(0,
|
|
1106
|
+
(0, import_react8.useEffect)(() => {
|
|
694
1107
|
if (result.status === "error") {
|
|
695
1108
|
onError?.(result.error);
|
|
696
1109
|
return;
|
|
@@ -704,18 +1117,35 @@ function VolumeBundle(props) {
|
|
|
704
1117
|
}
|
|
705
1118
|
}, [result, onError]);
|
|
706
1119
|
const product = bundle?.products[0];
|
|
707
|
-
const
|
|
1120
|
+
const variants = (0, import_react8.useMemo)(() => product?.variants.nodes ?? [], [product]);
|
|
1121
|
+
const optionNames = (0, import_react8.useMemo)(() => {
|
|
1122
|
+
const first = variants[0];
|
|
1123
|
+
return first ? first.selectedOptions.map((o) => o.name) : [];
|
|
1124
|
+
}, [variants]);
|
|
1125
|
+
const showPicker = variants.length > 1 && optionNames.length > 0;
|
|
1126
|
+
const { selectedValues, selectedVariant, setOptionValue, optionsFor } = useVariantSelection({ variants, optionNames });
|
|
1127
|
+
const displayVariant = selectedVariant ?? variants.find((v) => v.availableForSale) ?? variants[0];
|
|
1128
|
+
const basePrice = displayVariant ? parseFloat(displayVariant.price.amount) : product ? parseFloat(product.priceRange.minVariantPrice.amount) : 0;
|
|
708
1129
|
const currency = product?.priceRange.minVariantPrice.currencyCode ?? "USD";
|
|
709
|
-
const
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
) :
|
|
715
|
-
const
|
|
716
|
-
|
|
1130
|
+
const thumbImage = displayVariant?.image ?? product?.featuredImage ?? null;
|
|
1131
|
+
const unitPriceText = displayVariant ? (0, import_core10.formatUnitPrice)(
|
|
1132
|
+
displayVariant.unitPrice,
|
|
1133
|
+
displayVariant.unitPriceMeasurement,
|
|
1134
|
+
currency
|
|
1135
|
+
) : null;
|
|
1136
|
+
const tierSavings = (0, import_react8.useMemo)(
|
|
1137
|
+
() => bundle ? (0, import_core10.calculateTierSavings)(
|
|
1138
|
+
bundle.volumeTiers,
|
|
1139
|
+
basePrice,
|
|
1140
|
+
quantity,
|
|
1141
|
+
bundle.discountConfig.discountType
|
|
1142
|
+
) : [],
|
|
1143
|
+
[bundle, basePrice, quantity]
|
|
1144
|
+
);
|
|
1145
|
+
const activeTier = bundle ? (0, import_core10.getActiveTier)(bundle.volumeTiers, quantity) : null;
|
|
1146
|
+
const handleAddToCart = (0, import_react8.useCallback)(async () => {
|
|
717
1147
|
if (!bundle || !product) return;
|
|
718
|
-
const variant = product.variants.nodes.find((v) => v.availableForSale);
|
|
1148
|
+
const variant = selectedVariant ?? product.variants.nodes.find((v) => v.availableForSale);
|
|
719
1149
|
if (!variant) return;
|
|
720
1150
|
const lines = [
|
|
721
1151
|
{
|
|
@@ -752,18 +1182,20 @@ function VolumeBundle(props) {
|
|
|
752
1182
|
basePrice,
|
|
753
1183
|
onAddToCart,
|
|
754
1184
|
onError,
|
|
755
|
-
trackAddToCart
|
|
1185
|
+
trackAddToCart,
|
|
1186
|
+
selectedVariant,
|
|
1187
|
+
tierSavings
|
|
756
1188
|
]);
|
|
757
1189
|
if (result.status === "loading") {
|
|
758
|
-
return /* @__PURE__ */ (0,
|
|
759
|
-
/* @__PURE__ */ (0,
|
|
760
|
-
/* @__PURE__ */ (0,
|
|
1190
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: `lb-bundle lb-bundle--loading ${className ?? ""}`, children: [
|
|
1191
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "lb-skeleton lb-skeleton--title" }),
|
|
1192
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "lb-skeleton lb-skeleton--tiers" })
|
|
761
1193
|
] });
|
|
762
1194
|
}
|
|
763
1195
|
if (result.status === "error") return null;
|
|
764
1196
|
if (!bundle) return null;
|
|
765
1197
|
if (!product) return null;
|
|
766
|
-
return /* @__PURE__ */ (0,
|
|
1198
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
767
1199
|
"div",
|
|
768
1200
|
{
|
|
769
1201
|
ref: (el) => {
|
|
@@ -774,55 +1206,64 @@ function VolumeBundle(props) {
|
|
|
774
1206
|
role: "region",
|
|
775
1207
|
"aria-label": bundle.title,
|
|
776
1208
|
children: [
|
|
777
|
-
/* @__PURE__ */ (0,
|
|
778
|
-
/* @__PURE__ */ (0,
|
|
779
|
-
|
|
1209
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h3", { className: "lb-bundle__title", children: bundle.title }),
|
|
1210
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "lb-bundle__product lb-bundle__product--volume", children: [
|
|
1211
|
+
thumbImage && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
780
1212
|
"img",
|
|
781
1213
|
{
|
|
782
|
-
src:
|
|
783
|
-
alt:
|
|
1214
|
+
src: thumbImage.url,
|
|
1215
|
+
alt: thumbImage.altText ?? product.title,
|
|
784
1216
|
className: "lb-bundle__product-image",
|
|
785
1217
|
loading: "lazy"
|
|
786
1218
|
}
|
|
787
1219
|
),
|
|
788
|
-
/* @__PURE__ */ (0,
|
|
789
|
-
/* @__PURE__ */ (0,
|
|
790
|
-
/* @__PURE__ */ (0,
|
|
791
|
-
(0,
|
|
1220
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "lb-bundle__product-info", children: [
|
|
1221
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "lb-bundle__product-title", children: product.title }),
|
|
1222
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "lb-bundle__product-price", children: [
|
|
1223
|
+
(0, import_core10.formatMoney)(basePrice, currency),
|
|
792
1224
|
" each"
|
|
793
1225
|
] }),
|
|
794
|
-
((
|
|
795
|
-
|
|
796
|
-
const
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
)
|
|
801
|
-
return
|
|
802
|
-
|
|
1226
|
+
unitPriceText && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "lb-bundle__product-unit-price", children: unitPriceText }),
|
|
1227
|
+
showPicker && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "lb-bundle__product-variant-pickers", children: optionNames.map((optionName, optionIndex) => {
|
|
1228
|
+
const dropdownOptions = optionsFor(optionIndex).map((o) => ({
|
|
1229
|
+
value: o.value,
|
|
1230
|
+
label: o.value,
|
|
1231
|
+
disabled: o.disabled
|
|
1232
|
+
}));
|
|
1233
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
1234
|
+
VariantDropdown,
|
|
1235
|
+
{
|
|
1236
|
+
options: dropdownOptions,
|
|
1237
|
+
value: selectedValues[optionIndex] ?? null,
|
|
1238
|
+
onChange: (v) => setOptionValue(optionIndex, v),
|
|
1239
|
+
ariaLabel: optionName
|
|
1240
|
+
},
|
|
1241
|
+
optionName
|
|
1242
|
+
);
|
|
1243
|
+
}) })
|
|
803
1244
|
] })
|
|
804
1245
|
] }),
|
|
805
|
-
/* @__PURE__ */ (0,
|
|
1246
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
806
1247
|
"div",
|
|
807
1248
|
{
|
|
808
1249
|
className: "lb-bundle__tiers",
|
|
809
1250
|
role: "table",
|
|
810
1251
|
"aria-label": "Volume discounts",
|
|
811
|
-
children: tierSavings.map((ts) => /* @__PURE__ */ (0,
|
|
1252
|
+
children: tierSavings.map((ts) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
812
1253
|
"div",
|
|
813
1254
|
{
|
|
814
1255
|
className: `lb-bundle__tier ${ts.isActive ? "lb-bundle__tier--active" : ""}`,
|
|
815
1256
|
role: "row",
|
|
816
1257
|
children: [
|
|
817
|
-
/* @__PURE__ */ (0,
|
|
1258
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "lb-bundle__tier-quantity", role: "cell", children: [
|
|
818
1259
|
ts.tier.minQuantity,
|
|
819
1260
|
"+ items"
|
|
820
1261
|
] }),
|
|
821
|
-
/* @__PURE__ */ (0,
|
|
822
|
-
(0,
|
|
1262
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "lb-bundle__tier-price", role: "cell", children: [
|
|
1263
|
+
(0, import_core10.formatMoney)(ts.unitPrice, currency),
|
|
823
1264
|
" each"
|
|
824
1265
|
] }),
|
|
825
|
-
/* @__PURE__ */ (0,
|
|
1266
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "lb-bundle__tier-savings", role: "cell", children: [
|
|
826
1267
|
"Save ",
|
|
827
1268
|
ts.savingsPercent.toFixed(0),
|
|
828
1269
|
"%"
|
|
@@ -833,10 +1274,10 @@ function VolumeBundle(props) {
|
|
|
833
1274
|
))
|
|
834
1275
|
}
|
|
835
1276
|
),
|
|
836
|
-
/* @__PURE__ */ (0,
|
|
837
|
-
/* @__PURE__ */ (0,
|
|
838
|
-
/* @__PURE__ */ (0,
|
|
839
|
-
/* @__PURE__ */ (0,
|
|
1277
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "lb-bundle__quantity-selector", children: [
|
|
1278
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("label", { htmlFor: `lb-qty-${bundle.id}`, children: "Quantity" }),
|
|
1279
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "lb-bundle__quantity-control", children: [
|
|
1280
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
840
1281
|
"button",
|
|
841
1282
|
{
|
|
842
1283
|
"aria-label": "Decrease quantity",
|
|
@@ -844,7 +1285,7 @@ function VolumeBundle(props) {
|
|
|
844
1285
|
children: "\u2212"
|
|
845
1286
|
}
|
|
846
1287
|
),
|
|
847
|
-
/* @__PURE__ */ (0,
|
|
1288
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
848
1289
|
"input",
|
|
849
1290
|
{
|
|
850
1291
|
id: `lb-qty-${bundle.id}`,
|
|
@@ -858,7 +1299,7 @@ function VolumeBundle(props) {
|
|
|
858
1299
|
className: "lb-bundle__quantity-input"
|
|
859
1300
|
}
|
|
860
1301
|
),
|
|
861
|
-
/* @__PURE__ */ (0,
|
|
1302
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
862
1303
|
"button",
|
|
863
1304
|
{
|
|
864
1305
|
"aria-label": "Increase quantity",
|
|
@@ -868,8 +1309,8 @@ function VolumeBundle(props) {
|
|
|
868
1309
|
)
|
|
869
1310
|
] })
|
|
870
1311
|
] }),
|
|
871
|
-
cartError && /* @__PURE__ */ (0,
|
|
872
|
-
/* @__PURE__ */ (0,
|
|
1312
|
+
cartError && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "lb-bundle__error", role: "alert", children: cartError }),
|
|
1313
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
873
1314
|
"button",
|
|
874
1315
|
{
|
|
875
1316
|
className: "lb-bundle__cta",
|
|
@@ -885,21 +1326,21 @@ function VolumeBundle(props) {
|
|
|
885
1326
|
}
|
|
886
1327
|
|
|
887
1328
|
// src/hooks/useBundlesForProduct.ts
|
|
888
|
-
var
|
|
889
|
-
var
|
|
1329
|
+
var import_react9 = require("react");
|
|
1330
|
+
var import_core11 = require("@lime-bundles/core");
|
|
890
1331
|
var INITIAL_STATE2 = {
|
|
891
1332
|
status: "loading",
|
|
892
1333
|
bundles: null,
|
|
893
1334
|
error: null
|
|
894
1335
|
};
|
|
895
1336
|
function useBundlesForProduct(options) {
|
|
896
|
-
const [state, setState] = (0,
|
|
1337
|
+
const [state, setState] = (0, import_react9.useState)(
|
|
897
1338
|
INITIAL_STATE2
|
|
898
1339
|
);
|
|
899
|
-
(0,
|
|
1340
|
+
(0, import_react9.useEffect)(() => {
|
|
900
1341
|
const controller = new AbortController();
|
|
901
1342
|
setState(INITIAL_STATE2);
|
|
902
|
-
(0,
|
|
1343
|
+
(0, import_core11.fetchBundlesForProduct)({
|
|
903
1344
|
shopDomain: options.shopDomain,
|
|
904
1345
|
storefrontAccessToken: options.storefrontAccessToken,
|
|
905
1346
|
productHandle: options.productHandle,
|
|
@@ -922,7 +1363,7 @@ function useBundlesForProduct(options) {
|
|
|
922
1363
|
signal: controller.signal
|
|
923
1364
|
}).then((css) => {
|
|
924
1365
|
if (controller.signal.aborted) return;
|
|
925
|
-
(0,
|
|
1366
|
+
(0, import_core11.injectCustomCss)(options.shopDomain, css);
|
|
926
1367
|
}).catch(() => {
|
|
927
1368
|
});
|
|
928
1369
|
return () => {
|
|
@@ -938,8 +1379,8 @@ function useBundlesForProduct(options) {
|
|
|
938
1379
|
}
|
|
939
1380
|
|
|
940
1381
|
// src/index.ts
|
|
941
|
-
var
|
|
942
|
-
var
|
|
1382
|
+
var import_core12 = require("@lime-bundles/core");
|
|
1383
|
+
var import_core13 = require("@lime-bundles/core");
|
|
943
1384
|
// Annotate the CommonJS export names for ESM import in node:
|
|
944
1385
|
0 && (module.exports = {
|
|
945
1386
|
BUNDLES_FOR_PRODUCT_QUERY,
|
|
@@ -949,6 +1390,7 @@ var import_core11 = require("@lime-bundles/core");
|
|
|
949
1390
|
MixMatchBundle,
|
|
950
1391
|
SHOP_CUSTOM_CSS_QUERY,
|
|
951
1392
|
StorefrontApiError,
|
|
1393
|
+
VariantDropdown,
|
|
952
1394
|
VolumeBundle,
|
|
953
1395
|
WIDGET_CONFIG_DEFAULTS,
|
|
954
1396
|
applyABVariantB,
|
|
@@ -984,6 +1426,7 @@ var import_core11 = require("@lime-bundles/core");
|
|
|
984
1426
|
useAnalytics,
|
|
985
1427
|
useBundleData,
|
|
986
1428
|
useBundlesForProduct,
|
|
1429
|
+
useVariantSelection,
|
|
987
1430
|
useWidgetConfigVars,
|
|
988
1431
|
validateQuantity
|
|
989
1432
|
});
|