@wix/headless-bookings 0.0.39 → 0.0.41

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.
@@ -6,7 +6,7 @@ import React from 'react';
6
6
  import { AsChildChildren } from '@wix/headless-utils/react';
7
7
  import { MoneyData } from '@wix/headless-components/react';
8
8
  import type { PaymentServiceConfig, SlotService } from '../../services/payment/payment.js';
9
- import type { CombinedLineItem } from '../core/payment/Payment.js';
9
+ import type { LineItem as CoreLineItem } from '../core/payment/Payment.js';
10
10
  /**
11
11
  * Props for Payment.Root component
12
12
  */
@@ -35,13 +35,13 @@ export interface RootProps {
35
35
  * @component
36
36
  * @example
37
37
  * ```tsx
38
- * import { Payment, PaymentLineItem } from '@wix/bookings/components';
38
+ * import { Payment } from '@wix/bookings/components';
39
39
  *
40
40
  * // SSR mode
41
41
  * function PaymentPage({ paymentDetails }) {
42
42
  * return (
43
43
  * <Payment.Root paymentServiceConfig={{ paymentDetails }}>
44
- * <Payment.Summary />
44
+ * <Payment.Total />
45
45
  * </Payment.Root>
46
46
  * );
47
47
  * }
@@ -50,57 +50,13 @@ export interface RootProps {
50
50
  * function LazyPayment({ slotServices }) {
51
51
  * return (
52
52
  * <Payment.Root slotServices={slotServices} numberOfParticipants={2}>
53
- * {({ isLoading }) => isLoading ? <div>Loading...</div> : <Payment.Summary />}
53
+ * {({ isLoading }) => isLoading ? <div>Loading...</div> : <Payment.Total />}
54
54
  * </Payment.Root>
55
55
  * );
56
56
  * }
57
57
  * ```
58
58
  */
59
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
60
  /**
105
61
  * Props for Payment.Subtotal component
106
62
  */
@@ -128,7 +84,6 @@ export interface TaxProps {
128
84
  asChild?: boolean;
129
85
  children?: AsChildChildren<{
130
86
  tax: MoneyData | null;
131
- hasTax: boolean;
132
87
  }>;
133
88
  className?: string;
134
89
  }
@@ -150,7 +105,6 @@ export interface DiscountProps {
150
105
  asChild?: boolean;
151
106
  children?: AsChildChildren<{
152
107
  discount: MoneyData | null;
153
- hasDiscount: boolean;
154
108
  }>;
155
109
  className?: string;
156
110
  }
@@ -192,7 +146,6 @@ export interface PayNowProps {
192
146
  asChild?: boolean;
193
147
  children?: AsChildChildren<{
194
148
  payNow: MoneyData | null;
195
- isDeposit: boolean;
196
149
  }>;
197
150
  className?: string;
198
151
  }
@@ -214,7 +167,6 @@ export interface PayLaterProps {
214
167
  asChild?: boolean;
215
168
  children?: AsChildChildren<{
216
169
  payLater: MoneyData | null;
217
- isDeposit: boolean;
218
170
  }>;
219
171
  className?: string;
220
172
  }
@@ -229,12 +181,6 @@ export interface PayLaterProps {
229
181
  * ```
230
182
  */
231
183
  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
184
  /**
239
185
  * Props for Payment.LineItems component (Container Level)
240
186
  */
@@ -246,31 +192,22 @@ export interface LineItemsProps {
246
192
  /**
247
193
  * Container component for line items.
248
194
  * Follows the 3-level List/Options/Repeater pattern.
249
- * Provides context and doesn't render when there are no line items.
195
+ * Provides context and handles loading/error states via GenericList.
250
196
  *
251
197
  * @component
252
198
  * @example
253
199
  * ```tsx
254
200
  * <Payment.LineItems>
255
- * <Payment.LineItemsList>
201
+ * <Payment.LineItemsList
202
+ * emptyState={<div>No items</div>}
203
+ * loadingState={<div>Loading...</div>}
204
+ * errorState={<div>Failed to load</div>}
205
+ * >
256
206
  * <Payment.LineItemRepeater>
257
- * <LineItem.Price />
207
+ * <Payment.LineItemPrice />
258
208
  * </Payment.LineItemRepeater>
259
209
  * </Payment.LineItemsList>
260
210
  * </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
211
  * ```
275
212
  */
276
213
  export declare const LineItems: React.ForwardRefExoticComponent<LineItemsProps & React.RefAttributes<HTMLElement>>;
@@ -279,16 +216,25 @@ export declare const LineItems: React.ForwardRefExoticComponent<LineItemsProps &
279
216
  */
280
217
  export interface LineItemsListProps {
281
218
  children?: React.ReactNode;
219
+ /** Content to display when no items are available */
282
220
  emptyState?: React.ReactNode;
221
+ /** Content to display when loading */
222
+ loadingState?: React.ReactNode;
223
+ /** Content to display when there's an error */
224
+ errorState?: React.ReactNode;
283
225
  className?: string;
284
226
  }
285
227
  /**
286
- * List container for line items with empty state support.
228
+ * List container for line items with empty/loading/error state support.
287
229
  *
288
230
  * @component
289
231
  * @example
290
232
  * ```tsx
291
- * <Payment.LineItemsList emptyState={<div>No items</div>}>
233
+ * <Payment.LineItemsList
234
+ * emptyState={<div>No items</div>}
235
+ * loadingState={<div>Loading...</div>}
236
+ * errorState={<div>Failed to load payment details</div>}
237
+ * >
292
238
  * <Payment.LineItemRepeater />
293
239
  * </Payment.LineItemsList>
294
240
  * ```
@@ -298,9 +244,9 @@ export declare const LineItemsList: React.ForwardRefExoticComponent<LineItemsLis
298
244
  * Render props for LineItemRepeater asChild pattern
299
245
  */
300
246
  export interface LineItemRepeaterRenderProps {
301
- items: LineItemType[];
247
+ items: CoreLineItem[];
302
248
  itemWrapper: (props: {
303
- item: LineItemType;
249
+ item: CoreLineItem;
304
250
  index: number;
305
251
  children: React.ReactNode;
306
252
  }) => React.ReactNode;
@@ -313,7 +259,7 @@ export interface LineItemRepeaterProps {
313
259
  asChild?: boolean;
314
260
  }
315
261
  /**
316
- * Repeater component that renders LineItem.Root for each line item.
262
+ * Repeater component that renders LineItemRoot for each line item.
317
263
  * Supports asChild pattern for custom rendering.
318
264
  *
319
265
  * @component
@@ -321,7 +267,7 @@ export interface LineItemRepeaterProps {
321
267
  * ```tsx
322
268
  * // Standard usage
323
269
  * <Payment.LineItemRepeater>
324
- * <LineItem.Price />
270
+ * <Payment.LineItemPrice />
325
271
  * </Payment.LineItemRepeater>
326
272
  *
327
273
  * // AsChild usage with custom list
@@ -330,7 +276,7 @@ export interface LineItemRepeaterProps {
330
276
  * <ol>
331
277
  * {items.map((item, index) => (
332
278
  * <li key={item.id}>
333
- * {itemWrapper({ item, index, children: <LineItem.Price /> })}
279
+ * {itemWrapper({ item, index, children: <Payment.LineItemPrice /> })}
334
280
  * </li>
335
281
  * ))}
336
282
  * </ol>
@@ -339,4 +285,95 @@ export interface LineItemRepeaterProps {
339
285
  * ```
340
286
  */
341
287
  export declare const LineItemRepeater: React.ForwardRefExoticComponent<LineItemRepeaterProps & React.RefAttributes<HTMLElement>>;
342
- export {};
288
+ /**
289
+ * Props for Payment.LineItemRoot component
290
+ */
291
+ export interface LineItemRootProps {
292
+ lineItem: CoreLineItem;
293
+ currency: string;
294
+ children?: React.ReactNode | AsChildChildren<{
295
+ lineItem: CoreLineItem;
296
+ currency: string;
297
+ }>;
298
+ asChild?: boolean;
299
+ className?: string;
300
+ 'data-testid'?: string;
301
+ }
302
+ /**
303
+ * Root component for a single line item.
304
+ * Provides context for child components.
305
+ *
306
+ * @component
307
+ * @example
308
+ * ```tsx
309
+ * <Payment.LineItemRoot lineItem={item} currency="USD">
310
+ * <Payment.LineItemPrice />
311
+ * <Payment.LineItemDiscount />
312
+ * </Payment.LineItemRoot>
313
+ * ```
314
+ */
315
+ export declare const LineItemRoot: React.ForwardRefExoticComponent<LineItemRootProps & React.RefAttributes<HTMLElement>>;
316
+ /**
317
+ * Props for Payment.LineItemPrice component
318
+ */
319
+ export interface LineItemPriceProps {
320
+ asChild?: boolean;
321
+ children?: AsChildChildren<{
322
+ totalPrice: MoneyData | null;
323
+ priceText: string | null;
324
+ }>;
325
+ className?: string;
326
+ }
327
+ /**
328
+ * Displays the line item price.
329
+ * Shows priceText for CUSTOM rate type services, otherwise shows totalPrice.
330
+ *
331
+ * @component
332
+ * @example
333
+ * ```tsx
334
+ * <Payment.LineItemPrice className="text-lg font-bold" />
335
+ * ```
336
+ */
337
+ export declare const LineItemPrice: React.ForwardRefExoticComponent<LineItemPriceProps & React.RefAttributes<HTMLElement>>;
338
+ /**
339
+ * Props for Payment.LineItemDiscount component
340
+ */
341
+ export interface LineItemDiscountProps {
342
+ asChild?: boolean;
343
+ children?: AsChildChildren<{
344
+ discount: MoneyData | null;
345
+ }>;
346
+ className?: string;
347
+ }
348
+ /**
349
+ * Displays the line item discount.
350
+ * Uses data-has-discount attribute for conditional visibility.
351
+ *
352
+ * @component
353
+ * @example
354
+ * ```tsx
355
+ * <Payment.LineItemDiscount className="text-green-500" />
356
+ * ```
357
+ */
358
+ export declare const LineItemDiscount: React.ForwardRefExoticComponent<LineItemDiscountProps & React.RefAttributes<HTMLElement>>;
359
+ /**
360
+ * Props for Payment.LineItemDeposit component
361
+ */
362
+ export interface LineItemDepositProps {
363
+ asChild?: boolean;
364
+ children?: AsChildChildren<{
365
+ deposit: MoneyData | null;
366
+ }>;
367
+ className?: string;
368
+ }
369
+ /**
370
+ * Displays the line item deposit amount.
371
+ * Uses data-has-deposit attribute for conditional visibility.
372
+ *
373
+ * @component
374
+ * @example
375
+ * ```tsx
376
+ * <Payment.LineItemDeposit className="font-semibold" />
377
+ * ```
378
+ */
379
+ export declare const LineItemDeposit: React.ForwardRefExoticComponent<LineItemDepositProps & React.RefAttributes<HTMLElement>>;
@@ -1,17 +1,15 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  /**
3
3
  * Payment - High-level component for displaying payment information
4
4
  * Provides components for displaying payment summary, totals, and line items
5
5
  */
6
6
  import React from 'react';
7
7
  import * as CorePayment from '../core/payment/Payment.js';
8
- import * as PaymentLineItem from './PaymentLineItem.js';
9
8
  import { AsChildSlot } from '@wix/headless-utils/react';
10
9
  import { Money, GenericList } from '@wix/headless-components/react';
11
10
  var TestIds;
12
11
  (function (TestIds) {
13
12
  TestIds["paymentRoot"] = "payment-root";
14
- TestIds["paymentSummary"] = "payment-summary";
15
13
  TestIds["paymentSubtotal"] = "payment-subtotal";
16
14
  TestIds["paymentTax"] = "payment-tax";
17
15
  TestIds["paymentDiscount"] = "payment-discount";
@@ -21,6 +19,10 @@ var TestIds;
21
19
  TestIds["paymentLineItems"] = "payment-line-items";
22
20
  TestIds["paymentLineItemsList"] = "payment-line-items-list";
23
21
  TestIds["paymentLineItemRepeater"] = "payment-line-item-repeater";
22
+ TestIds["paymentLineItemRoot"] = "payment-line-item-root";
23
+ TestIds["paymentLineItemPrice"] = "payment-line-item-price";
24
+ TestIds["paymentLineItemDiscount"] = "payment-line-item-discount";
25
+ TestIds["paymentLineItemDeposit"] = "payment-line-item-deposit";
24
26
  })(TestIds || (TestIds = {}));
25
27
  /**
26
28
  * Root component that provides payment context to the entire app.
@@ -33,13 +35,13 @@ var TestIds;
33
35
  * @component
34
36
  * @example
35
37
  * ```tsx
36
- * import { Payment, PaymentLineItem } from '@wix/bookings/components';
38
+ * import { Payment } from '@wix/bookings/components';
37
39
  *
38
40
  * // SSR mode
39
41
  * function PaymentPage({ paymentDetails }) {
40
42
  * return (
41
43
  * <Payment.Root paymentServiceConfig={{ paymentDetails }}>
42
- * <Payment.Summary />
44
+ * <Payment.Total />
43
45
  * </Payment.Root>
44
46
  * );
45
47
  * }
@@ -48,7 +50,7 @@ var TestIds;
48
50
  * function LazyPayment({ slotServices }) {
49
51
  * return (
50
52
  * <Payment.Root slotServices={slotServices} numberOfParticipants={2}>
51
- * {({ isLoading }) => isLoading ? <div>Loading...</div> : <Payment.Summary />}
53
+ * {({ isLoading }) => isLoading ? <div>Loading...</div> : <Payment.Total />}
52
54
  * </Payment.Root>
53
55
  * );
54
56
  * }
@@ -61,40 +63,6 @@ export const Root = React.forwardRef((props, ref) => {
61
63
  } }));
62
64
  });
