@wix/headless-bookings 0.0.57 → 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/core/booking/Booking.d.ts +3 -3
- package/cjs/dist/react/core/booking/Booking.js +2 -2
- 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/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/core/booking/Booking.d.ts +3 -3
- package/dist/react/core/booking/Booking.js +2 -2
- 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/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 +2 -2
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Core Payment Components
|
|
4
|
+
* Provides low-level access to PaymentService via render props
|
|
5
|
+
* Note: Currently supports single service only
|
|
6
|
+
*/
|
|
7
|
+
import React from 'react';
|
|
2
8
|
import { WixServices, useService } from '@wix/services-manager-react';
|
|
3
9
|
import { createServicesMap } from '@wix/services-manager';
|
|
4
10
|
import { PaymentServiceDefinition, PaymentService, } from '../../../services/payment/payment.js';
|
|
@@ -20,7 +26,7 @@ function RootContent({ children, }) {
|
|
|
20
26
|
* Root component that provides payment context.
|
|
21
27
|
* Supports 3 modes:
|
|
22
28
|
* 1. SSR: paymentServiceConfig.paymentDetails - pre-fetched data
|
|
23
|
-
* 2. Lazy loading:
|
|
29
|
+
* 2. Lazy loading: pricingServiceSelections + numberOfParticipants props - calls API on init
|
|
24
30
|
* 3. Reactive: no config/props - reads from BookingService signals
|
|
25
31
|
*
|
|
26
32
|
* @component
|
|
@@ -32,7 +38,7 @@ function RootContent({ children, }) {
|
|
|
32
38
|
* </Payment.Root>
|
|
33
39
|
*
|
|
34
40
|
* // Lazy loading mode
|
|
35
|
-
* <Payment.Root
|
|
41
|
+
* <Payment.Root pricingServiceSelections={[...]} numberOfParticipants={2}>
|
|
36
42
|
* {({ isLoading }) => isLoading ? <div>Loading...</div> : <Payment.Total />}
|
|
37
43
|
* </Payment.Root>
|
|
38
44
|
*
|
|
@@ -43,11 +49,11 @@ function RootContent({ children, }) {
|
|
|
43
49
|
* ```
|
|
44
50
|
*/
|
|
45
51
|
export function Root(props) {
|
|
46
|
-
const { children, paymentServiceConfig = {},
|
|
52
|
+
const { children, paymentServiceConfig = {}, pricingServiceSelections, numberOfParticipants, } = props;
|
|
47
53
|
// Merge public config with lazy loading props into internal config
|
|
48
54
|
const internalConfig = {
|
|
49
55
|
...paymentServiceConfig,
|
|
50
|
-
|
|
56
|
+
pricingServiceSelections,
|
|
51
57
|
numberOfParticipants,
|
|
52
58
|
};
|
|
53
59
|
return (_jsx(WixServices, { servicesMap: createServicesMap().addService(PaymentServiceDefinition, PaymentService, internalConfig), children: _jsx(RootContent, { children: children }) }));
|
|
@@ -71,6 +77,16 @@ export function Data(props) {
|
|
|
71
77
|
const discount = convertMultiCurrencyPriceToMoneyData(priceSummary?.discount, currency);
|
|
72
78
|
const payNow = convertMultiCurrencyPriceToMoneyData(paymentDetails?.response?.payNow?.total, currency);
|
|
73
79
|
const payLater = convertMultiCurrencyPriceToMoneyData(paymentDetails?.response?.payLater?.total, currency);
|
|
80
|
+
// Get priceText from first line item (single service mode)
|
|
81
|
+
const additionalInfoList = paymentDetails?.additionalInfo?.lineItems || [];
|
|
82
|
+
const firstLineItemInfo = additionalInfoList[0];
|
|
83
|
+
const priceText = firstLineItemInfo?.priceText || null;
|
|
84
|
+
const hasPriceText = !!priceText;
|
|
85
|
+
const isFree = total !== null && total.amount === 0 && !hasPriceText;
|
|
86
|
+
// Computed flags
|
|
87
|
+
const hasTax = tax !== null && tax.amount > 0;
|
|
88
|
+
const hasDiscount = discount !== null && discount.amount > 0;
|
|
89
|
+
const isDeposit = payNow !== null && total !== null && payNow.amount < total.amount;
|
|
74
90
|
return props.children({
|
|
75
91
|
subtotal,
|
|
76
92
|
total,
|
|
@@ -78,6 +94,12 @@ export function Data(props) {
|
|
|
78
94
|
discount,
|
|
79
95
|
payNow,
|
|
80
96
|
payLater,
|
|
97
|
+
priceText,
|
|
98
|
+
hasPriceText,
|
|
99
|
+
isFree,
|
|
100
|
+
hasTax,
|
|
101
|
+
hasDiscount,
|
|
102
|
+
isDeposit,
|
|
81
103
|
currency,
|
|
82
104
|
isLoading,
|
|
83
105
|
error,
|
|
@@ -134,3 +156,79 @@ export function LineItems(props) {
|
|
|
134
156
|
error,
|
|
135
157
|
});
|
|
136
158
|
}
|
|
159
|
+
const LineItemContext = React.createContext(null);
|
|
160
|
+
/**
|
|
161
|
+
* Hook to access the current LineItem from context.
|
|
162
|
+
* Must be used within LineItemProvider.
|
|
163
|
+
*
|
|
164
|
+
* @throws Error if used outside of LineItemProvider context
|
|
165
|
+
*/
|
|
166
|
+
export function useLineItemContext() {
|
|
167
|
+
const context = React.useContext(LineItemContext);
|
|
168
|
+
if (!context) {
|
|
169
|
+
throw new Error('LineItem components must be used within LineItemProvider');
|
|
170
|
+
}
|
|
171
|
+
return context;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Provider component used by repeaters to provide LineItem context.
|
|
175
|
+
* Can be used by core consumers to create their own repeater.
|
|
176
|
+
*
|
|
177
|
+
* @component
|
|
178
|
+
* @example
|
|
179
|
+
* ```tsx
|
|
180
|
+
* {lineItems.map((item) => (
|
|
181
|
+
* <LineItemProvider key={item.id} lineItem={item} currency={currency}>
|
|
182
|
+
* {children}
|
|
183
|
+
* </LineItemProvider>
|
|
184
|
+
* ))}
|
|
185
|
+
* ```
|
|
186
|
+
*/
|
|
187
|
+
export function LineItemProvider(props) {
|
|
188
|
+
const { children, lineItem, currency } = props;
|
|
189
|
+
const contextValue = {
|
|
190
|
+
lineItem,
|
|
191
|
+
currency,
|
|
192
|
+
};
|
|
193
|
+
return (_jsx(LineItemContext.Provider, { value: contextValue, children: children }));
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Core component that provides access to line item info via render props.
|
|
197
|
+
* Must be used within LineItemProvider.
|
|
198
|
+
*
|
|
199
|
+
* @component
|
|
200
|
+
* @example
|
|
201
|
+
* ```tsx
|
|
202
|
+
* <LineItemInfo>
|
|
203
|
+
* {({ totalPrice, priceText, lineItem }) => (
|
|
204
|
+
* <div>
|
|
205
|
+
* {priceText ? <span>{priceText}</span> : <Money money={totalPrice} />}
|
|
206
|
+
* </div>
|
|
207
|
+
* )}
|
|
208
|
+
* </LineItemInfo>
|
|
209
|
+
* ```
|
|
210
|
+
*/
|
|
211
|
+
export function LineItemInfo(props) {
|
|
212
|
+
const { lineItem, currency } = useLineItemContext();
|
|
213
|
+
// Computed flags
|
|
214
|
+
const hasPriceText = !!lineItem.priceText;
|
|
215
|
+
const isFree = lineItem.totalPrice !== null &&
|
|
216
|
+
lineItem.totalPrice.amount === 0 &&
|
|
217
|
+
!hasPriceText;
|
|
218
|
+
const hasDiscount = lineItem.discount !== null && lineItem.discount.amount > 0;
|
|
219
|
+
const hasDeposit = lineItem.deposit !== null && lineItem.deposit.amount > 0;
|
|
220
|
+
return props.children({
|
|
221
|
+
lineItem,
|
|
222
|
+
currency,
|
|
223
|
+
totalPrice: lineItem.totalPrice,
|
|
224
|
+
subtotal: lineItem.subtotal,
|
|
225
|
+
tax: lineItem.tax,
|
|
226
|
+
discount: lineItem.discount,
|
|
227
|
+
deposit: lineItem.deposit,
|
|
228
|
+
priceText: lineItem.priceText,
|
|
229
|
+
hasPriceText,
|
|
230
|
+
isFree,
|
|
231
|
+
hasDiscount,
|
|
232
|
+
hasDeposit,
|
|
233
|
+
});
|
|
234
|
+
}
|
|
@@ -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';
|
package/dist/services/index.d.ts
CHANGED
|
@@ -8,6 +8,6 @@ export { TimeSlotListService, TimeSlotListServiceDefinition, TimeSlotService, Ti
|
|
|
8
8
|
export { ServiceListService, ServiceListServiceDefinition, type ServiceListServiceAPI, type ServiceListServiceConfig, type ServiceListFilters, type ServiceListActions, type QueryOptions, loadServiceListServiceInitialData, type SuccessServiceListServiceConfigResult, type ErrorServiceListServiceConfigResult, } from './service-list/service-list.js';
|
|
9
9
|
export { executeBookAction, canBook, buildBookingRequest, buildCheckoutRequest, type CanBookParams, type BookResult, type BookingError, type BookActionParams, type BookChildProps, type BookProps, type BuildCheckoutParams, } from './booking/book-action/index.js';
|
|
10
10
|
export { BookingFormService, BookingFormServiceDefinition, type BookingFormServiceAPI, type BookingFormServiceConfig, type BookingFormServiceInternalAPI, type ValidationResult, } from './booking-form/booking-form.js';
|
|
11
|
-
export { PaymentService, PaymentServiceDefinition, type PaymentServiceAPI, type PaymentServiceConfig, type PaymentDetails, type
|
|
11
|
+
export { PaymentService, PaymentServiceDefinition, type PaymentServiceAPI, type PaymentServiceConfig, type PaymentDetails, type PricingServiceSelection, type LineItemAdditionalInfo, loadPaymentConfig, type SuccessPaymentConfigResult, type ErrorPaymentConfigResult, } from './payment/payment.js';
|
|
12
12
|
export { LocationListService, LocationListServiceDefinition, LocationType, loadLocationListServiceInitialData, locationListServiceBinding, type LocationListServiceAPI, type LocationListServiceConfig, type LocationListActions, type LocationData, type DisplayLocation, type LoadLocationListServiceResult, } from './location-list/location-list.js';
|
|
13
13
|
export { StaffMemberListService, StaffMemberListServiceDefinition, loadStaffMemberListServiceInitialData, staffMemberListServiceBinding, type StaffMemberListServiceAPI, type StaffMemberListServiceConfig, type StaffMemberListActions, type StaffMemberData, type LoadStaffMemberListServiceResult, } from './staff-member-list/staff-member-list.js';
|