@wix/headless-bookings 0.0.67 → 0.0.69

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.
@@ -59,9 +59,7 @@ export interface DataProps {
59
59
  discount: MoneyData | null;
60
60
  payNow: MoneyData | null;
61
61
  payLater: MoneyData | null;
62
- priceText: string | null;
63
- hasPriceText: boolean;
64
- isFree: boolean;
62
+ customPrice: string | null;
65
63
  hasTax: boolean;
66
64
  hasDiscount: boolean;
67
65
  isDeposit: boolean;
@@ -93,10 +91,8 @@ export interface LineItem {
93
91
  discount: MoneyData | null;
94
92
  /** Deposit amount */
95
93
  deposit: MoneyData | null;
96
- /** Custom price text (for CUSTOM rate type) */
97
- priceText: string | null;
98
- /** Whether this is a free service (NO_FEE rate type) */
99
- isFree: boolean;
94
+ /** Custom price text (for CUSTOM rate type services) */
95
+ customPrice: string | null;
100
96
  }
101
97
  /**
102
98
  * Props for LineItems render prop component
@@ -180,9 +176,7 @@ export interface LineItemInfoProps {
180
176
  tax: MoneyData | null;
181
177
  discount: MoneyData | null;
182
178
  deposit: MoneyData | null;
183
- priceText: string | null;
184
- hasPriceText: boolean;
185
- isFree: boolean;
179
+ customPrice: string | null;
186
180
  hasDiscount: boolean;
187
181
  hasDeposit: boolean;
188
182
  }) => React.ReactNode;
@@ -195,9 +189,9 @@ export interface LineItemInfoProps {
195
189
  * @example
196
190
  * ```tsx
197
191
  * <LineItemInfo>
198
- * {({ totalPrice, priceText, lineItem }) => (
192
+ * {({ totalPrice, customPrice, lineItem }) => (
199
193
  * <div>
200
- * {priceText ? <span>{priceText}</span> : <Money money={totalPrice} />}
194
+ * {customPrice ? <span>{customPrice}</span> : <Money money={totalPrice} />}
201
195
  * </div>
202
196
  * )}
203
197
  * </LineItemInfo>
@@ -77,13 +77,10 @@ export function Data(props) {
77
77
  const discount = convertMultiCurrencyPriceToMoneyData(priceSummary?.discount, currency);
78
78
  const payNow = convertMultiCurrencyPriceToMoneyData(paymentDetails?.response?.payNow?.total, currency);
79
79
  const payLater = convertMultiCurrencyPriceToMoneyData(paymentDetails?.response?.payLater?.total, currency);
80
- // Get priceText and isFree from first line item (single service mode)
80
+ // Get customPrice from first line item (single service mode)
81
81
  const additionalInfoList = paymentDetails?.additionalInfo?.lineItems || [];
82
82
  const firstLineItemInfo = additionalInfoList[0];
83
- const priceText = firstLineItemInfo?.priceText || null;
84
- const hasPriceText = !!priceText;
85
- // Use isFree from service (NO_FEE rate type) if available, otherwise fallback to amount check
86
- const isFree = firstLineItemInfo?.isFree ?? false;
83
+ const customPrice = firstLineItemInfo?.customPrice || null;
87
84
  // Computed flags
88
85
  const hasTax = tax !== null && tax.amount > 0;
89
86
  const hasDiscount = discount !== null && discount.amount > 0;
@@ -95,9 +92,7 @@ export function Data(props) {
95
92
  discount,
96
93
  payNow,
97
94
  payLater,
98
- priceText,
99
- hasPriceText,
100
- isFree,
95
+ customPrice,
101
96
  hasTax,
102
97
  hasDiscount,
103
98
  isDeposit,
@@ -145,8 +140,7 @@ export function LineItems(props) {
145
140
  tax: convertMultiCurrencyPriceToMoneyData(pricesBreakdown?.taxDetails?.totalTax, currency),
146
141
  discount: convertMultiCurrencyPriceToMoneyData(pricesBreakdown?.totalDiscount, currency),
147
142
  deposit: convertMultiCurrencyPriceToMoneyData(pricesBreakdown?.depositAmount, currency),
148
- priceText: additionalInfo?.priceText || null,
149
- isFree: additionalInfo?.isFree ?? false,
143
+ customPrice: additionalInfo?.customPrice || null,
150
144
  };
151
145
  });
152
146
  const hasLineItems = lineItems.length > 0;
@@ -202,9 +196,9 @@ export function LineItemProvider(props) {
202
196
  * @example
203
197
  * ```tsx
204
198
  * <LineItemInfo>
205
- * {({ totalPrice, priceText, lineItem }) => (
199
+ * {({ totalPrice, customPrice, lineItem }) => (
206
200
  * <div>
207
- * {priceText ? <span>{priceText}</span> : <Money money={totalPrice} />}
201
+ * {customPrice ? <span>{customPrice}</span> : <Money money={totalPrice} />}
208
202
  * </div>
209
203
  * )}
210
204
  * </LineItemInfo>
@@ -213,7 +207,6 @@ export function LineItemProvider(props) {
213
207
  export function LineItemInfo(props) {
214
208
  const { lineItem, currency } = useLineItemContext();
215
209
  // Computed flags
216
- const hasPriceText = !!lineItem.priceText;
217
210
  const hasDiscount = lineItem.discount !== null && lineItem.discount.amount > 0;
218
211
  const hasDeposit = lineItem.deposit !== null && lineItem.deposit.amount > 0;
219
212
  return props.children({
@@ -224,9 +217,7 @@ export function LineItemInfo(props) {
224
217
  tax: lineItem.tax,
225
218
  discount: lineItem.discount,
226
219
  deposit: lineItem.deposit,
227
- priceText: lineItem.priceText,
228
- hasPriceText,
229
- isFree: lineItem.isFree,
220
+ customPrice: lineItem.customPrice,
230
221
  hasDiscount,
231
222
  hasDeposit,
232
223
  });
@@ -104,7 +104,7 @@ export interface ListDataRenderProps {
104
104
  isLoading: boolean;
105
105
  error: string | null;
106
106
  loadMore: () => Promise<void>;
107
- isSelectionComplete: boolean;
107
+ hasSelectedTimeSlot: boolean;
108
108
  }
109
109
  /**
110
110
  * Props for ListData render prop component
@@ -120,7 +120,7 @@ export interface ListDataProps {
120
120
  * @example
121
121
  * ```tsx
122
122
  * <ListData>
123
- * {({ timeSlots, hasMore, isLoading, loadMore, isSelectionComplete }) => (
123
+ * {({ timeSlots, hasMore, isLoading, loadMore, hasSelectedTimeSlot }) => (
124
124
  * <GenericList.Root items={timeSlots} hasMore={hasMore} isLoading={isLoading} loadMore={loadMore}>
125
125
  * {children}
126
126
  * </GenericList.Root>
@@ -129,7 +129,7 @@ export function Timezone(props) {
129
129
  * @example
130
130
  * ```tsx
131
131
  * <ListData>
132
- * {({ timeSlots, hasMore, isLoading, loadMore, isSelectionComplete }) => (
132
+ * {({ timeSlots, hasMore, isLoading, loadMore, hasSelectedTimeSlot }) => (
133
133
  * <GenericList.Root items={timeSlots} hasMore={hasMore} isLoading={isLoading} loadMore={loadMore}>
134
134
  * {children}
135
135
  * </GenericList.Root>
@@ -141,16 +141,13 @@ export function ListData(props) {
141
141
  const service = useService(TimeSlotListServiceDefinition);
142
142
  const bookingService = useService(BookingServiceDefinition);
143
143
  const selectedTimeSlot = bookingService.serviceSelections.get()[0]?.timeSlot;
144
- const hasTimeSlot = !!selectedTimeSlot;
145
- const hasSelectedStaffMember = (selectedTimeSlot?.resources?.length ?? 0) === 1;
146
- const isSelectionComplete = hasTimeSlot && hasSelectedStaffMember;
147
144
  return props.children({
148
145
  timeSlots: service.timeSlots.get(),
149
146
  hasMore: service.hasMore.get(),
150
147
  isLoading: service.isLoading.get(),
151
148
  error: service.error.get(),
152
149
  loadMore: service.actions.loadMore,
153
- isSelectionComplete,
150
+ hasSelectedTimeSlot: !!selectedTimeSlot,
154
151
  });
155
152
  }
156
153
  /**
@@ -63,15 +63,13 @@ export interface SubtotalProps {
63
63
  asChild?: boolean;
64
64
  children?: AsChildChildren<{
65
65
  subtotal: MoneyData | null;
66
- priceText: string | null;
67
- hasPriceText: boolean;
68
- isFree: boolean;
66
+ customPrice: string | null;
69
67
  }>;
70
68
  className?: string;
71
69
  }
72
70
  /**
73
71
  * Displays the payment subtotal.
74
- * Always displays the monetary value but exposes priceText, hasPriceText, and isFree for custom rendering.
72
+ * Always displays the monetary value. Exposes customPrice for custom rendering.
75
73
  *
76
74
  * @component
77
75
  * @example
@@ -81,10 +79,9 @@ export interface SubtotalProps {
81
79
  * @example
82
80
  * ```tsx
83
81
  * <Payment.Subtotal asChild>
84
- * {({ subtotal, priceText, hasPriceText, isFree }) => (
82
+ * {({ subtotal, customPrice }) => (
85
83
  * <div>
86
- * <Money money={subtotal} />
87
- * {hasPriceText && <span className="text-sm">({priceText})</span>}
84
+ * {customPrice ? <span>{customPrice}</span> : <Money money={subtotal} />}
88
85
  * </div>
89
86
  * )}
90
87
  * </Payment.Subtotal>
@@ -140,15 +137,13 @@ export interface TotalProps {
140
137
  asChild?: boolean;
141
138
  children?: AsChildChildren<{
142
139
  total: MoneyData | null;
143
- priceText: string | null;
144
- hasPriceText: boolean;
145
- isFree: boolean;
140
+ customPrice: string | null;
146
141
  }>;
147
142
  className?: string;
148
143
  }
149
144
  /**
150
145
  * Displays the payment total.
151
- * Always displays the monetary value but exposes priceText, hasPriceText, and isFree for custom rendering.
146
+ * Always displays the monetary value. Exposes customPrice for custom rendering.
152
147
  *
153
148
  * @component
154
149
  * @example
@@ -158,14 +153,9 @@ export interface TotalProps {
158
153
  * @example
159
154
  * ```tsx
160
155
  * <Payment.Total asChild>
161
- * {({ total, priceText, hasPriceText, isFree }) => (
156
+ * {({ total, customPrice }) => (
162
157
  * <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>}
158
+ * {customPrice ? <span>{customPrice}</span> : <Money money={total} />}
169
159
  * </div>
170
160
  * )}
171
161
  * </Payment.Total>
@@ -302,15 +292,13 @@ export interface LineItemTotalProps {
302
292
  asChild?: boolean;
303
293
  children?: AsChildChildren<{
304
294
  totalPrice: MoneyData | null;
305
- priceText: string | null;
306
- hasPriceText: boolean;
307
- isFree: boolean;
295
+ customPrice: string | null;
308
296
  }>;
309
297
  className?: string;
310
298
  }
311
299
  /**
312
300
  * Displays the line item total (total price after tax).
313
- * Shows priceText for CUSTOM rate type services, otherwise shows totalPrice.
301
+ * Shows customPrice for CUSTOM rate type services, otherwise shows totalPrice.
314
302
  *
315
303
  * @component
316
304
  * @example
@@ -326,15 +314,13 @@ export interface LineItemSubtotalProps {
326
314
  asChild?: boolean;
327
315
  children?: AsChildChildren<{
328
316
  subtotal: MoneyData | null;
329
- priceText: string | null;
330
- hasPriceText: boolean;
331
- isFree: boolean;
317
+ customPrice: string | null;
332
318
  }>;
333
319
  className?: string;
334
320
  }
335
321
  /**
336
322
  * Displays the line item subtotal (full price before discounts).
337
- * Shows priceText for CUSTOM rate type services, otherwise shows subtotal.
323
+ * Shows customPrice for CUSTOM rate type services, otherwise shows subtotal.
338
324
  *
339
325
  * @component
340
326
  * @example
@@ -65,7 +65,7 @@ export const Root = React.forwardRef((props, ref) => {
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
+ * Always displays the monetary value. Exposes customPrice for custom rendering.
69
69
  *
70
70
  * @component
71
71
  * @example
@@ -75,10 +75,9 @@ Root.displayName = 'Payment.Root';
75
75
  * @example
76
76
  * ```tsx
77
77
  * <Payment.Subtotal asChild>
78
- * {({ subtotal, priceText, hasPriceText, isFree }) => (
78
+ * {({ subtotal, customPrice }) => (
79
79
  * <div>
80
- * <Money money={subtotal} />
81
- * {hasPriceText && <span className="text-sm">({priceText})</span>}
80
+ * {customPrice ? <span>{customPrice}</span> : <Money money={subtotal} />}
82
81
  * </div>
83
82
  * )}
84
83
  * </Payment.Subtotal>
@@ -86,7 +85,10 @@ Root.displayName = 'Payment.Root';
86
85
  */
87
86
  export const Subtotal = React.forwardRef((props, ref) => {
88
87
  const { asChild, children, className } = props;
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 }) })) }));
88
+ return (_jsx(CorePayment.Data, { children: ({ subtotal, customPrice }) => (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.paymentSubtotal, "data-has-custom-price": !!customPrice, customElement: children, customElementProps: {
89
+ subtotal,
90
+ customPrice,
91
+ }, children: subtotal && _jsx(Money, { money: subtotal }) })) }));
90
92
  });
