@cimplify/sdk 0.9.7 → 0.9.9

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/react.js CHANGED
@@ -799,14 +799,6 @@ var CatalogueQueries = class {
799
799
  async getBundles() {
800
800
  return safe(this.client.get("/api/v1/catalogue/bundles"));
801
801
  }
802
- async getBundle(id) {
803
- const encodedId = encodeURIComponent(id);
804
- return safe(this.client.get(`/api/v1/catalogue/bundles/${encodedId}`));
805
- }
806
- async getBundleBySlug(slug) {
807
- const encodedSlug = encodeURIComponent(slug);
808
- return safe(this.client.get(`/api/v1/catalogue/bundles/slug/${encodedSlug}`));
809
- }
810
802
  async searchBundles(query, limit = 20) {
811
803
  const path = withQuery("/api/v1/catalogue/bundles", { search: query, limit });
812
804
  return safe(this.client.get(path));
@@ -815,18 +807,6 @@ var CatalogueQueries = class {
815
807
  const path = withQuery("/api/v1/catalogue/composites", { limit: options?.limit });
816
808
  return safe(this.client.get(path));
817
809
  }
818
- async getComposite(id) {
819
- const encodedId = encodeURIComponent(id);
820
- return safe(this.client.get(`/api/v1/catalogue/composites/${encodedId}`));
821
- }
822
- async getCompositeByProductId(productId) {
823
- const encodedId = encodeURIComponent(productId);
824
- return safe(
825
- this.client.get(
826
- `/api/v1/catalogue/composites/by-product/${encodedId}`
827
- )
828
- );
829
- }
830
810
  async calculateCompositePrice(compositeId, selections, locationId) {
831
811
  const encodedId = encodeURIComponent(compositeId);
832
812
  return safe(
@@ -6019,256 +5999,6 @@ function useCollection(idOrSlug, options = {}) {
6019
5999
  }, [cacheKey, load]);
6020
6000
  return { collection, products, isLoading, error, refetch };
6021
6001
  }
6022
- var bundleCache = /* @__PURE__ */ new Map();
6023
- var bundleInflight = /* @__PURE__ */ new Map();
6024
- function isLikelySlug3(value) {
6025
- return /^[a-z0-9-]+$/.test(value);
6026
- }
6027
- function buildBundleCacheKey(client, locationId, idOrSlug) {
6028
- return JSON.stringify({
6029
- key: client.getPublicKey(),
6030
- location_id: locationId || "__none__",
6031
- bundle: idOrSlug
6032
- });
6033
- }
6034
- function useBundle(idOrSlug, options = {}) {
6035
- const context = useOptionalCimplify();
6036
- const client = options.client ?? context?.client;
6037
- if (!client) {
6038
- throw new Error("useBundle must be used within CimplifyProvider or passed { client }.");
6039
- }
6040
- const enabled = options.enabled ?? true;
6041
- const locationId = client.getLocationId();
6042
- const previousLocationIdRef = React3.useRef(locationId);
6043
- const requestIdRef = React3.useRef(0);
6044
- const normalizedIdOrSlug = React3.useMemo(() => (idOrSlug || "").trim(), [idOrSlug]);
6045
- const cacheKey = React3.useMemo(
6046
- () => buildBundleCacheKey(client, locationId, normalizedIdOrSlug),
6047
- [client, locationId, normalizedIdOrSlug]
6048
- );
6049
- const cached = bundleCache.get(cacheKey);
6050
- const [bundle, setBundle] = React3.useState(cached?.bundle ?? null);
6051
- const [isLoading, setIsLoading] = React3.useState(
6052
- enabled && normalizedIdOrSlug.length > 0 && !cached
6053
- );
6054
- const [error, setError] = React3.useState(null);
6055
- React3.useEffect(() => {
6056
- if (previousLocationIdRef.current !== locationId) {
6057
- bundleCache.clear();
6058
- bundleInflight.clear();
6059
- previousLocationIdRef.current = locationId;
6060
- }
6061
- }, [locationId]);
6062
- const load = React3.useCallback(
6063
- async (force = false) => {
6064
- if (!enabled || normalizedIdOrSlug.length === 0) {
6065
- setBundle(null);
6066
- setIsLoading(false);
6067
- return;
6068
- }
6069
- const nextRequestId = ++requestIdRef.current;
6070
- setError(null);
6071
- if (!force) {
6072
- const cacheEntry = bundleCache.get(cacheKey);
6073
- if (cacheEntry) {
6074
- setBundle(cacheEntry.bundle);
6075
- setIsLoading(false);
6076
- return;
6077
- }
6078
- }
6079
- setIsLoading(true);
6080
- try {
6081
- const existing = bundleInflight.get(cacheKey);
6082
- const promise = existing ?? (async () => {
6083
- const result = isLikelySlug3(normalizedIdOrSlug) ? await client.catalogue.getBundleBySlug(normalizedIdOrSlug) : await client.catalogue.getBundle(normalizedIdOrSlug);
6084
- if (!result.ok) {
6085
- throw result.error;
6086
- }
6087
- return result.value;
6088
- })();
6089
- if (!existing) {
6090
- bundleInflight.set(cacheKey, promise);
6091
- promise.finally(() => {
6092
- bundleInflight.delete(cacheKey);
6093
- }).catch(() => void 0);
6094
- }
6095
- const value = await promise;
6096
- bundleCache.set(cacheKey, { bundle: value });
6097
- if (nextRequestId === requestIdRef.current) {
6098
- setBundle(value);
6099
- setError(null);
6100
- }
6101
- } catch (loadError) {
6102
- if (nextRequestId === requestIdRef.current) {
6103
- setError(loadError);
6104
- }
6105
- } finally {
6106
- if (nextRequestId === requestIdRef.current) {
6107
- setIsLoading(false);
6108
- }
6109
- }
6110
- },
6111
- [cacheKey, client, enabled, normalizedIdOrSlug]
6112
- );
6113
- React3.useEffect(() => {
6114
- void load(false);
6115
- }, [load]);
6116
- const refetch = React3.useCallback(async () => {
6117
- bundleCache.delete(cacheKey);
6118
- await load(true);
6119
- }, [cacheKey, load]);
6120
- return { bundle, isLoading, error, refetch };
6121
- }
6122
- var compositeCache = /* @__PURE__ */ new Map();
6123
- var compositeInflight = /* @__PURE__ */ new Map();
6124
- function shouldFetchByProductId(idOrProductId, byProductId) {
6125
- if (typeof byProductId === "boolean") {
6126
- return byProductId;
6127
- }
6128
- return idOrProductId.startsWith("prod_");
6129
- }
6130
- function buildCompositeCacheKey(client, locationId, idOrProductId, byProductId) {
6131
- return JSON.stringify({
6132
- key: client.getPublicKey(),
6133
- location_id: locationId || "__none__",
6134
- composite: idOrProductId,
6135
- by_product_id: byProductId
6136
- });
6137
- }
6138
- function useComposite(idOrProductId, options = {}) {
6139
- const context = useOptionalCimplify();
6140
- const client = options.client ?? context?.client;
6141
- if (!client) {
6142
- throw new Error("useComposite must be used within CimplifyProvider or passed { client }.");
6143
- }
6144
- const enabled = options.enabled ?? true;
6145
- const locationId = client.getLocationId();
6146
- const previousLocationIdRef = React3.useRef(locationId);
6147
- const requestIdRef = React3.useRef(0);
6148
- const priceRequestIdRef = React3.useRef(0);
6149
- const normalizedIdOrProductId = React3.useMemo(
6150
- () => (idOrProductId || "").trim(),
6151
- [idOrProductId]
6152
- );
6153
- const byProductId = React3.useMemo(
6154
- () => shouldFetchByProductId(normalizedIdOrProductId, options.byProductId),
6155
- [normalizedIdOrProductId, options.byProductId]
6156
- );
6157
- const cacheKey = React3.useMemo(
6158
- () => buildCompositeCacheKey(client, locationId, normalizedIdOrProductId, byProductId),
6159
- [byProductId, client, locationId, normalizedIdOrProductId]
6160
- );
6161
- const cached = compositeCache.get(cacheKey);
6162
- const [composite, setComposite] = React3.useState(cached?.composite ?? null);
6163
- const [isLoading, setIsLoading] = React3.useState(
6164
- enabled && normalizedIdOrProductId.length > 0 && !cached
6165
- );
6166
- const [error, setError] = React3.useState(null);
6167
- const [priceResult, setPriceResult] = React3.useState(null);
6168
- const [isPriceLoading, setIsPriceLoading] = React3.useState(false);
6169
- React3.useEffect(() => {
6170
- if (previousLocationIdRef.current !== locationId) {
6171
- compositeCache.clear();
6172
- compositeInflight.clear();
6173
- previousLocationIdRef.current = locationId;
6174
- }
6175
- }, [locationId]);
6176
- const load = React3.useCallback(
6177
- async (force = false) => {
6178
- if (!enabled || normalizedIdOrProductId.length === 0) {
6179
- setComposite(null);
6180
- setPriceResult(null);
6181
- setIsLoading(false);
6182
- return;
6183
- }
6184
- const nextRequestId = ++requestIdRef.current;
6185
- setError(null);
6186
- if (!force) {
6187
- const cacheEntry = compositeCache.get(cacheKey);
6188
- if (cacheEntry) {
6189
- setComposite(cacheEntry.composite);
6190
- setIsLoading(false);
6191
- return;
6192
- }
6193
- }
6194
- setIsLoading(true);
6195
- try {
6196
- const existing = compositeInflight.get(cacheKey);
6197
- const promise = existing ?? (async () => {
6198
- const result = byProductId ? await client.catalogue.getCompositeByProductId(normalizedIdOrProductId) : await client.catalogue.getComposite(normalizedIdOrProductId);
6199
- if (!result.ok) {
6200
- throw result.error;
6201
- }
6202
- return result.value;
6203
- })();
6204
- if (!existing) {
6205
- compositeInflight.set(cacheKey, promise);
6206
- promise.finally(() => {
6207
- compositeInflight.delete(cacheKey);
6208
- }).catch(() => void 0);
6209
- }
6210
- const value = await promise;
6211
- compositeCache.set(cacheKey, { composite: value });
6212
- if (nextRequestId === requestIdRef.current) {
6213
- setComposite(value);
6214
- setPriceResult(null);
6215
- setError(null);
6216
- }
6217
- } catch (loadError) {
6218
- if (nextRequestId === requestIdRef.current) {
6219
- setError(loadError);
6220
- }
6221
- } finally {
6222
- if (nextRequestId === requestIdRef.current) {
6223
- setIsLoading(false);
6224
- }
6225
- }
6226
- },
6227
- [byProductId, cacheKey, client, enabled, normalizedIdOrProductId]
6228
- );
6229
- React3.useEffect(() => {
6230
- void load(false);
6231
- }, [load]);
6232
- const calculatePrice = React3.useCallback(
6233
- async (selections, overrideLocationId) => {
6234
- if (!composite) {
6235
- return null;
6236
- }
6237
- const nextRequestId = ++priceRequestIdRef.current;
6238
- setIsPriceLoading(true);
6239
- try {
6240
- const result = await client.catalogue.calculateCompositePrice(
6241
- composite.id,
6242
- selections,
6243
- overrideLocationId
6244
- );
6245
- if (!result.ok) {
6246
- throw result.error;
6247
- }
6248
- if (nextRequestId === priceRequestIdRef.current) {
6249
- setPriceResult(result.value);
6250
- setError(null);
6251
- }
6252
- return result.value;
6253
- } catch (loadError) {
6254
- if (nextRequestId === priceRequestIdRef.current) {
6255
- setError(loadError);
6256
- }
6257
- return null;
6258
- } finally {
6259
- if (nextRequestId === priceRequestIdRef.current) {
6260
- setIsPriceLoading(false);
6261
- }
6262
- }
6263
- },
6264
- [client, composite]
6265
- );
6266
- const refetch = React3.useCallback(async () => {
6267
- compositeCache.delete(cacheKey);
6268
- await load(true);
6269
- }, [cacheKey, load]);
6270
- return { composite, isLoading, error, refetch, calculatePrice, priceResult, isPriceLoading };
6271
- }
6272
6002
  function useSearch(options = {}) {
6273
6003
  const context = useOptionalCimplify();
6274
6004
  const client = options.client ?? context?.client;
@@ -7022,15 +6752,122 @@ function AddOnSelector({
7022
6752
  ] }, addOn.id);
7023
6753
  }) });
