@best-bundles/bundle-ui 0.0.1
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/api/fetchBundleConfig.d.ts +7 -0
- package/dist/api/fetchBundleConfig.d.ts.map +1 -0
- package/dist/components/BundleBuilderDrawer.d.ts +5 -0
- package/dist/components/BundleBuilderDrawer.d.ts.map +1 -0
- package/dist/components/BundleButton.d.ts +7 -0
- package/dist/components/BundleButton.d.ts.map +1 -0
- package/dist/constants.d.ts +6 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/context/BundleProvider.d.ts +56 -0
- package/dist/context/BundleProvider.d.ts.map +1 -0
- package/dist/hooks/useBundleBuilder.d.ts +2 -0
- package/dist/hooks/useBundleBuilder.d.ts.map +1 -0
- package/dist/hooks/useBundleBuilderDrawer.d.ts +12 -0
- package/dist/hooks/useBundleBuilderDrawer.d.ts.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +687 -0
- package/dist/index.js.map +1 -0
- package/dist/stories/BundleUI.stories.d.ts +7 -0
- package/dist/stories/BundleUI.stories.d.ts.map +1 -0
- package/dist/types.d.ts +67 -0
- package/dist/types.d.ts.map +1 -0
- package/package.json +52 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { PublicBundleConfigResponse } from "../types";
|
|
2
|
+
export declare function fetchBundleConfig(params: {
|
|
3
|
+
apiBaseUrl: string;
|
|
4
|
+
shop: string;
|
|
5
|
+
signal?: AbortSignal;
|
|
6
|
+
}): Promise<PublicBundleConfigResponse>;
|
|
7
|
+
//# sourceMappingURL=fetchBundleConfig.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetchBundleConfig.d.ts","sourceRoot":"","sources":["../../src/api/fetchBundleConfig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,UAAU,CAAC;AAE3D,wBAAsB,iBAAiB,CAAC,MAAM,EAAE;IAC9C,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAiBtC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BundleBuilderDrawer.d.ts","sourceRoot":"","sources":["../../src/components/BundleBuilderDrawer.tsx"],"names":[],"mappings":"AAKA,MAAM,MAAM,wBAAwB,GAAG;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,wBAAwB,kDA8iBlE"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export type BundleButtonProps = {
|
|
3
|
+
children?: React.ReactNode;
|
|
4
|
+
className?: string;
|
|
5
|
+
};
|
|
6
|
+
export declare function BundleButton(props: BundleButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
//# sourceMappingURL=BundleButton.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BundleButton.d.ts","sourceRoot":"","sources":["../../src/components/BundleButton.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,2CAWpD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,uBAAuB;;;;CAI1B,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { BundleCartAdapter, BundleConfig, BundleEligibleVariant, PublicBundleConfigResponse } from "../types";
|
|
3
|
+
type BundleProviderData = {
|
|
4
|
+
currencyCode: string | null;
|
|
5
|
+
config: BundleConfig;
|
|
6
|
+
eligibleVariants: BundleEligibleVariant[];
|
|
7
|
+
};
|
|
8
|
+
type BundleSelectionState = Record<string, number>;
|
|
9
|
+
type BundleSelectionOrder = string[];
|
|
10
|
+
export type BundleProviderProps = {
|
|
11
|
+
apiBaseUrl: string;
|
|
12
|
+
shop: string;
|
|
13
|
+
cartAdapter: BundleCartAdapter;
|
|
14
|
+
/**
|
|
15
|
+
* v1 default is "default" to mirror the app's current single-config endpoint.
|
|
16
|
+
* Kept as a prop to avoid an API break when the public endpoint supports multiple handles.
|
|
17
|
+
*/
|
|
18
|
+
configHandle?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Optional override for Storybook/tests so we can avoid network calls.
|
|
21
|
+
*/
|
|
22
|
+
initialData?: BundleProviderData;
|
|
23
|
+
/**
|
|
24
|
+
* Optional fetcher override for Storybook/tests.
|
|
25
|
+
*/
|
|
26
|
+
configFetcher?: (params: {
|
|
27
|
+
apiBaseUrl: string;
|
|
28
|
+
shop: string;
|
|
29
|
+
signal?: AbortSignal;
|
|
30
|
+
}) => Promise<PublicBundleConfigResponse>;
|
|
31
|
+
children: React.ReactNode;
|
|
32
|
+
};
|
|
33
|
+
export type BundleBuilderContextValue = {
|
|
34
|
+
isOpen: boolean;
|
|
35
|
+
open: () => void;
|
|
36
|
+
close: () => void;
|
|
37
|
+
toggle: () => void;
|
|
38
|
+
loading: boolean;
|
|
39
|
+
submitting: boolean;
|
|
40
|
+
error: string | null;
|
|
41
|
+
currencyCode: string | null;
|
|
42
|
+
config: BundleConfig | null;
|
|
43
|
+
eligibleVariants: BundleEligibleVariant[];
|
|
44
|
+
selections: BundleSelectionState;
|
|
45
|
+
selectionOrder: BundleSelectionOrder;
|
|
46
|
+
setQuantity: (merchandiseId: string, quantity: number) => void;
|
|
47
|
+
clearSelections: () => void;
|
|
48
|
+
bundleSize: number;
|
|
49
|
+
minRequired: number;
|
|
50
|
+
canSubmit: boolean;
|
|
51
|
+
submit: () => Promise<void>;
|
|
52
|
+
};
|
|
53
|
+
export declare const BundleBuilderContext: React.Context<BundleBuilderContextValue | null>;
|
|
54
|
+
export declare function BundleProvider(props: BundleProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
55
|
+
export {};
|
|
56
|
+
//# sourceMappingURL=BundleProvider.d.ts.map
|
|
@@ -0,0 +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,2CA8MxD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useBundleBuilder.d.ts","sourceRoot":"","sources":["../../src/hooks/useBundleBuilder.ts"],"names":[],"mappings":"AAGA,wBAAgB,gBAAgB,kEAM/B"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type BundleBuilderDrawerControls = {
|
|
2
|
+
isOpen: boolean;
|
|
3
|
+
open: () => void;
|
|
4
|
+
close: () => void;
|
|
5
|
+
toggle: () => void;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Convenience hook for controlling the drawer (alternative to using <BundleButton />).
|
|
9
|
+
* Must be used within <BundleProvider />.
|
|
10
|
+
*/
|
|
11
|
+
export declare function useBundleBuilderDrawer(): BundleBuilderDrawerControls;
|
|
12
|
+
//# sourceMappingURL=useBundleBuilderDrawer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useBundleBuilderDrawer.d.ts","sourceRoot":"","sources":["../../src/hooks/useBundleBuilderDrawer.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,2BAA2B,GAAG;IACxC,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,2BAA2B,CAGpE"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type { BundleCartAdapter } from "./types";
|
|
2
|
+
export type { BundleConfig, BundleEligibleVariant, BundleDiscountRule, PublicBundleConfigResponse } from "./types";
|
|
3
|
+
export { BundleLineAttributeKeys } from "./constants";
|
|
4
|
+
export { BundleProvider } from "./context/BundleProvider";
|
|
5
|
+
export { useBundleBuilder } from "./hooks/useBundleBuilder";
|
|
6
|
+
export { useBundleBuilderDrawer } from "./hooks/useBundleBuilderDrawer";
|
|
7
|
+
export type { BundleBuilderDrawerControls } from "./hooks/useBundleBuilderDrawer";
|
|
8
|
+
export { BundleButton } from "./components/BundleButton";
|
|
9
|
+
export { BundleBuilderDrawer } from "./components/BundleBuilderDrawer";
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AACjD,YAAY,EAAE,YAAY,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,0BAA0B,EAAE,MAAM,SAAS,CAAC;AACnH,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAEtD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AACxE,YAAY,EAAE,2BAA2B,EAAE,MAAM,gCAAgC,CAAC;AAElF,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,687 @@
|
|
|
1
|
+
(function(){"use strict";try{if(typeof document<"u"){var t=document.createElement("style");t.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_7tuld_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_7tuld_14{opacity:1}._backdropClosed_7tuld_18{opacity:0}._panel_7tuld_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}._panelOpen_7tuld_37{animation:_bbSlideInFromRight_7tuld_1 var(--bb-drawer-transition-duration, .22s) ease forwards}._panelClosed_7tuld_41{animation:_bbSlideOutToRight_7tuld_1 var(--bb-drawer-transition-duration, .22s) ease forwards}@keyframes _bbSlideInFromRight_7tuld_1{0%{transform:translate(110%)}to{transform:translate(0)}}@keyframes _bbSlideOutToRight_7tuld_1{0%{transform:translate(0)}to{transform:translate(110%)}}@media(prefers-reduced-motion:reduce){._backdrop_7tuld_1{transition:none}._panelOpen_7tuld_37,._panelClosed_7tuld_41{animation:none}}._header_7tuld_76{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_7tuld_85{position:relative;min-width:0;display:flex;justify-content:center;align-items:center}._title_7tuld_93{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_7tuld_102{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_7tuld_102:hover{background:var(--bb-control-bg-hover, rgba(17, 24, 39, .04))}._searchIconButton_7tuld_102:focus-visible{outline:2px solid var(--bb-focus-ring, #2563eb);outline-offset:2px}._headerTitleWrap_7tuld_124{transition:opacity .18s ease,transform .22s ease}._headerSearchWrap_7tuld_128{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_7tuld_140 ._headerTitleWrap_7tuld_124{opacity:0;transform:translateY(2px);pointer-events:none}._headerSearchOpen_7tuld_140 ._headerSearchWrap_7tuld_128{opacity:1;transform:translateY(0);pointer-events:auto}._searchBar_7tuld_152{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_7tuld_164{width:100%;border:none;outline:none;background:transparent;font:inherit;font-size:14px;min-width:0;height:100%;line-height:36px;padding:0}._searchInput_7tuld_164::-webkit-search-cancel-button,._searchInput_7tuld_164::-webkit-search-decoration,._searchInput_7tuld_164::-webkit-search-results-button,._searchInput_7tuld_164::-webkit-search-results-decoration{-webkit-appearance:none;-moz-appearance:none;appearance:none}._searchClearButton_7tuld_185{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_7tuld_185:hover{background:var(--bb-control-bg-hover, rgba(17, 24, 39, .04))}._searchClearButton_7tuld_185:focus-visible{outline:2px solid var(--bb-focus-ring, #2563eb);outline-offset:2px}._closeButton_7tuld_207{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_7tuld_207:hover{background:var(--bb-control-bg-hover, rgba(17, 24, 39, .04))}._closeButton_7tuld_207:disabled{opacity:.6;cursor:not-allowed}._closeButton_7tuld_207:focus-visible{outline:2px solid var(--bb-focus-ring, #2563eb);outline-offset:2px}@media(prefers-reduced-motion:reduce){._headerTitleWrap_7tuld_124,._headerSearchWrap_7tuld_128{transition:none}}._body_7tuld_240{padding:var(--bb-body-padding, 8px 16px);overflow:auto}._muted_7tuld_245{color:var(--bb-muted-strong-color, rgba(17, 24, 39, .65));margin:0 0 12px}._error_7tuld_250{color:var(--bb-error-color, #b91c1c);margin:0 0 12px}._variants_7tuld_255{margin-top:4px}._variantList_7tuld_259{list-style:none;padding:0;margin:0;display:grid;gap:10px}._variantRow_7tuld_267{display:grid;grid-template-columns:1fr auto;gap:0px;align-items:stretch;padding:5px}._variantLeft_7tuld_275{min-width:0;display:flex;gap:12px;align-items:center}._addToBundleButton_7tuld_282{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_7tuld_282:hover{background:var(--bb-cta-bg-hover, #1d4ed8)}._addToBundleButton_7tuld_282:disabled{opacity:.6;cursor:not-allowed}._addToBundleButton_7tuld_282:focus-visible{outline:2px solid var(--bb-focus-ring, #2563eb);outline-offset:2px}._variantThumb_7tuld_310{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_7tuld_320{width:100%;height:100%;object-fit:cover;display:block}._variantThumbFallback_7tuld_327{width:100%;height:100%;display:flex;align-items:center;justify-content:center;font-weight:800;color:var(--bb-text-color, #111827)}._variantInfo_7tuld_337{min-width:0}._variantName_7tuld_341{font-size:14px;font-weight:600;margin-bottom:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._variantMeta_7tuld_350{font-size:12px;color:var(--bb-muted-color, rgba(17, 24, 39, .6));overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._variantPriceRow_7tuld_358{display:flex;align-items:baseline;gap:8px;margin-top:4px}._variantCompareAt_7tuld_365{font-size:12px;color:var(--bb-muted-color, rgba(17, 24, 39, .6));text-decoration:line-through}._variantPrice_7tuld_358{font-size:13px;font-weight:800}._qtyControls_7tuld_376{display:inline-flex;align-items:center;gap:6px}._qtyButton_7tuld_382{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_7tuld_382:hover{background:var(--bb-control-bg-hover, rgba(17, 24, 39, .04))}._qtyButton_7tuld_382:disabled{opacity:.6;cursor:not-allowed}._qtyButton_7tuld_382:focus-visible{outline:2px solid var(--bb-focus-ring, #2563eb);outline-offset:2px}._qtyValue_7tuld_407{min-width:18px;text-align:center;font-variant-numeric:tabular-nums;font-weight:700}._footer_7tuld_414{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_7tuld_421{margin-bottom:6px;overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;padding-bottom:6px;scrollbar-width:none;-ms-overflow-style:none}._boxSummaryWindow_7tuld_421::-webkit-scrollbar{display:none}._boxSummaryRow_7tuld_438{--bb-box-gap: 10px;display:flex;align-items:flex-start;gap:var(--bb-box-gap);width:100%}._boxSlot_7tuld_446{flex:0 0 calc((100% - (4 * var(--bb-box-gap))) / 5);display:flex;flex-direction:column;align-items:stretch;gap:6px}._boxItem_7tuld_454{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_7tuld_466{cursor:pointer}._boxItemClickable_7tuld_466:focus-visible{outline:2px solid var(--bb-focus-ring, #2563eb);outline-offset:2px}._boxThresholdLabel_7tuld_475{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_7tuld_486{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_7tuld_492{border:1px solid var(--bb-border-color, rgba(17, 24, 39, .08));background:var(--bb-surface-bg, #ffffff);overflow:hidden}._boxItemThreshold_7tuld_498{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_7tuld_506{font-size:12px;font-weight:800;text-align:center;line-height:1.1;padding:6px}._boxItemPlus_7tuld_514{font-size:22px;font-weight:700;opacity:.5;line-height:1}._boxItemImage_7tuld_521{width:100%;height:100%;object-fit:cover;display:block}._boxItemFallback_7tuld_528{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_7tuld_539{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_7tuld_551{display:flex;justify-content:space-between;align-items:baseline;gap:10px;font-variant-numeric:tabular-nums}._ctaDiscountBadge_7tuld_559{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_7tuld_573{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_7tuld_586{max-height:40px;opacity:1;transform:translateY(0);margin-bottom:8px}._ctaTotalsStrike_7tuld_593{opacity:.85;text-decoration:line-through;font-weight:700;color:var(--bb-muted-strong-color, rgba(17, 24, 39, .65))}._ctaTotalsPrice_7tuld_600{font-weight:900;color:var(--bb-text-color, #111827)}@media(prefers-reduced-motion:reduce){._ctaTotalsWrap_7tuld_573{transition:none}}._cta_7tuld_539:hover{background:var(--bb-cta-bg-hover, #1d4ed8)}._cta_7tuld_539:disabled{opacity:.6;cursor:not-allowed}._cta_7tuld_539:focus-visible{outline:2px solid var(--bb-cta-focus-ring, var(--bb-text-color, #111827));outline-offset:2px}._helperText_7tuld_625{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_7tuld_1{padding:0;justify-content:stretch}._panel_7tuld_22{width:100%;height:100%;border-radius:0}}')),document.head.appendChild(t)}}catch(e){console.error("vite-plugin-css-injected-by-js",e)}})();
|
|
2
|
+
import { jsx as r, jsxs as N, Fragment as Te } from "react/jsx-runtime";
|
|
3
|
+
import { useState as k, useRef as K, useEffect as Z, useCallback as oe, useMemo as y, createContext as Ie, useContext as we, forwardRef as Be, createElement as ye } from "react";
|
|
4
|
+
const fe = {
|
|
5
|
+
bundleId: "_bundle_id",
|
|
6
|
+
bundleConfig: "_bundle_config",
|
|
7
|
+
bundleSource: "_bundle_source"
|
|
8
|
+
};
|
|
9
|
+
async function Se(o) {
|
|
10
|
+
const l = new URL("/api/public/bundle-config", o.apiBaseUrl);
|
|
11
|
+
l.searchParams.set("shop", o.shop);
|
|
12
|
+
const m = await (await fetch(l, {
|
|
13
|
+
method: "GET",
|
|
14
|
+
signal: o.signal,
|
|
15
|
+
headers: { "Content-Type": "application/json" }
|
|
16
|
+
})).json().catch(() => null);
|
|
17
|
+
return !m || typeof m != "object" ? { ok: !1, error: "Invalid response." } : m;
|
|
18
|
+
}
|
|
19
|
+
const Ne = Ie(null);
|
|
20
|
+
function ke() {
|
|
21
|
+
try {
|
|
22
|
+
const o = globalThis.crypto;
|
|
23
|
+
if (o != null && o.randomUUID) return o.randomUUID();
|
|
24
|
+
} catch {
|
|
25
|
+
}
|
|
26
|
+
return `bb_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;
|
|
27
|
+
}
|
|
28
|
+
function ge(o) {
|
|
29
|
+
return Number.isFinite(o) ? Math.max(0, Math.floor(o)) : 0;
|
|
30
|
+
}
|
|
31
|
+
function Qt(o) {
|
|
32
|
+
const {
|
|
33
|
+
apiBaseUrl: l,
|
|
34
|
+
shop: _,
|
|
35
|
+
cartAdapter: m,
|
|
36
|
+
configHandle: T = "default",
|
|
37
|
+
initialData: h,
|
|
38
|
+
configFetcher: U,
|
|
39
|
+
children: x
|
|
40
|
+
} = o, [w, L] = k(!1), [M, G] = k(!h), [g, E] = k(!1), [J, le] = k(null), [F, X] = k((h == null ? void 0 : h.currencyCode) ?? null), [p, Y] = k((h == null ? void 0 : h.config) ?? null), [ee, te] = k(
|
|
41
|
+
(h == null ? void 0 : h.eligibleVariants) ?? []
|
|
42
|
+
), [se, me] = k(
|
|
43
|
+
() => ({ selections: {}, order: [] })
|
|
44
|
+
), he = K(null);
|
|
45
|
+
Z(() => {
|
|
46
|
+
var B;
|
|
47
|
+
if (h) return;
|
|
48
|
+
(B = he.current) == null || B.abort();
|
|
49
|
+
const d = new AbortController();
|
|
50
|
+
he.current = d;
|
|
51
|
+
const C = U ?? Se;
|
|
52
|
+
return G(!0), le(null), C({ apiBaseUrl: l, shop: _, signal: d.signal }).then((i) => {
|
|
53
|
+
if (!i.ok) {
|
|
54
|
+
le(i.error || "Failed to load bundle config."), Y(null), te([]), X(null);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
X(i.currencyCode ?? null), Y(i.config), te(i.eligibleVariants ?? []);
|
|
58
|
+
}).catch((i) => {
|
|
59
|
+
const D = i instanceof Error ? i.message : "Failed to load bundle config.";
|
|
60
|
+
le(D), Y(null), te([]), X(null);
|
|
61
|
+
}).finally(() => G(!1)), () => d.abort();
|
|
62
|
+
}, [l, _, h, U]);
|
|
63
|
+
const ie = oe(() => L(!0), []), I = oe(() => L(!1), []), A = oe(() => L((d) => !d), []), be = oe((d, C) => {
|
|
64
|
+
const B = ge(C);
|
|
65
|
+
me((i) => {
|
|
66
|
+
const D = i.selections[d] ?? 0, ne = B - D;
|
|
67
|
+
let j;
|
|
68
|
+
if (B <= 0) {
|
|
69
|
+
const { [d]: re, ...z } = i.selections;
|
|
70
|
+
j = z;
|
|
71
|
+
} else D === B ? j = i.selections : j = { ...i.selections, [d]: B };
|
|
72
|
+
let Q = i.order;
|
|
73
|
+
if (ne > 0)
|
|
74
|
+
Q = [...i.order, ...Array.from({ length: ne }, () => d)];
|
|
75
|
+
else if (ne < 0) {
|
|
76
|
+
let re = -ne;
|
|
77
|
+
const z = [];
|
|
78
|
+
for (let ae = i.order.length - 1; ae >= 0; ae--) {
|
|
79
|
+
const ue = i.order[ae];
|
|
80
|
+
if (ue === d && re > 0) {
|
|
81
|
+
re--;
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
z.push(ue);
|
|
85
|
+
}
|
|
86
|
+
z.reverse(), Q = z;
|
|
87
|
+
}
|
|
88
|
+
return j === i.selections && Q === i.order ? i : { selections: j, order: Q };
|
|
89
|
+
});
|
|
90
|
+
}, []), $ = oe(() => me({ selections: {}, order: [] }), []), W = se.selections, v = se.order, P = y(() => Object.values(W).reduce((d, C) => d + (C || 0), 0), [W]), V = y(() => {
|
|
91
|
+
const d = (p == null ? void 0 : p.rules) ?? [], C = d.length ? Math.min(...d.map((B) => B.minBundleSize)) : 2;
|
|
92
|
+
return Number.isFinite(C) && C > 0 ? C : 2;
|
|
93
|
+
}, [p]), S = y(() => !(M || g || J || !(p != null && p.isActive) || P < V), [P, p == null ? void 0 : p.isActive, J, M, V, g]), _e = oe(async () => {
|
|
94
|
+
var B;
|
|
95
|
+
if (!S || !p) return;
|
|
96
|
+
const d = ke(), C = Object.entries(W).map(([i, D]) => ({ merchandiseId: i, quantity: ge(D) })).filter((i) => i.quantity > 0).map((i) => ({
|
|
97
|
+
merchandiseId: i.merchandiseId,
|
|
98
|
+
quantity: i.quantity,
|
|
99
|
+
attributes: [
|
|
100
|
+
{ key: fe.bundleId, value: d },
|
|
101
|
+
{ key: fe.bundleConfig, value: T },
|
|
102
|
+
{ key: fe.bundleSource, value: "bundle_builder" }
|
|
103
|
+
]
|
|
104
|
+
}));
|
|
105
|
+
if (C.length) {
|
|
106
|
+
E(!0);
|
|
107
|
+
try {
|
|
108
|
+
await m.linesAdd(C), $(), I(), (B = m.openCartUI) == null || B.call(m);
|
|
109
|
+
} finally {
|
|
110
|
+
E(!1);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}, [S, m, $, I, p, T, W]), ce = y(
|
|
114
|
+
() => ({
|
|
115
|
+
isOpen: w,
|
|
116
|
+
open: ie,
|
|
117
|
+
close: I,
|
|
118
|
+
toggle: A,
|
|
119
|
+
loading: M,
|
|
120
|
+
submitting: g,
|
|
121
|
+
error: J,
|
|
122
|
+
currencyCode: F,
|
|
123
|
+
config: p,
|
|
124
|
+
eligibleVariants: ee,
|
|
125
|
+
selections: W,
|
|
126
|
+
selectionOrder: v,
|
|
127
|
+
setQuantity: be,
|
|
128
|
+
clearSelections: $,
|
|
129
|
+
bundleSize: P,
|
|
130
|
+
minRequired: V,
|
|
131
|
+
canSubmit: S,
|
|
132
|
+
submit: _e
|
|
133
|
+
}),
|
|
134
|
+
[
|
|
135
|
+
w,
|
|
136
|
+
ie,
|
|
137
|
+
I,
|
|
138
|
+
A,
|
|
139
|
+
M,
|
|
140
|
+
g,
|
|
141
|
+
J,
|
|
142
|
+
F,
|
|
143
|
+
p,
|
|
144
|
+
ee,
|
|
145
|
+
W,
|
|
146
|
+
v,
|
|
147
|
+
be,
|
|
148
|
+
$,
|
|
149
|
+
P,
|
|
150
|
+
V,
|
|
151
|
+
S,
|
|
152
|
+
_e
|
|
153
|
+
]
|
|
154
|
+
);
|
|
155
|
+
return /* @__PURE__ */ r(Ne.Provider, { value: ce, children: x });
|
|
156
|
+
}
|
|
157
|
+
function xe() {
|
|
158
|
+
const o = we(Ne);
|
|
159
|
+
if (!o)
|
|
160
|
+
throw new Error("useBundleBuilder must be used within <BundleProvider />");
|
|
161
|
+
return o;
|
|
162
|
+
}
|
|
163
|
+
function Ht() {
|
|
164
|
+
const { isOpen: o, open: l, close: _, toggle: m } = xe();
|
|
165
|
+
return { isOpen: o, open: l, close: _, toggle: m };
|
|
166
|
+
}
|
|
167
|
+
const Fe = "_button_18rtl_1", Pe = {
|
|
168
|
+
button: Fe
|
|
169
|
+
};
|
|
170
|
+
function Kt(o) {
|
|
171
|
+
const { toggle: l } = xe();
|
|
172
|
+
return /* @__PURE__ */ r(
|
|
173
|
+
"button",
|
|
174
|
+
{
|
|
175
|
+
type: "button",
|
|
176
|
+
onClick: l,
|
|
177
|
+
className: [Pe.button, o.className].filter(Boolean).join(" "),
|
|
178
|
+
children: o.children ?? "Build a bundle"
|
|
179
|
+
}
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* @license lucide-react v0.515.0 - ISC
|
|
184
|
+
*
|
|
185
|
+
* This source code is licensed under the ISC license.
|
|
186
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
187
|
+
*/
|
|
188
|
+
const Re = (o) => o.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase(), Oe = (o) => o.replace(
|
|
189
|
+
/^([A-Z])|[\s-_]+(\w)/g,
|
|
190
|
+
(l, _, m) => m ? m.toUpperCase() : _.toLowerCase()
|
|
191
|
+
), ve = (o) => {
|
|
192
|
+
const l = Oe(o);
|
|
193
|
+
return l.charAt(0).toUpperCase() + l.slice(1);
|
|
194
|
+
}, Ce = (...o) => o.filter((l, _, m) => !!l && l.trim() !== "" && m.indexOf(l) === _).join(" ").trim(), Le = (o) => {
|
|
195
|
+
for (const l in o)
|
|
196
|
+
if (l.startsWith("aria-") || l === "role" || l === "title")
|
|
197
|
+
return !0;
|
|
198
|
+
};
|
|
199
|
+
/**
|
|
200
|
+
* @license lucide-react v0.515.0 - ISC
|
|
201
|
+
*
|
|
202
|
+
* This source code is licensed under the ISC license.
|
|
203
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
204
|
+
*/
|
|
205
|
+
var Me = {
|
|
206
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
207
|
+
width: 24,
|
|
208
|
+
height: 24,
|
|
209
|
+
viewBox: "0 0 24 24",
|
|
210
|
+
fill: "none",
|
|
211
|
+
stroke: "currentColor",
|
|
212
|
+
strokeWidth: 2,
|
|
213
|
+
strokeLinecap: "round",
|
|
214
|
+
strokeLinejoin: "round"
|
|
215
|
+
};
|
|
216
|
+
/**
|
|
217
|
+
* @license lucide-react v0.515.0 - ISC
|
|
218
|
+
*
|
|
219
|
+
* This source code is licensed under the ISC license.
|
|
220
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
221
|
+
*/
|
|
222
|
+
const qe = Be(
|
|
223
|
+
({
|
|
224
|
+
color: o = "currentColor",
|
|
225
|
+
size: l = 24,
|
|
226
|
+
strokeWidth: _ = 2,
|
|
227
|
+
absoluteStrokeWidth: m,
|
|
228
|
+
className: T = "",
|
|
229
|
+
children: h,
|
|
230
|
+
iconNode: U,
|
|
231
|
+
...x
|
|
232
|
+
}, w) => ye(
|
|
233
|
+
"svg",
|
|
234
|
+
{
|
|
235
|
+
ref: w,
|
|
236
|
+
...Me,
|
|
237
|
+
width: l,
|
|
238
|
+
height: l,
|
|
239
|
+
stroke: o,
|
|
240
|
+
strokeWidth: m ? Number(_) * 24 / Number(l) : _,
|
|
241
|
+
className: Ce("lucide", T),
|
|
242
|
+
...!h && !Le(x) && { "aria-hidden": "true" },
|
|
243
|
+
...x
|
|
244
|
+
},
|
|
245
|
+
[
|
|
246
|
+
...U.map(([L, M]) => ye(L, M)),
|
|
247
|
+
...Array.isArray(h) ? h : [h]
|
|
248
|
+
]
|
|
249
|
+
)
|
|
250
|
+
);
|
|
251
|
+
/**
|
|
252
|
+
* @license lucide-react v0.515.0 - ISC
|
|
253
|
+
*
|
|
254
|
+
* This source code is licensed under the ISC license.
|
|
255
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
256
|
+
*/
|
|
257
|
+
const Ae = (o, l) => {
|
|
258
|
+
const _ = Be(
|
|
259
|
+
({ className: m, ...T }, h) => ye(qe, {
|
|
260
|
+
ref: h,
|
|
261
|
+
iconNode: l,
|
|
262
|
+
className: Ce(
|
|
263
|
+
`lucide-${Re(ve(o))}`,
|
|
264
|
+
`lucide-${o}`,
|
|
265
|
+
m
|
|
266
|
+
),
|
|
267
|
+
...T
|
|
268
|
+
})
|
|
269
|
+
);
|
|
270
|
+
return _.displayName = ve(o), _;
|
|
271
|
+
};
|
|
272
|
+
/**
|
|
273
|
+
* @license lucide-react v0.515.0 - ISC
|
|
274
|
+
*
|
|
275
|
+
* This source code is licensed under the ISC license.
|
|
276
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
277
|
+
*/
|
|
278
|
+
const $e = [
|
|
279
|
+
["path", { d: "m21 21-4.34-4.34", key: "14j7rj" }],
|
|
280
|
+
["circle", { cx: "11", cy: "11", r: "8", key: "4ej97u" }]
|
|
281
|
+
], We = Ae("search", $e), Ve = "_backdrop_7tuld_1", De = "_backdropOpen_7tuld_14", je = "_backdropClosed_7tuld_18", ze = "_panel_7tuld_22", Ue = "_panelOpen_7tuld_37", Ee = "_panelClosed_7tuld_41", Qe = "_header_7tuld_76", He = "_headerCenter_7tuld_85", Ke = "_title_7tuld_93", Ze = "_searchIconButton_7tuld_102", Ge = "_headerTitleWrap_7tuld_124", Je = "_headerSearchWrap_7tuld_128", Xe = "_headerSearchOpen_7tuld_140", Ye = "_searchBar_7tuld_152", et = "_searchInput_7tuld_164", tt = "_searchClearButton_7tuld_185", nt = "_closeButton_7tuld_207", rt = "_body_7tuld_240", at = "_muted_7tuld_245", ot = "_error_7tuld_250", lt = "_variants_7tuld_255", st = "_variantList_7tuld_259", it = "_variantRow_7tuld_267", ct = "_variantLeft_7tuld_275", ut = "_addToBundleButton_7tuld_282", dt = "_variantThumb_7tuld_310", mt = "_variantThumbImg_7tuld_320", ht = "_variantThumbFallback_7tuld_327", bt = "_variantInfo_7tuld_337", _t = "_variantName_7tuld_341", pt = "_variantMeta_7tuld_350", ft = "_variantPriceRow_7tuld_358", yt = "_variantCompareAt_7tuld_365", xt = "_variantPrice_7tuld_358", gt = "_qtyControls_7tuld_376", vt = "_qtyButton_7tuld_382", Bt = "_qtyValue_7tuld_407", Nt = "_footer_7tuld_414", Ct = "_boxSummaryWindow_7tuld_421", Tt = "_boxSummaryRow_7tuld_438", It = "_boxSlot_7tuld_446", wt = "_boxItem_7tuld_454", St = "_boxItemClickable_7tuld_466", kt = "_boxThresholdLabel_7tuld_475", Ft = "_boxItemPlaceholder_7tuld_486", Pt = "_boxItemFilled_7tuld_492", Rt = "_boxItemThreshold_7tuld_498", Ot = "_boxItemDiscountText_7tuld_506", Lt = "_boxItemPlus_7tuld_514", Mt = "_boxItemImage_7tuld_521", qt = "_boxItemFallback_7tuld_528", At = "_cta_7tuld_539", $t = "_ctaTotals_7tuld_551", Wt = "_ctaDiscountBadge_7tuld_559", Vt = "_ctaTotalsWrap_7tuld_573", Dt = "_ctaTotalsWrapVisible_7tuld_586", jt = "_ctaTotalsStrike_7tuld_593", zt = "_ctaTotalsPrice_7tuld_600", n = {
|
|
282
|
+
backdrop: Ve,
|
|
283
|
+
backdropOpen: De,
|
|
284
|
+
backdropClosed: je,
|
|
285
|
+
panel: ze,
|
|
286
|
+
panelOpen: Ue,
|
|
287
|
+
panelClosed: Ee,
|
|
288
|
+
header: Qe,
|
|
289
|
+
headerCenter: He,
|
|
290
|
+
title: Ke,
|
|
291
|
+
searchIconButton: Ze,
|
|
292
|
+
headerTitleWrap: Ge,
|
|
293
|
+
headerSearchWrap: Je,
|
|
294
|
+
headerSearchOpen: Xe,
|
|
295
|
+
searchBar: Ye,
|
|
296
|
+
searchInput: et,
|
|
297
|
+
searchClearButton: tt,
|
|
298
|
+
closeButton: nt,
|
|
299
|
+
body: rt,
|
|
300
|
+
muted: at,
|
|
301
|
+
error: ot,
|
|
302
|
+
variants: lt,
|
|
303
|
+
variantList: st,
|
|
304
|
+
variantRow: it,
|
|
305
|
+
variantLeft: ct,
|
|
306
|
+
addToBundleButton: ut,
|
|
307
|
+
variantThumb: dt,
|
|
308
|
+
variantThumbImg: mt,
|
|
309
|
+
variantThumbFallback: ht,
|
|
310
|
+
variantInfo: bt,
|
|
311
|
+
variantName: _t,
|
|
312
|
+
variantMeta: pt,
|
|
313
|
+
variantPriceRow: ft,
|
|
314
|
+
variantCompareAt: yt,
|
|
315
|
+
variantPrice: xt,
|
|
316
|
+
qtyControls: gt,
|
|
317
|
+
qtyButton: vt,
|
|
318
|
+
qtyValue: Bt,
|
|
319
|
+
footer: Nt,
|
|
320
|
+
boxSummaryWindow: Ct,
|
|
321
|
+
boxSummaryRow: Tt,
|
|
322
|
+
boxSlot: It,
|
|
323
|
+
boxItem: wt,
|
|
324
|
+
boxItemClickable: St,
|
|
325
|
+
boxThresholdLabel: kt,
|
|
326
|
+
boxItemPlaceholder: Ft,
|
|
327
|
+
boxItemFilled: Pt,
|
|
328
|
+
boxItemThreshold: Rt,
|
|
329
|
+
boxItemDiscountText: Ot,
|
|
330
|
+
boxItemPlus: Lt,
|
|
331
|
+
boxItemImage: Mt,
|
|
332
|
+
boxItemFallback: qt,
|
|
333
|
+
cta: At,
|
|
334
|
+
ctaTotals: $t,
|
|
335
|
+
ctaDiscountBadge: Wt,
|
|
336
|
+
ctaTotalsWrap: Vt,
|
|
337
|
+
ctaTotalsWrapVisible: Dt,
|
|
338
|
+
ctaTotalsStrike: jt,
|
|
339
|
+
ctaTotalsPrice: zt
|
|
340
|
+
};
|
|
341
|
+
function Zt(o) {
|
|
342
|
+
var ue;
|
|
343
|
+
const {
|
|
344
|
+
isOpen: l,
|
|
345
|
+
close: _,
|
|
346
|
+
loading: m,
|
|
347
|
+
submitting: T,
|
|
348
|
+
error: h,
|
|
349
|
+
currencyCode: U,
|
|
350
|
+
config: x,
|
|
351
|
+
eligibleVariants: w,
|
|
352
|
+
selections: L,
|
|
353
|
+
selectionOrder: M,
|
|
354
|
+
setQuantity: G,
|
|
355
|
+
bundleSize: g,
|
|
356
|
+
minRequired: E,
|
|
357
|
+
canSubmit: J,
|
|
358
|
+
submit: le
|
|
359
|
+
} = xe(), [F, X] = k(!1), [p, Y] = k(""), ee = K(null), te = (e) => {
|
|
360
|
+
const t = (e ?? []).filter((a) => {
|
|
361
|
+
var b, u;
|
|
362
|
+
const c = (b = a == null ? void 0 : a.name) == null ? void 0 : b.trim(), s = (u = a == null ? void 0 : a.value) == null ? void 0 : u.trim();
|
|
363
|
+
return !(!c || !s || c.toLowerCase() === "title");
|
|
364
|
+
});
|
|
365
|
+
return t.length ? t.map((a) => `${a.name}: ${a.value}`).join(" · ") : null;
|
|
366
|
+
}, se = (e) => {
|
|
367
|
+
var t;
|
|
368
|
+
return ((t = e.product) == null ? void 0 : t.title) ?? e.displayName ?? e.title;
|
|
369
|
+
}, me = (e) => {
|
|
370
|
+
const t = se(e), a = te(e.selectedOptions);
|
|
371
|
+
return [t, a].filter(Boolean).join(" — ");
|
|
372
|
+
}, [he, ie] = k(l), I = K(null), A = (e) => {
|
|
373
|
+
const t = Number(e);
|
|
374
|
+
if (!Number.isFinite(t)) return e;
|
|
375
|
+
if (U)
|
|
376
|
+
try {
|
|
377
|
+
return new Intl.NumberFormat(void 0, { style: "currency", currency: U }).format(t);
|
|
378
|
+
} catch {
|
|
379
|
+
}
|
|
380
|
+
return `$${t.toFixed(2)}`;
|
|
381
|
+
}, be = ((ue = x == null ? void 0 : x.title) == null ? void 0 : ue.trim()) || "Build your bundle", $ = y(() => [...w].sort((e, t) => e.displayName.localeCompare(t.displayName)), [w]), W = y(() => {
|
|
382
|
+
const e = p.trim().toLowerCase();
|
|
383
|
+
if (!e) return $;
|
|
384
|
+
const t = e.split(/\s+/).filter(Boolean), a = (c) => {
|
|
385
|
+
var u;
|
|
386
|
+
const s = [];
|
|
387
|
+
s.push(c.displayName), (u = c.product) != null && u.title && s.push(c.product.title);
|
|
388
|
+
for (const f of c.selectedOptions ?? [])
|
|
389
|
+
s.push(f.name), s.push(f.value);
|
|
390
|
+
const b = s.join(" ").toLowerCase();
|
|
391
|
+
return t.every((f) => b.includes(f));
|
|
392
|
+
};
|
|
393
|
+
return $.filter(a);
|
|
394
|
+
}, [p, $]), v = y(() => [...(x == null ? void 0 : x.rules) ?? []].sort((e, t) => e.minBundleSize - t.minBundleSize), [x == null ? void 0 : x.rules]), P = y(() => Math.max(0, E - g), [g, E]), V = y(() => {
|
|
395
|
+
let e = null;
|
|
396
|
+
for (const t of v)
|
|
397
|
+
g >= t.minBundleSize && (e = t);
|
|
398
|
+
return e;
|
|
399
|
+
}, [g, v]), S = y(() => {
|
|
400
|
+
if (!V) return null;
|
|
401
|
+
const e = Number.parseFloat(V.discountPercent);
|
|
402
|
+
return !Number.isFinite(e) || e <= 0 ? null : e;
|
|
403
|
+
}, [V]), _e = y(() => {
|
|
404
|
+
const e = v[0];
|
|
405
|
+
if (!e) return null;
|
|
406
|
+
const t = Number.parseFloat(e.discountPercent);
|
|
407
|
+
return !Number.isFinite(t) || t <= 0 ? null : t;
|
|
408
|
+
}, [v]), ce = S ?? _e, d = y(() => {
|
|
409
|
+
const e = new Map(w.map((a) => [a.id, a]));
|
|
410
|
+
let t = 0;
|
|
411
|
+
for (const [a, c] of Object.entries(L)) {
|
|
412
|
+
const s = c ?? 0;
|
|
413
|
+
if (s <= 0) continue;
|
|
414
|
+
const b = e.get(a), u = Number(b == null ? void 0 : b.price);
|
|
415
|
+
Number.isFinite(u) && (t += u * s);
|
|
416
|
+
}
|
|
417
|
+
return Math.round(t * 100) / 100;
|
|
418
|
+
}, [w, L]), C = y(() => {
|
|
419
|
+
if (!S) return d;
|
|
420
|
+
const e = d * (1 - S / 100);
|
|
421
|
+
return Math.round(e * 100) / 100;
|
|
422
|
+
}, [S, d]), B = y(() => v.length ? Math.max(...v.map((e) => e.minBundleSize)) : 0, [v]), i = y(() => {
|
|
423
|
+
const e = new Map(w.map((t) => [t.id, t]));
|
|
424
|
+
return M.map((t) => e.get(t)).filter((t) => !!t);
|
|
425
|
+
}, [w, M]), D = y(() => {
|
|
426
|
+
var t;
|
|
427
|
+
const e = /* @__PURE__ */ new Map();
|
|
428
|
+
for (const a of v) {
|
|
429
|
+
const c = Math.max(0, a.minBundleSize - 1);
|
|
430
|
+
e.set(c, {
|
|
431
|
+
discountPercent: a.discountPercent,
|
|
432
|
+
minBundleSize: a.minBundleSize,
|
|
433
|
+
label: ((t = a.label) == null ? void 0 : t.trim()) || `Buy ${a.minBundleSize}+`
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
return e;
|
|
437
|
+
}, [v]), ne = y(() => Math.max(B || E, i.length), [i.length, B, E]), j = K(null), Q = K(null), re = K(null), z = K(g), ae = (e) => {
|
|
438
|
+
const t = Q.current;
|
|
439
|
+
if (!t) return;
|
|
440
|
+
const a = t.querySelector(`[data-variant-row="${e}"]`);
|
|
441
|
+
if (!a) return;
|
|
442
|
+
const c = t.getBoundingClientRect(), s = a.getBoundingClientRect(), b = 8;
|
|
443
|
+
if (s.top >= c.top + b && s.bottom <= c.bottom - b) return;
|
|
444
|
+
const f = Math.max(0, t.scrollHeight - t.clientHeight), R = s.top - c.top + s.height / 2, O = t.scrollTop + R - t.clientHeight / 2, q = Math.min(f, Math.max(0, O));
|
|
445
|
+
t.scrollTo({ top: q, behavior: "smooth" });
|
|
446
|
+
};
|
|
447
|
+
return Z(() => {
|
|
448
|
+
if (!l) return;
|
|
449
|
+
const e = (t) => {
|
|
450
|
+
t.key === "Escape" && _();
|
|
451
|
+
};
|
|
452
|
+
return window.addEventListener("keydown", e), () => window.removeEventListener("keydown", e);
|
|
453
|
+
}, [_, l]), Z(() => {
|
|
454
|
+
if (I.current != null && (window.clearTimeout(I.current), I.current = null), l) {
|
|
455
|
+
ie(!0);
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
I.current = window.setTimeout(() => {
|
|
459
|
+
ie(!1), I.current = null;
|
|
460
|
+
}, 220);
|
|
461
|
+
}, [l]), Z(() => () => {
|
|
462
|
+
I.current != null && window.clearTimeout(I.current);
|
|
463
|
+
}, []), Z(() => {
|
|
464
|
+
if (!l || !F) return;
|
|
465
|
+
const e = requestAnimationFrame(() => {
|
|
466
|
+
var t;
|
|
467
|
+
return (t = ee.current) == null ? void 0 : t.focus();
|
|
468
|
+
});
|
|
469
|
+
return () => cancelAnimationFrame(e);
|
|
470
|
+
}, [l, F]), Z(() => {
|
|
471
|
+
const e = z.current;
|
|
472
|
+
if (z.current = g, g <= e) return;
|
|
473
|
+
const t = re.current;
|
|
474
|
+
if (!t) return;
|
|
475
|
+
const a = v.some((u) => u.minBundleSize === g), c = v.find((u) => u.minBundleSize > g), s = c && a ? c.minBundleSize - 1 : c ? null : g - 1;
|
|
476
|
+
if (s == null || s < 0) return;
|
|
477
|
+
const b = requestAnimationFrame(() => {
|
|
478
|
+
const u = t.querySelector(`[data-box-slot="${s}"]`);
|
|
479
|
+
if (!u) return;
|
|
480
|
+
const f = t.getBoundingClientRect(), O = u.getBoundingClientRect().right - f.right;
|
|
481
|
+
if (O <= 1) return;
|
|
482
|
+
const q = Math.max(0, t.scrollWidth - t.clientWidth), H = Math.min(q, Math.max(0, t.scrollLeft + O));
|
|
483
|
+
t.scrollTo({ left: H, behavior: "smooth" });
|
|
484
|
+
});
|
|
485
|
+
return () => cancelAnimationFrame(b);
|
|
486
|
+
}, [g, v]), Z(() => {
|
|
487
|
+
var e;
|
|
488
|
+
l && ((e = j.current) == null || e.focus());
|
|
489
|
+
}, [l]), he ? /* @__PURE__ */ r(
|
|
490
|
+
"div",
|
|
491
|
+
{
|
|
492
|
+
role: "dialog",
|
|
493
|
+
"aria-modal": "true",
|
|
494
|
+
"aria-label": "Bundle builder",
|
|
495
|
+
className: [n.backdrop, l ? n.backdropOpen : n.backdropClosed, o.className].filter(Boolean).join(" "),
|
|
496
|
+
onMouseDown: (e) => {
|
|
497
|
+
e.target === e.currentTarget && _();
|
|
498
|
+
},
|
|
499
|
+
children: /* @__PURE__ */ N("aside", { ref: j, className: [n.panel, l ? n.panelOpen : n.panelClosed].filter(Boolean).join(" "), tabIndex: -1, children: [
|
|
500
|
+
/* @__PURE__ */ N("header", { className: [n.header, F ? n.headerSearchOpen : null].filter(Boolean).join(" "), children: [
|
|
501
|
+
/* @__PURE__ */ r(
|
|
502
|
+
"button",
|
|
503
|
+
{
|
|
504
|
+
type: "button",
|
|
505
|
+
className: n.searchIconButton,
|
|
506
|
+
"aria-label": F ? "Search (expanded)" : "Search",
|
|
507
|
+
"aria-expanded": F,
|
|
508
|
+
onClick: () => {
|
|
509
|
+
X(!0);
|
|
510
|
+
},
|
|
511
|
+
children: /* @__PURE__ */ r(We, { size: 18, "aria-hidden": "true" })
|
|
512
|
+
}
|
|
513
|
+
),
|
|
514
|
+
/* @__PURE__ */ N("div", { className: n.headerCenter, children: [
|
|
515
|
+
/* @__PURE__ */ r("div", { className: n.headerTitleWrap, "aria-hidden": F, children: /* @__PURE__ */ r("h2", { className: n.title, children: be }) }),
|
|
516
|
+
/* @__PURE__ */ r("div", { className: n.headerSearchWrap, "aria-hidden": !F, children: /* @__PURE__ */ N("div", { className: n.searchBar, children: [
|
|
517
|
+
/* @__PURE__ */ r(
|
|
518
|
+
"input",
|
|
519
|
+
{
|
|
520
|
+
ref: ee,
|
|
521
|
+
className: n.searchInput,
|
|
522
|
+
type: "search",
|
|
523
|
+
value: p,
|
|
524
|
+
placeholder: "Search",
|
|
525
|
+
onChange: (e) => Y(e.target.value),
|
|
526
|
+
onBlur: () => {
|
|
527
|
+
p.trim() === "" && X(!1);
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
),
|
|
531
|
+
p.trim() ? /* @__PURE__ */ r(
|
|
532
|
+
"button",
|
|
533
|
+
{
|
|
534
|
+
type: "button",
|
|
535
|
+
className: n.searchClearButton,
|
|
536
|
+
onMouseDown: (e) => {
|
|
537
|
+
e.preventDefault();
|
|
538
|
+
},
|
|
539
|
+
onClick: () => {
|
|
540
|
+
var e;
|
|
541
|
+
Y(""), (e = ee.current) == null || e.focus();
|
|
542
|
+
},
|
|
543
|
+
"aria-label": "Clear search",
|
|
544
|
+
children: "Clear"
|
|
545
|
+
}
|
|
546
|
+
) : null
|
|
547
|
+
] }) })
|
|
548
|
+
] }),
|
|
549
|
+
/* @__PURE__ */ r("button", { type: "button", onClick: _, disabled: T, className: n.closeButton, "aria-label": "Close", children: "×" })
|
|
550
|
+
] }),
|
|
551
|
+
/* @__PURE__ */ N("div", { className: n.body, ref: Q, children: [
|
|
552
|
+
m ? /* @__PURE__ */ r("p", { className: n.muted, children: "Loading…" }) : null,
|
|
553
|
+
h ? /* @__PURE__ */ r("p", { className: n.error, children: h }) : null,
|
|
554
|
+
!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: W.map((e) => {
|
|
556
|
+
var O, q, H, de;
|
|
557
|
+
const t = L[e.id] ?? 0, a = se(e), c = te(e.selectedOptions), s = me(e), b = ce, u = Number(e.price), f = b != null && Number.isFinite(b) && b > 0 && Number.isFinite(u), R = f ? Math.round(u * (1 - b / 100) * 100) / 100 : null;
|
|
558
|
+
return /* @__PURE__ */ N("li", { className: n.variantRow, "data-variant-row": e.id, children: [
|
|
559
|
+
/* @__PURE__ */ N("div", { className: n.variantLeft, children: [
|
|
560
|
+
/* @__PURE__ */ r("div", { className: n.variantThumb, "aria-hidden": "true", children: (O = e.image) != null && O.url ? /* @__PURE__ */ r(
|
|
561
|
+
"img",
|
|
562
|
+
{
|
|
563
|
+
className: n.variantThumbImg,
|
|
564
|
+
src: e.image.url,
|
|
565
|
+
alt: e.image.altText ?? s,
|
|
566
|
+
loading: "lazy"
|
|
567
|
+
}
|
|
568
|
+
) : /* @__PURE__ */ r("div", { className: n.variantThumbFallback, children: ((de = (H = (q = e.product) == null ? void 0 : q.title) == null ? void 0 : H.slice(0, 1)) == null ? void 0 : de.toUpperCase()) ?? "•" }) }),
|
|
569
|
+
/* @__PURE__ */ N("div", { className: n.variantInfo, children: [
|
|
570
|
+
/* @__PURE__ */ r("div", { className: n.variantName, children: a }),
|
|
571
|
+
c ? /* @__PURE__ */ r("div", { className: n.variantMeta, children: c }) : null,
|
|
572
|
+
/* @__PURE__ */ N("div", { className: n.variantPriceRow, children: [
|
|
573
|
+
f ? /* @__PURE__ */ r("span", { className: n.variantCompareAt, children: A(Number.isFinite(u) ? u.toFixed(2) : e.price) }) : null,
|
|
574
|
+
/* @__PURE__ */ r("span", { className: n.variantPrice, children: A(
|
|
575
|
+
R != null ? R.toFixed(2) : Number.isFinite(u) ? u.toFixed(2) : e.price
|
|
576
|
+
) })
|
|
577
|
+
] })
|
|
578
|
+
] })
|
|
579
|
+
] }),
|
|
580
|
+
t <= 0 ? /* @__PURE__ */ r(
|
|
581
|
+
"button",
|
|
582
|
+
{
|
|
583
|
+
type: "button",
|
|
584
|
+
onClick: () => G(e.id, 1),
|
|
585
|
+
disabled: T,
|
|
586
|
+
className: n.addToBundleButton,
|
|
587
|
+
"aria-label": `Add ${s} to bundle`,
|
|
588
|
+
children: "Add"
|
|
589
|
+
}
|
|
590
|
+
) : /* @__PURE__ */ N("div", { className: n.qtyControls, children: [
|
|
591
|
+
/* @__PURE__ */ r(
|
|
592
|
+
"button",
|
|
593
|
+
{
|
|
594
|
+
type: "button",
|
|
595
|
+
onClick: () => G(e.id, t - 1),
|
|
596
|
+
disabled: T || t <= 0,
|
|
597
|
+
className: n.qtyButton,
|
|
598
|
+
"aria-label": `Decrease ${s}`,
|
|
599
|
+
children: "−"
|
|
600
|
+
}
|
|
601
|
+
),
|
|
602
|
+
/* @__PURE__ */ r("span", { className: n.qtyValue, "aria-label": `Quantity ${t}`, children: t }),
|
|
603
|
+
/* @__PURE__ */ r(
|
|
604
|
+
"button",
|
|
605
|
+
{
|
|
606
|
+
type: "button",
|
|
607
|
+
onClick: () => G(e.id, t + 1),
|
|
608
|
+
disabled: T,
|
|
609
|
+
className: n.qtyButton,
|
|
610
|
+
"aria-label": `Increase ${s}`,
|
|
611
|
+
children: "+"
|
|
612
|
+
}
|
|
613
|
+
)
|
|
614
|
+
] })
|
|
615
|
+
] }, e.id);
|
|
616
|
+
}) }) })
|
|
617
|
+
] }),
|
|
618
|
+
/* @__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: ne }).map((e, t) => {
|
|
620
|
+
var O, q, H, de;
|
|
621
|
+
const a = i[t], c = D.get(t), s = !!a, b = !!c, u = b && !s, f = c ? `${c.discountPercent}% off` : null, R = s ? a.displayName : `Slot ${t + 1}`;
|
|
622
|
+
return /* @__PURE__ */ N("div", { "data-box-slot": t, className: n.boxSlot, children: [
|
|
623
|
+
/* @__PURE__ */ r(
|
|
624
|
+
"div",
|
|
625
|
+
{
|
|
626
|
+
className: [
|
|
627
|
+
n.boxItem,
|
|
628
|
+
s ? n.boxItemFilled : n.boxItemPlaceholder,
|
|
629
|
+
b ? n.boxItemThreshold : null,
|
|
630
|
+
s ? n.boxItemClickable : null
|
|
631
|
+
].filter(Boolean).join(" "),
|
|
632
|
+
role: s ? "button" : void 0,
|
|
633
|
+
tabIndex: s ? 0 : void 0,
|
|
634
|
+
onClick: s ? () => ae(a.id) : void 0,
|
|
635
|
+
onKeyDown: s ? (pe) => {
|
|
636
|
+
(pe.key === "Enter" || pe.key === " ") && (pe.preventDefault(), ae(a.id));
|
|
637
|
+
} : void 0,
|
|
638
|
+
"aria-label": u && f ? `${R}. Unlocks ${f}.` : R,
|
|
639
|
+
title: u && f ? `${R} • Unlocks ${f}` : R,
|
|
640
|
+
children: s ? (O = a.image) != null && O.url ? /* @__PURE__ */ r(
|
|
641
|
+
"img",
|
|
642
|
+
{
|
|
643
|
+
className: n.boxItemImage,
|
|
644
|
+
src: a.image.url,
|
|
645
|
+
alt: a.image.altText ?? a.displayName,
|
|
646
|
+
loading: "lazy"
|
|
647
|
+
}
|
|
648
|
+
) : /* @__PURE__ */ r("div", { className: n.boxItemFallback, "aria-hidden": "true", children: ((de = (H = (q = a.product) == null ? void 0 : q.title) == null ? void 0 : H.slice(0, 1)) == null ? void 0 : de.toUpperCase()) ?? "•" }) : u && f ? /* @__PURE__ */ r("div", { className: n.boxItemDiscountText, children: f }) : /* @__PURE__ */ r("div", { className: n.boxItemPlus, "aria-hidden": "true", children: "+" })
|
|
649
|
+
}
|
|
650
|
+
),
|
|
651
|
+
b ? /* @__PURE__ */ r("div", { className: n.boxThresholdLabel, children: c.label }) : null
|
|
652
|
+
] }, t);
|
|
653
|
+
}) }) }),
|
|
654
|
+
/* @__PURE__ */ r(
|
|
655
|
+
"div",
|
|
656
|
+
{
|
|
657
|
+
className: [n.ctaTotalsWrap, P <= 0 ? n.ctaTotalsWrapVisible : null].filter(Boolean).join(" "),
|
|
658
|
+
"aria-hidden": P > 0,
|
|
659
|
+
children: /* @__PURE__ */ N("div", { className: n.ctaTotals, "aria-label": "Totals", children: [
|
|
660
|
+
ce ? /* @__PURE__ */ N("span", { className: n.ctaDiscountBadge, children: [
|
|
661
|
+
S ? "Unlocked " : "",
|
|
662
|
+
ce,
|
|
663
|
+
"% off"
|
|
664
|
+
] }) : /* @__PURE__ */ r("span", {}),
|
|
665
|
+
/* @__PURE__ */ r("span", { children: S ? /* @__PURE__ */ N(Te, { children: [
|
|
666
|
+
/* @__PURE__ */ r("span", { className: n.ctaTotalsStrike, children: A(d.toFixed(2)) }),
|
|
667
|
+
" ",
|
|
668
|
+
/* @__PURE__ */ r("span", { className: n.ctaTotalsPrice, children: A(C.toFixed(2)) })
|
|
669
|
+
] }) : /* @__PURE__ */ r("span", { className: n.ctaTotalsPrice, children: A(d.toFixed(2)) }) })
|
|
670
|
+
] })
|
|
671
|
+
}
|
|
672
|
+
),
|
|
673
|
+
/* @__PURE__ */ r("button", { type: "button", onClick: le, disabled: !J, className: n.cta, children: T ? "Adding…" : P > 0 ? `Add ${P} more product${P === 1 ? "" : "s"}` : "Add to Basket" })
|
|
674
|
+
] })
|
|
675
|
+
] })
|
|
676
|
+
}
|
|
677
|
+
) : null;
|
|
678
|
+
}
|
|
679
|
+
export {
|
|
680
|
+
Zt as BundleBuilderDrawer,
|
|
681
|
+
Kt as BundleButton,
|
|
682
|
+
fe as BundleLineAttributeKeys,
|
|
683
|
+
Qt as BundleProvider,
|
|
684
|
+
xe as useBundleBuilder,
|
|
685
|
+
Ht as useBundleBuilderDrawer
|
|
686
|
+
};
|
|
687
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +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","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","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]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
declare const meta: Meta;
|
|
3
|
+
export default meta;
|
|
4
|
+
export declare const FullIntegration: StoryObj;
|
|
5
|
+
export declare const HookControlledDrawer: StoryObj;
|
|
6
|
+
export declare const HeaderSearchFiltering: StoryObj;
|
|
7
|
+
//# sourceMappingURL=BundleUI.stories.d.ts.map
|
|
@@ -0,0 +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;AA6JpB,eAAO,MAAM,eAAe,EAAE,QAwB7B,CAAC;AAwBF,eAAO,MAAM,oBAAoB,EAAE,QAyBlC,CAAC;AAUF,eAAO,MAAM,qBAAqB,EAAE,QAyBnC,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
export type BundleCartLineAttribute = {
|
|
2
|
+
key: string;
|
|
3
|
+
value: string;
|
|
4
|
+
};
|
|
5
|
+
export type BundleCartAdapter = {
|
|
6
|
+
linesAdd(lines: Array<{
|
|
7
|
+
merchandiseId: string;
|
|
8
|
+
quantity: number;
|
|
9
|
+
attributes?: BundleCartLineAttribute[];
|
|
10
|
+
}>): Promise<void> | void;
|
|
11
|
+
linesUpdate?(lines: Array<{
|
|
12
|
+
id: string;
|
|
13
|
+
quantity: number;
|
|
14
|
+
attributes?: BundleCartLineAttribute[];
|
|
15
|
+
}>): Promise<void> | void;
|
|
16
|
+
linesRemove?(lineIds: string[]): Promise<void> | void;
|
|
17
|
+
openCartUI?(): void;
|
|
18
|
+
closeCartUI?(): void;
|
|
19
|
+
};
|
|
20
|
+
export type BundleDiscountRule = {
|
|
21
|
+
id: string;
|
|
22
|
+
handle: string;
|
|
23
|
+
minBundleSize: number;
|
|
24
|
+
discountPercent: string;
|
|
25
|
+
label: string;
|
|
26
|
+
sortOrder: number | null;
|
|
27
|
+
};
|
|
28
|
+
export type BundleConfig = {
|
|
29
|
+
id: string;
|
|
30
|
+
title: string;
|
|
31
|
+
isActive: boolean;
|
|
32
|
+
eligibleVariantIds: string[];
|
|
33
|
+
rules: BundleDiscountRule[];
|
|
34
|
+
};
|
|
35
|
+
export type BundleEligibleVariant = {
|
|
36
|
+
id: string;
|
|
37
|
+
title: string;
|
|
38
|
+
displayName: string;
|
|
39
|
+
selectedOptions: Array<{
|
|
40
|
+
name: string;
|
|
41
|
+
value: string;
|
|
42
|
+
}>;
|
|
43
|
+
price: string;
|
|
44
|
+
compareAtPrice: string | null;
|
|
45
|
+
image: null | {
|
|
46
|
+
url: string;
|
|
47
|
+
altText: string | null;
|
|
48
|
+
width: number | null;
|
|
49
|
+
height: number | null;
|
|
50
|
+
};
|
|
51
|
+
product: null | {
|
|
52
|
+
id: string;
|
|
53
|
+
title: string;
|
|
54
|
+
handle: string;
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
export type PublicBundleConfigResponse = {
|
|
58
|
+
ok: true;
|
|
59
|
+
shop: string;
|
|
60
|
+
currencyCode: string | null;
|
|
61
|
+
config: BundleConfig;
|
|
62
|
+
eligibleVariants: BundleEligibleVariant[];
|
|
63
|
+
} | {
|
|
64
|
+
ok: false;
|
|
65
|
+
error: string;
|
|
66
|
+
};
|
|
67
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,uBAAuB,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAErE,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;QACpB,aAAa,EAAE,MAAM,CAAC;QACtB,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,CAAC,EAAE,uBAAuB,EAAE,CAAC;KACxC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAE1B,WAAW,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC;QACxB,EAAE,EAAE,MAAM,CAAC;QACX,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,CAAC,EAAE,uBAAuB,EAAE,CAAC;KACxC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAE1B,WAAW,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAEtD,UAAU,CAAC,IAAI,IAAI,CAAC;IACpB,WAAW,CAAC,IAAI,IAAI,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,OAAO,CAAC;IAClB,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,KAAK,EAAE,kBAAkB,EAAE,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxD,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,KAAK,EAAE,IAAI,GAAG;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IACnG,OAAO,EAAE,IAAI,GAAG;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/D,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAClC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,EAAE,YAAY,CAAC;IAAC,gBAAgB,EAAE,qBAAqB,EAAE,CAAA;CAAE,GACxH;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@best-bundles/bundle-ui",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"private": false,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist"
|
|
8
|
+
],
|
|
9
|
+
"sideEffects": [
|
|
10
|
+
"**/*.css"
|
|
11
|
+
],
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"import": "./dist/index.js"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"main": "./dist/index.js",
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "npm run build:js && npm run build:types",
|
|
22
|
+
"build:js": "vite build",
|
|
23
|
+
"build:types": "tsc -p tsconfig.build.json",
|
|
24
|
+
"prepack": "npm run build",
|
|
25
|
+
"storybook": "STORYBOOK_DISABLE_TELEMETRY=1 CI=1 storybook dev -p 6007",
|
|
26
|
+
"build-storybook": "STORYBOOK_DISABLE_TELEMETRY=1 CI=1 storybook build"
|
|
27
|
+
},
|
|
28
|
+
"publishConfig": {
|
|
29
|
+
"access": "public"
|
|
30
|
+
},
|
|
31
|
+
"peerDependencies": {
|
|
32
|
+
"lucide-react": ">=0.300.0",
|
|
33
|
+
"react": ">=18",
|
|
34
|
+
"react-dom": ">=18"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@vitejs/plugin-react": "^4.7.0",
|
|
38
|
+
"@storybook/addon-essentials": "^8.6.0",
|
|
39
|
+
"@storybook/addon-interactions": "^8.6.0",
|
|
40
|
+
"@storybook/addon-links": "^8.6.0",
|
|
41
|
+
"@storybook/blocks": "^8.6.0",
|
|
42
|
+
"@storybook/react-vite": "^8.6.0",
|
|
43
|
+
"@storybook/test": "^8.6.0",
|
|
44
|
+
"@types/react": "^18.3.25",
|
|
45
|
+
"@types/react-dom": "^18.3.7",
|
|
46
|
+
"lucide-react": "^0.515.0",
|
|
47
|
+
"storybook": "^8.6.0",
|
|
48
|
+
"typescript": "^5.9.3",
|
|
49
|
+
"vite": "^6.3.6",
|
|
50
|
+
"vite-plugin-css-injected-by-js": "^3.5.2"
|
|
51
|
+
}
|
|
52
|
+
}
|