@wix/headless-bookings 0.0.89 → 0.0.91
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/react/booking/Book.d.ts +11 -19
- package/cjs/dist/react/booking/Book.js +17 -13
- package/cjs/dist/react/booking/Booking.d.ts +1 -1
- package/cjs/dist/react/booking/Booking.js +1 -1
- package/cjs/dist/react/booking-form/BookingForm.d.ts +5 -2
- package/cjs/dist/react/booking-form/BookingForm.js +3 -2
- package/cjs/dist/react/location/Location.d.ts +3 -4
- package/cjs/dist/react/location/Location.js +6 -6
- package/cjs/dist/react/location/LocationList.d.ts +2 -4
- package/cjs/dist/react/location/LocationList.js +22 -15
- package/cjs/dist/react/service/Service.d.ts +18 -33
- package/cjs/dist/react/service/Service.js +20 -33
- package/cjs/dist/react/staff-member/StaffMember.d.ts +9 -4
- package/cjs/dist/react/staff-member/StaffMember.js +7 -7
- package/cjs/dist/react/staff-member/StaffMemberList.d.ts +9 -4
- package/cjs/dist/react/staff-member/StaffMemberList.js +23 -16
- package/cjs/dist/react/time-slot-list/TimeSlot.d.ts +17 -21
- package/cjs/dist/react/time-slot-list/TimeSlot.js +18 -22
- package/cjs/dist/services/booking/book-action/types.d.ts +3 -3
- package/dist/react/booking/Book.d.ts +11 -19
- package/dist/react/booking/Book.js +17 -13
- package/dist/react/booking/Booking.d.ts +1 -1
- package/dist/react/booking/Booking.js +1 -1
- package/dist/react/booking-form/BookingForm.d.ts +5 -2
- package/dist/react/booking-form/BookingForm.js +3 -2
- package/dist/react/location/Location.d.ts +3 -4
- package/dist/react/location/Location.js +6 -6
- package/dist/react/location/LocationList.d.ts +2 -4
- package/dist/react/location/LocationList.js +22 -15
- package/dist/react/service/Service.d.ts +18 -33
- package/dist/react/service/Service.js +20 -33
- package/dist/react/staff-member/StaffMember.d.ts +9 -4
- package/dist/react/staff-member/StaffMember.js +7 -7
- package/dist/react/staff-member/StaffMemberList.d.ts +9 -4
- package/dist/react/staff-member/StaffMemberList.js +23 -16
- package/dist/react/time-slot-list/TimeSlot.d.ts +17 -21
- package/dist/react/time-slot-list/TimeSlot.js +18 -22
- package/dist/services/booking/book-action/types.d.ts +3 -3
- package/package.json +5 -5
|
@@ -13,7 +13,7 @@ export { useStaffMemberContext } from '../core/staff-member/StaffMember.js';
|
|
|
13
13
|
// ==========================================
|
|
14
14
|
// TestIds Enum
|
|
15
15
|
// ==========================================
|
|
16
|
-
var TestIds;
|
|
16
|
+
export var TestIds;
|
|
17
17
|
(function (TestIds) {
|
|
18
18
|
TestIds["staffMemberRoot"] = "staff-member-root";
|
|
19
19
|
TestIds["staffMemberName"] = "staff-member-name";
|
|
@@ -106,10 +106,10 @@ Raw.displayName = 'StaffMember.Raw';
|
|
|
106
106
|
* ```tsx
|
|
107
107
|
* <StaffMember.Actions.Select label="Choose Staff Member" />
|
|
108
108
|
*
|
|
109
|
-
* // With
|
|
109
|
+
* // With onClick callback
|
|
110
110
|
* <StaffMember.Actions.Select
|
|
111
111
|
* label="Select"
|
|
112
|
-
*
|
|
112
|
+
* onClick={() => console.log('Staff member selected')}
|
|
113
113
|
* />
|
|
114
114
|
*
|
|
115
115
|
* // With asChild
|
|
@@ -123,19 +123,19 @@ Raw.displayName = 'StaffMember.Raw';
|
|
|
123
123
|
* ```
|
|
124
124
|
*/
|
|
125
125
|
const Select = React.forwardRef((props, ref) => {
|
|
126
|
-
const { asChild, children,
|
|
126
|
+
const { asChild, children, onClick, label, className, ...buttonProps } = props;
|
|
127
127
|
return (_jsx(CoreStaffMember.Actions, { children: ({ select, selected, rawStaffMember }) => {
|
|
128
128
|
const handleClick = () => {
|
|
129
129
|
select();
|
|
130
|
-
if (
|
|
131
|
-
|
|
130
|
+
if (rawStaffMember) {
|
|
131
|
+
onClick?.(rawStaffMember);
|
|
132
132
|
}
|
|
133
133
|
};
|
|
134
134
|
return (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.staffMemberActionSelect, "data-selected": selected, customElement: children, customElementProps: {
|
|
135
135
|
onClick: handleClick,
|
|
136
136
|
selected,
|
|
137
137
|
staffMember: rawStaffMember,
|
|
138
|
-
},
|
|
138
|
+
}, children: _jsx("button", { ...buttonProps, onClick: handleClick, children: children || label }) }));
|
|
139
139
|
} }));
|
|
140
140
|
});
|
|
141
141
|
Select.displayName = 'StaffMember.Actions.Select';
|
|
@@ -9,6 +9,12 @@ import { GenericListRepeaterProps, type ListVariant } from '@wix/headless-compon
|
|
|
9
9
|
import { type AsChildChildren } from '@wix/headless-utils/react';
|
|
10
10
|
import type { StaffMemberListServiceConfig } from '../../services/staff-member-list/staff-member-list.js';
|
|
11
11
|
import type { StaffMemberData } from '../../services/staff-member-list/staff-member-list.def.js';
|
|
12
|
+
export declare enum TestIds {
|
|
13
|
+
staffMemberListRoot = "staff-member-list-root",
|
|
14
|
+
staffMemberListStaffMembers = "staff-member-list-staff-members",
|
|
15
|
+
staffMemberListStaffMember = "staff-member-list-staff-member",
|
|
16
|
+
staffMemberListActionClear = "staff-member-list-action-clear"
|
|
17
|
+
}
|
|
12
18
|
/**
|
|
13
19
|
* Props for the StaffMemberList root component
|
|
14
20
|
*/
|
|
@@ -97,15 +103,14 @@ export declare const Totals: React.ForwardRefExoticComponent<TotalsProps & React
|
|
|
97
103
|
/**
|
|
98
104
|
* Props for StaffMemberList.Actions.Clear component
|
|
99
105
|
*/
|
|
100
|
-
export interface ClearProps {
|
|
106
|
+
export interface ClearProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'children' | 'onClick'> {
|
|
101
107
|
asChild?: boolean;
|
|
102
108
|
children?: React.ReactNode | ((props: {
|
|
103
109
|
onClick: () => void;
|
|
104
110
|
}) => React.ReactNode);
|
|
105
|
-
className?: string;
|
|
106
111
|
label?: string;
|
|
107
|
-
/**
|
|
108
|
-
|
|
112
|
+
/** Called after clearing with the staffMember that was cleared */
|
|
113
|
+
onClick?: (staffMember: StaffMemberData | null) => void;
|
|
109
114
|
}
|
|
110
115
|
/**
|
|
111
116
|
* Actions namespace for staff member list-level actions
|
|
@@ -17,7 +17,7 @@ const STAFF_MEMBER_RESOURCE_TYPE_ID = '1cd44cf8-756f-41c3-bd90-3e2ffcaf1155';
|
|
|
17
17
|
// ============================================================================
|
|
18
18
|
// TestIds
|
|
19
19
|
// ============================================================================
|
|
20
|
-
var TestIds;
|
|
20
|
+
export var TestIds;
|
|
21
21
|
(function (TestIds) {
|
|
22
22
|
TestIds["staffMemberListRoot"] = "staff-member-list-root";
|
|
23
23
|
TestIds["staffMemberListStaffMembers"] = "staff-member-list-staff-members";
|
|
@@ -130,6 +130,11 @@ Totals.displayName = 'StaffMemberList.Totals';
|
|
|
130
130
|
* // With custom label
|
|
131
131
|
* <StaffMemberList.Actions.Clear label="Clear selection" />
|
|
132
132
|
*
|
|
133
|
+
* // With children as button content
|
|
134
|
+
* <StaffMemberList.Actions.Clear className="text-destructive">
|
|
135
|
+
* <span>Reset Staff</span>
|
|
136
|
+
* </StaffMemberList.Actions.Clear>
|
|
137
|
+
*
|
|
133
138
|
* // With asChild
|
|
134
139
|
* <StaffMemberList.Actions.Clear asChild>
|
|
135
140
|
* <button className="btn-secondary">Clear staff</button>
|
|
@@ -142,21 +147,23 @@ Totals.displayName = 'StaffMemberList.Totals';
|
|
|
142
147
|
* ```
|
|
143
148
|
*/
|
|
144
149
|
const Clear = React.forwardRef((props, ref) => {
|
|
145
|
-
const { asChild, children, className, label
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
150
|
+
const { asChild, children, className, label, onClick, ...buttonProps } = props;
|
|
151
|
+
return (_jsx(CoreStaffMemberList.Actions, { children: ({ selectedStaffMember }) => {
|
|
152
|
+
let bookingService = null;
|
|
153
|
+
try {
|
|
154
|
+
bookingService = useService(BookingServiceDefinition);
|
|
155
|
+
}
|
|
156
|
+
catch {
|
|
157
|
+
// BookingService not available - likely no ServiceManagerProvider
|
|
158
|
+
}
|
|
159
|
+
const handleClick = () => {
|
|
160
|
+
bookingService?.actions.clearResourceByType(STAFF_MEMBER_RESOURCE_TYPE_ID);
|
|
161
|
+
onClick?.(selectedStaffMember);
|
|
162
|
+
};
|
|
163
|
+
return (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.staffMemberListActionClear, customElement: children, customElementProps: {
|
|
164
|
+
onClick: handleClick,
|
|
165
|
+
}, children: _jsx("button", { ...buttonProps, onClick: handleClick, children: children || label }) }));
|
|
166
|
+
} }));
|
|
160
167
|
});
|
|
161
168
|
Clear.displayName = 'StaffMemberList.Actions.Clear';
|
|
162
169
|
/**
|
|
@@ -150,16 +150,17 @@ export declare const Duration: React.ForwardRefExoticComponent<DurationProps & R
|
|
|
150
150
|
/**
|
|
151
151
|
* Props for TimeSlot.Actions.Select component
|
|
152
152
|
*/
|
|
153
|
-
export interface SelectProps {
|
|
153
|
+
export interface SelectProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'children' | 'disabled' | 'onClick'> {
|
|
154
154
|
asChild?: boolean;
|
|
155
155
|
children?: React.ReactNode | ((props: {
|
|
156
156
|
isSelected: boolean;
|
|
157
157
|
bookable: boolean;
|
|
158
158
|
onClick: () => void;
|
|
159
|
+
timeSlot: TimeSlotType;
|
|
159
160
|
}) => React.ReactNode);
|
|
160
|
-
className?: string;
|
|
161
161
|
label?: string;
|
|
162
|
-
|
|
162
|
+
/** Called after selection with the selected timeSlot */
|
|
163
|
+
onClick?: (timeSlot: TimeSlotType) => void;
|
|
163
164
|
}
|
|
164
165
|
/**
|
|
165
166
|
* Button to select this time slot.
|
|
@@ -179,11 +180,9 @@ export interface SelectProps {
|
|
|
179
180
|
* <button className="btn-primary">Book this slot</button>
|
|
180
181
|
* </TimeSlot.Actions.Select>
|
|
181
182
|
*
|
|
182
|
-
* // With
|
|
183
|
+
* // With onClick callback
|
|
183
184
|
* <TimeSlot.Actions.Select
|
|
184
|
-
*
|
|
185
|
-
* router.push(`/booking/confirm/${timeSlot.localStartDate}`);
|
|
186
|
-
* }}
|
|
185
|
+
* onClick={() => router.push('/booking/confirm')}
|
|
187
186
|
* />
|
|
188
187
|
*
|
|
189
188
|
* // Using render prop pattern
|
|
@@ -200,14 +199,14 @@ export declare const Select: React.ForwardRefExoticComponent<SelectProps & React
|
|
|
200
199
|
/**
|
|
201
200
|
* Props for TimeSlot.Actions.ClearStaffSelection component
|
|
202
201
|
*/
|
|
203
|
-
export interface ClearStaffSelectionProps {
|
|
202
|
+
export interface ClearStaffSelectionProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'children' | 'onClick'> {
|
|
204
203
|
asChild?: boolean;
|
|
205
204
|
children?: React.ReactNode | ((props: {
|
|
206
205
|
onClick: () => void;
|
|
207
206
|
}) => React.ReactNode);
|
|
208
|
-
className?: string;
|
|
209
207
|
label?: string;
|
|
210
|
-
|
|
208
|
+
/** Called after clearing with the timeSlot whose staff selection was cleared */
|
|
209
|
+
onClick?: (timeSlot: TimeSlotType) => void;
|
|
211
210
|
}
|
|
212
211
|
/**
|
|
213
212
|
* Button to clear staff selection while keeping the slot selected.
|
|
@@ -228,11 +227,9 @@ export interface ClearStaffSelectionProps {
|
|
|
228
227
|
* <button className="btn-secondary">Clear staff</button>
|
|
229
228
|
* </TimeSlot.Actions.ClearStaffSelection>
|
|
230
229
|
*
|
|
231
|
-
* // With
|
|
230
|
+
* // With onClick callback
|
|
232
231
|
* <TimeSlot.Actions.ClearStaffSelection
|
|
233
|
-
*
|
|
234
|
-
* console.log('Staff selection cleared for', timeSlot.localStartDate);
|
|
235
|
-
* }}
|
|
232
|
+
* onClick={() => console.log('Staff selection cleared')}
|
|
236
233
|
* />
|
|
237
234
|
*
|
|
238
235
|
* // Using render prop pattern
|
|
@@ -360,15 +357,16 @@ export declare const StaffMemberName: React.ForwardRefExoticComponent<StaffMembe
|
|
|
360
357
|
/**
|
|
361
358
|
* Props for TimeSlot.StaffMember.Actions.Select component
|
|
362
359
|
*/
|
|
363
|
-
export interface SelectStaffMemberProps {
|
|
360
|
+
export interface SelectStaffMemberProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'children' | 'onClick'> {
|
|
364
361
|
asChild?: boolean;
|
|
365
362
|
children?: React.ReactNode | ((props: {
|
|
366
363
|
isSelected: boolean;
|
|
367
364
|
onClick: () => void;
|
|
365
|
+
staffMember: CoreTimeSlot.StaffMemberData;
|
|
368
366
|
}) => React.ReactNode);
|
|
369
|
-
className?: string;
|
|
370
367
|
label?: string;
|
|
371
|
-
|
|
368
|
+
/** Called after selection with the selected staffMember */
|
|
369
|
+
onClick?: (staffMember: CoreTimeSlot.StaffMemberData) => void;
|
|
372
370
|
}
|
|
373
371
|
/**
|
|
374
372
|
* Button to select this staff member.
|
|
@@ -388,11 +386,9 @@ export interface SelectStaffMemberProps {
|
|
|
388
386
|
* <button className="btn-primary">Choose Staff</button>
|
|
389
387
|
* </TimeSlot.StaffMember.Actions.Select>
|
|
390
388
|
*
|
|
391
|
-
* // With
|
|
389
|
+
* // With onClick callback
|
|
392
390
|
* <TimeSlot.StaffMember.Actions.Select
|
|
393
|
-
*
|
|
394
|
-
* console.log('Selected staff:', staffMember.name);
|
|
395
|
-
* }}
|
|
391
|
+
* onClick={() => console.log('Staff selected')}
|
|
396
392
|
* />
|
|
397
393
|
*
|
|
398
394
|
* // Using render prop pattern
|
|
@@ -159,11 +159,9 @@ Duration.displayName = 'TimeSlot.Duration';
|
|
|
159
159
|
* <button className="btn-primary">Book this slot</button>
|
|
160
160
|
* </TimeSlot.Actions.Select>
|
|
161
161
|
*
|
|
162
|
-
* // With
|
|
162
|
+
* // With onClick callback
|
|
163
163
|
* <TimeSlot.Actions.Select
|
|
164
|
-
*
|
|
165
|
-
* router.push(`/booking/confirm/${timeSlot.localStartDate}`);
|
|
166
|
-
* }}
|
|
164
|
+
* onClick={() => router.push('/booking/confirm')}
|
|
167
165
|
* />
|
|
168
166
|
*
|
|
169
167
|
* // Using render prop pattern
|
|
@@ -177,18 +175,19 @@ Duration.displayName = 'TimeSlot.Duration';
|
|
|
177
175
|
* ```
|
|
178
176
|
*/
|
|
179
177
|
export const Select = React.forwardRef((props, ref) => {
|
|
180
|
-
const { asChild, children, className, label
|
|
181
|
-
return (_jsx(CoreTimeSlot.Actions, { children: ({ selectTimeSlot, isSelected, bookable
|
|
178
|
+
const { asChild, children, className, label, onClick, ...buttonProps } = props;
|
|
179
|
+
return (_jsx(CoreTimeSlot.Actions, { children: ({ selectTimeSlot, timeSlot, isSelected, bookable }) => {
|
|
182
180
|
const handleClick = () => {
|
|
183
181
|
selectTimeSlot();
|
|
184
|
-
|
|
182
|
+
onClick?.(timeSlot);
|
|
185
183
|
};
|
|
186
184
|
return (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.timeSlotActionSelect, "data-selected": isSelected, "data-bookable": bookable, customElement: children, customElementProps: {
|
|
187
185
|
onClick: handleClick,
|
|
188
186
|
disabled: !bookable,
|
|
189
187
|
isSelected,
|
|
190
188
|
bookable,
|
|
191
|
-
|
|
189
|
+
timeSlot,
|
|
190
|
+
}, children: _jsx("button", { ...buttonProps, onClick: handleClick, disabled: !bookable, children: children || label }) }));
|
|
192
191
|
} }));
|
|
193
192
|
});
|
|
194
193
|
Select.displayName = 'TimeSlot.Actions.Select';
|
|
@@ -211,11 +210,9 @@ Select.displayName = 'TimeSlot.Actions.Select';
|
|
|
211
210
|
* <button className="btn-secondary">Clear staff</button>
|
|
212
211
|
* </TimeSlot.Actions.ClearStaffSelection>
|
|
213
212
|
*
|
|
214
|
-
* // With
|
|
213
|
+
* // With onClick callback
|
|
215
214
|
* <TimeSlot.Actions.ClearStaffSelection
|
|
216
|
-
*
|
|
217
|
-
* console.log('Staff selection cleared for', timeSlot.localStartDate);
|
|
218
|
-
* }}
|
|
215
|
+
* onClick={() => console.log('Staff selection cleared')}
|
|
219
216
|
* />
|
|
220
217
|
*
|
|
221
218
|
* // Using render prop pattern
|
|
@@ -225,18 +222,18 @@ Select.displayName = 'TimeSlot.Actions.Select';
|
|
|
225
222
|
* ```
|
|
226
223
|
*/
|
|
227
224
|
export const ClearStaffSelection = React.forwardRef((props, ref) => {
|
|
228
|
-
const { asChild, children, className, label
|
|
225
|
+
const { asChild, children, className, label, onClick, ...buttonProps } = props;
|
|
229
226
|
return (_jsx(CoreTimeSlot.Actions, { children: ({ clearStaffSelection, timeSlot }) => {
|
|
230
227
|
if (!clearStaffSelection) {
|
|
231
228
|
return null;
|
|
232
229
|
}
|
|
233
230
|
const handleClick = () => {
|
|
234
231
|
clearStaffSelection();
|
|
235
|
-
|
|
232
|
+
onClick?.(timeSlot);
|
|
236
233
|
};
|
|
237
234
|
return (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.timeSlotActionClearStaffSelection, customElement: children, customElementProps: {
|
|
238
235
|
onClick: handleClick,
|
|
239
|
-
}, children: _jsx("button", { onClick: handleClick, children: label }) }));
|
|
236
|
+
}, children: _jsx("button", { ...buttonProps, onClick: handleClick, children: children || label }) }));
|
|
240
237
|
} }));
|
|
241
238
|
});
|
|
242
239
|
ClearStaffSelection.displayName = 'TimeSlot.Actions.ClearStaffSelection';
|
|
@@ -366,11 +363,9 @@ StaffMemberName.displayName = 'TimeSlot.StaffMember.Name';
|
|
|
366
363
|
* <button className="btn-primary">Choose Staff</button>
|
|
367
364
|
* </TimeSlot.StaffMember.Actions.Select>
|
|
368
365
|
*
|
|
369
|
-
* // With
|
|
366
|
+
* // With onClick callback
|
|
370
367
|
* <TimeSlot.StaffMember.Actions.Select
|
|
371
|
-
*
|
|
372
|
-
* console.log('Selected staff:', staffMember.name);
|
|
373
|
-
* }}
|
|
368
|
+
* onClick={() => console.log('Staff selected')}
|
|
374
369
|
* />
|
|
375
370
|
*
|
|
376
371
|
* // Using render prop pattern
|
|
@@ -384,16 +379,17 @@ StaffMemberName.displayName = 'TimeSlot.StaffMember.Name';
|
|
|
384
379
|
* ```
|
|
385
380
|
*/
|
|
386
381
|
export const SelectStaffMember = React.forwardRef((props, ref) => {
|
|
387
|
-
const { asChild, children, className, label
|
|
382
|
+
const { asChild, children, className, label, onClick, ...buttonProps } = props;
|
|
388
383
|
return (_jsx(CoreTimeSlot.StaffMemberActions, { children: ({ selectStaffMember, isSelected, staffMember }) => {
|
|
389
384
|
const handleClick = () => {
|
|
390
385
|
selectStaffMember();
|
|
391
|
-
|
|
386
|
+
onClick?.(staffMember);
|
|
392
387
|
};
|
|
393
388
|
return (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.timeSlotStaffMemberActionSelect, "data-selected": isSelected, customElement: children, customElementProps: {
|
|
394
389
|
onClick: handleClick,
|
|
395
390
|
isSelected,
|
|
396
|
-
|
|
391
|
+
staffMember,
|
|
392
|
+
}, children: _jsx("button", { ...buttonProps, onClick: handleClick, children: children || label }) }));
|
|
397
393
|
} }));
|
|
398
394
|
});
|
|
399
395
|
SelectStaffMember.displayName = 'TimeSlot.StaffMember.Actions.Select';
|
|
@@ -62,9 +62,9 @@ export interface BookProps {
|
|
|
62
62
|
* The navigateToCheckout function has the checkoutId captured - just call it.
|
|
63
63
|
* When navigateToCheckout is called, the button will show loading state until navigation completes.
|
|
64
64
|
*/
|
|
65
|
-
onCheckout?: (
|
|
66
|
-
|
|
67
|
-
}) => void;
|
|
65
|
+
onCheckout?: (navigateToCheckout: (options: {
|
|
66
|
+
postFlowUrl: string;
|
|
67
|
+
}) => Promise<void>) => void;
|
|
68
68
|
/**
|
|
69
69
|
* Called when booking completes without requiring checkout (free/offline services).
|
|
70
70
|
* Receives the orderId which can be used to display confirmation or navigate to a thank you page.
|
|
@@ -7,28 +7,23 @@ import type { BookChildProps, BookingError } from '../../services/booking/book-a
|
|
|
7
7
|
/**
|
|
8
8
|
* Props for the high-level Book component
|
|
9
9
|
*/
|
|
10
|
-
export interface BookProps {
|
|
10
|
+
export interface BookProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'children' | 'disabled' | 'onError' | 'onClick'> {
|
|
11
11
|
asChild?: boolean;
|
|
12
12
|
children?: React.ReactNode | ((props: BookChildProps) => React.ReactNode);
|
|
13
|
-
className?: string;
|
|
14
13
|
label?: string;
|
|
15
14
|
loadingState?: string;
|
|
16
15
|
disabled?: boolean;
|
|
17
|
-
/**
|
|
18
|
-
* URL to redirect to after the checkout flow completes.
|
|
19
|
-
* Required for navigating to checkout.
|
|
20
|
-
*/
|
|
21
|
-
postFlowUrl: string;
|
|
22
16
|
/**
|
|
23
17
|
* Called when checkout is required for payment.
|
|
18
|
+
* Receives navigateToCheckout function that accepts postFlowUrl.
|
|
24
19
|
* The navigateToCheckout function already has the checkoutId captured - just call it to navigate.
|
|
25
20
|
*
|
|
26
21
|
* To keep loading active during navigation, return navigateToCheckout():
|
|
27
|
-
* `onCheckout={(
|
|
22
|
+
* `onCheckout={(navigateToCheckout) => navigateToCheckout({ postFlowUrl: '/thank-you' })}`
|
|
28
23
|
*/
|
|
29
|
-
onCheckout?: (
|
|
30
|
-
|
|
31
|
-
}) => void | Promise<unknown>;
|
|
24
|
+
onCheckout?: (navigateToCheckout: (options: {
|
|
25
|
+
postFlowUrl: string;
|
|
26
|
+
}) => Promise<void>) => void | Promise<unknown>;
|
|
32
27
|
/**
|
|
33
28
|
* Called when booking completes without requiring checkout (free/offline services).
|
|
34
29
|
* Receives the orderId which can be used to display confirmation or navigate to a thank you page.
|
|
@@ -39,6 +34,7 @@ export interface BookProps {
|
|
|
39
34
|
orderId: string;
|
|
40
35
|
}) => void | Promise<unknown>;
|
|
41
36
|
onError?: (error: BookingError) => void;
|
|
37
|
+
onClick?: (data: BookChildProps) => void;
|
|
42
38
|
}
|
|
43
39
|
/**
|
|
44
40
|
* Book action button component with AsChildSlot pattern.
|
|
@@ -53,22 +49,19 @@ export interface BookProps {
|
|
|
53
49
|
* ```tsx
|
|
54
50
|
* // Basic usage - call navigateToCheckout when ready
|
|
55
51
|
* <Booking.Actions.Book
|
|
56
|
-
* postFlowUrl
|
|
57
|
-
* onCheckout={({ navigateToCheckout }) => navigateToCheckout()}
|
|
52
|
+
* onCheckout={(navigateToCheckout) => navigateToCheckout({ postFlowUrl: '/thank-you' })}
|
|
58
53
|
* />
|
|
59
54
|
*
|
|
60
55
|
* // With callbacks
|
|
61
56
|
* <Booking.Actions.Book
|
|
62
|
-
* postFlowUrl
|
|
63
|
-
* onCheckout={({ navigateToCheckout }) => navigateToCheckout()}
|
|
57
|
+
* onCheckout={(navigateToCheckout) => navigateToCheckout({ postFlowUrl: '/thank-you' })}
|
|
64
58
|
* onComplete={({ orderId }) => navigate(`/thank-you?orderId=${orderId}`)}
|
|
65
59
|
* onError={(error) => console.error(error.message)}
|
|
66
60
|
* />
|
|
67
61
|
*
|
|
68
62
|
* // With render function
|
|
69
63
|
* <Booking.Actions.Book
|
|
70
|
-
* postFlowUrl
|
|
71
|
-
* onCheckout={({ navigateToCheckout }) => navigateToCheckout()}
|
|
64
|
+
* onCheckout={(navigateToCheckout) => navigateToCheckout({ postFlowUrl: '/thank-you' })}
|
|
72
65
|
* onComplete={({ orderId }) => navigate(`/thank-you?orderId=${orderId}`)}
|
|
73
66
|
* >
|
|
74
67
|
* {({ isLoading, error, canBook, onClick, disabled }) => (
|
|
@@ -81,8 +74,7 @@ export interface BookProps {
|
|
|
81
74
|
* // With asChild
|
|
82
75
|
* <Booking.Actions.Book
|
|
83
76
|
* asChild
|
|
84
|
-
* postFlowUrl
|
|
85
|
-
* onCheckout={({ navigateToCheckout }) => navigateToCheckout()}
|
|
77
|
+
* onCheckout={(navigateToCheckout) => navigateToCheckout({ postFlowUrl: '/thank-you' })}
|
|
86
78
|
* onComplete={({ orderId }) => navigate(`/thank-you?orderId=${orderId}`)}
|
|
87
79
|
* >
|
|
88
80
|
* <CustomBookButton />
|
|
@@ -24,22 +24,19 @@ var TestIds;
|
|
|
24
24
|
* ```tsx
|
|
25
25
|
* // Basic usage - call navigateToCheckout when ready
|
|
26
26
|
* <Booking.Actions.Book
|
|
27
|
-
* postFlowUrl
|
|
28
|
-
* onCheckout={({ navigateToCheckout }) => navigateToCheckout()}
|
|
27
|
+
* onCheckout={(navigateToCheckout) => navigateToCheckout({ postFlowUrl: '/thank-you' })}
|
|
29
28
|
* />
|
|
30
29
|
*
|
|
31
30
|
* // With callbacks
|
|
32
31
|
* <Booking.Actions.Book
|
|
33
|
-
* postFlowUrl
|
|
34
|
-
* onCheckout={({ navigateToCheckout }) => navigateToCheckout()}
|
|
32
|
+
* onCheckout={(navigateToCheckout) => navigateToCheckout({ postFlowUrl: '/thank-you' })}
|
|
35
33
|
* onComplete={({ orderId }) => navigate(`/thank-you?orderId=${orderId}`)}
|
|
36
34
|
* onError={(error) => console.error(error.message)}
|
|
37
35
|
* />
|
|
38
36
|
*
|
|
39
37
|
* // With render function
|
|
40
38
|
* <Booking.Actions.Book
|
|
41
|
-
* postFlowUrl
|
|
42
|
-
* onCheckout={({ navigateToCheckout }) => navigateToCheckout()}
|
|
39
|
+
* onCheckout={(navigateToCheckout) => navigateToCheckout({ postFlowUrl: '/thank-you' })}
|
|
43
40
|
* onComplete={({ orderId }) => navigate(`/thank-you?orderId=${orderId}`)}
|
|
44
41
|
* >
|
|
45
42
|
* {({ isLoading, error, canBook, onClick, disabled }) => (
|
|
@@ -52,8 +49,7 @@ var TestIds;
|
|
|
52
49
|
* // With asChild
|
|
53
50
|
* <Booking.Actions.Book
|
|
54
51
|
* asChild
|
|
55
|
-
* postFlowUrl
|
|
56
|
-
* onCheckout={({ navigateToCheckout }) => navigateToCheckout()}
|
|
52
|
+
* onCheckout={(navigateToCheckout) => navigateToCheckout({ postFlowUrl: '/thank-you' })}
|
|
57
53
|
* onComplete={({ orderId }) => navigate(`/thank-you?orderId=${orderId}`)}
|
|
58
54
|
* >
|
|
59
55
|
* <CustomBookButton />
|
|
@@ -61,17 +57,25 @@ var TestIds;
|
|
|
61
57
|
* ```
|
|
62
58
|
*/
|
|
63
59
|
export const Book = React.forwardRef((props, ref) => {
|
|
64
|
-
const { asChild, children, className, label
|
|
60
|
+
const { asChild, children, className, label, loadingState, disabled, onCheckout, onComplete, onError, onClick, ...buttonProps } = props;
|
|
65
61
|
return (_jsx(CoreBook.Book, { onCheckout: (result) => {
|
|
66
62
|
// Create navigateToCheckout with checkoutId captured
|
|
67
|
-
const navigateToCheckout = () => navigateToCheckoutUtil({
|
|
63
|
+
const navigateToCheckout = (options) => navigateToCheckoutUtil({
|
|
68
64
|
checkoutId: result.checkoutId,
|
|
69
|
-
navigationInfo: { postFlowUrl },
|
|
65
|
+
navigationInfo: { postFlowUrl: options.postFlowUrl },
|
|
70
66
|
});
|
|
71
67
|
// Return user's callback result so core can await it
|
|
72
|
-
return onCheckout?.(
|
|
68
|
+
return onCheckout?.(navigateToCheckout);
|
|
73
69
|
}, onComplete: (result) => {
|
|
74
70
|
return onComplete?.({ orderId: result.orderId });
|
|
75
|
-
}, onError: onError, disabled: disabled, children: (childProps) =>
|
|
71
|
+
}, onError: onError, disabled: disabled, children: (childProps) => {
|
|
72
|
+
const handleClick = () => {
|
|
73
|
+
childProps.onClick();
|
|
74
|
+
onClick?.(childProps);
|
|
75
|
+
};
|
|
76
|
+
return (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.bookingActionBook, "data-in-progress": childProps.isLoading, customElement: children, customElementProps: childProps, children: _jsx("button", { ...buttonProps, onClick: handleClick, disabled: childProps.disabled, children: childProps.isLoading
|
|
77
|
+
? loadingState
|
|
78
|
+
: children || label }) }));
|
|
79
|
+
} }));
|
|
76
80
|
});
|
|
77
81
|
Book.displayName = 'Booking.Actions.Book';
|
|
@@ -46,7 +46,7 @@ export declare const Root: {
|
|
|
46
46
|
*
|
|
47
47
|
* // With callbacks - navigateToCheckout has checkoutId captured, triggers loading when called
|
|
48
48
|
* <Booking.Actions.Book
|
|
49
|
-
* onCheckout={(
|
|
49
|
+
* onCheckout={(navigateToCheckout) => navigateToCheckout({ postFlowUrl: '/thank-you' })}
|
|
50
50
|
* onComplete={({ orderId }) => navigate(`/thank-you?orderId=${orderId}`)}
|
|
51
51
|
* onError={(error) => toast.error(error.message)}
|
|
52
52
|
* />
|
|
@@ -61,7 +61,7 @@ Root.displayName = 'Booking.Root';
|
|
|
61
61
|
*
|
|
62
62
|
* // With callbacks - navigateToCheckout has checkoutId captured, triggers loading when called
|
|
63
63
|
* <Booking.Actions.Book
|
|
64
|
-
* onCheckout={(
|
|
64
|
+
* onCheckout={(navigateToCheckout) => navigateToCheckout({ postFlowUrl: '/thank-you' })}
|
|
65
65
|
* onComplete={({ orderId }) => navigate(`/thank-you?orderId=${orderId}`)}
|
|
66
66
|
* onError={(error) => toast.error(error.message)}
|
|
67
67
|
* />
|
|
@@ -105,20 +105,23 @@ export declare const Fields: React.ForwardRefExoticComponent<FieldsProps & React
|
|
|
105
105
|
/**
|
|
106
106
|
* Props for BookingForm.Actions.ValidateFormSubmission component
|
|
107
107
|
*/
|
|
108
|
-
export interface ValidateFormSubmissionProps {
|
|
108
|
+
export interface ValidateFormSubmissionProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'children' | 'onClick'> {
|
|
109
109
|
asChild?: boolean;
|
|
110
110
|
children?: React.ReactNode | ((props: {
|
|
111
111
|
onClick: () => Promise<void>;
|
|
112
112
|
valid: boolean | null;
|
|
113
113
|
validationFailures: string[];
|
|
114
114
|
}) => React.ReactNode);
|
|
115
|
-
className?: string;
|
|
116
115
|
label?: string;
|
|
117
116
|
/** Callback when validation completes */
|
|
118
117
|
onValidationComplete?: (result: {
|
|
119
118
|
valid: boolean;
|
|
120
119
|
validationFailures: string[];
|
|
121
120
|
}) => void;
|
|
121
|
+
onClick?: (result: {
|
|
122
|
+
valid: boolean;
|
|
123
|
+
validationFailures: string[];
|
|
124
|
+
}) => void;
|
|
122
125
|
}
|
|
123
126
|
/**
|
|
124
127
|
* Button to validate the booking form submission.
|
|
@@ -171,7 +171,7 @@ Fields.displayName = 'BookingForm.Fields';
|
|
|
171
171
|
* ```
|
|
172
172
|
*/
|
|
173
173
|
export const ValidateFormSubmission = React.forwardRef((props, ref) => {
|
|
174
|
-
const { asChild, children, className, label
|
|
174
|
+
const { asChild, children, className, label, onValidationComplete, onClick, ...buttonProps } = props;
|
|
175
175
|
const [valid, setValid] = React.useState(null);
|
|
176
176
|
const [validationFailures, setValidationFailures] = React.useState([]);
|
|
177
177
|
return (_jsx(CoreBookingForm.Actions, { children: ({ validateFormSubmission }) => {
|
|
@@ -182,12 +182,13 @@ export const ValidateFormSubmission = React.forwardRef((props, ref) => {
|
|
|
182
182
|
if (onValidationComplete) {
|
|
183
183
|
onValidationComplete(result);
|
|
184
184
|
}
|
|
185
|
+
onClick?.(result);
|
|
185
186
|
};
|
|
186
187
|
return (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.bookingFormActionValidateFormSubmission, "data-valid": valid, customElement: children, customElementProps: {
|
|
187
188
|
onClick: handleClick,
|
|
188
189
|
valid,
|
|
189
190
|
validationFailures,
|
|
190
|
-
}, children: _jsx("button", { onClick: handleClick, children: label }) }));
|
|
191
|
+
}, children: _jsx("button", { ...buttonProps, onClick: handleClick, children: children || label }) }));
|
|
191
192
|
} }));
|
|
192
193
|
});
|
|
193
194
|
ValidateFormSubmission.displayName =
|
|
@@ -229,18 +229,17 @@ export declare const Raw: React.FC<RawProps>;
|
|
|
229
229
|
/**
|
|
230
230
|
* Props for Location.Actions.Select component
|
|
231
231
|
*/
|
|
232
|
-
export interface SelectProps {
|
|
232
|
+
export interface SelectProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'children' | 'onClick'> {
|
|
233
233
|
asChild?: boolean;
|
|
234
234
|
children?: React.ReactNode | AsChildChildren<{
|
|
235
235
|
onClick: () => void;
|
|
236
236
|
selected: boolean;
|
|
237
237
|
location: CoreLocation.Location | null;
|
|
238
238
|
}>;
|
|
239
|
-
/** Callback fired after location is selected - receives the location */
|
|
240
|
-
onClicked?: (location: CoreLocation.Location) => void;
|
|
241
239
|
/** Label for the button */
|
|
242
240
|
label?: string;
|
|
243
|
-
|
|
241
|
+
/** Called after selection with the selected location */
|
|
242
|
+
onClick?: (location: CoreLocation.Location) => void;
|
|
244
243
|
}
|
|
245
244
|
/**
|
|
246
245
|
* Actions namespace for location-related actions
|
|
@@ -227,10 +227,10 @@ Raw.displayName = 'Location.Raw';
|
|
|
227
227
|
* ```tsx
|
|
228
228
|
* <Location.Actions.Select label="Choose Location" />
|
|
229
229
|
*
|
|
230
|
-
* // With
|
|
230
|
+
* // With onClick callback
|
|
231
231
|
* <Location.Actions.Select
|
|
232
232
|
* label="Select"
|
|
233
|
-
*
|
|
233
|
+
* onClick={() => navigate('/time-slots')}
|
|
234
234
|
* />
|
|
235
235
|
*
|
|
236
236
|
* // With asChild
|
|
@@ -244,19 +244,19 @@ Raw.displayName = 'Location.Raw';
|
|
|
244
244
|
* ```
|
|
245
245
|
*/
|
|
246
246
|
const Select = React.forwardRef((props, ref) => {
|
|
247
|
-
const { asChild, children,
|
|
247
|
+
const { asChild, children, onClick, label, className, ...buttonProps } = props;
|
|
248
248
|
return (_jsx(CoreLocation.Actions, { children: ({ select, selected, rawLocation }) => {
|
|
249
249
|
const handleClick = () => {
|
|
250
250
|
select();
|
|
251
|
-
if (
|
|
252
|
-
|
|
251
|
+
if (rawLocation) {
|
|
252
|
+
onClick?.(rawLocation);
|
|
253
253
|
}
|
|
254
254
|
};
|
|
255
255
|
return (_jsx(AsChildSlot, { ref: ref, asChild: asChild, className: className, "data-testid": TestIds.locationActionSelect, "data-selected": selected, customElement: children, customElementProps: {
|
|
256
256
|
onClick: handleClick,
|
|
257
257
|
selected,
|
|
258
258
|
location: rawLocation,
|
|
259
|
-
},
|
|
259
|
+
}, children: _jsx("button", { ...buttonProps, onClick: handleClick, children: children || label }) }));
|
|
260
260
|
} }));
|
|
261
261
|
});
|
|
262
262
|
Select.displayName = 'Location.Actions.Select';
|