@wix/headless-bookings 0.0.87 → 0.0.89

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.
Files changed (47) hide show
  1. package/cjs/dist/react/booking/Booking.d.ts +36 -117
  2. package/cjs/dist/react/booking/Booking.js +40 -109
  3. package/cjs/dist/react/booking/BookingItem.d.ts +64 -0
  4. package/cjs/dist/react/booking/BookingItem.js +71 -0
  5. package/cjs/dist/react/core/payment/Payment.d.ts +3 -3
  6. package/cjs/dist/react/core/payment/Payment.js +4 -4
  7. package/cjs/dist/react/core/time-slot-list/TimeSlotList.d.ts +2 -0
  8. package/cjs/dist/react/core/time-slot-list/TimeSlotList.js +3 -0
  9. package/cjs/dist/react/index.d.ts +1 -0
  10. package/cjs/dist/react/index.js +1 -0
  11. package/cjs/dist/react/payment/Payment.d.ts +3 -46
  12. package/cjs/dist/react/payment/Payment.js +4 -37
  13. package/cjs/dist/react/service/Service.d.ts +0 -2
  14. package/cjs/dist/react/service/Service.js +3 -3
  15. package/cjs/dist/react/service/ServiceMedia.d.ts +1 -63
  16. package/cjs/dist/react/service/ServiceMedia.js +1 -60
  17. package/cjs/dist/react/time-slot-list/TimeSlot.d.ts +21 -6
  18. package/cjs/dist/react/time-slot-list/TimeSlot.js +34 -14
  19. package/cjs/dist/react/time-slot-list/TimeSlotList.d.ts +3 -49
  20. package/cjs/dist/react/time-slot-list/TimeSlotList.js +24 -21
  21. package/cjs/dist/services/payment/payment.d.ts +2 -2
  22. package/cjs/dist/services/payment/payment.def.d.ts +1 -1
  23. package/cjs/dist/services/payment/payment.js +11 -11
  24. package/dist/react/booking/Booking.d.ts +36 -117
  25. package/dist/react/booking/Booking.js +40 -109
  26. package/dist/react/booking/BookingItem.d.ts +64 -0
  27. package/dist/react/booking/BookingItem.js +71 -0
  28. package/dist/react/core/payment/Payment.d.ts +3 -3
  29. package/dist/react/core/payment/Payment.js +4 -4
  30. package/dist/react/core/time-slot-list/TimeSlotList.d.ts +2 -0
  31. package/dist/react/core/time-slot-list/TimeSlotList.js +3 -0
  32. package/dist/react/index.d.ts +1 -0
  33. package/dist/react/index.js +1 -0
  34. package/dist/react/payment/Payment.d.ts +3 -46
  35. package/dist/react/payment/Payment.js +4 -37
  36. package/dist/react/service/Service.d.ts +0 -2
  37. package/dist/react/service/Service.js +3 -3
  38. package/dist/react/service/ServiceMedia.d.ts +1 -63
  39. package/dist/react/service/ServiceMedia.js +1 -60
  40. package/dist/react/time-slot-list/TimeSlot.d.ts +21 -6
  41. package/dist/react/time-slot-list/TimeSlot.js +34 -14
  42. package/dist/react/time-slot-list/TimeSlotList.d.ts +3 -49
  43. package/dist/react/time-slot-list/TimeSlotList.js +24 -21
  44. package/dist/services/payment/payment.d.ts +2 -2
  45. package/dist/services/payment/payment.def.d.ts +1 -1
  46. package/dist/services/payment/payment.js +11 -11
  47. package/package.json +2 -2
@@ -1,4 +1,4 @@
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
  * TimeSlotList - High-level component for displaying time slot list information
4
4
  * Provides components for displaying timezone and time slot data
@@ -6,6 +6,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
6
6
  import React from 'react';
7
7
  import { GenericList } from '@wix/headless-components/react';
8
8
  import { AsChildSlot } from '@wix/headless-utils/react';
9
+ import { startOfDay, endOfDay, parse, format } from 'date-fns';
9
10
  import * as CoreTimeSlotList from '../core/time-slot-list/TimeSlotList.js';
10
11
  import * as CoreTimeSlot from '../core/time-slot-list/TimeSlot.js';
11
12
  import { StartDate as TimeSlotStartDate, EndDate as TimeSlotEndDate, Duration, Actions as TimeSlotActions, Location, StaffMembers, StaffMemberRepeater, StaffMember, Root as TimeSlotRoot, } from './TimeSlot.js';
