@wix/headless-bookings 0.0.16 → 0.0.18

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 (29) hide show
  1. package/cjs/dist/api/time-slot-list/index.d.ts +21 -1
  2. package/cjs/dist/api/time-slot-list/index.js +46 -8
  3. package/cjs/dist/react/core/time-slot-list/TimeSlot.d.ts +22 -18
  4. package/cjs/dist/react/core/time-slot-list/TimeSlot.js +41 -28
  5. package/cjs/dist/react/core/time-slot-list/TimeSlotList.d.ts +39 -7
  6. package/cjs/dist/react/core/time-slot-list/TimeSlotList.js +56 -11
  7. package/cjs/dist/react/time-slot-list/TimeSlot.js +3 -3
  8. package/cjs/dist/react/time-slot-list/TimeSlotList.d.ts +55 -12
  9. package/cjs/dist/react/time-slot-list/TimeSlotList.js +48 -18
  10. package/cjs/dist/services/index.d.ts +2 -2
  11. package/cjs/dist/services/time-slot-list/index.d.ts +1 -1
  12. package/cjs/dist/services/time-slot-list/time-slot-list.d.ts +3 -3
  13. package/cjs/dist/services/time-slot-list/time-slot-list.def.d.ts +23 -4
  14. package/cjs/dist/services/time-slot-list/time-slot-list.js +37 -9
  15. package/dist/api/time-slot-list/index.d.ts +21 -1
  16. package/dist/api/time-slot-list/index.js +46 -8
  17. package/dist/react/core/time-slot-list/TimeSlot.d.ts +22 -18
  18. package/dist/react/core/time-slot-list/TimeSlot.js +41 -28
  19. package/dist/react/core/time-slot-list/TimeSlotList.d.ts +39 -7
  20. package/dist/react/core/time-slot-list/TimeSlotList.js +56 -11
  21. package/dist/react/time-slot-list/TimeSlot.js +3 -3
  22. package/dist/react/time-slot-list/TimeSlotList.d.ts +55 -12
  23. package/dist/react/time-slot-list/TimeSlotList.js +48 -18
  24. package/dist/services/index.d.ts +2 -2
  25. package/dist/services/time-slot-list/index.d.ts +1 -1
  26. package/dist/services/time-slot-list/time-slot-list.d.ts +3 -3
  27. package/dist/services/time-slot-list/time-slot-list.def.d.ts +23 -4
  28. package/dist/services/time-slot-list/time-slot-list.js +37 -9
  29. package/package.json +3 -2
@@ -7,7 +7,8 @@ import { jsx as _jsx } from "react/jsx-runtime";
7
7
  * which provides the TimeSlotProvider context.
8
8
  */
9
9
  import React from 'react';
10
- import { useTimeSlotListService } from './TimeSlotList.js';
10
+ import { useService } from '@wix/services-manager-react';
11
+ import { TimeSlotListServiceDefinition, } from '../../../services/time-slot-list/time-slot-list.def.js';
11
12
  const TimeSlotContext = React.createContext(null);
12
13
  /**
13
14
  * Hook to access TimeSlot context
@@ -25,17 +26,17 @@ export function useTimeSlotContext() {
25
26
  * Not used directly by consumers - only by TimeSlotList.TimeSlotRepeater.
26
27
  */