91
93
  Subtotal.displayName = 'Payment.Subtotal';
92
94
  /**
@@ -121,7 +123,7 @@ export const Discount = React.forwardRef((props, ref) => {
121
123
  Discount.displayName = 'Payment.Discount';
122
124
  /**
123
125
  * Displays the payment total.
124
- * Always displays the monetary value but exposes priceText, hasPriceText, and isFree for custom rendering.
126
+ * Always displays the monetary value. Exposes customPrice for custom rendering.
125
127
  *
126
128
  * @component
127
129
  * @example
@@ -131,14 +133,9 @@ Discount.displayName = 'Payment.Discount';
131
133
  * @example
132
134
  * ```tsx
133
135
  * <Payment.Total asChild>
134
- * {({ total, priceText, hasPriceText, isFree }) => (
136
+ * {({ total, customPrice }) => (
135
137
  * <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>}
138
+ * {customPrice ? <span>{customPrice}</span> : <Money money={total} />}
142
139
  * </div>
143
140
  * )}
144
141
  * </Payment.Total>
@@ -146,7 +143,10 @@ Discount.displayName = 'Payment.Discount';
146
143
  */
147
144
  export const Total = React.forwardRef((props, ref) => {
148
145
  const { asChild, children, className } = props;
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 }) })) }));
146
+ return (_jsx(CorePayment.Data, { children: ({ total, customPrice }) => (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.paymentTotal, "data-has-custom-price": !!customPrice, customElement: children, customElementProps: {
147
+ total,
148
+ customPrice,
149
+ }, children: total && _jsx(Money, { money: total }) })) }));
150
150
  });