@@ -14,9 +15,19 @@ import { StartDate as TimeSlotStartDate, EndDate as TimeSlotEndDate, Duration, A
14
15
  // ============================================================================
15
16
  /**
16
17
  * Converts a Date to ISO date string format (YYYY-MM-DD) for input[type="date"]
18
+ * Uses the specified timezone or falls back to local timezone
17
19
  */
18
- function toISODateString(date) {
19
- return date.toISOString().split('T')[0] ?? '';
20
+ function toISODateString(date, timezone) {
21
+ if (timezone) {
22
+ const formatter = new Intl.DateTimeFormat('en-CA', {
23
+ timeZone: timezone,
24
+ year: 'numeric',
25
+ month: '2-digit',
26
+ day: '2-digit',
27
+ });
28
+ return formatter.format(date);
29
+ }
30
+ return format(date, 'yyyy-MM-dd');
20
31
  }
21
32
  /**
22
33
  * TimeSlot with required id field for GenericList
@@ -117,34 +128,22 @@ export const TimeSlots = React.forwardRef((props, ref) => {
117
128
  TimeSlots.displayName = 'TimeSlotList.TimeSlots';
118
129
  /**
119
130
  * Internal component that wraps each time slot item with context provider.
120
- * Supports both ReactNode and function children patterns.
121
131
  */
122
132
  const TimeSlotItemWrapper = ({ timeSlot, children, }) => {
123
- return (_jsx(TimeSlotRoot, { timeSlot: timeSlot, children: _jsx(CoreTimeSlot.Info, { children: (props) => (_jsx("div", { "data-testid": TestIds.timeSlotListTimeSlot, "data-bookable": props.bookable, "data-selected": props.isSelected, children: typeof children === 'function' ? children(props) : children })) }) }));
133
+ return (_jsx(TimeSlotRoot, { timeSlot: timeSlot, children: _jsx(CoreTimeSlot.Info, { children: (props) => (_jsx("div", { "data-testid": TestIds.timeSlotListTimeSlot, "data-bookable": props.bookable, "data-selected": props.isSelected, children: children })) }) }));
124
134
  };
125
135
  /**
126
- * Repeater component that renders each time slot.
136
+ * Repeater component that renders TimeSlot.Root for each time slot.
127
137
  * Follows Repeater Level pattern and uses GenericList.Repeater for consistency.
128
- * Automatically provides TimeSlot context to children.
129
138
  *
130
139
  * @component
131
140
  * @example
132
141
  * ```tsx
133
- * // Standard usage with nested components
134
142
  * <TimeSlotList.TimeSlotRepeater>
135
143
  * <TimeSlot.StartDate />
136
144
  * <TimeSlot.Duration />
137
145
  * <TimeSlot.Actions.Select />
138
146
  * </TimeSlotList.TimeSlotRepeater>
139
- *
140
- * // Function children pattern - all data available directly
141
- * <TimeSlotList.TimeSlotRepeater>
142
- * {({ isSelected, bookable, startDate }) => (
143
- * <button disabled={!bookable} className={isSelected ? 'selected' : ''}>
144
- * {formatTime(startDate)}
145
- * </button>
146
- * )}
147
- * </TimeSlotList.TimeSlotRepeater>
148
147
  * ```
149
148
  */
150
149
  const generateSlotKey = (timeSlot) => {
@@ -152,7 +151,7 @@ const generateSlotKey = (timeSlot) => {
152
151
  };
153
152
  export const TimeSlotRepeater = React.forwardRef((props, ref) => {
154
153
  const { children } = props;
155
- return (_jsx(GenericList.Repeater, { ref: ref, itemWrapper: ({ item: timeSlot }) => (_jsx(TimeSlotItemWrapper, { timeSlot: timeSlot, children: children }, generateSlotKey(timeSlot))), children: undefined }));
154
+ return (_jsx(GenericList.Repeater, { ref: ref, itemWrapper: ({ item: timeSlot, children: itemChildren }) => (_jsx(TimeSlotItemWrapper, { timeSlot: timeSlot, children: itemChildren }, generateSlotKey(timeSlot))), children: children }));
156
155
  });
157
156
  TimeSlotRepeater.displayName = 'TimeSlotList.TimeSlotRepeater';
158
157
  /**
@@ -203,14 +202,18 @@ export const Actions = {
203
202
  * </TimeSlotList.DateRange.Input>
204
203
  * ```
205
204
  */
206
- export const DateRangeInput = React.forwardRef((props, ref) => {
205
+ const DateRangeInput = React.forwardRef((props, ref) => {
207
206
  const { asChild, children, className, ...otherProps } = props;
208
- return (_jsx(CoreTimeSlotList.DateRange, { children: ({ startDate, endDate, setDateRange }) => {
209
- const defaultContent = (_jsxs("div", { ref: ref, className: className, "data-testid": TestIds.timeSlotListDateRangeInput, children: [_jsx("input", { type: "date", value: toISODateString(startDate), onChange: (e) => setDateRange(new Date(e.target.value), endDate) }), _jsx("span", { children: "-" }), _jsx("input", { type: "date", value: toISODateString(endDate), onChange: (e) => setDateRange(startDate, new Date(e.target.value)) })] }));
207
+ return (_jsx(CoreTimeSlotList.DateRange, { children: ({ startDate, endDate, setDateRange, timezone }) => {
208
+ const defaultContent = (_jsx("input", { ref: ref, type: "date", className: className, "data-testid": TestIds.timeSlotListDateRangeInput, value: toISODateString(startDate, timezone), required: true, onChange: (e) => {
209
+ const date = parse(e.target.value, 'yyyy-MM-dd', new Date());
210
+ setDateRange(startOfDay(date), endOfDay(date));
211
+ } }));
210
212
  return (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.timeSlotListDateRangeInput, customElement: children, customElementProps: {
211
213
  startDate,
212
214
  endDate,
213
215
  onChange: setDateRange,
216
+ timezone,
214
217
  }, ...otherProps, children: defaultContent }));
215
218
  } }));
216
219
  });
@@ -24,9 +24,9 @@ export type ErrorPaymentConfigResult = {
24
24
  * Calls the pricing APIs and returns pre-calculated payment details.
25
25
  *
26
26
  * @param params.pricingServiceSelections - Pricing service selections for calculation
27
- * @param params.numberOfParticipants - Number of participants (default: 1)
27
+ * @param params.totalParticipants - Number of participants (default: 1)
28
28
  */
29
29
  export declare function loadPaymentConfig(params: {
30
30
  pricingServiceSelections: PricingServiceSelection[];
31
- numberOfParticipants?: number;
31
+ totalParticipants?: number;
32
32
  }): Promise<SuccessPaymentConfigResult | ErrorPaymentConfigResult>;
@@ -53,7 +53,7 @@ export interface PaymentServiceInternalConfig extends PaymentServiceConfig {
53
53
  /** Booking services for lazy loading (internal use) */
54
54
  pricingServiceSelections?: PricingServiceSelection[];
55
55
  /** Number of participants for lazy loading (internal use) */
56
- numberOfParticipants?: number;
56
+ totalParticipants?: number;
57
57
  }
58
58
  export interface PaymentServiceAPI {
59
59
  paymentDetailsSignal: Signal<PaymentDetails | null>;
@@ -36,15 +36,15 @@ function getPaymentOption(service, hasDeposit) {
36
36
  }
37
37
  return 'FULL_PAYMENT_ONLINE';
38
38
  }
39
- function buildLineItem(service, numberOfParticipants, lineItemId) {
39
+ function buildLineItem(service, totalParticipants, lineItemId) {
40
40
  // Get fixed price from service
41
41
  const servicePrice = service.payment?.fixed?.price?.value;
42
- const price = Number(servicePrice || 0) * numberOfParticipants;
42
+ const price = Number(servicePrice || 0) * totalParticipants;
43
43
  // Get deposit if configured
44
44
  const depositValue = service.payment?.fixed?.deposit?.value;
45
45
  const hasDeposit = !!depositValue && Number(depositValue) > 0;
46
46
  const deposit = hasDeposit
47
- ? Number(depositValue) * numberOfParticipants
47
+ ? Number(depositValue) * totalParticipants
48
48
  : undefined;
49
49
  // Get payment option from service configuration (pass hasDeposit for correct API behavior)
50
50
  const paymentOption = getPaymentOption(service, hasDeposit);
@@ -60,13 +60,13 @@ function buildLineItem(service, numberOfParticipants, lineItemId) {
60
60
  paymentOption,
61
61
  };
62
62
  }
63
- async function calculatePaymentDetails(pricingServiceSelections, numberOfParticipants) {
63
+ async function calculatePaymentDetails(pricingServiceSelections, totalParticipants) {
64
64
  // Ensure all booking services have a lineItemId
65
65
  const data = pricingServiceSelections.map((selection) => ({
66
66
  ...selection,
67
67
  lineItemId: selection.lineItemId || generateLineItemId(),
68
68
  }));
69
- const lineItems = data.map((item) => buildLineItem(item.service, numberOfParticipants, item.lineItemId));
69
+ const lineItems = data.map((item) => buildLineItem(item.service, totalParticipants, item.lineItemId));
70
70
  const response = await calculateTotals({
71
71
  lineItems,
72
72
  });
@@ -96,7 +96,7 @@ export const PaymentService = implementService.withConfig()(PaymentServiceDefini
96
96
  const isLoadingSignal = signalsService.signal(false);
97
97
  const errorSignal = signalsService.signal(null);
98
98
  // Internal calculate function
99
- const calculate = async (pricingServiceSelections, numberOfParticipants) => {
99
+ const calculate = async (pricingServiceSelections, totalParticipants) => {
100
100
  if (!pricingServiceSelections.length) {
101
101
  paymentDetailsSignal.set(null);
102
102
  return;
@@ -104,7 +104,7 @@ export const PaymentService = implementService.withConfig()(PaymentServiceDefini
104
104
  isLoadingSignal.set(true);
105
105
  errorSignal.set(null);
106
106
  try {
107
- const paymentDetails = await calculatePaymentDetails(pricingServiceSelections, numberOfParticipants);
107
+ const paymentDetails = await calculatePaymentDetails(pricingServiceSelections, totalParticipants);
108
108
  paymentDetailsSignal.set(paymentDetails);
109
109
  }
110
110
  catch (error) {
@@ -124,7 +124,7 @@ export const PaymentService = implementService.withConfig()(PaymentServiceDefini
124
124
  }
125
125
  // Mode 2: Lazy loading - pricingServiceSelections provided via internal config
126
126
  else if (config.pricingServiceSelections?.length) {
127
- void calculate(config.pricingServiceSelections, config.numberOfParticipants ?? 1);
127
+ void calculate(config.pricingServiceSelections, config.totalParticipants ?? 1);
128
128
  }
129
129
  // Mode 3: Reactive - observe BookingService signals (client-side only)
130
130
  else if (typeof window !== 'undefined' && bookingService) {
@@ -159,18 +159,18 @@ export const PaymentService = implementService.withConfig()(PaymentServiceDefini
159
159
  * Calls the pricing APIs and returns pre-calculated payment details.
160
160
  *
161
161
  * @param params.pricingServiceSelections - Pricing service selections for calculation
162
- * @param params.numberOfParticipants - Number of participants (default: 1)
162
+ * @param params.totalParticipants - Number of participants (default: 1)
163
163
  */
164
164
  export async function loadPaymentConfig(params) {
165
165
  try {
166
- const { pricingServiceSelections, numberOfParticipants = 1 } = params;
166
+ const { pricingServiceSelections, totalParticipants = 1 } = params;
167
167
  if (!pricingServiceSelections.length) {
168
168
  return {
169
169
  type: 'success',
170
170
  config: { paymentDetails: undefined },
171
171
  };
172
172
  }
173
- const paymentDetails = await calculatePaymentDetails(pricingServiceSelections, numberOfParticipants);
173
+ const paymentDetails = await calculatePaymentDetails(pricingServiceSelections, totalParticipants);
174
174
  return {
175
175
  type: 'success',
176
176
  config: { paymentDetails },
@@ -5,7 +5,7 @@
5
5
  import React from 'react';
6
6
  import * as CoreBooking from '../core/booking/Booking.js';
7
7
  import type { BookingServiceConfig } from '../../services/booking/booking.js';
8
- import { type AsChildChildren } from '@wix/headless-utils/react';
8
+ import * as BookingItemComponents from './BookingItem.js';
9
9
  export type { BookingData, DataProps, BookingItem, } from '../core/booking/Booking.js';
10
10
  /**
11
11
  * Props for Booking.Root component
@@ -63,132 +63,70 @@ export declare const Actions: {
63
63
  */
64
64
  export declare const useBookingItem: typeof CoreBooking.useBookingItemContext;
65
65
  /**
66
- * Props for Booking.ItemsRoot component (Container Level)
66
+ * Props for Booking.BookingItems component
67
67
  */
68
- export interface ItemsRootProps {
69
- children: React.ReactNode;
70
- className?: string;
71
- }
72
- /**
73
- * Container component that provides GenericList.Root context for booking items.
74
- * Use Booking.Items inside for list container with emptyState support.
75
- *
76
- * @component
77
- * @example
78
- * ```tsx
79
- * <Booking.ItemsRoot>
80
- * <Booking.Items emptyState={<div>No bookings selected</div>}>
81
- * <Booking.ItemRepeater>
82
- * <div className="booking-card">
83
- * <Booking.Service>
84
- * <Service.Name />
85
- * </Booking.Service>
86
- * </div>
87
- * </Booking.ItemRepeater>
88
- * </Booking.Items>
89
- * </Booking.ItemsRoot>
90
- * ```
91
- */
92
- export declare const ItemsRoot: React.ForwardRefExoticComponent<ItemsRootProps & React.RefAttributes<HTMLDivElement>>;
93
- /**
94
- * Props for Booking.Items component (List Container Level)
95
- */
96
- export interface ItemsProps {
68
+ export interface BookingItemsProps {
97
69
  children: React.ReactNode;
98
70
  /** Content to render when there are no booking items */
99
71
  emptyState?: React.ReactNode;
100
72
  className?: string;
101
73
  }
102
74
  /**
103
- * List container component with emptyState support.
104
- * Wraps GenericList.Items. Must be used within Booking.ItemsRoot.
75
+ * Container component for booking items with emptyState support.
76
+ * Provides GenericList context and renders items.
105
77
  *
106
78
  * @component
107
79
  * @example
108
80
  * ```tsx
109
- * <Booking.ItemsRoot>
110
- * <Booking.Items emptyState={<div>No bookings selected</div>}>
111
- * <Booking.ItemRepeater>
112
- * <Booking.Service>
113
- * <Service.Name />
114
- * </Booking.Service>
115
- * </Booking.ItemRepeater>
116
- * </Booking.Items>
117
- * </Booking.ItemsRoot>
81
+ * <Booking.BookingItems emptyState={<div>No bookings selected</div>}>
82
+ * <Booking.BookingItemRepeater>
83
+ * <BookingItem.Service>
84
+ * <Service.Name />
85
+ * </BookingItem.Service>
86
+ * </Booking.BookingItemRepeater>
87
+ * </Booking.BookingItems>
118
88
  * ```
119
89
  */
120
- export declare const Items: React.ForwardRefExoticComponent<ItemsProps & React.RefAttributes<HTMLElement>>;
90
+ export declare const BookingItems: React.ForwardRefExoticComponent<BookingItemsProps & React.RefAttributes<HTMLDivElement>>;
91
+ /** @deprecated Use Booking.BookingItems instead */
92
+ export declare const ItemsRoot: React.ForwardRefExoticComponent<BookingItemsProps & React.RefAttributes<HTMLDivElement>>;
93
+ /** @deprecated Use Booking.BookingItems instead */
94
+ export declare const Items: React.ForwardRefExoticComponent<BookingItemsProps & React.RefAttributes<HTMLDivElement>>;
121
95
  /**
122
- * Props for Booking.ItemRepeater component
96
+ * Props for Booking.BookingItemRepeater component
123
97
  */
124
- export interface ItemRepeaterProps {
98
+ export interface BookingItemRepeaterProps {
125
99
  children: React.ReactNode;
126
100
  }
127
101
  /**
128
102
  * Repeater component that maps over booking items and provides context per item.
129
103
  * Uses GenericList.Repeater internally with itemWrapper that provides BookingItemContext.
130
- * Children have access to Booking.Service, Booking.TimeSlot, etc.
104
+ * Children have access to BookingItem.Service, BookingItem.TimeSlot, etc.
131
105
  *
132
106
  * @component
133
107
  * @example
134
108
  * ```tsx
135
- * <Booking.ItemRepeater>
109
+ * <Booking.BookingItemRepeater>
136
110
  * <div className="booking-card">
137
- * <Booking.Service>
111
+ * <BookingItem.Service>
138
112
  * <Service.Name />
139
113
  * <Service.Price />
140
- * </Booking.Service>
141
- * <Booking.TimeSlot>
114
+ * </BookingItem.Service>
115
+ * <BookingItem.TimeSlot>
142
116
  * <TimeSlot.StartDate />
143
- * </Booking.TimeSlot>
144
- * <Booking.StaffName />
117
+ * </BookingItem.TimeSlot>
118
+ * <BookingItem.StaffName />
145
119
  * </div>
146
- * </Booking.ItemRepeater>
147
- * ```
148
- */
149
- export declare const ItemRepeater: React.ForwardRefExoticComponent<ItemRepeaterProps & React.RefAttributes<HTMLElement>>;
150
- /**
151
- * Props for Booking.Service component
152
- */
153
- export interface BookingServiceProps {
154
- children: React.ReactNode;
155
- }
156
- /**
157
- * Wraps Service.Root with the service from the current booking item context.
158
- * Children can use all Service.* components (Service.Name, Service.Price, etc.).
159
- *
160
- * @component
161
- * @example
162
- * ```tsx
163
- * <Booking.Service>
164
- * <Service.Name className="text-xl font-bold" />
165
- * <Service.Description />
166
- * <Service.Price />
167
- * </Booking.Service>
120
+ * </Booking.BookingItemRepeater>
168
121
  * ```
169
122
  */
170
- export declare function Service(props: BookingServiceProps): React.ReactNode;
171
- /**
172
- * Props for Booking.TimeSlot component
173
- */
174
- export interface BookingTimeSlotProps {
175
- children: React.ReactNode;
176
- }
177
- /**
178
- * Wraps TimeSlot.Root with the timeSlot from the current booking item context.
179
- * Children can use all TimeSlot.* components (TimeSlot.StartDate, TimeSlot.Duration, etc.).
180
- * Always renders with data-has-time-slot attribute for CSS targeting.
181
- *
182
- * @component
183
- * @example
184
- * ```tsx
185
- * <Booking.TimeSlot>
186
- * <TimeSlot.StartDate />
187
- * <TimeSlot.Duration />
188
- * </Booking.TimeSlot>
189
- * ```
190
- */
191
- export declare function TimeSlot(props: BookingTimeSlotProps): React.ReactNode;
123
+ export declare const BookingItemRepeater: React.ForwardRefExoticComponent<BookingItemRepeaterProps & React.RefAttributes<HTMLElement>>;
124
+ /** @deprecated Use Booking.BookingItemRepeater instead */
125
+ export declare const ItemRepeater: React.ForwardRefExoticComponent<BookingItemRepeaterProps & React.RefAttributes<HTMLElement>>;
126
+ /** @deprecated Use BookingItem.Service instead */
127
+ export declare const Service: typeof BookingItemComponents.Service;
128
+ /** @deprecated Use BookingItem.TimeSlot instead */
129
+ export declare const TimeSlot: typeof BookingItemComponents.TimeSlot;
192
130
  /**
193
131
  * Props for Booking.Payment component
194
132
  */
@@ -244,24 +182,5 @@ export interface BookingLocationProps {
244
182
  * ```
245
183
  */
246
184
  export declare function Location(props: BookingLocationProps): React.ReactNode;
247
- /**
248
- * Props for Booking.StaffName component
249
- */
250
- export interface StaffNameProps {
251
- asChild?: boolean;
252
- children?: AsChildChildren<{
253
- name: string;
254
- }>;
255
- className?: string;
256
- }
257
- /**
258
- * Displays the first staff member's name from the current booking item.
259
- * Returns null when staff name is empty.
260
- *
261
- * @component
262
- * @example
263
- * ```tsx
264
- * <Booking.StaffName className="text-foreground" />
265
- * ```
266
- */
267
- export declare const StaffName: React.ForwardRefExoticComponent<StaffNameProps & React.RefAttributes<HTMLElement>>;
185
+ /** @deprecated Use BookingItem.StaffName instead */
186
+ export declare const StaffName: React.ForwardRefExoticComponent<BookingItemComponents.StaffNameProps & React.RefAttributes<HTMLElement>>;
@@ -6,12 +6,11 @@ import { jsx as _jsx } from "react/jsx-runtime";
6
6
  import React from 'react';
7
7
  import * as CoreBooking from '../core/booking/Booking.js';
8
8
  import { Book } from './Book.js';
9
- import { AsChildSlot } from '@wix/headless-utils/react';
10
- import * as ServiceComponent from '../service/Service.js';
11
- import * as TimeSlotComponent from '../time-slot-list/TimeSlot.js';
12
9
  import * as PaymentComponent from '../payment/Payment.js';
13
10
  import * as CoreLocation from '../core/location/Location.js';
14
11
  import { GenericList } from '@wix/headless-components/react';
12
+ // Re-export BookingItem components for backward compatibility
13
+ import * as BookingItemComponents from './BookingItem.js';
15
14
  // ============================================================================
16
15
  // TestIds
17
16
  // ============================================================================
@@ -82,56 +81,33 @@ export const Actions = {
82
81
  */
83
82
  export const useBookingItem = CoreBooking.useBookingItemContext;
84
83
  /**
85
- * Container component that provides GenericList.Root context for booking items.
86
- * Use Booking.Items inside for list container with emptyState support.
84
+ * Container component for booking items with emptyState support.
85
+ * Provides GenericList context and renders items.
87
86
  *
88
87
  * @component
89
88
  * @example
90
89
  * ```tsx
91
- * <Booking.ItemsRoot>
92
- * <Booking.Items emptyState={<div>No bookings selected</div>}>
93
- * <Booking.ItemRepeater>
94
- * <div className="booking-card">
95
- * <Booking.Service>
96
- * <Service.Name />
97
- * </Booking.Service>
98
- * </div>
99
- * </Booking.ItemRepeater>
100
- * </Booking.Items>
101
- * </Booking.ItemsRoot>
90
+ * <Booking.BookingItems emptyState={<div>No bookings selected</div>}>
91
+ * <Booking.BookingItemRepeater>
92
+ * <BookingItem.Service>
93
+ * <Service.Name />
94
+ * </BookingItem.Service>
95
+ * </Booking.BookingItemRepeater>
96
+ * </Booking.BookingItems>
102
97
  * ```
103
98
  */
104
- export const ItemsRoot = React.forwardRef((props, ref) => {
105
- const { children, ...otherProps } = props;
99
+ export const BookingItems = React.forwardRef((props, ref) => {
100
+ const { children, emptyState, ...otherProps } = props;
106
101
  return (_jsx(CoreBooking.ItemsData, { children: ({ items }) => (_jsx(GenericList.Root, { ref: ref, items: items.map((item) => ({
107
102
  ...item,
108
103
  id: item.instanceId,
109
- })), hasMore: false, isLoading: false, "data-testid": TestIds.bookingItemsRoot, ...otherProps, children: children })) }));
110
- });
111
- ItemsRoot.displayName = 'Booking.ItemsRoot';
112
- /**
113
- * List container component with emptyState support.
114
- * Wraps GenericList.Items. Must be used within Booking.ItemsRoot.
115
- *
116
- * @component
117
- * @example
118
- * ```tsx
119
- * <Booking.ItemsRoot>
120
- * <Booking.Items emptyState={<div>No bookings selected</div>}>
121
- * <Booking.ItemRepeater>
122
- * <Booking.Service>
123
- * <Service.Name />
124
- * </Booking.Service>
125
- * </Booking.ItemRepeater>
126
- * </Booking.Items>
127
- * </Booking.ItemsRoot>
128
- * ```
129
- */
130
- export const Items = React.forwardRef((props, ref) => {
131
- const { children, ...otherProps } = props;
132
- return (_jsx(GenericList.Items, { ref: ref, "data-testid": TestIds.bookingItems, ...otherProps, children: children }));
104
+ })), hasMore: false, isLoading: false, "data-testid": TestIds.bookingItems, ...otherProps, children: _jsx(GenericList.Items, { emptyState: emptyState, children: children }) })) }));
133
105
  });
134
- Items.displayName = 'Booking.Items';
106
+ BookingItems.displayName = 'Booking.BookingItems';
107
+ /** @deprecated Use Booking.BookingItems instead */
108
+ export const ItemsRoot = BookingItems;
109
+ /** @deprecated Use Booking.BookingItems instead */
110
+ export const Items = BookingItems;
135
111
  /**
136
112
  * Internal component that wraps each booking item with context provider.
137
113
  */
@@ -141,66 +117,39 @@ const BookingItemWrapper = ({ item, children, }) => {
141
117
  /**
142
118
  * Repeater component that maps over booking items and provides context per item.
143
119
  * Uses GenericList.Repeater internally with itemWrapper that provides BookingItemContext.
144
- * Children have access to Booking.Service, Booking.TimeSlot, etc.
120
+ * Children have access to BookingItem.Service, BookingItem.TimeSlot, etc.
145
121
  *
146
122
  * @component
147
123
  * @example
148
124
  * ```tsx
149
- * <Booking.ItemRepeater>
125
+ * <Booking.BookingItemRepeater>
150
126
  * <div className="booking-card">
151
- * <Booking.Service>
127
+ * <BookingItem.Service>
152
128
  * <Service.Name />
153
129
  * <Service.Price />
154
- * </Booking.Service>
155
- * <Booking.TimeSlot>
130
+ * </BookingItem.Service>
131
+ * <BookingItem.TimeSlot>
156
132
  * <TimeSlot.StartDate />
157
- * </Booking.TimeSlot>
158
- * <Booking.StaffName />
133
+ * </BookingItem.TimeSlot>
134
+ * <BookingItem.StaffName />
159
135
  * </div>
160
- * </Booking.ItemRepeater>
136
+ * </Booking.BookingItemRepeater>
161
137
  * ```
162
138
  */
163
- export const ItemRepeater = React.forwardRef((props, ref) => {
139
+ export const BookingItemRepeater = React.forwardRef((props, ref) => {
164
140
  const { children } = props;
165
141
  return (_jsx(GenericList.Repeater, { ref: ref, itemWrapper: ({ item }) => (_jsx(BookingItemWrapper, { item: item, children: children }, item.instanceId)), children: undefined }));
166
142
  });
167
- ItemRepeater.displayName = 'Booking.ItemRepeater';
168
- /**
169
- * Wraps Service.Root with the service from the current booking item context.
170
- * Children can use all Service.* components (Service.Name, Service.Price, etc.).
171
- *
172
- * @component
173
- * @example
174
- * ```tsx
175
- * <Booking.Service>
176
- * <Service.Name className="text-xl font-bold" />
177
- * <Service.Description />
178
- * <Service.Price />
179
- * </Booking.Service>
180
- * ```
181
- */
182
- export function Service(props) {
183
- const { children } = props;
184
- return (_jsx(CoreBooking.BookingItemInfo, { children: ({ service }) => (_jsx(ServiceComponent.Root, { service: service, children: children })) }));
185
- }
186
- /**
187
- * Wraps TimeSlot.Root with the timeSlot from the current booking item context.
188
- * Children can use all TimeSlot.* components (TimeSlot.StartDate, TimeSlot.Duration, etc.).
189
- * Always renders with data-has-time-slot attribute for CSS targeting.
190
- *
191
- * @component
192
- * @example
193
- * ```tsx
194
- * <Booking.TimeSlot>
195
- * <TimeSlot.StartDate />
196
- * <TimeSlot.Duration />
197
- * </Booking.TimeSlot>
198
- * ```
199
- */
200
- export function TimeSlot(props) {
201
- const { children } = props;
202
- return (_jsx(CoreBooking.BookingItemInfo, { children: ({ timeSlot }) => timeSlot ? (_jsx(TimeSlotComponent.Root, { timeSlot: timeSlot, children: children })) : null }));
203
- }
143
+ BookingItemRepeater.displayName = 'Booking.BookingItemRepeater';
144
+ /** @deprecated Use Booking.BookingItemRepeater instead */
145
+ export const ItemRepeater = BookingItemRepeater;
146
+ // ============================================================================
147
+ // Deprecated: Service, TimeSlot, StaffName (moved to BookingItem namespace)
148
+ // ============================================================================
149
+ /** @deprecated Use BookingItem.Service instead */
150
+ export const Service = BookingItemComponents.Service;
151
+ /** @deprecated Use BookingItem.TimeSlot instead */
152
+ export const TimeSlot = BookingItemComponents.TimeSlot;
204
153
  /**
205
154
  * Wraps Payment.Root with all services from all booking items.
206
155
  * Should be used outside of ItemRepeater - it calculates payment for all items.
@@ -245,23 +194,5 @@ export function Location(props) {
245
194
  const { children } = props;
246
195
  return (_jsx(CoreBooking.Data, { children: ({ location }) => location ? (_jsx(CoreLocation.Root, { location: location, children: children })) : null }));
247
196
  }
248
- /**
249
- * Displays the first staff member's name from the current booking item.
250
- * Returns null when staff name is empty.
251
- *
252
- * @component
253
- * @example
254
- * ```tsx
255
- * <Booking.StaffName className="text-foreground" />
256
- * ```
257
- */
258
- export const StaffName = React.forwardRef((props, ref) => {
259
- const { asChild, children, className } = props;
260
- return (_jsx(CoreBooking.BookingItemInfo, { children: ({ staffName }) => {
261
- if (!staffName) {
262
- return null;
263
- }
264
- return (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.bookingStaffName, customElement: children, customElementProps: { name: staffName }, children: _jsx("span", { children: staffName }) }));
265
- } }));
266
- });
267
- StaffName.displayName = 'Booking.StaffName';
197
+ /** @deprecated Use BookingItem.StaffName instead */
198
+ export const StaffName = BookingItemComponents.StaffName;