63
65
  Root.displayName = 'Payment.Root';
64
- /**
65
- * Displays the payment summary with totals.
66
- * Uses data-attributes for conditional visibility via CSS.
67
- *
68
- * @component
69
- * @example
70
- * ```tsx
71
- * // Default usage - renders subtotal, tax, discount, total
72
- * <Payment.Summary className="space-y-2" />
73
- *
74
- * // Custom rendering with full summary data
75
- * <Payment.Summary asChild>
76
- * {({ subtotal, tax, hasTax, discount, hasDiscount, total, payNow, isDeposit }) => (
77
- * <div>
78
- * <div>Subtotal: <Money money={subtotal} /></div>
79
- * <div data-has-tax={hasTax}>Tax: <Money money={tax} /></div>
80
- * <div data-has-discount={hasDiscount}>Discount: <Money money={discount} /></div>
81
- * <div>Total: <Money money={total} /></div>
82
- * <div data-has-deposit={isDeposit}>Pay Now: <Money money={payNow} /></div>
83
- * </div>
84
- * )}
85
- * </Payment.Summary>
86
- * ```
87
- */
88
- export const Summary = React.forwardRef((props, ref) => {
89
- const { asChild, children, className } = props;
90
- return (_jsx(CorePayment.Summary, { children: (summaryData) => {
91
- const { subtotal, total, tax, discount, payNow, payLater, isDeposit, } = summaryData;
92
- // Default rendering
93
- 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 }) })] }));
94
- 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() }));
95
- } }));
96
- });
97
- Summary.displayName = 'Payment.Summary';
98
66
  /**
99
67
  * Displays the payment subtotal.
100
68
  *
@@ -106,7 +74,7 @@ Summary.displayName = 'Payment.Summary';
106
74
  */