151
151
  Total.displayName = 'Payment.Total';
152
152
  /**
@@ -261,7 +261,7 @@ export const LineItemRepeater = React.forwardRef((props, ref) => {
261
261
  LineItemRepeater.displayName = 'Payment.LineItemRepeater';
262
262
  /**
263
263
  * Displays the line item total (total price after tax).
264
- * Shows priceText for CUSTOM rate type services, otherwise shows totalPrice.
264
+ * Shows customPrice for CUSTOM rate type services, otherwise shows totalPrice.
265
265
  *
266
266
  * @component
267
267
  * @example
@@ -271,12 +271,12 @@ LineItemRepeater.displayName = 'Payment.LineItemRepeater';
271
271
  */
272
272
  export const LineItemTotal = React.forwardRef((props, ref) => {
273
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 })) })) }));
274
+ return (_jsx(CorePayment.LineItemInfo, { children: ({ totalPrice, customPrice }) => (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.paymentLineItemTotal, "data-has-custom-price": !!customPrice, customElement: children, customElementProps: { totalPrice, customPrice }, children: customPrice ? (_jsx("span", { children: customPrice })) : (totalPrice && _jsx(Money, { money: totalPrice })) })) }));
275
275
  });
276
276
  LineItemTotal.displayName = 'Payment.LineItemTotal';
