@wix/headless-bookings 0.0.27 → 0.0.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/dist/api/fetch-availability/index.d.ts +4 -4
- package/cjs/dist/api/fetch-availability/index.js +3 -47
- package/cjs/dist/react/core/time-slot-list/TimeSlot.d.ts +9 -143
- package/cjs/dist/react/core/time-slot-list/TimeSlot.js +32 -167
- package/cjs/dist/react/core/time-slot-list/TimeSlotList.d.ts +3 -2
- package/cjs/dist/react/core/time-slot-list/TimeSlotList.js +1 -1
- package/cjs/dist/react/time-slot-list/TimeSlot.d.ts +15 -113
- package/cjs/dist/react/time-slot-list/TimeSlot.js +26 -125
- package/cjs/dist/react/time-slot-list/TimeSlotList.d.ts +5 -34
- package/cjs/dist/react/time-slot-list/TimeSlotList.js +12 -5
- package/cjs/dist/services/index.d.ts +1 -1
- package/cjs/dist/services/time-slot-list/index.d.ts +1 -1
- package/cjs/dist/services/time-slot-list/time-slot-list.d.ts +4 -4
- package/cjs/dist/services/time-slot-list/time-slot-list.def.d.ts +5 -40
- package/cjs/dist/services/time-slot-list/time-slot-list.js +38 -167
- package/dist/api/fetch-availability/index.d.ts +4 -4
- package/dist/api/fetch-availability/index.js +3 -47
- package/dist/react/core/time-slot-list/TimeSlot.d.ts +9 -143
- package/dist/react/core/time-slot-list/TimeSlot.js +32 -167
- package/dist/react/core/time-slot-list/TimeSlotList.d.ts +3 -2
- package/dist/react/core/time-slot-list/TimeSlotList.js +1 -1
- package/dist/react/time-slot-list/TimeSlot.d.ts +15 -113
- package/dist/react/time-slot-list/TimeSlot.js +26 -125
- package/dist/react/time-slot-list/TimeSlotList.d.ts +5 -34
- package/dist/react/time-slot-list/TimeSlotList.js +12 -5
- package/dist/services/index.d.ts +1 -1
- package/dist/services/time-slot-list/index.d.ts +1 -1
- package/dist/services/time-slot-list/time-slot-list.d.ts +4 -4
- package/dist/services/time-slot-list/time-slot-list.def.d.ts +5 -40
- package/dist/services/time-slot-list/time-slot-list.js +38 -167
- package/package.json +2 -2
|
@@ -21,12 +21,9 @@ var TestIds;
|
|
|
21
21
|
TestIds["timeSlotEndDate"] = "time-slot-end-date";
|
|
22
22
|
TestIds["timeSlotDuration"] = "time-slot-duration";
|
|
23
23
|
TestIds["timeSlotActionSelect"] = "time-slot-action-select";
|
|
24
|
-
TestIds["
|
|
25
|
-
// Location
|
|
26
|
-
TestIds["timeSlotLocations"] = "time-slot-locations";
|
|
27
|
-
TestIds["timeSlotLocation"] = "time-slot-location";
|
|
24
|
+
TestIds["timeSlotActionClearStaffSelection"] = "time-slot-action-clear-staff-selection";
|
|
25
|
+
// Location component
|
|
28
26
|
TestIds["timeSlotLocationName"] = "time-slot-location-name";
|
|
29
|
-
TestIds["timeSlotLocationActionSelect"] = "time-slot-location-action-select";
|
|
30
27
|
// StaffMember components
|
|
31
28
|
TestIds["timeSlotStaffMembers"] = "time-slot-staff-members";
|
|
32
29
|
TestIds["timeSlotStaffMember"] = "time-slot-staff-member";
|
|
@@ -139,95 +136,45 @@ export const Select = React.forwardRef((props, ref) => {
|
|
|
139
136
|
});
|
|
140
137
|
Select.displayName = 'TimeSlot.Actions.Select';
|
|
141
138
|
/**
|
|
142
|
-
* Button to clear
|
|
143
|
-
* Only renders when
|
|
144
|
-
* If it renders, clicking it will clear the preferences.
|
|
139
|
+
* Button to clear staff selection while keeping the slot selected.
|
|
140
|
+
* Only renders when a staff member is selected and there are multiple staff options.
|
|
145
141
|
*
|
|
146
142
|
* @component
|
|
147
143
|
* @example
|
|
148
144
|
* ```tsx
|
|
149
145
|
* // Default button - only shows when there's something to clear
|
|
150
|
-
* <TimeSlot.Actions.
|
|
146
|
+
* <TimeSlot.Actions.ClearStaffSelection label="Change staff" />
|
|
151
147
|
*
|
|
152
148
|
* // With asChild
|
|
153
|
-
* <TimeSlot.Actions.
|
|
154
|
-
* <button className="btn-secondary">Clear
|
|
155
|
-
* </TimeSlot.Actions.
|
|
149
|
+
* <TimeSlot.Actions.ClearStaffSelection asChild>
|
|
150
|
+
* <button className="btn-secondary">Clear staff</button>
|
|
151
|
+
* </TimeSlot.Actions.ClearStaffSelection>
|
|
156
152
|
*
|
|
157
153
|
* // Using render prop pattern
|
|
158
|
-
* <TimeSlot.Actions.
|
|
154
|
+
* <TimeSlot.Actions.ClearStaffSelection>
|
|
159
155
|
* {({ onClick }) => <button onClick={onClick}>Change selection</button>}
|
|
160
|
-
* </TimeSlot.Actions.
|
|
156
|
+
* </TimeSlot.Actions.ClearStaffSelection>
|
|
161
157
|
* ```
|
|
162
158
|
*/
|
|
163
|
-
export const
|
|
159
|
+
export const ClearStaffSelection = React.forwardRef((props, ref) => {
|
|
164
160
|
const { asChild, children, className, label } = props;
|
|
165
|
-
return (_jsx(CoreTimeSlot.Actions, { children: ({
|
|
166
|
-
if (!
|
|
161
|
+
return (_jsx(CoreTimeSlot.Actions, { children: ({ clearStaffSelection }) => {
|
|
162
|
+
if (!clearStaffSelection) {
|
|
167
163
|
return null;
|
|
168
164
|
}
|
|
169
|
-
return (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.
|
|
170
|
-
onClick:
|
|
171
|
-
}, children: _jsx("button", { onClick:
|
|
165
|
+
return (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.timeSlotActionClearStaffSelection, customElement: children, customElementProps: {
|
|
166
|
+
onClick: clearStaffSelection,
|
|
167
|
+
}, children: _jsx("button", { onClick: clearStaffSelection, children: label }) }));
|
|
172
168
|
} }));
|
|
173
169
|
});
|
|
174
|
-
|
|
170
|
+
ClearStaffSelection.displayName = 'TimeSlot.Actions.ClearStaffSelection';
|
|
175
171
|
/**
|
|
176
172
|
* Actions namespace for TimeSlot
|
|
177
173
|
*/
|
|
178
174
|
export const Actions = {
|
|
179
175
|
Select,
|
|
180
|
-
|
|
176
|
+
ClearStaffSelection,
|
|
181
177
|
};
|
|
182
|
-
/**
|
|
183
|
-
* Container for the locations list within a time slot.
|
|
184
|
-
* Uses GenericList.Root to manage the locations list.
|
|
185
|
-
*
|
|
186
|
-
* @component
|
|
187
|
-
* @example
|
|
188
|
-
* ```tsx
|
|
189
|
-
* <TimeSlot.Locations>
|
|
190
|
-
* <TimeSlot.LocationRepeater>
|
|
191
|
-
* <TimeSlot.Location.Name />
|
|
192
|
-
* <TimeSlot.Location.Actions.Select />
|
|
193
|
-
* </TimeSlot.LocationRepeater>
|
|
194
|
-
* </TimeSlot.Locations>
|
|
195
|
-
* ```
|
|
196
|
-
*/
|
|
197
|
-
export const Locations = React.forwardRef((props, ref) => {
|
|
198
|
-
const { children, className } = props;
|
|
199
|
-
return (_jsx(CoreTimeSlot.Locations, { children: ({ locations }) => {
|
|
200
|
-
return (_jsx(GenericList.Root, { items: locations, children: _jsx("div", { ref: ref, className: className, "data-testid": TestIds.timeSlotLocations, children: children }) }));
|
|
201
|
-
} }));
|
|
202
|
-
});
|
|
203
|
-
Locations.displayName = 'TimeSlot.Locations';
|
|
204
|
-
/**
|
|
205
|
-
* Internal component that wraps each location item with context provider.
|
|
206
|
-
*/
|
|
207
|
-
const LocationItemWrapper = ({ location, children, }) => {
|
|
208
|
-
return (_jsx(CoreTimeSlot.LocationProvider, { location: location, children: _jsx("div", { "data-testid": TestIds.timeSlotLocation, "data-location-id": location.id, "data-selected": location.isSelected, "data-selectable": location.isSelectable, children: children }) }));
|
|
209
|
-
};
|
|
210
|
-
/**
|
|
211
|
-
* Repeater component that renders each location.
|
|
212
|
-
* Follows Repeater Level pattern and uses GenericList.Repeater for consistency.
|
|
213
|
-
* Automatically provides Location context to children.
|
|
214
|
-
*
|
|
215
|
-
* @component
|
|
216
|
-
* @example
|
|
217
|
-
* ```tsx
|
|
218
|
-
* <TimeSlot.LocationRepeater>
|
|
219
|
-
* <div className="data-[selectable=false]:opacity-50 data-[selected=true]:bg-primary">
|
|
220
|
-
* <TimeSlot.Location.Name />
|
|
221
|
-
* <TimeSlot.Location.Actions.Select />
|
|
222
|
-
* </div>
|
|
223
|
-
* </TimeSlot.LocationRepeater>
|
|
224
|
-
* ```
|
|
225
|
-
*/
|
|
226
|
-
export const LocationRepeater = React.forwardRef((props, ref) => {
|
|
227
|
-
const { children } = props;
|
|
228
|
-
return (_jsx(GenericList.Repeater, { ref: ref, itemWrapper: ({ item: location, children: itemChildren }) => (_jsx(LocationItemWrapper, { location: location, children: itemChildren }, location.id)), children: children }));
|
|
229
|
-
});
|
|
230
|
-
LocationRepeater.displayName = 'TimeSlot.LocationRepeater';
|
|
231
178
|
/**
|
|
232
179
|
* Displays the location name.
|
|
233
180
|
*
|
|
@@ -247,60 +194,16 @@ LocationRepeater.displayName = 'TimeSlot.LocationRepeater';
|
|
|
247
194
|
*/
|
|
248
195
|
export const LocationName = React.forwardRef((props, ref) => {
|
|
249
196
|
const { asChild, children, className } = props;
|
|
250
|
-
return (_jsx(CoreTimeSlot.
|
|
197
|
+
return (_jsx(CoreTimeSlot.Info, { children: ({ locationName }) => {
|
|
198
|
+
return (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.timeSlotLocationName, customElement: children, customElementProps: { name: locationName }, children: _jsx("span", { children: locationName }) }));
|
|
199
|
+
} }));
|
|
251
200
|
});
|
|
252
201
|
LocationName.displayName = 'TimeSlot.Location.Name';
|
|
253
|
-
/**
|
|
254
|
-
* Button to select this location.
|
|
255
|
-
*
|
|
256
|
-
* @component
|
|
257
|
-
* @example
|
|
258
|
-
* ```tsx
|
|
259
|
-
* // Default button
|
|
260
|
-
* <TimeSlot.Location.Actions.Select label="Select" />
|
|
261
|
-
*
|
|
262
|
-
* // With asChild
|
|
263
|
-
* <TimeSlot.Location.Actions.Select asChild>
|
|
264
|
-
* <button className="btn-primary">Choose Location</button>
|
|
265
|
-
* </TimeSlot.Location.Actions.Select>
|
|
266
|
-
*
|
|
267
|
-
* // Using render prop pattern
|
|
268
|
-
* <TimeSlot.Location.Actions.Select>
|
|
269
|
-
* {({ isSelected, isSelectable, onClick }) => (
|
|
270
|
-
* <button onClick={onClick} disabled={!isSelectable}>
|
|
271
|
-
* {isSelected ? 'Selected' : 'Select'}
|
|
272
|
-
* </button>
|
|
273
|
-
* )}
|
|
274
|
-
* </TimeSlot.Location.Actions.Select>
|
|
275
|
-
* ```
|
|
276
|
-
*/
|
|
277
|
-
export const SelectLocation = React.forwardRef((props, ref) => {
|
|
278
|
-
const { asChild, children, className, label } = props;
|
|
279
|
-
return (_jsx(CoreTimeSlot.LocationActions, { children: ({ selectLocation, isSelected, isSelectable }) => (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.timeSlotLocationActionSelect, "data-selected": isSelected, "data-selectable": isSelectable, customElement: children, customElementProps: {
|
|
280
|
-
onClick: selectLocation,
|
|
281
|
-
disabled: !isSelectable,
|
|
282
|
-
isSelected,
|
|
283
|
-
isSelectable,
|
|
284
|
-
}, children: _jsx("button", { onClick: selectLocation, disabled: !isSelectable, children: label }) })) }));
|
|
285
|
-
});
|
|
286
|
-
SelectLocation.displayName = 'TimeSlot.Location.Actions.Select';
|
|
287
202
|
/**
|
|
288
203
|
* Location namespace containing components for displaying individual location data.
|
|
289
|
-
* These components must be used within TimeSlot.LocationRepeater.
|
|
290
|
-
*
|
|
291
|
-
* @example
|
|
292
|
-
* ```tsx
|
|
293
|
-
* <TimeSlot.LocationRepeater>
|
|
294
|
-
* <TimeSlot.Location.Name />
|
|
295
|
-
* <TimeSlot.Location.Actions.Select />
|
|
296
|
-
* </TimeSlot.LocationRepeater>
|
|
297
|
-
* ```
|
|
298
204
|
*/
|
|
299
205
|
export const Location = {
|
|
300
206
|
Name: LocationName,
|
|
301
|
-
Actions: {
|
|
302
|
-
Select: SelectLocation,
|
|
303
|
-
},
|
|
304
207
|
};
|
|
305
208
|
/**
|
|
306
209
|
* Container for the staff members list within a time slot.
|
|
@@ -328,7 +231,7 @@ StaffMembers.displayName = 'TimeSlot.StaffMembers';
|
|
|
328
231
|
* Internal component that wraps each staff member item with context provider.
|
|
329
232
|
*/
|
|
330
233
|
const StaffMemberItemWrapper = ({ staffMember, children, }) => {
|
|
331
|
-
return (_jsx(CoreTimeSlot.StaffMemberProvider, { staffMember: staffMember, children: _jsx("div", { "data-testid": TestIds.timeSlotStaffMember, "data-staff-member-id": staffMember.id, "data-selected": staffMember.isSelected,
|
|
234
|
+
return (_jsx(CoreTimeSlot.StaffMemberProvider, { staffMember: staffMember, children: _jsx("div", { "data-testid": TestIds.timeSlotStaffMember, "data-staff-member-id": staffMember.id, "data-selected": staffMember.isSelected, children: children }) }));
|
|
332
235
|
};
|
|
333
236
|
/**
|
|
334
237
|
* Repeater component that renders each staff member.
|
|
@@ -389,8 +292,8 @@ StaffMemberName.displayName = 'TimeSlot.StaffMember.Name';
|
|
|
389
292
|
*
|
|
390
293
|
* // Using render prop pattern
|
|
391
294
|
* <TimeSlot.StaffMember.Actions.Select>
|
|
392
|
-
* {({ isSelected,
|
|
393
|
-
* <button onClick={onClick}
|
|
295
|
+
* {({ isSelected, onClick }) => (
|
|
296
|
+
* <button onClick={onClick}>
|
|
394
297
|
* {isSelected ? 'Selected' : 'Select'}
|
|
395
298
|
* </button>
|
|
396
299
|
* )}
|
|
@@ -399,12 +302,10 @@ StaffMemberName.displayName = 'TimeSlot.StaffMember.Name';
|
|
|
399
302
|
*/
|
|
400
303
|
export const SelectStaffMember = React.forwardRef((props, ref) => {
|
|
401
304
|
const { asChild, children, className, label } = props;
|
|
402
|
-
return (_jsx(CoreTimeSlot.StaffMemberActions, { children: ({ selectStaffMember, isSelected
|
|
305
|
+
return (_jsx(CoreTimeSlot.StaffMemberActions, { children: ({ selectStaffMember, isSelected }) => (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.timeSlotStaffMemberActionSelect, "data-selected": isSelected, customElement: children, customElementProps: {
|
|
403
306
|
onClick: selectStaffMember,
|
|
404
|
-
disabled: !isSelectable,
|
|
405
307
|
isSelected,
|
|
406
|
-
|
|
407
|
-
}, children: _jsx("button", { onClick: selectStaffMember, disabled: !isSelectable, children: label }) })) }));
|
|
308
|
+
}, children: _jsx("button", { onClick: selectStaffMember, children: label }) })) }));
|
|
408
309
|
});
|
|
409
310
|
SelectStaffMember.displayName = 'TimeSlot.StaffMember.Actions.Select';
|
|
410
311
|
/**
|
|
@@ -5,8 +5,9 @@
|
|
|
5
5
|
import React from 'react';
|
|
6
6
|
import { ListVariant } from '@wix/headless-components/react';
|
|
7
7
|
import { AsChildChildren } from '@wix/headless-utils/react';
|
|
8
|
-
import type {
|
|
9
|
-
|
|
8
|
+
import type { TimeSlot as TimeSlotType } from '@wix/auto_sdk_bookings_availability-time-slots';
|
|
9
|
+
import type { TimeSlotListServiceConfig } from '../../services/time-slot-list/time-slot-list.def.js';
|
|
10
|
+
export type { StartDateProps as TimeSlotStartDateProps, EndDateProps as TimeSlotEndDateProps, DurationProps as TimeSlotDurationProps, SelectProps as TimeSlotSelectProps, LocationNameProps as TimeSlotLocationNameProps, StaffMembersProps as TimeSlotStaffMembersProps, StaffMemberRepeaterProps as TimeSlotStaffMemberRepeaterProps, StaffMemberNameProps as TimeSlotStaffMemberNameProps, SelectStaffMemberProps as TimeSlotSelectStaffMemberProps, ClearStaffSelectionProps as TimeSlotClearStaffSelectionProps, } from './TimeSlot.js';
|
|
10
11
|
/**
|
|
11
12
|
* Render props for TimeSlotList.Timezone component
|
|
12
13
|
*/
|
|
@@ -49,7 +50,7 @@ export declare const Timezone: React.ForwardRefExoticComponent<TimezoneProps & R
|
|
|
49
50
|
*/
|
|
50
51
|
export interface RootProps {
|
|
51
52
|
children: React.ReactNode;
|
|
52
|
-
config
|
|
53
|
+
config: TimeSlotListServiceConfig;
|
|
53
54
|
className?: string;
|
|
54
55
|
variant?: ListVariant;
|
|
55
56
|
}
|
|
@@ -134,31 +135,6 @@ type TimeSlotRepeaterChildren = React.ReactNode | ((props: TimeSlotRepeaterChild
|
|
|
134
135
|
export interface TimeSlotRepeaterProps {
|
|
135
136
|
children: TimeSlotRepeaterChildren;
|
|
136
137
|
}
|
|
137
|
-
/**
|
|
138
|
-
* Repeater component that renders each time slot.
|
|
139
|
-
* Follows Repeater Level pattern and uses GenericList.Repeater for consistency.
|
|
140
|
-
* Automatically provides TimeSlot context to children.
|
|
141
|
-
*
|
|
142
|
-
* @component
|
|
143
|
-
* @example
|
|
144
|
-
* ```tsx
|
|
145
|
-
* // Standard usage with nested components
|
|
146
|
-
* <TimeSlotList.TimeSlotRepeater>
|
|
147
|
-
* <TimeSlot.StartDate />
|
|
148
|
-
* <TimeSlot.Duration />
|
|
149
|
-
* <TimeSlot.Actions.Select />
|
|
150
|
-
* </TimeSlotList.TimeSlotRepeater>
|
|
151
|
-
*
|
|
152
|
-
* // Function children pattern - all data available directly
|
|
153
|
-
* <TimeSlotList.TimeSlotRepeater>
|
|
154
|
-
* {({ isSelected, bookable, startDate }) => (
|
|
155
|
-
* <button disabled={!bookable} className={isSelected ? 'selected' : ''}>
|
|
156
|
-
* {formatTime(startDate)}
|
|
157
|
-
* </button>
|
|
158
|
-
* )}
|
|
159
|
-
* </TimeSlotList.TimeSlotRepeater>
|
|
160
|
-
* ```
|
|
161
|
-
*/
|
|
162
138
|
export declare const TimeSlotRepeater: React.ForwardRefExoticComponent<TimeSlotRepeaterProps & React.RefAttributes<HTMLElement>>;
|
|
163
139
|
/**
|
|
164
140
|
* Props for TimeSlotList.Actions.LoadMore component
|
|
@@ -270,15 +246,10 @@ export declare const TimeSlot: {
|
|
|
270
246
|
Duration: React.ForwardRefExoticComponent<import("./TimeSlot.js").DurationProps & React.RefAttributes<HTMLElement>>;
|
|
271
247
|
Actions: {
|
|
272
248
|
Select: React.ForwardRefExoticComponent<import("./TimeSlot.js").SelectProps & React.RefAttributes<HTMLButtonElement>>;
|
|
273
|
-
|
|
249
|
+
ClearStaffSelection: React.ForwardRefExoticComponent<import("./TimeSlot.js").ClearStaffSelectionProps & React.RefAttributes<HTMLButtonElement>>;
|
|
274
250
|
};
|
|
275
|
-
Locations: React.ForwardRefExoticComponent<import("./TimeSlot.js").LocationsProps & React.RefAttributes<HTMLElement>>;
|
|
276
|
-
LocationRepeater: React.ForwardRefExoticComponent<import("./TimeSlot.js").LocationRepeaterProps & React.RefAttributes<HTMLElement>>;
|
|
277
251
|
Location: {
|
|
278
252
|
Name: React.ForwardRefExoticComponent<import("./TimeSlot.js").LocationNameProps & React.RefAttributes<HTMLElement>>;
|
|
279
|
-
Actions: {
|
|
280
|
-
Select: React.ForwardRefExoticComponent<import("./TimeSlot.js").SelectLocationProps & React.RefAttributes<HTMLButtonElement>>;
|
|
281
|
-
};
|
|
282
253
|
};
|
|
283
254
|
StaffMembers: React.ForwardRefExoticComponent<import("./TimeSlot.js").StaffMembersProps & React.RefAttributes<HTMLElement>>;
|
|
284
255
|
StaffMemberRepeater: React.ForwardRefExoticComponent<import("./TimeSlot.js").StaffMemberRepeaterProps & React.RefAttributes<HTMLElement>>;
|
|
@@ -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 as TimeSlotStartDate, EndDate as TimeSlotEndDate, Duration, Actions as TimeSlotActions,
|
|
11
|
+
import { StartDate as TimeSlotStartDate, EndDate as TimeSlotEndDate, Duration, Actions as TimeSlotActions, Location, StaffMembers, StaffMemberRepeater, StaffMember, } from './TimeSlot.js';
|
|
12
12
|
/**
|
|
13
13
|
* TimeSlot with required id field for GenericList
|
|
14
14
|
*/
|
|
@@ -77,7 +77,13 @@ Root.displayName = 'TimeSlotList.Root';
|
|
|
77
77
|
*/
|
|
78
78
|
const RootContent = React.forwardRef((props, ref) => {
|
|
79
79
|
const { children, className, variant } = props;
|
|
80
|
-
return (_jsx(CoreTimeSlotList.ListData, { children: ({ timeSlots, hasMore, isLoading, error, loadMore }) => (
|
|
80
|
+
return (_jsx(CoreTimeSlotList.ListData, { children: ({ timeSlots, hasMore, isLoading, error, loadMore }) => (
|
|
81
|
+
// Add stable `id` for GenericList at the headless boundary only.
|
|
82
|
+
// The underlying service slots remain raw (no grouping / no extra fields).
|
|
83
|
+
_jsx(GenericList.Root, { items: timeSlots.map((slot) => ({
|
|
84
|
+
...slot,
|
|
85
|
+
id: generateSlotKey(slot),
|
|
86
|
+
})), loadMore: loadMore, hasMore: hasMore, isLoading: isLoading, error: error, className: className, ref: ref, "data-testid": TestIds.timeSlotListRoot, variant: variant, children: children })) }));
|
|
81
87
|
});
|
|
82
88
|
RootContent.displayName = 'TimeSlotList.RootContent';
|
|
83
89
|
/**
|
|
@@ -136,9 +142,12 @@ const TimeSlotItemWrapper = ({ timeSlot, children, }) => {
|
|
|
136
142
|
* </TimeSlotList.TimeSlotRepeater>
|
|
137
143
|
* ```
|
|
138
144
|
*/
|
|
145
|
+
const generateSlotKey = (timeSlot) => {
|
|
146
|
+
return `${timeSlot.localStartDate}-${timeSlot.location?._id}`;
|
|
147
|
+
};
|
|
139
148
|
export const TimeSlotRepeater = React.forwardRef((props, ref) => {
|
|
140
149
|
const { children } = props;
|
|
141
|
-
return (_jsx(GenericList.Repeater, { ref: ref, itemWrapper: ({ item: timeSlot }) => (_jsx(TimeSlotItemWrapper, { timeSlot: timeSlot, children: children }, timeSlot
|
|
150
|
+
return (_jsx(GenericList.Repeater, { ref: ref, itemWrapper: ({ item: timeSlot }) => (_jsx(TimeSlotItemWrapper, { timeSlot: timeSlot, children: children }, generateSlotKey(timeSlot))), children: undefined }));
|
|
142
151
|
});
|
|
143
152
|
TimeSlotRepeater.displayName = 'TimeSlotList.TimeSlotRepeater';
|
|
144
153
|
/**
|
|
@@ -235,8 +244,6 @@ export const TimeSlot = {
|
|
|
235
244
|
EndDate: TimeSlotEndDate,
|
|
236
245
|
Duration,
|
|
237
246
|
Actions: TimeSlotActions,
|
|
238
|
-
Locations,
|
|
239
|
-
LocationRepeater,
|
|
240
247
|
Location,
|
|
241
248
|
StaffMembers,
|
|
242
249
|
StaffMemberRepeater,
|
package/dist/services/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
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, type ServiceSelection, type ServiceSelectionTimeSlot, } from './booking/booking.js';
|
|
7
|
-
export { TimeSlotListService, TimeSlotListServiceDefinition, ViewMode, loadTimeSlotListConfig, type TimeSlotListServiceAPI, type TimeSlotListServiceActions, type TimeSlotListServiceConfig, type
|
|
7
|
+
export { TimeSlotListService, TimeSlotListServiceDefinition, ViewMode, loadTimeSlotListConfig, type TimeSlotListServiceAPI, type TimeSlotListServiceActions, type TimeSlotListServiceConfig, type LoadTimeSlotListConfigOptions, type LoadTimeSlotListConfigResult, } from './time-slot-list/index.js';
|
|
8
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';
|
|
9
9
|
export { executeBookAction, canBook, buildBookingRequest, buildCheckoutRequest, type CanBookParams, type BookResult, type BookingError, type BookActionParams, type BookChildProps, type BookProps, type BuildCheckoutParams, } from './booking/book-action/index.js';
|
|
10
10
|
export { BookingFormService, BookingFormServiceDefinition, type BookingFormServiceAPI, type BookingFormServiceConfig, type BookingFormServiceInternalAPI, type ValidationResult, } from './booking-form/booking-form.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
|
|
5
|
+
export { TimeSlotListServiceDefinition, ViewMode, type TimeSlotListServiceAPI, type TimeSlotListServiceActions, type TimeSlotListServiceConfig, type TimeSlotsFilters, } from './time-slot-list.def.js';
|
|
6
6
|
export { TimeSlotListService, loadTimeSlotListConfig, type LoadTimeSlotListConfigOptions, type LoadTimeSlotListConfigResult, } from './time-slot-list.js';
|
|
@@ -15,10 +15,10 @@ export declare const TimeSlotListService: import("@wix/services-definitions").Se
|
|
|
15
15
|
export interface LoadTimeSlotListConfigOptions {
|
|
16
16
|
/** Services to fetch time slots for */
|
|
17
17
|
services?: Service[];
|
|
18
|
-
/** Start date for the time range
|
|
19
|
-
startDate
|
|
20
|
-
/** End date for the time range
|
|
21
|
-
endDate
|
|
18
|
+
/** Start date for the time range */
|
|
19
|
+
startDate: Date;
|
|
20
|
+
/** End date for the time range */
|
|
21
|
+
endDate: Date;
|
|
22
22
|
/** Timezone for formatting (defaults to UTC) */
|
|
23
23
|
timezone?: string;
|
|
24
24
|
/** Filters for narrowing down time slots */
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Defines interfaces and service contract for time slot management
|
|
4
4
|
*/
|
|
5
5
|
import type { Signal } from '@wix/services-definitions/core-services/signals';
|
|
6
|
-
import type {
|
|
6
|
+
import type { LocationTypeWithLiterals, TimeSlot } from '@wix/auto_sdk_bookings_availability-time-slots';
|
|
7
7
|
import type { Service } from '@wix/auto_sdk_bookings_services';
|
|
8
8
|
/**
|
|
9
9
|
* Location filter input for availability calls.
|
|
@@ -17,39 +17,6 @@ export declare enum ViewMode {
|
|
|
17
17
|
CLASSIC = "classic",
|
|
18
18
|
AGENDA = "agenda"
|
|
19
19
|
}
|
|
20
|
-
/**
|
|
21
|
-
* Maps a location to its available staff members
|
|
22
|
-
*/
|
|
23
|
-
export interface StaffByLocation {
|
|
24
|
-
location: {
|
|
25
|
-
id: string;
|
|
26
|
-
name: string;
|
|
27
|
-
};
|
|
28
|
-
staffMembers: {
|
|
29
|
-
id: string;
|
|
30
|
-
name: string;
|
|
31
|
-
}[];
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Grouped time slot that represents a unique time with all available locations/staff
|
|
35
|
-
* Extends the API TimeSlot type but replaces location-specific fields with aggregated data
|
|
36
|
-
*/
|
|
37
|
-
export interface TimeSlot extends Omit<ApiTimeSlot, 'location' | 'availableResources'> {
|
|
38
|
-
/** Maps each location to its available staff members */
|
|
39
|
-
staffByLocation: StaffByLocation[];
|
|
40
|
-
/** Original API slots for this time (needed for booking service) */
|
|
41
|
-
originalSlots: ApiTimeSlot[];
|
|
42
|
-
/** Unique identifier for the time slot */
|
|
43
|
-
id: string;
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* User's selection state
|
|
47
|
-
*/
|
|
48
|
-
export interface SlotSelection {
|
|
49
|
-
slot: TimeSlot;
|
|
50
|
-
locationId: string | null;
|
|
51
|
-
staffMemberId: string | null;
|
|
52
|
-
}
|
|
53
20
|
/**
|
|
54
21
|
* Filters for narrowing down available time slots
|
|
55
22
|
* Matches Wix Bookings API filter parameters
|
|
@@ -92,12 +59,12 @@ export interface TimeSlotsFilters {
|
|
|
92
59
|
export interface TimeSlotListServiceConfig {
|
|
93
60
|
/** Services to fetch time slots for */
|
|
94
61
|
services?: Service[];
|
|
95
|
-
/** Pre-loaded time slots (from SSR)
|
|
62
|
+
/** Pre-loaded time slots (from SSR) */
|
|
96
63
|
timeSlots?: TimeSlot[];
|
|
97
64
|
/** Start date for the time range */
|
|
98
|
-
startDate
|
|
65
|
+
startDate: Date;
|
|
99
66
|
/** End date for the time range */
|
|
100
|
-
endDate
|
|
67
|
+
endDate: Date;
|
|
101
68
|
/** Timezone for formatting */
|
|
102
69
|
timezone?: string;
|
|
103
70
|
/** Filters for narrowing down time slots */
|
|
@@ -105,15 +72,13 @@ export interface TimeSlotListServiceConfig {
|
|
|
105
72
|
}
|
|
106
73
|
export interface TimeSlotListServiceActions {
|
|
107
74
|
selectSlot: (slot: TimeSlot) => void;
|
|
108
|
-
selectLocation: (locationId: string) => void;
|
|
109
75
|
selectStaffMember: (staffMemberId: string) => void;
|
|
110
|
-
|
|
76
|
+
clearStaffSelection: () => void;
|
|
111
77
|
loadMore: () => Promise<void>;
|
|
112
78
|
setDateRange: (start: Date, end: Date) => void;
|
|
113
79
|
}
|
|
114
80
|
export interface TimeSlotListServiceAPI {
|
|
115
81
|
timeSlots: Signal<TimeSlot[]>;
|
|
116
|
-
selection: Signal<SlotSelection | null>;
|
|
117
82
|
isLoading: Signal<boolean>;
|
|
118
83
|
error: Signal<string | null>;
|
|
119
84
|
hasMore: Signal<boolean>;
|