27
28
  export function TimeSlotProvider(props) {
28
- const { children, slot } = props;
29
- const service = useTimeSlotListService();
29
+ const { children, timeSlot } = props;
30
+ const service = useService(TimeSlotListServiceDefinition);
30
31
  const selection = service.selection.get();
31
- const isSelected = selection?.slot?.id === slot.id;
32
- const selectSlot = () => {
33
- service.actions.selectSlot(slot);
32
+ const isSelected = selection?.slot?.id === timeSlot.id;
33
+ const selectTimeSlot = () => {
34
+ service.actions.selectSlot(timeSlot);
34
35
  };
35
36
  const contextValue = {
36
- slot,
37
+ timeSlot,
37
38
  isSelected,
38
- selectSlot,
39
+ selectTimeSlot,
39
40
  };
40
41
  return (_jsx(TimeSlotContext.Provider, { value: contextValue, children: children }));
41
42
  }
@@ -57,7 +58,7 @@ export function useLocationContext() {
57
58
  */
58
59
  export function LocationProvider(props) {
59
60
  const { children, location } = props;
60
- const service = useTimeSlotListService();
61
+ const service = useService(TimeSlotListServiceDefinition);
61
62
  const selectLocation = () => {
62
63
  service.actions.selectLocation(location.id);
63
64
  };
@@ -85,7 +86,7 @@ export function useStaffMemberContext() {
85
86
  */
86
87
  export function StaffMemberProvider(props) {
87
88
  const { children, staffMember } = props;
88
- const service = useTimeSlotListService();
89
+ const service = useService(TimeSlotListServiceDefinition);
89
90
  const selectStaffMember = () => {
90
91
  service.actions.selectStaffMember(staffMember.id);
91
92
  };
@@ -113,10 +114,10 @@ export function StaffMemberProvider(props) {
113
114
  * ```
114
115
  */
115
116
  export function Info(props) {
116
- const { slot, isSelected } = useTimeSlotContext();
117
- const startDate = slot.localStartDate ?? undefined;
118
- const endDate = slot.localEndDate ?? undefined;
119
- const bookable = slot.bookable ?? false;
117
+ const { timeSlot, isSelected } = useTimeSlotContext();
118
+ const startDate = timeSlot.localStartDate ?? undefined;
119
+ const endDate = timeSlot.localEndDate ?? undefined;
120
+ const bookable = timeSlot.bookable ?? false;
120
121
  // Calculate duration from start and end dates
121
122
  let durationInMinutes = null;
122
123
  if (startDate && endDate) {
@@ -130,7 +131,7 @@ export function Info(props) {
130
131
  durationInMinutes,
131
132
  bookable,
132
133
  isSelected,
133
- slot,
134
+ timeSlot,
134
135
  });
135
136
  }
136
137
  /**
@@ -154,24 +155,24 @@ export function Info(props) {
154
155
  * ```
155
156
  */
156
157
  export function Actions(props) {
157
- const { selectSlot, slot, isSelected } = useTimeSlotContext();
158
- const service = useTimeSlotListService();
158
+ const { selectTimeSlot, timeSlot, isSelected } = useTimeSlotContext();
159
+ const service = useService(TimeSlotListServiceDefinition);
159
160
  const selection = service.selection.get();
160
- const bookable = slot.bookable ?? false;
161
+ const bookable = timeSlot.bookable ?? false;
161
162
  // Check if at least one preference is selected
162
163
  const hasPreferenceSelected = !!selection?.locationId || !!selection?.staffMemberId;
163
164
  // Check if there are multiple options
164
- const locationCount = slot.staffByLocation.length;
165
- const staffCount = new Set(slot.staffByLocation.flatMap(({ staffMembers }) => staffMembers.map((s) => s.id))).size;
165
+ const locationCount = timeSlot.staffByLocation.length;
166
+ const staffCount = new Set(timeSlot.staffByLocation.flatMap(({ staffMembers }) => staffMembers.map((s) => s.id))).size;
166
167
  const hasMultipleOptions = locationCount > 1 || staffCount > 1;
167
168
  const shouldShowClearPreferences = hasPreferenceSelected && hasMultipleOptions;
168
169
  const clearPreferences = shouldShowClearPreferences
169
170
  ? service.actions.clearPreferences
170
171
  : undefined;
171
172
  return props.children({
172
- selectSlot,
173
+ selectTimeSlot,
173
174
  clearPreferences,
174
- slot,
175
+ timeSlot,
175
176
  bookable,
176
177
  isSelected,
177
178
  });
@@ -181,6 +182,8 @@ export function Actions(props) {
181
182
  * Extracts locations from slot.staffByLocation and enriches with name from originalSlots.
182
183
  * Each location includes isSelected and isSelectable based on current selection state.
183
184
  *
185
+ * Returns null if there's only 1 location (nothing to choose from).
186
+ *
184
187
  * @component
185
188
  * @example
186
189
  * ```tsx
@@ -194,13 +197,13 @@ export function Actions(props) {
194
197
  * ```
195
198
  */
196
199
  export function Locations(props) {
197
- const { slot } = useTimeSlotContext();
198
- const service = useTimeSlotListService();
200
+ const { timeSlot } = useTimeSlotContext();
201
+ const service = useService(TimeSlotListServiceDefinition);
199
202
  const selection = service.selection.get();
200
203
  const selectedLocationId = selection?.locationId ?? null;
201
204
  const selectedStaffMemberId = selection?.staffMemberId ?? null;
202
205
  // Build locations array from staffByLocation (names already included)
203
- const locations = slot.staffByLocation.map(({ location, staffMembers }) => {
206
+ const locations = timeSlot.staffByLocation.map(({ location, staffMembers }) => {
204
207
  // Check if this location is selectable based on selected staff
205
208
  // If no staff selected, all locations are selectable
206
209
  // If staff selected, only locations where that staff works are selectable
@@ -214,6 +217,10 @@ export function Locations(props) {
214
217
  isSelectable,
215
218
  };
216
219
  });
220
+ // Return null if only 1 location - nothing to choose from
221
+ if (locations.length <= 1) {
222
+ return null;
223
+ }
217
224
  return props.children({
218
225
  locations,
219
226
  selectLocation: service.actions.selectLocation,
@@ -272,6 +279,8 @@ export function LocationActions(props) {
272
279
  * Extracts unique staff members from slot.staffByLocation (names already included).
273
280
  * Each staff member includes isSelected and isSelectable based on current selection state.
274
281
  *
282
+ * Returns null if there's only 1 staff member (nothing to choose from).
283
+ *
275
284
  * @component
276
285
  * @example
277
286
  * ```tsx
@@ -285,14 +294,14 @@ export function LocationActions(props) {
285
294
  * ```
286
295
  */
287
296
  export function StaffMembers(props) {
288
- const { slot } = useTimeSlotContext();
289
- const service = useTimeSlotListService();
297
+ const { timeSlot } = useTimeSlotContext();
298
+ const service = useService(TimeSlotListServiceDefinition);
290
299
  const selection = service.selection.get();
291
300
  const selectedStaffMemberId = selection?.staffMemberId ?? null;
292
301
  const selectedLocationId = selection?.locationId ?? null;
293
302
  // Build unique staff members array from staffByLocation
294
303
  // Flatten all staff members with their location IDs, then dedupe by ID
295
- const allStaff = slot.staffByLocation.flatMap(({ location, staffMembers }) => staffMembers.map((s) => ({ ...s, locationId: location.id })));
304
+ const allStaff = timeSlot.staffByLocation.flatMap(({ location, staffMembers }) => staffMembers.map((s) => ({ ...s, locationId: location.id })));
296
305
  // Group by staff ID to get all locations per staff member
297
306
  const grouped = Object.groupBy(allStaff, (s) => s.id);
298
307
  const staffMembers = Object.entries(grouped).map(([id, entries]) => ({
@@ -302,6 +311,10 @@ export function StaffMembers(props) {
302
311
  isSelectable: !selectedLocationId ||
303
312
  entries.some((e) => e.locationId === selectedLocationId),
304
313
  }));
314
+ // Return null if only 1 staff member - nothing to choose from
315
+ if (staffMembers.length <= 1) {
316
+ return null;
317
+ }
305
318
  return props.children({
306
319
  staffMembers,
307
320
  selectStaffMember: service.actions.selectStaffMember,
@@ -3,11 +3,7 @@
3
3
  * Provides low-level access to TimeSlotListService via render props
4
4
  */
5
5
  import React from 'react';
6
- import { type TimeSlotListServiceAPI, type TimeSlotListServiceConfig, type TimeSlot } from '../../../services/time-slot-list/index.js';
7
- /**
8
- * Hook to access TimeSlotListService from within TimeSlotList.Root
9
- */
10
- export declare const useTimeSlotListService: () => TimeSlotListServiceAPI;
6
+ import { type TimeSlotListServiceConfig, type TimeSlot } from '../../../services/time-slot-list/index.js';
11
7
  /**
12
8
  * Props for Root component
13
9
  */
@@ -32,7 +28,10 @@ export declare function Root(props: RootProps): React.ReactNode;
32
28
  */
33
29
  export interface TimezoneProps {
34
30
  children: (data: {
31
+ /** Raw IANA timezone string (e.g., "America/New_York") */
35
32
  timezone: string | undefined;
33
+ /** User-friendly display name (e.g., "Eastern Standard Time") */
34
+ displayName: string;
36
35
  }) => React.ReactNode;
37
36
  }
38
37
  /**
@@ -42,8 +41,8 @@ export interface TimezoneProps {
42
41
  * @example
43
42
  * ```tsx
44
43
  * <Timezone>
45
- * {({ timezone }) => (
46
- * <span>{timezone}</span>
44
+ * {({ timezone, displayName }) => (
45
+ * <span>{displayName}</span> // "Eastern Standard Time"
47
46
  * )}
48
47
  * </Timezone>
49
48
  * ```
@@ -82,3 +81,36 @@ export interface ListDataProps {
82
81
  * ```
83
82
  */
84
83
  export declare function ListData(props: ListDataProps): React.ReactNode;
84
+ /**
85
+ * Render props for DateRange component
86
+ */
87
+ export interface DateRangeRenderProps {
88
+ startDate: Date;
89
+ endDate: Date;
90
+ setDateRange: (start: Date, end: Date) => void;
91
+ }
92
+ /**
93
+ * Props for DateRange render prop component
94
+ */
95
+ export interface DateRangeProps {
96
+ children: (data: DateRangeRenderProps) => React.ReactNode;
97
+ }
98
+ /**
99
+ * Core component that provides access to date range data and actions via render props.
100
+ * Use this to build date range inputs for calendar/week view navigation.
101
+ *
102
+ * @component
103
+ * @example
104
+ * ```tsx
105
+ * <DateRange>
106
+ * {({ startDate, endDate, setDateRange }) => (
107
+ * <MyDateRangePicker
108
+ * start={startDate}
109
+ * end={endDate}
110
+ * onChange={(start, end) => setDateRange(start, end)}
111
+ * />
112
+ * )}
113
+ * </DateRange>
114
+ * ```
115
+ */
116
+ export declare function DateRange(props: DateRangeProps): React.ReactNode;
@@ -2,12 +2,6 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { useService, WixServices } from '@wix/services-manager-react';
3
3
  import { createServicesMap } from '@wix/services-manager';
4
4
  import { TimeSlotListServiceDefinition, TimeSlotListService, } from '../../../services/time-slot-list/index.js';
5
- /**
6
- * Hook to access TimeSlotListService from within TimeSlotList.Root
7
- */
8
- export const useTimeSlotListService = () => {
9
- return useService(TimeSlotListServiceDefinition);
10
- };
11
5
  /**
12
6
  * Root component that provides TimeSlotListService context to its children.
13
7
  *
@@ -22,6 +16,30 @@ export const useTimeSlotListService = () => {
22
16
  export function Root(props) {
23
17
  return (_jsx(WixServices, { servicesMap: createServicesMap().addService(TimeSlotListServiceDefinition, TimeSlotListService, props.config || {}), children: props.children }));
24
18
  }
19
+ // ============================================================================
20
+ // Timezone Component
21
+ // ============================================================================
22
+ /**
23
+ * Gets the display name for a timezone using Intl.DateTimeFormat
24
+ * @param timezone - IANA timezone string (e.g., "America/New_York")
25
+ * @returns User-friendly display name (e.g., "Eastern Standard Time")
26
+ */
27
+ function getTimezoneDisplayName(timezone) {
28
+ if (!timezone)
29
+ return '';
30
+ try {
31
+ const formatter = new Intl.DateTimeFormat('en', {
32
+ timeZone: timezone,
33
+ timeZoneName: 'long',
34
+ });
35
+ const parts = formatter.formatToParts(new Date());
36
+ const timeZonePart = parts.find((part) => part.type === 'timeZoneName');
37
+ return timeZonePart?.value || timezone;
38
+ }
39
+ catch {
40
+ return timezone;
41
+ }
42
+ }
25
43
  /**
26
44
  * Core component that provides access to the current timezone via render props.
27
45
  *
@@ -29,16 +47,17 @@ export function Root(props) {
29
47
  * @example
30
48
  * ```tsx
31
49
  * <Timezone>
32
- * {({ timezone }) => (
33
- * <span>{timezone}</span>
50
+ * {({ timezone, displayName }) => (
51
+ * <span>{displayName}</span> // "Eastern Standard Time"
34
52
  * )}
35
53
  * </Timezone>
36
54
  * ```
37
55
  */
38
56
  export function Timezone(props) {
39
- const service = useTimeSlotListService();
57
+ const service = useService(TimeSlotListServiceDefinition);
40
58
  const timezone = service.timezone.get();
41
- return props.children({ timezone });
59
+ const displayName = getTimezoneDisplayName(timezone);
60
+ return props.children({ timezone, displayName });
42
61
  }
43
62
  /**
44
63
  * Core component that provides access to time slots list data via render props.
@@ -57,7 +76,7 @@ export function Timezone(props) {
57
76
  * ```
58
77
  */
59
78
  export function ListData(props) {
60
- const service = useTimeSlotListService();
79
+ const service = useService(TimeSlotListServiceDefinition);
61
80
  return props.children({
62
81
  timeSlots: service.timeSlots.get(),
63
82
  hasMore: service.hasMore.get(),
@@ -66,3 +85,29 @@ export function ListData(props) {
66
85
  loadMore: service.actions.loadMore,
67
86
  });
68
87
  }
88
+ /**
89
+ * Core component that provides access to date range data and actions via render props.
90
+ * Use this to build date range inputs for calendar/week view navigation.
91
+ *
92
+ * @component
93
+ * @example
94
+ * ```tsx
95
+ * <DateRange>
96
+ * {({ startDate, endDate, setDateRange }) => (
97
+ * <MyDateRangePicker
98
+ * start={startDate}
99
+ * end={endDate}
100
+ * onChange={(start, end) => setDateRange(start, end)}
101
+ * />
102
+ * )}
103
+ * </DateRange>
104
+ * ```
105
+ */
106
+ export function DateRange(props) {
107
+ const service = useService(TimeSlotListServiceDefinition);
108
+ return props.children({
109
+ startDate: service.startDate.get(),
110
+ endDate: service.endDate.get(),
111
+ setDateRange: service.actions.setDateRange,
112
+ });
113
+ }
@@ -128,13 +128,13 @@ Duration.displayName = 'TimeSlot.Duration';
128
128
  */
129
129
  export const Select = React.forwardRef((props, ref) => {
130
130
  const { asChild, children, className, label } = props;
131
- return (_jsx(CoreTimeSlot.Actions, { children: ({ selectSlot, isSelected, bookable }) => {
131
+ return (_jsx(CoreTimeSlot.Actions, { children: ({ selectTimeSlot, isSelected, bookable }) => {
132
132
  return (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.timeSlotActionSelect, "data-selected": isSelected, "data-bookable": bookable, customElement: children, customElementProps: {
133
- onClick: selectSlot,
133
+ onClick: selectTimeSlot,
134
134
  disabled: !bookable,
135
135
  isSelected,
136
136
  bookable,
137
- }, children: _jsx("button", { onClick: selectSlot, disabled: !bookable, children: label }) }));
137
+ }, children: _jsx("button", { onClick: selectTimeSlot, disabled: !bookable, children: label }) }));
138
138
  } }));
139
139
  });
140
140
  Select.displayName = 'TimeSlot.Actions.Select';
@@ -7,14 +7,21 @@ import { ListVariant } from '@wix/headless-components/react';
7
7
  import { AsChildChildren } from '@wix/headless-utils/react';
8
8
  import type { TimeSlotListServiceConfig } from '../../services/time-slot-list/time-slot-list.def.js';
9
9
  export type { StartDateProps as TimeSlotStartDateProps, EndDateProps as TimeSlotEndDateProps, DurationProps as TimeSlotDurationProps, SelectProps as TimeSlotSelectProps, LocationsProps as TimeSlotLocationsProps, LocationRepeaterProps as TimeSlotLocationRepeaterProps, LocationNameProps as TimeSlotLocationNameProps, SelectLocationProps as TimeSlotSelectLocationProps, StaffMembersProps as TimeSlotStaffMembersProps, StaffMemberRepeaterProps as TimeSlotStaffMemberRepeaterProps, StaffMemberNameProps as TimeSlotStaffMemberNameProps, SelectStaffMemberProps as TimeSlotSelectStaffMemberProps, } from './TimeSlot.js';
10
+ /**
11
+ * Render props for TimeSlotList.Timezone component
12
+ */
13
+ export interface TimezoneRenderProps {
14
+ /** Raw IANA timezone string (e.g., "America/New_York") */
15
+ timezone: string | undefined;
16
+ /** User-friendly display name (e.g., "Eastern Standard Time") */
17
+ displayName: string;
18
+ }
10
19
  /**
11
20
  * Props for TimeSlotList.Timezone component
12
21
  */
13
22
  export interface TimezoneProps {
14
23
  asChild?: boolean;
15
- children?: AsChildChildren<{
16
- timezone: string | undefined;
17
- }>;
24
+ children?: AsChildChildren<TimezoneRenderProps>;
18
25
  className?: string;
19
26
  }
20
27
  /**
@@ -23,19 +30,14 @@ export interface TimezoneProps {
23
30
  * @component
24
31
  * @example
25
32
  * ```tsx
26
- * // Default usage
33
+ * // Default usage - shows display name
27
34
  * <TimeSlotList.Timezone className="text-sm text-gray-600" />
28
35
  *
29
- * // asChild with primitive
30
- * <TimeSlotList.Timezone asChild>
31
- * <span className="font-medium" />
32
- * </TimeSlotList.Timezone>
33
- *
34
- * // asChild with render function
36
+ * // asChild with render function for custom formatting
35
37
  * <TimeSlotList.Timezone asChild>
36
- * {({ timezone }) => (
38
+ * {({ timezone, displayName }) => (
37
39
  * <span className="text-sm">
38
- * Timezone: {timezone || 'Not set'}
40
+ * {displayName} // "Eastern Standard Time"
39
41
  * </span>
40
42
  * )}
41
43
  * </TimeSlotList.Timezone>
@@ -153,6 +155,47 @@ export declare const LoadMore: React.ForwardRefExoticComponent<LoadMoreProps & R
153
155
  export declare const Actions: {
154
156
  LoadMore: React.ForwardRefExoticComponent<LoadMoreProps & React.RefAttributes<HTMLButtonElement>>;
155
157
  };
158
+ /**
159
+ * Props for DateRange.Input component
160
+ */
161
+ export interface DateRangeInputProps {
162
+ /** Whether to render as a child component */
163
+ asChild?: boolean;
164
+ /** Children for custom rendering */
165
+ children?: AsChildChildren<{
166
+ startDate: Date;
167
+ endDate: Date;
168
+ onChange: (start: Date, end: Date) => void;
169
+ }>;
170
+ /** CSS classes to apply to the container */
171
+ className?: string;
172
+ }
173
+ /**
174
+ * Date range input for setting the start and end date filter.
175
+ * Uses the core DateRange component to access service data.
176
+ * Both dates are set together and trigger a single fetch.
177
+ *
178
+ * @component
179
+ * @example
180
+ * ```tsx
181
+ * <TimeSlotList.DateRange.Input asChild>
182
+ * {({ startDate, endDate, onChange }) => (
183
+ * <MyDateRangePicker
184
+ * start={startDate}
185
+ * end={endDate}
186
+ * onRangeChange={(start, end) => onChange(start, end)}
187
+ * />
188
+ * )}
189
+ * </TimeSlotList.DateRange.Input>
190
+ * ```
191
+ */
192
+ export declare const DateRangeInput: React.ForwardRefExoticComponent<DateRangeInputProps & React.RefAttributes<HTMLElement>>;
193
+ /**
194
+ * DateRange namespace for TimeSlotList date range filter
195
+ */
196
+ export declare const DateRange: {
197
+ Input: React.ForwardRefExoticComponent<DateRangeInputProps & React.RefAttributes<HTMLElement>>;
198
+ };
156
199
  /**
157
200
  * TimeSlot namespace containing components for displaying individual time slot data.
158
201
  * These components must be used within TimeSlotList.TimeSlotRepeater.
@@ -1,4 +1,4 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs } 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
@@ -8,7 +8,7 @@ import { GenericList } from '@wix/headless-components/react';
8
8
  import { AsChildSlot } from '@wix/headless-utils/react';
9
9
  import * as CoreTimeSlotList from '../core/time-slot-list/TimeSlotList.js';
10
10
  import { TimeSlotProvider, Info as CoreTimeSlotInfo, } from '../core/time-slot-list/TimeSlot.js';
11
- import { StartDate, EndDate, Duration, Actions as TimeSlotActions, Locations, LocationRepeater, Location, StaffMembers, StaffMemberRepeater, StaffMember, } from './TimeSlot.js';
11
+ import { StartDate as TimeSlotStartDate, EndDate as TimeSlotEndDate, Duration, Actions as TimeSlotActions, Locations, LocationRepeater, Location, StaffMembers, StaffMemberRepeater, StaffMember, } from './TimeSlot.js';
12
12
  /**
13
13
  * TimeSlot with required id field for GenericList
14
14
  */
@@ -19,6 +19,7 @@ var TestIds;
19
19
  TestIds["timeSlotListTimeSlot"] = "time-slot-list-time-slot";
20
20
  TestIds["timeSlotListTimezone"] = "time-slot-list-timezone";
21
21
  TestIds["timeSlotListLoadMore"] = "time-slot-list-load-more";
22
+ TestIds["timeSlotListDateRangeInput"] = "time-slot-list-date-range-input";
22
23
  })(TestIds || (TestIds = {}));
23
24
  /**
24
25
  * Displays the current timezone with customizable rendering.
@@ -26,19 +27,14 @@ var TestIds;
26
27
  * @component
27
28
  * @example
28
29
  * ```tsx
29
- * // Default usage
30
+ * // Default usage - shows display name
30
31
  * <TimeSlotList.Timezone className="text-sm text-gray-600" />
31
32
  *
32
- * // asChild with primitive
33
+ * // asChild with render function for custom formatting
33
34
  * <TimeSlotList.Timezone asChild>
34
- * <span className="font-medium" />
35
- * </TimeSlotList.Timezone>
36
- *
37
- * // asChild with render function
38
- * <TimeSlotList.Timezone asChild>
39
- * {({ timezone }) => (
35
+ * {({ timezone, displayName }) => (
40
36
  * <span className="text-sm">
41
- * Timezone: {timezone || 'Not set'}
37
+ * {displayName} // "Eastern Standard Time"
42
38
  * </span>
43
39
  * )}
44
40
  * </TimeSlotList.Timezone>
@@ -46,7 +42,7 @@ var TestIds;
46
42
  */
47
43
  export const Timezone = React.forwardRef((props, ref) => {
48
44
  const { asChild, children, className } = props;
49
- return (_jsx(CoreTimeSlotList.Timezone, { children: ({ timezone }) => (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.timeSlotListTimezone, customElement: children, customElementProps: { timezone }, children: _jsx("span", { children: timezone }) })) }));
45
+ return (_jsx(CoreTimeSlotList.Timezone, { children: ({ timezone, displayName }) => (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.timeSlotListTimezone, customElement: children, customElementProps: { timezone, displayName }, children: _jsx("span", { children: displayName }) })) }));
50
46
  });
51
47
  Timezone.displayName = 'TimeSlotList.Timezone';
52
48
  /**
@@ -81,7 +77,7 @@ Root.displayName = 'TimeSlotList.Root';
81
77
  */
82
78
  const RootContent = React.forwardRef((props, ref) => {
83
79
  const { children, className, variant } = props;
84
- return (_jsx(CoreTimeSlotList.ListData, { children: ({ timeSlots, hasMore, isLoading, loadMore }) => (_jsx(GenericList.Root, { items: timeSlots, loadMore: loadMore, hasMore: hasMore, isLoading: isLoading, className: className, ref: ref, "data-testid": TestIds.timeSlotListRoot, variant: variant, children: children })) }));
80
+ return (_jsx(CoreTimeSlotList.ListData, { children: ({ timeSlots, hasMore, isLoading, error, loadMore }) => (_jsx(GenericList.Root, { items: timeSlots, loadMore: loadMore, hasMore: hasMore, isLoading: isLoading, error: error, className: className, ref: ref, "data-testid": TestIds.timeSlotListRoot, variant: variant, children: children })) }));
85
81
  });
86
82
  RootContent.displayName = 'TimeSlotList.RootContent';
87
83
  /**
@@ -107,8 +103,8 @@ TimeSlots.displayName = 'TimeSlotList.TimeSlots';
107
103
  * Internal component that wraps each time slot item with context provider.
108
104
  * This is separate to allow using the service hook within the repeater.
109
105
  */
110
- const TimeSlotItemWrapper = ({ slot, children, }) => {
111
- return (_jsx(TimeSlotProvider, { slot: slot, children: _jsx(CoreTimeSlotInfo, { children: ({ bookable, isSelected }) => (_jsx("div", { "data-testid": TestIds.timeSlotListTimeSlot, "data-slot-start": slot.localStartDate, "data-slot-id": slot.id, "data-bookable": bookable, "data-selected": isSelected, children: children })) }) }));
106
+ const TimeSlotItemWrapper = ({ timeSlot, children, }) => {
107
+ return (_jsx(TimeSlotProvider, { timeSlot: timeSlot, children: _jsx(CoreTimeSlotInfo, { children: ({ bookable, isSelected }) => (_jsx("div", { "data-testid": TestIds.timeSlotListTimeSlot, "data-slot-start": timeSlot.localStartDate, "data-slot-id": timeSlot.id, "data-bookable": bookable, "data-selected": isSelected, children: children })) }) }));
112
108
  };
113
109
  /**
114
110
  * Repeater component that renders each time slot.
@@ -127,7 +123,7 @@ const TimeSlotItemWrapper = ({ slot, children, }) => {
127
123
  */
128
124
  export const TimeSlotRepeater = React.forwardRef((props, ref) => {
129
125
  const { children } = props;
130
- return (_jsx(GenericList.Repeater, { ref: ref, itemWrapper: ({ item: slot, children: itemChildren }) => (_jsx(TimeSlotItemWrapper, { slot: slot, children: itemChildren }, slot.id)), children: children }));
126
+ return (_jsx(GenericList.Repeater, { ref: ref, itemWrapper: ({ item: timeSlot, children: itemChildren }) => (_jsx(TimeSlotItemWrapper, { timeSlot: timeSlot, children: itemChildren }, timeSlot.id)), children: children }));
131
127
  });
132
128
  TimeSlotRepeater.displayName = 'TimeSlotList.TimeSlotRepeater';
133
129
  /**
@@ -153,6 +149,40 @@ LoadMore.displayName = 'TimeSlotList.Actions.LoadMore';
153
149
  export const Actions = {
154
150
  LoadMore,
155
151
  };
152
+ /**
153
+ * Date range input for setting the start and end date filter.
154
+ * Uses the core DateRange component to access service data.
155
+ * Both dates are set together and trigger a single fetch.
156
+ *
157
+ * @component
158
+ * @example
159
+ * ```tsx
160
+ * <TimeSlotList.DateRange.Input asChild>
161
+ * {({ startDate, endDate, onChange }) => (
162
+ * <MyDateRangePicker
163
+ * start={startDate}
164
+ * end={endDate}
165
+ * onRangeChange={(start, end) => onChange(start, end)}
166
+ * />
167
+ * )}
168
+ * </TimeSlotList.DateRange.Input>
169
+ * ```
170
+ */
171
+ export const DateRangeInput = React.forwardRef((props, ref) => {
172
+ const { asChild, children, className, ...otherProps } = props;
173
+ return (_jsx(CoreTimeSlotList.DateRange, { children: ({ startDate, endDate, setDateRange }) => (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.timeSlotListDateRangeInput, customElement: children, customElementProps: {
174
+ startDate,
175
+ endDate,
176
+ onChange: setDateRange,
177
+ }, ...otherProps, children: _jsxs("div", { children: [startDate.toLocaleDateString(), " - ", endDate.toLocaleDateString()] }) })) }));
178
+ });
179
+ DateRangeInput.displayName = 'TimeSlotList.DateRange.Input';
180
+ /**
181
+ * DateRange namespace for TimeSlotList date range filter
182
+ */
183
+ export const DateRange = {
184
+ Input: DateRangeInput,
185
+ };
156
186
  // ============================================================================
157
187
  // TimeSlot Entity Components (re-exported)
158
188
  // ============================================================================
@@ -186,8 +216,8 @@ export const Actions = {
186
216
  * ```
187
217
  */
188
218
  export const TimeSlot = {
189
- StartDate,
190
- EndDate,
219
+ StartDate: TimeSlotStartDate,
220
+ EndDate: TimeSlotEndDate,
191
221
  Duration,
192
222
  Actions: TimeSlotActions,
193
223
  Locations,
@@ -4,5 +4,5 @@
4
4
  */
5
5
  export { ServiceService, ServiceServiceDefinition, type ServiceServiceAPI, type ServiceServiceConfig, type ServiceActions, type ServicePaymentData, loadServiceServiceInitialData, type SuccessServiceServiceConfigResult, type NotFoundServiceServiceConfigResult, } from './service/service.js';
6
6
  export { BookingService, BookingServiceDefinition, type BookingServiceConfig, type Location, type BookingServiceActions, } from './booking/booking.js';
7
- export { TimeSlotListService, TimeSlotListServiceDefinition, ViewMode, loadTimeSlotListConfig, type TimeSlotListServiceAPI, type TimeSlotListServiceActions, type TimeSlotListServiceConfig, type SlotSelection, type LoadTimeSlotListConfigOptions, type LoadTimeSlotListConfigResult, } from './time-slot-list/index.js';
8
- export { ServiceListService, ServiceListServiceDefinition, type ServiceListServiceAPI, type ServiceListServiceConfig, type ServiceListActions, type QueryOptions, loadServiceListServiceInitialData, type SuccessServiceListServiceConfigResult, type ErrorServiceListServiceConfigResult, } from './service-list/service-list.js';
7
+ export { TimeSlotListService, TimeSlotListServiceDefinition, ViewMode, loadTimeSlotListConfig, type TimeSlotListServiceAPI, type TimeSlotListServiceActions, type TimeSlotListServiceConfig, type SlotSelection, type TimeSlot, type LoadTimeSlotListConfigOptions, type LoadTimeSlotListConfigResult, } from './time-slot-list/index.js';
8
+ export { ServiceListService, ServiceListServiceDefinition, type ServiceListServiceAPI, type ServiceListServiceConfig, type ServiceListFilters, type ServiceListActions, type QueryOptions, loadServiceListServiceInitialData, type SuccessServiceListServiceConfigResult, type ErrorServiceListServiceConfigResult, } from './service-list/service-list.js';
@@ -2,5 +2,5 @@
2
2
  * TimeSlotList Service
3
3
  * Main export file for time slot list service
4
4
  */
5
- export { TimeSlotListServiceDefinition, ViewMode, type TimeSlot, type TimeSlotListServiceAPI, type TimeSlotListServiceActions, type TimeSlotListServiceConfig, type SlotSelection, } from './time-slot-list.def.js';
5
+ export { TimeSlotListServiceDefinition, ViewMode, type TimeSlot, type TimeSlotListServiceAPI, type TimeSlotListServiceActions, type TimeSlotListServiceConfig, type TimeSlotsFilters, type SlotSelection, } from './time-slot-list.def.js';
6
6
  export { TimeSlotListService, loadTimeSlotListConfig, type LoadTimeSlotListConfigOptions, type LoadTimeSlotListConfigResult, } from './time-slot-list.js';
@@ -3,7 +3,7 @@
3
3
  * Manages time slot fetching, selection, and state
4
4
  */
5
5
  import type { Service } from '@wix/auto_sdk_bookings_services';
6
- import { type TimeSlotListServiceConfig, ViewMode } from './time-slot-list.def.js';
6
+ import { type TimeSlotListServiceConfig, type TimeSlotsFilters } from './time-slot-list.def.js';
7
7
  export declare const TimeSlotListService: import("@wix/services-definitions").ServiceFactory<string & {
8
8
  __api: import("./time-slot-list.def.js").TimeSlotListServiceAPI;
9
9
  __config: {};
@@ -21,8 +21,8 @@ export interface LoadTimeSlotListConfigOptions {
21
21
  endDate?: Date;
22
22
  /** Timezone for formatting (defaults to UTC) */
23
23
  timezone?: string;
24
- /** View mode (defaults to CLASSIC) */
25
- viewMode?: ViewMode;
24
+ /** Filters for narrowing down time slots */
25
+ filters?: TimeSlotsFilters;
26
26
  }
27
27
  /**
28
28
  * Result type for SSR loader - either success with config or error