107
75
  export const Subtotal = React.forwardRef((props, ref) => {
108
76
  const { asChild, children, className } = props;
109
- 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 })) }));
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 ? _jsx(Money, { money: subtotal }) : null })) }));
110
78
  });
111
79
  Subtotal.displayName = 'Payment.Subtotal';
112
80
  /**
@@ -121,7 +89,10 @@ Subtotal.displayName = 'Payment.Subtotal';
121
89
  */
122
90
  export const Tax = React.forwardRef((props, ref) => {
123
91
  const { asChild, children, className } = props;
124
- 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 })) }));
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
+ } }));
125
96
  });
126
97
  Tax.displayName = 'Payment.Tax';
127
98
  /**
@@ -136,7 +107,10 @@ Tax.displayName = 'Payment.Tax';
136
107
  */
137
108
  export const Discount = React.forwardRef((props, ref) => {
138
109
  const { asChild, children, className } = props;
139
- 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 })) }));
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
+ } }));
140
114
  });
141
115
  Discount.displayName = 'Payment.Discount';
142
116
  /**
@@ -150,7 +124,7 @@ Discount.displayName = 'Payment.Discount';
150
124
  */
151
125
  export const Total = React.forwardRef((props, ref) => {
152
126
  const { asChild, children, className } = props;
153
- 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 })) }));
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 ? _jsx(Money, { money: total }) : null })) }));
154
128
  });
