@betterstore/react 0.2.40 → 0.2.42
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/CHANGELOG.md +12 -0
- package/dist/components/checkout-embed/steps/shipping/form.d.ts +4 -1
- package/dist/components/checkout-embed/steps/shipping/shipping-option-wrapper.d.ts +1 -1
- package/dist/components/checkout-embed/steps/summary/index.d.ts +2 -2
- package/dist/components/checkout-embed/useFormStore.d.ts +2 -3
- package/dist/index.cjs.js +145 -87
- package/dist/index.mjs +145 -87
- package/dist/lib/betterstore.d.ts +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ShippingRate } from "@betterstore/sdk";
|
|
2
2
|
import React from "react";
|
|
3
3
|
import { type ShippingMethodFormData } from "../../checkout-schema";
|
|
4
|
+
import { FormStore } from "../../useFormStore";
|
|
4
5
|
interface ShippingMethodFormProps {
|
|
5
6
|
shippingRates: ShippingRate[];
|
|
6
7
|
initialData?: ShippingMethodFormData;
|
|
@@ -12,6 +13,8 @@ interface ShippingMethodFormProps {
|
|
|
12
13
|
exchangeRate: number;
|
|
13
14
|
locale?: string;
|
|
14
15
|
countryCode?: string;
|
|
16
|
+
setFormData: FormStore["setFormData"];
|
|
17
|
+
formData: FormStore["formData"];
|
|
15
18
|
}
|
|
16
|
-
export default function ShippingMethodForm({ shippingRates, initialData, onSubmit, onBack, contactEmail, shippingAddress, currency, exchangeRate, locale, countryCode, }: ShippingMethodFormProps): React.JSX.Element;
|
|
19
|
+
export default function ShippingMethodForm({ shippingRates, initialData, onSubmit, onBack, contactEmail, shippingAddress, currency, exchangeRate, locale, countryCode, setFormData, formData, }: ShippingMethodFormProps): React.JSX.Element;
|
|
17
20
|
export {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { LineItem } from "@betterstore/sdk";
|
|
2
2
|
import React from "react";
|
|
3
3
|
export default function CheckoutSummary({ lineItems, shipping, tax, currency, cancelUrl, exchangeRate, }: {
|
|
4
|
-
lineItems:
|
|
4
|
+
lineItems: LineItem[];
|
|
5
5
|
shipping?: number;
|
|
6
6
|
tax?: number;
|
|
7
7
|
currency: string;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { CheckoutFormData } from "./checkout-schema";
|
|
2
2
|
export type CheckoutStep = "customer" | "shipping" | "payment";
|
|
3
|
-
interface FormStore {
|
|
3
|
+
export interface FormStore {
|
|
4
4
|
formData: Partial<CheckoutFormData>;
|
|
5
5
|
setFormData: (formData: Partial<CheckoutFormData>) => void;
|
|
6
6
|
step: CheckoutStep;
|
|
7
7
|
setStep: (step: CheckoutStep) => void;
|
|
8
8
|
}
|
|
9
|
-
export declare const useFormStore:
|
|
9
|
+
export declare const useFormStore: import("zustand").UseBoundStore<Omit<import("zustand").StoreApi<FormStore>, "persist"> & {
|
|
10
10
|
persist: {
|
|
11
11
|
setOptions: (options: Partial<import("zustand/middleware").PersistOptions<FormStore, FormStore>>) => void;
|
|
12
12
|
clearStorage: () => void;
|
|
@@ -17,4 +17,3 @@ export declare const useFormStore: (checkoutId: string) => import("zustand").Use
|
|
|
17
17
|
getOptions: () => Partial<import("zustand/middleware").PersistOptions<FormStore, FormStore>>;
|
|
18
18
|
};
|
|
19
19
|
}>;
|
|
20
|
-
export {};
|
package/dist/index.cjs.js
CHANGED
|
@@ -3589,7 +3589,7 @@ function useConstant(init) {
|
|
|
3589
3589
|
|
|
3590
3590
|
const isBrowser = typeof window !== "undefined";
|
|
3591
3591
|
|
|
3592
|
-
const useIsomorphicLayoutEffect = isBrowser ? React.useLayoutEffect : React.useEffect;
|
|
3592
|
+
const useIsomorphicLayoutEffect$1 = isBrowser ? React.useLayoutEffect : React.useEffect;
|
|
3593
3593
|
|
|
3594
3594
|
/**
|
|
3595
3595
|
* @public
|
|
@@ -3852,7 +3852,7 @@ const AnimatePresence = ({ children, custom, initial = true, onExitComplete, pre
|
|
|
3852
3852
|
*/
|
|
3853
3853
|
const [diffedChildren, setDiffedChildren] = React.useState(presentChildren);
|
|
3854
3854
|
const [renderedChildren, setRenderedChildren] = React.useState(presentChildren);
|
|
3855
|
-
useIsomorphicLayoutEffect(() => {
|
|
3855
|
+
useIsomorphicLayoutEffect$1(() => {
|
|
3856
3856
|
isInitialRender.current = false;
|
|
3857
3857
|
pendingPresentChildren.current = presentChildren;
|
|
3858
3858
|
/**
|
|
@@ -4472,7 +4472,7 @@ function useVisualElement(Component, visualState, props, createVisualElement, Pr
|
|
|
4472
4472
|
const wantsHandoff = React.useRef(Boolean(optimisedAppearId) &&
|
|
4473
4473
|
!window.MotionHandoffIsComplete?.(optimisedAppearId) &&
|
|
4474
4474
|
window.MotionHasOptimisedAnimation?.(optimisedAppearId));
|
|
4475
|
-
useIsomorphicLayoutEffect(() => {
|
|
4475
|
+
useIsomorphicLayoutEffect$1(() => {
|
|
4476
4476
|
if (!visualElement)
|
|
4477
4477
|
return;
|
|
4478
4478
|
isMounted.current = true;
|
|
@@ -18513,6 +18513,48 @@ var getProxyFormState = (formState, control, localProxyFormState, isRoot = true)
|
|
|
18513
18513
|
return result;
|
|
18514
18514
|
};
|
|
18515
18515
|
|
|
18516
|
+
var isPrimitive = (value) => isNullOrUndefined(value) || !isObjectType(value);
|
|
18517
|
+
|
|
18518
|
+
function deepEqual(object1, object2) {
|
|
18519
|
+
if (isPrimitive(object1) || isPrimitive(object2)) {
|
|
18520
|
+
return object1 === object2;
|
|
18521
|
+
}
|
|
18522
|
+
if (isDateObject(object1) && isDateObject(object2)) {
|
|
18523
|
+
return object1.getTime() === object2.getTime();
|
|
18524
|
+
}
|
|
18525
|
+
const keys1 = Object.keys(object1);
|
|
18526
|
+
const keys2 = Object.keys(object2);
|
|
18527
|
+
if (keys1.length !== keys2.length) {
|
|
18528
|
+
return false;
|
|
18529
|
+
}
|
|
18530
|
+
for (const key of keys1) {
|
|
18531
|
+
const val1 = object1[key];
|
|
18532
|
+
if (!keys2.includes(key)) {
|
|
18533
|
+
return false;
|
|
18534
|
+
}
|
|
18535
|
+
if (key !== 'ref') {
|
|
18536
|
+
const val2 = object2[key];
|
|
18537
|
+
if ((isDateObject(val1) && isDateObject(val2)) ||
|
|
18538
|
+
(isObject(val1) && isObject(val2)) ||
|
|
18539
|
+
(Array.isArray(val1) && Array.isArray(val2))
|
|
18540
|
+
? !deepEqual(val1, val2)
|
|
18541
|
+
: val1 !== val2) {
|
|
18542
|
+
return false;
|
|
18543
|
+
}
|
|
18544
|
+
}
|
|
18545
|
+
}
|
|
18546
|
+
return true;
|
|
18547
|
+
}
|
|
18548
|
+
|
|
18549
|
+
const useDeepEqualEffect = (effect, deps) => {
|
|
18550
|
+
const ref = React.useRef(deps);
|
|
18551
|
+
if (!deepEqual(deps, ref.current)) {
|
|
18552
|
+
ref.current = deps;
|
|
18553
|
+
}
|
|
18554
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
18555
|
+
React.useEffect(effect, ref.current);
|
|
18556
|
+
};
|
|
18557
|
+
|
|
18516
18558
|
/**
|
|
18517
18559
|
* This custom hook allows you to subscribe to each form state, and isolate the re-render at the custom hook level. It has its scope in terms of form state subscription, so it would not affect other useFormState and useForm. Using this hook can reduce the re-render impact on large and complex form application.
|
|
18518
18560
|
*
|
|
@@ -18557,10 +18599,8 @@ function useFormState(props) {
|
|
|
18557
18599
|
isValid: false,
|
|
18558
18600
|
errors: false,
|
|
18559
18601
|
});
|
|
18560
|
-
|
|
18561
|
-
|
|
18562
|
-
React.useEffect(() => control._subscribe({
|
|
18563
|
-
name: _name.current,
|
|
18602
|
+
useDeepEqualEffect(() => control._subscribe({
|
|
18603
|
+
name: name,
|
|
18564
18604
|
formState: _localProxyFormState.current,
|
|
18565
18605
|
exact,
|
|
18566
18606
|
callback: (formState) => {
|
|
@@ -18570,7 +18610,7 @@ function useFormState(props) {
|
|
|
18570
18610
|
...formState,
|
|
18571
18611
|
});
|
|
18572
18612
|
},
|
|
18573
|
-
}), [
|
|
18613
|
+
}), [name, disabled, exact]);
|
|
18574
18614
|
React.useEffect(() => {
|
|
18575
18615
|
_localProxyFormState.current.isValid && control._setValid(true);
|
|
18576
18616
|
}, [control]);
|
|
@@ -18610,19 +18650,16 @@ var generateWatchOutput = (names, _names, formValues, isGlobal, defaultValue) =>
|
|
|
18610
18650
|
function useWatch(props) {
|
|
18611
18651
|
const methods = useFormContext();
|
|
18612
18652
|
const { control = methods.control, name, defaultValue, disabled, exact, } = props || {};
|
|
18613
|
-
const
|
|
18614
|
-
|
|
18615
|
-
|
|
18616
|
-
React.useEffect(() => control._subscribe({
|
|
18617
|
-
name: _name.current,
|
|
18653
|
+
const [value, updateValue] = React.useState(control._getWatch(name, defaultValue));
|
|
18654
|
+
useDeepEqualEffect(() => control._subscribe({
|
|
18655
|
+
name: name,
|
|
18618
18656
|
formState: {
|
|
18619
18657
|
values: true,
|
|
18620
18658
|
},
|
|
18621
18659
|
exact,
|
|
18622
18660
|
callback: (formState) => !disabled &&
|
|
18623
|
-
updateValue(generateWatchOutput(
|
|
18624
|
-
}), [
|
|
18625
|
-
const [value, updateValue] = React.useState(control._getWatch(name, defaultValue));
|
|
18661
|
+
updateValue(generateWatchOutput(name, control._names, formState.values || control._formValues, false, defaultValue)),
|
|
18662
|
+
}), [name, defaultValue, disabled, exact]);
|
|
18626
18663
|
React.useEffect(() => control._removeUnmounted());
|
|
18627
18664
|
return value;
|
|
18628
18665
|
}
|
|
@@ -18857,39 +18894,6 @@ var createSubject = () => {
|
|
|
18857
18894
|
};
|
|
18858
18895
|
};
|
|
18859
18896
|
|
|
18860
|
-
var isPrimitive = (value) => isNullOrUndefined(value) || !isObjectType(value);
|
|
18861
|
-
|
|
18862
|
-
function deepEqual(object1, object2) {
|
|
18863
|
-
if (isPrimitive(object1) || isPrimitive(object2)) {
|
|
18864
|
-
return object1 === object2;
|
|
18865
|
-
}
|
|
18866
|
-
if (isDateObject(object1) && isDateObject(object2)) {
|
|
18867
|
-
return object1.getTime() === object2.getTime();
|
|
18868
|
-
}
|
|
18869
|
-
const keys1 = Object.keys(object1);
|
|
18870
|
-
const keys2 = Object.keys(object2);
|
|
18871
|
-
if (keys1.length !== keys2.length) {
|
|
18872
|
-
return false;
|
|
18873
|
-
}
|
|
18874
|
-
for (const key of keys1) {
|
|
18875
|
-
const val1 = object1[key];
|
|
18876
|
-
if (!keys2.includes(key)) {
|
|
18877
|
-
return false;
|
|
18878
|
-
}
|
|
18879
|
-
if (key !== 'ref') {
|
|
18880
|
-
const val2 = object2[key];
|
|
18881
|
-
if ((isDateObject(val1) && isDateObject(val2)) ||
|
|
18882
|
-
(isObject(val1) && isObject(val2)) ||
|
|
18883
|
-
(Array.isArray(val1) && Array.isArray(val2))
|
|
18884
|
-
? !deepEqual(val1, val2)
|
|
18885
|
-
: val1 !== val2) {
|
|
18886
|
-
return false;
|
|
18887
|
-
}
|
|
18888
|
-
}
|
|
18889
|
-
}
|
|
18890
|
-
return true;
|
|
18891
|
-
}
|
|
18892
|
-
|
|
18893
18897
|
var isEmptyObject = (value) => isObject(value) && !Object.keys(value).length;
|
|
18894
18898
|
|
|
18895
18899
|
var isFileInput = (element) => element.type === 'file';
|
|
@@ -19438,6 +19442,7 @@ function createFormControl(props = {}) {
|
|
|
19438
19442
|
let _formState = {
|
|
19439
19443
|
submitCount: 0,
|
|
19440
19444
|
isDirty: false,
|
|
19445
|
+
isReady: false,
|
|
19441
19446
|
isLoading: isFunction(_options.defaultValues),
|
|
19442
19447
|
isValidating: false,
|
|
19443
19448
|
isSubmitted: false,
|
|
@@ -20457,6 +20462,7 @@ function createFormControl(props = {}) {
|
|
|
20457
20462
|
};
|
|
20458
20463
|
}
|
|
20459
20464
|
|
|
20465
|
+
const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect;
|
|
20460
20466
|
/**
|
|
20461
20467
|
* Custom hook to manage the entire form.
|
|
20462
20468
|
*
|
|
@@ -20503,6 +20509,7 @@ function useForm(props = {}) {
|
|
|
20503
20509
|
validatingFields: {},
|
|
20504
20510
|
errors: props.errors || {},
|
|
20505
20511
|
disabled: props.disabled || false,
|
|
20512
|
+
isReady: false,
|
|
20506
20513
|
defaultValues: isFunction(props.defaultValues)
|
|
20507
20514
|
? undefined
|
|
20508
20515
|
: props.defaultValues,
|
|
@@ -20520,12 +20527,36 @@ function useForm(props = {}) {
|
|
|
20520
20527
|
}
|
|
20521
20528
|
const control = _formControl.current.control;
|
|
20522
20529
|
control._options = props;
|
|
20523
|
-
|
|
20524
|
-
|
|
20525
|
-
|
|
20526
|
-
|
|
20527
|
-
|
|
20530
|
+
useIsomorphicLayoutEffect(() => {
|
|
20531
|
+
const sub = control._subscribe({
|
|
20532
|
+
formState: control._proxyFormState,
|
|
20533
|
+
callback: () => updateFormState({ ...control._formState }),
|
|
20534
|
+
reRenderRoot: true,
|
|
20535
|
+
});
|
|
20536
|
+
updateFormState((data) => ({
|
|
20537
|
+
...data,
|
|
20538
|
+
isReady: true,
|
|
20539
|
+
}));
|
|
20540
|
+
return sub;
|
|
20541
|
+
}, [control]);
|
|
20528
20542
|
React.useEffect(() => control._disableForm(props.disabled), [control, props.disabled]);
|
|
20543
|
+
React.useEffect(() => {
|
|
20544
|
+
if (props.mode) {
|
|
20545
|
+
control._options.mode = props.mode;
|
|
20546
|
+
}
|
|
20547
|
+
if (props.reValidateMode) {
|
|
20548
|
+
control._options.reValidateMode = props.reValidateMode;
|
|
20549
|
+
}
|
|
20550
|
+
if (props.errors && !isEmptyObject(props.errors)) {
|
|
20551
|
+
control._setErrors(props.errors);
|
|
20552
|
+
}
|
|
20553
|
+
}, [control, props.errors, props.mode, props.reValidateMode]);
|
|
20554
|
+
React.useEffect(() => {
|
|
20555
|
+
props.shouldUnregister &&
|
|
20556
|
+
control._subjects.state.next({
|
|
20557
|
+
values: control._getWatch(),
|
|
20558
|
+
});
|
|
20559
|
+
}, [control, props.shouldUnregister]);
|
|
20529
20560
|
React.useEffect(() => {
|
|
20530
20561
|
if (control._proxyFormState.isDirty) {
|
|
20531
20562
|
const isDirty = control._getDirty();
|
|
@@ -20545,12 +20576,7 @@ function useForm(props = {}) {
|
|
|
20545
20576
|
else {
|
|
20546
20577
|
control._resetDefaultValues();
|
|
20547
20578
|
}
|
|
20548
|
-
}, [props.values
|
|
20549
|
-
React.useEffect(() => {
|
|
20550
|
-
if (props.errors && !isEmptyObject(props.errors)) {
|
|
20551
|
-
control._setErrors(props.errors);
|
|
20552
|
-
}
|
|
20553
|
-
}, [props.errors, control]);
|
|
20579
|
+
}, [control, props.values]);
|
|
20554
20580
|
React.useEffect(() => {
|
|
20555
20581
|
if (!control._state.mount) {
|
|
20556
20582
|
control._setValid();
|
|
@@ -20562,12 +20588,6 @@ function useForm(props = {}) {
|
|
|
20562
20588
|
}
|
|
20563
20589
|
control._removeUnmounted();
|
|
20564
20590
|
});
|
|
20565
|
-
React.useEffect(() => {
|
|
20566
|
-
props.shouldUnregister &&
|
|
20567
|
-
control._subjects.state.next({
|
|
20568
|
-
values: control._getWatch(),
|
|
20569
|
-
});
|
|
20570
|
-
}, [props.shouldUnregister, control]);
|
|
20571
20591
|
_formControl.current.formState = getProxyFormState(formState, control);
|
|
20572
20592
|
return _formControl.current;
|
|
20573
20593
|
}
|
|
@@ -34207,7 +34227,7 @@ const CheckoutForm$1 = ({ onSuccess, onError, children, setSubmitting, }) => {
|
|
|
34207
34227
|
};
|
|
34208
34228
|
var CheckoutForm$2 = React.memo(CheckoutForm$1);
|
|
34209
34229
|
|
|
34210
|
-
const publicStripeKey = "
|
|
34230
|
+
const publicStripeKey = "pk_live_51QvliXK5wvEuxX36GWLFgMtUrG2cGIjpW0eXoqVzjEr8S0PdGzAp4ydQa6ssxVW9u0zaLajod93YZnQIU5C8cgqp00Bb64X60b";
|
|
34211
34231
|
const stripePromise = loadStripe(publicStripeKey);
|
|
34212
34232
|
function PaymentElement({ paymentSecret, checkoutAppearance, locale, fonts, onSuccess, onError, children, setSubmitting, }) {
|
|
34213
34233
|
const options = {
|
|
@@ -34307,10 +34327,10 @@ function ShippingOptionWrapper({ rate, children, onPickupPointSelected, locale,
|
|
|
34307
34327
|
if (rate.provider === "zasilkovna") {
|
|
34308
34328
|
return (React.createElement(ZasilkovnaShippingOption, { onPickupPointSelected: onPickupPointSelected, locale: locale, countryCode: countryCode, apiKey: rate.clientSecret }, children));
|
|
34309
34329
|
}
|
|
34310
|
-
return;
|
|
34330
|
+
return React.createElement(React.Fragment, null, children);
|
|
34311
34331
|
}
|
|
34312
34332
|
|
|
34313
|
-
function ShippingMethodForm({ shippingRates, initialData, onSubmit, onBack, contactEmail, shippingAddress, currency, exchangeRate, locale, countryCode, }) {
|
|
34333
|
+
function ShippingMethodForm({ shippingRates, initialData, onSubmit, onBack, contactEmail, shippingAddress, currency, exchangeRate, locale, countryCode, setFormData, formData, }) {
|
|
34314
34334
|
var _a;
|
|
34315
34335
|
const { t } = useTranslation();
|
|
34316
34336
|
const form = useForm({
|
|
@@ -34353,17 +34373,39 @@ function ShippingMethodForm({ shippingRates, initialData, onSubmit, onBack, cont
|
|
|
34353
34373
|
return (React.createElement(ShippingOptionWrapper, { rate: rate, key: rateId, onPickupPointSelected: (pickupPointId, pickupPointName) => {
|
|
34354
34374
|
form.setValue("pickupPointId", pickupPointId);
|
|
34355
34375
|
form.setValue("pickupPointDisplayName", pickupPointName);
|
|
34376
|
+
setFormData(Object.assign(Object.assign({}, formData), { shipping: {
|
|
34377
|
+
rateId,
|
|
34378
|
+
provider: rate.provider,
|
|
34379
|
+
price: intPrice,
|
|
34380
|
+
name: rate.name,
|
|
34381
|
+
pickupPointId,
|
|
34382
|
+
pickupPointDisplayName,
|
|
34383
|
+
} }));
|
|
34356
34384
|
}, locale: locale, countryCode: countryCode },
|
|
34357
34385
|
React.createElement("div", { className: clsx("p-4 cursor-pointer rounded-md border bg-background", {
|
|
34358
34386
|
"bg-muted border-primary": currentRateId === rateId,
|
|
34359
34387
|
}), onClick: () => {
|
|
34388
|
+
const newFormData = {
|
|
34389
|
+
rateId,
|
|
34390
|
+
provider: rate.provider,
|
|
34391
|
+
price: intPrice,
|
|
34392
|
+
name: rate.name,
|
|
34393
|
+
pickupPointId: rate.provider === "zasilkovna"
|
|
34394
|
+
? form.watch("pickupPointId")
|
|
34395
|
+
: "",
|
|
34396
|
+
pickupPointDisplayName: rate.provider === "zasilkovna"
|
|
34397
|
+
? form.watch("pickupPointDisplayName")
|
|
34398
|
+
: "",
|
|
34399
|
+
};
|
|
34360
34400
|
form.setValue("rateId", rateId);
|
|
34361
34401
|
form.setValue("provider", rate.provider);
|
|
34362
34402
|
form.setValue("name", rate.name);
|
|
34363
34403
|
form.setValue("price", intPrice);
|
|
34364
34404
|
if (rate.provider !== "zasilkovna") {
|
|
34365
34405
|
form.setValue("pickupPointDisplayName", "");
|
|
34406
|
+
form.setValue("pickupPointId", "");
|
|
34366
34407
|
}
|
|
34408
|
+
setFormData(Object.assign(Object.assign({}, formData), { shipping: newFormData }));
|
|
34367
34409
|
} },
|
|
34368
34410
|
React.createElement("div", { className: "flex items-center justify-between w-full" },
|
|
34369
34411
|
React.createElement("p", null, rate.name),
|
|
@@ -34391,12 +34433,12 @@ function ShippingRateLoading() {
|
|
|
34391
34433
|
React.createElement(Skeleton, { className: "w-40 h-3.5" })));
|
|
34392
34434
|
}
|
|
34393
34435
|
|
|
34394
|
-
const useFormStore =
|
|
34436
|
+
const useFormStore = create()(persist((set) => ({
|
|
34395
34437
|
formData: {},
|
|
34396
34438
|
setFormData: (formData) => set({ formData }),
|
|
34397
34439
|
step: "customer",
|
|
34398
34440
|
setStep: (step) => set({ step }),
|
|
34399
|
-
}), { name: `checkout
|
|
34441
|
+
}), { name: `checkout` }));
|
|
34400
34442
|
|
|
34401
34443
|
const motionSettings = {
|
|
34402
34444
|
initial: { opacity: 0 },
|
|
@@ -34405,7 +34447,7 @@ const motionSettings = {
|
|
|
34405
34447
|
transition: { duration: 0.2 },
|
|
34406
34448
|
};
|
|
34407
34449
|
function CheckoutForm({ storeClient, checkoutId, onSuccess, onError, cancelUrl, clientSecret, customer, currency, checkoutAppearance, fonts, locale, setShippingCost, exchangeRate, }) {
|
|
34408
|
-
const { formData, setFormData, step, setStep } = useFormStore(
|
|
34450
|
+
const { formData, setFormData, step, setStep } = useFormStore();
|
|
34409
34451
|
const [paymentSecret, setPaymentSecret] = React.useState(null);
|
|
34410
34452
|
const [shippingRates, setShippingRates] = React.useState([]);
|
|
34411
34453
|
const validateStep = React.useCallback(() => {
|
|
@@ -34452,12 +34494,17 @@ function CheckoutForm({ storeClient, checkoutId, onSuccess, onError, cancelUrl,
|
|
|
34452
34494
|
if (shippingRates.length > 0)
|
|
34453
34495
|
return;
|
|
34454
34496
|
const getShippingRates = () => __awaiter(this, void 0, void 0, function* () {
|
|
34455
|
-
|
|
34456
|
-
|
|
34457
|
-
|
|
34497
|
+
try {
|
|
34498
|
+
const shippingRates = yield storeClient.getCheckoutShippingRates(clientSecret, checkoutId);
|
|
34499
|
+
setShippingRates(shippingRates);
|
|
34500
|
+
}
|
|
34501
|
+
catch (error) {
|
|
34502
|
+
console.error("Failed to load shipping rates:", error);
|
|
34503
|
+
setShippingRates([]);
|
|
34504
|
+
}
|
|
34458
34505
|
});
|
|
34459
34506
|
getShippingRates();
|
|
34460
|
-
}, [step,
|
|
34507
|
+
}, [step, clientSecret, checkoutId]);
|
|
34461
34508
|
// Handle address form submission
|
|
34462
34509
|
const handleCustomerSubmit = (data) => __awaiter(this, void 0, void 0, function* () {
|
|
34463
34510
|
setFormData(Object.assign(Object.assign({}, formData), { customer: data }));
|
|
@@ -34494,8 +34541,7 @@ function CheckoutForm({ storeClient, checkoutId, onSuccess, onError, cancelUrl,
|
|
|
34494
34541
|
const newFormData = Object.assign(Object.assign({}, formData), { shipping: data });
|
|
34495
34542
|
setFormData(newFormData);
|
|
34496
34543
|
yield storeClient.updateCheckout(clientSecret, checkoutId, {
|
|
34497
|
-
|
|
34498
|
-
shipmentInfo: {
|
|
34544
|
+
shipmentData: {
|
|
34499
34545
|
provider: data.provider,
|
|
34500
34546
|
pickupPointId: data.pickupPointId,
|
|
34501
34547
|
},
|
|
@@ -34532,7 +34578,7 @@ function CheckoutForm({ storeClient, checkoutId, onSuccess, onError, cancelUrl,
|
|
|
34532
34578
|
step === "customer" && (React.createElement(motion.div, Object.assign({ key: "customer" }, motionSettings, { className: "absolute w-full" }),
|
|
34533
34579
|
React.createElement(CustomerForm, { initialData: formData.customer, onSubmit: handleCustomerSubmit }))),
|
|
34534
34580
|
step === "shipping" && formData.customer && (React.createElement(motion.div, Object.assign({ key: "shipping" }, motionSettings, { className: "absolute w-full" }),
|
|
34535
|
-
React.createElement(ShippingMethodForm, { shippingRates: shippingRates, initialData: formData.shipping, onSubmit: handleShippingSubmit, onBack: handleBack, contactEmail: formData.customer.email, shippingAddress: formatAddress(formData.customer.address), currency: currency, exchangeRate: exchangeRate, locale: locale, countryCode: formData.customer.address.countryCode }))),
|
|
34581
|
+
React.createElement(ShippingMethodForm, { setFormData: setFormData, formData: formData, shippingRates: shippingRates, initialData: formData.shipping, onSubmit: handleShippingSubmit, onBack: handleBack, contactEmail: formData.customer.email, shippingAddress: formatAddress(formData.customer.address), currency: currency, exchangeRate: exchangeRate, locale: locale, countryCode: formData.customer.address.countryCode }))),
|
|
34536
34582
|
step === "payment" && formData.customer && formData.shipping && (React.createElement(motion.div, Object.assign({ key: "payment" }, motionSettings, { className: "absolute w-full" }),
|
|
34537
34583
|
React.createElement(PaymentForm, { locale: locale, fonts: fonts, checkoutAppearance: checkoutAppearance, paymentSecret: paymentSecret, onSuccess: onSuccess, onError: onError, onBack: handleBack, onDoubleBack: handleDoubleBack, contactEmail: formData.customer.email, shippingAddress: formatAddress(formData.customer.address), shippingProvider: formData.shipping.provider, shippingPrice: storeHelpers.formatPrice(formData.shipping.price, currency, exchangeRate) }))))));
|
|
34538
34584
|
}
|
|
@@ -34557,13 +34603,18 @@ function InputGroupLoading({ className }) {
|
|
|
34557
34603
|
}
|
|
34558
34604
|
|
|
34559
34605
|
function CheckoutSummary({ lineItems, shipping, tax, currency, cancelUrl, exchangeRate, }) {
|
|
34606
|
+
var _a;
|
|
34607
|
+
const { formData } = useFormStore();
|
|
34560
34608
|
const [isOpen, setIsOpen] = React.useState(false);
|
|
34561
34609
|
const { t } = useTranslation();
|
|
34562
34610
|
const subtotal = lineItems.reduce((acc, item) => {
|
|
34563
34611
|
var _a, _b;
|
|
34564
|
-
|
|
34612
|
+
const variant = (_a = item.product) === null || _a === void 0 ? void 0 : _a.productVariants.find((variant) => variant.variantOptions === item.variantOptions);
|
|
34613
|
+
const productItem = variant || item.product;
|
|
34614
|
+
return acc + ((_b = productItem === null || productItem === void 0 ? void 0 : productItem.priceInCents) !== null && _b !== void 0 ? _b : 0) * item.quantity;
|
|
34565
34615
|
}, 0);
|
|
34566
|
-
const
|
|
34616
|
+
const shippingPrice = shipping !== null && shipping !== void 0 ? shipping : (_a = formData.shipping) === null || _a === void 0 ? void 0 : _a.price;
|
|
34617
|
+
const total = subtotal + (tax !== null && tax !== void 0 ? tax : 0) + (shippingPrice !== null && shippingPrice !== void 0 ? shippingPrice : 0);
|
|
34567
34618
|
return (React.createElement("div", { className: "grid gap-5" },
|
|
34568
34619
|
React.createElement("div", { className: "flex justify-between items-center" },
|
|
34569
34620
|
React.createElement("div", { onClick: () => setIsOpen(!isOpen), className: "flex items-center gap-2 cursor-pointer" },
|
|
@@ -34584,8 +34635,8 @@ function CheckoutSummary({ lineItems, shipping, tax, currency, cancelUrl, exchan
|
|
|
34584
34635
|
React.createElement("p", null, storeHelpers.formatPrice(subtotal, currency, exchangeRate))),
|
|
34585
34636
|
React.createElement("div", { className: "flex justify-between" },
|
|
34586
34637
|
React.createElement("p", null, t("CheckoutEmbed.Summary.shipping")),
|
|
34587
|
-
React.createElement("p", null, !!
|
|
34588
|
-
? storeHelpers.formatPrice(
|
|
34638
|
+
React.createElement("p", null, !!shippingPrice
|
|
34639
|
+
? storeHelpers.formatPrice(shippingPrice, currency, exchangeRate)
|
|
34589
34640
|
: t("CheckoutEmbed.Summary.calculatedAtNextStep"))),
|
|
34590
34641
|
!!tax && (React.createElement("div", { className: "flex justify-between" },
|
|
34591
34642
|
React.createElement("p", null, t("CheckoutEmbed.Summary.tax")),
|
|
@@ -34602,15 +34653,22 @@ function CheckoutSummary({ lineItems, shipping, tax, currency, cancelUrl, exchan
|
|
|
34602
34653
|
grid: isOpen,
|
|
34603
34654
|
}) }, lineItems.map((item, index) => {
|
|
34604
34655
|
var _a, _b, _c, _d, _e;
|
|
34656
|
+
const variant = (_a = item.product) === null || _a === void 0 ? void 0 : _a.productVariants.find((variant) => variant.variantOptions === item.variantOptions);
|
|
34657
|
+
const productItem = variant || item.product;
|
|
34605
34658
|
return (React.createElement("div", { key: index, className: "flex items-center" },
|
|
34606
34659
|
React.createElement("div", { className: "relative" },
|
|
34607
|
-
React.createElement("div", { className: "w-16 h-16 bg-secondary rounded-lg overflow-hidden relative" }, (
|
|
34660
|
+
React.createElement("div", { className: "w-16 h-16 bg-secondary rounded-lg overflow-hidden relative" }, (productItem === null || productItem === void 0 ? void 0 : productItem.images[0]) && (React.createElement("img", { src: productItem.images[0] ||
|
|
34661
|
+
((_b = item === null || item === void 0 ? void 0 : item.product) === null || _b === void 0 ? void 0 : _b.images[0]) ||
|
|
34662
|
+
"/placeholder.svg", alt: ((_c = item.product) === null || _c === void 0 ? void 0 : _c.title) || "", className: "object-cover w-full h-full", sizes: "64px" }))),
|
|
34608
34663
|
React.createElement("div", { className: "absolute -top-2 -right-2 w-6 h-6 bg-primary rounded-full flex items-center text-background justify-center text-sm" }, item.quantity)),
|
|
34609
34664
|
React.createElement("div", { className: "ml-4 flex-1" },
|
|
34610
|
-
React.createElement("h3", { className: "text-lg font-medium" }, (
|
|
34611
|
-
React.createElement("p", { className: "text-muted-foreground text-sm" }, item.variantOptions.map((option) =>
|
|
34665
|
+
React.createElement("h3", { className: "text-lg font-medium" }, (_d = item.product) === null || _d === void 0 ? void 0 : _d.title),
|
|
34666
|
+
React.createElement("p", { className: "text-muted-foreground text-sm" }, item.variantOptions.map((option) => (React.createElement("span", { key: option.name },
|
|
34667
|
+
option.name,
|
|
34668
|
+
": ",
|
|
34669
|
+
option.value))))),
|
|
34612
34670
|
React.createElement("div", { className: "text-right" },
|
|
34613
|
-
React.createElement("p", { className: "text-lg font-medium" }, storeHelpers.formatPrice((_e =
|
|
34671
|
+
React.createElement("p", { className: "text-lg font-medium" }, storeHelpers.formatPrice((_e = productItem === null || productItem === void 0 ? void 0 : productItem.priceInCents) !== null && _e !== void 0 ? _e : 0, currency, exchangeRate)))));
|
|
34614
34672
|
}))));
|
|
34615
34673
|
}
|
|
34616
34674
|
|
package/dist/index.mjs
CHANGED
|
@@ -3566,7 +3566,7 @@ function useConstant(init) {
|
|
|
3566
3566
|
|
|
3567
3567
|
const isBrowser = typeof window !== "undefined";
|
|
3568
3568
|
|
|
3569
|
-
const useIsomorphicLayoutEffect = isBrowser ? useLayoutEffect : useEffect;
|
|
3569
|
+
const useIsomorphicLayoutEffect$1 = isBrowser ? useLayoutEffect : useEffect;
|
|
3570
3570
|
|
|
3571
3571
|
/**
|
|
3572
3572
|
* @public
|
|
@@ -3829,7 +3829,7 @@ const AnimatePresence = ({ children, custom, initial = true, onExitComplete, pre
|
|
|
3829
3829
|
*/
|
|
3830
3830
|
const [diffedChildren, setDiffedChildren] = useState(presentChildren);
|
|
3831
3831
|
const [renderedChildren, setRenderedChildren] = useState(presentChildren);
|
|
3832
|
-
useIsomorphicLayoutEffect(() => {
|
|
3832
|
+
useIsomorphicLayoutEffect$1(() => {
|
|
3833
3833
|
isInitialRender.current = false;
|
|
3834
3834
|
pendingPresentChildren.current = presentChildren;
|
|
3835
3835
|
/**
|
|
@@ -4449,7 +4449,7 @@ function useVisualElement(Component, visualState, props, createVisualElement, Pr
|
|
|
4449
4449
|
const wantsHandoff = useRef(Boolean(optimisedAppearId) &&
|
|
4450
4450
|
!window.MotionHandoffIsComplete?.(optimisedAppearId) &&
|
|
4451
4451
|
window.MotionHasOptimisedAnimation?.(optimisedAppearId));
|
|
4452
|
-
useIsomorphicLayoutEffect(() => {
|
|
4452
|
+
useIsomorphicLayoutEffect$1(() => {
|
|
4453
4453
|
if (!visualElement)
|
|
4454
4454
|
return;
|
|
4455
4455
|
isMounted.current = true;
|
|
@@ -18490,6 +18490,48 @@ var getProxyFormState = (formState, control, localProxyFormState, isRoot = true)
|
|
|
18490
18490
|
return result;
|
|
18491
18491
|
};
|
|
18492
18492
|
|
|
18493
|
+
var isPrimitive = (value) => isNullOrUndefined(value) || !isObjectType(value);
|
|
18494
|
+
|
|
18495
|
+
function deepEqual(object1, object2) {
|
|
18496
|
+
if (isPrimitive(object1) || isPrimitive(object2)) {
|
|
18497
|
+
return object1 === object2;
|
|
18498
|
+
}
|
|
18499
|
+
if (isDateObject(object1) && isDateObject(object2)) {
|
|
18500
|
+
return object1.getTime() === object2.getTime();
|
|
18501
|
+
}
|
|
18502
|
+
const keys1 = Object.keys(object1);
|
|
18503
|
+
const keys2 = Object.keys(object2);
|
|
18504
|
+
if (keys1.length !== keys2.length) {
|
|
18505
|
+
return false;
|
|
18506
|
+
}
|
|
18507
|
+
for (const key of keys1) {
|
|
18508
|
+
const val1 = object1[key];
|
|
18509
|
+
if (!keys2.includes(key)) {
|
|
18510
|
+
return false;
|
|
18511
|
+
}
|
|
18512
|
+
if (key !== 'ref') {
|
|
18513
|
+
const val2 = object2[key];
|
|
18514
|
+
if ((isDateObject(val1) && isDateObject(val2)) ||
|
|
18515
|
+
(isObject(val1) && isObject(val2)) ||
|
|
18516
|
+
(Array.isArray(val1) && Array.isArray(val2))
|
|
18517
|
+
? !deepEqual(val1, val2)
|
|
18518
|
+
: val1 !== val2) {
|
|
18519
|
+
return false;
|
|
18520
|
+
}
|
|
18521
|
+
}
|
|
18522
|
+
}
|
|
18523
|
+
return true;
|
|
18524
|
+
}
|
|
18525
|
+
|
|
18526
|
+
const useDeepEqualEffect = (effect, deps) => {
|
|
18527
|
+
const ref = useRef(deps);
|
|
18528
|
+
if (!deepEqual(deps, ref.current)) {
|
|
18529
|
+
ref.current = deps;
|
|
18530
|
+
}
|
|
18531
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
18532
|
+
useEffect(effect, ref.current);
|
|
18533
|
+
};
|
|
18534
|
+
|
|
18493
18535
|
/**
|
|
18494
18536
|
* This custom hook allows you to subscribe to each form state, and isolate the re-render at the custom hook level. It has its scope in terms of form state subscription, so it would not affect other useFormState and useForm. Using this hook can reduce the re-render impact on large and complex form application.
|
|
18495
18537
|
*
|
|
@@ -18534,10 +18576,8 @@ function useFormState(props) {
|
|
|
18534
18576
|
isValid: false,
|
|
18535
18577
|
errors: false,
|
|
18536
18578
|
});
|
|
18537
|
-
|
|
18538
|
-
|
|
18539
|
-
React__default.useEffect(() => control._subscribe({
|
|
18540
|
-
name: _name.current,
|
|
18579
|
+
useDeepEqualEffect(() => control._subscribe({
|
|
18580
|
+
name: name,
|
|
18541
18581
|
formState: _localProxyFormState.current,
|
|
18542
18582
|
exact,
|
|
18543
18583
|
callback: (formState) => {
|
|
@@ -18547,7 +18587,7 @@ function useFormState(props) {
|
|
|
18547
18587
|
...formState,
|
|
18548
18588
|
});
|
|
18549
18589
|
},
|
|
18550
|
-
}), [
|
|
18590
|
+
}), [name, disabled, exact]);
|
|
18551
18591
|
React__default.useEffect(() => {
|
|
18552
18592
|
_localProxyFormState.current.isValid && control._setValid(true);
|
|
18553
18593
|
}, [control]);
|
|
@@ -18587,19 +18627,16 @@ var generateWatchOutput = (names, _names, formValues, isGlobal, defaultValue) =>
|
|
|
18587
18627
|
function useWatch(props) {
|
|
18588
18628
|
const methods = useFormContext();
|
|
18589
18629
|
const { control = methods.control, name, defaultValue, disabled, exact, } = props || {};
|
|
18590
|
-
const
|
|
18591
|
-
|
|
18592
|
-
|
|
18593
|
-
React__default.useEffect(() => control._subscribe({
|
|
18594
|
-
name: _name.current,
|
|
18630
|
+
const [value, updateValue] = React__default.useState(control._getWatch(name, defaultValue));
|
|
18631
|
+
useDeepEqualEffect(() => control._subscribe({
|
|
18632
|
+
name: name,
|
|
18595
18633
|
formState: {
|
|
18596
18634
|
values: true,
|
|
18597
18635
|
},
|
|
18598
18636
|
exact,
|
|
18599
18637
|
callback: (formState) => !disabled &&
|
|
18600
|
-
updateValue(generateWatchOutput(
|
|
18601
|
-
}), [
|
|
18602
|
-
const [value, updateValue] = React__default.useState(control._getWatch(name, defaultValue));
|
|
18638
|
+
updateValue(generateWatchOutput(name, control._names, formState.values || control._formValues, false, defaultValue)),
|
|
18639
|
+
}), [name, defaultValue, disabled, exact]);
|
|
18603
18640
|
React__default.useEffect(() => control._removeUnmounted());
|
|
18604
18641
|
return value;
|
|
18605
18642
|
}
|
|
@@ -18834,39 +18871,6 @@ var createSubject = () => {
|
|
|
18834
18871
|
};
|
|
18835
18872
|
};
|
|
18836
18873
|
|
|
18837
|
-
var isPrimitive = (value) => isNullOrUndefined(value) || !isObjectType(value);
|
|
18838
|
-
|
|
18839
|
-
function deepEqual(object1, object2) {
|
|
18840
|
-
if (isPrimitive(object1) || isPrimitive(object2)) {
|
|
18841
|
-
return object1 === object2;
|
|
18842
|
-
}
|
|
18843
|
-
if (isDateObject(object1) && isDateObject(object2)) {
|
|
18844
|
-
return object1.getTime() === object2.getTime();
|
|
18845
|
-
}
|
|
18846
|
-
const keys1 = Object.keys(object1);
|
|
18847
|
-
const keys2 = Object.keys(object2);
|
|
18848
|
-
if (keys1.length !== keys2.length) {
|
|
18849
|
-
return false;
|
|
18850
|
-
}
|
|
18851
|
-
for (const key of keys1) {
|
|
18852
|
-
const val1 = object1[key];
|
|
18853
|
-
if (!keys2.includes(key)) {
|
|
18854
|
-
return false;
|
|
18855
|
-
}
|
|
18856
|
-
if (key !== 'ref') {
|
|
18857
|
-
const val2 = object2[key];
|
|
18858
|
-
if ((isDateObject(val1) && isDateObject(val2)) ||
|
|
18859
|
-
(isObject(val1) && isObject(val2)) ||
|
|
18860
|
-
(Array.isArray(val1) && Array.isArray(val2))
|
|
18861
|
-
? !deepEqual(val1, val2)
|
|
18862
|
-
: val1 !== val2) {
|
|
18863
|
-
return false;
|
|
18864
|
-
}
|
|
18865
|
-
}
|
|
18866
|
-
}
|
|
18867
|
-
return true;
|
|
18868
|
-
}
|
|
18869
|
-
|
|
18870
18874
|
var isEmptyObject = (value) => isObject(value) && !Object.keys(value).length;
|
|
18871
18875
|
|
|
18872
18876
|
var isFileInput = (element) => element.type === 'file';
|
|
@@ -19415,6 +19419,7 @@ function createFormControl(props = {}) {
|
|
|
19415
19419
|
let _formState = {
|
|
19416
19420
|
submitCount: 0,
|
|
19417
19421
|
isDirty: false,
|
|
19422
|
+
isReady: false,
|
|
19418
19423
|
isLoading: isFunction(_options.defaultValues),
|
|
19419
19424
|
isValidating: false,
|
|
19420
19425
|
isSubmitted: false,
|
|
@@ -20434,6 +20439,7 @@ function createFormControl(props = {}) {
|
|
|
20434
20439
|
};
|
|
20435
20440
|
}
|
|
20436
20441
|
|
|
20442
|
+
const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? React__default.useLayoutEffect : React__default.useEffect;
|
|
20437
20443
|
/**
|
|
20438
20444
|
* Custom hook to manage the entire form.
|
|
20439
20445
|
*
|
|
@@ -20480,6 +20486,7 @@ function useForm(props = {}) {
|
|
|
20480
20486
|
validatingFields: {},
|
|
20481
20487
|
errors: props.errors || {},
|
|
20482
20488
|
disabled: props.disabled || false,
|
|
20489
|
+
isReady: false,
|
|
20483
20490
|
defaultValues: isFunction(props.defaultValues)
|
|
20484
20491
|
? undefined
|
|
20485
20492
|
: props.defaultValues,
|
|
@@ -20497,12 +20504,36 @@ function useForm(props = {}) {
|
|
|
20497
20504
|
}
|
|
20498
20505
|
const control = _formControl.current.control;
|
|
20499
20506
|
control._options = props;
|
|
20500
|
-
|
|
20501
|
-
|
|
20502
|
-
|
|
20503
|
-
|
|
20504
|
-
|
|
20507
|
+
useIsomorphicLayoutEffect(() => {
|
|
20508
|
+
const sub = control._subscribe({
|
|
20509
|
+
formState: control._proxyFormState,
|
|
20510
|
+
callback: () => updateFormState({ ...control._formState }),
|
|
20511
|
+
reRenderRoot: true,
|
|
20512
|
+
});
|
|
20513
|
+
updateFormState((data) => ({
|
|
20514
|
+
...data,
|
|
20515
|
+
isReady: true,
|
|
20516
|
+
}));
|
|
20517
|
+
return sub;
|
|
20518
|
+
}, [control]);
|
|
20505
20519
|
React__default.useEffect(() => control._disableForm(props.disabled), [control, props.disabled]);
|
|
20520
|
+
React__default.useEffect(() => {
|
|
20521
|
+
if (props.mode) {
|
|
20522
|
+
control._options.mode = props.mode;
|
|
20523
|
+
}
|
|
20524
|
+
if (props.reValidateMode) {
|
|
20525
|
+
control._options.reValidateMode = props.reValidateMode;
|
|
20526
|
+
}
|
|
20527
|
+
if (props.errors && !isEmptyObject(props.errors)) {
|
|
20528
|
+
control._setErrors(props.errors);
|
|
20529
|
+
}
|
|
20530
|
+
}, [control, props.errors, props.mode, props.reValidateMode]);
|
|
20531
|
+
React__default.useEffect(() => {
|
|
20532
|
+
props.shouldUnregister &&
|
|
20533
|
+
control._subjects.state.next({
|
|
20534
|
+
values: control._getWatch(),
|
|
20535
|
+
});
|
|
20536
|
+
}, [control, props.shouldUnregister]);
|
|
20506
20537
|
React__default.useEffect(() => {
|
|
20507
20538
|
if (control._proxyFormState.isDirty) {
|
|
20508
20539
|
const isDirty = control._getDirty();
|
|
@@ -20522,12 +20553,7 @@ function useForm(props = {}) {
|
|
|
20522
20553
|
else {
|
|
20523
20554
|
control._resetDefaultValues();
|
|
20524
20555
|
}
|
|
20525
|
-
}, [props.values
|
|
20526
|
-
React__default.useEffect(() => {
|
|
20527
|
-
if (props.errors && !isEmptyObject(props.errors)) {
|
|
20528
|
-
control._setErrors(props.errors);
|
|
20529
|
-
}
|
|
20530
|
-
}, [props.errors, control]);
|
|
20556
|
+
}, [control, props.values]);
|
|
20531
20557
|
React__default.useEffect(() => {
|
|
20532
20558
|
if (!control._state.mount) {
|
|
20533
20559
|
control._setValid();
|
|
@@ -20539,12 +20565,6 @@ function useForm(props = {}) {
|
|
|
20539
20565
|
}
|
|
20540
20566
|
control._removeUnmounted();
|
|
20541
20567
|
});
|
|
20542
|
-
React__default.useEffect(() => {
|
|
20543
|
-
props.shouldUnregister &&
|
|
20544
|
-
control._subjects.state.next({
|
|
20545
|
-
values: control._getWatch(),
|
|
20546
|
-
});
|
|
20547
|
-
}, [props.shouldUnregister, control]);
|
|
20548
20568
|
_formControl.current.formState = getProxyFormState(formState, control);
|
|
20549
20569
|
return _formControl.current;
|
|
20550
20570
|
}
|
|
@@ -34184,7 +34204,7 @@ const CheckoutForm$1 = ({ onSuccess, onError, children, setSubmitting, }) => {
|
|
|
34184
34204
|
};
|
|
34185
34205
|
var CheckoutForm$2 = memo$1(CheckoutForm$1);
|
|
34186
34206
|
|
|
34187
|
-
const publicStripeKey = "
|
|
34207
|
+
const publicStripeKey = "pk_live_51QvliXK5wvEuxX36GWLFgMtUrG2cGIjpW0eXoqVzjEr8S0PdGzAp4ydQa6ssxVW9u0zaLajod93YZnQIU5C8cgqp00Bb64X60b";
|
|
34188
34208
|
const stripePromise = loadStripe(publicStripeKey);
|
|
34189
34209
|
function PaymentElement({ paymentSecret, checkoutAppearance, locale, fonts, onSuccess, onError, children, setSubmitting, }) {
|
|
34190
34210
|
const options = {
|
|
@@ -34284,10 +34304,10 @@ function ShippingOptionWrapper({ rate, children, onPickupPointSelected, locale,
|
|
|
34284
34304
|
if (rate.provider === "zasilkovna") {
|
|
34285
34305
|
return (React__default.createElement(ZasilkovnaShippingOption, { onPickupPointSelected: onPickupPointSelected, locale: locale, countryCode: countryCode, apiKey: rate.clientSecret }, children));
|
|
34286
34306
|
}
|
|
34287
|
-
return;
|
|
34307
|
+
return React__default.createElement(React__default.Fragment, null, children);
|
|
34288
34308
|
}
|
|
34289
34309
|
|
|
34290
|
-
function ShippingMethodForm({ shippingRates, initialData, onSubmit, onBack, contactEmail, shippingAddress, currency, exchangeRate, locale, countryCode, }) {
|
|
34310
|
+
function ShippingMethodForm({ shippingRates, initialData, onSubmit, onBack, contactEmail, shippingAddress, currency, exchangeRate, locale, countryCode, setFormData, formData, }) {
|
|
34291
34311
|
var _a;
|
|
34292
34312
|
const { t } = useTranslation();
|
|
34293
34313
|
const form = useForm({
|
|
@@ -34330,17 +34350,39 @@ function ShippingMethodForm({ shippingRates, initialData, onSubmit, onBack, cont
|
|
|
34330
34350
|
return (React__default.createElement(ShippingOptionWrapper, { rate: rate, key: rateId, onPickupPointSelected: (pickupPointId, pickupPointName) => {
|
|
34331
34351
|
form.setValue("pickupPointId", pickupPointId);
|
|
34332
34352
|
form.setValue("pickupPointDisplayName", pickupPointName);
|
|
34353
|
+
setFormData(Object.assign(Object.assign({}, formData), { shipping: {
|
|
34354
|
+
rateId,
|
|
34355
|
+
provider: rate.provider,
|
|
34356
|
+
price: intPrice,
|
|
34357
|
+
name: rate.name,
|
|
34358
|
+
pickupPointId,
|
|
34359
|
+
pickupPointDisplayName,
|
|
34360
|
+
} }));
|
|
34333
34361
|
}, locale: locale, countryCode: countryCode },
|
|
34334
34362
|
React__default.createElement("div", { className: clsx("p-4 cursor-pointer rounded-md border bg-background", {
|
|
34335
34363
|
"bg-muted border-primary": currentRateId === rateId,
|
|
34336
34364
|
}), onClick: () => {
|
|
34365
|
+
const newFormData = {
|
|
34366
|
+
rateId,
|
|
34367
|
+
provider: rate.provider,
|
|
34368
|
+
price: intPrice,
|
|
34369
|
+
name: rate.name,
|
|
34370
|
+
pickupPointId: rate.provider === "zasilkovna"
|
|
34371
|
+
? form.watch("pickupPointId")
|
|
34372
|
+
: "",
|
|
34373
|
+
pickupPointDisplayName: rate.provider === "zasilkovna"
|
|
34374
|
+
? form.watch("pickupPointDisplayName")
|
|
34375
|
+
: "",
|
|
34376
|
+
};
|
|
34337
34377
|
form.setValue("rateId", rateId);
|
|
34338
34378
|
form.setValue("provider", rate.provider);
|
|
34339
34379
|
form.setValue("name", rate.name);
|
|
34340
34380
|
form.setValue("price", intPrice);
|
|
34341
34381
|
if (rate.provider !== "zasilkovna") {
|
|
34342
34382
|
form.setValue("pickupPointDisplayName", "");
|
|
34383
|
+
form.setValue("pickupPointId", "");
|
|
34343
34384
|
}
|
|
34385
|
+
setFormData(Object.assign(Object.assign({}, formData), { shipping: newFormData }));
|
|
34344
34386
|
} },
|
|
34345
34387
|
React__default.createElement("div", { className: "flex items-center justify-between w-full" },
|
|
34346
34388
|
React__default.createElement("p", null, rate.name),
|
|
@@ -34368,12 +34410,12 @@ function ShippingRateLoading() {
|
|
|
34368
34410
|
React__default.createElement(Skeleton, { className: "w-40 h-3.5" })));
|
|
34369
34411
|
}
|
|
34370
34412
|
|
|
34371
|
-
const useFormStore =
|
|
34413
|
+
const useFormStore = create()(persist((set) => ({
|
|
34372
34414
|
formData: {},
|
|
34373
34415
|
setFormData: (formData) => set({ formData }),
|
|
34374
34416
|
step: "customer",
|
|
34375
34417
|
setStep: (step) => set({ step }),
|
|
34376
|
-
}), { name: `checkout
|
|
34418
|
+
}), { name: `checkout` }));
|
|
34377
34419
|
|
|
34378
34420
|
const motionSettings = {
|
|
34379
34421
|
initial: { opacity: 0 },
|
|
@@ -34382,7 +34424,7 @@ const motionSettings = {
|
|
|
34382
34424
|
transition: { duration: 0.2 },
|
|
34383
34425
|
};
|
|
34384
34426
|
function CheckoutForm({ storeClient, checkoutId, onSuccess, onError, cancelUrl, clientSecret, customer, currency, checkoutAppearance, fonts, locale, setShippingCost, exchangeRate, }) {
|
|
34385
|
-
const { formData, setFormData, step, setStep } = useFormStore(
|
|
34427
|
+
const { formData, setFormData, step, setStep } = useFormStore();
|
|
34386
34428
|
const [paymentSecret, setPaymentSecret] = useState(null);
|
|
34387
34429
|
const [shippingRates, setShippingRates] = useState([]);
|
|
34388
34430
|
const validateStep = useCallback(() => {
|
|
@@ -34429,12 +34471,17 @@ function CheckoutForm({ storeClient, checkoutId, onSuccess, onError, cancelUrl,
|
|
|
34429
34471
|
if (shippingRates.length > 0)
|
|
34430
34472
|
return;
|
|
34431
34473
|
const getShippingRates = () => __awaiter(this, void 0, void 0, function* () {
|
|
34432
|
-
|
|
34433
|
-
|
|
34434
|
-
|
|
34474
|
+
try {
|
|
34475
|
+
const shippingRates = yield storeClient.getCheckoutShippingRates(clientSecret, checkoutId);
|
|
34476
|
+
setShippingRates(shippingRates);
|
|
34477
|
+
}
|
|
34478
|
+
catch (error) {
|
|
34479
|
+
console.error("Failed to load shipping rates:", error);
|
|
34480
|
+
setShippingRates([]);
|
|
34481
|
+
}
|
|
34435
34482
|
});
|
|
34436
34483
|
getShippingRates();
|
|
34437
|
-
}, [step,
|
|
34484
|
+
}, [step, clientSecret, checkoutId]);
|
|
34438
34485
|
// Handle address form submission
|
|
34439
34486
|
const handleCustomerSubmit = (data) => __awaiter(this, void 0, void 0, function* () {
|
|
34440
34487
|
setFormData(Object.assign(Object.assign({}, formData), { customer: data }));
|
|
@@ -34471,8 +34518,7 @@ function CheckoutForm({ storeClient, checkoutId, onSuccess, onError, cancelUrl,
|
|
|
34471
34518
|
const newFormData = Object.assign(Object.assign({}, formData), { shipping: data });
|
|
34472
34519
|
setFormData(newFormData);
|
|
34473
34520
|
yield storeClient.updateCheckout(clientSecret, checkoutId, {
|
|
34474
|
-
|
|
34475
|
-
shipmentInfo: {
|
|
34521
|
+
shipmentData: {
|
|
34476
34522
|
provider: data.provider,
|
|
34477
34523
|
pickupPointId: data.pickupPointId,
|
|
34478
34524
|
},
|
|
@@ -34509,7 +34555,7 @@ function CheckoutForm({ storeClient, checkoutId, onSuccess, onError, cancelUrl,
|
|
|
34509
34555
|
step === "customer" && (React__default.createElement(motion.div, Object.assign({ key: "customer" }, motionSettings, { className: "absolute w-full" }),
|
|
34510
34556
|
React__default.createElement(CustomerForm, { initialData: formData.customer, onSubmit: handleCustomerSubmit }))),
|
|
34511
34557
|
step === "shipping" && formData.customer && (React__default.createElement(motion.div, Object.assign({ key: "shipping" }, motionSettings, { className: "absolute w-full" }),
|
|
34512
|
-
React__default.createElement(ShippingMethodForm, { shippingRates: shippingRates, initialData: formData.shipping, onSubmit: handleShippingSubmit, onBack: handleBack, contactEmail: formData.customer.email, shippingAddress: formatAddress(formData.customer.address), currency: currency, exchangeRate: exchangeRate, locale: locale, countryCode: formData.customer.address.countryCode }))),
|
|
34558
|
+
React__default.createElement(ShippingMethodForm, { setFormData: setFormData, formData: formData, shippingRates: shippingRates, initialData: formData.shipping, onSubmit: handleShippingSubmit, onBack: handleBack, contactEmail: formData.customer.email, shippingAddress: formatAddress(formData.customer.address), currency: currency, exchangeRate: exchangeRate, locale: locale, countryCode: formData.customer.address.countryCode }))),
|
|
34513
34559
|
step === "payment" && formData.customer && formData.shipping && (React__default.createElement(motion.div, Object.assign({ key: "payment" }, motionSettings, { className: "absolute w-full" }),
|
|
34514
34560
|
React__default.createElement(PaymentForm, { locale: locale, fonts: fonts, checkoutAppearance: checkoutAppearance, paymentSecret: paymentSecret, onSuccess: onSuccess, onError: onError, onBack: handleBack, onDoubleBack: handleDoubleBack, contactEmail: formData.customer.email, shippingAddress: formatAddress(formData.customer.address), shippingProvider: formData.shipping.provider, shippingPrice: storeHelpers.formatPrice(formData.shipping.price, currency, exchangeRate) }))))));
|
|
34515
34561
|
}
|
|
@@ -34534,13 +34580,18 @@ function InputGroupLoading({ className }) {
|
|
|
34534
34580
|
}
|
|
34535
34581
|
|
|
34536
34582
|
function CheckoutSummary({ lineItems, shipping, tax, currency, cancelUrl, exchangeRate, }) {
|
|
34583
|
+
var _a;
|
|
34584
|
+
const { formData } = useFormStore();
|
|
34537
34585
|
const [isOpen, setIsOpen] = useState(false);
|
|
34538
34586
|
const { t } = useTranslation();
|
|
34539
34587
|
const subtotal = lineItems.reduce((acc, item) => {
|
|
34540
34588
|
var _a, _b;
|
|
34541
|
-
|
|
34589
|
+
const variant = (_a = item.product) === null || _a === void 0 ? void 0 : _a.productVariants.find((variant) => variant.variantOptions === item.variantOptions);
|
|
34590
|
+
const productItem = variant || item.product;
|
|
34591
|
+
return acc + ((_b = productItem === null || productItem === void 0 ? void 0 : productItem.priceInCents) !== null && _b !== void 0 ? _b : 0) * item.quantity;
|
|
34542
34592
|
}, 0);
|
|
34543
|
-
const
|
|
34593
|
+
const shippingPrice = shipping !== null && shipping !== void 0 ? shipping : (_a = formData.shipping) === null || _a === void 0 ? void 0 : _a.price;
|
|
34594
|
+
const total = subtotal + (tax !== null && tax !== void 0 ? tax : 0) + (shippingPrice !== null && shippingPrice !== void 0 ? shippingPrice : 0);
|
|
34544
34595
|
return (React__default.createElement("div", { className: "grid gap-5" },
|
|
34545
34596
|
React__default.createElement("div", { className: "flex justify-between items-center" },
|
|
34546
34597
|
React__default.createElement("div", { onClick: () => setIsOpen(!isOpen), className: "flex items-center gap-2 cursor-pointer" },
|
|
@@ -34561,8 +34612,8 @@ function CheckoutSummary({ lineItems, shipping, tax, currency, cancelUrl, exchan
|
|
|
34561
34612
|
React__default.createElement("p", null, storeHelpers.formatPrice(subtotal, currency, exchangeRate))),
|
|
34562
34613
|
React__default.createElement("div", { className: "flex justify-between" },
|
|
34563
34614
|
React__default.createElement("p", null, t("CheckoutEmbed.Summary.shipping")),
|
|
34564
|
-
React__default.createElement("p", null, !!
|
|
34565
|
-
? storeHelpers.formatPrice(
|
|
34615
|
+
React__default.createElement("p", null, !!shippingPrice
|
|
34616
|
+
? storeHelpers.formatPrice(shippingPrice, currency, exchangeRate)
|
|
34566
34617
|
: t("CheckoutEmbed.Summary.calculatedAtNextStep"))),
|
|
34567
34618
|
!!tax && (React__default.createElement("div", { className: "flex justify-between" },
|
|
34568
34619
|
React__default.createElement("p", null, t("CheckoutEmbed.Summary.tax")),
|
|
@@ -34579,15 +34630,22 @@ function CheckoutSummary({ lineItems, shipping, tax, currency, cancelUrl, exchan
|
|
|
34579
34630
|
grid: isOpen,
|
|
34580
34631
|
}) }, lineItems.map((item, index) => {
|
|
34581
34632
|
var _a, _b, _c, _d, _e;
|
|
34633
|
+
const variant = (_a = item.product) === null || _a === void 0 ? void 0 : _a.productVariants.find((variant) => variant.variantOptions === item.variantOptions);
|
|
34634
|
+
const productItem = variant || item.product;
|
|
34582
34635
|
return (React__default.createElement("div", { key: index, className: "flex items-center" },
|
|
34583
34636
|
React__default.createElement("div", { className: "relative" },
|
|
34584
|
-
React__default.createElement("div", { className: "w-16 h-16 bg-secondary rounded-lg overflow-hidden relative" }, (
|
|
34637
|
+
React__default.createElement("div", { className: "w-16 h-16 bg-secondary rounded-lg overflow-hidden relative" }, (productItem === null || productItem === void 0 ? void 0 : productItem.images[0]) && (React__default.createElement("img", { src: productItem.images[0] ||
|
|
34638
|
+
((_b = item === null || item === void 0 ? void 0 : item.product) === null || _b === void 0 ? void 0 : _b.images[0]) ||
|
|
34639
|
+
"/placeholder.svg", alt: ((_c = item.product) === null || _c === void 0 ? void 0 : _c.title) || "", className: "object-cover w-full h-full", sizes: "64px" }))),
|
|
34585
34640
|
React__default.createElement("div", { className: "absolute -top-2 -right-2 w-6 h-6 bg-primary rounded-full flex items-center text-background justify-center text-sm" }, item.quantity)),
|
|
34586
34641
|
React__default.createElement("div", { className: "ml-4 flex-1" },
|
|
34587
|
-
React__default.createElement("h3", { className: "text-lg font-medium" }, (
|
|
34588
|
-
React__default.createElement("p", { className: "text-muted-foreground text-sm" }, item.variantOptions.map((option) =>
|
|
34642
|
+
React__default.createElement("h3", { className: "text-lg font-medium" }, (_d = item.product) === null || _d === void 0 ? void 0 : _d.title),
|
|
34643
|
+
React__default.createElement("p", { className: "text-muted-foreground text-sm" }, item.variantOptions.map((option) => (React__default.createElement("span", { key: option.name },
|
|
34644
|
+
option.name,
|
|
34645
|
+
": ",
|
|
34646
|
+
option.value))))),
|
|
34589
34647
|
React__default.createElement("div", { className: "text-right" },
|
|
34590
|
-
React__default.createElement("p", { className: "text-lg font-medium" }, storeHelpers.formatPrice((_e =
|
|
34648
|
+
React__default.createElement("p", { className: "text-lg font-medium" }, storeHelpers.formatPrice((_e = productItem === null || productItem === void 0 ? void 0 : productItem.priceInCents) !== null && _e !== void 0 ? _e : 0, currency, exchangeRate)))));
|
|
34591
34649
|
}))));
|
|
34592
34650
|
}
|
|
34593
34651
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare const storeHelpers: {
|
|
2
2
|
proxy?: string;
|
|
3
|
-
formatPrice(priceInCents: number, currency: string, exchangeRate?: number): string;
|
|
3
|
+
formatPrice(priceInCents: number, currency: string, exchangeRate?: number | null): string;
|
|
4
4
|
getExchangeRate(baseCurrency: string, targetCurrency: string): Promise<number>;
|
|
5
5
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@betterstore/react",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.42",
|
|
4
4
|
"description": "E-commerce for Developers",
|
|
5
5
|
"private": false,
|
|
6
6
|
"publishConfig": {
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"author": "Better Store",
|
|
20
20
|
"license": "MIT",
|
|
21
21
|
"devDependencies": {
|
|
22
|
-
"@betterstore/sdk": "^0.3.
|
|
22
|
+
"@betterstore/sdk": "^0.3.36",
|
|
23
23
|
"@changesets/cli": "^2.28.1",
|
|
24
24
|
"@rollup/plugin-commonjs": "^28.0.3",
|
|
25
25
|
"@rollup/plugin-json": "^6.1.0",
|