7024
6754
  }
6755
+ function BundleSelector({
6756
+ components,
6757
+ bundlePrice,
6758
+ discountValue,
6759
+ onSelectionsChange,
6760
+ onReady,
6761
+ className
6762
+ }) {
6763
+ const [variantChoices, setVariantChoices] = React3.useState({});
6764
+ React3.useEffect(() => {
6765
+ const defaults = {};
6766
+ for (const comp of components) {
6767
+ if (comp.variant_id) {
6768
+ defaults[comp.id] = comp.variant_id;
6769
+ } else if (comp.available_variants.length > 0) {
6770
+ const defaultVariant = comp.available_variants.find((v) => v.is_default) || comp.available_variants[0];
6771
+ if (defaultVariant) {
6772
+ defaults[comp.id] = defaultVariant.id;
6773
+ }
6774
+ }
6775
+ }
6776
+ setVariantChoices(defaults);
6777
+ }, [components]);
6778
+ const selections = React3.useMemo(() => {
6779
+ return components.map((comp) => ({
6780
+ component_id: comp.id,
6781
+ variant_id: variantChoices[comp.id],
6782
+ quantity: comp.quantity
6783
+ }));
6784
+ }, [components, variantChoices]);
6785
+ React3.useEffect(() => {
6786
+ onSelectionsChange(selections);
6787
+ }, [selections, onSelectionsChange]);
6788
+ React3.useEffect(() => {
6789
+ onReady?.(components.length > 0 && selections.length > 0);
6790
+ }, [components, selections, onReady]);
6791
+ const handleVariantChange = React3.useCallback(
6792
+ (componentId, variantId) => {
6793
+ setVariantChoices((prev) => ({ ...prev, [componentId]: variantId }));
6794
+ },
6795
+ []
6796
+ );
6797
+ if (components.length === 0) {
6798
+ return null;
6799
+ }
6800
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-bundle-selector": true, className, children: [
6801
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-bundle-heading": true, children: "Included in this bundle" }),
6802
+ /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-bundle-components": true, children: components.map((comp) => /* @__PURE__ */ jsxRuntime.jsx(
6803
+ BundleComponentCard,
6804
+ {
6805
+ component: comp,
6806
+ selectedVariantId: variantChoices[comp.id],
6807
+ onVariantChange: (variantId) => handleVariantChange(comp.id, variantId)
6808
+ },
6809
+ comp.id
6810
+ )) }),
6811
+ bundlePrice && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-bundle-summary": true, children: [
6812
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Bundle price" }),
6813
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: bundlePrice })
6814
+ ] }),
6815
+ discountValue && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-bundle-savings": true, children: [
6816
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "You save" }),
6817
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: discountValue })
6818
+ ] })
6819
+ ] });
6820
+ }
6821
+ function BundleComponentCard({
6822
+ component,
6823
+ selectedVariantId,
6824
+ onVariantChange
6825
+ }) {
6826
+ const showVariantPicker = component.allow_variant_choice && component.available_variants.length > 1;
6827
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-bundle-component": true, children: [
6828
+ /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-bundle-component-header": true, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
6829
+ component.quantity > 1 && /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-bundle-component-qty": true, children: [
6830
+ "\xD7",
6831
+ component.quantity
6832
+ ] }),
6833
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-bundle-component-name": true, children: component.product_name })
6834
+ ] }) }),
6835
+ showVariantPicker && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-bundle-variant-picker": true, children: component.available_variants.map((variant) => {
6836
+ const isSelected = selectedVariantId === variant.id;
6837
+ const adjustment = parsePrice(variant.price_adjustment);
6838
+ return /* @__PURE__ */ jsxRuntime.jsxs(
6839
+ "button",
6840
+ {
6841
+ type: "button",
6842
+ "aria-selected": isSelected,
6843
+ onClick: () => onVariantChange(variant.id),
6844
+ "data-cimplify-bundle-variant-option": true,
6845
+ "data-selected": isSelected || void 0,
6846
+ children: [
6847
+ variant.display_name,
6848
+ adjustment !== 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-bundle-variant-adjustment": true, children: [
6849
+ adjustment > 0 ? "+" : "",
6850
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: variant.price_adjustment })
6851
+ ] })
6852
+ ]
6853
+ },
6854
+ variant.id
6855
+ );
6856
+ }) })
6857
+ ] });
6858
+ }
7025
6859
  function CompositeSelector({
7026
- productId,
6860
+ compositeId,
6861
+ groups,
7027
6862
  onSelectionsChange,
7028
6863
  onPriceChange,
7029
6864
  onReady,
7030
6865
  className
7031
6866
  }) {
7032
- const { composite, isLoading, error, calculatePrice, priceResult, isPriceLoading } = useComposite(productId);
6867
+ const { client } = useCimplify();
7033
6868
  const [groupSelections, setGroupSelections] = React3.useState({});
6869
+ const [priceResult, setPriceResult] = React3.useState(null);
6870
+ const [isPriceLoading, setIsPriceLoading] = React3.useState(false);
7034
6871
  const selections = React3.useMemo(() => {
7035
6872
  const result = [];
7036
6873
  for (const groupSels of Object.values(groupSelections)) {
@@ -7049,22 +6886,32 @@ function CompositeSelector({
7049
6886
  onPriceChange?.(priceResult);
7050
6887
  }, [priceResult, onPriceChange]);
7051
6888
  const allGroupsSatisfied = React3.useMemo(() => {
7052
- if (!composite) return false;
7053
- for (const group of composite.groups) {
6889
+ for (const group of groups) {
7054
6890
  const groupSels = groupSelections[group.id] || {};
7055
6891
  const totalSelected = Object.values(groupSels).reduce((sum, q) => sum + q, 0);
7056
6892
  if (totalSelected < group.min_selections) return false;
7057
6893
  }
7058
6894
  return true;
7059
- }, [composite, groupSelections]);
6895
+ }, [groups, groupSelections]);
7060
6896
  React3.useEffect(() => {
7061
6897
  onReady?.(allGroupsSatisfied);
7062
6898
  }, [allGroupsSatisfied, onReady]);
7063
6899
  React3.useEffect(() => {
7064
- if (allGroupsSatisfied && selections.length > 0) {
7065
- void calculatePrice(selections);
7066
- }
7067
- }, [selections, allGroupsSatisfied, calculatePrice]);
6900
+ if (!allGroupsSatisfied || selections.length === 0) return;
6901
+ let cancelled = false;
6902
+ setIsPriceLoading(true);
6903
+ void client.catalogue.calculateCompositePrice(compositeId, selections).then((result) => {
6904
+ if (cancelled) return;
6905
+ if (result.ok) {
6906
+ setPriceResult(result.value);
6907
+ }
6908
+ }).finally(() => {
6909
+ if (!cancelled) setIsPriceLoading(false);
6910
+ });
6911
+ return () => {
6912
+ cancelled = true;
6913
+ };
6914
+ }, [selections, allGroupsSatisfied, compositeId, client]);
7068
6915
  const toggleComponent = React3.useCallback(
7069
6916
  (group, component) => {
7070
6917
  setGroupSelections((prev) => {
@@ -7112,14 +6959,11 @@ function CompositeSelector({
7112
6959
  },
7113
6960
  []
7114
6961
  );
7115
- if (isLoading) {
7116
- return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-composite-selector": true, "data-loading": true, className, children: "Loading options..." });
7117
- }
7118
- if (error || !composite) {
6962
+ if (groups.length === 0) {
7119
6963
  return null;
7120
6964
  }
7121
6965
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-composite-selector": true, className, children: [
7122
- composite.groups.sort((a, b) => a.display_order - b.display_order).map((group) => {
6966
+ [...groups].sort((a, b) => a.display_order - b.display_order).map((group) => {
7123
6967
  const groupSels = groupSelections[group.id] || {};
7124
6968
  const totalSelected = Object.values(groupSels).reduce((sum, q) => sum + q, 0);
7125
6969
  const minMet = totalSelected >= group.min_selections;
@@ -7139,7 +6983,7 @@ function CompositeSelector({
7139
6983
  /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-composite-components": true, children: group.components.filter((c) => c.is_available && !c.is_archived).sort((a, b) => a.display_order - b.display_order).map((component) => {
7140
6984
  const qty = groupSels[component.id] || 0;
7141
6985
  const isSelected = qty > 0;
7142
- const displayName = component.display_name || component.product_id || component.id;
6986
+ const displayName = component.display_name || component.id;
7143
6987
  return /* @__PURE__ */ jsxRuntime.jsxs(
7144
6988
  "button",
7145
6989
  {
@@ -7213,118 +7057,6 @@ function CompositeSelector({
7213
7057
  isPriceLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-composite-calculating": true, children: "Calculating price..." })
7214
7058
  ] });
7215
7059
  }
7216
- function BundleSelector({
7217
- bundleIdOrSlug,
7218
- onSelectionsChange,
7219
- onReady,
7220
- className
7221
- }) {
7222
- const { bundle, isLoading, error } = useBundle(bundleIdOrSlug);
7223
- const [variantChoices, setVariantChoices] = React3.useState({});
7224
- React3.useEffect(() => {
7225
- if (!bundle) return;
7226
- const defaults = {};
7227
- for (const comp of bundle.components) {
7228
- if (comp.component.variant_id) {
7229
- defaults[comp.component.id] = comp.component.variant_id;
7230
- } else if (comp.variants.length > 0) {
7231
- const defaultVariant = comp.variants.find((v) => v.is_default) || comp.variants[0];
7232
- if (defaultVariant) {
7233
- defaults[comp.component.id] = defaultVariant.id;
7234
- }
7235
- }
7236
- }
7237
- setVariantChoices(defaults);
7238
- }, [bundle]);
7239
- const selections = React3.useMemo(() => {
7240
- if (!bundle) return [];
7241
- return bundle.components.map((comp) => ({
7242
- component_id: comp.component.id,
7243
- variant_id: variantChoices[comp.component.id],
7244
- quantity: comp.component.quantity
7245
- }));
7246
- }, [bundle, variantChoices]);
7247
- React3.useEffect(() => {
7248
- onSelectionsChange(selections);
7249
- }, [selections, onSelectionsChange]);
7250
- React3.useEffect(() => {
7251
- onReady?.(bundle != null && selections.length > 0);
7252
- }, [bundle, selections, onReady]);
7253
- const handleVariantChange = React3.useCallback(
7254
- (componentId, variantId) => {
7255
- setVariantChoices((prev) => ({ ...prev, [componentId]: variantId }));
7256
- },
7257
- []
7258
- );
7259
- if (isLoading) {
7260
- return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-bundle-selector": true, "data-loading": true, className, children: "Loading bundle..." });
7261
- }
7262
- if (error || !bundle) {
7263
- return null;
7264
- }
7265
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-bundle-selector": true, className, children: [
7266
- /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-bundle-heading": true, children: "Included in this bundle" }),
7267
- /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-bundle-components": true, children: bundle.components.map((comp) => /* @__PURE__ */ jsxRuntime.jsx(
7268
- BundleComponentCard,
7269
- {
7270
- data: comp,
7271
- selectedVariantId: variantChoices[comp.component.id],
7272
- onVariantChange: (variantId) => handleVariantChange(comp.component.id, variantId)
7273
- },
7274
- comp.component.id
7275
- )) }),
7276
- bundle.bundle_price && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-bundle-summary": true, children: [
7277
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Bundle price" }),
7278
- /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: bundle.bundle_price })
7279
- ] }),
7280
- bundle.discount_value && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-bundle-savings": true, children: [
7281
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "You save" }),
7282
- /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: bundle.discount_value })
7283
- ] })
7284
- ] });
7285
- }
7286
- function BundleComponentCard({
7287
- data,
7288
- selectedVariantId,
7289
- onVariantChange
7290
- }) {
7291
- const { component, product, variants } = data;
7292
- const showVariantPicker = component.allow_variant_choice && variants.length > 1;
7293
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-bundle-component": true, children: [
7294
- /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-bundle-component-header": true, children: [
7295
- /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
7296
- component.quantity > 1 && /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-bundle-component-qty": true, children: [
7297
- "\xD7",
7298
- component.quantity
7299
- ] }),
7300
- /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-bundle-component-name": true, children: product.name })
7301
- ] }),
7302
- /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: product.default_price })
7303
- ] }),
7304
- showVariantPicker && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-bundle-variant-picker": true, children: variants.map((variant) => {
7305
- const isSelected = selectedVariantId === variant.id;
7306
- const adjustment = parsePrice(variant.price_adjustment);
7307
- return /* @__PURE__ */ jsxRuntime.jsxs(
7308
- "button",
7309
- {
7310
- type: "button",
7311
- "aria-selected": isSelected,
7312
- onClick: () => onVariantChange(variant.id),
7313
- "data-cimplify-bundle-variant-option": true,
7314
- "data-selected": isSelected || void 0,
7315
- children: [
7316
- getVariantDisplayName(variant, product.name),
7317
- adjustment !== 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-bundle-variant-adjustment": true, children: [
7318
- adjustment > 0 ? "+" : "",
7319
- /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: variant.price_adjustment })
7320
- ] })
7321
- ]
7322
- },
7323
- variant.id
7324
- );
7325
- }) })
7326
- ] });
7327
- }
7328
7060
  function ProductCustomizer({
7329
7061
  product,
7330
7062
  onAddToCart,
@@ -7472,19 +7204,22 @@ function ProductCustomizer({
7472
7204
  }
7473
7205
  };
7474
7206
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-customizer": true, className, children: [
7475
- isComposite && /* @__PURE__ */ jsxRuntime.jsx(
7207
+ isComposite && product.groups && product.composite_id && /* @__PURE__ */ jsxRuntime.jsx(
7476
7208
  CompositeSelector,
7477
7209
  {
7478
- productId: product.id,
7210
+ compositeId: product.composite_id,
7211
+ groups: product.groups,
7479
7212
  onSelectionsChange: setCompositeSelections,
7480
7213
  onPriceChange: setCompositePrice,
7481
7214
  onReady: setCompositeReady
7482
7215
  }
7483
7216
  ),
7484
- isBundle && /* @__PURE__ */ jsxRuntime.jsx(
7217
+ isBundle && product.components && /* @__PURE__ */ jsxRuntime.jsx(
7485
7218
  BundleSelector,
7486
7219
  {
7487
- bundleIdOrSlug: product.slug,
7220
+ components: product.components,
7221
+ bundlePrice: product.bundle_price,
7222
+ discountValue: product.discount_value,
7488
7223
  onSelectionsChange: setBundleSelections,
7489
7224
  onReady: setBundleReady
7490
7225
  }
@@ -7728,14 +7463,12 @@ exports.QuantitySelector = QuantitySelector;
7728
7463
  exports.VariantSelector = VariantSelector;
7729
7464
  exports.getVariantDisplayName = getVariantDisplayName;
7730
7465
  exports.useAds = useAds;
7731
- exports.useBundle = useBundle;
7732
7466
  exports.useCart = useCart;
7733
7467
  exports.useCategories = useCategories;
7734
7468
  exports.useCheckout = useCheckout;
7735
7469
  exports.useCimplify = useCimplify;
7736
7470
  exports.useCollection = useCollection;
7737
7471
  exports.useCollections = useCollections;
7738
- exports.useComposite = useComposite;
7739
7472
  exports.useElements = useElements;
7740
7473
  exports.useElementsReady = useElementsReady;
7741
7474
  exports.useLocations = useLocations;