155
129
  Total.displayName = 'Payment.Total';
156
130
  /**
@@ -165,7 +139,10 @@ Total.displayName = 'Payment.Total';
165
139
  */
166
140
  export const PayNow = React.forwardRef((props, ref) => {
167
141
  const { asChild, children, className } = props;
168
- 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 })) }));
142
+ return (_jsx(CorePayment.Data, { children: ({ payNow, total }) => {
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
+ } }));
169
146
  });
170
147
  PayNow.displayName = 'Payment.PayNow';
171
148
  /**
@@ -180,51 +157,36 @@ PayNow.displayName = 'Payment.PayNow';
180
157
  */
181
158
  export const PayLater = React.forwardRef((props, ref) => {
182
159
  const { asChild, children, className } = props;
183
- 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 })) }));
160
+ return (_jsx(CorePayment.Data, { children: ({ payLater, payNow, total }) => {
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
+ } }));
184
164
  });
185
165
  PayLater.displayName = 'Payment.PayLater';
186
166
  /**
187
167
  * Container component for line items.
188
168
  * Follows the 3-level List/Options/Repeater pattern.
189
- * Provides context and doesn't render when there are no line items.
169
+ * Provides context and handles loading/error states via GenericList.
190
170
  *
191
171
  * @component
192
172
  * @example
193
173
  * ```tsx
194
174
  * <Payment.LineItems>
195
- * <Payment.LineItemsList>
175
+ * <Payment.LineItemsList
176
+ * emptyState={<div>No items</div>}
177
+ * loadingState={<div>Loading...</div>}
178
+ * errorState={<div>Failed to load</div>}
179
+ * >
196
180
  * <Payment.LineItemRepeater>
197
- * <LineItem.Price />
181
+ * <Payment.LineItemPrice />
198
182
  * </Payment.LineItemRepeater>
199
183
  * </Payment.LineItemsList>
200
184
  * </Payment.LineItems>
201
- *
202
- * // With asChild pattern for custom container
203
- * <Payment.LineItems asChild>
204
- * {({ lineItems, currency }) => (
205
- * <div className="border rounded p-4">
206
- * <Payment.LineItemsList>
207
- * <Payment.LineItemRepeater>
208
- * <LineItem.Price />
209
- * </Payment.LineItemRepeater>
210
- * </Payment.LineItemsList>
211
- * </div>
212
- * )}
213
- * </Payment.LineItems>
214
185
  * ```
215
186
  */