277
277
  /**
278
278
  * Displays the line item subtotal (full price before discounts).
279
- * Shows priceText for CUSTOM rate type services, otherwise shows subtotal.
279
+ * Shows customPrice for CUSTOM rate type services, otherwise shows subtotal.
280
280
  *
281
281
  * @component
282
282
  * @example
@@ -286,7 +286,7 @@ LineItemTotal.displayName = 'Payment.LineItemTotal';
286
286
  */
287
287
  export const LineItemSubtotal = React.forwardRef((props, ref) => {
288
288
  const { asChild, children, className } = props;
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 })) })) }));
289
+ return (_jsx(CorePayment.LineItemInfo, { children: ({ subtotal, customPrice }) => (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.paymentLineItemSubtotal, "data-has-custom-price": !!customPrice, customElement: children, customElementProps: { subtotal, customPrice }, children: customPrice ? (_jsx("span", { children: customPrice })) : (subtotal && _jsx(Money, { money: subtotal })) })) }));
290
290
  });
291
291
  LineItemSubtotal.displayName = 'Payment.LineItemSubtotal';
292
292
  /**
@@ -105,10 +105,10 @@ Root.displayName = 'TimeSlotList.Root';
105
105
  */
106
106
  const RootContent = React.forwardRef((props, ref) => {
107
107
  const { children, className, variant } = props;
108
- return (_jsx(CoreTimeSlotList.ListData, { children: ({ timeSlots, hasMore, isLoading, error, loadMore, isSelectionComplete, }) => (_jsx(GenericList.Root, { items: timeSlots.map((slot) => ({
108
+ return (_jsx(CoreTimeSlotList.ListData, { children: ({ timeSlots, hasMore, isLoading, error, loadMore, hasSelectedTimeSlot, }) => (_jsx(GenericList.Root, { items: timeSlots.map((slot) => ({
109
109
  ...slot,
110
110
  id: generateSlotKey(slot),
111
- })), loadMore: loadMore, hasMore: hasMore, isLoading: isLoading, error: error, className: className, ref: ref, "data-testid": TestIds.timeSlotListRoot, "data-selection-complete": isSelectionComplete, variant: variant, children: children })) }));
111
+ })), loadMore: loadMore, hasMore: hasMore, isLoading: isLoading, error: error, className: className, ref: ref, "data-testid": TestIds.timeSlotListRoot, "data-has-selected-time-slot": hasSelectedTimeSlot, variant: variant, children: children })) }));
112
112
  });
113
113
  RootContent.displayName = 'TimeSlotList.RootContent';
114
114
  /**
@@ -15,10 +15,8 @@ export type PaymentOption = 'FULL_PAYMENT_ONLINE' | 'FULL_PAYMENT_OFFLINE' | 'DE
15
15
  export interface LineItemAdditionalInfo {
16
16
  /** Line item ID to match with SDK's calculatedLineItems */
17
17
  lineItemId: string;
18
- /** Custom price text (for CUSTOM rate type services) */
19
- priceText?: string;
20
- /** Whether this is a free service (NO_FEE rate type) */
21
- isFree?: boolean;
18
+ /** Custom price (for CUSTOM rate type services) */
19
+ customPrice?: string;
22
20
  }
23
21
  /**
24
22
  * Payment calculation result with SDK response and additional computed info
@@ -20,11 +20,10 @@ const BOOKINGS_APP_DEF_ID = '13d21c63-b5ec-5912-8397-c3a5ddb27a97';
20
20
  // ============================================================================
21
21
  function getAdditionalInfo(service, lineItemId) {
22
22
  const payment = service.payment;
23
- const priceText = payment?.rateType === RateType.CUSTOM && payment.custom?.description
23
+ const customPrice = payment?.rateType === RateType.CUSTOM && payment.custom?.description
24
24
  ? payment.custom.description
25
25
  : undefined;
26
- const isFree = payment?.rateType === RateType.NO_FEE;
27
- return { lineItemId, priceText, isFree };
26
+ return { lineItemId, customPrice };
28
27
  }
29
28
  function getPaymentOption(service, hasDeposit) {
30
29
  const options = service.payment?.options;
@@ -59,9 +59,7 @@ export interface DataProps {
59
59
  discount: MoneyData | null;
60
60
  payNow: MoneyData | null;
61
61
  payLater: MoneyData | null;
62
- priceText: string | null;
63
- hasPriceText: boolean;
64
- isFree: boolean;
62
+ customPrice: string | null;
65
63
  hasTax: boolean;
66
64
  hasDiscount: boolean;
67
65
  isDeposit: boolean;
@@ -93,10 +91,8 @@ export interface LineItem {
93
91
  discount: MoneyData | null;
94
92
  /** Deposit amount */
