@cimplify/sdk 0.28.0 → 0.29.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/advanced.d.mts +2 -2
- package/dist/advanced.d.ts +2 -2
- package/dist/{chunk-GS7AX6B3.js → chunk-R4AKAGZQ.js} +115 -0
- package/dist/{chunk-FFUCCUG4.mjs → chunk-REXW2PET.mjs} +113 -1
- package/dist/{index-EGhIxwfI.d.mts → index-Cjfczg2W.d.ts} +2 -2
- package/dist/{index-C2U1gHyP.d.ts → index-D4-b5OZO.d.mts} +2 -2
- package/dist/{index-ClrQ0yTH.d.mts → index-DijjnO-u.d.mts} +52 -2
- package/dist/{index-iHKILmG9.d.ts → index-DwvzjdGi.d.ts} +52 -2
- package/dist/index.d.mts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +22 -10
- package/dist/index.mjs +1 -1
- package/dist/{payment-k8feV7r8.d.ts → payment-BeLHpQMo.d.mts} +101 -1
- package/dist/{payment-k8feV7r8.d.mts → payment-BeLHpQMo.d.ts} +101 -1
- package/dist/{price-4EK-0zF5.d.ts → price-C6gfys5B.d.ts} +1 -1
- package/dist/{price-Den0zv61.d.mts → price-Dvl1p9AM.d.mts} +1 -1
- package/dist/react.d.mts +48 -4
- package/dist/react.d.ts +48 -4
- package/dist/react.js +1258 -358
- package/dist/react.mjs +923 -24
- package/dist/styles.css +1 -1
- package/dist/utils.d.mts +3 -3
- package/dist/utils.d.ts +3 -3
- package/package.json +1 -1
- package/registry/cart-summary.json +1 -1
- package/registry/product-customizer.json +1 -1
package/dist/react.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { DURATION_UNIT, getVariantDisplayName, PRODUCT_TYPE, createCimplifyClient, RENDER_HINT } from './chunk-
|
|
3
|
-
export { getVariantDisplayName } from './chunk-
|
|
2
|
+
import { DURATION_UNIT, getVariantDisplayName, INPUT_FIELD_TYPE, PRODUCT_TYPE, createCimplifyClient, RENDER_HINT } from './chunk-REXW2PET.mjs';
|
|
3
|
+
export { getVariantDisplayName } from './chunk-REXW2PET.mjs';
|
|
4
4
|
import { ELEMENT_TYPES, EVENT_TYPES } from './chunk-3J4PPSMI.mjs';
|
|
5
5
|
import { isSupportedCurrency, formatPrice, parsePrice, getUnitPriceAtQuantity, isOnSale, getDiscountPercentage, getBasePrice, getPriceRange, formatPriceRange } from './chunk-E3HC2YAE.mjs';
|
|
6
|
-
import
|
|
6
|
+
import React10, { createContext, useRef, useState, useCallback, useEffect, useContext, useMemo, useSyncExternalStore, useId } from 'react';
|
|
7
7
|
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
8
8
|
import { clsx } from 'clsx';
|
|
9
9
|
import { twMerge } from 'tailwind-merge';
|
|
@@ -565,7 +565,8 @@ function mapServerCart(serverCart) {
|
|
|
565
565
|
confirmationCode: item.confirmation_code || void 0,
|
|
566
566
|
serviceStatus: item.service_status || void 0,
|
|
567
567
|
bundleResolved: item.bundle_resolved || void 0,
|
|
568
|
-
compositeResolved: item.composite_resolved || void 0
|
|
568
|
+
compositeResolved: item.composite_resolved || void 0,
|
|
569
|
+
customerInputs: item.customer_inputs || void 0
|
|
569
570
|
});
|
|
570
571
|
});
|
|
571
572
|
return {
|
|
@@ -785,7 +786,8 @@ function createCartStore(params) {
|
|
|
785
786
|
scheduled_start: normalizedOptions.scheduledStart,
|
|
786
787
|
scheduled_end: normalizedOptions.scheduledEnd,
|
|
787
788
|
staff_id: normalizedOptions.staffId,
|
|
788
|
-
resource_id: normalizedOptions.resourceId
|
|
789
|
+
resource_id: normalizedOptions.resourceId,
|
|
790
|
+
customer_inputs: normalizedOptions.customerInputs
|
|
789
791
|
});
|
|
790
792
|
if (!result.ok) {
|
|
791
793
|
throw result.error;
|
|
@@ -1423,14 +1425,14 @@ function CimplifyCheckout({
|
|
|
1423
1425
|
resolvedCartRef.current = resolvedCart;
|
|
1424
1426
|
const primaryColor = appearance?.variables?.primaryColor || "#0a2540";
|
|
1425
1427
|
const isDark = appearance?.theme === "dark";
|
|
1426
|
-
const emitStatus =
|
|
1428
|
+
const emitStatus = React10.useEffectEvent(
|
|
1427
1429
|
(nextStatus, context = {}) => {
|
|
1428
1430
|
setStatus(nextStatus);
|
|
1429
1431
|
setStatusText(context.display_text || "");
|
|
1430
1432
|
onStatusChange?.(nextStatus, context);
|
|
1431
1433
|
}
|
|
1432
1434
|
);
|
|
1433
|
-
const fireError =
|
|
1435
|
+
const fireError = React10.useEffectEvent(
|
|
1434
1436
|
(error) => {
|
|
1435
1437
|
onError?.(error);
|
|
1436
1438
|
}
|
|
@@ -1536,7 +1538,7 @@ function CimplifyCheckout({
|
|
|
1536
1538
|
activeCheckoutRef.current = null;
|
|
1537
1539
|
};
|
|
1538
1540
|
}, []);
|
|
1539
|
-
const handleSubmit =
|
|
1541
|
+
const handleSubmit = React10.useEffectEvent(async () => {
|
|
1540
1542
|
if (isSubmitting || isInitializing || !resolvedCartId) {
|
|
1541
1543
|
if (!resolvedCartId && !isInitializing) {
|
|
1542
1544
|
const message = "Your cart is empty. Add items before checkout.";
|
|
@@ -4848,6 +4850,880 @@ function VolumePricing({
|
|
|
4848
4850
|
}
|
|
4849
4851
|
);
|
|
4850
4852
|
}
|
|
4853
|
+
function CustomerInputFields({
|
|
4854
|
+
fields,
|
|
4855
|
+
values,
|
|
4856
|
+
onChange,
|
|
4857
|
+
onFileUpload,
|
|
4858
|
+
className,
|
|
4859
|
+
classNames
|
|
4860
|
+
}) {
|
|
4861
|
+
const clientContext = useOptionalCimplifyClient();
|
|
4862
|
+
if (fields.length === 0) return null;
|
|
4863
|
+
const sorted = [...fields].sort((a, b) => a.display_order - b.display_order);
|
|
4864
|
+
const setValue = useCallback(
|
|
4865
|
+
(fieldId, value) => {
|
|
4866
|
+
onChange({ ...values, [fieldId]: value });
|
|
4867
|
+
},
|
|
4868
|
+
[values, onChange]
|
|
4869
|
+
);
|
|
4870
|
+
const defaultFileUpload = useCallback(
|
|
4871
|
+
async (file) => {
|
|
4872
|
+
if (onFileUpload) return onFileUpload(file, {});
|
|
4873
|
+
if (!clientContext?.client) throw new Error("No upload provider available");
|
|
4874
|
+
const result = await clientContext.client.uploads.upload(file);
|
|
4875
|
+
if (!result.ok) throw new Error(result.error.message);
|
|
4876
|
+
return result.value.url;
|
|
4877
|
+
},
|
|
4878
|
+
[onFileUpload, clientContext]
|
|
4879
|
+
);
|
|
4880
|
+
return /* @__PURE__ */ jsx("div", { "data-cimplify-customer-inputs": true, className: cn("space-y-4", className, classNames?.root), children: sorted.map((field) => /* @__PURE__ */ jsx(
|
|
4881
|
+
InputField,
|
|
4882
|
+
{
|
|
4883
|
+
field,
|
|
4884
|
+
value: values[field.id],
|
|
4885
|
+
onValueChange: (value) => setValue(field.id, value),
|
|
4886
|
+
onFileUpload: onFileUpload ?? (clientContext?.client ? (_file, _field) => defaultFileUpload(_file) : void 0),
|
|
4887
|
+
classNames
|
|
4888
|
+
},
|
|
4889
|
+
field.id
|
|
4890
|
+
)) });
|
|
4891
|
+
}
|
|
4892
|
+
function InputField({
|
|
4893
|
+
field,
|
|
4894
|
+
value,
|
|
4895
|
+
onValueChange,
|
|
4896
|
+
onFileUpload,
|
|
4897
|
+
classNames
|
|
4898
|
+
}) {
|
|
4899
|
+
const hasPriceAdjustment = field.price_adjustment != null && parsePrice(field.price_adjustment) > 0;
|
|
4900
|
+
return /* @__PURE__ */ jsxs("div", { "data-cimplify-customer-input": true, "data-field-type": field.field_type, className: classNames?.field, children: [
|
|
4901
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mb-1.5", children: [
|
|
4902
|
+
/* @__PURE__ */ jsx("label", { className: cn("text-sm font-semibold", classNames?.label), children: field.name }),
|
|
4903
|
+
field.is_required && /* @__PURE__ */ jsx("span", { className: cn("text-xs text-destructive", classNames?.required), children: "Required" }),
|
|
4904
|
+
hasPriceAdjustment && /* @__PURE__ */ jsxs("span", { className: cn("text-xs text-muted-foreground", classNames?.priceAdjustment), children: [
|
|
4905
|
+
"+",
|
|
4906
|
+
/* @__PURE__ */ jsx(Price, { amount: field.price_adjustment })
|
|
4907
|
+
] })
|
|
4908
|
+
] }),
|
|
4909
|
+
field.help_text && /* @__PURE__ */ jsx("p", { className: cn("text-xs text-muted-foreground mb-1.5", classNames?.helpText), children: field.help_text }),
|
|
4910
|
+
/* @__PURE__ */ jsx(
|
|
4911
|
+
FieldInput,
|
|
4912
|
+
{
|
|
4913
|
+
field,
|
|
4914
|
+
value,
|
|
4915
|
+
onValueChange,
|
|
4916
|
+
onFileUpload,
|
|
4917
|
+
classNames
|
|
4918
|
+
}
|
|
4919
|
+
)
|
|
4920
|
+
] });
|
|
4921
|
+
}
|
|
4922
|
+
function FieldInput({
|
|
4923
|
+
field,
|
|
4924
|
+
value,
|
|
4925
|
+
onValueChange,
|
|
4926
|
+
onFileUpload,
|
|
4927
|
+
classNames
|
|
4928
|
+
}) {
|
|
4929
|
+
const inputClass = cn(
|
|
4930
|
+
"w-full rounded-md border border-input bg-background px-3 py-2 text-sm placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring",
|
|
4931
|
+
classNames?.input
|
|
4932
|
+
);
|
|
4933
|
+
switch (field.field_type) {
|
|
4934
|
+
case INPUT_FIELD_TYPE.Text:
|
|
4935
|
+
case INPUT_FIELD_TYPE.Url:
|
|
4936
|
+
return /* @__PURE__ */ jsx(
|
|
4937
|
+
"input",
|
|
4938
|
+
{
|
|
4939
|
+
type: field.field_type === INPUT_FIELD_TYPE.Url ? "url" : "text",
|
|
4940
|
+
value: typeof value === "string" ? value : "",
|
|
4941
|
+
onChange: (e) => onValueChange(e.target.value),
|
|
4942
|
+
placeholder: field.placeholder,
|
|
4943
|
+
required: field.is_required,
|
|
4944
|
+
maxLength: field.validation?.max_length ?? void 0,
|
|
4945
|
+
className: inputClass
|
|
4946
|
+
}
|
|
4947
|
+
);
|
|
4948
|
+
case INPUT_FIELD_TYPE.Textarea:
|
|
4949
|
+
return /* @__PURE__ */ jsx(
|
|
4950
|
+
"textarea",
|
|
4951
|
+
{
|
|
4952
|
+
value: typeof value === "string" ? value : "",
|
|
4953
|
+
onChange: (e) => onValueChange(e.target.value),
|
|
4954
|
+
placeholder: field.placeholder,
|
|
4955
|
+
required: field.is_required,
|
|
4956
|
+
maxLength: field.validation?.max_length ?? void 0,
|
|
4957
|
+
rows: 3,
|
|
4958
|
+
className: cn(inputClass, "resize-none", classNames?.textarea)
|
|
4959
|
+
}
|
|
4960
|
+
);
|
|
4961
|
+
case INPUT_FIELD_TYPE.Number:
|
|
4962
|
+
return /* @__PURE__ */ jsx(
|
|
4963
|
+
"input",
|
|
4964
|
+
{
|
|
4965
|
+
type: "number",
|
|
4966
|
+
value: typeof value === "number" ? value : "",
|
|
4967
|
+
onChange: (e) => onValueChange(e.target.value ? parseFloat(e.target.value) : void 0),
|
|
4968
|
+
placeholder: field.placeholder,
|
|
4969
|
+
required: field.is_required,
|
|
4970
|
+
min: field.validation?.min_value ?? void 0,
|
|
4971
|
+
max: field.validation?.max_value ?? void 0,
|
|
4972
|
+
className: inputClass
|
|
4973
|
+
}
|
|
4974
|
+
);
|
|
4975
|
+
case INPUT_FIELD_TYPE.Select:
|
|
4976
|
+
return /* @__PURE__ */ jsxs(
|
|
4977
|
+
"select",
|
|
4978
|
+
{
|
|
4979
|
+
value: typeof value === "string" ? value : "",
|
|
4980
|
+
onChange: (e) => onValueChange(e.target.value || void 0),
|
|
4981
|
+
required: field.is_required,
|
|
4982
|
+
className: cn(inputClass, classNames?.select),
|
|
4983
|
+
children: [
|
|
4984
|
+
/* @__PURE__ */ jsx("option", { value: "", children: field.placeholder || "Select..." }),
|
|
4985
|
+
(field.options || []).map((opt) => /* @__PURE__ */ jsx("option", { value: opt, children: opt }, opt))
|
|
4986
|
+
]
|
|
4987
|
+
}
|
|
4988
|
+
);
|
|
4989
|
+
case INPUT_FIELD_TYPE.Radio:
|
|
4990
|
+
return /* @__PURE__ */ jsx("div", { className: cn("space-y-2", classNames?.radioGroup), children: (field.options || []).map((opt) => /* @__PURE__ */ jsxs(
|
|
4991
|
+
"label",
|
|
4992
|
+
{
|
|
4993
|
+
className: cn(
|
|
4994
|
+
"flex items-center gap-2 text-sm cursor-pointer",
|
|
4995
|
+
classNames?.radioOption
|
|
4996
|
+
),
|
|
4997
|
+
children: [
|
|
4998
|
+
/* @__PURE__ */ jsx(
|
|
4999
|
+
"input",
|
|
5000
|
+
{
|
|
5001
|
+
type: "radio",
|
|
5002
|
+
name: field.id,
|
|
5003
|
+
value: opt,
|
|
5004
|
+
checked: value === opt,
|
|
5005
|
+
onChange: () => onValueChange(opt),
|
|
5006
|
+
className: "accent-primary"
|
|
5007
|
+
}
|
|
5008
|
+
),
|
|
5009
|
+
opt
|
|
5010
|
+
]
|
|
5011
|
+
},
|
|
5012
|
+
opt
|
|
5013
|
+
)) });
|
|
5014
|
+
case INPUT_FIELD_TYPE.Checkbox:
|
|
5015
|
+
return /* @__PURE__ */ jsxs("label", { className: cn("flex items-center gap-2 text-sm cursor-pointer", classNames?.checkboxLabel), children: [
|
|
5016
|
+
/* @__PURE__ */ jsx(
|
|
5017
|
+
"input",
|
|
5018
|
+
{
|
|
5019
|
+
type: "checkbox",
|
|
5020
|
+
checked: value === true,
|
|
5021
|
+
onChange: (e) => onValueChange(e.target.checked),
|
|
5022
|
+
className: "accent-primary w-4 h-4"
|
|
5023
|
+
}
|
|
5024
|
+
),
|
|
5025
|
+
field.placeholder || field.name
|
|
5026
|
+
] });
|
|
5027
|
+
case INPUT_FIELD_TYPE.Color:
|
|
5028
|
+
return /* @__PURE__ */ jsx(
|
|
5029
|
+
"input",
|
|
5030
|
+
{
|
|
5031
|
+
type: "color",
|
|
5032
|
+
value: typeof value === "string" ? value : "#000000",
|
|
5033
|
+
onChange: (e) => onValueChange(e.target.value),
|
|
5034
|
+
className: cn("w-12 h-10 rounded-md border border-input cursor-pointer", classNames?.colorInput)
|
|
5035
|
+
}
|
|
5036
|
+
);
|
|
5037
|
+
case INPUT_FIELD_TYPE.Date:
|
|
5038
|
+
return /* @__PURE__ */ jsx(
|
|
5039
|
+
"input",
|
|
5040
|
+
{
|
|
5041
|
+
type: "date",
|
|
5042
|
+
value: typeof value === "string" ? value : "",
|
|
5043
|
+
onChange: (e) => onValueChange(e.target.value || void 0),
|
|
5044
|
+
required: field.is_required,
|
|
5045
|
+
className: inputClass
|
|
5046
|
+
}
|
|
5047
|
+
);
|
|
5048
|
+
case INPUT_FIELD_TYPE.File:
|
|
5049
|
+
case INPUT_FIELD_TYPE.Image:
|
|
5050
|
+
return /* @__PURE__ */ jsx(
|
|
5051
|
+
FileUploadInput,
|
|
5052
|
+
{
|
|
5053
|
+
field,
|
|
5054
|
+
value,
|
|
5055
|
+
onValueChange,
|
|
5056
|
+
onFileUpload,
|
|
5057
|
+
classNames
|
|
5058
|
+
}
|
|
5059
|
+
);
|
|
5060
|
+
case INPUT_FIELD_TYPE.Email:
|
|
5061
|
+
return /* @__PURE__ */ jsx(
|
|
5062
|
+
"input",
|
|
5063
|
+
{
|
|
5064
|
+
type: "email",
|
|
5065
|
+
value: typeof value === "string" ? value : "",
|
|
5066
|
+
onChange: (e) => onValueChange(e.target.value),
|
|
5067
|
+
placeholder: field.placeholder || "email@example.com",
|
|
5068
|
+
required: field.is_required,
|
|
5069
|
+
className: inputClass
|
|
5070
|
+
}
|
|
5071
|
+
);
|
|
5072
|
+
case INPUT_FIELD_TYPE.DateTime: {
|
|
5073
|
+
const dtLocalValue = typeof value === "string" && value.includes("T") ? value.slice(0, 16) : typeof value === "string" ? value : "";
|
|
5074
|
+
return /* @__PURE__ */ jsx(
|
|
5075
|
+
"input",
|
|
5076
|
+
{
|
|
5077
|
+
type: "datetime-local",
|
|
5078
|
+
value: dtLocalValue,
|
|
5079
|
+
onChange: (e) => {
|
|
5080
|
+
if (!e.target.value) {
|
|
5081
|
+
onValueChange(void 0);
|
|
5082
|
+
return;
|
|
5083
|
+
}
|
|
5084
|
+
const date = new Date(e.target.value);
|
|
5085
|
+
onValueChange(Number.isNaN(date.getTime()) ? e.target.value : date.toISOString());
|
|
5086
|
+
},
|
|
5087
|
+
required: field.is_required,
|
|
5088
|
+
className: inputClass
|
|
5089
|
+
}
|
|
5090
|
+
);
|
|
5091
|
+
}
|
|
5092
|
+
case INPUT_FIELD_TYPE.Time:
|
|
5093
|
+
return /* @__PURE__ */ jsx(
|
|
5094
|
+
"input",
|
|
5095
|
+
{
|
|
5096
|
+
type: "time",
|
|
5097
|
+
value: typeof value === "string" ? value : "",
|
|
5098
|
+
onChange: (e) => onValueChange(e.target.value || void 0),
|
|
5099
|
+
required: field.is_required,
|
|
5100
|
+
className: inputClass
|
|
5101
|
+
}
|
|
5102
|
+
);
|
|
5103
|
+
case INPUT_FIELD_TYPE.MultiSelect:
|
|
5104
|
+
return /* @__PURE__ */ jsx(
|
|
5105
|
+
MultiSelectInput,
|
|
5106
|
+
{
|
|
5107
|
+
field,
|
|
5108
|
+
value,
|
|
5109
|
+
onValueChange,
|
|
5110
|
+
classNames
|
|
5111
|
+
}
|
|
5112
|
+
);
|
|
5113
|
+
case INPUT_FIELD_TYPE.DateRange:
|
|
5114
|
+
return /* @__PURE__ */ jsx(
|
|
5115
|
+
DateRangeInput,
|
|
5116
|
+
{
|
|
5117
|
+
field,
|
|
5118
|
+
value,
|
|
5119
|
+
onValueChange,
|
|
5120
|
+
classNames,
|
|
5121
|
+
inputClass
|
|
5122
|
+
}
|
|
5123
|
+
);
|
|
5124
|
+
case INPUT_FIELD_TYPE.Address:
|
|
5125
|
+
return /* @__PURE__ */ jsx(
|
|
5126
|
+
AddressInput,
|
|
5127
|
+
{
|
|
5128
|
+
field,
|
|
5129
|
+
value,
|
|
5130
|
+
onValueChange,
|
|
5131
|
+
classNames,
|
|
5132
|
+
inputClass
|
|
5133
|
+
}
|
|
5134
|
+
);
|
|
5135
|
+
case INPUT_FIELD_TYPE.Location:
|
|
5136
|
+
return /* @__PURE__ */ jsx(
|
|
5137
|
+
LocationInput,
|
|
5138
|
+
{
|
|
5139
|
+
field,
|
|
5140
|
+
value,
|
|
5141
|
+
onValueChange,
|
|
5142
|
+
classNames,
|
|
5143
|
+
inputClass
|
|
5144
|
+
}
|
|
5145
|
+
);
|
|
5146
|
+
case INPUT_FIELD_TYPE.Phone:
|
|
5147
|
+
return /* @__PURE__ */ jsx(
|
|
5148
|
+
PhoneInput,
|
|
5149
|
+
{
|
|
5150
|
+
field,
|
|
5151
|
+
value,
|
|
5152
|
+
onValueChange,
|
|
5153
|
+
classNames,
|
|
5154
|
+
inputClass
|
|
5155
|
+
}
|
|
5156
|
+
);
|
|
5157
|
+
case INPUT_FIELD_TYPE.Signature:
|
|
5158
|
+
return /* @__PURE__ */ jsx(
|
|
5159
|
+
SignatureInput,
|
|
5160
|
+
{
|
|
5161
|
+
field,
|
|
5162
|
+
value,
|
|
5163
|
+
onValueChange,
|
|
5164
|
+
classNames
|
|
5165
|
+
}
|
|
5166
|
+
);
|
|
5167
|
+
default:
|
|
5168
|
+
return /* @__PURE__ */ jsx(
|
|
5169
|
+
"input",
|
|
5170
|
+
{
|
|
5171
|
+
type: "text",
|
|
5172
|
+
value: typeof value === "string" ? value : "",
|
|
5173
|
+
onChange: (e) => onValueChange(e.target.value),
|
|
5174
|
+
placeholder: field.placeholder,
|
|
5175
|
+
className: inputClass
|
|
5176
|
+
}
|
|
5177
|
+
);
|
|
5178
|
+
}
|
|
5179
|
+
}
|
|
5180
|
+
function FileUploadInput({
|
|
5181
|
+
field,
|
|
5182
|
+
value,
|
|
5183
|
+
onValueChange,
|
|
5184
|
+
onFileUpload,
|
|
5185
|
+
classNames
|
|
5186
|
+
}) {
|
|
5187
|
+
const [isUploading, setIsUploading] = React10.useState(false);
|
|
5188
|
+
const fileUrl = typeof value === "string" ? value : void 0;
|
|
5189
|
+
const acceptedFormats = field.validation?.accepted_formats;
|
|
5190
|
+
const accept = acceptedFormats ? acceptedFormats.map((f) => `.${f}`).join(",") : field.field_type === INPUT_FIELD_TYPE.Image ? "image/*" : void 0;
|
|
5191
|
+
const handleFile = async (file) => {
|
|
5192
|
+
if (!onFileUpload) return;
|
|
5193
|
+
if (field.validation?.max_size_mb) {
|
|
5194
|
+
const maxBytes = field.validation.max_size_mb * 1024 * 1024;
|
|
5195
|
+
if (file.size > maxBytes) {
|
|
5196
|
+
return;
|
|
5197
|
+
}
|
|
5198
|
+
}
|
|
5199
|
+
setIsUploading(true);
|
|
5200
|
+
try {
|
|
5201
|
+
const url = await onFileUpload(file, field);
|
|
5202
|
+
onValueChange(url);
|
|
5203
|
+
} finally {
|
|
5204
|
+
setIsUploading(false);
|
|
5205
|
+
}
|
|
5206
|
+
};
|
|
5207
|
+
return /* @__PURE__ */ jsx("div", { className: cn("space-y-2", classNames?.fileInput), children: fileUrl ? /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
|
|
5208
|
+
field.field_type === INPUT_FIELD_TYPE.Image && /* @__PURE__ */ jsx("img", { src: fileUrl, alt: "Uploaded", className: "w-16 h-16 object-cover rounded-md border border-border" }),
|
|
5209
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsx("p", { className: "text-sm text-foreground truncate", children: fileUrl.split("/").pop() }) }),
|
|
5210
|
+
/* @__PURE__ */ jsx(
|
|
5211
|
+
"button",
|
|
5212
|
+
{
|
|
5213
|
+
type: "button",
|
|
5214
|
+
onClick: () => onValueChange(void 0),
|
|
5215
|
+
className: "text-xs text-muted-foreground hover:text-destructive transition-colors",
|
|
5216
|
+
children: "Remove"
|
|
5217
|
+
}
|
|
5218
|
+
)
|
|
5219
|
+
] }) : /* @__PURE__ */ jsxs("label", { className: "flex flex-col items-center justify-center w-full h-24 border-2 border-dashed border-border rounded-lg cursor-pointer hover:border-primary/40 transition-colors", children: [
|
|
5220
|
+
/* @__PURE__ */ jsx(
|
|
5221
|
+
"input",
|
|
5222
|
+
{
|
|
5223
|
+
type: "file",
|
|
5224
|
+
accept,
|
|
5225
|
+
onChange: (e) => {
|
|
5226
|
+
const file = e.target.files?.[0];
|
|
5227
|
+
if (file) void handleFile(file);
|
|
5228
|
+
},
|
|
5229
|
+
className: "hidden",
|
|
5230
|
+
disabled: isUploading
|
|
5231
|
+
}
|
|
5232
|
+
),
|
|
5233
|
+
isUploading ? /* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: "Uploading..." }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5234
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: field.placeholder || `Upload ${field.field_type === INPUT_FIELD_TYPE.Image ? "image" : "file"}` }),
|
|
5235
|
+
acceptedFormats && /* @__PURE__ */ jsxs("span", { className: "text-xs text-muted-foreground/60 mt-1", children: [
|
|
5236
|
+
acceptedFormats.map((f) => f.toUpperCase()).join(", "),
|
|
5237
|
+
field.validation?.max_size_mb && ` \xB7 Max ${field.validation.max_size_mb}MB`
|
|
5238
|
+
] })
|
|
5239
|
+
] })
|
|
5240
|
+
] }) });
|
|
5241
|
+
}
|
|
5242
|
+
function MultiSelectInput({
|
|
5243
|
+
field,
|
|
5244
|
+
value,
|
|
5245
|
+
onValueChange,
|
|
5246
|
+
classNames
|
|
5247
|
+
}) {
|
|
5248
|
+
const selected = Array.isArray(value) ? value : [];
|
|
5249
|
+
const options = field.options || [];
|
|
5250
|
+
const maxSelections = field.validation?.max_selections;
|
|
5251
|
+
const toggle = (opt) => {
|
|
5252
|
+
const next = selected.includes(opt) ? selected.filter((s) => s !== opt) : maxSelections && selected.length >= maxSelections ? selected : [...selected, opt];
|
|
5253
|
+
onValueChange(next.length > 0 ? next : void 0);
|
|
5254
|
+
};
|
|
5255
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("space-y-2", classNames?.multiSelectGroup), children: [
|
|
5256
|
+
options.map((opt) => /* @__PURE__ */ jsxs(
|
|
5257
|
+
"label",
|
|
5258
|
+
{
|
|
5259
|
+
className: cn(
|
|
5260
|
+
"flex items-center gap-2 text-sm cursor-pointer",
|
|
5261
|
+
classNames?.multiSelectOption
|
|
5262
|
+
),
|
|
5263
|
+
children: [
|
|
5264
|
+
/* @__PURE__ */ jsx(
|
|
5265
|
+
"input",
|
|
5266
|
+
{
|
|
5267
|
+
type: "checkbox",
|
|
5268
|
+
checked: selected.includes(opt),
|
|
5269
|
+
onChange: () => toggle(opt),
|
|
5270
|
+
className: "accent-primary w-4 h-4"
|
|
5271
|
+
}
|
|
5272
|
+
),
|
|
5273
|
+
opt
|
|
5274
|
+
]
|
|
5275
|
+
},
|
|
5276
|
+
opt
|
|
5277
|
+
)),
|
|
5278
|
+
maxSelections && /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground", children: [
|
|
5279
|
+
selected.length,
|
|
5280
|
+
"/",
|
|
5281
|
+
maxSelections,
|
|
5282
|
+
" selected"
|
|
5283
|
+
] })
|
|
5284
|
+
] });
|
|
5285
|
+
}
|
|
5286
|
+
function DateRangeInput({
|
|
5287
|
+
field,
|
|
5288
|
+
value,
|
|
5289
|
+
onValueChange,
|
|
5290
|
+
classNames,
|
|
5291
|
+
inputClass
|
|
5292
|
+
}) {
|
|
5293
|
+
const range = value && typeof value === "object" ? value : {};
|
|
5294
|
+
const update = (key, v) => {
|
|
5295
|
+
const next = { ...range, [key]: v };
|
|
5296
|
+
onValueChange(next.start || next.end ? next : void 0);
|
|
5297
|
+
};
|
|
5298
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("grid grid-cols-2 gap-3", classNames?.dateRangeInput), children: [
|
|
5299
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
5300
|
+
/* @__PURE__ */ jsx("label", { className: "text-xs text-muted-foreground mb-1 block", children: "Start" }),
|
|
5301
|
+
/* @__PURE__ */ jsx(
|
|
5302
|
+
"input",
|
|
5303
|
+
{
|
|
5304
|
+
type: "date",
|
|
5305
|
+
value: range.start || "",
|
|
5306
|
+
onChange: (e) => update("start", e.target.value),
|
|
5307
|
+
required: field.is_required,
|
|
5308
|
+
className: inputClass
|
|
5309
|
+
}
|
|
5310
|
+
)
|
|
5311
|
+
] }),
|
|
5312
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
5313
|
+
/* @__PURE__ */ jsx("label", { className: "text-xs text-muted-foreground mb-1 block", children: "End" }),
|
|
5314
|
+
/* @__PURE__ */ jsx(
|
|
5315
|
+
"input",
|
|
5316
|
+
{
|
|
5317
|
+
type: "date",
|
|
5318
|
+
value: range.end || "",
|
|
5319
|
+
onChange: (e) => update("end", e.target.value),
|
|
5320
|
+
required: field.is_required,
|
|
5321
|
+
className: inputClass
|
|
5322
|
+
}
|
|
5323
|
+
)
|
|
5324
|
+
] })
|
|
5325
|
+
] });
|
|
5326
|
+
}
|
|
5327
|
+
function AddressInput({
|
|
5328
|
+
field,
|
|
5329
|
+
value,
|
|
5330
|
+
onValueChange,
|
|
5331
|
+
classNames,
|
|
5332
|
+
inputClass
|
|
5333
|
+
}) {
|
|
5334
|
+
const clientContext = useOptionalCimplifyClient();
|
|
5335
|
+
const addr = value && typeof value === "object" ? value : null;
|
|
5336
|
+
const [inputText, setInputText] = React10.useState(addr?.formatted_address ?? "");
|
|
5337
|
+
const [suggestions, setSuggestions] = React10.useState([]);
|
|
5338
|
+
const [isOpen, setIsOpen] = React10.useState(false);
|
|
5339
|
+
const [highlightedIndex, setHighlightedIndex] = React10.useState(-1);
|
|
5340
|
+
const debounceRef = React10.useRef(null);
|
|
5341
|
+
const seqRef = React10.useRef(0);
|
|
5342
|
+
const sessionTokenRef = React10.useRef(createSessionToken());
|
|
5343
|
+
const blurTimeoutRef = React10.useRef(null);
|
|
5344
|
+
React10.useEffect(() => {
|
|
5345
|
+
return () => {
|
|
5346
|
+
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
5347
|
+
if (blurTimeoutRef.current) clearTimeout(blurTimeoutRef.current);
|
|
5348
|
+
seqRef.current += 1;
|
|
5349
|
+
};
|
|
5350
|
+
}, []);
|
|
5351
|
+
const fetchSuggestions = React10.useCallback(async (query) => {
|
|
5352
|
+
const client = clientContext?.client;
|
|
5353
|
+
if (!client || query.length < 3) {
|
|
5354
|
+
setSuggestions([]);
|
|
5355
|
+
setIsOpen(false);
|
|
5356
|
+
return;
|
|
5357
|
+
}
|
|
5358
|
+
const seq = ++seqRef.current;
|
|
5359
|
+
const result = await client.places.autocomplete(query, sessionTokenRef.current);
|
|
5360
|
+
if (seqRef.current !== seq) return;
|
|
5361
|
+
if (result.ok && result.value.predictions.length > 0) {
|
|
5362
|
+
setSuggestions(result.value.predictions);
|
|
5363
|
+
setHighlightedIndex(0);
|
|
5364
|
+
setIsOpen(true);
|
|
5365
|
+
} else {
|
|
5366
|
+
setSuggestions([]);
|
|
5367
|
+
setIsOpen(false);
|
|
5368
|
+
}
|
|
5369
|
+
}, [clientContext]);
|
|
5370
|
+
const handleInputChange = (nextValue) => {
|
|
5371
|
+
setInputText(nextValue);
|
|
5372
|
+
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
5373
|
+
debounceRef.current = setTimeout(() => void fetchSuggestions(nextValue.trim()), 300);
|
|
5374
|
+
};
|
|
5375
|
+
const selectSuggestion = React10.useCallback(async (suggestion) => {
|
|
5376
|
+
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
5377
|
+
if (blurTimeoutRef.current) clearTimeout(blurTimeoutRef.current);
|
|
5378
|
+
const fallback = suggestion.description.split(",")[0]?.trim() || suggestion.description;
|
|
5379
|
+
setInputText(fallback);
|
|
5380
|
+
setSuggestions([]);
|
|
5381
|
+
setIsOpen(false);
|
|
5382
|
+
const client = clientContext?.client;
|
|
5383
|
+
if (!client) return;
|
|
5384
|
+
const result = await client.places.details(suggestion.place_id, sessionTokenRef.current);
|
|
5385
|
+
sessionTokenRef.current = createSessionToken();
|
|
5386
|
+
if (result.ok) {
|
|
5387
|
+
const d = result.value;
|
|
5388
|
+
const addressValue = {
|
|
5389
|
+
formatted_address: d.formatted_address || fallback,
|
|
5390
|
+
street_address: d.street_address,
|
|
5391
|
+
apartment: d.apartment,
|
|
5392
|
+
city: d.city,
|
|
5393
|
+
region: d.region,
|
|
5394
|
+
postal_code: d.postal_code,
|
|
5395
|
+
country: d.country,
|
|
5396
|
+
latitude: d.latitude,
|
|
5397
|
+
longitude: d.longitude,
|
|
5398
|
+
place_id: d.place_id
|
|
5399
|
+
};
|
|
5400
|
+
setInputText(addressValue.formatted_address);
|
|
5401
|
+
onValueChange(addressValue);
|
|
5402
|
+
}
|
|
5403
|
+
}, [clientContext, onValueChange]);
|
|
5404
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("space-y-2 relative", classNames?.addressInput), children: [
|
|
5405
|
+
/* @__PURE__ */ jsx(
|
|
5406
|
+
"input",
|
|
5407
|
+
{
|
|
5408
|
+
type: "text",
|
|
5409
|
+
value: inputText,
|
|
5410
|
+
onChange: (e) => handleInputChange(e.target.value),
|
|
5411
|
+
onFocus: () => {
|
|
5412
|
+
if (suggestions.length > 0) setIsOpen(true);
|
|
5413
|
+
},
|
|
5414
|
+
onBlur: () => {
|
|
5415
|
+
blurTimeoutRef.current = setTimeout(() => setIsOpen(false), 120);
|
|
5416
|
+
},
|
|
5417
|
+
onKeyDown: (e) => {
|
|
5418
|
+
if (e.key === "Escape") {
|
|
5419
|
+
setIsOpen(false);
|
|
5420
|
+
return;
|
|
5421
|
+
}
|
|
5422
|
+
if (!isOpen || suggestions.length === 0) return;
|
|
5423
|
+
if (e.key === "ArrowDown") {
|
|
5424
|
+
e.preventDefault();
|
|
5425
|
+
setHighlightedIndex((i) => i < suggestions.length - 1 ? i + 1 : 0);
|
|
5426
|
+
} else if (e.key === "ArrowUp") {
|
|
5427
|
+
e.preventDefault();
|
|
5428
|
+
setHighlightedIndex((i) => i > 0 ? i - 1 : suggestions.length - 1);
|
|
5429
|
+
} else if (e.key === "Enter" && highlightedIndex >= 0) {
|
|
5430
|
+
e.preventDefault();
|
|
5431
|
+
void selectSuggestion(suggestions[highlightedIndex]);
|
|
5432
|
+
}
|
|
5433
|
+
},
|
|
5434
|
+
placeholder: field.placeholder || "Search for an address...",
|
|
5435
|
+
required: field.is_required,
|
|
5436
|
+
autoComplete: "off",
|
|
5437
|
+
"aria-autocomplete": "list",
|
|
5438
|
+
"aria-expanded": isOpen && suggestions.length > 0,
|
|
5439
|
+
className: inputClass
|
|
5440
|
+
}
|
|
5441
|
+
),
|
|
5442
|
+
isOpen && suggestions.length > 0 && /* @__PURE__ */ jsx("div", { role: "listbox", className: "absolute left-0 right-0 top-full z-20 mt-1 overflow-hidden rounded-md border border-border bg-background shadow-lg", children: suggestions.map((s, i) => /* @__PURE__ */ jsx(
|
|
5443
|
+
"button",
|
|
5444
|
+
{
|
|
5445
|
+
type: "button",
|
|
5446
|
+
role: "option",
|
|
5447
|
+
"aria-selected": i === highlightedIndex,
|
|
5448
|
+
onMouseDown: (e) => {
|
|
5449
|
+
e.preventDefault();
|
|
5450
|
+
void selectSuggestion(s);
|
|
5451
|
+
},
|
|
5452
|
+
className: cn("block w-full px-3 py-2.5 text-left text-sm transition-colors", i === highlightedIndex ? "bg-muted text-foreground" : "text-foreground hover:bg-muted/70"),
|
|
5453
|
+
children: s.description
|
|
5454
|
+
},
|
|
5455
|
+
s.place_id
|
|
5456
|
+
)) }),
|
|
5457
|
+
addr && /* @__PURE__ */ jsx(
|
|
5458
|
+
"input",
|
|
5459
|
+
{
|
|
5460
|
+
type: "text",
|
|
5461
|
+
value: addr.apartment || "",
|
|
5462
|
+
onChange: (e) => onValueChange({ ...addr, apartment: e.target.value || void 0 }),
|
|
5463
|
+
placeholder: "Apt, suite, unit (optional)",
|
|
5464
|
+
className: inputClass
|
|
5465
|
+
}
|
|
5466
|
+
)
|
|
5467
|
+
] });
|
|
5468
|
+
}
|
|
5469
|
+
function LocationInput({
|
|
5470
|
+
field,
|
|
5471
|
+
value,
|
|
5472
|
+
onValueChange,
|
|
5473
|
+
classNames,
|
|
5474
|
+
inputClass
|
|
5475
|
+
}) {
|
|
5476
|
+
const clientContext = useOptionalCimplifyClient();
|
|
5477
|
+
const loc = value && typeof value === "object" ? value : null;
|
|
5478
|
+
const [inputText, setInputText] = React10.useState(loc?.label ?? "");
|
|
5479
|
+
const [suggestions, setSuggestions] = React10.useState([]);
|
|
5480
|
+
const [isOpen, setIsOpen] = React10.useState(false);
|
|
5481
|
+
const [highlightedIndex, setHighlightedIndex] = React10.useState(-1);
|
|
5482
|
+
const debounceRef = React10.useRef(null);
|
|
5483
|
+
const seqRef = React10.useRef(0);
|
|
5484
|
+
const sessionTokenRef = React10.useRef(createSessionToken());
|
|
5485
|
+
const blurTimeoutRef = React10.useRef(null);
|
|
5486
|
+
React10.useEffect(() => {
|
|
5487
|
+
return () => {
|
|
5488
|
+
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
5489
|
+
if (blurTimeoutRef.current) clearTimeout(blurTimeoutRef.current);
|
|
5490
|
+
seqRef.current += 1;
|
|
5491
|
+
};
|
|
5492
|
+
}, []);
|
|
5493
|
+
const fetchSuggestions = React10.useCallback(async (query) => {
|
|
5494
|
+
const client = clientContext?.client;
|
|
5495
|
+
if (!client || query.length < 3) {
|
|
5496
|
+
setSuggestions([]);
|
|
5497
|
+
setIsOpen(false);
|
|
5498
|
+
return;
|
|
5499
|
+
}
|
|
5500
|
+
const seq = ++seqRef.current;
|
|
5501
|
+
const result = await client.places.autocomplete(query, sessionTokenRef.current);
|
|
5502
|
+
if (seqRef.current !== seq) return;
|
|
5503
|
+
if (result.ok && result.value.predictions.length > 0) {
|
|
5504
|
+
setSuggestions(result.value.predictions);
|
|
5505
|
+
setHighlightedIndex(0);
|
|
5506
|
+
setIsOpen(true);
|
|
5507
|
+
} else {
|
|
5508
|
+
setSuggestions([]);
|
|
5509
|
+
setIsOpen(false);
|
|
5510
|
+
}
|
|
5511
|
+
}, [clientContext]);
|
|
5512
|
+
const handleInputChange = (nextValue) => {
|
|
5513
|
+
setInputText(nextValue);
|
|
5514
|
+
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
5515
|
+
debounceRef.current = setTimeout(() => void fetchSuggestions(nextValue.trim()), 300);
|
|
5516
|
+
};
|
|
5517
|
+
const selectSuggestion = React10.useCallback(async (suggestion) => {
|
|
5518
|
+
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
5519
|
+
if (blurTimeoutRef.current) clearTimeout(blurTimeoutRef.current);
|
|
5520
|
+
const label = suggestion.description.split(",")[0]?.trim() || suggestion.description;
|
|
5521
|
+
setInputText(label);
|
|
5522
|
+
setSuggestions([]);
|
|
5523
|
+
setIsOpen(false);
|
|
5524
|
+
const client = clientContext?.client;
|
|
5525
|
+
if (!client) return;
|
|
5526
|
+
const result = await client.places.details(suggestion.place_id, sessionTokenRef.current);
|
|
5527
|
+
sessionTokenRef.current = createSessionToken();
|
|
5528
|
+
if (result.ok) {
|
|
5529
|
+
const d = result.value;
|
|
5530
|
+
onValueChange({
|
|
5531
|
+
latitude: d.latitude,
|
|
5532
|
+
longitude: d.longitude,
|
|
5533
|
+
label: d.formatted_address || label
|
|
5534
|
+
});
|
|
5535
|
+
setInputText(d.formatted_address || label);
|
|
5536
|
+
}
|
|
5537
|
+
}, [clientContext, onValueChange]);
|
|
5538
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("relative", classNames?.locationInput), children: [
|
|
5539
|
+
/* @__PURE__ */ jsx(
|
|
5540
|
+
"input",
|
|
5541
|
+
{
|
|
5542
|
+
type: "text",
|
|
5543
|
+
value: inputText,
|
|
5544
|
+
onChange: (e) => handleInputChange(e.target.value),
|
|
5545
|
+
onFocus: () => {
|
|
5546
|
+
if (suggestions.length > 0) setIsOpen(true);
|
|
5547
|
+
},
|
|
5548
|
+
onBlur: () => {
|
|
5549
|
+
blurTimeoutRef.current = setTimeout(() => setIsOpen(false), 120);
|
|
5550
|
+
},
|
|
5551
|
+
onKeyDown: (e) => {
|
|
5552
|
+
if (e.key === "Escape") {
|
|
5553
|
+
setIsOpen(false);
|
|
5554
|
+
return;
|
|
5555
|
+
}
|
|
5556
|
+
if (!isOpen || suggestions.length === 0) return;
|
|
5557
|
+
if (e.key === "ArrowDown") {
|
|
5558
|
+
e.preventDefault();
|
|
5559
|
+
setHighlightedIndex((i) => i < suggestions.length - 1 ? i + 1 : 0);
|
|
5560
|
+
} else if (e.key === "ArrowUp") {
|
|
5561
|
+
e.preventDefault();
|
|
5562
|
+
setHighlightedIndex((i) => i > 0 ? i - 1 : suggestions.length - 1);
|
|
5563
|
+
} else if (e.key === "Enter" && highlightedIndex >= 0) {
|
|
5564
|
+
e.preventDefault();
|
|
5565
|
+
void selectSuggestion(suggestions[highlightedIndex]);
|
|
5566
|
+
}
|
|
5567
|
+
},
|
|
5568
|
+
placeholder: field.placeholder || "Search for a location...",
|
|
5569
|
+
required: field.is_required,
|
|
5570
|
+
autoComplete: "off",
|
|
5571
|
+
"aria-autocomplete": "list",
|
|
5572
|
+
"aria-expanded": isOpen && suggestions.length > 0,
|
|
5573
|
+
className: inputClass
|
|
5574
|
+
}
|
|
5575
|
+
),
|
|
5576
|
+
isOpen && suggestions.length > 0 && /* @__PURE__ */ jsx("div", { role: "listbox", className: "absolute left-0 right-0 top-full z-20 mt-1 overflow-hidden rounded-md border border-border bg-background shadow-lg", children: suggestions.map((s, i) => /* @__PURE__ */ jsx(
|
|
5577
|
+
"button",
|
|
5578
|
+
{
|
|
5579
|
+
type: "button",
|
|
5580
|
+
role: "option",
|
|
5581
|
+
"aria-selected": i === highlightedIndex,
|
|
5582
|
+
onMouseDown: (e) => {
|
|
5583
|
+
e.preventDefault();
|
|
5584
|
+
void selectSuggestion(s);
|
|
5585
|
+
},
|
|
5586
|
+
className: cn("block w-full px-3 py-2.5 text-left text-sm transition-colors", i === highlightedIndex ? "bg-muted text-foreground" : "text-foreground hover:bg-muted/70"),
|
|
5587
|
+
children: s.description
|
|
5588
|
+
},
|
|
5589
|
+
s.place_id
|
|
5590
|
+
)) }),
|
|
5591
|
+
loc && /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground mt-1", children: [
|
|
5592
|
+
loc.latitude.toFixed(4),
|
|
5593
|
+
", ",
|
|
5594
|
+
loc.longitude.toFixed(4)
|
|
5595
|
+
] })
|
|
5596
|
+
] });
|
|
5597
|
+
}
|
|
5598
|
+
function PhoneInput({
|
|
5599
|
+
field,
|
|
5600
|
+
value,
|
|
5601
|
+
onValueChange,
|
|
5602
|
+
classNames,
|
|
5603
|
+
inputClass
|
|
5604
|
+
}) {
|
|
5605
|
+
const phone = value && typeof value === "object" ? value : null;
|
|
5606
|
+
const [code, setCode] = React10.useState(phone?.country_code ?? "+1");
|
|
5607
|
+
const [number, setNumber] = React10.useState(phone?.number ?? "");
|
|
5608
|
+
const update = (nextCode, nextNumber) => {
|
|
5609
|
+
setCode(nextCode);
|
|
5610
|
+
setNumber(nextNumber);
|
|
5611
|
+
if (nextNumber) {
|
|
5612
|
+
onValueChange({
|
|
5613
|
+
country_code: nextCode,
|
|
5614
|
+
number: nextNumber,
|
|
5615
|
+
formatted: `${nextCode} ${nextNumber}`
|
|
5616
|
+
});
|
|
5617
|
+
} else {
|
|
5618
|
+
onValueChange(void 0);
|
|
5619
|
+
}
|
|
5620
|
+
};
|
|
5621
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("flex gap-2", classNames?.phoneInput), children: [
|
|
5622
|
+
/* @__PURE__ */ jsx(
|
|
5623
|
+
"input",
|
|
5624
|
+
{
|
|
5625
|
+
type: "text",
|
|
5626
|
+
value: code,
|
|
5627
|
+
onChange: (e) => update(e.target.value, number),
|
|
5628
|
+
placeholder: "+1",
|
|
5629
|
+
className: cn(inputClass, "w-20 shrink-0")
|
|
5630
|
+
}
|
|
5631
|
+
),
|
|
5632
|
+
/* @__PURE__ */ jsx(
|
|
5633
|
+
"input",
|
|
5634
|
+
{
|
|
5635
|
+
type: "tel",
|
|
5636
|
+
value: number,
|
|
5637
|
+
onChange: (e) => update(code, e.target.value),
|
|
5638
|
+
placeholder: field.placeholder || "Phone number",
|
|
5639
|
+
required: field.is_required,
|
|
5640
|
+
className: inputClass
|
|
5641
|
+
}
|
|
5642
|
+
)
|
|
5643
|
+
] });
|
|
5644
|
+
}
|
|
5645
|
+
function SignatureInput({
|
|
5646
|
+
field,
|
|
5647
|
+
value,
|
|
5648
|
+
onValueChange,
|
|
5649
|
+
classNames
|
|
5650
|
+
}) {
|
|
5651
|
+
const sig = value && typeof value === "object" ? value : null;
|
|
5652
|
+
const canvasRef = React10.useRef(null);
|
|
5653
|
+
const isDrawing = React10.useRef(false);
|
|
5654
|
+
const getCtx = () => canvasRef.current?.getContext("2d") ?? null;
|
|
5655
|
+
const startDraw = (e) => {
|
|
5656
|
+
const ctx = getCtx();
|
|
5657
|
+
if (!ctx) return;
|
|
5658
|
+
isDrawing.current = true;
|
|
5659
|
+
const rect = canvasRef.current.getBoundingClientRect();
|
|
5660
|
+
ctx.beginPath();
|
|
5661
|
+
ctx.moveTo(e.clientX - rect.left, e.clientY - rect.top);
|
|
5662
|
+
canvasRef.current.setPointerCapture(e.pointerId);
|
|
5663
|
+
};
|
|
5664
|
+
const draw = (e) => {
|
|
5665
|
+
if (!isDrawing.current) return;
|
|
5666
|
+
const ctx = getCtx();
|
|
5667
|
+
if (!ctx) return;
|
|
5668
|
+
const rect = canvasRef.current.getBoundingClientRect();
|
|
5669
|
+
ctx.lineWidth = 2;
|
|
5670
|
+
ctx.lineCap = "round";
|
|
5671
|
+
const style = getComputedStyle(canvasRef.current);
|
|
5672
|
+
ctx.strokeStyle = style.color || "#000";
|
|
5673
|
+
ctx.lineTo(e.clientX - rect.left, e.clientY - rect.top);
|
|
5674
|
+
ctx.stroke();
|
|
5675
|
+
};
|
|
5676
|
+
const endDraw = () => {
|
|
5677
|
+
if (!isDrawing.current) return;
|
|
5678
|
+
isDrawing.current = false;
|
|
5679
|
+
const canvas = canvasRef.current;
|
|
5680
|
+
if (!canvas) return;
|
|
5681
|
+
onValueChange({
|
|
5682
|
+
data_url: canvas.toDataURL("image/png"),
|
|
5683
|
+
signer_name: sig?.signer_name
|
|
5684
|
+
});
|
|
5685
|
+
};
|
|
5686
|
+
const clear = () => {
|
|
5687
|
+
const canvas = canvasRef.current;
|
|
5688
|
+
if (!canvas) return;
|
|
5689
|
+
const ctx = canvas.getContext("2d");
|
|
5690
|
+
if (ctx) ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
5691
|
+
onValueChange(void 0);
|
|
5692
|
+
};
|
|
5693
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("space-y-2", classNames?.signatureCanvas), children: [
|
|
5694
|
+
/* @__PURE__ */ jsxs("div", { className: "relative rounded-md border border-input overflow-hidden", children: [
|
|
5695
|
+
/* @__PURE__ */ jsx(
|
|
5696
|
+
"canvas",
|
|
5697
|
+
{
|
|
5698
|
+
ref: canvasRef,
|
|
5699
|
+
width: 400,
|
|
5700
|
+
height: 150,
|
|
5701
|
+
className: "w-full touch-none cursor-crosshair bg-background text-foreground",
|
|
5702
|
+
onPointerDown: startDraw,
|
|
5703
|
+
onPointerMove: draw,
|
|
5704
|
+
onPointerUp: endDraw,
|
|
5705
|
+
onPointerLeave: endDraw
|
|
5706
|
+
}
|
|
5707
|
+
),
|
|
5708
|
+
sig?.data_url && /* @__PURE__ */ jsx(
|
|
5709
|
+
"button",
|
|
5710
|
+
{
|
|
5711
|
+
type: "button",
|
|
5712
|
+
onClick: clear,
|
|
5713
|
+
className: "absolute top-1.5 right-1.5 text-xs text-muted-foreground hover:text-destructive transition-colors",
|
|
5714
|
+
children: "Clear"
|
|
5715
|
+
}
|
|
5716
|
+
)
|
|
5717
|
+
] }),
|
|
5718
|
+
!sig?.data_url && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: field.placeholder || "Draw your signature above" })
|
|
5719
|
+
] });
|
|
5720
|
+
}
|
|
5721
|
+
function createSessionToken() {
|
|
5722
|
+
if (typeof crypto !== "undefined" && crypto.randomUUID) {
|
|
5723
|
+
return crypto.randomUUID();
|
|
5724
|
+
}
|
|
5725
|
+
return `places_${Date.now()}_${Math.random().toString(16).slice(2)}`;
|
|
5726
|
+
}
|
|
4851
5727
|
function ProductCustomizer({
|
|
4852
5728
|
product,
|
|
4853
5729
|
onAddToCart,
|
|
@@ -4868,6 +5744,7 @@ function ProductCustomizer({
|
|
|
4868
5744
|
const [bundleTotalPrice, setBundleTotalPrice] = useState(null);
|
|
4869
5745
|
const [bundleReady, setBundleReady] = useState(false);
|
|
4870
5746
|
const [selectedBillingPlan, setSelectedBillingPlan] = useState(null);
|
|
5747
|
+
const [customerInputValues, setCustomerInputValues] = useState({});
|
|
4871
5748
|
const [specialInstructions, setSpecialInstructions] = useState("");
|
|
4872
5749
|
const cart = useCart();
|
|
4873
5750
|
const productType = product.type || "product";
|
|
@@ -4892,6 +5769,7 @@ function ProductCustomizer({
|
|
|
4892
5769
|
setBundleTotalPrice(null);
|
|
4893
5770
|
setBundleReady(false);
|
|
4894
5771
|
setSelectedBillingPlan(null);
|
|
5772
|
+
setCustomerInputValues({});
|
|
4895
5773
|
setSpecialInstructions("");
|
|
4896
5774
|
}, [product.id, product.min_order_quantity]);
|
|
4897
5775
|
const selectedAddOnOptions = useMemo(() => {
|
|
@@ -4954,7 +5832,15 @@ function ProductCustomizer({
|
|
|
4954
5832
|
}),
|
|
4955
5833
|
[product.id, quantity, selectedVariantId, normalizedAddOnOptionIds, isBundle, bundleSelections, isComposite, compositeSelections]
|
|
4956
5834
|
);
|
|
4957
|
-
const
|
|
5835
|
+
const requiredInputsSatisfied = useMemo(() => {
|
|
5836
|
+
if (!product.input_fields || product.input_fields.length === 0) return true;
|
|
5837
|
+
return product.input_fields.every((field) => {
|
|
5838
|
+
if (!field.is_required) return true;
|
|
5839
|
+
const val = customerInputValues[field.id];
|
|
5840
|
+
return val !== void 0 && val !== "" && val !== null;
|
|
5841
|
+
});
|
|
5842
|
+
}, [product.input_fields, customerInputValues]);
|
|
5843
|
+
const quoteEnabled = isComposite ? compositeReady && requiredInputsSatisfied : isBundle ? bundleReady && requiredInputsSatisfied : requiredAddOnsSatisfied && requiredInputsSatisfied;
|
|
4958
5844
|
const { quote } = useQuote(quoteInput, {
|
|
4959
5845
|
enabled: quoteEnabled
|
|
4960
5846
|
});
|
|
@@ -4993,6 +5879,7 @@ function ProductCustomizer({
|
|
|
4993
5879
|
compositeSelections: isComposite && compositeSelections.length > 0 ? compositeSelections : void 0,
|
|
4994
5880
|
bundleSelections: isBundle && bundleSelections.length > 0 ? bundleSelections : void 0,
|
|
4995
5881
|
billingPlanId: selectedBillingPlan?.id,
|
|
5882
|
+
customerInputs: Object.keys(customerInputValues).length > 0 ? Object.entries(customerInputValues).filter(([, v]) => v !== void 0 && v !== "").map(([fieldId, value]) => ({ field_id: fieldId, value })) : void 0,
|
|
4996
5883
|
specialInstructions: specialInstructions.trim() || void 0
|
|
4997
5884
|
};
|
|
4998
5885
|
try {
|
|
@@ -5011,7 +5898,7 @@ function ProductCustomizer({
|
|
|
5011
5898
|
} finally {
|
|
5012
5899
|
setIsSubmitting(false);
|
|
5013
5900
|
}
|
|
5014
|
-
}, [product, quantity, selectedVariantId, selectedVariant, quoteId, normalizedAddOnOptionIds, selectedAddOnOptions, isComposite, compositeSelections, isBundle, bundleSelections, selectedBillingPlan, specialInstructions, isSubmitting, onAddToCart, cart]);
|
|
5901
|
+
}, [product, quantity, selectedVariantId, selectedVariant, quoteId, normalizedAddOnOptionIds, selectedAddOnOptions, isComposite, compositeSelections, isBundle, bundleSelections, selectedBillingPlan, customerInputValues, specialInstructions, isSubmitting, onAddToCart, cart]);
|
|
5015
5902
|
return /* @__PURE__ */ jsxs("div", { "data-cimplify-customizer": true, className: cn("space-y-6", className, classNames?.root), children: [
|
|
5016
5903
|
isComposite && product.groups && product.composite_id && /* @__PURE__ */ jsx(
|
|
5017
5904
|
CompositeSelector,
|
|
@@ -5072,6 +5959,14 @@ function ProductCustomizer({
|
|
|
5072
5959
|
currentQuantity: quantity
|
|
5073
5960
|
}
|
|
5074
5961
|
),
|
|
5962
|
+
product.input_fields && product.input_fields.length > 0 && /* @__PURE__ */ jsx(
|
|
5963
|
+
CustomerInputFields,
|
|
5964
|
+
{
|
|
5965
|
+
fields: product.input_fields,
|
|
5966
|
+
values: customerInputValues,
|
|
5967
|
+
onChange: setCustomerInputValues
|
|
5968
|
+
}
|
|
5969
|
+
),
|
|
5075
5970
|
product.deposit_type && product.deposit_type !== "none" && product.deposit_amount && /* @__PURE__ */ jsx("div", { "data-cimplify-customizer-deposit": true, className: cn("text-sm text-muted-foreground", classNames?.depositInfo), children: product.deposit_type === "fixed" ? /* @__PURE__ */ jsxs("span", { children: [
|
|
5076
5971
|
"Deposit required: ",
|
|
5077
5972
|
/* @__PURE__ */ jsx(Price, { amount: product.deposit_amount })
|
|
@@ -5273,6 +6168,10 @@ function CartLineItemRow({
|
|
|
5273
6168
|
] }),
|
|
5274
6169
|
(hasComposite || hasBundle) && /* @__PURE__ */ jsx("span", { "data-cimplify-cart-item-badge": true, children: hasComposite ? "Custom" : "Bundle" }),
|
|
5275
6170
|
item.specialInstructions && /* @__PURE__ */ jsx("span", { "data-cimplify-cart-item-instructions": true, className: "text-xs text-muted-foreground", children: item.specialInstructions }),
|
|
6171
|
+
item.customerInputs && item.customerInputs.length > 0 && /* @__PURE__ */ jsx("div", { "data-cimplify-cart-customer-inputs": true, className: classNames?.customerInputs, children: item.customerInputs.map((input) => /* @__PURE__ */ jsxs("div", { "data-cimplify-cart-input": true, children: [
|
|
6172
|
+
/* @__PURE__ */ jsx("span", { "data-cimplify-cart-input-label": true, children: input.field_name }),
|
|
6173
|
+
/* @__PURE__ */ jsx("span", { "data-cimplify-cart-input-value": true, children: input.field_type === INPUT_FIELD_TYPE.File || input.field_type === INPUT_FIELD_TYPE.Image ? String(input.value).split("/").pop() || "Uploaded file" : String(input.value) })
|
|
6174
|
+
] }, input.field_id)) }),
|
|
5276
6175
|
(item.lineType === "service" || item.product.type === "service") && item.scheduledStart && /* @__PURE__ */ jsxs("div", { "data-cimplify-cart-service-info": true, className: classNames?.serviceInfo, children: [
|
|
5277
6176
|
/* @__PURE__ */ jsxs("span", { children: [
|
|
5278
6177
|
"\u{1F4C5}",
|
|
@@ -6741,13 +7640,13 @@ function ProductGrid({
|
|
|
6741
7640
|
className,
|
|
6742
7641
|
classNames
|
|
6743
7642
|
}) {
|
|
6744
|
-
const rawId =
|
|
7643
|
+
const rawId = React10.useId();
|
|
6745
7644
|
const gridId = `cimplify-grid-${rawId.replace(/:/g, "")}`;
|
|
6746
7645
|
const sm = columns?.sm ?? 1;
|
|
6747
7646
|
const md = columns?.md ?? 2;
|
|
6748
7647
|
const lg = columns?.lg ?? 3;
|
|
6749
7648
|
const xl = columns?.xl ?? 4;
|
|
6750
|
-
const css =
|
|
7649
|
+
const css = React10.useMemo(
|
|
6751
7650
|
() => [
|
|
6752
7651
|
`#${gridId}{display:grid;grid-template-columns:repeat(${sm},1fr);gap:1rem}`,
|
|
6753
7652
|
`@media(min-width:768px){#${gridId}{grid-template-columns:repeat(${md},1fr)}}`,
|
|
@@ -7108,7 +8007,7 @@ function CategoryGrid({
|
|
|
7108
8007
|
enabled: categoriesProp === void 0
|
|
7109
8008
|
});
|
|
7110
8009
|
const categories = categoriesProp ?? fetched;
|
|
7111
|
-
const rawId =
|
|
8010
|
+
const rawId = React10.useId();
|
|
7112
8011
|
const gridId = `cimplify-cat-grid-${rawId.replace(/:/g, "")}`;
|
|
7113
8012
|
const sm = columns?.sm ?? 2;
|
|
7114
8013
|
const md = columns?.md ?? 3;
|
|
@@ -7334,7 +8233,7 @@ function OrderSummary({
|
|
|
7334
8233
|
/* @__PURE__ */ jsx("p", { children: order.delivery_address })
|
|
7335
8234
|
] }),
|
|
7336
8235
|
/* @__PURE__ */ jsx("div", { "data-cimplify-order-items": true, className: classNames?.items, children: order.items.map(
|
|
7337
|
-
(item) => renderLineItem ? /* @__PURE__ */ jsx(
|
|
8236
|
+
(item) => renderLineItem ? /* @__PURE__ */ jsx(React10.Fragment, { children: renderLineItem(item) }, item.id) : /* @__PURE__ */ jsxs("div", { "data-cimplify-order-line-item": true, className: classNames?.lineItem, children: [
|
|
7338
8237
|
/* @__PURE__ */ jsxs("div", { "data-cimplify-order-line-info": true, children: [
|
|
7339
8238
|
/* @__PURE__ */ jsxs("span", { "data-cimplify-order-line-qty": true, children: [
|
|
7340
8239
|
item.quantity,
|
|
@@ -8315,7 +9214,7 @@ function DefaultCatalogueLayout({
|
|
|
8315
9214
|
/* @__PURE__ */ jsx("p", { className: "text-lg font-medium", children: "No products found" }),
|
|
8316
9215
|
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground mt-1", children: "Try adjusting your filters" })
|
|
8317
9216
|
] }) : /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 md:grid-cols-3 gap-4", children: products.map(
|
|
8318
|
-
(product) => renderCard ? /* @__PURE__ */ jsx(
|
|
9217
|
+
(product) => renderCard ? /* @__PURE__ */ jsx(React10.Fragment, { children: renderCard(product) }, product.id) : /* @__PURE__ */ jsx(
|
|
8319
9218
|
ProductCard,
|
|
8320
9219
|
{
|
|
8321
9220
|
product,
|
|
@@ -8422,7 +9321,7 @@ function CompactCatalogueLayout({
|
|
|
8422
9321
|
/* @__PURE__ */ jsx("p", { className: "text-lg font-medium", children: "No items found" }),
|
|
8423
9322
|
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground mt-1", children: "Try a different category or search" })
|
|
8424
9323
|
] }) : /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 lg:grid-cols-3 gap-5", children: products.map(
|
|
8425
|
-
(product) => renderCard ? /* @__PURE__ */ jsx(
|
|
9324
|
+
(product) => renderCard ? /* @__PURE__ */ jsx(React10.Fragment, { children: renderCard(product) }, product.id) : /* @__PURE__ */ jsx(
|
|
8426
9325
|
ProductCard,
|
|
8427
9326
|
{
|
|
8428
9327
|
product,
|
|
@@ -8445,8 +9344,8 @@ var BUILT_IN_LAYOUTS = {
|
|
|
8445
9344
|
["compact" /* Compact */]: CompactCatalogueLayout
|
|
8446
9345
|
};
|
|
8447
9346
|
function useDebounce(value, delay) {
|
|
8448
|
-
const [debounced, setDebounced] =
|
|
8449
|
-
|
|
9347
|
+
const [debounced, setDebounced] = React10.useState(value);
|
|
9348
|
+
React10.useEffect(() => {
|
|
8450
9349
|
const timer = setTimeout(() => setDebounced(value), delay);
|
|
8451
9350
|
return () => clearTimeout(timer);
|
|
8452
9351
|
}, [value, delay]);
|
|
@@ -9716,7 +10615,7 @@ function DefaultCollectionLayout({
|
|
|
9716
10615
|
] })
|
|
9717
10616
|
] }),
|
|
9718
10617
|
filtered.length > 0 ? /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4", children: filtered.map(
|
|
9719
|
-
(product) => renderCard ? /* @__PURE__ */ jsx(
|
|
10618
|
+
(product) => renderCard ? /* @__PURE__ */ jsx(React10.Fragment, { children: renderCard(product) }, product.id) : /* @__PURE__ */ jsx(
|
|
9720
10619
|
ProductCard,
|
|
9721
10620
|
{
|
|
9722
10621
|
product,
|
|
@@ -9769,7 +10668,7 @@ function FeaturedCollectionLayout({
|
|
|
9769
10668
|
] })
|
|
9770
10669
|
] }),
|
|
9771
10670
|
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6", children: products.map(
|
|
9772
|
-
(product) => renderCard ? /* @__PURE__ */ jsx(
|
|
10671
|
+
(product) => renderCard ? /* @__PURE__ */ jsx(React10.Fragment, { children: renderCard(product) }, product.id) : /* @__PURE__ */ jsx(
|
|
9773
10672
|
ProductCard,
|
|
9774
10673
|
{
|
|
9775
10674
|
product,
|
|
@@ -9893,7 +10792,7 @@ function CatalogueCollectionLayout({
|
|
|
9893
10792
|
] })
|
|
9894
10793
|
] }),
|
|
9895
10794
|
filtered.length > 0 ? /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4", children: filtered.map(
|
|
9896
|
-
(product) => renderCard ? /* @__PURE__ */ jsx(
|
|
10795
|
+
(product) => renderCard ? /* @__PURE__ */ jsx(React10.Fragment, { children: renderCard(product) }, product.id) : /* @__PURE__ */ jsx(
|
|
9897
10796
|
ProductCard,
|
|
9898
10797
|
{
|
|
9899
10798
|
product,
|
|
@@ -10273,7 +11172,7 @@ function DefaultSearchLayout({
|
|
|
10273
11172
|
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground mt-1", children: "Try a different search term" }),
|
|
10274
11173
|
/* @__PURE__ */ jsx("button", { onClick: clear, className: "text-sm font-medium text-primary mt-4 hover:underline", children: "Clear search" })
|
|
10275
11174
|
] }) : results.length > 0 ? /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 md:grid-cols-3 gap-4", children: results.map(
|
|
10276
|
-
(product) => renderCard ? /* @__PURE__ */ jsx(
|
|
11175
|
+
(product) => renderCard ? /* @__PURE__ */ jsx(React10.Fragment, { children: renderCard(product) }, product.id) : /* @__PURE__ */ jsx(
|
|
10277
11176
|
ProductCard,
|
|
10278
11177
|
{
|
|
10279
11178
|
product,
|
|
@@ -10375,7 +11274,7 @@ function CompactSearchLayout({
|
|
|
10375
11274
|
/* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground mt-1", children: "Try a different search term" }),
|
|
10376
11275
|
/* @__PURE__ */ jsx("button", { onClick: clear, className: "text-sm font-medium text-primary mt-4 hover:underline", children: "Clear search" })
|
|
10377
11276
|
] }) : results.length > 0 ? /* @__PURE__ */ jsx("div", { className: "grid grid-cols-2 lg:grid-cols-3 gap-5", children: results.map(
|
|
10378
|
-
(product) => renderCard ? /* @__PURE__ */ jsx(
|
|
11277
|
+
(product) => renderCard ? /* @__PURE__ */ jsx(React10.Fragment, { children: renderCard(product) }, product.id) : /* @__PURE__ */ jsx(
|
|
10379
11278
|
ProductCard,
|
|
10380
11279
|
{
|
|
10381
11280
|
product,
|
|
@@ -10940,4 +11839,4 @@ function ResourcePicker({
|
|
|
10940
11839
|
);
|
|
10941
11840
|
}
|
|
10942
11841
|
|
|
10943
|
-
export { AccommodationCard, Ad, AdProvider, AddOnSelector, AddressElement, AuthElement, AvailabilityBadge, BillingPlanSelector, BookingCard, BookingList, BundleProductCard, BundleProductLayout, BundleSelector, CardImage, CardShell, CardVariant, CartPage, CartSummary, CartTemplate, CatalogueCollectionLayout, CataloguePage, CatalogueTemplate, CategoryFilter, CategoryGrid, CheckoutPage, CimplifyAccount, CimplifyCheckout, CimplifyProvider, CollectionPage, CollectionTemplate, CompactCartLayout, CompactCatalogueLayout, CompactSearchLayout, CompactServiceCard, CompositeProductCard, CompositeProductLayout, CompositeSelector, CurrencySelector, CustomAttributesTable, DateSlotPicker, DealBanner, DealsPage, DefaultCartLayout, DefaultCatalogueLayout, DefaultCollectionLayout, DefaultProductLayout, DefaultSearchLayout, DeliveryEstimate, DigitalProductCard, DigitalProductLayout, DiscountInput, ElementsProvider, FeaturedCollectionLayout, FoodProductCard, FoodProductLayout, InventoryBadge, LeaseServiceCard, LocationPicker, MetadataStringList, OrderDetailPage, OrderHistory, OrderHistoryPage, OrderSummary, PaymentElement, Price, PriceRange, ProductCard, ProductCustomizer, ProductGrid, ProductImageGallery, ProductPage, ProductSheet, ProductTemplate, PropertiesTable, QuantitySelector, QuickAddButton, RecentlyViewed, RecommendationCarousel, RelatedProductsSection, RentalServiceCard, ResourcePicker, RetailProductCard, SaleBadge, ScheduleServiceCard, SearchInput, SearchPage, SearchTemplate, ServiceProductLayout, SessionMessageBanner, SlotPicker, SoldOutOverlay, StaffPicker, StandardServiceCard, StoreNav, SubscriptionCard, TagPills, TwoColumnGrid, VariantSelector, VolumePricing, WholesaleProductCard, WholesaleProductLayout, WishlistButton, cn, roomToResource, useActivityState, useAds, useAttributeDefinitions, useAvailableSlots, useBillingPlans, useBookings, useBootstrap, useBundles, useCart, useCategories, useCheckout, useCimplify, useCimplifyClient, useCollection, useCollections, useDeals, useDeliveryFee, useElements, useElementsReady, useFxRate, useLocations, useOptionalCimplify, useOrder, useOrders, useProduct, useProductAvailability, useProductDeals, useProductPrice, useProductSchedules, useProducts, useProductsOnSale, usePropertyFacets, useQuote, useRecommendations, useSearch, useServiceAvailability, useServices, useSubscription, useSubscriptions, useTaxonomies, useTaxonomy, useTaxonomyPath, useValidateDiscount, useVariantSelector };
|
|
11842
|
+
export { AccommodationCard, Ad, AdProvider, AddOnSelector, AddressElement, AuthElement, AvailabilityBadge, BillingPlanSelector, BookingCard, BookingList, BundleProductCard, BundleProductLayout, BundleSelector, CardImage, CardShell, CardVariant, CartPage, CartSummary, CartTemplate, CatalogueCollectionLayout, CataloguePage, CatalogueTemplate, CategoryFilter, CategoryGrid, CheckoutPage, CimplifyAccount, CimplifyCheckout, CimplifyProvider, CollectionPage, CollectionTemplate, CompactCartLayout, CompactCatalogueLayout, CompactSearchLayout, CompactServiceCard, CompositeProductCard, CompositeProductLayout, CompositeSelector, CurrencySelector, CustomAttributesTable, CustomerInputFields, DateSlotPicker, DealBanner, DealsPage, DefaultCartLayout, DefaultCatalogueLayout, DefaultCollectionLayout, DefaultProductLayout, DefaultSearchLayout, DeliveryEstimate, DigitalProductCard, DigitalProductLayout, DiscountInput, ElementsProvider, FeaturedCollectionLayout, FoodProductCard, FoodProductLayout, InventoryBadge, LeaseServiceCard, LocationPicker, MetadataStringList, OrderDetailPage, OrderHistory, OrderHistoryPage, OrderSummary, PaymentElement, Price, PriceRange, ProductCard, ProductCustomizer, ProductGrid, ProductImageGallery, ProductPage, ProductSheet, ProductTemplate, PropertiesTable, QuantitySelector, QuickAddButton, RecentlyViewed, RecommendationCarousel, RelatedProductsSection, RentalServiceCard, ResourcePicker, RetailProductCard, SaleBadge, ScheduleServiceCard, SearchInput, SearchPage, SearchTemplate, ServiceProductLayout, SessionMessageBanner, SlotPicker, SoldOutOverlay, StaffPicker, StandardServiceCard, StoreNav, SubscriptionCard, TagPills, TwoColumnGrid, VariantSelector, VolumePricing, WholesaleProductCard, WholesaleProductLayout, WishlistButton, cn, roomToResource, useActivityState, useAds, useAttributeDefinitions, useAvailableSlots, useBillingPlans, useBookings, useBootstrap, useBundles, useCart, useCategories, useCheckout, useCimplify, useCimplifyClient, useCollection, useCollections, useDeals, useDeliveryFee, useElements, useElementsReady, useFxRate, useLocations, useOptionalCimplify, useOrder, useOrders, useProduct, useProductAvailability, useProductDeals, useProductPrice, useProductSchedules, useProducts, useProductsOnSale, usePropertyFacets, useQuote, useRecommendations, useSearch, useServiceAvailability, useServices, useSubscription, useSubscriptions, useTaxonomies, useTaxonomy, useTaxonomyPath, useValidateDiscount, useVariantSelector };
|