216
187
  export const LineItems = React.forwardRef((props, ref) => {
217
188
  const { asChild, children, className, ...attributes } = props;
218
- return (_jsx(CorePayment.LineItems, { children: ({ lineItems, currency }) => {
219
- if (!lineItems.length)
220
- return null;
221
- // Map line items to include required id field for GenericList
222
- const items = lineItems.map((item, index) => ({
223
- ...item,
224
- id: item.sdkLineItem.lineItemId || String(index),
225
- }));
226
- 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 }) }) }) }));
227
- } }));
189
+ return (_jsx(CorePayment.LineItems, { children: ({ lineItems, currency, isLoading, error }) => (_jsx(GenericList.Root, { items: lineItems, isLoading: isLoading, error: error, children: _jsx(LineItemsContext.Provider, { value: { currency }, children: _jsx(AsChildSlot, { ...attributes, ref: ref, asChild: asChild, className: className, "data-testid": TestIds.paymentLineItems, "data-loading": isLoading, "data-error": !!error, customElement: children, customElementProps: { lineItems, currency, isLoading, error }, children: _jsx("div", { children: React.isValidElement(children) ? children : null }) }) }) })) }));
228
190
  });
229
191
  LineItems.displayName = 'Payment.LineItems';
230
192
  // Context for line items currency