95
93
  deposit: MoneyData | null;
96
- /** Custom price text (for CUSTOM rate type) */
97
- priceText: string | null;
98
- /** Whether this is a free service (NO_FEE rate type) */
99
- isFree: boolean;
94
+ /** Custom price text (for CUSTOM rate type services) */
95
+ customPrice: string | null;
100
96
  }
101
97
  /**
102
98
  * Props for LineItems render prop component
@@ -180,9 +176,7 @@ export interface LineItemInfoProps {
180
176
  tax: MoneyData | null;
181
177
  discount: MoneyData | null;
182
178
  deposit: MoneyData | null;
183
- priceText: string | null;
184
- hasPriceText: boolean;
185
- isFree: boolean;
179
+ customPrice: string | null;
186
180
  hasDiscount: boolean;
187
181
  hasDeposit: boolean;
188
182
  }) => React.ReactNode;
@@ -195,9 +189,9 @@ export interface LineItemInfoProps {
195
189
  * @example
196
190
  * ```tsx
197
191
  * <LineItemInfo>
198
- * {({ totalPrice, priceText, lineItem }) => (
192
+ * {({ totalPrice, customPrice, lineItem }) => (
199
193
  * <div>
200
- * {priceText ? <span>{priceText}</span> : <Money money={totalPrice} />}
194
+ * {customPrice ? <span>{customPrice}</span> : <Money money={totalPrice} />}
201
195
  * </div>
202
196
  * )}
203
197
  * </LineItemInfo>
@@ -77,13 +77,10 @@ export function Data(props) {
77
77
  const discount = convertMultiCurrencyPriceToMoneyData(priceSummary?.discount, currency);
78
78
  const payNow = convertMultiCurrencyPriceToMoneyData(paymentDetails?.response?.payNow?.total, currency);
79
79
  const payLater = convertMultiCurrencyPriceToMoneyData(paymentDetails?.response?.payLater?.total, currency);
80
- // Get priceText and isFree from first line item (single service mode)
80
+ // Get customPrice from first line item (single service mode)
81
81
  const additionalInfoList = paymentDetails?.additionalInfo?.lineItems || [];
82
82
  const firstLineItemInfo = additionalInfoList[0];
83
- const priceText = firstLineItemInfo?.priceText || null;
84
- const hasPriceText = !!priceText;
85
- // Use isFree from service (NO_FEE rate type) if available, otherwise fallback to amount check
86
- const isFree = firstLineItemInfo?.isFree ?? false;
83
+ const customPrice = firstLineItemInfo?.customPrice || null;
87
84
  // Computed flags
88
85
  const hasTax = tax !== null && tax.amount > 0;
89
86
  const hasDiscount = discount !== null && discount.amount > 0;
@@ -95,9 +92,7 @@ export function Data(props) {
95
92
  discount,
96
93
  payNow,
97
94
  payLater,
98
- priceText,
99
- hasPriceText,
100
- isFree,
95
+ customPrice,
101
96
  hasTax,
102
97
  hasDiscount,
103
98
  isDeposit,
@@ -145,8 +140,7 @@ export function LineItems(props) {
145
140
  tax: convertMultiCurrencyPriceToMoneyData(pricesBreakdown?.taxDetails?.totalTax, currency),
146
141
  discount: convertMultiCurrencyPriceToMoneyData(pricesBreakdown?.totalDiscount, currency),
147
142
  deposit: convertMultiCurrencyPriceToMoneyData(pricesBreakdown?.depositAmount, currency),
148
- priceText: additionalInfo?.priceText || null,
149
- isFree: additionalInfo?.isFree ?? false,
143
+ customPrice: additionalInfo?.customPrice || null,
150
144
  };
151
145
  });
152
146
  const hasLineItems = lineItems.length > 0;
@@ -202,9 +196,9 @@ export function LineItemProvider(props) {
202
196
  * @example
203
197
  * ```tsx
204
198
  * <LineItemInfo>
205
- * {({ totalPrice, priceText, lineItem }) => (
199
+ * {({ totalPrice, customPrice, lineItem }) => (
206
200
  * <div>
207
- * {priceText ? <span>{priceText}</span> : <Money money={totalPrice} />}
201
+ * {customPrice ? <span>{customPrice}</span> : <Money money={totalPrice} />}
208
202
  * </div>
209
203
  * )}
210
204
  * </LineItemInfo>
@@ -213,7 +207,6 @@ export function LineItemProvider(props) {
213
207
  export function LineItemInfo(props) {
214
208
  const { lineItem, currency } = useLineItemContext();
215
209
  // Computed flags
216
- const hasPriceText = !!lineItem.priceText;
217
210
  const hasDiscount = lineItem.discount !== null && lineItem.discount.amount > 0;
218
211
  const hasDeposit = lineItem.deposit !== null && lineItem.deposit.amount > 0;
219
212
  return props.children({
@@ -224,9 +217,7 @@ export function LineItemInfo(props) {
224
217
  tax: lineItem.tax,
225
218
  discount: lineItem.discount,
226
219
  deposit: lineItem.deposit,
227
- priceText: lineItem.priceText,
228
- hasPriceText,
229
- isFree: lineItem.isFree,
220
+ customPrice: lineItem.customPrice,
230
221
  hasDiscount,
231
222
  hasDeposit,
232
223
  });
@@ -104,7 +104,7 @@ export interface ListDataRenderProps {
104
104
  isLoading: boolean;
105
105
  error: string | null;
106
106
  loadMore: () => Promise<void>;
107
- isSelectionComplete: boolean;
107
+ hasSelectedTimeSlot: boolean;
108
108
  }
109
109
  /**
110
110
  * Props for ListData render prop component
@@ -120,7 +120,7 @@ export interface ListDataProps {
120
120
  * @example
121
121
  * ```tsx
122
122
  * <ListData>
123
- * {({ timeSlots, hasMore, isLoading, loadMore, isSelectionComplete }) => (
123
+ * {({ timeSlots, hasMore, isLoading, loadMore, hasSelectedTimeSlot }) => (
124
124
  * <GenericList.Root items={timeSlots} hasMore={hasMore} isLoading={isLoading} loadMore={loadMore}>
125
125
  * {children}
126
126
  * </GenericList.Root>
@@ -129,7 +129,7 @@ export function Timezone(props) {
129
129
  * @example
130
130
  * ```tsx
131
131
  * <ListData>
132
- * {({ timeSlots, hasMore, isLoading, loadMore, isSelectionComplete }) => (
132
+ * {({ timeSlots, hasMore, isLoading, loadMore, hasSelectedTimeSlot }) => (
133
133
  * <GenericList.Root items={timeSlots} hasMore={hasMore} isLoading={isLoading} loadMore={loadMore}>
134
134
  * {children}
135
135
  * </GenericList.Root>
@@ -141,16 +141,13 @@ export function ListData(props) {
141
141
  const service = useService(TimeSlotListServiceDefinition);
142
142
  const bookingService = useService(BookingServiceDefinition);
143
143
  const selectedTimeSlot = bookingService.serviceSelections.get()[0]?.timeSlot;
144
- const hasTimeSlot = !!selectedTimeSlot;
145
- const hasSelectedStaffMember = (selectedTimeSlot?.resources?.length ?? 0) === 1;
146
- const isSelectionComplete = hasTimeSlot && hasSelectedStaffMember;
147
144
  return props.children({
148
145
  timeSlots: service.timeSlots.get(),
149
146
  hasMore: service.hasMore.get(),
150
147
  isLoading: service.isLoading.get(),
151
148
  error: service.error.get(),
152
149
  loadMore: service.actions.loadMore,
153
- isSelectionComplete,
150
+ hasSelectedTimeSlot: !!selectedTimeSlot,
154
151
  });
155
152
  }
156
153
  /**
@@ -63,15 +63,13 @@ export interface SubtotalProps {
63
63
  asChild?: boolean;
64
64
  children?: AsChildChildren<{
65
65
  subtotal: MoneyData | null;
66
- priceText: string | null;
67
- hasPriceText: boolean;
68
- isFree: boolean;
66
+ customPrice: string | null;
69
67
  }>;
70
68
  className?: string;
71
69
  }
72
70
  /**
73
71
  * Displays the payment subtotal.
74
- * Always displays the monetary value but exposes priceText, hasPriceText, and isFree for custom rendering.
72
+ * Always displays the monetary value. Exposes customPrice for custom rendering.
75
73
  *
76
74
  * @component
77
75
  * @example
@@ -81,10 +79,9 @@ export interface SubtotalProps {
81
79
  * @example
82
80
  * ```tsx
83
81
  * <Payment.Subtotal asChild>
84
- * {({ subtotal, priceText, hasPriceText, isFree }) => (
82
+ * {({ subtotal, customPrice }) => (
85
83
  * <div>
86
- * <Money money={subtotal} />
87
- * {hasPriceText && <span className="text-sm">({priceText})</span>}
84
+ * {customPrice ? <span>{customPrice}</span> : <Money money={subtotal} />}
88
85
  * </div>
89
86
  * )}
90
87
  * </Payment.Subtotal>
@@ -140,15 +137,13 @@ export interface TotalProps {
140
137
  asChild?: boolean;
141
138
  children?: AsChildChildren<{
142
139
  total: MoneyData | null;
143
- priceText: string | null;
144
- hasPriceText: boolean;
145
- isFree: boolean;
140
+ customPrice: string | null;
146
141
  }>;
147
142
  className?: string;
148
143
  }
149
144
  /**
150
145
  * Displays the payment total.
151
- * Always displays the monetary value but exposes priceText, hasPriceText, and isFree for custom rendering.
146
+ * Always displays the monetary value. Exposes customPrice for custom rendering.
152
147
  *
153
148
  * @component
154
149
  * @example
@@ -158,14 +153,9 @@ export interface TotalProps {
158
153
  * @example
159
154
  * ```tsx
160
155
  * <Payment.Total asChild>
161
- * {({ total, priceText, hasPriceText, isFree }) => (
156
+ * {({ total, customPrice }) => (
162
157
  * <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>}
158
+ * {customPrice ? <span>{customPrice}</span> : <Money money={total} />}
169
159
  * </div>
170
160
  * )}
171
161
  * </Payment.Total>
@@ -302,15 +292,13 @@ export interface LineItemTotalProps {
302
292
  asChild?: boolean;
303
293
  children?: AsChildChildren<{
304
294
  totalPrice: MoneyData | null;
305
- priceText: string | null;
306
- hasPriceText: boolean;
307
- isFree: boolean;
295
+ customPrice: string | null;
308
296
  }>;
309
297
  className?: string;
310
298
  }
311
299
  /**
312
300
  * Displays the line item total (total price after tax).
313
- * Shows priceText for CUSTOM rate type services, otherwise shows totalPrice.
301
+ * Shows customPrice for CUSTOM rate type services, otherwise shows totalPrice.
314
302
  *
315
303
  * @component
316
304
  * @example
@@ -326,15 +314,13 @@ export interface LineItemSubtotalProps {
326
314
  asChild?: boolean;
327
315
  children?: AsChildChildren<{
328
316
  subtotal: MoneyData | null;
329
- priceText: string | null;
330
- hasPriceText: boolean;
331
- isFree: boolean;
317
+ customPrice: string | null;
332
318
  }>;
333
319
  className?: string;
334
320
  }
335
321
  /**
336
322
  * Displays the line item subtotal (full price before discounts).
337
- * Shows priceText for CUSTOM rate type services, otherwise shows subtotal.
323
+ * Shows customPrice for CUSTOM rate type services, otherwise shows subtotal.
338
324
  *
339
325
  * @component
340
326
  * @example
@@ -65,7 +65,7 @@ export const Root = React.forwardRef((props, ref) => {
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
+ * Always displays the monetary value. Exposes customPrice for custom rendering.
69
69
  *
70
70
  * @component
71
71
  * @example
@@ -75,10 +75,9 @@ Root.displayName = 'Payment.Root';
75
75
  * @example
76
76
  * ```tsx
77
77
  * <Payment.Subtotal asChild>
78
- * {({ subtotal, priceText, hasPriceText, isFree }) => (
78
+ * {({ subtotal, customPrice }) => (
79
79
  * <div>
80
- * <Money money={subtotal} />
81
- * {hasPriceText && <span className="text-sm">({priceText})</span>}
80
+ * {customPrice ? <span>{customPrice}</span> : <Money money={subtotal} />}
82
81
  * </div>
83
82
  * )}
84
83
  * </Payment.Subtotal>
@@ -86,7 +85,10 @@ Root.displayName = 'Payment.Root';
86
85
  */
