@wix/headless-bookings 0.0.56 → 0.0.58
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/cjs/dist/react/booking/Booking.js +1 -1
- package/cjs/dist/react/booking-form/BookingForm.d.ts +117 -17
- package/cjs/dist/react/booking-form/BookingForm.js +149 -15
- package/cjs/dist/react/core/booking/Booking.d.ts +3 -3
- package/cjs/dist/react/core/booking/Booking.js +2 -2
- package/cjs/dist/react/core/booking-form/BookingForm.d.ts +112 -10
- package/cjs/dist/react/core/booking-form/BookingForm.js +204 -64
- package/cjs/dist/react/core/payment/Payment.d.ts +84 -5
- package/cjs/dist/react/core/payment/Payment.js +102 -4
- package/cjs/dist/react/payment/Payment.d.ts +64 -58
- package/cjs/dist/react/payment/Payment.js +66 -80
- package/cjs/dist/services/booking-form/booking-form.d.ts +22 -13
- package/cjs/dist/services/booking-form/booking-form.js +67 -25
- package/cjs/dist/services/booking-form/utils.d.ts +52 -0
- package/cjs/dist/services/booking-form/utils.js +47 -0
- package/cjs/dist/services/index.d.ts +1 -1
- package/cjs/dist/services/payment/payment.d.ts +4 -4
- package/cjs/dist/services/payment/payment.def.d.ts +4 -4
- package/cjs/dist/services/payment/payment.js +26 -18
- package/dist/react/booking/Booking.js +1 -1
- package/dist/react/booking-form/BookingForm.d.ts +117 -17
- package/dist/react/booking-form/BookingForm.js +149 -15
- package/dist/react/core/booking/Booking.d.ts +3 -3
- package/dist/react/core/booking/Booking.js +2 -2
- package/dist/react/core/booking-form/BookingForm.d.ts +112 -10
- package/dist/react/core/booking-form/BookingForm.js +204 -64
- package/dist/react/core/payment/Payment.d.ts +84 -5
- package/dist/react/core/payment/Payment.js +102 -4
- package/dist/react/payment/Payment.d.ts +64 -58
- package/dist/react/payment/Payment.js +66 -80
- package/dist/services/booking-form/booking-form.d.ts +22 -13
- package/dist/services/booking-form/booking-form.js +67 -25
- package/dist/services/booking-form/utils.d.ts +52 -0
- package/dist/services/booking-form/utils.js +47 -0
- package/dist/services/index.d.ts +1 -1
- package/dist/services/payment/payment.d.ts +4 -4
- package/dist/services/payment/payment.def.d.ts +4 -4
- package/dist/services/payment/payment.js +26 -18
- package/package.json +3 -3
|
@@ -5,8 +5,7 @@
|
|
|
5
5
|
import React from 'react';
|
|
6
6
|
import { AsChildChildren } from '@wix/headless-utils/react';
|
|
7
7
|
import { MoneyData } from '@wix/headless-components/react';
|
|
8
|
-
import type { PaymentServiceConfig,
|
|
9
|
-
import type { LineItem as CoreLineItem } from '../core/payment/Payment.js';
|
|
8
|
+
import type { PaymentServiceConfig, PricingServiceSelection } from '../../services/payment/payment.js';
|
|
10
9
|
/**
|
|
11
10
|
* Props for Payment.Root component
|
|
12
11
|
*/
|
|
@@ -17,8 +16,8 @@ export interface RootProps {
|
|
|
17
16
|
}) => React.ReactNode);
|
|
18
17
|
/** Service config for SSR (pre-fetched paymentDetails) */
|
|
19
18
|
paymentServiceConfig?: PaymentServiceConfig;
|
|
20
|
-
/**
|
|
21
|
-
|
|
19
|
+
/** Pricing service selections for lazy loading (triggers API call) */
|
|
20
|
+
pricingServiceSelections?: PricingServiceSelection[];
|
|
22
21
|
/** Number of participants for lazy loading */
|
|
23
22
|
numberOfParticipants?: number;
|
|
24
23
|
asChild?: boolean;
|
|
@@ -28,7 +27,7 @@ export interface RootProps {
|
|
|
28
27
|
* Root component that provides payment context to the entire app.
|
|
29
28
|
* Supports 3 modes:
|
|
30
29
|
* 1. SSR: paymentServiceConfig.paymentDetails - pre-fetched data
|
|
31
|
-
* 2. Lazy loading:
|
|
30
|
+
* 2. Lazy loading: pricingServiceSelections + numberOfParticipants props - calls API via useEffect
|
|
32
31
|
* 3. Reactive: no config/props - reads from BookingService signals
|
|
33
32
|
*
|
|
34
33
|
* @order 1
|
|
@@ -64,17 +63,32 @@ export interface SubtotalProps {
|
|
|
64
63
|
asChild?: boolean;
|
|
65
64
|
children?: AsChildChildren<{
|
|
66
65
|
subtotal: MoneyData | null;
|
|
66
|
+
priceText: string | null;
|
|
67
|
+
hasPriceText: boolean;
|
|
68
|
+
isFree: boolean;
|
|
67
69
|
}>;
|
|
68
70
|
className?: string;
|
|
69
71
|
}
|
|
70
72
|
/**
|
|
71
73
|
* Displays the payment subtotal.
|
|
74
|
+
* Always displays the monetary value but exposes priceText, hasPriceText, and isFree for custom rendering.
|
|
72
75
|
*
|
|
73
76
|
* @component
|
|
74
77
|
* @example
|
|
75
78
|
* ```tsx
|
|
76
79
|
* <Payment.Subtotal className="text-lg" />
|
|
77
80
|
* ```
|
|
81
|
+
* @example
|
|
82
|
+
* ```tsx
|
|
83
|
+
* <Payment.Subtotal asChild>
|
|
84
|
+
* {({ subtotal, priceText, hasPriceText, isFree }) => (
|
|
85
|
+
* <div>
|
|
86
|
+
* <Money money={subtotal} />
|
|
87
|
+
* {hasPriceText && <span className="text-sm">({priceText})</span>}
|
|
88
|
+
* </div>
|
|
89
|
+
* )}
|
|
90
|
+
* </Payment.Subtotal>
|
|
91
|
+
* ```
|
|
78
92
|
*/
|
|
79
93
|
export declare const Subtotal: React.ForwardRefExoticComponent<SubtotalProps & React.RefAttributes<HTMLElement>>;
|
|
80
94
|
/**
|
|
@@ -126,17 +140,36 @@ export interface TotalProps {
|
|
|
126
140
|
asChild?: boolean;
|
|
127
141
|
children?: AsChildChildren<{
|
|
128
142
|
total: MoneyData | null;
|
|
143
|
+
priceText: string | null;
|
|
144
|
+
hasPriceText: boolean;
|
|
145
|
+
isFree: boolean;
|
|
129
146
|
}>;
|
|
130
147
|
className?: string;
|
|
131
148
|
}
|
|
132
149
|
/**
|
|
133
150
|
* Displays the payment total.
|
|
151
|
+
* Always displays the monetary value but exposes priceText, hasPriceText, and isFree for custom rendering.
|
|
134
152
|
*
|
|
135
153
|
* @component
|
|
136
154
|
* @example
|
|
137
155
|
* ```tsx
|
|
138
156
|
* <Payment.Total className="text-2xl font-bold" />
|
|
139
157
|
* ```
|
|
158
|
+
* @example
|
|
159
|
+
* ```tsx
|
|
160
|
+
* <Payment.Total asChild>
|
|
161
|
+
* {({ total, priceText, hasPriceText, isFree }) => (
|
|
162
|
+
* <div>
|
|
163
|
+
* {isFree ? (
|
|
164
|
+
* <span className="text-green-500">Free</span>
|
|
165
|
+
* ) : (
|
|
166
|
+
* <Money money={total} />
|
|
167
|
+
* )}
|
|
168
|
+
* {hasPriceText && <span className="text-sm">({priceText})</span>}
|
|
169
|
+
* </div>
|
|
170
|
+
* )}
|
|
171
|
+
* </Payment.Total>
|
|
172
|
+
* ```
|
|
140
173
|
*/
|
|
141
174
|
export declare const Total: React.ForwardRefExoticComponent<TotalProps & React.RefAttributes<HTMLElement>>;
|
|
142
175
|
/**
|
|
@@ -240,101 +273,74 @@ export interface LineItemsListProps {
|
|
|
240
273
|
* ```
|
|
241
274
|
*/
|
|
242
275
|
export declare const LineItemsList: React.ForwardRefExoticComponent<LineItemsListProps & React.RefAttributes<HTMLElement>>;
|
|
243
|
-
/**
|
|
244
|
-
* Render props for LineItemRepeater asChild pattern
|
|
245
|
-
*/
|
|
246
|
-
export interface LineItemRepeaterRenderProps {
|
|
247
|
-
items: CoreLineItem[];
|
|
248
|
-
itemWrapper: (props: {
|
|
249
|
-
item: CoreLineItem;
|
|
250
|
-
index: number;
|
|
251
|
-
children: React.ReactNode;
|
|
252
|
-
}) => React.ReactNode;
|
|
253
|
-
}
|
|
254
276
|
/**
|
|
255
277
|
* Props for Payment.LineItemRepeater component
|
|
256
278
|
*/
|
|
257
279
|
export interface LineItemRepeaterProps {
|
|
258
|
-
children
|
|
259
|
-
asChild?: boolean;
|
|
280
|
+
children: React.ReactNode;
|
|
260
281
|
}
|
|
261
282
|
/**
|
|
262
|
-
* Repeater component that
|
|
263
|
-
*
|
|
283
|
+
* Repeater component that maps over line items and provides context per item.
|
|
284
|
+
* Uses GenericList.Repeater internally with itemWrapper that provides LineItemContext.
|
|
264
285
|
*
|
|
265
286
|
* @component
|
|
266
287
|
* @example
|
|
267
288
|
* ```tsx
|
|
268
|
-
* // Standard usage
|
|
269
289
|
* <Payment.LineItemRepeater>
|
|
270
|
-
* <Payment.
|
|
271
|
-
*
|
|
272
|
-
*
|
|
273
|
-
* // AsChild usage with custom list
|
|
274
|
-
* <Payment.LineItemRepeater asChild>
|
|
275
|
-
* {({ items, itemWrapper }) => (
|
|
276
|
-
* <ol>
|
|
277
|
-
* {items.map((item, index) => (
|
|
278
|
-
* <li key={item.id}>
|
|
279
|
-
* {itemWrapper({ item, index, children: <Payment.LineItemPrice /> })}
|
|
280
|
-
* </li>
|
|
281
|
-
* ))}
|
|
282
|
-
* </ol>
|
|
283
|
-
* )}
|
|
290
|
+
* <Payment.LineItemTotal />
|
|
291
|
+
* <Payment.LineItemDiscount />
|
|
284
292
|
* </Payment.LineItemRepeater>
|
|
285
293
|
* ```
|
|
286
294
|
*/
|
|
287
295
|
export declare const LineItemRepeater: React.ForwardRefExoticComponent<LineItemRepeaterProps & React.RefAttributes<HTMLElement>>;
|
|
288
296
|
/**
|
|
289
|
-
* Props for Payment.
|
|
297
|
+
* Props for Payment.LineItemTotal component
|
|
290
298
|
*/
|
|
291
|
-
export interface
|
|
292
|
-
lineItem: CoreLineItem;
|
|
293
|
-
currency: string;
|
|
294
|
-
children?: React.ReactNode | AsChildChildren<{
|
|
295
|
-
lineItem: CoreLineItem;
|
|
296
|
-
currency: string;
|
|
297
|
-
}>;
|
|
299
|
+
export interface LineItemTotalProps {
|
|
298
300
|
asChild?: boolean;
|
|
301
|
+
children?: AsChildChildren<{
|
|
302
|
+
totalPrice: MoneyData | null;
|
|
303
|
+
priceText: string | null;
|
|
304
|
+
hasPriceText: boolean;
|
|
305
|
+
isFree: boolean;
|
|
306
|
+
}>;
|
|
299
307
|
className?: string;
|
|
300
|
-
'data-testid'?: string;
|
|
301
308
|
}
|
|
302
309
|
/**
|
|
303
|
-
*
|
|
304
|
-
*
|
|
310
|
+
* Displays the line item total (total price after tax).
|
|
311
|
+
* Shows priceText for CUSTOM rate type services, otherwise shows totalPrice.
|
|
305
312
|
*
|
|
306
313
|
* @component
|
|
307
314
|
* @example
|
|
308
315
|
* ```tsx
|
|
309
|
-
* <Payment.
|
|
310
|
-
* <Payment.LineItemPrice />
|
|
311
|
-
* <Payment.LineItemDiscount />
|
|
312
|
-
* </Payment.LineItemRoot>
|
|
316
|
+
* <Payment.LineItemTotal className="text-2xl font-bold" />
|
|
313
317
|
* ```
|
|
314
318
|
*/
|
|
315
|
-
export declare const
|
|
319
|
+
export declare const LineItemTotal: React.ForwardRefExoticComponent<LineItemTotalProps & React.RefAttributes<HTMLElement>>;
|
|
316
320
|
/**
|
|
317
|
-
* Props for Payment.
|
|
321
|
+
* Props for Payment.LineItemSubtotal component
|
|
318
322
|
*/
|
|
319
|
-
export interface
|
|
323
|
+
export interface LineItemSubtotalProps {
|
|
320
324
|
asChild?: boolean;
|
|
321
325
|
children?: AsChildChildren<{
|
|
322
|
-
|
|
326
|
+
subtotal: MoneyData | null;
|
|
323
327
|
priceText: string | null;
|
|
328
|
+
hasPriceText: boolean;
|
|
329
|
+
isFree: boolean;
|
|
324
330
|
}>;
|
|
325
331
|
className?: string;
|
|
326
332
|
}
|
|
327
333
|
/**
|
|
328
|
-
* Displays the line item price.
|
|
329
|
-
* Shows priceText for CUSTOM rate type services, otherwise shows
|
|
334
|
+
* Displays the line item subtotal (full price before discounts).
|
|
335
|
+
* Shows priceText for CUSTOM rate type services, otherwise shows subtotal.
|
|
330
336
|
*
|
|
331
337
|
* @component
|
|
332
338
|
* @example
|
|
333
339
|
* ```tsx
|
|
334
|
-
* <Payment.
|
|
340
|
+
* <Payment.LineItemSubtotal className="text-lg" />
|
|
335
341
|
* ```
|
|
336
342
|
*/
|
|
337
|
-
export declare const
|
|
343
|
+
export declare const LineItemSubtotal: React.ForwardRefExoticComponent<LineItemSubtotalProps & React.RefAttributes<HTMLElement>>;
|
|
338
344
|
/**
|
|
339
345
|
* Props for Payment.LineItemDiscount component
|
|
340
346
|
*/
|
|
@@ -19,8 +19,8 @@ var TestIds;
|
|
|
19
19
|
TestIds["paymentLineItems"] = "payment-line-items";
|
|
20
20
|
TestIds["paymentLineItemsList"] = "payment-line-items-list";
|
|
21
21
|
TestIds["paymentLineItemRepeater"] = "payment-line-item-repeater";
|
|
22
|
-
TestIds["
|
|
23
|
-
TestIds["
|
|
22
|
+
TestIds["paymentLineItemTotal"] = "payment-line-item-total";
|
|
23
|
+
TestIds["paymentLineItemSubtotal"] = "payment-line-item-subtotal";
|
|
24
24
|
TestIds["paymentLineItemDiscount"] = "payment-line-item-discount";
|
|
25
25
|
TestIds["paymentLineItemDeposit"] = "payment-line-item-deposit";
|
|
26
26
|
})(TestIds || (TestIds = {}));
|
|
@@ -28,7 +28,7 @@ var TestIds;
|
|
|
28
28
|
* Root component that provides payment context to the entire app.
|
|
29
29
|
* Supports 3 modes:
|
|
30
30
|
* 1. SSR: paymentServiceConfig.paymentDetails - pre-fetched data
|
|
31
|
-
* 2. Lazy loading:
|
|
31
|
+
* 2. Lazy loading: pricingServiceSelections + numberOfParticipants props - calls API via useEffect
|
|
32
32
|
* 3. Reactive: no config/props - reads from BookingService signals
|
|
33
33
|
*
|
|
34
34
|
* @order 1
|
|
@@ -57,24 +57,36 @@ var TestIds;
|
|
|
57
57
|
* ```
|
|
58
58
|
*/
|
|
59
59
|
export const Root = React.forwardRef((props, ref) => {
|
|
60
|
-
const { children, paymentServiceConfig,
|
|
61
|
-
return (_jsx(CorePayment.Root, { paymentServiceConfig: paymentServiceConfig,
|
|
60
|
+
const { children, paymentServiceConfig, pricingServiceSelections, numberOfParticipants, asChild, className, ...attrs } = props;
|
|
61
|
+
return (_jsx(CorePayment.Root, { paymentServiceConfig: paymentServiceConfig, pricingServiceSelections: pricingServiceSelections, numberOfParticipants: numberOfParticipants, children: ({ isLoading, hasError }) => {
|
|
62
62
|
return (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.paymentRoot, "data-loading": isLoading, "data-has-error": hasError, customElement: children, customElementProps: { isLoading, hasError }, ...attrs, children: children }));
|
|
63
63
|
} }));
|
|
64
64
|
});
|
|
65
65
|
Root.displayName = 'Payment.Root';
|
|
66
66
|
/**
|
|
67
67
|
* Displays the payment subtotal.
|
|
68
|
+
* Always displays the monetary value but exposes priceText, hasPriceText, and isFree for custom rendering.
|
|
68
69
|
*
|
|
69
70
|
* @component
|
|
70
71
|
* @example
|
|
71
72
|
* ```tsx
|
|
72
73
|
* <Payment.Subtotal className="text-lg" />
|
|
73
74
|
* ```
|
|
75
|
+
* @example
|
|
76
|
+
* ```tsx
|
|
77
|
+
* <Payment.Subtotal asChild>
|
|
78
|
+
* {({ subtotal, priceText, hasPriceText, isFree }) => (
|
|
79
|
+
* <div>
|
|
80
|
+
* <Money money={subtotal} />
|
|
81
|
+
* {hasPriceText && <span className="text-sm">({priceText})</span>}
|
|
82
|
+
* </div>
|
|
83
|
+
* )}
|
|
84
|
+
* </Payment.Subtotal>
|
|
85
|
+
* ```
|
|
74
86
|
*/
|
|
75
87
|
export const Subtotal = React.forwardRef((props, ref) => {
|
|
76
88
|
const { asChild, children, className } = props;
|
|
77
|
-
return (_jsx(CorePayment.Data, { children: ({ subtotal }) => (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.paymentSubtotal, customElement: children, customElementProps: { subtotal }, children: subtotal
|
|
89
|
+
return (_jsx(CorePayment.Data, { children: ({ subtotal, priceText, hasPriceText, isFree }) => (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.paymentSubtotal, "data-has-price-text": hasPriceText, "data-is-free": isFree, customElement: children, customElementProps: { subtotal, priceText, hasPriceText, isFree }, children: subtotal && _jsx(Money, { money: subtotal }) })) }));
|
|
78
90
|
});
|
|
79
91
|
Subtotal.displayName = 'Payment.Subtotal';
|
|
80
92
|
/**
|
|
@@ -89,10 +101,7 @@ Subtotal.displayName = 'Payment.Subtotal';
|
|
|
89
101
|
*/
|
|
90
102
|
export const Tax = React.forwardRef((props, ref) => {
|
|
91
103
|
const { asChild, children, className } = props;
|
|
92
|
-
return (_jsx(CorePayment.Data, { children: ({ tax }) => {
|
|
93
|
-
const hasTax = tax !== null && tax.amount > 0;
|
|
94
|
-
return (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.paymentTax, "data-has-tax": hasTax, customElement: children, customElementProps: { tax }, children: tax ? _jsx(Money, { money: tax }) : null }));
|
|
95
|
-
} }));
|
|
104
|
+
return (_jsx(CorePayment.Data, { children: ({ tax, hasTax }) => (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.paymentTax, "data-has-tax": hasTax, customElement: children, customElementProps: { tax }, children: hasTax && _jsx(Money, { money: tax }) })) }));
|
|
96
105
|
});
|
|
97
106
|
Tax.displayName = 'Payment.Tax';
|
|
98
107
|
/**
|
|
@@ -107,24 +116,37 @@ Tax.displayName = 'Payment.Tax';
|
|
|
107
116
|
*/
|
|
108
117
|
export const Discount = React.forwardRef((props, ref) => {
|
|
109
118
|
const { asChild, children, className } = props;
|
|
110
|
-
return (_jsx(CorePayment.Data, { children: ({ discount }) => {
|
|
111
|
-
const hasDiscount = discount !== null && discount.amount > 0;
|
|
112
|
-
return (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.paymentDiscount, "data-has-discount": hasDiscount, customElement: children, customElementProps: { discount }, children: discount ? _jsx(Money, { money: discount }) : null }));
|
|
113
|
-
} }));
|
|
119
|
+
return (_jsx(CorePayment.Data, { children: ({ discount, hasDiscount }) => (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.paymentDiscount, "data-has-discount": hasDiscount, customElement: children, customElementProps: { discount }, children: hasDiscount && _jsx(Money, { money: discount }) })) }));
|
|
114
120
|
});
|
|
115
121
|
Discount.displayName = 'Payment.Discount';
|
|
116
122
|
/**
|
|
117
123
|
* Displays the payment total.
|
|
124
|
+
* Always displays the monetary value but exposes priceText, hasPriceText, and isFree for custom rendering.
|
|
118
125
|
*
|
|
119
126
|
* @component
|
|
120
127
|
* @example
|
|
121
128
|
* ```tsx
|
|
122
129
|
* <Payment.Total className="text-2xl font-bold" />
|
|
123
130
|
* ```
|
|
131
|
+
* @example
|
|
132
|
+
* ```tsx
|
|
133
|
+
* <Payment.Total asChild>
|
|
134
|
+
* {({ total, priceText, hasPriceText, isFree }) => (
|
|
135
|
+
* <div>
|
|
136
|
+
* {isFree ? (
|
|
137
|
+
* <span className="text-green-500">Free</span>
|
|
138
|
+
* ) : (
|
|
139
|
+
* <Money money={total} />
|
|
140
|
+
* )}
|
|
141
|
+
* {hasPriceText && <span className="text-sm">({priceText})</span>}
|
|
142
|
+
* </div>
|
|
143
|
+
* )}
|
|
144
|
+
* </Payment.Total>
|
|
145
|
+
* ```
|
|
124
146
|
*/
|
|
125
147
|
export const Total = React.forwardRef((props, ref) => {
|
|
126
148
|
const { asChild, children, className } = props;
|
|
127
|
-
return (_jsx(CorePayment.Data, { children: ({ total }) => (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.paymentTotal, customElement: children, customElementProps: { total }, children: total
|
|
149
|
+
return (_jsx(CorePayment.Data, { children: ({ total, priceText, hasPriceText, isFree }) => (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.paymentTotal, "data-has-price-text": hasPriceText, "data-is-free": isFree, customElement: children, customElementProps: { total, priceText, hasPriceText, isFree }, children: total && _jsx(Money, { money: total }) })) }));
|
|
128
150
|
});
|
|
129
151
|
Total.displayName = 'Payment.Total';
|
|
130
152
|
/**
|
|
@@ -139,10 +161,7 @@ Total.displayName = 'Payment.Total';
|
|
|
139
161
|
*/
|
|
140
162
|
export const PayNow = React.forwardRef((props, ref) => {
|
|
141
163
|
const { asChild, children, className } = props;
|
|
142
|
-
return (_jsx(CorePayment.Data, { children: ({ payNow,
|
|
143
|
-
const isDeposit = payNow !== null && total !== null && payNow.amount < total.amount;
|
|
144
|
-
return (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.paymentPayNow, "data-has-deposit": isDeposit, customElement: children, customElementProps: { payNow }, children: payNow ? _jsx(Money, { money: payNow }) : null }));
|
|
145
|
-
} }));
|
|
164
|
+
return (_jsx(CorePayment.Data, { children: ({ payNow, isDeposit }) => (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.paymentPayNow, "data-has-deposit": isDeposit, customElement: children, customElementProps: { payNow }, children: payNow && payNow.amount > 0 && _jsx(Money, { money: payNow }) })) }));
|
|
146
165
|
});
|
|
147
166
|
PayNow.displayName = 'Payment.PayNow';
|
|
148
167
|
/**
|
|
@@ -157,10 +176,7 @@ PayNow.displayName = 'Payment.PayNow';
|
|
|
157
176
|
*/
|
|
158
177
|
export const PayLater = React.forwardRef((props, ref) => {
|
|
159
178
|
const { asChild, children, className } = props;
|
|
160
|
-
return (_jsx(CorePayment.Data, { children: ({ payLater,
|
|
161
|
-
const isDeposit = payNow !== null && total !== null && payNow.amount < total.amount;
|
|
162
|
-
return (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.paymentPayLater, "data-has-deposit": isDeposit, customElement: children, customElementProps: { payLater }, children: payLater ? _jsx(Money, { money: payLater }) : null }));
|
|
163
|
-
} }));
|
|
179
|
+
return (_jsx(CorePayment.Data, { children: ({ payLater, isDeposit }) => (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.paymentPayLater, "data-has-deposit": isDeposit, customElement: children, customElementProps: { payLater }, children: payLater && payLater.amount > 0 && _jsx(Money, { money: payLater }) })) }));
|
|
164
180
|
});
|
|
165
181
|
PayLater.displayName = 'Payment.PayLater';
|
|
166
182
|
/**
|
|
@@ -219,84 +235,60 @@ export const LineItemsList = React.forwardRef((props, ref) => {
|
|
|
219
235
|
});
|
|
220
236
|
LineItemsList.displayName = 'Payment.LineItemsList';
|
|
221
237
|
/**
|
|
222
|
-
*
|
|
223
|
-
|
|
238
|
+
* Internal component that wraps each line item with context provider.
|
|
239
|
+
*/
|
|
240
|
+
const LineItemWrapper = ({ item, currency, children, }) => {
|
|
241
|
+
return (_jsx(CorePayment.LineItemProvider, { lineItem: item, currency: currency, children: children }));
|
|
242
|
+
};
|
|
243
|
+
/**
|
|
244
|
+
* Repeater component that maps over line items and provides context per item.
|
|
245
|
+
* Uses GenericList.Repeater internally with itemWrapper that provides LineItemContext.
|
|
224
246
|
*
|
|
225
247
|
* @component
|
|
226
248
|
* @example
|
|
227
249
|
* ```tsx
|
|
228
|
-
* // Standard usage
|
|
229
250
|
* <Payment.LineItemRepeater>
|
|
230
|
-
* <Payment.
|
|
231
|
-
*
|
|
232
|
-
*
|
|
233
|
-
* // AsChild usage with custom list
|
|
234
|
-
* <Payment.LineItemRepeater asChild>
|
|
235
|
-
* {({ items, itemWrapper }) => (
|
|
236
|
-
* <ol>
|
|
237
|
-
* {items.map((item, index) => (
|
|
238
|
-
* <li key={item.id}>
|
|
239
|
-
* {itemWrapper({ item, index, children: <Payment.LineItemPrice /> })}
|
|
240
|
-
* </li>
|
|
241
|
-
* ))}
|
|
242
|
-
* </ol>
|
|
243
|
-
* )}
|
|
251
|
+
* <Payment.LineItemTotal />
|
|
252
|
+
* <Payment.LineItemDiscount />
|
|
244
253
|
* </Payment.LineItemRepeater>
|
|
245
254
|
* ```
|
|
246
255
|
*/
|
|
247
256
|
export const LineItemRepeater = React.forwardRef((props, ref) => {
|
|
248
|
-
const { children
|
|
257
|
+
const { children } = props;
|
|
249
258
|
const { currency } = useLineItemsContext();
|
|
250
|
-
|
|
251
|
-
const lineItemWrapper = ({ item, children: itemChildren, }) => {
|
|
252
|
-
return (_jsx(LineItemRoot, { lineItem: item, currency: currency, "data-testid": TestIds.paymentLineItemRepeater, children: itemChildren || undefined }, item.id));
|
|
253
|
-
};
|
|
254
|
-
return (_jsx(GenericList.Repeater, { ref: ref, itemWrapper: lineItemWrapper, asChild: asChild, children: children }));
|
|
259
|
+
return (_jsx(GenericList.Repeater, { ref: ref, itemWrapper: ({ item }) => (_jsx(LineItemWrapper, { item: item, currency: currency, children: children }, item.id)), children: undefined }));
|
|
255
260
|
});
|
|
256
261
|
LineItemRepeater.displayName = 'Payment.LineItemRepeater';
|
|
257
|
-
const LineItemContext = React.createContext(null);
|
|
258
|
-
function useLineItemContext() {
|
|
259
|
-
const context = React.useContext(LineItemContext);
|
|
260
|
-
if (!context) {
|
|
261
|
-
throw new Error('useLineItemContext must be used within a Payment.LineItemRoot component');
|
|
262
|
-
}
|
|
263
|
-
return context;
|
|
264
|
-
}
|
|
265
262
|
/**
|
|
266
|
-
*
|
|
267
|
-
*
|
|
263
|
+
* Displays the line item total (total price after tax).
|
|
264
|
+
* Shows priceText for CUSTOM rate type services, otherwise shows totalPrice.
|
|
268
265
|
*
|
|
269
266
|
* @component
|
|
270
267
|
* @example
|
|
271
268
|
* ```tsx
|
|
272
|
-
* <Payment.
|
|
273
|
-
* <Payment.LineItemPrice />
|
|
274
|
-
* <Payment.LineItemDiscount />
|
|
275
|
-
* </Payment.LineItemRoot>
|
|
269
|
+
* <Payment.LineItemTotal className="text-2xl font-bold" />
|
|
276
270
|
* ```
|
|
277
271
|
*/
|
|
278
|
-
export const
|
|
279
|
-
const {
|
|
280
|
-
return (_jsx(
|
|
272
|
+
export const LineItemTotal = React.forwardRef((props, ref) => {
|
|
273
|
+
const { asChild, children, className } = props;
|
|
274
|
+
return (_jsx(CorePayment.LineItemInfo, { children: ({ totalPrice, priceText, hasPriceText, isFree }) => (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.paymentLineItemTotal, "data-has-price-text": hasPriceText, "data-is-free": isFree, customElement: children, customElementProps: { totalPrice, priceText, hasPriceText, isFree }, children: priceText ? (_jsx("span", { children: priceText })) : (totalPrice && _jsx(Money, { money: totalPrice })) })) }));
|
|
281
275
|
});
|
|
282
|
-
|
|
276
|
+
LineItemTotal.displayName = 'Payment.LineItemTotal';
|
|
283
277
|
/**
|
|
284
|
-
* Displays the line item price.
|
|
285
|
-
* Shows priceText for CUSTOM rate type services, otherwise shows
|
|
278
|
+
* Displays the line item subtotal (full price before discounts).
|
|
279
|
+
* Shows priceText for CUSTOM rate type services, otherwise shows subtotal.
|
|
286
280
|
*
|
|
287
281
|
* @component
|
|
288
282
|
* @example
|
|
289
283
|
* ```tsx
|
|
290
|
-
* <Payment.
|
|
284
|
+
* <Payment.LineItemSubtotal className="text-lg" />
|
|
291
285
|
* ```
|
|
292
286
|
*/
|
|
293
|
-
export const
|
|
287
|
+
export const LineItemSubtotal = React.forwardRef((props, ref) => {
|
|
294
288
|
const { asChild, children, className } = props;
|
|
295
|
-
|
|
296
|
-
const { totalPrice, priceText } = lineItem;
|
|
297
|
-
return (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.paymentLineItemPrice, "data-has-price-text": !!priceText, customElement: children, customElementProps: { totalPrice, priceText }, children: priceText ? (_jsx("span", { children: priceText })) : totalPrice ? (_jsx(Money, { money: totalPrice })) : null }));
|
|
289
|
+
return (_jsx(CorePayment.LineItemInfo, { children: ({ subtotal, priceText, hasPriceText, isFree }) => (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.paymentLineItemSubtotal, "data-has-price-text": hasPriceText, "data-is-free": isFree, customElement: children, customElementProps: { subtotal, priceText, hasPriceText, isFree }, children: priceText ? (_jsx("span", { children: priceText })) : (subtotal && _jsx(Money, { money: subtotal })) })) }));
|
|
298
290
|
});
|
|
299
|
-
|
|
291
|
+
LineItemSubtotal.displayName = 'Payment.LineItemSubtotal';
|
|
300
292
|
/**
|
|
301
293
|
* Displays the line item discount.
|
|
302
294
|
* Uses data-has-discount attribute for conditional visibility.
|
|
@@ -309,10 +301,7 @@ LineItemPrice.displayName = 'Payment.LineItemPrice';
|
|
|
309
301
|
*/
|
|
310
302
|
export const LineItemDiscount = React.forwardRef((props, ref) => {
|
|
311
303
|
const { asChild, children, className } = props;
|
|
312
|
-
|
|
313
|
-
const { discount } = lineItem;
|
|
314
|
-
const hasDiscount = discount !== null && discount.amount > 0;
|
|
315
|
-
return (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.paymentLineItemDiscount, "data-has-discount": hasDiscount, customElement: children, customElementProps: { discount }, children: discount ? _jsx(Money, { money: discount }) : null }));
|
|
304
|
+
return (_jsx(CorePayment.LineItemInfo, { children: ({ discount, hasDiscount }) => (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.paymentLineItemDiscount, "data-has-discount": hasDiscount, customElement: children, customElementProps: { discount }, children: hasDiscount && _jsx(Money, { money: discount }) })) }));
|
|
316
305
|
});
|
|
317
306
|
LineItemDiscount.displayName = 'Payment.LineItemDiscount';
|
|
318
307
|
/**
|
|
@@ -327,9 +316,6 @@ LineItemDiscount.displayName = 'Payment.LineItemDiscount';
|
|
|
327
316
|
*/
|
|
328
317
|
export const LineItemDeposit = React.forwardRef((props, ref) => {
|
|
329
318
|
const { asChild, children, className } = props;
|
|
330
|
-
|
|
331
|
-
const { deposit } = lineItem;
|
|
332
|
-
const hasDeposit = deposit !== null && deposit.amount > 0;
|
|
333
|
-
return (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.paymentLineItemDeposit, "data-has-deposit": hasDeposit, customElement: children, customElementProps: { deposit }, children: deposit ? _jsx(Money, { money: deposit }) : null }));
|
|
319
|
+
return (_jsx(CorePayment.LineItemInfo, { children: ({ deposit, hasDeposit }) => (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.paymentLineItemDeposit, "data-has-deposit": hasDeposit, customElement: children, customElementProps: { deposit }, children: hasDeposit && _jsx(Money, { money: deposit }) })) }));
|
|
334
320
|
});
|
|
335
321
|
LineItemDeposit.displayName = 'Payment.LineItemDeposit';
|
|
@@ -25,24 +25,44 @@ export interface ValidationResult {
|
|
|
25
25
|
/** Array of validation failure messages */
|
|
26
26
|
validationFailures: string[];
|
|
27
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Error thrown when BookingFormService cannot be initialized due to missing configuration.
|
|
30
|
+
* This occurs when:
|
|
31
|
+
* - No config (formId or form) was provided
|
|
32
|
+
* - AND the component is not wrapped with Booking.Root (no BookingService available)
|
|
33
|
+
*/
|
|
34
|
+
export declare class BookingFormConfigurationError extends Error {
|
|
35
|
+
constructor(message?: string);
|
|
36
|
+
}
|
|
28
37
|
/**
|
|
29
38
|
* Configuration for BookingFormService.
|
|
30
39
|
* Supports two modes:
|
|
31
40
|
* 1. Client-side loading: Provide formId to fetch the form dynamically
|
|
32
41
|
* 2. SSR/SSG: Provide a pre-loaded form object (must be from bookings namespace)
|
|
33
42
|
*
|
|
43
|
+
* Note: The config itself is optional. If not provided, the formId will be
|
|
44
|
+
* extracted from the selected service if available.
|
|
45
|
+
*
|
|
34
46
|
* @example
|
|
35
47
|
* ```tsx
|
|
36
48
|
* // Pattern 1: Client-side loading
|
|
37
49
|
* const config = { formId: 'form-123' };
|
|
38
50
|
*
|
|
51
|
+
* // Pattern 1b: Client-side loading with service IDs
|
|
52
|
+
* const config = { formId: 'form-123', serviceIds: ['service-1', 'service-2'] };
|
|
53
|
+
*
|
|
39
54
|
* // Pattern 2: Pre-loaded form (SSR/SSG)
|
|
40
55
|
* const config = { form: preloadedForm };
|
|
56
|
+
*
|
|
57
|
+
* // Pattern 3: No config (formId extracted from service)
|
|
58
|
+
* // config = undefined
|
|
41
59
|
* ```
|
|
42
60
|
*/
|
|
43
61
|
export type BookingFormServiceConfig = {
|
|
44
62
|
/** The form ID to load (client-side loading) */
|
|
45
63
|
formId: string;
|
|
64
|
+
/** Optional list of service IDs associated with this booking form */
|
|
65
|
+
serviceIds?: string[];
|
|
46
66
|
} | {
|
|
47
67
|
/** Pre-loaded form object (SSR/SSG) - must be from bookings namespace */
|
|
48
68
|
form: forms.Form;
|
|
@@ -79,18 +99,7 @@ export interface BookingFormServiceInternalAPI extends BookingFormServiceAPI {
|
|
|
79
99
|
/** Internal: Register validate callback (called by core component) */
|
|
80
100
|
_setValidateCallback: (callback: () => Promise<ValidationResult>) => void;
|
|
81
101
|
}
|
|
82
|
-
|
|
83
|
-
* Type guard to check if config has formId
|
|
84
|
-
*/
|
|
85
|
-
export declare function hasFormId(config: BookingFormServiceConfig): config is {
|
|
86
|
-
formId: string;
|
|
87
|
-
};
|
|
88
|
-
/**
|
|
89
|
-
* Type guard to check if config has pre-loaded form
|
|
90
|
-
*/
|
|
91
|
-
export declare function hasForm(config: BookingFormServiceConfig): config is {
|
|
92
|
-
form: forms.Form;
|
|
93
|
-
};
|
|
102
|
+
export { hasFormId, hasForm, extractFormIdFromForm, extractFormIdFromConfig, type FormIdConfig, } from './utils.js';
|
|
94
103
|
/**
|
|
95
104
|
* Service definition for BookingForm.
|
|
96
105
|
* Defines the contract that the BookingFormService must implement.
|
|
@@ -137,4 +146,4 @@ export declare const BookingFormService: import("@wix/services-definitions").Ser
|
|
|
137
146
|
__api: BookingFormServiceAPI;
|
|
138
147
|
__config: {};
|
|
139
148
|
isServiceDefinition?: boolean;
|
|
140
|
-
} & BookingFormServiceAPI, BookingFormServiceConfig>;
|
|
149
|
+
} & BookingFormServiceAPI, BookingFormServiceConfig | undefined>;
|