@@ -237,23 +199,27 @@ function useLineItemsContext() {
237
199
  return context;
238
200
  }
239
201
  /**
240
- * List container for line items with empty state support.
202
+ * List container for line items with empty/loading/error state support.
241
203
  *
242
204
  * @component
243
205
  * @example
244
206
  * ```tsx
245
- * <Payment.LineItemsList emptyState={<div>No items</div>}>
207
+ * <Payment.LineItemsList
208
+ * emptyState={<div>No items</div>}
209
+ * loadingState={<div>Loading...</div>}
210
+ * errorState={<div>Failed to load payment details</div>}
211
+ * >
246
212
  * <Payment.LineItemRepeater />
247
213
  * </Payment.LineItemsList>
248
214
  * ```
249
215
  */
250
216
  export const LineItemsList = React.forwardRef((props, ref) => {
251
- const { children, emptyState, className, ...otherProps } = props;
252
- return (_jsx(GenericList.Items, { ref: ref, emptyState: emptyState, className: className, "data-testid": TestIds.paymentLineItemsList, ...otherProps, children: children }));
217
+ const { children, emptyState, loadingState, errorState, className, ...otherProps } = props;
218
+ return (_jsx(GenericList.Items, { ref: ref, emptyState: emptyState, loadingState: loadingState, errorState: errorState, className: className, "data-testid": TestIds.paymentLineItemsList, ...otherProps, children: children }));
253
219
  });
254
220
  LineItemsList.displayName = 'Payment.LineItemsList';
