@cimplify/sdk 0.8.13 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/react.js CHANGED
@@ -612,6 +612,12 @@ function normalizeCatalogueProductPayload(product) {
612
612
  if (variantAdjustment === void 0 || variantAdjustment === null || variantAdjustment === "") {
613
613
  normalizedVariant["price_adjustment"] = readFinalPrice(normalizedVariant["price_info"]) ?? "0";
614
614
  }
615
+ if (!normalizedVariant["name"]) {
616
+ const attrs = normalizedVariant["display_attributes"];
617
+ if (Array.isArray(attrs) && attrs.length > 0) {
618
+ normalizedVariant["name"] = attrs.map((a) => a.value_name).filter(Boolean).join(" / ");
619
+ }
620
+ }
615
621
  return normalizedVariant;
616
622
  });
617
623
  }
@@ -4416,6 +4422,8 @@ function CimplifyCheckout({
4416
4422
  locationId,
4417
4423
  linkUrl,
4418
4424
  orderTypes,
4425
+ defaultOrderType,
4426
+ submitLabel,
4419
4427
  enrollInLink = true,
4420
4428
  onComplete,
4421
4429
  onError,
@@ -4428,7 +4436,13 @@ function CimplifyCheckout({
4428
4436
  () => orderTypes && orderTypes.length > 0 ? orderTypes : ["pickup", "delivery"],
4429
4437
  [orderTypes]
4430
4438
  );
4431
- const [orderType, setOrderType] = React3.useState(resolvedOrderTypes[0] || "pickup");
4439
+ const resolvedDefaultOrderType = React3.useMemo(() => {
4440
+ if (defaultOrderType && resolvedOrderTypes.includes(defaultOrderType)) {
4441
+ return defaultOrderType;
4442
+ }
4443
+ return resolvedOrderTypes[0] || "pickup";
4444
+ }, [defaultOrderType, resolvedOrderTypes]);
4445
+ const [orderType, setOrderType] = React3.useState(resolvedDefaultOrderType);
4432
4446
  const [status, setStatus] = React3.useState(null);
4433
4447
  const [statusText, setStatusText] = React3.useState("");
4434
4448
  const [isSubmitting, setIsSubmitting] = React3.useState(false);
@@ -4475,9 +4489,9 @@ function CimplifyCheckout({
4475
4489
  );
4476
4490
  React3.useEffect(() => {
4477
4491
  if (!resolvedOrderTypes.includes(orderType)) {
4478
- setOrderType(resolvedOrderTypes[0] || "pickup");
4492
+ setOrderType(resolvedDefaultOrderType);
4479
4493
  }
4480
- }, [resolvedOrderTypes, orderType]);
4494
+ }, [resolvedOrderTypes, resolvedDefaultOrderType, orderType]);
4481
4495
  React3.useEffect(() => {
4482
4496
  if (appearance && appearance !== initialAppearanceRef.current && !hasWarnedInlineAppearanceRef.current) {
4483
4497
  hasWarnedInlineAppearanceRef.current = true;
@@ -4667,7 +4681,8 @@ function CimplifyCheckout({
4667
4681
  elementsRef.current = elements;
4668
4682
  const checkout = elements.create("checkout", {
4669
4683
  orderTypes: resolvedOrderTypes,
4670
- defaultOrderType: resolvedOrderTypes[0]
4684
+ defaultOrderType: resolvedDefaultOrderType,
4685
+ submitLabel
4671
4686
  });
4672
4687
  if (checkoutMountRef.current) {
4673
4688
  checkout.mount(checkoutMountRef.current);
@@ -4693,7 +4708,14 @@ function CimplifyCheckout({
4693
4708
  elements.destroy();
4694
4709
  elementsRef.current = null;
4695
4710
  };
4696
- }, [client, resolvedBusinessId, isDemoCheckout]);
4711
+ }, [
4712
+ client,
4713
+ resolvedBusinessId,
4714
+ isDemoCheckout,
4715
+ resolvedOrderTypes,
4716
+ resolvedDefaultOrderType,
4717
+ submitLabel
4718
+ ]);
4697
4719
  React3.useEffect(() => {
4698
4720
  if (!resolvedCart || !elementsRef.current) return;
4699
4721
  const checkoutElement = elementsRef.current.getElement("checkout");
@@ -6762,16 +6784,940 @@ function useCheckout() {
6762
6784
  );
6763
6785
  return { submit, process, isLoading };
6764
6786
  }
6787
+ function QuantitySelector({
6788
+ value,
6789
+ onChange,
6790
+ min = 1,
6791
+ max,
6792
+ className
6793
+ }) {
6794
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-quantity": true, className, style: { display: "inline-flex", alignItems: "center", gap: "0.5rem" }, children: [
6795
+ /* @__PURE__ */ jsxRuntime.jsx(
6796
+ "button",
6797
+ {
6798
+ type: "button",
6799
+ onClick: () => onChange(Math.max(min, value - 1)),
6800
+ disabled: value <= min,
6801
+ "aria-label": "Decrease quantity",
6802
+ "data-cimplify-quantity-decrement": true,
6803
+ children: "\u2212"
6804
+ }
6805
+ ),
6806
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-quantity-value": true, "aria-live": "polite", children: value }),
6807
+ /* @__PURE__ */ jsxRuntime.jsx(
6808
+ "button",
6809
+ {
6810
+ type: "button",
6811
+ onClick: () => onChange(max != null ? Math.min(max, value + 1) : value + 1),
6812
+ disabled: max != null && value >= max,
6813
+ "aria-label": "Increase quantity",
6814
+ "data-cimplify-quantity-increment": true,
6815
+ children: "+"
6816
+ }
6817
+ )
6818
+ ] });
6819
+ }
6820
+
6821
+ // src/utils/variant.ts
6822
+ function getVariantDisplayName(variant) {
6823
+ if (variant.name) return variant.name;
6824
+ if (variant.display_attributes?.length) {
6825
+ return variant.display_attributes.map((a) => a.value_name).join(" / ");
6826
+ }
6827
+ return variant.is_default ? "Default" : "Option";
6828
+ }
6829
+ function VariantSelector({
6830
+ variants,
6831
+ variantAxes,
6832
+ basePrice,
6833
+ selectedVariantId,
6834
+ onVariantChange,
6835
+ className
6836
+ }) {
6837
+ const [axisSelections, setAxisSelections] = React3.useState({});
6838
+ const initialized = React3.useRef(false);
6839
+ React3.useEffect(() => {
6840
+ initialized.current = false;
6841
+ }, [variants]);
6842
+ React3.useEffect(() => {
6843
+ if (initialized.current) return;
6844
+ if (!variants || variants.length === 0) return;
6845
+ const defaultVariant = variants.find((v) => v.is_default) || variants[0];
6846
+ if (!defaultVariant) return;
6847
+ initialized.current = true;
6848
+ onVariantChange(defaultVariant.id, defaultVariant);
6849
+ if (defaultVariant.display_attributes) {
6850
+ const initial = {};
6851
+ for (const attr of defaultVariant.display_attributes) {
6852
+ initial[attr.axis_id] = attr.value_id;
6853
+ }
6854
+ setAxisSelections(initial);
6855
+ }
6856
+ }, [variants, onVariantChange]);
6857
+ React3.useEffect(() => {
6858
+ if (!initialized.current) return;
6859
+ if (!variantAxes || variantAxes.length === 0) return;
6860
+ const match = variants.find((v) => {
6861
+ if (!v.display_attributes) return false;
6862
+ return v.display_attributes.every(
6863
+ (attr) => axisSelections[attr.axis_id] === attr.value_id
6864
+ );
6865
+ });
6866
+ if (match && match.id !== selectedVariantId) {
6867
+ onVariantChange(match.id, match);
6868
+ }
6869
+ }, [axisSelections, variants, variantAxes, selectedVariantId, onVariantChange]);
6870
+ if (!variants || variants.length <= 1) {
6871
+ return null;
6872
+ }
6873
+ const basePriceNum = basePrice != null ? parsePrice(basePrice) : 0;
6874
+ if (variantAxes && variantAxes.length > 0) {
6875
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-variant-selector": true, className, children: variantAxes.map((axis) => /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-variant-axis": true, children: [
6876
+ /* @__PURE__ */ jsxRuntime.jsx("label", { "data-cimplify-variant-axis-label": true, children: axis.name }),
6877
+ /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-variant-axis-options": true, children: axis.values.map((value) => {
6878
+ const isSelected = axisSelections[axis.id] === value.id;
6879
+ return /* @__PURE__ */ jsxRuntime.jsx(
6880
+ "button",
6881
+ {
6882
+ type: "button",
6883
+ "aria-selected": isSelected,
6884
+ onClick: () => {
6885
+ setAxisSelections((prev) => ({
6886
+ ...prev,
6887
+ [axis.id]: value.id
6888
+ }));
6889
+ },
6890
+ "data-cimplify-variant-option": true,
6891
+ "data-selected": isSelected || void 0,
6892
+ children: value.name
6893
+ },
6894
+ value.id
6895
+ );
6896
+ }) })
6897
+ ] }, axis.id)) });
6898
+ }
6899
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-variant-selector": true, className, children: [
6900
+ /* @__PURE__ */ jsxRuntime.jsx("label", { "data-cimplify-variant-list-label": true, children: "Options" }),
6901
+ /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-variant-list": true, children: variants.map((variant) => {
6902
+ const isSelected = selectedVariantId === variant.id;
6903
+ const adjustment = parsePrice(variant.price_adjustment);
6904
+ const effectivePrice = basePriceNum + adjustment;
6905
+ return /* @__PURE__ */ jsxRuntime.jsxs(
6906
+ "button",
6907
+ {
6908
+ type: "button",
6909
+ "aria-selected": isSelected,
6910
+ onClick: () => onVariantChange(variant.id, variant),
6911
+ "data-cimplify-variant-option": true,
6912
+ "data-selected": isSelected || void 0,
6913
+ children: [
6914
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-variant-name": true, children: getVariantDisplayName(variant) }),
6915
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-variant-pricing": true, children: [
6916
+ adjustment !== 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-variant-adjustment": true, children: [
6917
+ adjustment > 0 ? "+" : "",
6918
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: variant.price_adjustment })
6919
+ ] }),
6920
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: effectivePrice })
6921
+ ] })
6922
+ ]
6923
+ },
6924
+ variant.id
6925
+ );
6926
+ }) })
6927
+ ] });
6928
+ }
6929
+ function AddOnSelector({
6930
+ addOns,
6931
+ selectedOptions,
6932
+ onOptionsChange,
6933
+ className
6934
+ }) {
6935
+ const isOptionSelected = React3.useCallback(
6936
+ (optionId) => selectedOptions.includes(optionId),
6937
+ [selectedOptions]
6938
+ );
6939
+ const toggleOption = React3.useCallback(
6940
+ (addOn, optionId) => {
6941
+ const isSelected = selectedOptions.includes(optionId);
6942
+ if (addOn.is_mutually_exclusive || !addOn.is_multiple_allowed) {
6943
+ const groupOptionIds = new Set(addOn.options.map((o) => o.id));
6944
+ const withoutGroup = selectedOptions.filter((id) => !groupOptionIds.has(id));
6945
+ if (isSelected) {
6946
+ if (!addOn.is_required) {
6947
+ onOptionsChange(withoutGroup);
6948
+ }
6949
+ } else {
6950
+ onOptionsChange([...withoutGroup, optionId]);
6951
+ }
6952
+ } else {
6953
+ if (isSelected) {
6954
+ onOptionsChange(selectedOptions.filter((id) => id !== optionId));
6955
+ } else {
6956
+ const currentCount = selectedOptions.filter(
6957
+ (id) => addOn.options.some((o) => o.id === id)
6958
+ ).length;
6959
+ if (addOn.max_selections && currentCount >= addOn.max_selections) {
6960
+ return;
6961
+ }
6962
+ onOptionsChange([...selectedOptions, optionId]);
6963
+ }
6964
+ }
6965
+ },
6966
+ [selectedOptions, onOptionsChange]
6967
+ );
6968
+ if (!addOns || addOns.length === 0) {
6969
+ return null;
6970
+ }
6971
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-addon-selector": true, className, children: addOns.map((addOn) => {
6972
+ const currentSelections = selectedOptions.filter(
6973
+ (id) => addOn.options.some((o) => o.id === id)
6974
+ ).length;
6975
+ const minMet = !addOn.min_selections || currentSelections >= addOn.min_selections;
6976
+ const isSingleSelect = addOn.is_mutually_exclusive || !addOn.is_multiple_allowed;
6977
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-addon-group": true, children: [
6978
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-addon-header": true, children: [
6979
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
6980
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-addon-name": true, children: [
6981
+ addOn.name,
6982
+ addOn.is_required && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-addon-required": true, children: " *" })
6983
+ ] }),
6984
+ (addOn.min_selections || addOn.max_selections) && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-addon-constraint": true, children: addOn.min_selections && addOn.max_selections ? `Choose ${addOn.min_selections}\u2013${addOn.max_selections}` : addOn.min_selections ? `Choose at least ${addOn.min_selections}` : `Choose up to ${addOn.max_selections}` })
6985
+ ] }),
6986
+ !minMet && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-addon-validation": true, children: "Required" })
6987
+ ] }),
6988
+ /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-addon-options": true, children: addOn.options.map((option) => {
6989
+ const isSelected = isOptionSelected(option.id);
6990
+ return /* @__PURE__ */ jsxRuntime.jsxs(
6991
+ "button",
6992
+ {
6993
+ type: "button",
6994
+ role: isSingleSelect ? "radio" : "checkbox",
6995
+ "aria-checked": isSelected,
6996
+ onClick: () => toggleOption(addOn, option.id),
6997
+ "data-cimplify-addon-option": true,
6998
+ "data-selected": isSelected || void 0,
6999
+ children: [
7000
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-addon-option-name": true, children: option.name }),
7001
+ option.default_price && option.default_price !== "0" && /* @__PURE__ */ jsxRuntime.jsx(
7002
+ Price,
7003
+ {
7004
+ amount: option.default_price,
7005
+ prefix: "+"
7006
+ }
7007
+ )
7008
+ ]
7009
+ },
7010
+ option.id
7011
+ );
7012
+ }) })
7013
+ ] }, addOn.id);
7014
+ }) });
7015
+ }
7016
+ function CompositeSelector({
7017
+ productId,
7018
+ onSelectionsChange,
7019
+ onPriceChange,
7020
+ onReady,
7021
+ className
7022
+ }) {
7023
+ const { composite, isLoading, error, calculatePrice, priceResult, isPriceLoading } = useComposite(productId);
7024
+ const [groupSelections, setGroupSelections] = React3.useState({});
7025
+ const selections = React3.useMemo(() => {
7026
+ const result = [];
7027
+ for (const groupSels of Object.values(groupSelections)) {
7028
+ for (const [componentId, qty] of Object.entries(groupSels)) {
7029
+ if (qty > 0) {
7030
+ result.push({ component_id: componentId, quantity: qty });
7031
+ }
7032
+ }
7033
+ }
7034
+ return result;
7035
+ }, [groupSelections]);
7036
+ React3.useEffect(() => {
7037
+ onSelectionsChange(selections);
7038
+ }, [selections, onSelectionsChange]);
7039
+ React3.useEffect(() => {
7040
+ onPriceChange?.(priceResult);
7041
+ }, [priceResult, onPriceChange]);
7042
+ const allGroupsSatisfied = React3.useMemo(() => {
7043
+ if (!composite) return false;
7044
+ for (const group of composite.groups) {
7045
+ const groupSels = groupSelections[group.id] || {};
7046
+ const totalSelected = Object.values(groupSels).reduce((sum, q) => sum + q, 0);
7047
+ if (totalSelected < group.min_selections) return false;
7048
+ }
7049
+ return true;
7050
+ }, [composite, groupSelections]);
7051
+ React3.useEffect(() => {
7052
+ onReady?.(allGroupsSatisfied);
7053
+ }, [allGroupsSatisfied, onReady]);
7054
+ React3.useEffect(() => {
7055
+ if (allGroupsSatisfied && selections.length > 0) {
7056
+ void calculatePrice(selections);
7057
+ }
7058
+ }, [selections, allGroupsSatisfied, calculatePrice]);
7059
+ const toggleComponent = React3.useCallback(
7060
+ (group, component) => {
7061
+ setGroupSelections((prev) => {
7062
+ const groupSels = { ...prev[group.id] || {} };
7063
+ const currentQty = groupSels[component.id] || 0;
7064
+ if (currentQty > 0) {
7065
+ if (group.min_selections > 0) {
7066
+ const totalOthers = Object.entries(groupSels).filter(([id]) => id !== component.id).reduce((sum, [, q]) => sum + q, 0);
7067
+ if (totalOthers < group.min_selections) {
7068
+ return prev;
7069
+ }
7070
+ }
7071
+ delete groupSels[component.id];
7072
+ } else {
7073
+ const totalSelected = Object.values(groupSels).reduce((sum, q) => sum + q, 0);
7074
+ if (group.max_selections && totalSelected >= group.max_selections) {
7075
+ if (group.max_selections === 1) {
7076
+ return { ...prev, [group.id]: { [component.id]: 1 } };
7077
+ }
7078
+ return prev;
7079
+ }
7080
+ groupSels[component.id] = 1;
7081
+ }
7082
+ return { ...prev, [group.id]: groupSels };
7083
+ });
7084
+ },
7085
+ []
7086
+ );
7087
+ const updateQuantity = React3.useCallback(
7088
+ (group, componentId, delta) => {
7089
+ setGroupSelections((prev) => {
7090
+ const groupSels = { ...prev[group.id] || {} };
7091
+ const current = groupSels[componentId] || 0;
7092
+ const next = Math.max(0, current + delta);
7093
+ if (group.max_quantity_per_component && next > group.max_quantity_per_component) {
7094
+ return prev;
7095
+ }
7096
+ if (next === 0) {
7097
+ delete groupSels[componentId];
7098
+ } else {
7099
+ groupSels[componentId] = next;
7100
+ }
7101
+ return { ...prev, [group.id]: groupSels };
7102
+ });
7103
+ },
7104
+ []
7105
+ );
7106
+ if (isLoading) {
7107
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-composite-selector": true, "data-loading": true, className, children: "Loading options..." });
7108
+ }
7109
+ if (error || !composite) {
7110
+ return null;
7111
+ }
7112
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-composite-selector": true, className, children: [
7113
+ composite.groups.sort((a, b) => a.display_order - b.display_order).map((group) => {
7114
+ const groupSels = groupSelections[group.id] || {};
7115
+ const totalSelected = Object.values(groupSels).reduce((sum, q) => sum + q, 0);
7116
+ const minMet = totalSelected >= group.min_selections;
7117
+ const isSingleSelect = group.max_selections === 1;
7118
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-composite-group": true, children: [
7119
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-composite-group-header": true, children: [
7120
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
7121
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-composite-group-name": true, children: [
7122
+ group.name,
7123
+ group.min_selections > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-composite-required": true, children: " *" })
7124
+ ] }),
7125
+ group.description && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-composite-group-description": true, children: group.description }),
7126
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-composite-group-constraint": true, children: group.min_selections > 0 && group.max_selections ? `Choose ${group.min_selections}\u2013${group.max_selections}` : group.min_selections > 0 ? `Choose at least ${group.min_selections}` : group.max_selections ? `Choose up to ${group.max_selections}` : "Choose as many as you like" })
7127
+ ] }),
7128
+ !minMet && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-composite-validation": true, children: "Required" })
7129
+ ] }),
7130
+ /* @__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) => {
7131
+ const qty = groupSels[component.id] || 0;
7132
+ const isSelected = qty > 0;
7133
+ const displayName = component.display_name || component.product_id || component.id;
7134
+ return /* @__PURE__ */ jsxRuntime.jsxs(
7135
+ "button",
7136
+ {
7137
+ type: "button",
7138
+ role: isSingleSelect ? "radio" : "checkbox",
7139
+ "aria-checked": isSelected,
7140
+ onClick: () => toggleComponent(group, component),
7141
+ "data-cimplify-composite-component": true,
7142
+ "data-selected": isSelected || void 0,
7143
+ children: [
7144
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-composite-component-info": true, children: [
7145
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-composite-component-name": true, children: displayName }),
7146
+ component.is_popular && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-composite-badge": "popular", children: "Popular" }),
7147
+ component.is_premium && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-composite-badge": "premium", children: "Premium" }),
7148
+ component.display_description && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-composite-component-description": true, children: component.display_description }),
7149
+ component.calories != null && /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-composite-component-calories": true, children: [
7150
+ component.calories,
7151
+ " cal"
7152
+ ] })
7153
+ ] }),
7154
+ group.allow_quantity && isSelected && /* @__PURE__ */ jsxRuntime.jsxs(
7155
+ "span",
7156
+ {
7157
+ "data-cimplify-composite-qty": true,
7158
+ onClick: (e) => e.stopPropagation(),
7159
+ children: [
7160
+ /* @__PURE__ */ jsxRuntime.jsx(
7161
+ "button",
7162
+ {
7163
+ type: "button",
7164
+ onClick: () => updateQuantity(group, component.id, -1),
7165
+ "aria-label": `Decrease ${displayName} quantity`,
7166
+ children: "\u2212"
7167
+ }
7168
+ ),
7169
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: qty }),
7170
+ /* @__PURE__ */ jsxRuntime.jsx(
7171
+ "button",
7172
+ {
7173
+ type: "button",
7174
+ onClick: () => updateQuantity(group, component.id, 1),
7175
+ "aria-label": `Increase ${displayName} quantity`,
7176
+ children: "+"
7177
+ }
7178
+ )
7179
+ ]
7180
+ }
7181
+ ),
7182
+ component.price && component.price !== "0" && /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: component.price, prefix: "+" })
7183
+ ]
7184
+ },
7185
+ component.id
7186
+ );
7187
+ }) })
7188
+ ] }, group.id);
7189
+ }),
7190
+ priceResult && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-composite-summary": true, children: [
7191
+ priceResult.base_price !== "0" && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-composite-summary-line": true, children: [
7192
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Base" }),
7193
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: priceResult.base_price })
7194
+ ] }),
7195
+ priceResult.components_total !== "0" && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-composite-summary-line": true, children: [
7196
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Selections" }),
7197
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: priceResult.components_total })
7198
+ ] }),
7199
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-composite-summary-total": true, children: [
7200
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Total" }),
7201
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: priceResult.final_price })
7202
+ ] })
7203
+ ] }),
7204
+ isPriceLoading && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-composite-calculating": true, children: "Calculating price..." })
7205
+ ] });
7206
+ }
7207
+ function BundleSelector({
7208
+ bundleIdOrSlug,
7209
+ onSelectionsChange,
7210
+ onReady,
7211
+ className
7212
+ }) {
7213
+ const { bundle, isLoading, error } = useBundle(bundleIdOrSlug);
7214
+ const [variantChoices, setVariantChoices] = React3.useState({});
7215
+ React3.useEffect(() => {
7216
+ if (!bundle) return;
7217
+ const defaults = {};
7218
+ for (const comp of bundle.components) {
7219
+ if (comp.component.variant_id) {
7220
+ defaults[comp.component.id] = comp.component.variant_id;
7221
+ } else if (comp.variants.length > 0) {
7222
+ const defaultVariant = comp.variants.find((v) => v.is_default) || comp.variants[0];
7223
+ if (defaultVariant) {
7224
+ defaults[comp.component.id] = defaultVariant.id;
7225
+ }
7226
+ }
7227
+ }
7228
+ setVariantChoices(defaults);
7229
+ }, [bundle]);
7230
+ const selections = React3.useMemo(() => {
7231
+ if (!bundle) return [];
7232
+ return bundle.components.map((comp) => ({
7233
+ component_id: comp.component.id,
7234
+ variant_id: variantChoices[comp.component.id],
7235
+ quantity: comp.component.quantity
7236
+ }));
7237
+ }, [bundle, variantChoices]);
7238
+ React3.useEffect(() => {
7239
+ onSelectionsChange(selections);
7240
+ }, [selections, onSelectionsChange]);
7241
+ React3.useEffect(() => {
7242
+ onReady?.(bundle != null && selections.length > 0);
7243
+ }, [bundle, selections, onReady]);
7244
+ const handleVariantChange = React3.useCallback(
7245
+ (componentId, variantId) => {
7246
+ setVariantChoices((prev) => ({ ...prev, [componentId]: variantId }));
7247
+ },
7248
+ []
7249
+ );
7250
+ if (isLoading) {
7251
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-bundle-selector": true, "data-loading": true, className, children: "Loading bundle..." });
7252
+ }
7253
+ if (error || !bundle) {
7254
+ return null;
7255
+ }
7256
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-bundle-selector": true, className, children: [
7257
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-bundle-heading": true, children: "Included in this bundle" }),
7258
+ /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-bundle-components": true, children: bundle.components.map((comp) => /* @__PURE__ */ jsxRuntime.jsx(
7259
+ BundleComponentCard,
7260
+ {
7261
+ data: comp,
7262
+ selectedVariantId: variantChoices[comp.component.id],
7263
+ onVariantChange: (variantId) => handleVariantChange(comp.component.id, variantId)
7264
+ },
7265
+ comp.component.id
7266
+ )) }),
7267
+ bundle.bundle_price && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-bundle-summary": true, children: [
7268
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Bundle price" }),
7269
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: bundle.bundle_price })
7270
+ ] }),
7271
+ bundle.discount_value && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-bundle-savings": true, children: [
7272
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "You save" }),
7273
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: bundle.discount_value })
7274
+ ] })
7275
+ ] });
7276
+ }
7277
+ function BundleComponentCard({
7278
+ data,
7279
+ selectedVariantId,
7280
+ onVariantChange
7281
+ }) {
7282
+ const { component, product, variants } = data;
7283
+ const showVariantPicker = component.allow_variant_choice && variants.length > 1;
7284
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-bundle-component": true, children: [
7285
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-bundle-component-header": true, children: [
7286
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
7287
+ component.quantity > 1 && /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-bundle-component-qty": true, children: [
7288
+ "\xD7",
7289
+ component.quantity
7290
+ ] }),
7291
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-bundle-component-name": true, children: product.name })
7292
+ ] }),
7293
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: product.default_price })
7294
+ ] }),
7295
+ showVariantPicker && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-bundle-variant-picker": true, children: variants.map((variant) => {
7296
+ const isSelected = selectedVariantId === variant.id;
7297
+ const adjustment = parsePrice(variant.price_adjustment);
7298
+ return /* @__PURE__ */ jsxRuntime.jsxs(
7299
+ "button",
7300
+ {
7301
+ type: "button",
7302
+ "aria-selected": isSelected,
7303
+ onClick: () => onVariantChange(variant.id),
7304
+ "data-cimplify-bundle-variant-option": true,
7305
+ "data-selected": isSelected || void 0,
7306
+ children: [
7307
+ getVariantDisplayName(variant),
7308
+ adjustment !== 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-bundle-variant-adjustment": true, children: [
7309
+ adjustment > 0 ? "+" : "",
7310
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: variant.price_adjustment })
7311
+ ] })
7312
+ ]
7313
+ },
7314
+ variant.id
7315
+ );
7316
+ }) })
7317
+ ] });
7318
+ }
7319
+ function ProductCustomizer({
7320
+ product,
7321
+ onAddToCart,
7322
+ className
7323
+ }) {
7324
+ const [quantity, setQuantity] = React3.useState(1);
7325
+ const [isAdded, setIsAdded] = React3.useState(false);
7326
+ const [isSubmitting, setIsSubmitting] = React3.useState(false);
7327
+ const [selectedVariantId, setSelectedVariantId] = React3.useState();
7328
+ const [selectedVariant, setSelectedVariant] = React3.useState();
7329
+ const [selectedAddOnOptionIds, setSelectedAddOnOptionIds] = React3.useState([]);
7330
+ const [compositeSelections, setCompositeSelections] = React3.useState([]);
7331
+ const [compositePrice, setCompositePrice] = React3.useState(null);
7332
+ const [compositeReady, setCompositeReady] = React3.useState(false);
7333
+ const [bundleSelections, setBundleSelections] = React3.useState([]);
7334
+ const [bundleReady, setBundleReady] = React3.useState(false);
7335
+ const cart = useCart();
7336
+ const productType = product.product_type || "product";
7337
+ const isComposite = productType === "composite";
7338
+ const isBundle = productType === "bundle";
7339
+ const isStandard = !isComposite && !isBundle;
7340
+ const hasVariants = isStandard && product.variants && product.variants.length > 0;
7341
+ const hasAddOns = isStandard && product.add_ons && product.add_ons.length > 0;
7342
+ React3.useEffect(() => {
7343
+ setQuantity(1);
7344
+ setIsAdded(false);
7345
+ setIsSubmitting(false);
7346
+ setSelectedVariantId(void 0);
7347
+ setSelectedVariant(void 0);
7348
+ setSelectedAddOnOptionIds([]);
7349
+ setCompositeSelections([]);
7350
+ setCompositePrice(null);
7351
+ setCompositeReady(false);
7352
+ setBundleSelections([]);
7353
+ setBundleReady(false);
7354
+ }, [product.id]);
7355
+ const selectedAddOnOptions = React3.useMemo(() => {
7356
+ if (!product.add_ons) return [];
7357
+ const options = [];
7358
+ for (const addOn of product.add_ons) {
7359
+ for (const option of addOn.options) {
7360
+ if (selectedAddOnOptionIds.includes(option.id)) {
7361
+ options.push(option);
7362
+ }
7363
+ }
7364
+ }
7365
+ return options;
7366
+ }, [product.add_ons, selectedAddOnOptionIds]);
7367
+ const normalizedAddOnOptionIds = React3.useMemo(() => {
7368
+ if (selectedAddOnOptionIds.length === 0) return [];
7369
+ return Array.from(new Set(selectedAddOnOptionIds.map((id) => id.trim()).filter(Boolean))).sort();
7370
+ }, [selectedAddOnOptionIds]);
7371
+ const localTotalPrice = React3.useMemo(() => {
7372
+ if (isComposite && compositePrice) {
7373
+ return parsePrice(compositePrice.final_price) * quantity;
7374
+ }
7375
+ let price = parsePrice(product.default_price);
7376
+ if (selectedVariant?.price_adjustment) {
7377
+ price += parsePrice(selectedVariant.price_adjustment);
7378
+ }
7379
+ for (const option of selectedAddOnOptions) {
7380
+ if (option.default_price) {
7381
+ price += parsePrice(option.default_price);
7382
+ }
7383
+ }
7384
+ return price * quantity;
7385
+ }, [product.default_price, selectedVariant, selectedAddOnOptions, quantity, isComposite, compositePrice]);
7386
+ const requiredAddOnsSatisfied = React3.useMemo(() => {
7387
+ if (!product.add_ons) return true;
7388
+ for (const addOn of product.add_ons) {
7389
+ if (addOn.is_required) {
7390
+ const selectedInGroup = selectedAddOnOptionIds.filter(
7391
+ (id) => addOn.options.some((opt) => opt.id === id)
7392
+ ).length;
7393
+ const minRequired = addOn.min_selections || 1;
7394
+ if (selectedInGroup < minRequired) {
7395
+ return false;
7396
+ }
7397
+ }
7398
+ }
7399
+ return true;
7400
+ }, [product.add_ons, selectedAddOnOptionIds]);
7401
+ const quoteInput = React3.useMemo(
7402
+ () => ({
7403
+ productId: product.id,
7404
+ quantity,
7405
+ variantId: selectedVariantId,
7406
+ addOnOptionIds: normalizedAddOnOptionIds.length > 0 ? normalizedAddOnOptionIds : void 0
7407
+ }),
7408
+ [product.id, quantity, selectedVariantId, normalizedAddOnOptionIds]
7409
+ );
7410
+ const { quote } = useQuote(quoteInput, {
7411
+ enabled: isStandard && requiredAddOnsSatisfied
7412
+ });
7413
+ const quoteId = quote?.quote_id;
7414
+ const quotedTotalPrice = React3.useMemo(() => {
7415
+ if (!quote) return void 0;
7416
+ const quotedTotal = quote.quoted_total_price_info?.final_price ?? quote.final_price_info.final_price;
7417
+ return quotedTotal === void 0 || quotedTotal === null ? void 0 : parsePrice(quotedTotal);
7418
+ }, [quote]);
7419
+ const displayTotalPrice = quotedTotalPrice ?? localTotalPrice;
7420
+ const canAddToCart = React3.useMemo(() => {
7421
+ if (isComposite) return compositeReady;
7422
+ if (isBundle) return bundleReady;
7423
+ return requiredAddOnsSatisfied;
7424
+ }, [isComposite, isBundle, compositeReady, bundleReady, requiredAddOnsSatisfied]);
7425
+ const handleVariantChange = React3.useCallback(
7426
+ (variantId, variant) => {
7427
+ setSelectedVariantId(variantId);
7428
+ setSelectedVariant(variant);
7429
+ },
7430
+ []
7431
+ );
7432
+ const handleAddToCart = async () => {
7433
+ if (isSubmitting) return;
7434
+ setIsSubmitting(true);
7435
+ const options = {
7436
+ variantId: selectedVariantId,
7437
+ variant: selectedVariant ? { id: selectedVariant.id, name: selectedVariant.name || "", price_adjustment: selectedVariant.price_adjustment } : void 0,
7438
+ quoteId,
7439
+ addOnOptionIds: normalizedAddOnOptionIds.length > 0 ? normalizedAddOnOptionIds : void 0,
7440
+ addOnOptions: selectedAddOnOptions.length > 0 ? selectedAddOnOptions.map((opt) => ({
7441
+ id: opt.id,
7442
+ name: opt.name,
7443
+ add_on_id: opt.add_on_id,
7444
+ default_price: opt.default_price
7445
+ })) : void 0,
7446
+ compositeSelections: isComposite && compositeSelections.length > 0 ? compositeSelections : void 0,
7447
+ bundleSelections: isBundle && bundleSelections.length > 0 ? bundleSelections : void 0
7448
+ };
7449
+ try {
7450
+ if (onAddToCart) {
7451
+ await onAddToCart(product, quantity, options);
7452
+ } else {
7453
+ await cart.addItem(product, quantity, options);
7454
+ }
7455
+ setIsAdded(true);
7456
+ setTimeout(() => {
7457
+ setIsAdded(false);
7458
+ setQuantity(1);
7459
+ }, 2e3);
7460
+ } catch {
7461
+ } finally {
7462
+ setIsSubmitting(false);
7463
+ }
7464
+ };
7465
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-customizer": true, className, children: [
7466
+ isComposite && /* @__PURE__ */ jsxRuntime.jsx(
7467
+ CompositeSelector,
7468
+ {
7469
+ productId: product.id,
7470
+ onSelectionsChange: setCompositeSelections,
7471
+ onPriceChange: setCompositePrice,
7472
+ onReady: setCompositeReady
7473
+ }
7474
+ ),
7475
+ isBundle && /* @__PURE__ */ jsxRuntime.jsx(
7476
+ BundleSelector,
7477
+ {
7478
+ bundleIdOrSlug: product.slug,
7479
+ onSelectionsChange: setBundleSelections,
7480
+ onReady: setBundleReady
7481
+ }
7482
+ ),
7483
+ hasVariants && /* @__PURE__ */ jsxRuntime.jsx(
7484
+ VariantSelector,
7485
+ {
7486
+ variants: product.variants,
7487
+ variantAxes: product.variant_axes,
7488
+ basePrice: product.default_price,
7489
+ selectedVariantId,
7490
+ onVariantChange: handleVariantChange
7491
+ }
7492
+ ),
7493
+ hasAddOns && /* @__PURE__ */ jsxRuntime.jsx(
7494
+ AddOnSelector,
7495
+ {
7496
+ addOns: product.add_ons,
7497
+ selectedOptions: selectedAddOnOptionIds,
7498
+ onOptionsChange: setSelectedAddOnOptionIds
7499
+ }
7500
+ ),
7501
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-customizer-actions": true, children: [
7502
+ /* @__PURE__ */ jsxRuntime.jsx(
7503
+ QuantitySelector,
7504
+ {
7505
+ value: quantity,
7506
+ onChange: setQuantity,
7507
+ min: 1
7508
+ }
7509
+ ),
7510
+ /* @__PURE__ */ jsxRuntime.jsx(
7511
+ "button",
7512
+ {
7513
+ type: "button",
7514
+ onClick: handleAddToCart,
7515
+ disabled: isAdded || isSubmitting || !canAddToCart,
7516
+ "data-cimplify-customizer-submit": true,
7517
+ children: isAdded ? "Added to Cart" : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
7518
+ "Add to Cart \xB7 ",
7519
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: displayTotalPrice })
7520
+ ] })
7521
+ }
7522
+ )
7523
+ ] }),
7524
+ !canAddToCart && /* @__PURE__ */ jsxRuntime.jsx("p", { "data-cimplify-customizer-validation": true, children: "Please select all required options" })
7525
+ ] });
7526
+ }
7527
+ var ASPECT_STYLES = {
7528
+ square: { aspectRatio: "1/1" },
7529
+ "4/3": { aspectRatio: "4/3" },
7530
+ "16/10": { aspectRatio: "16/10" },
7531
+ "3/4": { aspectRatio: "3/4" }
7532
+ };
7533
+ function ProductImageGallery({
7534
+ images,
7535
+ productName,
7536
+ aspectRatio = "4/3",
7537
+ className
7538
+ }) {
7539
+ const normalizedImages = React3.useMemo(
7540
+ () => images.filter(
7541
+ (image) => typeof image === "string" && image.trim().length > 0
7542
+ ),
7543
+ [images]
7544
+ );
7545
+ const [selectedImage, setSelectedImage] = React3.useState(0);
7546
+ React3.useEffect(() => {
7547
+ setSelectedImage(0);
7548
+ }, [normalizedImages.length, productName]);
7549
+ if (normalizedImages.length === 0) {
7550
+ return null;
7551
+ }
7552
+ const activeImage = normalizedImages[selectedImage] || normalizedImages[0];
7553
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-image-gallery": true, className, children: [
7554
+ /* @__PURE__ */ jsxRuntime.jsx(
7555
+ "div",
7556
+ {
7557
+ "data-cimplify-image-gallery-main": true,
7558
+ style: { position: "relative", overflow: "hidden", ...ASPECT_STYLES[aspectRatio] },
7559
+ children: /* @__PURE__ */ jsxRuntime.jsx(
7560
+ "img",
7561
+ {
7562
+ src: activeImage,
7563
+ alt: productName,
7564
+ style: { width: "100%", height: "100%", objectFit: "cover" },
7565
+ "data-cimplify-image-gallery-active": true
7566
+ }
7567
+ )
7568
+ }
7569
+ ),
7570
+ normalizedImages.length > 1 && /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-image-gallery-thumbnails": true, style: { display: "flex", gap: "0.5rem", marginTop: "0.75rem" }, children: normalizedImages.map((image, index) => /* @__PURE__ */ jsxRuntime.jsx(
7571
+ "button",
7572
+ {
7573
+ type: "button",
7574
+ onClick: () => setSelectedImage(index),
7575
+ "aria-selected": selectedImage === index,
7576
+ "data-cimplify-image-gallery-thumb": true,
7577
+ "data-selected": selectedImage === index || void 0,
7578
+ style: {
7579
+ width: "4rem",
7580
+ height: "4rem",
7581
+ overflow: "hidden",
7582
+ padding: 0,
7583
+ border: "none",
7584
+ cursor: "pointer"
7585
+ },
7586
+ children: /* @__PURE__ */ jsxRuntime.jsx(
7587
+ "img",
7588
+ {
7589
+ src: image,
7590
+ alt: "",
7591
+ style: { width: "100%", height: "100%", objectFit: "cover" }
7592
+ }
7593
+ )
7594
+ },
7595
+ `${image}-${index}`
7596
+ )) })
7597
+ ] });
7598
+ }
7599
+ function computeUnitPrice(item) {
7600
+ let price = parsePrice(item.product.default_price);
7601
+ if (item.variant?.price_adjustment) {
7602
+ price += parsePrice(item.variant.price_adjustment);
7603
+ }
7604
+ for (const option of item.addOnOptions || []) {
7605
+ if (option.default_price) {
7606
+ price += parsePrice(option.default_price);
7607
+ }
7608
+ }
7609
+ return Math.round(price * 100) / 100;
7610
+ }
7611
+ function CartSummary({
7612
+ onCheckout,
7613
+ onItemRemove,
7614
+ onQuantityChange,
7615
+ emptyMessage = "Your cart is empty",
7616
+ className
7617
+ }) {
7618
+ const { items, itemCount, subtotal, tax, total, isEmpty, removeItem, updateQuantity } = useCart();
7619
+ const handleRemove = (itemId) => {
7620
+ if (onItemRemove) {
7621
+ onItemRemove(itemId);
7622
+ } else {
7623
+ void removeItem(itemId);
7624
+ }
7625
+ };
7626
+ const handleQuantityChange = (itemId, qty) => {
7627
+ if (onQuantityChange) {
7628
+ onQuantityChange(itemId, qty);
7629
+ } else {
7630
+ void updateQuantity(itemId, qty);
7631
+ }
7632
+ };
7633
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-cart-summary": true, className, children: isEmpty ? /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-cart-empty": true, children: /* @__PURE__ */ jsxRuntime.jsx("p", { children: emptyMessage }) }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
7634
+ /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cimplify-cart-items": true, children: items.map((item) => {
7635
+ const unitPrice = computeUnitPrice(item);
7636
+ const hasComposite = item.compositeSelections && item.compositeSelections.length > 0;
7637
+ const hasBundle = item.bundleSelections && item.bundleSelections.length > 0;
7638
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-item": true, children: [
7639
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-item-info": true, children: [
7640
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-cart-item-name": true, children: item.product.name }),
7641
+ item.variant && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-cart-item-variant": true, children: getVariantDisplayName(item.variant) }),
7642
+ item.addOnOptions && item.addOnOptions.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-cart-item-addons": true, children: [
7643
+ "+ ",
7644
+ item.addOnOptions.map((opt) => opt.name).join(", ")
7645
+ ] }),
7646
+ (hasComposite || hasBundle) && /* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-cart-item-badge": true, children: hasComposite ? "Custom" : "Bundle" }),
7647
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: unitPrice })
7648
+ ] }),
7649
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-item-controls": true, children: [
7650
+ /* @__PURE__ */ jsxRuntime.jsx(
7651
+ QuantitySelector,
7652
+ {
7653
+ value: item.quantity,
7654
+ onChange: (qty) => handleQuantityChange(item.id, qty),
7655
+ min: 0
7656
+ }
7657
+ ),
7658
+ /* @__PURE__ */ jsxRuntime.jsx(
7659
+ "button",
7660
+ {
7661
+ type: "button",
7662
+ onClick: () => handleRemove(item.id),
7663
+ "data-cimplify-cart-item-remove": true,
7664
+ "aria-label": `Remove ${item.product.name}`,
7665
+ children: "Remove"
7666
+ }
7667
+ )
7668
+ ] })
7669
+ ] }, item.id);
7670
+ }) }),
7671
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-totals": true, children: [
7672
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-subtotal": true, children: [
7673
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
7674
+ "Subtotal (",
7675
+ itemCount,
7676
+ " ",
7677
+ itemCount === 1 ? "item" : "items",
7678
+ ")"
7679
+ ] }),
7680
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: subtotal })
7681
+ ] }),
7682
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-tax": true, children: [
7683
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Tax" }),
7684
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: tax })
7685
+ ] }),
7686
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-total": true, children: [
7687
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Total" }),
7688
+ /* @__PURE__ */ jsxRuntime.jsx(Price, { amount: total })
7689
+ ] })
7690
+ ] }),
7691
+ onCheckout && /* @__PURE__ */ jsxRuntime.jsx(
7692
+ "button",
7693
+ {
7694
+ type: "button",
7695
+ onClick: onCheckout,
7696
+ "data-cimplify-cart-checkout": true,
7697
+ children: "Proceed to Checkout"
7698
+ }
7699
+ )
7700
+ ] }) });
7701
+ }
6765
7702
 
6766
7703
  exports.Ad = Ad;
6767
7704
  exports.AdProvider = AdProvider;
7705
+ exports.AddOnSelector = AddOnSelector;
6768
7706
  exports.AddressElement = AddressElement;
6769
7707
  exports.AuthElement = AuthElement;
7708
+ exports.BundleSelector = BundleSelector;
7709
+ exports.CartSummary = CartSummary;
6770
7710
  exports.CimplifyCheckout = CimplifyCheckout;
6771
7711
  exports.CimplifyProvider = CimplifyProvider;
7712
+ exports.CompositeSelector = CompositeSelector;
6772
7713
  exports.ElementsProvider = ElementsProvider;
6773
7714
  exports.PaymentElement = PaymentElement;
6774
7715
  exports.Price = Price;
7716
+ exports.ProductCustomizer = ProductCustomizer;
7717
+ exports.ProductImageGallery = ProductImageGallery;
7718
+ exports.QuantitySelector = QuantitySelector;
7719
+ exports.VariantSelector = VariantSelector;
7720
+ exports.getVariantDisplayName = getVariantDisplayName;
6775
7721
  exports.useAds = useAds;
6776
7722
  exports.useBundle = useBundle;
6777
7723
  exports.useCart = useCart;