87
86
  export const Subtotal = React.forwardRef((props, ref) => {
88
87
  const { asChild, children, className } = props;
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 }) })) }));
88
+ return (_jsx(CorePayment.Data, { children: ({ subtotal, customPrice }) => (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.paymentSubtotal, "data-has-custom-price": !!customPrice, customElement: children, customElementProps: {
89
+ subtotal,
90
+ customPrice,
91
+ }, children: subtotal && _jsx(Money, { money: subtotal }) })) }));
90
92
  });
91
93
  Subtotal.displayName = 'Payment.Subtotal';
92
94
  /**
@@ -121,7 +123,7 @@ export const Discount = React.forwardRef((props, ref) => {
121
123
  Discount.displayName = 'Payment.Discount';
122
124
  /**
123
125
  * Displays the payment total.
124
- * Always displays the monetary value but exposes priceText, hasPriceText, and isFree for custom rendering.
126
+ * Always displays the monetary value. Exposes customPrice for custom rendering.
125
127
  *
126
128
  * @component
127
129
  * @example
@@ -131,14 +133,9 @@ Discount.displayName = 'Payment.Discount';
131
133
  * @example
132
134
  * ```tsx
133
135
  * <Payment.Total asChild>
134
- * {({ total, priceText, hasPriceText, isFree }) => (
136
+ * {({ total, customPrice }) => (
135
137
  * <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>}
138
+ * {customPrice ? <span>{customPrice}</span> : <Money money={total} />}
142
139
  * </div>
143
140
  * )}
144
141
  * </Payment.Total>
@@ -146,7 +143,10 @@ Discount.displayName = 'Payment.Discount';
146
143
  */