255
221
  /**
256
- * Repeater component that renders LineItem.Root for each line item.
222
+ * Repeater component that renders LineItemRoot for each line item.
257
223
  * Supports asChild pattern for custom rendering.
258
224
  *
259
225
  * @component
@@ -261,7 +227,7 @@ LineItemsList.displayName = 'Payment.LineItemsList';
261
227
  * ```tsx
262
228
  * // Standard usage
263
229
  * <Payment.LineItemRepeater>
264
- * <LineItem.Price />
230
+ * <Payment.LineItemPrice />
265
231
  * </Payment.LineItemRepeater>
266
232
  *
267
233
  * // AsChild usage with custom list
@@ -270,7 +236,7 @@ LineItemsList.displayName = 'Payment.LineItemsList';
270
236
  * <ol>
271
237
  * {items.map((item, index) => (
272
238
  * <li key={item.id}>
273
- * {itemWrapper({ item, index, children: <LineItem.Price /> })}
239
+ * {itemWrapper({ item, index, children: <Payment.LineItemPrice /> })}
274
240
  * </li>
275
241
  * ))}
276
242
  * </ol>
@@ -281,10 +247,89 @@ LineItemsList.displayName = 'Payment.LineItemsList';
281
247
  export const LineItemRepeater = React.forwardRef((props, ref) => {
282
248
  const { children, asChild } = props;
283
249
  const { currency } = useLineItemsContext();
284
- // Custom itemWrapper that renders LineItem.Root for each line item
250
+ // Custom itemWrapper that renders LineItemRoot for each line item
285
251
  const lineItemWrapper = ({ item, children: itemChildren, }) => {
286
- return (_jsx(PaymentLineItem.Root, { lineItem: item, currency: currency, "data-testid": TestIds.paymentLineItemRepeater, children: itemChildren || undefined }, item.id));
252
+ return (_jsx(LineItemRoot, { lineItem: item, currency: currency, "data-testid": TestIds.paymentLineItemRepeater, children: itemChildren || undefined }, item.id));
287
253
  };
288
254
  return (_jsx(GenericList.Repeater, { ref: ref, itemWrapper: lineItemWrapper, asChild: asChild, children: children }));
289
255
  });
290
256
  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
+ /**
266
+ * Root component for a single line item.
267
+ * Provides context for child components.
268
+ *
269
+ * @component
270
+ * @example
271
+ * ```tsx
272
+ * <Payment.LineItemRoot lineItem={item} currency="USD">
273
+ * <Payment.LineItemPrice />
274
+ * <Payment.LineItemDiscount />
275
+ * </Payment.LineItemRoot>
276
+ * ```
277
+ */
278
+ export const LineItemRoot = React.forwardRef((props, ref) => {
279
+ const { lineItem, currency, children, asChild, className, ...attrs } = props;
280
+ return (_jsx(LineItemContext.Provider, { value: { lineItem, currency }, children: _jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": attrs['data-testid'] || TestIds.paymentLineItemRoot, customElement: children, customElementProps: { lineItem, currency }, ...attrs, children: _jsx("div", { children: React.isValidElement(children) ? children : null }) }) }));
281
+ });
282
+ LineItemRoot.displayName = 'Payment.LineItemRoot';
283
+ /**
284
+ * Displays the line item price.
285
+ * Shows priceText for CUSTOM rate type services, otherwise shows totalPrice.
286
+ *
287
+ * @component
288
+ * @example
289
+ * ```tsx
290
+ * <Payment.LineItemPrice className="text-lg font-bold" />
291
+ * ```
292
+ */
293
+ export const LineItemPrice = React.forwardRef((props, ref) => {
294
+ const { asChild, children, className } = props;
295
+ const { lineItem } = useLineItemContext();
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 }));
298
+ });
299
+ LineItemPrice.displayName = 'Payment.LineItemPrice';
300
+ /**
301
+ * Displays the line item discount.
302
+ * Uses data-has-discount attribute for conditional visibility.
303
+ *
304
+ * @component
305
+ * @example
306
+ * ```tsx
307
+ * <Payment.LineItemDiscount className="text-green-500" />
308
+ * ```
309
+ */
310
+ export const LineItemDiscount = React.forwardRef((props, ref) => {
311
+ const { asChild, children, className } = props;
312
+ const { lineItem } = useLineItemContext();
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 }));
316
+ });
317
+ LineItemDiscount.displayName = 'Payment.LineItemDiscount';
318
+ /**
319
+ * Displays the line item deposit amount.
320
+ * Uses data-has-deposit attribute for conditional visibility.
321
+ *
322
+ * @component
323
+ * @example
324
+ * ```tsx
325
+ * <Payment.LineItemDeposit className="font-semibold" />
326
+ * ```
327
+ */
328
+ export const LineItemDeposit = React.forwardRef((props, ref) => {
329
+ const { asChild, children, className } = props;
330
+ const { lineItem } = useLineItemContext();
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 }));
334
+ });
335
+ LineItemDeposit.displayName = 'Payment.LineItemDeposit';