@best-bundles/bundle-ui 0.0.2 → 0.0.3
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/constants.d.ts
CHANGED
package/dist/constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,uBAAuB
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,uBAAuB;;;;;CAK1B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BundleProvider.d.ts","sourceRoot":"","sources":["../../src/context/BundleProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA2E,MAAM,OAAO,CAAC;AAGhG,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,qBAAqB,EAAE,0BAA0B,EAAE,MAAM,UAAU,CAAC;AAEnH,KAAK,kBAAkB,GAAG;IACxB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,MAAM,EAAE,YAAY,CAAC;IACrB,gBAAgB,EAAE,qBAAqB,EAAE,CAAC;CAC3C,CAAC;AAEF,KAAK,oBAAoB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACnD,KAAK,oBAAoB,GAAG,MAAM,EAAE,CAAC;AAErC,MAAM,MAAM,mBAAmB,GAAG;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,iBAAiB,CAAC;IAE/B;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,WAAW,CAAC,EAAE,kBAAkB,CAAC;IAEjC;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,KAAK,OAAO,CAAC,0BAA0B,CAAC,CAAC;IAE5H,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,MAAM,EAAE,MAAM,IAAI,CAAC;IAEnB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAErB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;IAC5B,gBAAgB,EAAE,qBAAqB,EAAE,CAAC;IAE1C,UAAU,EAAE,oBAAoB,CAAC;IACjC,cAAc,EAAE,oBAAoB,CAAC;IACrC,WAAW,EAAE,CAAC,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/D,eAAe,EAAE,MAAM,IAAI,CAAC;IAE5B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7B,CAAC;AAEF,eAAO,MAAM,oBAAoB,iDAAwD,CAAC;AAkB1F,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,
|
|
1
|
+
{"version":3,"file":"BundleProvider.d.ts","sourceRoot":"","sources":["../../src/context/BundleProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA2E,MAAM,OAAO,CAAC;AAGhG,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,qBAAqB,EAAE,0BAA0B,EAAE,MAAM,UAAU,CAAC;AAEnH,KAAK,kBAAkB,GAAG;IACxB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,MAAM,EAAE,YAAY,CAAC;IACrB,gBAAgB,EAAE,qBAAqB,EAAE,CAAC;CAC3C,CAAC;AAEF,KAAK,oBAAoB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACnD,KAAK,oBAAoB,GAAG,MAAM,EAAE,CAAC;AAErC,MAAM,MAAM,mBAAmB,GAAG;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,iBAAiB,CAAC;IAE/B;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,WAAW,CAAC,EAAE,kBAAkB,CAAC;IAEjC;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,KAAK,OAAO,CAAC,0BAA0B,CAAC,CAAC;IAE5H,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,MAAM,EAAE,MAAM,IAAI,CAAC;IAEnB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAErB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;IAC5B,gBAAgB,EAAE,qBAAqB,EAAE,CAAC;IAE1C,UAAU,EAAE,oBAAoB,CAAC;IACjC,cAAc,EAAE,oBAAoB,CAAC;IACrC,WAAW,EAAE,CAAC,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/D,eAAe,EAAE,MAAM,IAAI,CAAC;IAE5B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7B,CAAC;AAEF,eAAO,MAAM,oBAAoB,iDAAwD,CAAC;AAkB1F,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,2CAgNxD"}
|
package/dist/index.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
(function(){"use strict";try{if(typeof document<"u"){var r=document.createElement("style");r.appendChild(document.createTextNode('._button_18rtl_1{display:inline-flex;align-items:center;justify-content:center;gap:8px;font-family:var(--bb-font-family, inherit);border:1px solid var(--bb-button-border, rgba(0, 0, 0, .12));background:var(--bb-button-bg, #111827);color:var(--bb-button-text, #ffffff);font:inherit;line-height:1;padding:10px 14px;border-radius:var(--bb-button-radius, 10px);cursor:pointer;transition:transform .12s ease,background .12s ease,border-color .12s ease,opacity .12s ease}._button_18rtl_1:hover{background:var(--bb-button-bg-hover, #0b1220)}._button_18rtl_1:active{transform:translateY(1px)}._button_18rtl_1:disabled{opacity:.6;cursor:not-allowed}._button_18rtl_1:focus-visible{outline:2px solid var(--bb-focus-ring, #2563eb);outline-offset:2px}._backdrop_1ctfr_1{position:fixed;top:0;right:0;bottom:0;left:0;z-index:var(--bb-backdrop-z-index, 9999);display:flex;justify-content:flex-end;background:var(--bb-backdrop-bg, rgba(0, 0, 0, .5));-webkit-backdrop-filter:blur(var(--bb-backdrop-blur, 2px));backdrop-filter:blur(var(--bb-backdrop-blur, 2px));padding:var(--bb-backdrop-padding, 12px);opacity:0;transition:opacity var(--bb-drawer-transition-duration, .22s) ease}._backdropOpen_1ctfr_14{opacity:1}._backdropClosed_1ctfr_18{opacity:0}._panel_1ctfr_22{width:440px;max-width:100%;height:100%;background:var(--bb-surface-bg, #ffffff);color:var(--bb-text-color, #111827);font-family:var(--bb-font-family-body, "Cabin", system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, sans-serif);border-radius:var(--bb-panel-radius, 16px);box-shadow:0 20px 60px #00000059;display:grid;grid-template-rows:auto 1fr auto;overflow:hidden;outline:none;position:relative;top:unset;right:unset;bottom:unset;left:unset}._panelOpen_1ctfr_42{animation:_bbSlideInFromRight_1ctfr_1 var(--bb-drawer-transition-duration, .22s) ease forwards}._panelClosed_1ctfr_46{animation:_bbSlideOutToRight_1ctfr_1 var(--bb-drawer-transition-duration, .22s) ease forwards}@keyframes _bbSlideInFromRight_1ctfr_1{0%{transform:translate(110%)}to{transform:translate(0)}}@keyframes _bbSlideOutToRight_1ctfr_1{0%{transform:translate(0)}to{transform:translate(110%)}}@media(prefers-reduced-motion:reduce){._backdrop_1ctfr_1{transition:none}._panelOpen_1ctfr_42,._panelClosed_1ctfr_46{animation:none}}._header_1ctfr_81{display:grid;grid-template-columns:36px 1fr 36px;align-items:center;column-gap:12px;padding:var(--bb-header-padding, 16px 16px 12px 16px);border-bottom:1px solid var(--bb-border-color, rgba(17, 24, 39, .08))}._headerCenter_1ctfr_90{position:relative;min-width:0;display:flex;justify-content:center;align-items:center}._title_1ctfr_98{font-size:24px;margin:0;line-height:1.2;font-family:var(--bb-font-family-title, "Bebas Neue", "Cabin", system-ui, -apple-system, Segoe UI, Roboto, Helvetica, Arial, sans-serif);letter-spacing:.02em;color:var(--bb-title-color, var(--bb-text-color, #111827))}._searchIconButton_1ctfr_107{width:36px;height:36px;border-radius:10px;border:1px solid var(--bb-border-strong-color, rgba(17, 24, 39, .12));background:var(--bb-surface-bg, #ffffff);color:var(--bb-text-color, #111827);cursor:pointer;display:inline-flex;align-items:center;justify-content:center}._searchIconButton_1ctfr_107:hover{background:var(--bb-control-bg-hover, rgba(17, 24, 39, .04))}._searchIconButton_1ctfr_107:focus-visible{outline:2px solid var(--bb-focus-ring, #2563eb);outline-offset:2px}._headerTitleWrap_1ctfr_129{transition:opacity .18s ease,transform .22s ease}._headerSearchWrap_1ctfr_133{position:absolute;top:0;right:0;bottom:0;left:0;display:flex;justify-content:center;align-items:center;pointer-events:none;opacity:0;transform:translateY(-2px);transition:opacity .18s ease,transform .22s ease}._headerSearchOpen_1ctfr_145 ._headerTitleWrap_1ctfr_129{opacity:0;transform:translateY(2px);pointer-events:none}._headerSearchOpen_1ctfr_145 ._headerSearchWrap_1ctfr_133{opacity:1;transform:translateY(0);pointer-events:auto}._searchBar_1ctfr_157{width:min(320px,100%);height:36px;display:flex;align-items:center;gap:8px;background:var(--bb-surface-bg, #ffffff);border:1px solid var(--bb-border-strong-color, rgba(17, 24, 39, .12));border-radius:10px;padding:0 8px}._searchInput_1ctfr_169{width:100%;border:none;outline:none;background:transparent;font:inherit;font-size:14px;min-width:0;height:100%;line-height:36px;padding:0}._searchInput_1ctfr_169::-webkit-search-cancel-button,._searchInput_1ctfr_169::-webkit-search-decoration,._searchInput_1ctfr_169::-webkit-search-results-button,._searchInput_1ctfr_169::-webkit-search-results-decoration{-webkit-appearance:none;-moz-appearance:none;appearance:none}._searchClearButton_1ctfr_190{border:none;background:transparent;color:var(--bb-text-color, #111827);font:inherit;font-size:13px;font-weight:700;cursor:pointer;padding:6px;border-radius:10px;line-height:1}._searchClearButton_1ctfr_190:hover{background:var(--bb-control-bg-hover, rgba(17, 24, 39, .04))}._searchClearButton_1ctfr_190:focus-visible{outline:2px solid var(--bb-focus-ring, #2563eb);outline-offset:2px}._closeButton_1ctfr_212{border:1px solid var(--bb-border-strong-color, rgba(17, 24, 39, .12));background:var(--bb-surface-bg, #ffffff);color:var(--bb-text-color, #111827);width:36px;height:36px;border-radius:10px;cursor:pointer;flex:0 0 auto}._closeButton_1ctfr_212:hover{background:var(--bb-control-bg-hover, rgba(17, 24, 39, .04))}._closeButton_1ctfr_212:disabled{opacity:.6;cursor:not-allowed}._closeButton_1ctfr_212:focus-visible{outline:2px solid var(--bb-focus-ring, #2563eb);outline-offset:2px}@media(prefers-reduced-motion:reduce){._headerTitleWrap_1ctfr_129,._headerSearchWrap_1ctfr_133{transition:none}}._body_1ctfr_245{padding:var(--bb-body-padding, 8px 16px);overflow:auto}._muted_1ctfr_250{color:var(--bb-muted-strong-color, rgba(17, 24, 39, .65));margin:0 0 12px}._error_1ctfr_255{color:var(--bb-error-color, #b91c1c);margin:0 0 12px}._variants_1ctfr_260{margin-top:4px}._variantList_1ctfr_264{list-style:none;padding:0;margin:0;display:grid;gap:10px}._variantRow_1ctfr_272{display:grid;grid-template-columns:1fr auto;gap:0px;align-items:stretch;padding:5px}._variantLeft_1ctfr_280{min-width:0;display:flex;gap:12px;align-items:center}._addToBundleButton_1ctfr_287{height:100%;align-self:stretch;border-radius:12px;border:none;background:var(--bb-cta-bg, #91aae5);color:var(--bb-cta-text, #ffffff);font:inherit;font-weight:800;padding:0 16px;cursor:pointer;white-space:nowrap}._addToBundleButton_1ctfr_287:hover{background:var(--bb-cta-bg-hover, #1d4ed8)}._addToBundleButton_1ctfr_287:disabled{opacity:.6;cursor:not-allowed}._addToBundleButton_1ctfr_287:focus-visible{outline:2px solid var(--bb-focus-ring, #2563eb);outline-offset:2px}._variantThumb_1ctfr_315{width:60px;height:60px;border-radius:12px;overflow:hidden;border:1px solid var(--bb-border-color, rgba(17, 24, 39, .08));background:var(--bb-surface-subtle-bg, rgba(17, 24, 39, .02));flex:0 0 auto}._variantThumbImg_1ctfr_325{width:100%;height:100%;object-fit:cover;display:block}._variantThumbFallback_1ctfr_332{width:100%;height:100%;display:flex;align-items:center;justify-content:center;font-weight:800;color:var(--bb-text-color, #111827)}._variantInfo_1ctfr_342{min-width:0}._variantName_1ctfr_346{font-size:14px;font-weight:600;margin-bottom:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._variantMeta_1ctfr_355{font-size:12px;color:var(--bb-muted-color, rgba(17, 24, 39, .6));overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._variantPriceRow_1ctfr_363{display:flex;align-items:baseline;gap:8px;margin-top:4px}._variantCompareAt_1ctfr_370{font-size:12px;color:var(--bb-muted-color, rgba(17, 24, 39, .6));text-decoration:line-through}._variantPrice_1ctfr_363{font-size:13px;font-weight:800}._qtyControls_1ctfr_381{display:inline-flex;align-items:center;gap:6px}._qtyButton_1ctfr_387{width:34px;height:34px;border-radius:10px;border:1px solid var(--bb-border-strong-color, rgba(17, 24, 39, .12));background:var(--bb-surface-bg, #ffffff);cursor:pointer;line-height:1;font-size:16px}._qtyButton_1ctfr_387:hover{background:var(--bb-control-bg-hover, rgba(17, 24, 39, .04))}._qtyButton_1ctfr_387:disabled{opacity:.6;cursor:not-allowed}._qtyButton_1ctfr_387:focus-visible{outline:2px solid var(--bb-focus-ring, #2563eb);outline-offset:2px}._qtyValue_1ctfr_412{min-width:18px;text-align:center;font-variant-numeric:tabular-nums;font-weight:700}._footer_1ctfr_419{padding:var(--bb-footer-padding, 12px 16px 16px 16px);border-top:1px solid var(--bb-border-color, rgba(17, 24, 39, .08));background:var(--bb-surface-bg, #ffffff);position:relative}._boxSummaryWindow_1ctfr_426{margin-bottom:6px;overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;padding-bottom:6px;scrollbar-width:none;-ms-overflow-style:none}._boxSummaryWindow_1ctfr_426::-webkit-scrollbar{display:none}._boxSummaryRow_1ctfr_443{--bb-box-gap: 10px;display:flex;align-items:flex-start;gap:var(--bb-box-gap);width:100%}._boxSlot_1ctfr_451{flex:0 0 calc((100% - (4 * var(--bb-box-gap))) / 5);display:flex;flex-direction:column;align-items:stretch;gap:6px}._boxItem_1ctfr_459{width:100%;aspect-ratio:1 / 1;border-radius:12px;position:relative;display:flex;align-items:center;justify-content:center;-webkit-user-select:none;user-select:none;box-sizing:border-box}._boxItemClickable_1ctfr_471{cursor:pointer}._boxItemClickable_1ctfr_471:focus-visible{outline:2px solid var(--bb-focus-ring, #2563eb);outline-offset:2px}._boxThresholdLabel_1ctfr_480{font-size:11px;line-height:1.15;font-weight:700;color:var(--bb-muted-strong-color, rgba(17, 24, 39, .65));text-align:center;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}._boxItemPlaceholder_1ctfr_491{border:1px dashed var(--bb-border-strong-color, rgba(17, 24, 39, .18));background:var(--bb-surface-subtle-bg, rgba(17, 24, 39, .02));color:var(--bb-muted-color, rgba(17, 24, 39, .6))}._boxItemFilled_1ctfr_497{border:1px solid var(--bb-border-color, rgba(17, 24, 39, .08));background:var(--bb-surface-bg, #ffffff);overflow:hidden}._boxItemThreshold_1ctfr_503{border-style:solid;border-width:2px;border-color:var(--bb-tier-border, rgba(37, 99, 235, .55));background:linear-gradient(180deg,#2563eb1a,#2563eb08);color:var(--bb-tier-text, rgba(29, 78, 216, .95))}._boxItemDiscountText_1ctfr_511{font-size:12px;font-weight:800;text-align:center;line-height:1.1;padding:6px}._boxItemPlus_1ctfr_519{font-size:22px;font-weight:700;opacity:.5;line-height:1}._boxItemImage_1ctfr_526{width:100%;height:100%;object-fit:cover;display:block}._boxItemFallback_1ctfr_533{width:100%;height:100%;display:flex;align-items:center;justify-content:center;background:var(--bb-surface-subtle-bg, rgba(17, 24, 39, .04));color:var(--bb-text-color, #111827);font-weight:800}._cta_1ctfr_544{width:100%;border:1px solid var(--bb-cta-border, rgba(0, 0, 0, .12));background:var(--bb-cta-bg, #2563eb);color:var(--bb-cta-text, #ffffff);font:inherit;font-weight:700;padding:12px 14px;border-radius:12px;cursor:pointer}._ctaTotals_1ctfr_556{display:flex;justify-content:space-between;align-items:baseline;gap:10px;font-variant-numeric:tabular-nums}._ctaDiscountBadge_1ctfr_564{display:inline-flex;align-items:center;gap:6px;padding:6px 10px;border-radius:999px;font-size:12px;font-weight:800;background:linear-gradient(180deg,#2563eb24,#2563eb0f);border:1px solid rgba(37,99,235,.3);color:#1d4ed8f2;white-space:nowrap}._ctaTotalsWrap_1ctfr_578{overflow:hidden;max-height:0;opacity:0;transform:translateY(4px);margin-bottom:0;transition:max-height .22s ease,opacity .16s ease,transform .22s ease,margin-bottom .22s ease}._ctaTotalsWrapVisible_1ctfr_591{max-height:40px;opacity:1;transform:translateY(0);margin-bottom:8px}._ctaTotalsStrike_1ctfr_598{opacity:.85;text-decoration:line-through;font-weight:700;color:var(--bb-muted-strong-color, rgba(17, 24, 39, .65))}._ctaTotalsPrice_1ctfr_605{font-weight:900;color:var(--bb-text-color, #111827)}@media(prefers-reduced-motion:reduce){._ctaTotalsWrap_1ctfr_578{transition:none}}._cta_1ctfr_544:hover{background:var(--bb-cta-bg-hover, #1d4ed8)}._cta_1ctfr_544:disabled{opacity:.6;cursor:not-allowed}._cta_1ctfr_544:focus-visible{outline:2px solid var(--bb-cta-focus-ring, var(--bb-text-color, #111827));outline-offset:2px}._helperText_1ctfr_630{margin-top:8px;font-size:12px;color:var(--bb-muted-strong-color, rgba(17, 24, 39, .65));text-align:center}@media(max-width:767px){._backdrop_1ctfr_1{padding:0;justify-content:stretch}._panel_1ctfr_22{width:100%;height:100%;border-radius:0}}')),document.head.appendChild(r)}}catch(t){console.error("vite-plugin-css-injected-by-js",t)}})();
|
|
2
2
|
import { jsx as r, jsxs as N, Fragment as Te } from "react/jsx-runtime";
|
|
3
|
-
import { useState as
|
|
4
|
-
const
|
|
3
|
+
import { useState as F, useRef as Z, useEffect as G, useCallback as oe, useMemo as y, createContext as Ie, useContext as we, forwardRef as Be, createElement as ye } from "react";
|
|
4
|
+
const _e = {
|
|
5
5
|
bundleId: "_bundle_id",
|
|
6
6
|
bundleConfig: "_bundle_config",
|
|
7
|
-
bundleSource: "_bundle_source"
|
|
7
|
+
bundleSource: "_bundle_source",
|
|
8
|
+
bundleTitle: "_bundle_title"
|
|
8
9
|
};
|
|
9
10
|
async function Se(o) {
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
const m = await (await fetch(
|
|
11
|
+
const l = new URL("/api/public/bundle-config", o.apiBaseUrl);
|
|
12
|
+
l.searchParams.set("shop", o.shop);
|
|
13
|
+
const m = await (await fetch(l, {
|
|
13
14
|
method: "GET",
|
|
14
15
|
signal: o.signal,
|
|
15
16
|
headers: { "Content-Type": "application/json" }
|
|
@@ -30,125 +31,126 @@ function ge(o) {
|
|
|
30
31
|
}
|
|
31
32
|
function Qt(o) {
|
|
32
33
|
const {
|
|
33
|
-
apiBaseUrl:
|
|
34
|
-
shop:
|
|
34
|
+
apiBaseUrl: l,
|
|
35
|
+
shop: _,
|
|
35
36
|
cartAdapter: m,
|
|
36
|
-
configHandle:
|
|
37
|
+
configHandle: I = "default",
|
|
37
38
|
initialData: h,
|
|
38
|
-
configFetcher:
|
|
39
|
+
configFetcher: E,
|
|
39
40
|
children: x
|
|
40
|
-
} = o, [
|
|
41
|
+
} = o, [S, M] = F(!1), [q, J] = F(!h), [g, Q] = F(!1), [X, le] = F(null), [P, Y] = F((h == null ? void 0 : h.currencyCode) ?? null), [f, ee] = F((h == null ? void 0 : h.config) ?? null), [te, ne] = F(
|
|
41
42
|
(h == null ? void 0 : h.eligibleVariants) ?? []
|
|
42
|
-
), [
|
|
43
|
+
), [ce, me] = F(
|
|
43
44
|
() => ({ selections: {}, order: [] })
|
|
44
|
-
), he =
|
|
45
|
-
|
|
45
|
+
), he = Z(null);
|
|
46
|
+
G(() => {
|
|
46
47
|
var B;
|
|
47
48
|
if (h) return;
|
|
48
49
|
(B = he.current) == null || B.abort();
|
|
49
50
|
const d = new AbortController();
|
|
50
51
|
he.current = d;
|
|
51
|
-
const C =
|
|
52
|
-
return
|
|
53
|
-
if (!
|
|
54
|
-
|
|
52
|
+
const C = E ?? Se;
|
|
53
|
+
return J(!0), le(null), C({ apiBaseUrl: l, shop: _, signal: d.signal }).then((s) => {
|
|
54
|
+
if (!s.ok) {
|
|
55
|
+
le(s.error || "Failed to load bundle config."), ee(null), ne([]), Y(null);
|
|
55
56
|
return;
|
|
56
57
|
}
|
|
57
|
-
|
|
58
|
-
}).catch((
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
}).finally(() =>
|
|
62
|
-
}, [
|
|
63
|
-
const
|
|
58
|
+
Y(s.currencyCode ?? null), ee(s.config), ne(s.eligibleVariants ?? []);
|
|
59
|
+
}).catch((s) => {
|
|
60
|
+
const T = s instanceof Error ? s.message : "Failed to load bundle config.";
|
|
61
|
+
le(T), ee(null), ne([]), Y(null);
|
|
62
|
+
}).finally(() => J(!1)), () => d.abort();
|
|
63
|
+
}, [l, _, h, E]);
|
|
64
|
+
const se = oe(() => M(!0), []), w = oe(() => M(!1), []), $ = oe(() => M((d) => !d), []), be = oe((d, C) => {
|
|
64
65
|
const B = ge(C);
|
|
65
|
-
me((
|
|
66
|
-
const
|
|
67
|
-
let
|
|
66
|
+
me((s) => {
|
|
67
|
+
const T = s.selections[d] ?? 0, j = B - T;
|
|
68
|
+
let z;
|
|
68
69
|
if (B <= 0) {
|
|
69
|
-
const { [d]: re, ...
|
|
70
|
-
|
|
71
|
-
} else
|
|
72
|
-
let
|
|
73
|
-
if (
|
|
74
|
-
|
|
75
|
-
else if (
|
|
76
|
-
let re = -
|
|
77
|
-
const
|
|
78
|
-
for (let ae =
|
|
79
|
-
const ue =
|
|
70
|
+
const { [d]: re, ...U } = s.selections;
|
|
71
|
+
z = U;
|
|
72
|
+
} else T === B ? z = s.selections : z = { ...s.selections, [d]: B };
|
|
73
|
+
let H = s.order;
|
|
74
|
+
if (j > 0)
|
|
75
|
+
H = [...s.order, ...Array.from({ length: j }, () => d)];
|
|
76
|
+
else if (j < 0) {
|
|
77
|
+
let re = -j;
|
|
78
|
+
const U = [];
|
|
79
|
+
for (let ae = s.order.length - 1; ae >= 0; ae--) {
|
|
80
|
+
const ue = s.order[ae];
|
|
80
81
|
if (ue === d && re > 0) {
|
|
81
82
|
re--;
|
|
82
83
|
continue;
|
|
83
84
|
}
|
|
84
|
-
|
|
85
|
+
U.push(ue);
|
|
85
86
|
}
|
|
86
|
-
|
|
87
|
+
U.reverse(), H = U;
|
|
87
88
|
}
|
|
88
|
-
return
|
|
89
|
+
return z === s.selections && H === s.order ? s : { selections: z, order: H };
|
|
89
90
|
});
|
|
90
|
-
}, []),
|
|
91
|
-
const d = (
|
|
91
|
+
}, []), W = oe(() => me({ selections: {}, order: [] }), []), V = ce.selections, v = ce.order, R = y(() => Object.values(V).reduce((d, C) => d + (C || 0), 0), [V]), D = y(() => {
|
|
92
|
+
const d = (f == null ? void 0 : f.rules) ?? [], C = d.length ? Math.min(...d.map((B) => B.minBundleSize)) : 2;
|
|
92
93
|
return Number.isFinite(C) && C > 0 ? C : 2;
|
|
93
|
-
}, [
|
|
94
|
-
var
|
|
95
|
-
if (!
|
|
96
|
-
const d = ke(), C = Object.entries(
|
|
97
|
-
merchandiseId:
|
|
98
|
-
quantity:
|
|
94
|
+
}, [f]), k = y(() => !(q || g || X || !(f != null && f.isActive) || R < D), [R, f == null ? void 0 : f.isActive, X, q, D, g]), fe = oe(async () => {
|
|
95
|
+
var s;
|
|
96
|
+
if (!k || !f) return;
|
|
97
|
+
const d = ke(), C = (f.title ?? "").trim().slice(0, 255), B = Object.entries(V).map(([T, j]) => ({ merchandiseId: T, quantity: ge(j) })).filter((T) => T.quantity > 0).map((T) => ({
|
|
98
|
+
merchandiseId: T.merchandiseId,
|
|
99
|
+
quantity: T.quantity,
|
|
99
100
|
attributes: [
|
|
100
|
-
{ key:
|
|
101
|
-
{ key:
|
|
102
|
-
{ key:
|
|
101
|
+
{ key: _e.bundleId, value: d },
|
|
102
|
+
{ key: _e.bundleConfig, value: I },
|
|
103
|
+
{ key: _e.bundleSource, value: "bundle_builder" },
|
|
104
|
+
...C ? [{ key: _e.bundleTitle, value: C }] : []
|
|
103
105
|
]
|
|
104
106
|
}));
|
|
105
|
-
if (
|
|
106
|
-
|
|
107
|
+
if (B.length) {
|
|
108
|
+
Q(!0);
|
|
107
109
|
try {
|
|
108
|
-
await m.linesAdd(
|
|
110
|
+
await m.linesAdd(B), W(), w(), (s = m.openCartUI) == null || s.call(m);
|
|
109
111
|
} finally {
|
|
110
|
-
|
|
112
|
+
Q(!1);
|
|
111
113
|
}
|
|
112
114
|
}
|
|
113
|
-
}, [
|
|
115
|
+
}, [k, m, W, w, f, I, V]), ie = y(
|
|
114
116
|
() => ({
|
|
115
|
-
isOpen:
|
|
116
|
-
open:
|
|
117
|
-
close:
|
|
118
|
-
toggle:
|
|
119
|
-
loading:
|
|
117
|
+
isOpen: S,
|
|
118
|
+
open: se,
|
|
119
|
+
close: w,
|
|
120
|
+
toggle: $,
|
|
121
|
+
loading: q,
|
|
120
122
|
submitting: g,
|
|
121
|
-
error:
|
|
122
|
-
currencyCode:
|
|
123
|
-
config:
|
|
124
|
-
eligibleVariants:
|
|
125
|
-
selections:
|
|
123
|
+
error: X,
|
|
124
|
+
currencyCode: P,
|
|
125
|
+
config: f,
|
|
126
|
+
eligibleVariants: te,
|
|
127
|
+
selections: V,
|
|
126
128
|
selectionOrder: v,
|
|
127
129
|
setQuantity: be,
|
|
128
|
-
clearSelections:
|
|
129
|
-
bundleSize:
|
|
130
|
-
minRequired:
|
|
131
|
-
canSubmit:
|
|
130
|
+
clearSelections: W,
|
|
131
|
+
bundleSize: R,
|
|
132
|
+
minRequired: D,
|
|
133
|
+
canSubmit: k,
|
|
132
134
|
submit: fe
|
|
133
135
|
}),
|
|
134
136
|
[
|
|
137
|
+
S,
|
|
138
|
+
se,
|
|
135
139
|
w,
|
|
136
|
-
le,
|
|
137
|
-
I,
|
|
138
|
-
A,
|
|
139
|
-
M,
|
|
140
|
-
g,
|
|
141
|
-
J,
|
|
142
|
-
F,
|
|
143
|
-
_,
|
|
144
|
-
ee,
|
|
145
|
-
W,
|
|
146
|
-
v,
|
|
147
|
-
be,
|
|
148
140
|
$,
|
|
141
|
+
q,
|
|
142
|
+
g,
|
|
143
|
+
X,
|
|
149
144
|
P,
|
|
145
|
+
f,
|
|
146
|
+
te,
|
|
150
147
|
V,
|
|
151
|
-
|
|
148
|
+
v,
|
|
149
|
+
be,
|
|
150
|
+
W,
|
|
151
|
+
R,
|
|
152
|
+
D,
|
|
153
|
+
k,
|
|
152
154
|
fe
|
|
153
155
|
]
|
|
154
156
|
);
|
|
@@ -161,19 +163,19 @@ function xe() {
|
|
|
161
163
|
return o;
|
|
162
164
|
}
|
|
163
165
|
function Ht() {
|
|
164
|
-
const { isOpen: o, open:
|
|
165
|
-
return { isOpen: o, open:
|
|
166
|
+
const { isOpen: o, open: l, close: _, toggle: m } = xe();
|
|
167
|
+
return { isOpen: o, open: l, close: _, toggle: m };
|
|
166
168
|
}
|
|
167
169
|
const Fe = "_button_18rtl_1", Pe = {
|
|
168
170
|
button: Fe
|
|
169
171
|
};
|
|
170
172
|
function Kt(o) {
|
|
171
|
-
const { toggle:
|
|
173
|
+
const { toggle: l } = xe();
|
|
172
174
|
return /* @__PURE__ */ r(
|
|
173
175
|
"button",
|
|
174
176
|
{
|
|
175
177
|
type: "button",
|
|
176
|
-
onClick:
|
|
178
|
+
onClick: l,
|
|
177
179
|
className: [Pe.button, o.className].filter(Boolean).join(" "),
|
|
178
180
|
children: o.children ?? "Build a bundle"
|
|
179
181
|
}
|
|
@@ -187,13 +189,13 @@ function Kt(o) {
|
|
|
187
189
|
*/
|
|
188
190
|
const Re = (o) => o.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase(), Oe = (o) => o.replace(
|
|
189
191
|
/^([A-Z])|[\s-_]+(\w)/g,
|
|
190
|
-
(
|
|
192
|
+
(l, _, m) => m ? m.toUpperCase() : _.toLowerCase()
|
|
191
193
|
), ve = (o) => {
|
|
192
|
-
const
|
|
193
|
-
return
|
|
194
|
-
}, Ce = (...o) => o.filter((
|
|
195
|
-
for (const
|
|
196
|
-
if (
|
|
194
|
+
const l = Oe(o);
|
|
195
|
+
return l.charAt(0).toUpperCase() + l.slice(1);
|
|
196
|
+
}, Ce = (...o) => o.filter((l, _, m) => !!l && l.trim() !== "" && m.indexOf(l) === _).join(" ").trim(), Le = (o) => {
|
|
197
|
+
for (const l in o)
|
|
198
|
+
if (l.startsWith("aria-") || l === "role" || l === "title")
|
|
197
199
|
return !0;
|
|
198
200
|
};
|
|
199
201
|
/**
|
|
@@ -222,28 +224,28 @@ var Me = {
|
|
|
222
224
|
const qe = Be(
|
|
223
225
|
({
|
|
224
226
|
color: o = "currentColor",
|
|
225
|
-
size:
|
|
226
|
-
strokeWidth:
|
|
227
|
+
size: l = 24,
|
|
228
|
+
strokeWidth: _ = 2,
|
|
227
229
|
absoluteStrokeWidth: m,
|
|
228
|
-
className:
|
|
230
|
+
className: I = "",
|
|
229
231
|
children: h,
|
|
230
|
-
iconNode:
|
|
232
|
+
iconNode: E,
|
|
231
233
|
...x
|
|
232
|
-
},
|
|
234
|
+
}, S) => ye(
|
|
233
235
|
"svg",
|
|
234
236
|
{
|
|
235
|
-
ref:
|
|
237
|
+
ref: S,
|
|
236
238
|
...Me,
|
|
237
|
-
width:
|
|
238
|
-
height:
|
|
239
|
+
width: l,
|
|
240
|
+
height: l,
|
|
239
241
|
stroke: o,
|
|
240
|
-
strokeWidth: m ? Number(
|
|
241
|
-
className: Ce("lucide",
|
|
242
|
+
strokeWidth: m ? Number(_) * 24 / Number(l) : _,
|
|
243
|
+
className: Ce("lucide", I),
|
|
242
244
|
...!h && !Le(x) && { "aria-hidden": "true" },
|
|
243
245
|
...x
|
|
244
246
|
},
|
|
245
247
|
[
|
|
246
|
-
...
|
|
248
|
+
...E.map(([M, q]) => ye(M, q)),
|
|
247
249
|
...Array.isArray(h) ? h : [h]
|
|
248
250
|
]
|
|
249
251
|
)
|
|
@@ -254,20 +256,20 @@ const qe = Be(
|
|
|
254
256
|
* This source code is licensed under the ISC license.
|
|
255
257
|
* See the LICENSE file in the root directory of this source tree.
|
|
256
258
|
*/
|
|
257
|
-
const Ae = (o,
|
|
258
|
-
const
|
|
259
|
-
({ className: m, ...
|
|
259
|
+
const Ae = (o, l) => {
|
|
260
|
+
const _ = Be(
|
|
261
|
+
({ className: m, ...I }, h) => ye(qe, {
|
|
260
262
|
ref: h,
|
|
261
|
-
iconNode:
|
|
263
|
+
iconNode: l,
|
|
262
264
|
className: Ce(
|
|
263
265
|
`lucide-${Re(ve(o))}`,
|
|
264
266
|
`lucide-${o}`,
|
|
265
267
|
m
|
|
266
268
|
),
|
|
267
|
-
...
|
|
269
|
+
...I
|
|
268
270
|
})
|
|
269
271
|
);
|
|
270
|
-
return
|
|
272
|
+
return _.displayName = ve(o), _;
|
|
271
273
|
};
|
|
272
274
|
/**
|
|
273
275
|
* @license lucide-react v0.515.0 - ISC
|
|
@@ -278,7 +280,7 @@ const Ae = (o, c) => {
|
|
|
278
280
|
const $e = [
|
|
279
281
|
["path", { d: "m21 21-4.34-4.34", key: "14j7rj" }],
|
|
280
282
|
["circle", { cx: "11", cy: "11", r: "8", key: "4ej97u" }]
|
|
281
|
-
], We = Ae("search", $e), Ve = "_backdrop_1ctfr_1", De = "_backdropOpen_1ctfr_14", je = "_backdropClosed_1ctfr_18", ze = "_panel_1ctfr_22", Ue = "_panelOpen_1ctfr_42", Ee = "_panelClosed_1ctfr_46", Qe = "_header_1ctfr_81", He = "_headerCenter_1ctfr_90", Ke = "_title_1ctfr_98", Ze = "_searchIconButton_1ctfr_107", Ge = "_headerTitleWrap_1ctfr_129", Je = "_headerSearchWrap_1ctfr_133", Xe = "_headerSearchOpen_1ctfr_145", Ye = "_searchBar_1ctfr_157", et = "_searchInput_1ctfr_169", tt = "_searchClearButton_1ctfr_190", nt = "_closeButton_1ctfr_212", rt = "_body_1ctfr_245", at = "_muted_1ctfr_250", ot = "_error_1ctfr_255",
|
|
283
|
+
], We = Ae("search", $e), Ve = "_backdrop_1ctfr_1", De = "_backdropOpen_1ctfr_14", je = "_backdropClosed_1ctfr_18", ze = "_panel_1ctfr_22", Ue = "_panelOpen_1ctfr_42", Ee = "_panelClosed_1ctfr_46", Qe = "_header_1ctfr_81", He = "_headerCenter_1ctfr_90", Ke = "_title_1ctfr_98", Ze = "_searchIconButton_1ctfr_107", Ge = "_headerTitleWrap_1ctfr_129", Je = "_headerSearchWrap_1ctfr_133", Xe = "_headerSearchOpen_1ctfr_145", Ye = "_searchBar_1ctfr_157", et = "_searchInput_1ctfr_169", tt = "_searchClearButton_1ctfr_190", nt = "_closeButton_1ctfr_212", rt = "_body_1ctfr_245", at = "_muted_1ctfr_250", ot = "_error_1ctfr_255", lt = "_variants_1ctfr_260", ct = "_variantList_1ctfr_264", st = "_variantRow_1ctfr_272", it = "_variantLeft_1ctfr_280", ut = "_addToBundleButton_1ctfr_287", dt = "_variantThumb_1ctfr_315", mt = "_variantThumbImg_1ctfr_325", ht = "_variantThumbFallback_1ctfr_332", bt = "_variantInfo_1ctfr_342", ft = "_variantName_1ctfr_346", _t = "_variantMeta_1ctfr_355", pt = "_variantPriceRow_1ctfr_363", yt = "_variantCompareAt_1ctfr_370", xt = "_variantPrice_1ctfr_363", gt = "_qtyControls_1ctfr_381", vt = "_qtyButton_1ctfr_387", Bt = "_qtyValue_1ctfr_412", Nt = "_footer_1ctfr_419", Ct = "_boxSummaryWindow_1ctfr_426", Tt = "_boxSummaryRow_1ctfr_443", It = "_boxSlot_1ctfr_451", wt = "_boxItem_1ctfr_459", St = "_boxItemClickable_1ctfr_471", kt = "_boxThresholdLabel_1ctfr_480", Ft = "_boxItemPlaceholder_1ctfr_491", Pt = "_boxItemFilled_1ctfr_497", Rt = "_boxItemThreshold_1ctfr_503", Ot = "_boxItemDiscountText_1ctfr_511", Lt = "_boxItemPlus_1ctfr_519", Mt = "_boxItemImage_1ctfr_526", qt = "_boxItemFallback_1ctfr_533", At = "_cta_1ctfr_544", $t = "_ctaTotals_1ctfr_556", Wt = "_ctaDiscountBadge_1ctfr_564", Vt = "_ctaTotalsWrap_1ctfr_578", Dt = "_ctaTotalsWrapVisible_1ctfr_591", jt = "_ctaTotalsStrike_1ctfr_598", zt = "_ctaTotalsPrice_1ctfr_605", n = {
|
|
282
284
|
backdrop: Ve,
|
|
283
285
|
backdropOpen: De,
|
|
284
286
|
backdropClosed: je,
|
|
@@ -299,9 +301,9 @@ const $e = [
|
|
|
299
301
|
body: rt,
|
|
300
302
|
muted: at,
|
|
301
303
|
error: ot,
|
|
302
|
-
variants:
|
|
303
|
-
variantList:
|
|
304
|
-
variantRow:
|
|
304
|
+
variants: lt,
|
|
305
|
+
variantList: ct,
|
|
306
|
+
variantRow: st,
|
|
305
307
|
variantLeft: it,
|
|
306
308
|
addToBundleButton: ut,
|
|
307
309
|
variantThumb: dt,
|
|
@@ -341,88 +343,88 @@ const $e = [
|
|
|
341
343
|
function Zt(o) {
|
|
342
344
|
var ue;
|
|
343
345
|
const {
|
|
344
|
-
isOpen:
|
|
345
|
-
close:
|
|
346
|
+
isOpen: l,
|
|
347
|
+
close: _,
|
|
346
348
|
loading: m,
|
|
347
|
-
submitting:
|
|
349
|
+
submitting: I,
|
|
348
350
|
error: h,
|
|
349
|
-
currencyCode:
|
|
351
|
+
currencyCode: E,
|
|
350
352
|
config: x,
|
|
351
|
-
eligibleVariants:
|
|
352
|
-
selections:
|
|
353
|
-
selectionOrder:
|
|
354
|
-
setQuantity:
|
|
353
|
+
eligibleVariants: S,
|
|
354
|
+
selections: M,
|
|
355
|
+
selectionOrder: q,
|
|
356
|
+
setQuantity: J,
|
|
355
357
|
bundleSize: g,
|
|
356
|
-
minRequired:
|
|
357
|
-
canSubmit:
|
|
358
|
-
submit:
|
|
359
|
-
} = xe(), [
|
|
358
|
+
minRequired: Q,
|
|
359
|
+
canSubmit: X,
|
|
360
|
+
submit: le
|
|
361
|
+
} = xe(), [P, Y] = F(!1), [f, ee] = F(""), te = Z(null), ne = (e) => {
|
|
360
362
|
const t = (e ?? []).filter((a) => {
|
|
361
363
|
var b, u;
|
|
362
|
-
const i = (b = a == null ? void 0 : a.name) == null ? void 0 : b.trim(),
|
|
363
|
-
return !(!i || !
|
|
364
|
+
const i = (b = a == null ? void 0 : a.name) == null ? void 0 : b.trim(), c = (u = a == null ? void 0 : a.value) == null ? void 0 : u.trim();
|
|
365
|
+
return !(!i || !c || i.toLowerCase() === "title");
|
|
364
366
|
});
|
|
365
367
|
return t.length ? t.map((a) => `${a.name}: ${a.value}`).join(" · ") : null;
|
|
366
|
-
},
|
|
368
|
+
}, ce = (e) => {
|
|
367
369
|
var t;
|
|
368
370
|
return ((t = e.product) == null ? void 0 : t.title) ?? e.displayName ?? e.title;
|
|
369
371
|
}, me = (e) => {
|
|
370
|
-
const t =
|
|
372
|
+
const t = ce(e), a = ne(e.selectedOptions);
|
|
371
373
|
return [t, a].filter(Boolean).join(" — ");
|
|
372
|
-
}, [he,
|
|
374
|
+
}, [he, se] = F(l), w = Z(null), $ = (e) => {
|
|
373
375
|
const t = Number(e);
|
|
374
376
|
if (!Number.isFinite(t)) return e;
|
|
375
|
-
if (
|
|
377
|
+
if (E)
|
|
376
378
|
try {
|
|
377
|
-
return new Intl.NumberFormat(void 0, { style: "currency", currency:
|
|
379
|
+
return new Intl.NumberFormat(void 0, { style: "currency", currency: E }).format(t);
|
|
378
380
|
} catch {
|
|
379
381
|
}
|
|
380
382
|
return `$${t.toFixed(2)}`;
|
|
381
|
-
}, be = ((ue = x == null ? void 0 : x.title) == null ? void 0 : ue.trim()) || "Build your bundle",
|
|
382
|
-
const e =
|
|
383
|
-
if (!e) return
|
|
383
|
+
}, be = ((ue = x == null ? void 0 : x.title) == null ? void 0 : ue.trim()) || "Build your bundle", W = y(() => [...S].sort((e, t) => e.displayName.localeCompare(t.displayName)), [S]), V = y(() => {
|
|
384
|
+
const e = f.trim().toLowerCase();
|
|
385
|
+
if (!e) return W;
|
|
384
386
|
const t = e.split(/\s+/).filter(Boolean), a = (i) => {
|
|
385
387
|
var u;
|
|
386
|
-
const
|
|
387
|
-
|
|
388
|
+
const c = [];
|
|
389
|
+
c.push(i.displayName), (u = i.product) != null && u.title && c.push(i.product.title);
|
|
388
390
|
for (const p of i.selectedOptions ?? [])
|
|
389
|
-
|
|
390
|
-
const b =
|
|
391
|
+
c.push(p.name), c.push(p.value);
|
|
392
|
+
const b = c.join(" ").toLowerCase();
|
|
391
393
|
return t.every((p) => b.includes(p));
|
|
392
394
|
};
|
|
393
|
-
return
|
|
394
|
-
}, [
|
|
395
|
+
return W.filter(a);
|
|
396
|
+
}, [f, W]), v = y(() => [...(x == null ? void 0 : x.rules) ?? []].sort((e, t) => e.minBundleSize - t.minBundleSize), [x == null ? void 0 : x.rules]), R = y(() => Math.max(0, Q - g), [g, Q]), D = y(() => {
|
|
395
397
|
let e = null;
|
|
396
398
|
for (const t of v)
|
|
397
399
|
g >= t.minBundleSize && (e = t);
|
|
398
400
|
return e;
|
|
399
|
-
}, [g, v]),
|
|
400
|
-
if (!
|
|
401
|
-
const e = Number.parseFloat(
|
|
401
|
+
}, [g, v]), k = y(() => {
|
|
402
|
+
if (!D) return null;
|
|
403
|
+
const e = Number.parseFloat(D.discountPercent);
|
|
402
404
|
return !Number.isFinite(e) || e <= 0 ? null : e;
|
|
403
|
-
}, [
|
|
405
|
+
}, [D]), fe = y(() => {
|
|
404
406
|
const e = v[0];
|
|
405
407
|
if (!e) return null;
|
|
406
408
|
const t = Number.parseFloat(e.discountPercent);
|
|
407
409
|
return !Number.isFinite(t) || t <= 0 ? null : t;
|
|
408
|
-
}, [v]), ie =
|
|
409
|
-
const e = new Map(
|
|
410
|
+
}, [v]), ie = k ?? fe, d = y(() => {
|
|
411
|
+
const e = new Map(S.map((a) => [a.id, a]));
|
|
410
412
|
let t = 0;
|
|
411
|
-
for (const [a, i] of Object.entries(
|
|
412
|
-
const
|
|
413
|
-
if (
|
|
413
|
+
for (const [a, i] of Object.entries(M)) {
|
|
414
|
+
const c = i ?? 0;
|
|
415
|
+
if (c <= 0) continue;
|
|
414
416
|
const b = e.get(a), u = Number(b == null ? void 0 : b.price);
|
|
415
|
-
Number.isFinite(u) && (t += u *
|
|
417
|
+
Number.isFinite(u) && (t += u * c);
|
|
416
418
|
}
|
|
417
419
|
return Math.round(t * 100) / 100;
|
|
418
|
-
}, [
|
|
419
|
-
if (!
|
|
420
|
-
const e = d * (1 -
|
|
420
|
+
}, [S, M]), C = y(() => {
|
|
421
|
+
if (!k) return d;
|
|
422
|
+
const e = d * (1 - k / 100);
|
|
421
423
|
return Math.round(e * 100) / 100;
|
|
422
|
-
}, [
|
|
423
|
-
const e = new Map(
|
|
424
|
-
return
|
|
425
|
-
}, [
|
|
424
|
+
}, [k, d]), B = y(() => v.length ? Math.max(...v.map((e) => e.minBundleSize)) : 0, [v]), s = y(() => {
|
|
425
|
+
const e = new Map(S.map((t) => [t.id, t]));
|
|
426
|
+
return q.map((t) => e.get(t)).filter((t) => !!t);
|
|
427
|
+
}, [S, q]), T = y(() => {
|
|
426
428
|
var t;
|
|
427
429
|
const e = /* @__PURE__ */ new Map();
|
|
428
430
|
for (const a of v) {
|
|
@@ -434,101 +436,101 @@ function Zt(o) {
|
|
|
434
436
|
});
|
|
435
437
|
}
|
|
436
438
|
return e;
|
|
437
|
-
}, [v]),
|
|
438
|
-
const t =
|
|
439
|
+
}, [v]), j = y(() => Math.max(B || Q, s.length), [s.length, B, Q]), z = Z(null), H = Z(null), re = Z(null), U = Z(g), ae = (e) => {
|
|
440
|
+
const t = H.current;
|
|
439
441
|
if (!t) return;
|
|
440
442
|
const a = t.querySelector(`[data-variant-row="${e}"]`);
|
|
441
443
|
if (!a) return;
|
|
442
|
-
const i = t.getBoundingClientRect(),
|
|
443
|
-
if (
|
|
444
|
-
const p = Math.max(0, t.scrollHeight - t.clientHeight),
|
|
445
|
-
t.scrollTo({ top:
|
|
444
|
+
const i = t.getBoundingClientRect(), c = a.getBoundingClientRect(), b = 8;
|
|
445
|
+
if (c.top >= i.top + b && c.bottom <= i.bottom - b) return;
|
|
446
|
+
const p = Math.max(0, t.scrollHeight - t.clientHeight), O = c.top - i.top + c.height / 2, L = t.scrollTop + O - t.clientHeight / 2, A = Math.min(p, Math.max(0, L));
|
|
447
|
+
t.scrollTo({ top: A, behavior: "smooth" });
|
|
446
448
|
};
|
|
447
|
-
return
|
|
448
|
-
if (!
|
|
449
|
+
return G(() => {
|
|
450
|
+
if (!l) return;
|
|
449
451
|
const e = (t) => {
|
|
450
|
-
t.key === "Escape" &&
|
|
452
|
+
t.key === "Escape" && _();
|
|
451
453
|
};
|
|
452
454
|
return window.addEventListener("keydown", e), () => window.removeEventListener("keydown", e);
|
|
453
|
-
}, [
|
|
454
|
-
if (
|
|
455
|
-
|
|
455
|
+
}, [_, l]), G(() => {
|
|
456
|
+
if (w.current != null && (window.clearTimeout(w.current), w.current = null), l) {
|
|
457
|
+
se(!0);
|
|
456
458
|
return;
|
|
457
459
|
}
|
|
458
|
-
|
|
459
|
-
|
|
460
|
+
w.current = window.setTimeout(() => {
|
|
461
|
+
se(!1), w.current = null;
|
|
460
462
|
}, 220);
|
|
461
|
-
}, [
|
|
462
|
-
|
|
463
|
-
}, []),
|
|
464
|
-
if (!
|
|
463
|
+
}, [l]), G(() => () => {
|
|
464
|
+
w.current != null && window.clearTimeout(w.current);
|
|
465
|
+
}, []), G(() => {
|
|
466
|
+
if (!l || !P) return;
|
|
465
467
|
const e = requestAnimationFrame(() => {
|
|
466
468
|
var t;
|
|
467
|
-
return (t =
|
|
469
|
+
return (t = te.current) == null ? void 0 : t.focus();
|
|
468
470
|
});
|
|
469
471
|
return () => cancelAnimationFrame(e);
|
|
470
|
-
}, [
|
|
471
|
-
const e =
|
|
472
|
-
if (
|
|
472
|
+
}, [l, P]), G(() => {
|
|
473
|
+
const e = U.current;
|
|
474
|
+
if (U.current = g, g <= e) return;
|
|
473
475
|
const t = re.current;
|
|
474
476
|
if (!t) return;
|
|
475
|
-
const a = v.some((u) => u.minBundleSize === g), i = v.find((u) => u.minBundleSize > g),
|
|
476
|
-
if (
|
|
477
|
+
const a = v.some((u) => u.minBundleSize === g), i = v.find((u) => u.minBundleSize > g), c = i && a ? i.minBundleSize - 1 : i ? null : g - 1;
|
|
478
|
+
if (c == null || c < 0) return;
|
|
477
479
|
const b = requestAnimationFrame(() => {
|
|
478
|
-
const u = t.querySelector(`[data-box-slot="${
|
|
480
|
+
const u = t.querySelector(`[data-box-slot="${c}"]`);
|
|
479
481
|
if (!u) return;
|
|
480
|
-
const p = t.getBoundingClientRect(),
|
|
481
|
-
if (
|
|
482
|
-
const
|
|
483
|
-
t.scrollTo({ left:
|
|
482
|
+
const p = t.getBoundingClientRect(), L = u.getBoundingClientRect().right - p.right;
|
|
483
|
+
if (L <= 1) return;
|
|
484
|
+
const A = Math.max(0, t.scrollWidth - t.clientWidth), K = Math.min(A, Math.max(0, t.scrollLeft + L));
|
|
485
|
+
t.scrollTo({ left: K, behavior: "smooth" });
|
|
484
486
|
});
|
|
485
487
|
return () => cancelAnimationFrame(b);
|
|
486
|
-
}, [g, v]),
|
|
488
|
+
}, [g, v]), G(() => {
|
|
487
489
|
var e;
|
|
488
|
-
|
|
489
|
-
}, [
|
|
490
|
+
l && ((e = z.current) == null || e.focus());
|
|
491
|
+
}, [l]), he ? /* @__PURE__ */ r(
|
|
490
492
|
"div",
|
|
491
493
|
{
|
|
492
494
|
role: "dialog",
|
|
493
495
|
"aria-modal": "true",
|
|
494
496
|
"aria-label": "Bundle builder",
|
|
495
|
-
className: [n.backdrop,
|
|
497
|
+
className: [n.backdrop, l ? n.backdropOpen : n.backdropClosed, o.className].filter(Boolean).join(" "),
|
|
496
498
|
onMouseDown: (e) => {
|
|
497
|
-
e.target === e.currentTarget &&
|
|
499
|
+
e.target === e.currentTarget && _();
|
|
498
500
|
},
|
|
499
|
-
children: /* @__PURE__ */ N("aside", { ref:
|
|
500
|
-
/* @__PURE__ */ N("header", { className: [n.header,
|
|
501
|
+
children: /* @__PURE__ */ N("aside", { ref: z, className: [n.panel, l ? n.panelOpen : n.panelClosed].filter(Boolean).join(" "), tabIndex: -1, children: [
|
|
502
|
+
/* @__PURE__ */ N("header", { className: [n.header, P ? n.headerSearchOpen : null].filter(Boolean).join(" "), children: [
|
|
501
503
|
/* @__PURE__ */ r(
|
|
502
504
|
"button",
|
|
503
505
|
{
|
|
504
506
|
type: "button",
|
|
505
507
|
className: n.searchIconButton,
|
|
506
|
-
"aria-label":
|
|
507
|
-
"aria-expanded":
|
|
508
|
+
"aria-label": P ? "Search (expanded)" : "Search",
|
|
509
|
+
"aria-expanded": P,
|
|
508
510
|
onClick: () => {
|
|
509
|
-
|
|
511
|
+
Y(!0);
|
|
510
512
|
},
|
|
511
513
|
children: /* @__PURE__ */ r(We, { size: 18, "aria-hidden": "true" })
|
|
512
514
|
}
|
|
513
515
|
),
|
|
514
516
|
/* @__PURE__ */ N("div", { className: n.headerCenter, children: [
|
|
515
|
-
/* @__PURE__ */ r("div", { className: n.headerTitleWrap, "aria-hidden":
|
|
516
|
-
/* @__PURE__ */ r("div", { className: n.headerSearchWrap, "aria-hidden": !
|
|
517
|
+
/* @__PURE__ */ r("div", { className: n.headerTitleWrap, "aria-hidden": P, children: /* @__PURE__ */ r("h2", { className: n.title, children: be }) }),
|
|
518
|
+
/* @__PURE__ */ r("div", { className: n.headerSearchWrap, "aria-hidden": !P, children: /* @__PURE__ */ N("div", { className: n.searchBar, children: [
|
|
517
519
|
/* @__PURE__ */ r(
|
|
518
520
|
"input",
|
|
519
521
|
{
|
|
520
|
-
ref:
|
|
522
|
+
ref: te,
|
|
521
523
|
className: n.searchInput,
|
|
522
524
|
type: "search",
|
|
523
|
-
value:
|
|
525
|
+
value: f,
|
|
524
526
|
placeholder: "Search",
|
|
525
|
-
onChange: (e) =>
|
|
527
|
+
onChange: (e) => ee(e.target.value),
|
|
526
528
|
onBlur: () => {
|
|
527
|
-
|
|
529
|
+
f.trim() === "" && Y(!1);
|
|
528
530
|
}
|
|
529
531
|
}
|
|
530
532
|
),
|
|
531
|
-
|
|
533
|
+
f.trim() ? /* @__PURE__ */ r(
|
|
532
534
|
"button",
|
|
533
535
|
{
|
|
534
536
|
type: "button",
|
|
@@ -538,7 +540,7 @@ function Zt(o) {
|
|
|
538
540
|
},
|
|
539
541
|
onClick: () => {
|
|
540
542
|
var e;
|
|
541
|
-
|
|
543
|
+
ee(""), (e = te.current) == null || e.focus();
|
|
542
544
|
},
|
|
543
545
|
"aria-label": "Clear search",
|
|
544
546
|
children: "Clear"
|
|
@@ -546,33 +548,33 @@ function Zt(o) {
|
|
|
546
548
|
) : null
|
|
547
549
|
] }) })
|
|
548
550
|
] }),
|
|
549
|
-
/* @__PURE__ */ r("button", { type: "button", onClick:
|
|
551
|
+
/* @__PURE__ */ r("button", { type: "button", onClick: _, disabled: I, className: n.closeButton, "aria-label": "Close", children: "×" })
|
|
550
552
|
] }),
|
|
551
|
-
/* @__PURE__ */ N("div", { className: n.body, ref:
|
|
553
|
+
/* @__PURE__ */ N("div", { className: n.body, ref: H, children: [
|
|
552
554
|
m ? /* @__PURE__ */ r("p", { className: n.muted, children: "Loading…" }) : null,
|
|
553
555
|
h ? /* @__PURE__ */ r("p", { className: n.error, children: h }) : null,
|
|
554
556
|
!m && x && !x.isActive ? /* @__PURE__ */ r("p", { className: n.error, children: "Bundles are not active." }) : null,
|
|
555
|
-
/* @__PURE__ */ r("div", { className: n.variants, children: /* @__PURE__ */ r("ul", { className: n.variantList, children:
|
|
556
|
-
var
|
|
557
|
-
const t =
|
|
557
|
+
/* @__PURE__ */ r("div", { className: n.variants, children: /* @__PURE__ */ r("ul", { className: n.variantList, children: V.map((e) => {
|
|
558
|
+
var L, A, K, de;
|
|
559
|
+
const t = M[e.id] ?? 0, a = ce(e), i = ne(e.selectedOptions), c = me(e), b = ie, u = Number(e.price), p = b != null && Number.isFinite(b) && b > 0 && Number.isFinite(u), O = p ? Math.round(u * (1 - b / 100) * 100) / 100 : null;
|
|
558
560
|
return /* @__PURE__ */ N("li", { className: n.variantRow, "data-variant-row": e.id, children: [
|
|
559
561
|
/* @__PURE__ */ N("div", { className: n.variantLeft, children: [
|
|
560
|
-
/* @__PURE__ */ r("div", { className: n.variantThumb, "aria-hidden": "true", children: (
|
|
562
|
+
/* @__PURE__ */ r("div", { className: n.variantThumb, "aria-hidden": "true", children: (L = e.image) != null && L.url ? /* @__PURE__ */ r(
|
|
561
563
|
"img",
|
|
562
564
|
{
|
|
563
565
|
className: n.variantThumbImg,
|
|
564
566
|
src: e.image.url,
|
|
565
|
-
alt: e.image.altText ??
|
|
567
|
+
alt: e.image.altText ?? c,
|
|
566
568
|
loading: "lazy"
|
|
567
569
|
}
|
|
568
|
-
) : /* @__PURE__ */ r("div", { className: n.variantThumbFallback, children: ((de = (
|
|
570
|
+
) : /* @__PURE__ */ r("div", { className: n.variantThumbFallback, children: ((de = (K = (A = e.product) == null ? void 0 : A.title) == null ? void 0 : K.slice(0, 1)) == null ? void 0 : de.toUpperCase()) ?? "•" }) }),
|
|
569
571
|
/* @__PURE__ */ N("div", { className: n.variantInfo, children: [
|
|
570
572
|
/* @__PURE__ */ r("div", { className: n.variantName, children: a }),
|
|
571
573
|
i ? /* @__PURE__ */ r("div", { className: n.variantMeta, children: i }) : null,
|
|
572
574
|
/* @__PURE__ */ N("div", { className: n.variantPriceRow, children: [
|
|
573
|
-
p ? /* @__PURE__ */ r("span", { className: n.variantCompareAt, children:
|
|
574
|
-
/* @__PURE__ */ r("span", { className: n.variantPrice, children:
|
|
575
|
-
|
|
575
|
+
p ? /* @__PURE__ */ r("span", { className: n.variantCompareAt, children: $(Number.isFinite(u) ? u.toFixed(2) : e.price) }) : null,
|
|
576
|
+
/* @__PURE__ */ r("span", { className: n.variantPrice, children: $(
|
|
577
|
+
O != null ? O.toFixed(2) : Number.isFinite(u) ? u.toFixed(2) : e.price
|
|
576
578
|
) })
|
|
577
579
|
] })
|
|
578
580
|
] })
|
|
@@ -581,10 +583,10 @@ function Zt(o) {
|
|
|
581
583
|
"button",
|
|
582
584
|
{
|
|
583
585
|
type: "button",
|
|
584
|
-
onClick: () =>
|
|
585
|
-
disabled:
|
|
586
|
+
onClick: () => J(e.id, 1),
|
|
587
|
+
disabled: I,
|
|
586
588
|
className: n.addToBundleButton,
|
|
587
|
-
"aria-label": `Add ${
|
|
589
|
+
"aria-label": `Add ${c} to bundle`,
|
|
588
590
|
children: "Add"
|
|
589
591
|
}
|
|
590
592
|
) : /* @__PURE__ */ N("div", { className: n.qtyControls, children: [
|
|
@@ -592,10 +594,10 @@ function Zt(o) {
|
|
|
592
594
|
"button",
|
|
593
595
|
{
|
|
594
596
|
type: "button",
|
|
595
|
-
onClick: () =>
|
|
596
|
-
disabled:
|
|
597
|
+
onClick: () => J(e.id, t - 1),
|
|
598
|
+
disabled: I || t <= 0,
|
|
597
599
|
className: n.qtyButton,
|
|
598
|
-
"aria-label": `Decrease ${
|
|
600
|
+
"aria-label": `Decrease ${c}`,
|
|
599
601
|
children: "−"
|
|
600
602
|
}
|
|
601
603
|
),
|
|
@@ -604,10 +606,10 @@ function Zt(o) {
|
|
|
604
606
|
"button",
|
|
605
607
|
{
|
|
606
608
|
type: "button",
|
|
607
|
-
onClick: () =>
|
|
608
|
-
disabled:
|
|
609
|
+
onClick: () => J(e.id, t + 1),
|
|
610
|
+
disabled: I,
|
|
609
611
|
className: n.qtyButton,
|
|
610
|
-
"aria-label": `Increase ${
|
|
612
|
+
"aria-label": `Increase ${c}`,
|
|
611
613
|
children: "+"
|
|
612
614
|
}
|
|
613
615
|
)
|
|
@@ -616,28 +618,28 @@ function Zt(o) {
|
|
|
616
618
|
}) }) })
|
|
617
619
|
] }),
|
|
618
620
|
/* @__PURE__ */ N("footer", { className: n.footer, children: [
|
|
619
|
-
/* @__PURE__ */ r("div", { className: n.boxSummaryWindow, ref: re, children: /* @__PURE__ */ r("div", { className: n.boxSummaryRow, "aria-label": "Bundle box summary", children: Array.from({ length:
|
|
620
|
-
var
|
|
621
|
-
const a =
|
|
621
|
+
/* @__PURE__ */ r("div", { className: n.boxSummaryWindow, ref: re, children: /* @__PURE__ */ r("div", { className: n.boxSummaryRow, "aria-label": "Bundle box summary", children: Array.from({ length: j }).map((e, t) => {
|
|
622
|
+
var L, A, K, de;
|
|
623
|
+
const a = s[t], i = T.get(t), c = !!a, b = !!i, u = b && !c, p = i ? `${i.discountPercent}% off` : null, O = c ? a.displayName : `Slot ${t + 1}`;
|
|
622
624
|
return /* @__PURE__ */ N("div", { "data-box-slot": t, className: n.boxSlot, children: [
|
|
623
625
|
/* @__PURE__ */ r(
|
|
624
626
|
"div",
|
|
625
627
|
{
|
|
626
628
|
className: [
|
|
627
629
|
n.boxItem,
|
|
628
|
-
|
|
630
|
+
c ? n.boxItemFilled : n.boxItemPlaceholder,
|
|
629
631
|
b ? n.boxItemThreshold : null,
|
|
630
|
-
|
|
632
|
+
c ? n.boxItemClickable : null
|
|
631
633
|
].filter(Boolean).join(" "),
|
|
632
|
-
role:
|
|
633
|
-
tabIndex:
|
|
634
|
-
onClick:
|
|
635
|
-
onKeyDown:
|
|
636
|
-
(
|
|
634
|
+
role: c ? "button" : void 0,
|
|
635
|
+
tabIndex: c ? 0 : void 0,
|
|
636
|
+
onClick: c ? () => ae(a.id) : void 0,
|
|
637
|
+
onKeyDown: c ? (pe) => {
|
|
638
|
+
(pe.key === "Enter" || pe.key === " ") && (pe.preventDefault(), ae(a.id));
|
|
637
639
|
} : void 0,
|
|
638
|
-
"aria-label": u && p ? `${
|
|
639
|
-
title: u && p ? `${
|
|
640
|
-
children:
|
|
640
|
+
"aria-label": u && p ? `${O}. Unlocks ${p}.` : O,
|
|
641
|
+
title: u && p ? `${O} • Unlocks ${p}` : O,
|
|
642
|
+
children: c ? (L = a.image) != null && L.url ? /* @__PURE__ */ r(
|
|
641
643
|
"img",
|
|
642
644
|
{
|
|
643
645
|
className: n.boxItemImage,
|
|
@@ -645,7 +647,7 @@ function Zt(o) {
|
|
|
645
647
|
alt: a.image.altText ?? a.displayName,
|
|
646
648
|
loading: "lazy"
|
|
647
649
|
}
|
|
648
|
-
) : /* @__PURE__ */ r("div", { className: n.boxItemFallback, "aria-hidden": "true", children: ((de = (
|
|
650
|
+
) : /* @__PURE__ */ r("div", { className: n.boxItemFallback, "aria-hidden": "true", children: ((de = (K = (A = a.product) == null ? void 0 : A.title) == null ? void 0 : K.slice(0, 1)) == null ? void 0 : de.toUpperCase()) ?? "•" }) : u && p ? /* @__PURE__ */ r("div", { className: n.boxItemDiscountText, children: p }) : /* @__PURE__ */ r("div", { className: n.boxItemPlus, "aria-hidden": "true", children: "+" })
|
|
649
651
|
}
|
|
650
652
|
),
|
|
651
653
|
b ? /* @__PURE__ */ r("div", { className: n.boxThresholdLabel, children: i.label }) : null
|
|
@@ -654,23 +656,23 @@ function Zt(o) {
|
|
|
654
656
|
/* @__PURE__ */ r(
|
|
655
657
|
"div",
|
|
656
658
|
{
|
|
657
|
-
className: [n.ctaTotalsWrap,
|
|
658
|
-
"aria-hidden":
|
|
659
|
+
className: [n.ctaTotalsWrap, R <= 0 ? n.ctaTotalsWrapVisible : null].filter(Boolean).join(" "),
|
|
660
|
+
"aria-hidden": R > 0,
|
|
659
661
|
children: /* @__PURE__ */ N("div", { className: n.ctaTotals, "aria-label": "Totals", children: [
|
|
660
662
|
ie ? /* @__PURE__ */ N("span", { className: n.ctaDiscountBadge, children: [
|
|
661
|
-
|
|
663
|
+
k ? "Unlocked " : "",
|
|
662
664
|
ie,
|
|
663
665
|
"% off"
|
|
664
666
|
] }) : /* @__PURE__ */ r("span", {}),
|
|
665
|
-
/* @__PURE__ */ r("span", { children:
|
|
666
|
-
/* @__PURE__ */ r("span", { className: n.ctaTotalsStrike, children:
|
|
667
|
+
/* @__PURE__ */ r("span", { children: k ? /* @__PURE__ */ N(Te, { children: [
|
|
668
|
+
/* @__PURE__ */ r("span", { className: n.ctaTotalsStrike, children: $(d.toFixed(2)) }),
|
|
667
669
|
" ",
|
|
668
|
-
/* @__PURE__ */ r("span", { className: n.ctaTotalsPrice, children:
|
|
669
|
-
] }) : /* @__PURE__ */ r("span", { className: n.ctaTotalsPrice, children:
|
|
670
|
+
/* @__PURE__ */ r("span", { className: n.ctaTotalsPrice, children: $(C.toFixed(2)) })
|
|
671
|
+
] }) : /* @__PURE__ */ r("span", { className: n.ctaTotalsPrice, children: $(d.toFixed(2)) }) })
|
|
670
672
|
] })
|
|
671
673
|
}
|
|
672
674
|
),
|
|
673
|
-
/* @__PURE__ */ r("button", { type: "button", onClick:
|
|
675
|
+
/* @__PURE__ */ r("button", { type: "button", onClick: le, disabled: !X, className: n.cta, children: I ? "Adding…" : R > 0 ? `Add ${R} more product${R === 1 ? "" : "s"}` : "Add to Basket" })
|
|
674
676
|
] })
|
|
675
677
|
] })
|
|
676
678
|
}
|
|
@@ -679,7 +681,7 @@ function Zt(o) {
|
|
|
679
681
|
export {
|
|
680
682
|
Zt as BundleBuilderDrawer,
|
|
681
683
|
Kt as BundleButton,
|
|
682
|
-
|
|
684
|
+
_e as BundleLineAttributeKeys,
|
|
683
685
|
Qt as BundleProvider,
|
|
684
686
|
xe as useBundleBuilder,
|
|
685
687
|
Ht as useBundleBuilderDrawer
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/constants.ts","../src/api/fetchBundleConfig.ts","../src/context/BundleProvider.tsx","../src/hooks/useBundleBuilder.ts","../src/hooks/useBundleBuilderDrawer.ts","../src/components/BundleButton.tsx","../../../node_modules/lucide-react/dist/esm/shared/src/utils.js","../../../node_modules/lucide-react/dist/esm/defaultAttributes.js","../../../node_modules/lucide-react/dist/esm/Icon.js","../../../node_modules/lucide-react/dist/esm/createLucideIcon.js","../../../node_modules/lucide-react/dist/esm/icons/search.js","../src/components/BundleBuilderDrawer.tsx"],"sourcesContent":["export const BundleLineAttributeKeys = {\n bundleId: \"_bundle_id\",\n bundleConfig: \"_bundle_config\",\n bundleSource: \"_bundle_source\",\n} as const;\n\n","import type { PublicBundleConfigResponse } from \"../types\";\n\nexport async function fetchBundleConfig(params: {\n apiBaseUrl: string;\n shop: string;\n signal?: AbortSignal;\n}): Promise<PublicBundleConfigResponse> {\n const url = new URL(\"/api/public/bundle-config\", params.apiBaseUrl);\n url.searchParams.set(\"shop\", params.shop);\n\n const resp = await fetch(url, {\n method: \"GET\",\n signal: params.signal,\n headers: { \"Content-Type\": \"application/json\" },\n });\n\n // The endpoint uses 4xx/5xx for some errors; normalize to {ok:false}.\n const json = (await resp.json().catch(() => null)) as unknown;\n if (!json || typeof json !== \"object\") {\n return { ok: false, error: \"Invalid response.\" };\n }\n\n return json as PublicBundleConfigResponse;\n}\n\n","import React, { createContext, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { BundleLineAttributeKeys } from \"../constants\";\nimport { fetchBundleConfig as defaultFetchBundleConfig } from \"../api/fetchBundleConfig\";\nimport type { BundleCartAdapter, BundleConfig, BundleEligibleVariant, PublicBundleConfigResponse } from \"../types\";\n\ntype BundleProviderData = {\n currencyCode: string | null;\n config: BundleConfig;\n eligibleVariants: BundleEligibleVariant[];\n};\n\ntype BundleSelectionState = Record<string, number>; // merchandiseId -> qty\ntype BundleSelectionOrder = string[]; // merchandiseId (variant GID) per-item, in first-added -> last-added order\n\nexport type BundleProviderProps = {\n apiBaseUrl: string;\n shop: string;\n cartAdapter: BundleCartAdapter;\n\n /**\n * v1 default is \"default\" to mirror the app's current single-config endpoint.\n * Kept as a prop to avoid an API break when the public endpoint supports multiple handles.\n */\n configHandle?: string;\n\n /**\n * Optional override for Storybook/tests so we can avoid network calls.\n */\n initialData?: BundleProviderData;\n\n /**\n * Optional fetcher override for Storybook/tests.\n */\n configFetcher?: (params: { apiBaseUrl: string; shop: string; signal?: AbortSignal }) => Promise<PublicBundleConfigResponse>;\n\n children: React.ReactNode;\n};\n\nexport type BundleBuilderContextValue = {\n isOpen: boolean;\n open: () => void;\n close: () => void;\n toggle: () => void;\n\n loading: boolean;\n submitting: boolean;\n error: string | null;\n\n currencyCode: string | null;\n config: BundleConfig | null;\n eligibleVariants: BundleEligibleVariant[];\n\n selections: BundleSelectionState;\n selectionOrder: BundleSelectionOrder;\n setQuantity: (merchandiseId: string, quantity: number) => void;\n clearSelections: () => void;\n\n bundleSize: number;\n minRequired: number;\n canSubmit: boolean;\n submit: () => Promise<void>;\n};\n\nexport const BundleBuilderContext = createContext<BundleBuilderContextValue | null>(null);\n\nfunction safeRandomUUID() {\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const cryptoAny = (globalThis as any).crypto as Crypto | undefined;\n if (cryptoAny?.randomUUID) return cryptoAny.randomUUID();\n } catch {\n // ignore\n }\n return `bb_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;\n}\n\nfunction clampQty(n: number) {\n if (!Number.isFinite(n)) return 0;\n return Math.max(0, Math.floor(n));\n}\n\nexport function BundleProvider(props: BundleProviderProps) {\n const {\n apiBaseUrl,\n shop,\n cartAdapter,\n configHandle = \"default\",\n initialData,\n configFetcher,\n children,\n } = props;\n\n const [isOpen, setIsOpen] = useState(false);\n const [loading, setLoading] = useState(!initialData);\n const [submitting, setSubmitting] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const [currencyCode, setCurrencyCode] = useState<string | null>(initialData?.currencyCode ?? null);\n const [config, setConfig] = useState<BundleConfig | null>(initialData?.config ?? null);\n const [eligibleVariants, setEligibleVariants] = useState<BundleEligibleVariant[]>(\n initialData?.eligibleVariants ?? [],\n );\n\n const [selectionsState, setSelectionsState] = useState<{ selections: BundleSelectionState; order: BundleSelectionOrder }>(\n () => ({ selections: {}, order: [] }),\n );\n\n const abortRef = useRef<AbortController | null>(null);\n\n useEffect(() => {\n if (initialData) return;\n\n abortRef.current?.abort();\n const ac = new AbortController();\n abortRef.current = ac;\n\n const fetcher = configFetcher ?? defaultFetchBundleConfig;\n\n setLoading(true);\n setError(null);\n fetcher({ apiBaseUrl, shop, signal: ac.signal })\n .then((json) => {\n if (!json.ok) {\n setError(json.error || \"Failed to load bundle config.\");\n setConfig(null);\n setEligibleVariants([]);\n setCurrencyCode(null);\n return;\n }\n setCurrencyCode(json.currencyCode ?? null);\n setConfig(json.config);\n setEligibleVariants(json.eligibleVariants ?? []);\n })\n .catch((e: unknown) => {\n const msg = e instanceof Error ? e.message : \"Failed to load bundle config.\";\n setError(msg);\n setConfig(null);\n setEligibleVariants([]);\n setCurrencyCode(null);\n })\n .finally(() => setLoading(false));\n\n return () => ac.abort();\n }, [apiBaseUrl, shop, initialData, configFetcher]);\n\n const open = useCallback(() => setIsOpen(true), []);\n const close = useCallback(() => setIsOpen(false), []);\n const toggle = useCallback(() => setIsOpen((v) => !v), []);\n\n const setQuantity = useCallback((merchandiseId: string, quantity: number) => {\n const q = clampQty(quantity);\n setSelectionsState((prev) => {\n const prevQty = prev.selections[merchandiseId] ?? 0;\n const delta = q - prevQty;\n\n // selections\n let nextSelections: BundleSelectionState;\n if (q <= 0) {\n const { [merchandiseId]: _, ...rest } = prev.selections;\n nextSelections = rest;\n } else if (prevQty === q) {\n nextSelections = prev.selections;\n } else {\n nextSelections = { ...prev.selections, [merchandiseId]: q };\n }\n\n // order\n let nextOrder = prev.order;\n if (delta > 0) {\n // Add N items to the end.\n nextOrder = [...prev.order, ...Array.from({ length: delta }, () => merchandiseId)];\n } else if (delta < 0) {\n // Remove N most-recent occurrences of this variant.\n let remainingToRemove = -delta;\n const keptReversed: string[] = [];\n for (let i = prev.order.length - 1; i >= 0; i--) {\n const id = prev.order[i];\n if (id === merchandiseId && remainingToRemove > 0) {\n remainingToRemove--;\n continue;\n }\n keptReversed.push(id);\n }\n keptReversed.reverse();\n nextOrder = keptReversed;\n }\n\n if (nextSelections === prev.selections && nextOrder === prev.order) return prev;\n return { selections: nextSelections, order: nextOrder };\n });\n }, []);\n\n const clearSelections = useCallback(() => setSelectionsState({ selections: {}, order: [] }), []);\n\n const selections = selectionsState.selections;\n const selectionOrder = selectionsState.order;\n\n const bundleSize = useMemo(() => Object.values(selections).reduce((sum, q) => sum + (q || 0), 0), [selections]);\n\n const minRequired = useMemo(() => {\n const rules = config?.rules ?? [];\n const min = rules.length ? Math.min(...rules.map((r) => r.minBundleSize)) : 2;\n return Number.isFinite(min) && min > 0 ? min : 2;\n }, [config]);\n\n const canSubmit = useMemo(() => {\n if (loading || submitting) return false;\n if (error) return false;\n if (!config?.isActive) return false;\n if (bundleSize < minRequired) return false;\n return true;\n }, [bundleSize, config?.isActive, error, loading, minRequired, submitting]);\n\n const submit = useCallback(async () => {\n if (!canSubmit || !config) return;\n\n const bundleId = safeRandomUUID();\n const lines = Object.entries(selections)\n .map(([merchandiseId, quantity]) => ({ merchandiseId, quantity: clampQty(quantity) }))\n .filter((l) => l.quantity > 0)\n .map((l) => ({\n merchandiseId: l.merchandiseId,\n quantity: l.quantity,\n attributes: [\n { key: BundleLineAttributeKeys.bundleId, value: bundleId },\n { key: BundleLineAttributeKeys.bundleConfig, value: configHandle },\n { key: BundleLineAttributeKeys.bundleSource, value: \"bundle_builder\" },\n ],\n }));\n\n if (!lines.length) return;\n\n setSubmitting(true);\n try {\n await cartAdapter.linesAdd(lines);\n clearSelections();\n close();\n cartAdapter.openCartUI?.();\n } finally {\n setSubmitting(false);\n }\n }, [canSubmit, cartAdapter, clearSelections, close, config, configHandle, selections]);\n\n const value: BundleBuilderContextValue = useMemo(\n () => ({\n isOpen,\n open,\n close,\n toggle,\n loading,\n submitting,\n error,\n currencyCode,\n config,\n eligibleVariants,\n selections,\n selectionOrder,\n setQuantity,\n clearSelections,\n bundleSize,\n minRequired,\n canSubmit,\n submit,\n }),\n [\n isOpen,\n open,\n close,\n toggle,\n loading,\n submitting,\n error,\n currencyCode,\n config,\n eligibleVariants,\n selections,\n selectionOrder,\n setQuantity,\n clearSelections,\n bundleSize,\n minRequired,\n canSubmit,\n submit,\n ],\n );\n\n return <BundleBuilderContext.Provider value={value}>{children}</BundleBuilderContext.Provider>;\n}\n\n","import { useContext } from \"react\";\nimport { BundleBuilderContext } from \"../context/BundleProvider\";\n\nexport function useBundleBuilder() {\n const ctx = useContext(BundleBuilderContext);\n if (!ctx) {\n throw new Error(\"useBundleBuilder must be used within <BundleProvider />\");\n }\n return ctx;\n}\n\n","import { useBundleBuilder } from \"./useBundleBuilder\";\n\nexport type BundleBuilderDrawerControls = {\n isOpen: boolean;\n open: () => void;\n close: () => void;\n toggle: () => void;\n};\n\n/**\n * Convenience hook for controlling the drawer (alternative to using <BundleButton />).\n * Must be used within <BundleProvider />.\n */\nexport function useBundleBuilderDrawer(): BundleBuilderDrawerControls {\n const { isOpen, open, close, toggle } = useBundleBuilder();\n return { isOpen, open, close, toggle };\n}\n\n","import React from \"react\";\nimport { useBundleBuilder } from \"../hooks/useBundleBuilder\";\nimport styles from \"./BundleButton.module.css\";\n\nexport type BundleButtonProps = {\n children?: React.ReactNode;\n className?: string;\n};\n\nexport function BundleButton(props: BundleButtonProps) {\n const { toggle } = useBundleBuilder();\n return (\n <button\n type=\"button\"\n onClick={toggle}\n className={[styles.button, props.className].filter(Boolean).join(\" \")}\n >\n {props.children ?? \"Build a bundle\"}\n </button>\n );\n}\n\n","/**\n * @license lucide-react v0.515.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nconst toKebabCase = (string) => string.replace(/([a-z0-9])([A-Z])/g, \"$1-$2\").toLowerCase();\nconst toCamelCase = (string) => string.replace(\n /^([A-Z])|[\\s-_]+(\\w)/g,\n (match, p1, p2) => p2 ? p2.toUpperCase() : p1.toLowerCase()\n);\nconst toPascalCase = (string) => {\n const camelCase = toCamelCase(string);\n return camelCase.charAt(0).toUpperCase() + camelCase.slice(1);\n};\nconst mergeClasses = (...classes) => classes.filter((className, index, array) => {\n return Boolean(className) && className.trim() !== \"\" && array.indexOf(className) === index;\n}).join(\" \").trim();\nconst hasA11yProp = (props) => {\n for (const prop in props) {\n if (prop.startsWith(\"aria-\") || prop === \"role\" || prop === \"title\") {\n return true;\n }\n }\n};\n\nexport { hasA11yProp, mergeClasses, toCamelCase, toKebabCase, toPascalCase };\n//# sourceMappingURL=utils.js.map\n","/**\n * @license lucide-react v0.515.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nvar defaultAttributes = {\n xmlns: \"http://www.w3.org/2000/svg\",\n width: 24,\n height: 24,\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n stroke: \"currentColor\",\n strokeWidth: 2,\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n};\n\nexport { defaultAttributes as default };\n//# sourceMappingURL=defaultAttributes.js.map\n","/**\n * @license lucide-react v0.515.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { forwardRef, createElement } from 'react';\nimport defaultAttributes from './defaultAttributes.js';\nimport { mergeClasses, hasA11yProp } from './shared/src/utils.js';\n\nconst Icon = forwardRef(\n ({\n color = \"currentColor\",\n size = 24,\n strokeWidth = 2,\n absoluteStrokeWidth,\n className = \"\",\n children,\n iconNode,\n ...rest\n }, ref) => createElement(\n \"svg\",\n {\n ref,\n ...defaultAttributes,\n width: size,\n height: size,\n stroke: color,\n strokeWidth: absoluteStrokeWidth ? Number(strokeWidth) * 24 / Number(size) : strokeWidth,\n className: mergeClasses(\"lucide\", className),\n ...!children && !hasA11yProp(rest) && { \"aria-hidden\": \"true\" },\n ...rest\n },\n [\n ...iconNode.map(([tag, attrs]) => createElement(tag, attrs)),\n ...Array.isArray(children) ? children : [children]\n ]\n )\n);\n\nexport { Icon as default };\n//# sourceMappingURL=Icon.js.map\n","/**\n * @license lucide-react v0.515.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { forwardRef, createElement } from 'react';\nimport { mergeClasses, toKebabCase, toPascalCase } from './shared/src/utils.js';\nimport Icon from './Icon.js';\n\nconst createLucideIcon = (iconName, iconNode) => {\n const Component = forwardRef(\n ({ className, ...props }, ref) => createElement(Icon, {\n ref,\n iconNode,\n className: mergeClasses(\n `lucide-${toKebabCase(toPascalCase(iconName))}`,\n `lucide-${iconName}`,\n className\n ),\n ...props\n })\n );\n Component.displayName = toPascalCase(iconName);\n return Component;\n};\n\nexport { createLucideIcon as default };\n//# sourceMappingURL=createLucideIcon.js.map\n","/**\n * @license lucide-react v0.515.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"m21 21-4.34-4.34\", key: \"14j7rj\" }],\n [\"circle\", { cx: \"11\", cy: \"11\", r: \"8\", key: \"4ej97u\" }]\n];\nconst Search = createLucideIcon(\"search\", __iconNode);\n\nexport { __iconNode, Search as default };\n//# sourceMappingURL=search.js.map\n","import React, { useEffect, useMemo, useRef, useState } from \"react\";\nimport { Search } from \"lucide-react\";\nimport { useBundleBuilder } from \"../hooks/useBundleBuilder\";\nimport styles from \"./BundleBuilderDrawer.module.css\";\n\nexport type BundleBuilderDrawerProps = {\n className?: string;\n};\n\nexport function BundleBuilderDrawer(props: BundleBuilderDrawerProps) {\n const {\n isOpen,\n close,\n loading,\n submitting,\n error,\n currencyCode,\n config,\n eligibleVariants,\n selections,\n selectionOrder,\n setQuantity,\n bundleSize,\n minRequired,\n canSubmit,\n submit,\n } = useBundleBuilder();\n\n const [isSearchOpen, setIsSearchOpen] = useState(false);\n const [searchQuery, setSearchQuery] = useState(\"\");\n const searchInputRef = useRef<HTMLInputElement | null>(null);\n\n const formatVariantOptions = (selectedOptions: Array<{ name: string; value: string }> | null | undefined) => {\n const opts = (selectedOptions ?? []).filter((o) => {\n const name = o?.name?.trim();\n const value = o?.value?.trim();\n if (!name || !value) return false;\n if (name.toLowerCase() === \"title\") return false;\n return true;\n });\n if (!opts.length) return null;\n return opts.map((o) => `${o.name}: ${o.value}`).join(\" · \");\n };\n\n const getVariantPrimaryName = (v: (typeof eligibleVariants)[number]) => {\n return v.product?.title ?? v.displayName ?? v.title;\n };\n\n const getVariantA11yLabel = (v: (typeof eligibleVariants)[number]) => {\n const name = getVariantPrimaryName(v);\n const opts = formatVariantOptions(v.selectedOptions);\n return [name, opts].filter(Boolean).join(\" — \");\n };\n\n const [isMounted, setIsMounted] = useState(isOpen);\n const closeTimerRef = useRef<number | null>(null);\n\n const formatMoney = (amount: string) => {\n const n = Number(amount);\n if (!Number.isFinite(n)) return amount;\n\n if (currencyCode) {\n try {\n return new Intl.NumberFormat(undefined, { style: \"currency\", currency: currencyCode }).format(n);\n } catch {\n // ignore and fall through\n }\n }\n\n return `$${n.toFixed(2)}`;\n };\n\n const title = config?.title?.trim() || \"Build your bundle\";\n\n const sorted = useMemo(() => {\n return [...eligibleVariants].sort((a, b) => a.displayName.localeCompare(b.displayName));\n }, [eligibleVariants]);\n\n const filteredVariants = useMemo(() => {\n const q = searchQuery.trim().toLowerCase();\n if (!q) return sorted;\n\n const tokens = q.split(/\\s+/).filter(Boolean);\n const matches = (v: (typeof sorted)[number]) => {\n const parts: string[] = [];\n parts.push(v.displayName);\n if (v.product?.title) parts.push(v.product.title);\n for (const o of v.selectedOptions ?? []) {\n parts.push(o.name);\n parts.push(o.value);\n }\n const haystack = parts.join(\" \").toLowerCase();\n return tokens.every((t) => haystack.includes(t));\n };\n\n return sorted.filter(matches);\n }, [searchQuery, sorted]);\n\n const rulesSorted = useMemo(() => {\n return [...(config?.rules ?? [])].sort((a, b) => a.minBundleSize - b.minBundleSize);\n }, [config?.rules]);\n\n const itemsRemaining = useMemo(() => Math.max(0, minRequired - bundleSize), [bundleSize, minRequired]);\n\n const appliedRule = useMemo(() => {\n let best = null as (typeof rulesSorted)[number] | null;\n for (const r of rulesSorted) {\n if (bundleSize >= r.minBundleSize) best = r;\n }\n return best;\n }, [bundleSize, rulesSorted]);\n\n const appliedDiscountPercent = useMemo(() => {\n if (!appliedRule) return null;\n const pct = Number.parseFloat(appliedRule.discountPercent);\n if (!Number.isFinite(pct) || pct <= 0) return null;\n return pct;\n }, [appliedRule]);\n\n const minRuleDiscountPercent = useMemo(() => {\n const r = rulesSorted[0];\n if (!r) return null;\n const pct = Number.parseFloat(r.discountPercent);\n if (!Number.isFinite(pct) || pct <= 0) return null;\n return pct;\n }, [rulesSorted]);\n\n const badgeDiscountPercent = appliedDiscountPercent ?? minRuleDiscountPercent;\n\n const subtotal = useMemo(() => {\n const byId = new Map(eligibleVariants.map((v) => [v.id, v] as const));\n let total = 0;\n for (const [variantId, qty] of Object.entries(selections)) {\n const q = qty ?? 0;\n if (q <= 0) continue;\n const v = byId.get(variantId);\n const price = Number(v?.price);\n if (!Number.isFinite(price)) continue;\n total += price * q;\n }\n // Keep cents stable for display.\n return Math.round(total * 100) / 100;\n }, [eligibleVariants, selections]);\n\n const discountedTotal = useMemo(() => {\n if (!appliedDiscountPercent) return subtotal;\n const total = subtotal * (1 - appliedDiscountPercent / 100);\n return Math.round(total * 100) / 100;\n }, [appliedDiscountPercent, subtotal]);\n\n const maxRuleSize = useMemo(() => {\n if (!rulesSorted.length) return 0;\n return Math.max(...rulesSorted.map((r) => r.minBundleSize));\n }, [rulesSorted]);\n\n const filledVariants = useMemo(() => {\n const byId = new Map(eligibleVariants.map((v) => [v.id, v] as const));\n return selectionOrder\n .map((variantId) => byId.get(variantId))\n .filter((v): v is (typeof eligibleVariants)[number] => Boolean(v));\n }, [eligibleVariants, selectionOrder]);\n\n const thresholdByIndex = useMemo(() => {\n // Slot index (0-based) => rule that becomes active at that slot.\n const map = new Map<number, { discountPercent: string; minBundleSize: number; label: string }>();\n for (const r of rulesSorted) {\n const idx = Math.max(0, r.minBundleSize - 1);\n map.set(idx, {\n discountPercent: r.discountPercent,\n minBundleSize: r.minBundleSize,\n label: r.label?.trim() || `Buy ${r.minBundleSize}+`,\n });\n }\n return map;\n }, [rulesSorted]);\n\n const slotCount = useMemo(() => {\n // Placeholders show until highest tier; if user adds more, extend (scroll).\n return Math.max(maxRuleSize || minRequired, filledVariants.length);\n }, [filledVariants.length, maxRuleSize, minRequired]);\n\n const panelRef = useRef<HTMLDivElement | null>(null);\n const bodyRef = useRef<HTMLDivElement | null>(null);\n const boxSummaryWindowRef = useRef<HTMLDivElement | null>(null);\n const prevBundleSizeRef = useRef<number>(bundleSize);\n\n const scrollVariantRowIntoView = (variantId: string) => {\n const container = bodyRef.current;\n if (!container) return;\n const row = container.querySelector<HTMLElement>(`[data-variant-row=\"${variantId}\"]`);\n if (!row) return;\n\n const c = container.getBoundingClientRect();\n const r = row.getBoundingClientRect();\n const padding = 8;\n const isFullyVisible = r.top >= c.top + padding && r.bottom <= c.bottom - padding;\n if (isFullyVisible) return;\n\n const maxTop = Math.max(0, container.scrollHeight - container.clientHeight);\n const rowCenterOffset = (r.top - c.top) + r.height / 2;\n const targetTop = container.scrollTop + rowCenterOffset - container.clientHeight / 2;\n const nextTop = Math.min(maxTop, Math.max(0, targetTop));\n container.scrollTo({ top: nextTop, behavior: \"smooth\" });\n };\n\n useEffect(() => {\n if (!isOpen) return;\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") close();\n };\n window.addEventListener(\"keydown\", onKeyDown);\n return () => window.removeEventListener(\"keydown\", onKeyDown);\n }, [close, isOpen]);\n\n useEffect(() => {\n if (closeTimerRef.current != null) {\n window.clearTimeout(closeTimerRef.current);\n closeTimerRef.current = null;\n }\n\n if (isOpen) {\n setIsMounted(true);\n return;\n }\n\n // Keep mounted long enough to play exit animation.\n closeTimerRef.current = window.setTimeout(() => {\n setIsMounted(false);\n closeTimerRef.current = null;\n }, 220);\n }, [isOpen]);\n\n useEffect(() => {\n return () => {\n if (closeTimerRef.current != null) window.clearTimeout(closeTimerRef.current);\n };\n }, []);\n\n useEffect(() => {\n if (!isOpen) return;\n if (!isSearchOpen) return;\n const raf = requestAnimationFrame(() => searchInputRef.current?.focus());\n return () => cancelAnimationFrame(raf);\n }, [isOpen, isSearchOpen]);\n\n useEffect(() => {\n const prev = prevBundleSizeRef.current;\n prevBundleSizeRef.current = bundleSize;\n\n // Only respond to adds (qty increases).\n if (bundleSize <= prev) return;\n\n const container = boxSummaryWindowRef.current;\n if (!container) return;\n\n const hitThreshold = rulesSorted.some((r) => r.minBundleSize === bundleSize);\n const nextThreshold = rulesSorted.find((r) => r.minBundleSize > bundleSize);\n\n // When hitting a threshold, try to reveal the NEXT threshold (aligned right) if it's off-screen to the right.\n // If no remaining thresholds, scroll the newest added item into view.\n const targetIdx = nextThreshold && hitThreshold ? nextThreshold.minBundleSize - 1 : !nextThreshold ? bundleSize - 1 : null;\n if (targetIdx == null || targetIdx < 0) return;\n\n const raf = requestAnimationFrame(() => {\n const el = container.querySelector<HTMLElement>(`[data-box-slot=\"${targetIdx}\"]`);\n if (!el) return;\n\n const containerRect = container.getBoundingClientRect();\n const elRect = el.getBoundingClientRect();\n const deltaRight = elRect.right - containerRect.right;\n\n // Only scroll rightward when the target is off-screen to the right.\n if (deltaRight <= 1) return;\n\n const maxLeft = Math.max(0, container.scrollWidth - container.clientWidth);\n const nextLeft = Math.min(maxLeft, Math.max(0, container.scrollLeft + deltaRight));\n container.scrollTo({ left: nextLeft, behavior: \"smooth\" });\n });\n\n return () => cancelAnimationFrame(raf);\n }, [bundleSize, rulesSorted]);\n\n useEffect(() => {\n if (!isOpen) return;\n panelRef.current?.focus();\n }, [isOpen]);\n\n if (!isMounted) return null;\n\n return (\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Bundle builder\"\n className={[styles.backdrop, isOpen ? styles.backdropOpen : styles.backdropClosed, props.className].filter(Boolean).join(\" \")}\n onMouseDown={(e) => {\n if (e.target === e.currentTarget) close();\n }}\n >\n <aside ref={panelRef} className={[styles.panel, isOpen ? styles.panelOpen : styles.panelClosed].filter(Boolean).join(\" \")} tabIndex={-1}>\n <header className={[styles.header, isSearchOpen ? styles.headerSearchOpen : null].filter(Boolean).join(\" \")}>\n <button\n type=\"button\"\n className={styles.searchIconButton}\n aria-label={isSearchOpen ? \"Search (expanded)\" : \"Search\"}\n aria-expanded={isSearchOpen}\n onClick={() => {\n setIsSearchOpen(true);\n }}\n >\n <Search size={18} aria-hidden=\"true\" />\n </button>\n\n <div className={styles.headerCenter}>\n <div className={styles.headerTitleWrap} aria-hidden={isSearchOpen}>\n <h2 className={styles.title}>{title}</h2>\n </div>\n\n <div className={styles.headerSearchWrap} aria-hidden={!isSearchOpen}>\n <div className={styles.searchBar}>\n <input\n ref={searchInputRef}\n className={styles.searchInput}\n type=\"search\"\n value={searchQuery}\n placeholder=\"Search\"\n onChange={(e) => setSearchQuery(e.target.value)}\n onBlur={() => {\n if (searchQuery.trim() === \"\") setIsSearchOpen(false);\n }}\n />\n {searchQuery.trim() ? (\n <button\n type=\"button\"\n className={styles.searchClearButton}\n onMouseDown={(e) => {\n // Prevent input blur so the bar stays open and focused.\n e.preventDefault();\n }}\n onClick={() => {\n setSearchQuery(\"\");\n searchInputRef.current?.focus();\n }}\n aria-label=\"Clear search\"\n >\n Clear\n </button>\n ) : null}\n </div>\n </div>\n </div>\n\n <button type=\"button\" onClick={close} disabled={submitting} className={styles.closeButton} aria-label=\"Close\">\n ×\n </button>\n </header>\n\n <div className={styles.body} ref={bodyRef}>\n {loading ? <p className={styles.muted}>Loading…</p> : null}\n {error ? <p className={styles.error}>{error}</p> : null}\n {!loading && config && !config.isActive ? <p className={styles.error}>Bundles are not active.</p> : null}\n\n <div className={styles.variants}>\n <ul className={styles.variantList}>\n {filteredVariants.map((v) => {\n const qty = selections[v.id] ?? 0;\n const variantPrimaryName = getVariantPrimaryName(v);\n const variantOptionText = formatVariantOptions(v.selectedOptions);\n const variantA11y = getVariantA11yLabel(v);\n\n // Price display:\n // - Always show a \"discounted\" price based on the unlocked discount, falling back to the minimum rule discount.\n // - Show the original price with a strikethrough when a discount applies.\n const discountPercentToUse = badgeDiscountPercent;\n const originalPriceNumber = Number(v.price);\n const hasDiscount =\n discountPercentToUse != null &&\n Number.isFinite(discountPercentToUse) &&\n discountPercentToUse > 0 &&\n Number.isFinite(originalPriceNumber);\n const discountedPriceNumber = hasDiscount\n ? Math.round(originalPriceNumber * (1 - discountPercentToUse / 100) * 100) / 100\n : null;\n\n return (\n <li key={v.id} className={styles.variantRow} data-variant-row={v.id}>\n <div className={styles.variantLeft}>\n <div className={styles.variantThumb} aria-hidden=\"true\">\n {v.image?.url ? (\n <img\n className={styles.variantThumbImg}\n src={v.image.url}\n alt={v.image.altText ?? variantA11y}\n loading=\"lazy\"\n />\n ) : (\n <div className={styles.variantThumbFallback}>{v.product?.title?.slice(0, 1)?.toUpperCase() ?? \"•\"}</div>\n )}\n </div>\n\n <div className={styles.variantInfo}>\n <div className={styles.variantName}>{variantPrimaryName}</div>\n {variantOptionText ? <div className={styles.variantMeta}>{variantOptionText}</div> : null}\n <div className={styles.variantPriceRow}>\n {hasDiscount ? (\n <span className={styles.variantCompareAt}>\n {formatMoney(Number.isFinite(originalPriceNumber) ? originalPriceNumber.toFixed(2) : v.price)}\n </span>\n ) : null}\n <span className={styles.variantPrice}>\n {formatMoney(\n discountedPriceNumber != null\n ? discountedPriceNumber.toFixed(2)\n : Number.isFinite(originalPriceNumber)\n ? originalPriceNumber.toFixed(2)\n : v.price,\n )}\n </span>\n </div>\n </div>\n </div>\n {qty <= 0 ? (\n <button\n type=\"button\"\n onClick={() => setQuantity(v.id, 1)}\n disabled={submitting}\n className={styles.addToBundleButton}\n aria-label={`Add ${variantA11y} to bundle`}\n >\n Add\n </button>\n ) : (\n <div className={styles.qtyControls}>\n <button\n type=\"button\"\n onClick={() => setQuantity(v.id, qty - 1)}\n disabled={submitting || qty <= 0}\n className={styles.qtyButton}\n aria-label={`Decrease ${variantA11y}`}\n >\n −\n </button>\n <span className={styles.qtyValue} aria-label={`Quantity ${qty}`}>\n {qty}\n </span>\n <button\n type=\"button\"\n onClick={() => setQuantity(v.id, qty + 1)}\n disabled={submitting}\n className={styles.qtyButton}\n aria-label={`Increase ${variantA11y}`}\n >\n +\n </button>\n </div>\n )}\n </li>\n );\n })}\n </ul>\n </div>\n </div>\n\n <footer className={styles.footer}>\n <div className={styles.boxSummaryWindow} ref={boxSummaryWindowRef}>\n <div className={styles.boxSummaryRow} aria-label=\"Bundle box summary\">\n {Array.from({ length: slotCount }).map((_, idx) => {\n const variant = filledVariants[idx];\n const threshold = thresholdByIndex.get(idx);\n const isFilled = Boolean(variant);\n\n // Per your preference: show discount text only while it's still a placeholder (unlocked display comes later elsewhere).\n const isThreshold = Boolean(threshold);\n const showThreshold = isThreshold && !isFilled;\n const discountText = threshold ? `${threshold.discountPercent}% off` : null;\n\n const titleText = isFilled ? variant!.displayName : `Slot ${idx + 1}`;\n\n return (\n <div key={idx} data-box-slot={idx} className={styles.boxSlot}>\n <div\n className={[\n styles.boxItem,\n isFilled ? styles.boxItemFilled : styles.boxItemPlaceholder,\n isThreshold ? styles.boxItemThreshold : null,\n isFilled ? styles.boxItemClickable : null,\n ]\n .filter(Boolean)\n .join(\" \")}\n role={isFilled ? \"button\" : undefined}\n tabIndex={isFilled ? 0 : undefined}\n onClick={isFilled ? () => scrollVariantRowIntoView(variant!.id) : undefined}\n onKeyDown={\n isFilled\n ? (e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n scrollVariantRowIntoView(variant!.id);\n }\n }\n : undefined\n }\n aria-label={showThreshold && discountText ? `${titleText}. Unlocks ${discountText}.` : titleText}\n title={showThreshold && discountText ? `${titleText} • Unlocks ${discountText}` : titleText}\n >\n {isFilled ? (\n variant!.image?.url ? (\n <img\n className={styles.boxItemImage}\n src={variant!.image!.url}\n alt={variant!.image!.altText ?? variant!.displayName}\n loading=\"lazy\"\n />\n ) : (\n <div className={styles.boxItemFallback} aria-hidden=\"true\">\n {variant!.product?.title?.slice(0, 1)?.toUpperCase() ?? \"•\"}\n </div>\n )\n ) : showThreshold && discountText ? (\n <div className={styles.boxItemDiscountText}>{discountText}</div>\n ) : (\n <div className={styles.boxItemPlus} aria-hidden=\"true\">\n +\n </div>\n )}\n </div>\n\n {isThreshold ? <div className={styles.boxThresholdLabel}>{threshold!.label}</div> : null}\n </div>\n );\n })}\n </div>\n </div>\n <div\n className={[styles.ctaTotalsWrap, itemsRemaining <= 0 ? styles.ctaTotalsWrapVisible : null].filter(Boolean).join(\" \")}\n aria-hidden={itemsRemaining > 0}\n >\n <div className={styles.ctaTotals} aria-label=\"Totals\">\n {badgeDiscountPercent ? (\n <span className={styles.ctaDiscountBadge}>\n {appliedDiscountPercent ? \"Unlocked \" : \"\"}\n {badgeDiscountPercent}% off\n </span>\n ) : (\n <span />\n )}\n\n <span>\n {appliedDiscountPercent ? (\n <>\n <span className={styles.ctaTotalsStrike}>{formatMoney(subtotal.toFixed(2))}</span>{\" \"}\n <span className={styles.ctaTotalsPrice}>{formatMoney(discountedTotal.toFixed(2))}</span>\n </>\n ) : (\n <span className={styles.ctaTotalsPrice}>{formatMoney(subtotal.toFixed(2))}</span>\n )}\n </span>\n </div>\n </div>\n\n <button type=\"button\" onClick={submit} disabled={!canSubmit} className={styles.cta}>\n {submitting ? \"Adding…\" : itemsRemaining > 0 ? `Add ${itemsRemaining} more product${itemsRemaining === 1 ? \"\" : \"s\"}` : \"Add to Basket\"}\n </button>\n </footer>\n </aside>\n </div>\n );\n}\n\n"],"names":["BundleLineAttributeKeys","fetchBundleConfig","params","url","json","BundleBuilderContext","createContext","safeRandomUUID","cryptoAny","clampQty","n","BundleProvider","props","apiBaseUrl","shop","cartAdapter","configHandle","initialData","configFetcher","children","isOpen","setIsOpen","useState","loading","setLoading","submitting","setSubmitting","error","setError","currencyCode","setCurrencyCode","config","setConfig","eligibleVariants","setEligibleVariants","selectionsState","setSelectionsState","abortRef","useRef","useEffect","_a","ac","fetcher","defaultFetchBundleConfig","e","msg","open","useCallback","close","toggle","v","setQuantity","merchandiseId","quantity","q","prev","prevQty","delta","nextSelections","_","rest","nextOrder","remainingToRemove","keptReversed","i","id","clearSelections","selections","selectionOrder","bundleSize","useMemo","sum","minRequired","rules","min","r","canSubmit","submit","bundleId","lines","value","jsx","useBundleBuilder","ctx","useContext","useBundleBuilderDrawer","BundleButton","styles","toKebabCase","string","toCamelCase","match","p1","p2","toPascalCase","camelCase","mergeClasses","classes","className","index","array","hasA11yProp","prop","defaultAttributes","Icon","forwardRef","color","size","strokeWidth","absoluteStrokeWidth","iconNode","ref","createElement","tag","attrs","createLucideIcon","iconName","Component","__iconNode","Search","BundleBuilderDrawer","isSearchOpen","setIsSearchOpen","searchQuery","setSearchQuery","searchInputRef","formatVariantOptions","selectedOptions","opts","o","name","_b","getVariantPrimaryName","getVariantA11yLabel","isMounted","setIsMounted","closeTimerRef","formatMoney","amount","title","sorted","a","b","filteredVariants","tokens","matches","parts","haystack","t","rulesSorted","itemsRemaining","appliedRule","best","appliedDiscountPercent","pct","minRuleDiscountPercent","badgeDiscountPercent","subtotal","byId","total","variantId","qty","price","discountedTotal","maxRuleSize","filledVariants","thresholdByIndex","map","idx","slotCount","panelRef","bodyRef","boxSummaryWindowRef","prevBundleSizeRef","scrollVariantRowIntoView","container","row","c","padding","maxTop","rowCenterOffset","targetTop","nextTop","onKeyDown","raf","hitThreshold","nextThreshold","targetIdx","el","containerRect","deltaRight","maxLeft","nextLeft","jsxs","variantPrimaryName","variantOptionText","variantA11y","discountPercentToUse","originalPriceNumber","hasDiscount","discountedPriceNumber","_d","_c","variant","threshold","isFilled","isThreshold","showThreshold","discountText","titleText","Fragment"],"mappings":"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","x_google_ignoreList":[6,7,8,9,10]}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/constants.ts","../src/api/fetchBundleConfig.ts","../src/context/BundleProvider.tsx","../src/hooks/useBundleBuilder.ts","../src/hooks/useBundleBuilderDrawer.ts","../src/components/BundleButton.tsx","../../../node_modules/lucide-react/dist/esm/shared/src/utils.js","../../../node_modules/lucide-react/dist/esm/defaultAttributes.js","../../../node_modules/lucide-react/dist/esm/Icon.js","../../../node_modules/lucide-react/dist/esm/createLucideIcon.js","../../../node_modules/lucide-react/dist/esm/icons/search.js","../src/components/BundleBuilderDrawer.tsx"],"sourcesContent":["export const BundleLineAttributeKeys = {\n bundleId: \"_bundle_id\",\n bundleConfig: \"_bundle_config\",\n bundleSource: \"_bundle_source\",\n bundleTitle: \"_bundle_title\",\n} as const;\n\n","import type { PublicBundleConfigResponse } from \"../types\";\n\nexport async function fetchBundleConfig(params: {\n apiBaseUrl: string;\n shop: string;\n signal?: AbortSignal;\n}): Promise<PublicBundleConfigResponse> {\n const url = new URL(\"/api/public/bundle-config\", params.apiBaseUrl);\n url.searchParams.set(\"shop\", params.shop);\n\n const resp = await fetch(url, {\n method: \"GET\",\n signal: params.signal,\n headers: { \"Content-Type\": \"application/json\" },\n });\n\n // The endpoint uses 4xx/5xx for some errors; normalize to {ok:false}.\n const json = (await resp.json().catch(() => null)) as unknown;\n if (!json || typeof json !== \"object\") {\n return { ok: false, error: \"Invalid response.\" };\n }\n\n return json as PublicBundleConfigResponse;\n}\n\n","import React, { createContext, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { BundleLineAttributeKeys } from \"../constants\";\nimport { fetchBundleConfig as defaultFetchBundleConfig } from \"../api/fetchBundleConfig\";\nimport type { BundleCartAdapter, BundleConfig, BundleEligibleVariant, PublicBundleConfigResponse } from \"../types\";\n\ntype BundleProviderData = {\n currencyCode: string | null;\n config: BundleConfig;\n eligibleVariants: BundleEligibleVariant[];\n};\n\ntype BundleSelectionState = Record<string, number>; // merchandiseId -> qty\ntype BundleSelectionOrder = string[]; // merchandiseId (variant GID) per-item, in first-added -> last-added order\n\nexport type BundleProviderProps = {\n apiBaseUrl: string;\n shop: string;\n cartAdapter: BundleCartAdapter;\n\n /**\n * v1 default is \"default\" to mirror the app's current single-config endpoint.\n * Kept as a prop to avoid an API break when the public endpoint supports multiple handles.\n */\n configHandle?: string;\n\n /**\n * Optional override for Storybook/tests so we can avoid network calls.\n */\n initialData?: BundleProviderData;\n\n /**\n * Optional fetcher override for Storybook/tests.\n */\n configFetcher?: (params: { apiBaseUrl: string; shop: string; signal?: AbortSignal }) => Promise<PublicBundleConfigResponse>;\n\n children: React.ReactNode;\n};\n\nexport type BundleBuilderContextValue = {\n isOpen: boolean;\n open: () => void;\n close: () => void;\n toggle: () => void;\n\n loading: boolean;\n submitting: boolean;\n error: string | null;\n\n currencyCode: string | null;\n config: BundleConfig | null;\n eligibleVariants: BundleEligibleVariant[];\n\n selections: BundleSelectionState;\n selectionOrder: BundleSelectionOrder;\n setQuantity: (merchandiseId: string, quantity: number) => void;\n clearSelections: () => void;\n\n bundleSize: number;\n minRequired: number;\n canSubmit: boolean;\n submit: () => Promise<void>;\n};\n\nexport const BundleBuilderContext = createContext<BundleBuilderContextValue | null>(null);\n\nfunction safeRandomUUID() {\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const cryptoAny = (globalThis as any).crypto as Crypto | undefined;\n if (cryptoAny?.randomUUID) return cryptoAny.randomUUID();\n } catch {\n // ignore\n }\n return `bb_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;\n}\n\nfunction clampQty(n: number) {\n if (!Number.isFinite(n)) return 0;\n return Math.max(0, Math.floor(n));\n}\n\nexport function BundleProvider(props: BundleProviderProps) {\n const {\n apiBaseUrl,\n shop,\n cartAdapter,\n configHandle = \"default\",\n initialData,\n configFetcher,\n children,\n } = props;\n\n const [isOpen, setIsOpen] = useState(false);\n const [loading, setLoading] = useState(!initialData);\n const [submitting, setSubmitting] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const [currencyCode, setCurrencyCode] = useState<string | null>(initialData?.currencyCode ?? null);\n const [config, setConfig] = useState<BundleConfig | null>(initialData?.config ?? null);\n const [eligibleVariants, setEligibleVariants] = useState<BundleEligibleVariant[]>(\n initialData?.eligibleVariants ?? [],\n );\n\n const [selectionsState, setSelectionsState] = useState<{ selections: BundleSelectionState; order: BundleSelectionOrder }>(\n () => ({ selections: {}, order: [] }),\n );\n\n const abortRef = useRef<AbortController | null>(null);\n\n useEffect(() => {\n if (initialData) return;\n\n abortRef.current?.abort();\n const ac = new AbortController();\n abortRef.current = ac;\n\n const fetcher = configFetcher ?? defaultFetchBundleConfig;\n\n setLoading(true);\n setError(null);\n fetcher({ apiBaseUrl, shop, signal: ac.signal })\n .then((json) => {\n if (!json.ok) {\n setError(json.error || \"Failed to load bundle config.\");\n setConfig(null);\n setEligibleVariants([]);\n setCurrencyCode(null);\n return;\n }\n setCurrencyCode(json.currencyCode ?? null);\n setConfig(json.config);\n setEligibleVariants(json.eligibleVariants ?? []);\n })\n .catch((e: unknown) => {\n const msg = e instanceof Error ? e.message : \"Failed to load bundle config.\";\n setError(msg);\n setConfig(null);\n setEligibleVariants([]);\n setCurrencyCode(null);\n })\n .finally(() => setLoading(false));\n\n return () => ac.abort();\n }, [apiBaseUrl, shop, initialData, configFetcher]);\n\n const open = useCallback(() => setIsOpen(true), []);\n const close = useCallback(() => setIsOpen(false), []);\n const toggle = useCallback(() => setIsOpen((v) => !v), []);\n\n const setQuantity = useCallback((merchandiseId: string, quantity: number) => {\n const q = clampQty(quantity);\n setSelectionsState((prev) => {\n const prevQty = prev.selections[merchandiseId] ?? 0;\n const delta = q - prevQty;\n\n // selections\n let nextSelections: BundleSelectionState;\n if (q <= 0) {\n const { [merchandiseId]: _, ...rest } = prev.selections;\n nextSelections = rest;\n } else if (prevQty === q) {\n nextSelections = prev.selections;\n } else {\n nextSelections = { ...prev.selections, [merchandiseId]: q };\n }\n\n // order\n let nextOrder = prev.order;\n if (delta > 0) {\n // Add N items to the end.\n nextOrder = [...prev.order, ...Array.from({ length: delta }, () => merchandiseId)];\n } else if (delta < 0) {\n // Remove N most-recent occurrences of this variant.\n let remainingToRemove = -delta;\n const keptReversed: string[] = [];\n for (let i = prev.order.length - 1; i >= 0; i--) {\n const id = prev.order[i];\n if (id === merchandiseId && remainingToRemove > 0) {\n remainingToRemove--;\n continue;\n }\n keptReversed.push(id);\n }\n keptReversed.reverse();\n nextOrder = keptReversed;\n }\n\n if (nextSelections === prev.selections && nextOrder === prev.order) return prev;\n return { selections: nextSelections, order: nextOrder };\n });\n }, []);\n\n const clearSelections = useCallback(() => setSelectionsState({ selections: {}, order: [] }), []);\n\n const selections = selectionsState.selections;\n const selectionOrder = selectionsState.order;\n\n const bundleSize = useMemo(() => Object.values(selections).reduce((sum, q) => sum + (q || 0), 0), [selections]);\n\n const minRequired = useMemo(() => {\n const rules = config?.rules ?? [];\n const min = rules.length ? Math.min(...rules.map((r) => r.minBundleSize)) : 2;\n return Number.isFinite(min) && min > 0 ? min : 2;\n }, [config]);\n\n const canSubmit = useMemo(() => {\n if (loading || submitting) return false;\n if (error) return false;\n if (!config?.isActive) return false;\n if (bundleSize < minRequired) return false;\n return true;\n }, [bundleSize, config?.isActive, error, loading, minRequired, submitting]);\n\n const submit = useCallback(async () => {\n if (!canSubmit || !config) return;\n\n const bundleId = safeRandomUUID();\n const bundleTitle = (config.title ?? \"\").trim().slice(0, 255);\n const lines = Object.entries(selections)\n .map(([merchandiseId, quantity]) => ({ merchandiseId, quantity: clampQty(quantity) }))\n .filter((l) => l.quantity > 0)\n .map((l) => ({\n merchandiseId: l.merchandiseId,\n quantity: l.quantity,\n attributes: [\n { key: BundleLineAttributeKeys.bundleId, value: bundleId },\n { key: BundleLineAttributeKeys.bundleConfig, value: configHandle },\n { key: BundleLineAttributeKeys.bundleSource, value: \"bundle_builder\" },\n ...(bundleTitle ? [{ key: BundleLineAttributeKeys.bundleTitle, value: bundleTitle }] : []),\n ],\n }));\n\n if (!lines.length) return;\n\n setSubmitting(true);\n try {\n await cartAdapter.linesAdd(lines);\n clearSelections();\n close();\n cartAdapter.openCartUI?.();\n } finally {\n setSubmitting(false);\n }\n }, [canSubmit, cartAdapter, clearSelections, close, config, configHandle, selections]);\n\n const value: BundleBuilderContextValue = useMemo(\n () => ({\n isOpen,\n open,\n close,\n toggle,\n loading,\n submitting,\n error,\n currencyCode,\n config,\n eligibleVariants,\n selections,\n selectionOrder,\n setQuantity,\n clearSelections,\n bundleSize,\n minRequired,\n canSubmit,\n submit,\n }),\n [\n isOpen,\n open,\n close,\n toggle,\n loading,\n submitting,\n error,\n currencyCode,\n config,\n eligibleVariants,\n selections,\n selectionOrder,\n setQuantity,\n clearSelections,\n bundleSize,\n minRequired,\n canSubmit,\n submit,\n ],\n );\n\n return <BundleBuilderContext.Provider value={value}>{children}</BundleBuilderContext.Provider>;\n}\n\n","import { useContext } from \"react\";\nimport { BundleBuilderContext } from \"../context/BundleProvider\";\n\nexport function useBundleBuilder() {\n const ctx = useContext(BundleBuilderContext);\n if (!ctx) {\n throw new Error(\"useBundleBuilder must be used within <BundleProvider />\");\n }\n return ctx;\n}\n\n","import { useBundleBuilder } from \"./useBundleBuilder\";\n\nexport type BundleBuilderDrawerControls = {\n isOpen: boolean;\n open: () => void;\n close: () => void;\n toggle: () => void;\n};\n\n/**\n * Convenience hook for controlling the drawer (alternative to using <BundleButton />).\n * Must be used within <BundleProvider />.\n */\nexport function useBundleBuilderDrawer(): BundleBuilderDrawerControls {\n const { isOpen, open, close, toggle } = useBundleBuilder();\n return { isOpen, open, close, toggle };\n}\n\n","import React from \"react\";\nimport { useBundleBuilder } from \"../hooks/useBundleBuilder\";\nimport styles from \"./BundleButton.module.css\";\n\nexport type BundleButtonProps = {\n children?: React.ReactNode;\n className?: string;\n};\n\nexport function BundleButton(props: BundleButtonProps) {\n const { toggle } = useBundleBuilder();\n return (\n <button\n type=\"button\"\n onClick={toggle}\n className={[styles.button, props.className].filter(Boolean).join(\" \")}\n >\n {props.children ?? \"Build a bundle\"}\n </button>\n );\n}\n\n","/**\n * @license lucide-react v0.515.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nconst toKebabCase = (string) => string.replace(/([a-z0-9])([A-Z])/g, \"$1-$2\").toLowerCase();\nconst toCamelCase = (string) => string.replace(\n /^([A-Z])|[\\s-_]+(\\w)/g,\n (match, p1, p2) => p2 ? p2.toUpperCase() : p1.toLowerCase()\n);\nconst toPascalCase = (string) => {\n const camelCase = toCamelCase(string);\n return camelCase.charAt(0).toUpperCase() + camelCase.slice(1);\n};\nconst mergeClasses = (...classes) => classes.filter((className, index, array) => {\n return Boolean(className) && className.trim() !== \"\" && array.indexOf(className) === index;\n}).join(\" \").trim();\nconst hasA11yProp = (props) => {\n for (const prop in props) {\n if (prop.startsWith(\"aria-\") || prop === \"role\" || prop === \"title\") {\n return true;\n }\n }\n};\n\nexport { hasA11yProp, mergeClasses, toCamelCase, toKebabCase, toPascalCase };\n//# sourceMappingURL=utils.js.map\n","/**\n * @license lucide-react v0.515.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nvar defaultAttributes = {\n xmlns: \"http://www.w3.org/2000/svg\",\n width: 24,\n height: 24,\n viewBox: \"0 0 24 24\",\n fill: \"none\",\n stroke: \"currentColor\",\n strokeWidth: 2,\n strokeLinecap: \"round\",\n strokeLinejoin: \"round\"\n};\n\nexport { defaultAttributes as default };\n//# sourceMappingURL=defaultAttributes.js.map\n","/**\n * @license lucide-react v0.515.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { forwardRef, createElement } from 'react';\nimport defaultAttributes from './defaultAttributes.js';\nimport { mergeClasses, hasA11yProp } from './shared/src/utils.js';\n\nconst Icon = forwardRef(\n ({\n color = \"currentColor\",\n size = 24,\n strokeWidth = 2,\n absoluteStrokeWidth,\n className = \"\",\n children,\n iconNode,\n ...rest\n }, ref) => createElement(\n \"svg\",\n {\n ref,\n ...defaultAttributes,\n width: size,\n height: size,\n stroke: color,\n strokeWidth: absoluteStrokeWidth ? Number(strokeWidth) * 24 / Number(size) : strokeWidth,\n className: mergeClasses(\"lucide\", className),\n ...!children && !hasA11yProp(rest) && { \"aria-hidden\": \"true\" },\n ...rest\n },\n [\n ...iconNode.map(([tag, attrs]) => createElement(tag, attrs)),\n ...Array.isArray(children) ? children : [children]\n ]\n )\n);\n\nexport { Icon as default };\n//# sourceMappingURL=Icon.js.map\n","/**\n * @license lucide-react v0.515.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport { forwardRef, createElement } from 'react';\nimport { mergeClasses, toKebabCase, toPascalCase } from './shared/src/utils.js';\nimport Icon from './Icon.js';\n\nconst createLucideIcon = (iconName, iconNode) => {\n const Component = forwardRef(\n ({ className, ...props }, ref) => createElement(Icon, {\n ref,\n iconNode,\n className: mergeClasses(\n `lucide-${toKebabCase(toPascalCase(iconName))}`,\n `lucide-${iconName}`,\n className\n ),\n ...props\n })\n );\n Component.displayName = toPascalCase(iconName);\n return Component;\n};\n\nexport { createLucideIcon as default };\n//# sourceMappingURL=createLucideIcon.js.map\n","/**\n * @license lucide-react v0.515.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\"path\", { d: \"m21 21-4.34-4.34\", key: \"14j7rj\" }],\n [\"circle\", { cx: \"11\", cy: \"11\", r: \"8\", key: \"4ej97u\" }]\n];\nconst Search = createLucideIcon(\"search\", __iconNode);\n\nexport { __iconNode, Search as default };\n//# sourceMappingURL=search.js.map\n","import React, { useEffect, useMemo, useRef, useState } from \"react\";\nimport { Search } from \"lucide-react\";\nimport { useBundleBuilder } from \"../hooks/useBundleBuilder\";\nimport styles from \"./BundleBuilderDrawer.module.css\";\n\nexport type BundleBuilderDrawerProps = {\n className?: string;\n};\n\nexport function BundleBuilderDrawer(props: BundleBuilderDrawerProps) {\n const {\n isOpen,\n close,\n loading,\n submitting,\n error,\n currencyCode,\n config,\n eligibleVariants,\n selections,\n selectionOrder,\n setQuantity,\n bundleSize,\n minRequired,\n canSubmit,\n submit,\n } = useBundleBuilder();\n\n const [isSearchOpen, setIsSearchOpen] = useState(false);\n const [searchQuery, setSearchQuery] = useState(\"\");\n const searchInputRef = useRef<HTMLInputElement | null>(null);\n\n const formatVariantOptions = (selectedOptions: Array<{ name: string; value: string }> | null | undefined) => {\n const opts = (selectedOptions ?? []).filter((o) => {\n const name = o?.name?.trim();\n const value = o?.value?.trim();\n if (!name || !value) return false;\n if (name.toLowerCase() === \"title\") return false;\n return true;\n });\n if (!opts.length) return null;\n return opts.map((o) => `${o.name}: ${o.value}`).join(\" · \");\n };\n\n const getVariantPrimaryName = (v: (typeof eligibleVariants)[number]) => {\n return v.product?.title ?? v.displayName ?? v.title;\n };\n\n const getVariantA11yLabel = (v: (typeof eligibleVariants)[number]) => {\n const name = getVariantPrimaryName(v);\n const opts = formatVariantOptions(v.selectedOptions);\n return [name, opts].filter(Boolean).join(\" — \");\n };\n\n const [isMounted, setIsMounted] = useState(isOpen);\n const closeTimerRef = useRef<number | null>(null);\n\n const formatMoney = (amount: string) => {\n const n = Number(amount);\n if (!Number.isFinite(n)) return amount;\n\n if (currencyCode) {\n try {\n return new Intl.NumberFormat(undefined, { style: \"currency\", currency: currencyCode }).format(n);\n } catch {\n // ignore and fall through\n }\n }\n\n return `$${n.toFixed(2)}`;\n };\n\n const title = config?.title?.trim() || \"Build your bundle\";\n\n const sorted = useMemo(() => {\n return [...eligibleVariants].sort((a, b) => a.displayName.localeCompare(b.displayName));\n }, [eligibleVariants]);\n\n const filteredVariants = useMemo(() => {\n const q = searchQuery.trim().toLowerCase();\n if (!q) return sorted;\n\n const tokens = q.split(/\\s+/).filter(Boolean);\n const matches = (v: (typeof sorted)[number]) => {\n const parts: string[] = [];\n parts.push(v.displayName);\n if (v.product?.title) parts.push(v.product.title);\n for (const o of v.selectedOptions ?? []) {\n parts.push(o.name);\n parts.push(o.value);\n }\n const haystack = parts.join(\" \").toLowerCase();\n return tokens.every((t) => haystack.includes(t));\n };\n\n return sorted.filter(matches);\n }, [searchQuery, sorted]);\n\n const rulesSorted = useMemo(() => {\n return [...(config?.rules ?? [])].sort((a, b) => a.minBundleSize - b.minBundleSize);\n }, [config?.rules]);\n\n const itemsRemaining = useMemo(() => Math.max(0, minRequired - bundleSize), [bundleSize, minRequired]);\n\n const appliedRule = useMemo(() => {\n let best = null as (typeof rulesSorted)[number] | null;\n for (const r of rulesSorted) {\n if (bundleSize >= r.minBundleSize) best = r;\n }\n return best;\n }, [bundleSize, rulesSorted]);\n\n const appliedDiscountPercent = useMemo(() => {\n if (!appliedRule) return null;\n const pct = Number.parseFloat(appliedRule.discountPercent);\n if (!Number.isFinite(pct) || pct <= 0) return null;\n return pct;\n }, [appliedRule]);\n\n const minRuleDiscountPercent = useMemo(() => {\n const r = rulesSorted[0];\n if (!r) return null;\n const pct = Number.parseFloat(r.discountPercent);\n if (!Number.isFinite(pct) || pct <= 0) return null;\n return pct;\n }, [rulesSorted]);\n\n const badgeDiscountPercent = appliedDiscountPercent ?? minRuleDiscountPercent;\n\n const subtotal = useMemo(() => {\n const byId = new Map(eligibleVariants.map((v) => [v.id, v] as const));\n let total = 0;\n for (const [variantId, qty] of Object.entries(selections)) {\n const q = qty ?? 0;\n if (q <= 0) continue;\n const v = byId.get(variantId);\n const price = Number(v?.price);\n if (!Number.isFinite(price)) continue;\n total += price * q;\n }\n // Keep cents stable for display.\n return Math.round(total * 100) / 100;\n }, [eligibleVariants, selections]);\n\n const discountedTotal = useMemo(() => {\n if (!appliedDiscountPercent) return subtotal;\n const total = subtotal * (1 - appliedDiscountPercent / 100);\n return Math.round(total * 100) / 100;\n }, [appliedDiscountPercent, subtotal]);\n\n const maxRuleSize = useMemo(() => {\n if (!rulesSorted.length) return 0;\n return Math.max(...rulesSorted.map((r) => r.minBundleSize));\n }, [rulesSorted]);\n\n const filledVariants = useMemo(() => {\n const byId = new Map(eligibleVariants.map((v) => [v.id, v] as const));\n return selectionOrder\n .map((variantId) => byId.get(variantId))\n .filter((v): v is (typeof eligibleVariants)[number] => Boolean(v));\n }, [eligibleVariants, selectionOrder]);\n\n const thresholdByIndex = useMemo(() => {\n // Slot index (0-based) => rule that becomes active at that slot.\n const map = new Map<number, { discountPercent: string; minBundleSize: number; label: string }>();\n for (const r of rulesSorted) {\n const idx = Math.max(0, r.minBundleSize - 1);\n map.set(idx, {\n discountPercent: r.discountPercent,\n minBundleSize: r.minBundleSize,\n label: r.label?.trim() || `Buy ${r.minBundleSize}+`,\n });\n }\n return map;\n }, [rulesSorted]);\n\n const slotCount = useMemo(() => {\n // Placeholders show until highest tier; if user adds more, extend (scroll).\n return Math.max(maxRuleSize || minRequired, filledVariants.length);\n }, [filledVariants.length, maxRuleSize, minRequired]);\n\n const panelRef = useRef<HTMLDivElement | null>(null);\n const bodyRef = useRef<HTMLDivElement | null>(null);\n const boxSummaryWindowRef = useRef<HTMLDivElement | null>(null);\n const prevBundleSizeRef = useRef<number>(bundleSize);\n\n const scrollVariantRowIntoView = (variantId: string) => {\n const container = bodyRef.current;\n if (!container) return;\n const row = container.querySelector<HTMLElement>(`[data-variant-row=\"${variantId}\"]`);\n if (!row) return;\n\n const c = container.getBoundingClientRect();\n const r = row.getBoundingClientRect();\n const padding = 8;\n const isFullyVisible = r.top >= c.top + padding && r.bottom <= c.bottom - padding;\n if (isFullyVisible) return;\n\n const maxTop = Math.max(0, container.scrollHeight - container.clientHeight);\n const rowCenterOffset = (r.top - c.top) + r.height / 2;\n const targetTop = container.scrollTop + rowCenterOffset - container.clientHeight / 2;\n const nextTop = Math.min(maxTop, Math.max(0, targetTop));\n container.scrollTo({ top: nextTop, behavior: \"smooth\" });\n };\n\n useEffect(() => {\n if (!isOpen) return;\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") close();\n };\n window.addEventListener(\"keydown\", onKeyDown);\n return () => window.removeEventListener(\"keydown\", onKeyDown);\n }, [close, isOpen]);\n\n useEffect(() => {\n if (closeTimerRef.current != null) {\n window.clearTimeout(closeTimerRef.current);\n closeTimerRef.current = null;\n }\n\n if (isOpen) {\n setIsMounted(true);\n return;\n }\n\n // Keep mounted long enough to play exit animation.\n closeTimerRef.current = window.setTimeout(() => {\n setIsMounted(false);\n closeTimerRef.current = null;\n }, 220);\n }, [isOpen]);\n\n useEffect(() => {\n return () => {\n if (closeTimerRef.current != null) window.clearTimeout(closeTimerRef.current);\n };\n }, []);\n\n useEffect(() => {\n if (!isOpen) return;\n if (!isSearchOpen) return;\n const raf = requestAnimationFrame(() => searchInputRef.current?.focus());\n return () => cancelAnimationFrame(raf);\n }, [isOpen, isSearchOpen]);\n\n useEffect(() => {\n const prev = prevBundleSizeRef.current;\n prevBundleSizeRef.current = bundleSize;\n\n // Only respond to adds (qty increases).\n if (bundleSize <= prev) return;\n\n const container = boxSummaryWindowRef.current;\n if (!container) return;\n\n const hitThreshold = rulesSorted.some((r) => r.minBundleSize === bundleSize);\n const nextThreshold = rulesSorted.find((r) => r.minBundleSize > bundleSize);\n\n // When hitting a threshold, try to reveal the NEXT threshold (aligned right) if it's off-screen to the right.\n // If no remaining thresholds, scroll the newest added item into view.\n const targetIdx = nextThreshold && hitThreshold ? nextThreshold.minBundleSize - 1 : !nextThreshold ? bundleSize - 1 : null;\n if (targetIdx == null || targetIdx < 0) return;\n\n const raf = requestAnimationFrame(() => {\n const el = container.querySelector<HTMLElement>(`[data-box-slot=\"${targetIdx}\"]`);\n if (!el) return;\n\n const containerRect = container.getBoundingClientRect();\n const elRect = el.getBoundingClientRect();\n const deltaRight = elRect.right - containerRect.right;\n\n // Only scroll rightward when the target is off-screen to the right.\n if (deltaRight <= 1) return;\n\n const maxLeft = Math.max(0, container.scrollWidth - container.clientWidth);\n const nextLeft = Math.min(maxLeft, Math.max(0, container.scrollLeft + deltaRight));\n container.scrollTo({ left: nextLeft, behavior: \"smooth\" });\n });\n\n return () => cancelAnimationFrame(raf);\n }, [bundleSize, rulesSorted]);\n\n useEffect(() => {\n if (!isOpen) return;\n panelRef.current?.focus();\n }, [isOpen]);\n\n if (!isMounted) return null;\n\n return (\n <div\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Bundle builder\"\n className={[styles.backdrop, isOpen ? styles.backdropOpen : styles.backdropClosed, props.className].filter(Boolean).join(\" \")}\n onMouseDown={(e) => {\n if (e.target === e.currentTarget) close();\n }}\n >\n <aside ref={panelRef} className={[styles.panel, isOpen ? styles.panelOpen : styles.panelClosed].filter(Boolean).join(\" \")} tabIndex={-1}>\n <header className={[styles.header, isSearchOpen ? styles.headerSearchOpen : null].filter(Boolean).join(\" \")}>\n <button\n type=\"button\"\n className={styles.searchIconButton}\n aria-label={isSearchOpen ? \"Search (expanded)\" : \"Search\"}\n aria-expanded={isSearchOpen}\n onClick={() => {\n setIsSearchOpen(true);\n }}\n >\n <Search size={18} aria-hidden=\"true\" />\n </button>\n\n <div className={styles.headerCenter}>\n <div className={styles.headerTitleWrap} aria-hidden={isSearchOpen}>\n <h2 className={styles.title}>{title}</h2>\n </div>\n\n <div className={styles.headerSearchWrap} aria-hidden={!isSearchOpen}>\n <div className={styles.searchBar}>\n <input\n ref={searchInputRef}\n className={styles.searchInput}\n type=\"search\"\n value={searchQuery}\n placeholder=\"Search\"\n onChange={(e) => setSearchQuery(e.target.value)}\n onBlur={() => {\n if (searchQuery.trim() === \"\") setIsSearchOpen(false);\n }}\n />\n {searchQuery.trim() ? (\n <button\n type=\"button\"\n className={styles.searchClearButton}\n onMouseDown={(e) => {\n // Prevent input blur so the bar stays open and focused.\n e.preventDefault();\n }}\n onClick={() => {\n setSearchQuery(\"\");\n searchInputRef.current?.focus();\n }}\n aria-label=\"Clear search\"\n >\n Clear\n </button>\n ) : null}\n </div>\n </div>\n </div>\n\n <button type=\"button\" onClick={close} disabled={submitting} className={styles.closeButton} aria-label=\"Close\">\n ×\n </button>\n </header>\n\n <div className={styles.body} ref={bodyRef}>\n {loading ? <p className={styles.muted}>Loading…</p> : null}\n {error ? <p className={styles.error}>{error}</p> : null}\n {!loading && config && !config.isActive ? <p className={styles.error}>Bundles are not active.</p> : null}\n\n <div className={styles.variants}>\n <ul className={styles.variantList}>\n {filteredVariants.map((v) => {\n const qty = selections[v.id] ?? 0;\n const variantPrimaryName = getVariantPrimaryName(v);\n const variantOptionText = formatVariantOptions(v.selectedOptions);\n const variantA11y = getVariantA11yLabel(v);\n\n // Price display:\n // - Always show a \"discounted\" price based on the unlocked discount, falling back to the minimum rule discount.\n // - Show the original price with a strikethrough when a discount applies.\n const discountPercentToUse = badgeDiscountPercent;\n const originalPriceNumber = Number(v.price);\n const hasDiscount =\n discountPercentToUse != null &&\n Number.isFinite(discountPercentToUse) &&\n discountPercentToUse > 0 &&\n Number.isFinite(originalPriceNumber);\n const discountedPriceNumber = hasDiscount\n ? Math.round(originalPriceNumber * (1 - discountPercentToUse / 100) * 100) / 100\n : null;\n\n return (\n <li key={v.id} className={styles.variantRow} data-variant-row={v.id}>\n <div className={styles.variantLeft}>\n <div className={styles.variantThumb} aria-hidden=\"true\">\n {v.image?.url ? (\n <img\n className={styles.variantThumbImg}\n src={v.image.url}\n alt={v.image.altText ?? variantA11y}\n loading=\"lazy\"\n />\n ) : (\n <div className={styles.variantThumbFallback}>{v.product?.title?.slice(0, 1)?.toUpperCase() ?? \"•\"}</div>\n )}\n </div>\n\n <div className={styles.variantInfo}>\n <div className={styles.variantName}>{variantPrimaryName}</div>\n {variantOptionText ? <div className={styles.variantMeta}>{variantOptionText}</div> : null}\n <div className={styles.variantPriceRow}>\n {hasDiscount ? (\n <span className={styles.variantCompareAt}>\n {formatMoney(Number.isFinite(originalPriceNumber) ? originalPriceNumber.toFixed(2) : v.price)}\n </span>\n ) : null}\n <span className={styles.variantPrice}>\n {formatMoney(\n discountedPriceNumber != null\n ? discountedPriceNumber.toFixed(2)\n : Number.isFinite(originalPriceNumber)\n ? originalPriceNumber.toFixed(2)\n : v.price,\n )}\n </span>\n </div>\n </div>\n </div>\n {qty <= 0 ? (\n <button\n type=\"button\"\n onClick={() => setQuantity(v.id, 1)}\n disabled={submitting}\n className={styles.addToBundleButton}\n aria-label={`Add ${variantA11y} to bundle`}\n >\n Add\n </button>\n ) : (\n <div className={styles.qtyControls}>\n <button\n type=\"button\"\n onClick={() => setQuantity(v.id, qty - 1)}\n disabled={submitting || qty <= 0}\n className={styles.qtyButton}\n aria-label={`Decrease ${variantA11y}`}\n >\n −\n </button>\n <span className={styles.qtyValue} aria-label={`Quantity ${qty}`}>\n {qty}\n </span>\n <button\n type=\"button\"\n onClick={() => setQuantity(v.id, qty + 1)}\n disabled={submitting}\n className={styles.qtyButton}\n aria-label={`Increase ${variantA11y}`}\n >\n +\n </button>\n </div>\n )}\n </li>\n );\n })}\n </ul>\n </div>\n </div>\n\n <footer className={styles.footer}>\n <div className={styles.boxSummaryWindow} ref={boxSummaryWindowRef}>\n <div className={styles.boxSummaryRow} aria-label=\"Bundle box summary\">\n {Array.from({ length: slotCount }).map((_, idx) => {\n const variant = filledVariants[idx];\n const threshold = thresholdByIndex.get(idx);\n const isFilled = Boolean(variant);\n\n // Per your preference: show discount text only while it's still a placeholder (unlocked display comes later elsewhere).\n const isThreshold = Boolean(threshold);\n const showThreshold = isThreshold && !isFilled;\n const discountText = threshold ? `${threshold.discountPercent}% off` : null;\n\n const titleText = isFilled ? variant!.displayName : `Slot ${idx + 1}`;\n\n return (\n <div key={idx} data-box-slot={idx} className={styles.boxSlot}>\n <div\n className={[\n styles.boxItem,\n isFilled ? styles.boxItemFilled : styles.boxItemPlaceholder,\n isThreshold ? styles.boxItemThreshold : null,\n isFilled ? styles.boxItemClickable : null,\n ]\n .filter(Boolean)\n .join(\" \")}\n role={isFilled ? \"button\" : undefined}\n tabIndex={isFilled ? 0 : undefined}\n onClick={isFilled ? () => scrollVariantRowIntoView(variant!.id) : undefined}\n onKeyDown={\n isFilled\n ? (e) => {\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n scrollVariantRowIntoView(variant!.id);\n }\n }\n : undefined\n }\n aria-label={showThreshold && discountText ? `${titleText}. Unlocks ${discountText}.` : titleText}\n title={showThreshold && discountText ? `${titleText} • Unlocks ${discountText}` : titleText}\n >\n {isFilled ? (\n variant!.image?.url ? (\n <img\n className={styles.boxItemImage}\n src={variant!.image!.url}\n alt={variant!.image!.altText ?? variant!.displayName}\n loading=\"lazy\"\n />\n ) : (\n <div className={styles.boxItemFallback} aria-hidden=\"true\">\n {variant!.product?.title?.slice(0, 1)?.toUpperCase() ?? \"•\"}\n </div>\n )\n ) : showThreshold && discountText ? (\n <div className={styles.boxItemDiscountText}>{discountText}</div>\n ) : (\n <div className={styles.boxItemPlus} aria-hidden=\"true\">\n +\n </div>\n )}\n </div>\n\n {isThreshold ? <div className={styles.boxThresholdLabel}>{threshold!.label}</div> : null}\n </div>\n );\n })}\n </div>\n </div>\n <div\n className={[styles.ctaTotalsWrap, itemsRemaining <= 0 ? styles.ctaTotalsWrapVisible : null].filter(Boolean).join(\" \")}\n aria-hidden={itemsRemaining > 0}\n >\n <div className={styles.ctaTotals} aria-label=\"Totals\">\n {badgeDiscountPercent ? (\n <span className={styles.ctaDiscountBadge}>\n {appliedDiscountPercent ? \"Unlocked \" : \"\"}\n {badgeDiscountPercent}% off\n </span>\n ) : (\n <span />\n )}\n\n <span>\n {appliedDiscountPercent ? (\n <>\n <span className={styles.ctaTotalsStrike}>{formatMoney(subtotal.toFixed(2))}</span>{\" \"}\n <span className={styles.ctaTotalsPrice}>{formatMoney(discountedTotal.toFixed(2))}</span>\n </>\n ) : (\n <span className={styles.ctaTotalsPrice}>{formatMoney(subtotal.toFixed(2))}</span>\n )}\n </span>\n </div>\n </div>\n\n <button type=\"button\" onClick={submit} disabled={!canSubmit} className={styles.cta}>\n {submitting ? \"Adding…\" : itemsRemaining > 0 ? `Add ${itemsRemaining} more product${itemsRemaining === 1 ? \"\" : \"s\"}` : \"Add to Basket\"}\n </button>\n </footer>\n </aside>\n </div>\n );\n}\n\n"],"names":["BundleLineAttributeKeys","fetchBundleConfig","params","url","json","BundleBuilderContext","createContext","safeRandomUUID","cryptoAny","clampQty","n","BundleProvider","props","apiBaseUrl","shop","cartAdapter","configHandle","initialData","configFetcher","children","isOpen","setIsOpen","useState","loading","setLoading","submitting","setSubmitting","error","setError","currencyCode","setCurrencyCode","config","setConfig","eligibleVariants","setEligibleVariants","selectionsState","setSelectionsState","abortRef","useRef","useEffect","_a","ac","fetcher","defaultFetchBundleConfig","e","msg","open","useCallback","close","toggle","v","setQuantity","merchandiseId","quantity","q","prev","prevQty","delta","nextSelections","_","rest","nextOrder","remainingToRemove","keptReversed","i","id","clearSelections","selections","selectionOrder","bundleSize","useMemo","sum","minRequired","rules","min","r","canSubmit","submit","bundleId","bundleTitle","lines","l","value","jsx","useBundleBuilder","ctx","useContext","useBundleBuilderDrawer","BundleButton","styles","toKebabCase","string","toCamelCase","match","p1","p2","toPascalCase","camelCase","mergeClasses","classes","className","index","array","hasA11yProp","prop","defaultAttributes","Icon","forwardRef","color","size","strokeWidth","absoluteStrokeWidth","iconNode","ref","createElement","tag","attrs","createLucideIcon","iconName","Component","__iconNode","Search","BundleBuilderDrawer","isSearchOpen","setIsSearchOpen","searchQuery","setSearchQuery","searchInputRef","formatVariantOptions","selectedOptions","opts","o","name","_b","getVariantPrimaryName","getVariantA11yLabel","isMounted","setIsMounted","closeTimerRef","formatMoney","amount","title","sorted","a","b","filteredVariants","tokens","matches","parts","haystack","t","rulesSorted","itemsRemaining","appliedRule","best","appliedDiscountPercent","pct","minRuleDiscountPercent","badgeDiscountPercent","subtotal","byId","total","variantId","qty","price","discountedTotal","maxRuleSize","filledVariants","thresholdByIndex","map","idx","slotCount","panelRef","bodyRef","boxSummaryWindowRef","prevBundleSizeRef","scrollVariantRowIntoView","container","row","c","padding","maxTop","rowCenterOffset","targetTop","nextTop","onKeyDown","raf","hitThreshold","nextThreshold","targetIdx","el","containerRect","deltaRight","maxLeft","nextLeft","jsxs","variantPrimaryName","variantOptionText","variantA11y","discountPercentToUse","originalPriceNumber","hasDiscount","discountedPriceNumber","_d","_c","variant","threshold","isFilled","isThreshold","showThreshold","discountText","titleText","Fragment"],"mappings":"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","x_google_ignoreList":[6,7,8,9,10]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BundleUI.stories.d.ts","sourceRoot":"","sources":["../../src/stories/BundleUI.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAKvD,QAAA,MAAM,IAAI,EAAE,IAEX,CAAC;AAEF,eAAe,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"BundleUI.stories.d.ts","sourceRoot":"","sources":["../../src/stories/BundleUI.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAKvD,QAAA,MAAM,IAAI,EAAE,IAEX,CAAC;AAEF,eAAe,IAAI,CAAC;AA8JpB,eAAO,MAAM,eAAe,EAAE,QAwB7B,CAAC;AAwBF,eAAO,MAAM,oBAAoB,EAAE,QAyBlC,CAAC;AAUF,eAAO,MAAM,qBAAqB,EAAE,QAyBnC,CAAC"}
|