147
144
  export const Total = React.forwardRef((props, ref) => {
148
145
  const { asChild, children, className } = props;
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 }) })) }));
146
+ return (_jsx(CorePayment.Data, { children: ({ total, customPrice }) => (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.paymentTotal, "data-has-custom-price": !!customPrice, customElement: children, customElementProps: {
147
+ total,
148
+ customPrice,
149
+ }, children: total && _jsx(Money, { money: total }) })) }));
150
150
  });
151
151
  Total.displayName = 'Payment.Total';
152
152
  /**
@@ -261,7 +261,7 @@ export const LineItemRepeater = React.forwardRef((props, ref) => {
261
261
  LineItemRepeater.displayName = 'Payment.LineItemRepeater';
262
262
  /**
263
263
  * Displays the line item total (total price after tax).
264
- * Shows priceText for CUSTOM rate type services, otherwise shows totalPrice.
264
+ * Shows customPrice for CUSTOM rate type services, otherwise shows totalPrice.
265
265
  *
266
266
  * @component
267
267
  * @example
@@ -271,12 +271,12 @@ LineItemRepeater.displayName = 'Payment.LineItemRepeater';
271
271
  */
272
272
  export const LineItemTotal = React.forwardRef((props, ref) => {
273
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 })) })) }));
274
+ return (_jsx(CorePayment.LineItemInfo, { children: ({ totalPrice, customPrice }) => (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.paymentLineItemTotal, "data-has-custom-price": !!customPrice, customElement: children, customElementProps: { totalPrice, customPrice }, children: customPrice ? (_jsx("span", { children: customPrice })) : (totalPrice && _jsx(Money, { money: totalPrice })) })) }));
275
275
  });
