@wix/headless-bookings 0.0.30 → 0.0.32
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/core/payment/Payment.d.ts +193 -0
- package/cjs/dist/react/core/payment/Payment.js +202 -0
- package/cjs/dist/react/index.d.ts +2 -0
- package/cjs/dist/react/index.js +2 -0
- package/cjs/dist/react/payment/Payment.d.ts +342 -0
- package/cjs/dist/react/payment/Payment.js +294 -0
- package/cjs/dist/react/payment/PaymentLineItem.d.ts +144 -0
- package/cjs/dist/react/payment/PaymentLineItem.js +141 -0
- package/cjs/dist/react/time-slot-list/TimeSlot.d.ts +23 -11
- package/cjs/dist/react/time-slot-list/TimeSlot.js +34 -16
- package/cjs/dist/react/time-slot-list/TimeSlotList.d.ts +6 -0
- package/cjs/dist/react/time-slot-list/TimeSlotList.js +23 -5
- package/cjs/dist/services/index.d.ts +1 -0
- package/cjs/dist/services/index.js +1 -0
- package/cjs/dist/services/payment/payment.d.ts +32 -0
- package/cjs/dist/services/payment/payment.def.d.ts +66 -0
- package/cjs/dist/services/payment/payment.def.js +9 -0
- package/cjs/dist/services/payment/payment.js +167 -0
- package/cjs/dist/utils/money.d.ts +11 -0
- package/cjs/dist/utils/money.js +16 -0
- package/dist/react/core/payment/Payment.d.ts +193 -0
- package/dist/react/core/payment/Payment.js +202 -0
- package/dist/react/index.d.ts +2 -0
- package/dist/react/index.js +2 -0
- package/dist/react/payment/Payment.d.ts +342 -0
- package/dist/react/payment/Payment.js +294 -0
- package/dist/react/payment/PaymentLineItem.d.ts +144 -0
- package/dist/react/payment/PaymentLineItem.js +141 -0
- package/dist/react/time-slot-list/TimeSlot.d.ts +23 -11
- package/dist/react/time-slot-list/TimeSlot.js +34 -16
- package/dist/react/time-slot-list/TimeSlotList.d.ts +6 -0
- package/dist/react/time-slot-list/TimeSlotList.js +23 -5
- package/dist/services/index.d.ts +1 -0
- package/dist/services/index.js +1 -0
- package/dist/services/payment/payment.d.ts +32 -0
- package/dist/services/payment/payment.def.d.ts +66 -0
- package/dist/services/payment/payment.def.js +9 -0
- package/dist/services/payment/payment.js +167 -0
- package/dist/utils/money.d.ts +11 -0
- package/dist/utils/money.js +16 -0
- package/package.json +2 -2
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Payment - High-level component for displaying payment information
|
|
3
|
+
* Provides components for displaying payment summary, totals, and line items
|
|
4
|
+
*/
|
|
5
|
+
import React from 'react';
|
|
6
|
+
import { AsChildChildren } from '@wix/headless-utils/react';
|
|
7
|
+
import { MoneyData } from '@wix/headless-components/react';
|
|
8
|
+
import type { PaymentServiceConfig, SlotService } from '../../services/payment/payment.js';
|
|
9
|
+
import type { CombinedLineItem } from '../core/payment/Payment.js';
|
|
10
|
+
/**
|
|
11
|
+
* Props for Payment.Root component
|
|
12
|
+
*/
|
|
13
|
+
export interface RootProps {
|
|
14
|
+
children?: React.ReactNode | ((props: {
|
|
15
|
+
isLoading: boolean;
|
|
16
|
+
hasError: boolean;
|
|
17
|
+
}) => React.ReactNode);
|
|
18
|
+
/** Service config for SSR (pre-fetched paymentDetails) */
|
|
19
|
+
paymentServiceConfig?: PaymentServiceConfig;
|
|
20
|
+
/** Slot services for lazy loading (triggers API call) */
|
|
21
|
+
slotServices?: SlotService[];
|
|
22
|
+
/** Number of participants for lazy loading */
|
|
23
|
+
numberOfParticipants?: number;
|
|
24
|
+
asChild?: boolean;
|
|
25
|
+
className?: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Root component that provides payment context to the entire app.
|
|
29
|
+
* Supports 3 modes:
|
|
30
|
+
* 1. SSR: paymentServiceConfig.paymentDetails - pre-fetched data
|
|
31
|
+
* 2. Lazy loading: slotServices + numberOfParticipants props - calls API via useEffect
|
|
32
|
+
* 3. Reactive: no config/props - reads from BookingService signals
|
|
33
|
+
*
|
|
34
|
+
* @order 1
|
|
35
|
+
* @component
|
|
36
|
+
* @example
|
|
37
|
+
* ```tsx
|
|
38
|
+
* import { Payment, PaymentLineItem } from '@wix/bookings/components';
|
|
39
|
+
*
|
|
40
|
+
* // SSR mode
|
|
41
|
+
* function PaymentPage({ paymentDetails }) {
|
|
42
|
+
* return (
|
|
43
|
+
* <Payment.Root paymentServiceConfig={{ paymentDetails }}>
|
|
44
|
+
* <Payment.Summary />
|
|
45
|
+
* </Payment.Root>
|
|
46
|
+
* );
|
|
47
|
+
* }
|
|
48
|
+
*
|
|
49
|
+
* // Lazy loading mode
|
|
50
|
+
* function LazyPayment({ slotServices }) {
|
|
51
|
+
* return (
|
|
52
|
+
* <Payment.Root slotServices={slotServices} numberOfParticipants={2}>
|
|
53
|
+
* {({ isLoading }) => isLoading ? <div>Loading...</div> : <Payment.Summary />}
|
|
54
|
+
* </Payment.Root>
|
|
55
|
+
* );
|
|
56
|
+
* }
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
export declare const Root: React.ForwardRefExoticComponent<RootProps & React.RefAttributes<HTMLElement>>;
|
|
60
|
+
/**
|
|
61
|
+
* Props for Payment.Summary component
|
|
62
|
+
*/
|
|
63
|
+
export interface SummaryProps {
|
|
64
|
+
asChild?: boolean;
|
|
65
|
+
children?: AsChildChildren<{
|
|
66
|
+
subtotal: MoneyData | null;
|
|
67
|
+
total: MoneyData | null;
|
|
68
|
+
currency: string;
|
|
69
|
+
tax: MoneyData | null;
|
|
70
|
+
hasTax: boolean;
|
|
71
|
+
discount: MoneyData | null;
|
|
72
|
+
hasDiscount: boolean;
|
|
73
|
+
payNow: MoneyData | null;
|
|
74
|
+
payLater: MoneyData | null;
|
|
75
|
+
isDeposit: boolean;
|
|
76
|
+
}>;
|
|
77
|
+
className?: string;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Displays the payment summary with totals.
|
|
81
|
+
* Uses data-attributes for conditional visibility via CSS.
|
|
82
|
+
*
|
|
83
|
+
* @component
|
|
84
|
+
* @example
|
|
85
|
+
* ```tsx
|
|
86
|
+
* // Default usage - renders subtotal, tax, discount, total
|
|
87
|
+
* <Payment.Summary className="space-y-2" />
|
|
88
|
+
*
|
|
89
|
+
* // Custom rendering with full summary data
|
|
90
|
+
* <Payment.Summary asChild>
|
|
91
|
+
* {({ subtotal, tax, hasTax, discount, hasDiscount, total, payNow, isDeposit }) => (
|
|
92
|
+
* <div>
|
|
93
|
+
* <div>Subtotal: <Money money={subtotal} /></div>
|
|
94
|
+
* <div data-has-tax={hasTax}>Tax: <Money money={tax} /></div>
|
|
95
|
+
* <div data-has-discount={hasDiscount}>Discount: <Money money={discount} /></div>
|
|
96
|
+
* <div>Total: <Money money={total} /></div>
|
|
97
|
+
* <div data-has-deposit={isDeposit}>Pay Now: <Money money={payNow} /></div>
|
|
98
|
+
* </div>
|
|
99
|
+
* )}
|
|
100
|
+
* </Payment.Summary>
|
|
101
|
+
* ```
|
|
102
|
+
*/
|
|
103
|
+
export declare const Summary: React.ForwardRefExoticComponent<SummaryProps & React.RefAttributes<HTMLElement>>;
|
|
104
|
+
/**
|
|
105
|
+
* Props for Payment.Subtotal component
|
|
106
|
+
*/
|
|
107
|
+
export interface SubtotalProps {
|
|
108
|
+
asChild?: boolean;
|
|
109
|
+
children?: AsChildChildren<{
|
|
110
|
+
subtotal: MoneyData | null;
|
|
111
|
+
}>;
|
|
112
|
+
className?: string;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Displays the payment subtotal.
|
|
116
|
+
*
|
|
117
|
+
* @component
|
|
118
|
+
* @example
|
|
119
|
+
* ```tsx
|
|
120
|
+
* <Payment.Subtotal className="text-lg" />
|
|
121
|
+
* ```
|
|
122
|
+
*/
|
|
123
|
+
export declare const Subtotal: React.ForwardRefExoticComponent<SubtotalProps & React.RefAttributes<HTMLElement>>;
|
|
124
|
+
/**
|
|
125
|
+
* Props for Payment.Tax component
|
|
126
|
+
*/
|
|
127
|
+
export interface TaxProps {
|
|
128
|
+
asChild?: boolean;
|
|
129
|
+
children?: AsChildChildren<{
|
|
130
|
+
tax: MoneyData | null;
|
|
131
|
+
hasTax: boolean;
|
|
132
|
+
}>;
|
|
133
|
+
className?: string;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Displays the payment tax.
|
|
137
|
+
* Uses data-has-tax attribute for conditional visibility.
|
|
138
|
+
*
|
|
139
|
+
* @component
|
|
140
|
+
* @example
|
|
141
|
+
* ```tsx
|
|
142
|
+
* <Payment.Tax className="text-secondary-foreground" />
|
|
143
|
+
* ```
|
|
144
|
+
*/
|
|
145
|
+
export declare const Tax: React.ForwardRefExoticComponent<TaxProps & React.RefAttributes<HTMLElement>>;
|
|
146
|
+
/**
|
|
147
|
+
* Props for Payment.Discount component
|
|
148
|
+
*/
|
|
149
|
+
export interface DiscountProps {
|
|
150
|
+
asChild?: boolean;
|
|
151
|
+
children?: AsChildChildren<{
|
|
152
|
+
discount: MoneyData | null;
|
|
153
|
+
hasDiscount: boolean;
|
|
154
|
+
}>;
|
|
155
|
+
className?: string;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Displays the payment discount.
|
|
159
|
+
* Uses data-has-discount attribute for conditional visibility.
|
|
160
|
+
*
|
|
161
|
+
* @component
|
|
162
|
+
* @example
|
|
163
|
+
* ```tsx
|
|
164
|
+
* <Payment.Discount className="text-green-500" />
|
|
165
|
+
* ```
|
|
166
|
+
*/
|
|
167
|
+
export declare const Discount: React.ForwardRefExoticComponent<DiscountProps & React.RefAttributes<HTMLElement>>;
|
|
168
|
+
/**
|
|
169
|
+
* Props for Payment.Total component
|
|
170
|
+
*/
|
|
171
|
+
export interface TotalProps {
|
|
172
|
+
asChild?: boolean;
|
|
173
|
+
children?: AsChildChildren<{
|
|
174
|
+
total: MoneyData | null;
|
|
175
|
+
}>;
|
|
176
|
+
className?: string;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Displays the payment total.
|
|
180
|
+
*
|
|
181
|
+
* @component
|
|
182
|
+
* @example
|
|
183
|
+
* ```tsx
|
|
184
|
+
* <Payment.Total className="text-2xl font-bold" />
|
|
185
|
+
* ```
|
|
186
|
+
*/
|
|
187
|
+
export declare const Total: React.ForwardRefExoticComponent<TotalProps & React.RefAttributes<HTMLElement>>;
|
|
188
|
+
/**
|
|
189
|
+
* Props for Payment.PayNow component
|
|
190
|
+
*/
|
|
191
|
+
export interface PayNowProps {
|
|
192
|
+
asChild?: boolean;
|
|
193
|
+
children?: AsChildChildren<{
|
|
194
|
+
payNow: MoneyData | null;
|
|
195
|
+
isDeposit: boolean;
|
|
196
|
+
}>;
|
|
197
|
+
className?: string;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Displays the pay now amount (for deposit scenarios).
|
|
201
|
+
* Uses data-has-deposit attribute for conditional visibility.
|
|
202
|
+
*
|
|
203
|
+
* @component
|
|
204
|
+
* @example
|
|
205
|
+
* ```tsx
|
|
206
|
+
* <Payment.PayNow className="font-semibold" />
|
|
207
|
+
* ```
|
|
208
|
+
*/
|
|
209
|
+
export declare const PayNow: React.ForwardRefExoticComponent<PayNowProps & React.RefAttributes<HTMLElement>>;
|
|
210
|
+
/**
|
|
211
|
+
* Props for Payment.PayLater component
|
|
212
|
+
*/
|
|
213
|
+
export interface PayLaterProps {
|
|
214
|
+
asChild?: boolean;
|
|
215
|
+
children?: AsChildChildren<{
|
|
216
|
+
payLater: MoneyData | null;
|
|
217
|
+
isDeposit: boolean;
|
|
218
|
+
}>;
|
|
219
|
+
className?: string;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Displays the pay later amount (for deposit scenarios).
|
|
223
|
+
* Uses data-has-deposit attribute for conditional visibility.
|
|
224
|
+
*
|
|
225
|
+
* @component
|
|
226
|
+
* @example
|
|
227
|
+
* ```tsx
|
|
228
|
+
* <Payment.PayLater className="text-secondary-foreground" />
|
|
229
|
+
* ```
|
|
230
|
+
*/
|
|
231
|
+
export declare const PayLater: React.ForwardRefExoticComponent<PayLaterProps & React.RefAttributes<HTMLElement>>;
|
|
232
|
+
/**
|
|
233
|
+
* Type for line item with required id field for GenericList
|
|
234
|
+
*/
|
|
235
|
+
type LineItemType = CombinedLineItem & {
|
|
236
|
+
id: string;
|
|
237
|
+
};
|
|
238
|
+
/**
|
|
239
|
+
* Props for Payment.LineItems component (Container Level)
|
|
240
|
+
*/
|
|
241
|
+
export interface LineItemsProps {
|
|
242
|
+
asChild?: boolean;
|
|
243
|
+
children?: React.ReactNode;
|
|
244
|
+
className?: string;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Container component for line items.
|
|
248
|
+
* Follows the 3-level List/Options/Repeater pattern.
|
|
249
|
+
* Provides context and doesn't render when there are no line items.
|
|
250
|
+
*
|
|
251
|
+
* @component
|
|
252
|
+
* @example
|
|
253
|
+
* ```tsx
|
|
254
|
+
* <Payment.LineItems>
|
|
255
|
+
* <Payment.LineItemsList>
|
|
256
|
+
* <Payment.LineItemRepeater>
|
|
257
|
+
* <LineItem.Price />
|
|
258
|
+
* </Payment.LineItemRepeater>
|
|
259
|
+
* </Payment.LineItemsList>
|
|
260
|
+
* </Payment.LineItems>
|
|
261
|
+
*
|
|
262
|
+
* // With asChild pattern for custom container
|
|
263
|
+
* <Payment.LineItems asChild>
|
|
264
|
+
* {({ lineItems, currency }) => (
|
|
265
|
+
* <div className="border rounded p-4">
|
|
266
|
+
* <Payment.LineItemsList>
|
|
267
|
+
* <Payment.LineItemRepeater>
|
|
268
|
+
* <LineItem.Price />
|
|
269
|
+
* </Payment.LineItemRepeater>
|
|
270
|
+
* </Payment.LineItemsList>
|
|
271
|
+
* </div>
|
|
272
|
+
* )}
|
|
273
|
+
* </Payment.LineItems>
|
|
274
|
+
* ```
|
|
275
|
+
*/
|
|
276
|
+
export declare const LineItems: React.ForwardRefExoticComponent<LineItemsProps & React.RefAttributes<HTMLElement>>;
|
|
277
|
+
/**
|
|
278
|
+
* Props for Payment.LineItemsList component
|
|
279
|
+
*/
|
|
280
|
+
export interface LineItemsListProps {
|
|
281
|
+
children?: React.ReactNode;
|
|
282
|
+
emptyState?: React.ReactNode;
|
|
283
|
+
className?: string;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* List container for line items with empty state support.
|
|
287
|
+
*
|
|
288
|
+
* @component
|
|
289
|
+
* @example
|
|
290
|
+
* ```tsx
|
|
291
|
+
* <Payment.LineItemsList emptyState={<div>No items</div>}>
|
|
292
|
+
* <Payment.LineItemRepeater />
|
|
293
|
+
* </Payment.LineItemsList>
|
|
294
|
+
* ```
|
|
295
|
+
*/
|
|
296
|
+
export declare const LineItemsList: React.ForwardRefExoticComponent<LineItemsListProps & React.RefAttributes<HTMLElement>>;
|
|
297
|
+
/**
|
|
298
|
+
* Render props for LineItemRepeater asChild pattern
|
|
299
|
+
*/
|
|
300
|
+
export interface LineItemRepeaterRenderProps {
|
|
301
|
+
items: LineItemType[];
|
|
302
|
+
itemWrapper: (props: {
|
|
303
|
+
item: LineItemType;
|
|
304
|
+
index: number;
|
|
305
|
+
children: React.ReactNode;
|
|
306
|
+
}) => React.ReactNode;
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Props for Payment.LineItemRepeater component
|
|
310
|
+
*/
|
|
311
|
+
export interface LineItemRepeaterProps {
|
|
312
|
+
children?: React.ReactNode | ((props: LineItemRepeaterRenderProps) => React.ReactNode);
|
|
313
|
+
asChild?: boolean;
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Repeater component that renders LineItem.Root for each line item.
|
|
317
|
+
* Supports asChild pattern for custom rendering.
|
|
318
|
+
*
|
|
319
|
+
* @component
|
|
320
|
+
* @example
|
|
321
|
+
* ```tsx
|
|
322
|
+
* // Standard usage
|
|
323
|
+
* <Payment.LineItemRepeater>
|
|
324
|
+
* <LineItem.Price />
|
|
325
|
+
* </Payment.LineItemRepeater>
|
|
326
|
+
*
|
|
327
|
+
* // AsChild usage with custom list
|
|
328
|
+
* <Payment.LineItemRepeater asChild>
|
|
329
|
+
* {({ items, itemWrapper }) => (
|
|
330
|
+
* <ol>
|
|
331
|
+
* {items.map((item, index) => (
|
|
332
|
+
* <li key={item.id}>
|
|
333
|
+
* {itemWrapper({ item, index, children: <LineItem.Price /> })}
|
|
334
|
+
* </li>
|
|
335
|
+
* ))}
|
|
336
|
+
* </ol>
|
|
337
|
+
* )}
|
|
338
|
+
* </Payment.LineItemRepeater>
|
|
339
|
+
* ```
|
|
340
|
+
*/
|
|
341
|
+
export declare const LineItemRepeater: React.ForwardRefExoticComponent<LineItemRepeaterProps & React.RefAttributes<HTMLElement>>;
|
|
342
|
+
export {};
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Payment - High-level component for displaying payment information
|
|
4
|
+
* Provides components for displaying payment summary, totals, and line items
|
|
5
|
+
*/
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import * as CorePayment from '../core/payment/Payment.js';
|
|
8
|
+
import * as PaymentLineItem from './PaymentLineItem.js';
|
|
9
|
+
import { AsChildSlot } from '@wix/headless-utils/react';
|
|
10
|
+
import { Money, GenericList } from '@wix/headless-components/react';
|
|
11
|
+
var TestIds;
|
|
12
|
+
(function (TestIds) {
|
|
13
|
+
TestIds["paymentRoot"] = "payment-root";
|
|
14
|
+
TestIds["paymentSummary"] = "payment-summary";
|
|
15
|
+
TestIds["paymentSubtotal"] = "payment-subtotal";
|
|
16
|
+
TestIds["paymentTax"] = "payment-tax";
|
|
17
|
+
TestIds["paymentDiscount"] = "payment-discount";
|
|
18
|
+
TestIds["paymentTotal"] = "payment-total";
|
|
19
|
+
TestIds["paymentPayNow"] = "payment-pay-now";
|
|
20
|
+
TestIds["paymentPayLater"] = "payment-pay-later";
|
|
21
|
+
TestIds["paymentLineItems"] = "payment-line-items";
|
|
22
|
+
TestIds["paymentLineItemsList"] = "payment-line-items-list";
|
|
23
|
+
TestIds["paymentLineItemRepeater"] = "payment-line-item-repeater";
|
|
24
|
+
})(TestIds || (TestIds = {}));
|
|
25
|
+
/**
|
|
26
|
+
* Root component that provides payment context to the entire app.
|
|
27
|
+
* Supports 3 modes:
|
|
28
|
+
* 1. SSR: paymentServiceConfig.paymentDetails - pre-fetched data
|
|
29
|
+
* 2. Lazy loading: slotServices + numberOfParticipants props - calls API via useEffect
|
|
30
|
+
* 3. Reactive: no config/props - reads from BookingService signals
|
|
31
|
+
*
|
|
32
|
+
* @order 1
|
|
33
|
+
* @component
|
|
34
|
+
* @example
|
|
35
|
+
* ```tsx
|
|
36
|
+
* import { Payment, PaymentLineItem } from '@wix/bookings/components';
|
|
37
|
+
*
|
|
38
|
+
* // SSR mode
|
|
39
|
+
* function PaymentPage({ paymentDetails }) {
|
|
40
|
+
* return (
|
|
41
|
+
* <Payment.Root paymentServiceConfig={{ paymentDetails }}>
|
|
42
|
+
* <Payment.Summary />
|
|
43
|
+
* </Payment.Root>
|
|
44
|
+
* );
|
|
45
|
+
* }
|
|
46
|
+
*
|
|
47
|
+
* // Lazy loading mode
|
|
48
|
+
* function LazyPayment({ slotServices }) {
|
|
49
|
+
* return (
|
|
50
|
+
* <Payment.Root slotServices={slotServices} numberOfParticipants={2}>
|
|
51
|
+
* {({ isLoading }) => isLoading ? <div>Loading...</div> : <Payment.Summary />}
|
|
52
|
+
* </Payment.Root>
|
|
53
|
+
* );
|
|
54
|
+
* }
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
export const Root = React.forwardRef((props, ref) => {
|
|
58
|
+
const { children, paymentServiceConfig, slotServices, numberOfParticipants, asChild, className, ...attrs } = props;
|
|
59
|
+
return (_jsx(CorePayment.Root, { paymentServiceConfig: paymentServiceConfig, slotServices: slotServices, numberOfParticipants: numberOfParticipants, children: ({ isLoading, hasError }) => {
|
|
60
|
+
// Handle render function children regardless of asChild
|
|
61
|
+
const resolvedChildren = typeof children === 'function'
|
|
62
|
+
? children({ isLoading, hasError })
|
|
63
|
+
: children;
|
|
64
|
+
return (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.paymentRoot, "data-loading": isLoading, "data-has-error": hasError, customElement: resolvedChildren, customElementProps: { isLoading, hasError }, ...attrs, children: _jsx("div", { children: React.isValidElement(resolvedChildren) ? resolvedChildren : null }) }));
|
|
65
|
+
} }));
|
|
66
|
+
});
|
|
67
|
+
Root.displayName = 'Payment.Root';
|
|
68
|
+
/**
|
|
69
|
+
* Displays the payment summary with totals.
|
|
70
|
+
* Uses data-attributes for conditional visibility via CSS.
|
|
71
|
+
*
|
|
72
|
+
* @component
|
|
73
|
+
* @example
|
|
74
|
+
* ```tsx
|
|
75
|
+
* // Default usage - renders subtotal, tax, discount, total
|
|
76
|
+
* <Payment.Summary className="space-y-2" />
|
|
77
|
+
*
|
|
78
|
+
* // Custom rendering with full summary data
|
|
79
|
+
* <Payment.Summary asChild>
|
|
80
|
+
* {({ subtotal, tax, hasTax, discount, hasDiscount, total, payNow, isDeposit }) => (
|
|
81
|
+
* <div>
|
|
82
|
+
* <div>Subtotal: <Money money={subtotal} /></div>
|
|
83
|
+
* <div data-has-tax={hasTax}>Tax: <Money money={tax} /></div>
|
|
84
|
+
* <div data-has-discount={hasDiscount}>Discount: <Money money={discount} /></div>
|
|
85
|
+
* <div>Total: <Money money={total} /></div>
|
|
86
|
+
* <div data-has-deposit={isDeposit}>Pay Now: <Money money={payNow} /></div>
|
|
87
|
+
* </div>
|
|
88
|
+
* )}
|
|
89
|
+
* </Payment.Summary>
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
export const Summary = React.forwardRef((props, ref) => {
|
|
93
|
+
const { asChild, children, className } = props;
|
|
94
|
+
return (_jsx(CorePayment.Summary, { children: (summaryData) => {
|
|
95
|
+
const { subtotal, total, tax, discount, payNow, payLater, isDeposit, } = summaryData;
|
|
96
|
+
// Default rendering
|
|
97
|
+
const renderDefaultSummary = () => (_jsxs("div", { className: className, "data-testid": TestIds.paymentSummary, children: [_jsx("div", { "data-testid": TestIds.paymentSubtotal, children: subtotal && _jsx(Money, { money: subtotal }) }), _jsx("div", { "data-testid": TestIds.paymentTax, "data-has-tax": tax !== null && tax.amount > 0, children: tax && _jsx(Money, { money: tax }) }), _jsx("div", { "data-testid": TestIds.paymentDiscount, "data-has-discount": discount !== null && discount.amount > 0, children: discount && _jsx(Money, { money: discount }) }), _jsx("div", { "data-testid": TestIds.paymentTotal, children: total && _jsx(Money, { money: total }) }), _jsx("div", { "data-testid": TestIds.paymentPayNow, "data-has-deposit": isDeposit, children: payNow && _jsx(Money, { money: payNow }) }), _jsx("div", { "data-testid": TestIds.paymentPayLater, "data-has-deposit": isDeposit, children: payLater && _jsx(Money, { money: payLater }) })] }));
|
|
98
|
+
return (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.paymentSummary, "data-has-tax": tax !== null && tax.amount > 0, "data-has-discount": discount !== null && discount.amount > 0, "data-has-deposit": isDeposit, customElement: children, customElementProps: summaryData, children: renderDefaultSummary() }));
|
|
99
|
+
} }));
|
|
100
|
+
});
|
|
101
|
+
Summary.displayName = 'Payment.Summary';
|
|
102
|
+
/**
|
|
103
|
+
* Displays the payment subtotal.
|
|
104
|
+
*
|
|
105
|
+
* @component
|
|
106
|
+
* @example
|
|
107
|
+
* ```tsx
|
|
108
|
+
* <Payment.Subtotal className="text-lg" />
|
|
109
|
+
* ```
|
|
110
|
+
*/
|
|
111
|
+
export const Subtotal = React.forwardRef((props, ref) => {
|
|
112
|
+
const { asChild, children, className } = props;
|
|
113
|
+
return (_jsx(CorePayment.Summary, { children: ({ subtotal }) => (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.paymentSubtotal, customElement: children, customElementProps: { subtotal }, children: subtotal ? _jsx(Money, { money: subtotal }) : null })) }));
|
|
114
|
+
});
|
|
115
|
+
Subtotal.displayName = 'Payment.Subtotal';
|
|
116
|
+
/**
|
|
117
|
+
* Displays the payment tax.
|
|
118
|
+
* Uses data-has-tax attribute for conditional visibility.
|
|
119
|
+
*
|
|
120
|
+
* @component
|
|
121
|
+
* @example
|
|
122
|
+
* ```tsx
|
|
123
|
+
* <Payment.Tax className="text-secondary-foreground" />
|
|
124
|
+
* ```
|
|
125
|
+
*/
|
|
126
|
+
export const Tax = React.forwardRef((props, ref) => {
|
|
127
|
+
const { asChild, children, className } = props;
|
|
128
|
+
return (_jsx(CorePayment.Summary, { children: ({ tax, hasTax }) => (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.paymentTax, "data-has-tax": hasTax, customElement: children, customElementProps: { tax, hasTax }, children: tax ? _jsx(Money, { money: tax }) : null })) }));
|
|
129
|
+
});
|
|
130
|
+
Tax.displayName = 'Payment.Tax';
|
|
131
|
+
/**
|
|
132
|
+
* Displays the payment discount.
|
|
133
|
+
* Uses data-has-discount attribute for conditional visibility.
|
|
134
|
+
*
|
|
135
|
+
* @component
|
|
136
|
+
* @example
|
|
137
|
+
* ```tsx
|
|
138
|
+
* <Payment.Discount className="text-green-500" />
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
141
|
+
export const Discount = React.forwardRef((props, ref) => {
|
|
142
|
+
const { asChild, children, className } = props;
|
|
143
|
+
return (_jsx(CorePayment.Summary, { children: ({ discount, hasDiscount }) => (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.paymentDiscount, "data-has-discount": hasDiscount, customElement: children, customElementProps: { discount, hasDiscount }, children: discount ? _jsx(Money, { money: discount }) : null })) }));
|
|
144
|
+
});
|
|
145
|
+
Discount.displayName = 'Payment.Discount';
|
|
146
|
+
/**
|
|
147
|
+
* Displays the payment total.
|
|
148
|
+
*
|
|
149
|
+
* @component
|
|
150
|
+
* @example
|
|
151
|
+
* ```tsx
|
|
152
|
+
* <Payment.Total className="text-2xl font-bold" />
|
|
153
|
+
* ```
|
|
154
|
+
*/
|
|
155
|
+
export const Total = React.forwardRef((props, ref) => {
|
|
156
|
+
const { asChild, children, className } = props;
|
|
157
|
+
return (_jsx(CorePayment.Summary, { children: ({ total }) => (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.paymentTotal, customElement: children, customElementProps: { total }, children: total ? _jsx(Money, { money: total }) : null })) }));
|
|
158
|
+
});
|
|
159
|
+
Total.displayName = 'Payment.Total';
|
|
160
|
+
/**
|
|
161
|
+
* Displays the pay now amount (for deposit scenarios).
|
|
162
|
+
* Uses data-has-deposit attribute for conditional visibility.
|
|
163
|
+
*
|
|
164
|
+
* @component
|
|
165
|
+
* @example
|
|
166
|
+
* ```tsx
|
|
167
|
+
* <Payment.PayNow className="font-semibold" />
|
|
168
|
+
* ```
|
|
169
|
+
*/
|
|
170
|
+
export const PayNow = React.forwardRef((props, ref) => {
|
|
171
|
+
const { asChild, children, className } = props;
|
|
172
|
+
return (_jsx(CorePayment.Summary, { children: ({ payNow, isDeposit }) => (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.paymentPayNow, "data-has-deposit": isDeposit, customElement: children, customElementProps: { payNow, isDeposit }, children: payNow ? _jsx(Money, { money: payNow }) : null })) }));
|
|
173
|
+
});
|
|
174
|
+
PayNow.displayName = 'Payment.PayNow';
|
|
175
|
+
/**
|
|
176
|
+
* Displays the pay later amount (for deposit scenarios).
|
|
177
|
+
* Uses data-has-deposit attribute for conditional visibility.
|
|
178
|
+
*
|
|
179
|
+
* @component
|
|
180
|
+
* @example
|
|
181
|
+
* ```tsx
|
|
182
|
+
* <Payment.PayLater className="text-secondary-foreground" />
|
|
183
|
+
* ```
|
|
184
|
+
*/
|
|
185
|
+
export const PayLater = React.forwardRef((props, ref) => {
|
|
186
|
+
const { asChild, children, className } = props;
|
|
187
|
+
return (_jsx(CorePayment.Summary, { children: ({ payLater, isDeposit }) => (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.paymentPayLater, "data-has-deposit": isDeposit, customElement: children, customElementProps: { payLater, isDeposit }, children: payLater ? _jsx(Money, { money: payLater }) : null })) }));
|
|
188
|
+
});
|
|
189
|
+
PayLater.displayName = 'Payment.PayLater';
|
|
190
|
+
/**
|
|
191
|
+
* Container component for line items.
|
|
192
|
+
* Follows the 3-level List/Options/Repeater pattern.
|
|
193
|
+
* Provides context and doesn't render when there are no line items.
|
|
194
|
+
*
|
|
195
|
+
* @component
|
|
196
|
+
* @example
|
|
197
|
+
* ```tsx
|
|
198
|
+
* <Payment.LineItems>
|
|
199
|
+
* <Payment.LineItemsList>
|
|
200
|
+
* <Payment.LineItemRepeater>
|
|
201
|
+
* <LineItem.Price />
|
|
202
|
+
* </Payment.LineItemRepeater>
|
|
203
|
+
* </Payment.LineItemsList>
|
|
204
|
+
* </Payment.LineItems>
|
|
205
|
+
*
|
|
206
|
+
* // With asChild pattern for custom container
|
|
207
|
+
* <Payment.LineItems asChild>
|
|
208
|
+
* {({ lineItems, currency }) => (
|
|
209
|
+
* <div className="border rounded p-4">
|
|
210
|
+
* <Payment.LineItemsList>
|
|
211
|
+
* <Payment.LineItemRepeater>
|
|
212
|
+
* <LineItem.Price />
|
|
213
|
+
* </Payment.LineItemRepeater>
|
|
214
|
+
* </Payment.LineItemsList>
|
|
215
|
+
* </div>
|
|
216
|
+
* )}
|
|
217
|
+
* </Payment.LineItems>
|
|
218
|
+
* ```
|
|
219
|
+
*/
|
|
220
|
+
export const LineItems = React.forwardRef((props, ref) => {
|
|
221
|
+
const { asChild, children, className, ...attributes } = props;
|
|
222
|
+
return (_jsx(CorePayment.LineItems, { children: ({ lineItems, currency }) => {
|
|
223
|
+
if (!lineItems.length)
|
|
224
|
+
return null;
|
|
225
|
+
// Map line items to include required id field for GenericList
|
|
226
|
+
const items = lineItems.map((item, index) => ({
|
|
227
|
+
...item,
|
|
228
|
+
id: item.sdkLineItem.lineItemId || String(index),
|
|
229
|
+
}));
|
|
230
|
+
return (_jsx(GenericList.Root, { items: items, children: _jsx(LineItemsContext.Provider, { value: { currency }, children: _jsx(AsChildSlot, { ...attributes, ref: ref, asChild: asChild, className: className, "data-testid": TestIds.paymentLineItems, customElement: children, customElementProps: { lineItems, currency }, children: _jsx("div", { children: React.isValidElement(children) ? children : null }) }) }) }));
|
|
231
|
+
} }));
|
|
232
|
+
});
|
|
233
|
+
LineItems.displayName = 'Payment.LineItems';
|
|
234
|
+
// Context for line items currency
|
|
235
|
+
const LineItemsContext = React.createContext(null);
|
|
236
|
+
function useLineItemsContext() {
|
|
237
|
+
const context = React.useContext(LineItemsContext);
|
|
238
|
+
if (!context) {
|
|
239
|
+
throw new Error('useLineItemsContext must be used within a Payment.LineItems component');
|
|
240
|
+
}
|
|
241
|
+
return context;
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* List container for line items with empty state support.
|
|
245
|
+
*
|
|
246
|
+
* @component
|
|
247
|
+
* @example
|
|
248
|
+
* ```tsx
|
|
249
|
+
* <Payment.LineItemsList emptyState={<div>No items</div>}>
|
|
250
|
+
* <Payment.LineItemRepeater />
|
|
251
|
+
* </Payment.LineItemsList>
|
|
252
|
+
* ```
|
|
253
|
+
*/
|
|
254
|
+
export const LineItemsList = React.forwardRef((props, ref) => {
|
|
255
|
+
const { children, emptyState, className, ...otherProps } = props;
|
|
256
|
+
return (_jsx(GenericList.Items, { ref: ref, emptyState: emptyState, className: className, "data-testid": TestIds.paymentLineItemsList, ...otherProps, children: children }));
|
|
257
|
+
});
|
|
258
|
+
LineItemsList.displayName = 'Payment.LineItemsList';
|
|
259
|
+
/**
|
|
260
|
+
* Repeater component that renders LineItem.Root for each line item.
|
|
261
|
+
* Supports asChild pattern for custom rendering.
|
|
262
|
+
*
|
|
263
|
+
* @component
|
|
264
|
+
* @example
|
|
265
|
+
* ```tsx
|
|
266
|
+
* // Standard usage
|
|
267
|
+
* <Payment.LineItemRepeater>
|
|
268
|
+
* <LineItem.Price />
|
|
269
|
+
* </Payment.LineItemRepeater>
|
|
270
|
+
*
|
|
271
|
+
* // AsChild usage with custom list
|
|
272
|
+
* <Payment.LineItemRepeater asChild>
|
|
273
|
+
* {({ items, itemWrapper }) => (
|
|
274
|
+
* <ol>
|
|
275
|
+
* {items.map((item, index) => (
|
|
276
|
+
* <li key={item.id}>
|
|
277
|
+
* {itemWrapper({ item, index, children: <LineItem.Price /> })}
|
|
278
|
+
* </li>
|
|
279
|
+
* ))}
|
|
280
|
+
* </ol>
|
|
281
|
+
* )}
|
|
282
|
+
* </Payment.LineItemRepeater>
|
|
283
|
+
* ```
|
|
284
|
+
*/
|
|
285
|
+
export const LineItemRepeater = React.forwardRef((props, ref) => {
|
|
286
|
+
const { children, asChild } = props;
|
|
287
|
+
const { currency } = useLineItemsContext();
|
|
288
|
+
// Custom itemWrapper that renders LineItem.Root for each line item
|
|
289
|
+
const lineItemWrapper = ({ item, children: itemChildren, }) => {
|
|
290
|
+
return (_jsx(PaymentLineItem.Root, { lineItem: item, currency: currency, "data-testid": TestIds.paymentLineItemRepeater, children: itemChildren || undefined }, item.id));
|
|
291
|
+
};
|
|
292
|
+
return (_jsx(GenericList.Repeater, { ref: ref, itemWrapper: lineItemWrapper, asChild: asChild, children: children }));
|
|
293
|
+
});
|
|
294
|
+
LineItemRepeater.displayName = 'Payment.LineItemRepeater';
|