276
276
  LineItemTotal.displayName = 'Payment.LineItemTotal';
277
277
  /**
278
278
  * Displays the line item subtotal (full price before discounts).
279
- * Shows priceText for CUSTOM rate type services, otherwise shows subtotal.
279
+ * Shows customPrice for CUSTOM rate type services, otherwise shows subtotal.
280
280
  *
281
281
  * @component
282
282
  * @example
@@ -286,7 +286,7 @@ LineItemTotal.displayName = 'Payment.LineItemTotal';
286
286
  */
287
287
  export const LineItemSubtotal = React.forwardRef((props, ref) => {
288
288
  const { asChild, children, className } = props;
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 })) })) }));
289
+ return (_jsx(CorePayment.LineItemInfo, { children: ({ subtotal, customPrice }) => (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.paymentLineItemSubtotal, "data-has-custom-price": !!customPrice, customElement: children, customElementProps: { subtotal, customPrice }, children: customPrice ? (_jsx("span", { children: customPrice })) : (subtotal && _jsx(Money, { money: subtotal })) })) }));
290
290
  });
291
291
  LineItemSubtotal.displayName = 'Payment.LineItemSubtotal';
292
292
  /**
@@ -105,10 +105,10 @@ Root.displayName = 'TimeSlotList.Root';
105
105
  */
106
106
  const RootContent = React.forwardRef((props, ref) => {
107
107
  const { children, className, variant } = props;
108
- return (_jsx(CoreTimeSlotList.ListData, { children: ({ timeSlots, hasMore, isLoading, error, loadMore, isSelectionComplete, }) => (_jsx(GenericList.Root, { items: timeSlots.map((slot) => ({
108
+ return (_jsx(CoreTimeSlotList.ListData, { children: ({ timeSlots, hasMore, isLoading, error, loadMore, hasSelectedTimeSlot, }) => (_jsx(GenericList.Root, { items: timeSlots.map((slot) => ({
109
109
  ...slot,
110
110
  id: generateSlotKey(slot),
111
- })), loadMore: loadMore, hasMore: hasMore, isLoading: isLoading, error: error, className: className, ref: ref, "data-testid": TestIds.timeSlotListRoot, "data-selection-complete": isSelectionComplete, variant: variant, children: children })) }));
111
+ })), loadMore: loadMore, hasMore: hasMore, isLoading: isLoading, error: error, className: className, ref: ref, "data-testid": TestIds.timeSlotListRoot, "data-has-selected-time-slot": hasSelectedTimeSlot, variant: variant, children: children })) }));
112
112
  });
113
113
  RootContent.displayName = 'TimeSlotList.RootContent';
114
114
  /**
@@ -15,10 +15,8 @@ export type PaymentOption = 'FULL_PAYMENT_ONLINE' | 'FULL_PAYMENT_OFFLINE' | 'DE
15
15
  export interface LineItemAdditionalInfo {
16
16
  /** Line item ID to match with SDK's calculatedLineItems */
17
17
  lineItemId: string;
18
- /** Custom price text (for CUSTOM rate type services) */
19
- priceText?: string;
20
- /** Whether this is a free service (NO_FEE rate type) */
21
- isFree?: boolean;
18
+ /** Custom price (for CUSTOM rate type services) */
19
+ customPrice?: string;
22
20
  }
23
21
  /**
24
22
  * Payment calculation result with SDK response and additional computed info
@@ -20,11 +20,10 @@ const BOOKINGS_APP_DEF_ID = '13d21c63-b5ec-5912-8397-c3a5ddb27a97';
20
20
  // ============================================================================
21
21
  function getAdditionalInfo(service, lineItemId) {
22
22
  const payment = service.payment;
23
- const priceText = payment?.rateType === RateType.CUSTOM && payment.custom?.description
23
+ const customPrice = payment?.rateType === RateType.CUSTOM && payment.custom?.description
24
24
  ? payment.custom.description
25
25
  : undefined;
26
- const isFree = payment?.rateType === RateType.NO_FEE;
27
- return { lineItemId, priceText, isFree };
26
+ return { lineItemId, customPrice };
28
27
  }
29
28
  function getPaymentOption(service, hasDeposit) {
30
29
  const options = service.payment?.options;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wix/headless-bookings",
3
- "version": "0.0.67",
3
+ "version": "0.0.69",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -72,5 +72,5 @@
72
72
  "groupId": "com.wixpress.headless-components"
73
73
  }
74
74
  },
75
- "falconPackageHash": "f753dc96a84c513f1de40c287b7dca7b153ceea1706ec4a28ee69f97"
75
+ "falconPackageHash": "36ec02463af5b2d94e0b43ec06b66b1b90bf8dda8bab1f7f9fa0ac6f"
76
76
  }