@bookinglab/booking-ui-react 1.5.0 → 1.6.0
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/README.md +83 -0
- package/dist/index.d.cts +73 -1
- package/dist/index.d.ts +73 -1
- package/dist/index.js +172 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +172 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -481,6 +481,85 @@ const formRef = useRef<ContactDetailsFormRef>(null);
|
|
|
481
481
|
|
|
482
482
|
---
|
|
483
483
|
|
|
484
|
+
## ResetPasswordForm
|
|
485
|
+
|
|
486
|
+
A reusable password reset form with current password, new password, and confirm new password fields. Includes built-in validation, customizable submit button text, and programmatic control via ref.
|
|
487
|
+
|
|
488
|
+
### Props
|
|
489
|
+
|
|
490
|
+
| Prop | Type | Default | Description |
|
|
491
|
+
|------|------|---------|-------------|
|
|
492
|
+
| `onSubmit` | `(values: ResetPasswordFormValues) => void` | required | Called with all 3 values on valid submit |
|
|
493
|
+
| `onChange` | `(values: Partial<ResetPasswordFormValues>, isValid: boolean) => void` | `undefined` | Called on every field change |
|
|
494
|
+
| `submitLabel` | `string` | `"Update Password"` | Text for the submit button |
|
|
495
|
+
| `validateOnBlur` | `boolean` | `true` | Whether to validate fields on blur |
|
|
496
|
+
| `className` | `string` | `""` | Class name for the form element |
|
|
497
|
+
| `classNames` | `ResetPasswordFormClassNames` | `undefined` | Custom class names for styling |
|
|
498
|
+
|
|
499
|
+
### Fields
|
|
500
|
+
|
|
501
|
+
| Field | Label | Required | Validation |
|
|
502
|
+
|-------|-------|----------|------------|
|
|
503
|
+
| `currentPassword` | Current Password | Yes | required |
|
|
504
|
+
| `newPassword` | New Password | Yes | required |
|
|
505
|
+
| `confirmNewPassword` | Confirm New Password | Yes | required, must match New Password |
|
|
506
|
+
|
|
507
|
+
### Usage
|
|
508
|
+
|
|
509
|
+
```tsx
|
|
510
|
+
import { useRef } from 'react';
|
|
511
|
+
import {
|
|
512
|
+
ResetPasswordForm,
|
|
513
|
+
ResetPasswordFormRef,
|
|
514
|
+
ResetPasswordFormValues,
|
|
515
|
+
} from '@bookinglab/booking-ui-react';
|
|
516
|
+
|
|
517
|
+
function MyComponent() {
|
|
518
|
+
const formRef = useRef<ResetPasswordFormRef>(null);
|
|
519
|
+
|
|
520
|
+
const handleSubmit = (values: ResetPasswordFormValues) => {
|
|
521
|
+
console.log('Password reset:', values);
|
|
522
|
+
// { currentPassword: '...', newPassword: '...', confirmNewPassword: '...' }
|
|
523
|
+
};
|
|
524
|
+
|
|
525
|
+
return (
|
|
526
|
+
<>
|
|
527
|
+
<ResetPasswordForm
|
|
528
|
+
ref={formRef}
|
|
529
|
+
onSubmit={handleSubmit}
|
|
530
|
+
submitLabel="Change Password"
|
|
531
|
+
/>
|
|
532
|
+
<button onClick={() => formRef.current?.reset()}>Reset</button>
|
|
533
|
+
</>
|
|
534
|
+
);
|
|
535
|
+
}
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
### Ref Methods
|
|
539
|
+
|
|
540
|
+
| Method | Description |
|
|
541
|
+
|--------|-------------|
|
|
542
|
+
| `reset()` | Clear all values, errors, and touched state |
|
|
543
|
+
| `setValues(values)` | Programmatically set field values |
|
|
544
|
+
|
|
545
|
+
### Styling
|
|
546
|
+
|
|
547
|
+
```tsx
|
|
548
|
+
<ResetPasswordForm
|
|
549
|
+
onSubmit={handleSubmit}
|
|
550
|
+
classNames={{
|
|
551
|
+
fieldWrapper: 'mb-6',
|
|
552
|
+
label: 'text-white font-bold',
|
|
553
|
+
input: 'border-2 border-gray-400 rounded-lg p-3',
|
|
554
|
+
inputError: 'border-red-500',
|
|
555
|
+
errorText: 'text-red-400 text-sm',
|
|
556
|
+
button: 'bg-primary text-white py-3 px-6 rounded-lg',
|
|
557
|
+
}}
|
|
558
|
+
/>
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
---
|
|
562
|
+
|
|
484
563
|
## Requirements
|
|
485
564
|
|
|
486
565
|
- React 17.0.0 or higher
|
|
@@ -515,6 +594,10 @@ import type {
|
|
|
515
594
|
ContactDetailsFieldSettings,
|
|
516
595
|
ContactDetailsInitialValues,
|
|
517
596
|
ContactFieldSettings,
|
|
597
|
+
ResetPasswordFormProps,
|
|
598
|
+
ResetPasswordFormRef,
|
|
599
|
+
ResetPasswordFormValues,
|
|
600
|
+
ResetPasswordFormClassNames,
|
|
518
601
|
} from '@bookinglab/booking-ui-react';
|
|
519
602
|
```
|
|
520
603
|
|
package/dist/index.d.cts
CHANGED
|
@@ -218,6 +218,58 @@ interface ContactDetailsFormRef {
|
|
|
218
218
|
}>) => void;
|
|
219
219
|
}
|
|
220
220
|
|
|
221
|
+
/**
|
|
222
|
+
* Values emitted by the ResetPasswordForm on submit
|
|
223
|
+
*/
|
|
224
|
+
interface ResetPasswordFormValues {
|
|
225
|
+
currentPassword: string;
|
|
226
|
+
newPassword: string;
|
|
227
|
+
confirmNewPassword: string;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Custom class names for styling ResetPasswordForm elements
|
|
231
|
+
*/
|
|
232
|
+
interface ResetPasswordFormClassNames {
|
|
233
|
+
/** Wrapper for each form field */
|
|
234
|
+
fieldWrapper?: string;
|
|
235
|
+
/** All labels */
|
|
236
|
+
label?: string;
|
|
237
|
+
/** All input elements */
|
|
238
|
+
input?: string;
|
|
239
|
+
/** Input elements in error state */
|
|
240
|
+
inputError?: string;
|
|
241
|
+
/** Error message text */
|
|
242
|
+
errorText?: string;
|
|
243
|
+
/** Submit button */
|
|
244
|
+
button?: string;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Props for the ResetPasswordForm component
|
|
248
|
+
*/
|
|
249
|
+
interface ResetPasswordFormProps {
|
|
250
|
+
/** Called with all 3 password values on valid submit */
|
|
251
|
+
onSubmit: (values: ResetPasswordFormValues) => void;
|
|
252
|
+
/** Called on every field change with current values and validity */
|
|
253
|
+
onChange?: (values: Partial<ResetPasswordFormValues>, isValid: boolean) => void;
|
|
254
|
+
/** Whether to validate on blur (default: true) */
|
|
255
|
+
validateOnBlur?: boolean;
|
|
256
|
+
/** Text for the submit button (default: "Update Password") */
|
|
257
|
+
submitLabel?: string;
|
|
258
|
+
/** Class name for the form element */
|
|
259
|
+
className?: string;
|
|
260
|
+
/** Custom class names for styling individual elements */
|
|
261
|
+
classNames?: ResetPasswordFormClassNames;
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Imperative handle methods exposed via ref
|
|
265
|
+
*/
|
|
266
|
+
interface ResetPasswordFormRef {
|
|
267
|
+
/** Reset all form values and errors */
|
|
268
|
+
reset: () => void;
|
|
269
|
+
/** Programmatically set form values */
|
|
270
|
+
setValues: (values: Partial<ResetPasswordFormValues>) => void;
|
|
271
|
+
}
|
|
272
|
+
|
|
221
273
|
interface QuestionOption {
|
|
222
274
|
id: number;
|
|
223
275
|
name: string;
|
|
@@ -355,6 +407,26 @@ declare const RegistrationForm: React.ForwardRefExoticComponent<RegistrationForm
|
|
|
355
407
|
*/
|
|
356
408
|
declare const ContactDetailsForm: React.ForwardRefExoticComponent<ContactDetailsFormProps & React.RefAttributes<ContactDetailsFormRef>>;
|
|
357
409
|
|
|
410
|
+
/**
|
|
411
|
+
* A reusable, accessible reset-password form component.
|
|
412
|
+
*
|
|
413
|
+
* Features:
|
|
414
|
+
* - Three password fields: Current, New, Confirm New
|
|
415
|
+
* - Validation: all required; confirm must match new password
|
|
416
|
+
* - forwardRef for programmatic reset()/setValues()
|
|
417
|
+
* - onChange callback with live validity
|
|
418
|
+
* - Granular styling via classNames prop
|
|
419
|
+
*
|
|
420
|
+
* @example
|
|
421
|
+
* ```tsx
|
|
422
|
+
* <ResetPasswordForm
|
|
423
|
+
* onSubmit={(values) => console.log(values)}
|
|
424
|
+
* submitLabel="Change Password"
|
|
425
|
+
* />
|
|
426
|
+
* ```
|
|
427
|
+
*/
|
|
428
|
+
declare const ResetPasswordForm: React.ForwardRefExoticComponent<ResetPasswordFormProps & React.RefAttributes<ResetPasswordFormRef>>;
|
|
429
|
+
|
|
358
430
|
/**
|
|
359
431
|
* Validation helper functions for form fields
|
|
360
432
|
* Each validator returns an error message string if invalid, or null if valid
|
|
@@ -388,4 +460,4 @@ declare function minLen(min: number): (value: string) => string | null;
|
|
|
388
460
|
*/
|
|
389
461
|
declare function compose(...validators: Array<(value: string) => string | null>): (value: string) => string | null;
|
|
390
462
|
|
|
391
|
-
export { BookingForm, type BookingFormClassNames, type BookingFormProps, type BookingUIConfig, type ContactDetailsAnswerEntry, type ContactDetailsFieldSettings, ContactDetailsForm, type ContactDetailsFormClassNames, type ContactDetailsFormProps, type ContactDetailsFormRef, type ContactDetailsInitialValues, type ContactDetailsQuestionEntry, type ContactDetailsValues, type ContactFieldSettings, type FieldConfig, type FieldOption, type FormErrors, type FormValues, type Question, type QuestionOption, type QuestionSettings, RegistrationForm, type RegistrationFormClassNames, type RegistrationFormErrors, type RegistrationFormProps, type RegistrationFormRef, type RegistrationFormValues, compose, email, minLen, phone, required, ukPostcode };
|
|
463
|
+
export { BookingForm, type BookingFormClassNames, type BookingFormProps, type BookingUIConfig, type ContactDetailsAnswerEntry, type ContactDetailsFieldSettings, ContactDetailsForm, type ContactDetailsFormClassNames, type ContactDetailsFormProps, type ContactDetailsFormRef, type ContactDetailsInitialValues, type ContactDetailsQuestionEntry, type ContactDetailsValues, type ContactFieldSettings, type FieldConfig, type FieldOption, type FormErrors, type FormValues, type Question, type QuestionOption, type QuestionSettings, RegistrationForm, type RegistrationFormClassNames, type RegistrationFormErrors, type RegistrationFormProps, type RegistrationFormRef, type RegistrationFormValues, ResetPasswordForm, type ResetPasswordFormClassNames, type ResetPasswordFormProps, type ResetPasswordFormRef, type ResetPasswordFormValues, compose, email, minLen, phone, required, ukPostcode };
|
package/dist/index.d.ts
CHANGED
|
@@ -218,6 +218,58 @@ interface ContactDetailsFormRef {
|
|
|
218
218
|
}>) => void;
|
|
219
219
|
}
|
|
220
220
|
|
|
221
|
+
/**
|
|
222
|
+
* Values emitted by the ResetPasswordForm on submit
|
|
223
|
+
*/
|
|
224
|
+
interface ResetPasswordFormValues {
|
|
225
|
+
currentPassword: string;
|
|
226
|
+
newPassword: string;
|
|
227
|
+
confirmNewPassword: string;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Custom class names for styling ResetPasswordForm elements
|
|
231
|
+
*/
|
|
232
|
+
interface ResetPasswordFormClassNames {
|
|
233
|
+
/** Wrapper for each form field */
|
|
234
|
+
fieldWrapper?: string;
|
|
235
|
+
/** All labels */
|
|
236
|
+
label?: string;
|
|
237
|
+
/** All input elements */
|
|
238
|
+
input?: string;
|
|
239
|
+
/** Input elements in error state */
|
|
240
|
+
inputError?: string;
|
|
241
|
+
/** Error message text */
|
|
242
|
+
errorText?: string;
|
|
243
|
+
/** Submit button */
|
|
244
|
+
button?: string;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Props for the ResetPasswordForm component
|
|
248
|
+
*/
|
|
249
|
+
interface ResetPasswordFormProps {
|
|
250
|
+
/** Called with all 3 password values on valid submit */
|
|
251
|
+
onSubmit: (values: ResetPasswordFormValues) => void;
|
|
252
|
+
/** Called on every field change with current values and validity */
|
|
253
|
+
onChange?: (values: Partial<ResetPasswordFormValues>, isValid: boolean) => void;
|
|
254
|
+
/** Whether to validate on blur (default: true) */
|
|
255
|
+
validateOnBlur?: boolean;
|
|
256
|
+
/** Text for the submit button (default: "Update Password") */
|
|
257
|
+
submitLabel?: string;
|
|
258
|
+
/** Class name for the form element */
|
|
259
|
+
className?: string;
|
|
260
|
+
/** Custom class names for styling individual elements */
|
|
261
|
+
classNames?: ResetPasswordFormClassNames;
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Imperative handle methods exposed via ref
|
|
265
|
+
*/
|
|
266
|
+
interface ResetPasswordFormRef {
|
|
267
|
+
/** Reset all form values and errors */
|
|
268
|
+
reset: () => void;
|
|
269
|
+
/** Programmatically set form values */
|
|
270
|
+
setValues: (values: Partial<ResetPasswordFormValues>) => void;
|
|
271
|
+
}
|
|
272
|
+
|
|
221
273
|
interface QuestionOption {
|
|
222
274
|
id: number;
|
|
223
275
|
name: string;
|
|
@@ -355,6 +407,26 @@ declare const RegistrationForm: React.ForwardRefExoticComponent<RegistrationForm
|
|
|
355
407
|
*/
|
|
356
408
|
declare const ContactDetailsForm: React.ForwardRefExoticComponent<ContactDetailsFormProps & React.RefAttributes<ContactDetailsFormRef>>;
|
|
357
409
|
|
|
410
|
+
/**
|
|
411
|
+
* A reusable, accessible reset-password form component.
|
|
412
|
+
*
|
|
413
|
+
* Features:
|
|
414
|
+
* - Three password fields: Current, New, Confirm New
|
|
415
|
+
* - Validation: all required; confirm must match new password
|
|
416
|
+
* - forwardRef for programmatic reset()/setValues()
|
|
417
|
+
* - onChange callback with live validity
|
|
418
|
+
* - Granular styling via classNames prop
|
|
419
|
+
*
|
|
420
|
+
* @example
|
|
421
|
+
* ```tsx
|
|
422
|
+
* <ResetPasswordForm
|
|
423
|
+
* onSubmit={(values) => console.log(values)}
|
|
424
|
+
* submitLabel="Change Password"
|
|
425
|
+
* />
|
|
426
|
+
* ```
|
|
427
|
+
*/
|
|
428
|
+
declare const ResetPasswordForm: React.ForwardRefExoticComponent<ResetPasswordFormProps & React.RefAttributes<ResetPasswordFormRef>>;
|
|
429
|
+
|
|
358
430
|
/**
|
|
359
431
|
* Validation helper functions for form fields
|
|
360
432
|
* Each validator returns an error message string if invalid, or null if valid
|
|
@@ -388,4 +460,4 @@ declare function minLen(min: number): (value: string) => string | null;
|
|
|
388
460
|
*/
|
|
389
461
|
declare function compose(...validators: Array<(value: string) => string | null>): (value: string) => string | null;
|
|
390
462
|
|
|
391
|
-
export { BookingForm, type BookingFormClassNames, type BookingFormProps, type BookingUIConfig, type ContactDetailsAnswerEntry, type ContactDetailsFieldSettings, ContactDetailsForm, type ContactDetailsFormClassNames, type ContactDetailsFormProps, type ContactDetailsFormRef, type ContactDetailsInitialValues, type ContactDetailsQuestionEntry, type ContactDetailsValues, type ContactFieldSettings, type FieldConfig, type FieldOption, type FormErrors, type FormValues, type Question, type QuestionOption, type QuestionSettings, RegistrationForm, type RegistrationFormClassNames, type RegistrationFormErrors, type RegistrationFormProps, type RegistrationFormRef, type RegistrationFormValues, compose, email, minLen, phone, required, ukPostcode };
|
|
463
|
+
export { BookingForm, type BookingFormClassNames, type BookingFormProps, type BookingUIConfig, type ContactDetailsAnswerEntry, type ContactDetailsFieldSettings, ContactDetailsForm, type ContactDetailsFormClassNames, type ContactDetailsFormProps, type ContactDetailsFormRef, type ContactDetailsInitialValues, type ContactDetailsQuestionEntry, type ContactDetailsValues, type ContactFieldSettings, type FieldConfig, type FieldOption, type FormErrors, type FormValues, type Question, type QuestionOption, type QuestionSettings, RegistrationForm, type RegistrationFormClassNames, type RegistrationFormErrors, type RegistrationFormProps, type RegistrationFormRef, type RegistrationFormValues, ResetPasswordForm, type ResetPasswordFormClassNames, type ResetPasswordFormProps, type ResetPasswordFormRef, type ResetPasswordFormValues, compose, email, minLen, phone, required, ukPostcode };
|
package/dist/index.js
CHANGED
|
@@ -1088,10 +1088,182 @@ var ContactDetailsForm = react.forwardRef(
|
|
|
1088
1088
|
}
|
|
1089
1089
|
);
|
|
1090
1090
|
ContactDetailsForm.displayName = "ContactDetailsForm";
|
|
1091
|
+
var FIELDS = [
|
|
1092
|
+
{ name: "currentPassword", label: "Current Password" },
|
|
1093
|
+
{ name: "newPassword", label: "New Password" },
|
|
1094
|
+
{ name: "confirmNewPassword", label: "Confirm New Password" }
|
|
1095
|
+
];
|
|
1096
|
+
var ResetPasswordForm = react.forwardRef(
|
|
1097
|
+
({
|
|
1098
|
+
onSubmit,
|
|
1099
|
+
onChange,
|
|
1100
|
+
validateOnBlur = true,
|
|
1101
|
+
submitLabel = "Update Password",
|
|
1102
|
+
className = "",
|
|
1103
|
+
classNames = {}
|
|
1104
|
+
}, ref) => {
|
|
1105
|
+
const formId = react.useId();
|
|
1106
|
+
const [values, setValues] = react.useState({
|
|
1107
|
+
currentPassword: "",
|
|
1108
|
+
newPassword: "",
|
|
1109
|
+
confirmNewPassword: ""
|
|
1110
|
+
});
|
|
1111
|
+
const [errors, setErrors] = react.useState({});
|
|
1112
|
+
const [touched, setTouched] = react.useState({});
|
|
1113
|
+
const validateField = react.useCallback(
|
|
1114
|
+
(name, val, allValues) => {
|
|
1115
|
+
if (!val || val.trim() === "") return "This field is required";
|
|
1116
|
+
if (name === "confirmNewPassword" && val !== allValues.newPassword) {
|
|
1117
|
+
return "Passwords do not match";
|
|
1118
|
+
}
|
|
1119
|
+
return null;
|
|
1120
|
+
},
|
|
1121
|
+
[]
|
|
1122
|
+
);
|
|
1123
|
+
const checkIsValid = react.useCallback(
|
|
1124
|
+
(v) => {
|
|
1125
|
+
for (const field of FIELDS) {
|
|
1126
|
+
if (validateField(field.name, v[field.name], v)) return false;
|
|
1127
|
+
}
|
|
1128
|
+
return true;
|
|
1129
|
+
},
|
|
1130
|
+
[validateField]
|
|
1131
|
+
);
|
|
1132
|
+
const handleChange = react.useCallback(
|
|
1133
|
+
(name, val) => {
|
|
1134
|
+
const newValues = { ...values, [name]: val };
|
|
1135
|
+
setValues(newValues);
|
|
1136
|
+
if (touched[name]) {
|
|
1137
|
+
const error = validateField(name, val, newValues);
|
|
1138
|
+
if (!error) {
|
|
1139
|
+
setErrors((prev) => {
|
|
1140
|
+
const next = { ...prev };
|
|
1141
|
+
delete next[name];
|
|
1142
|
+
return next;
|
|
1143
|
+
});
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
if (name === "newPassword" && touched.confirmNewPassword) {
|
|
1147
|
+
const confirmError = validateField("confirmNewPassword", newValues.confirmNewPassword, newValues);
|
|
1148
|
+
if (confirmError) {
|
|
1149
|
+
setErrors((prev) => ({ ...prev, confirmNewPassword: confirmError }));
|
|
1150
|
+
} else {
|
|
1151
|
+
setErrors((prev) => {
|
|
1152
|
+
const next = { ...prev };
|
|
1153
|
+
delete next.confirmNewPassword;
|
|
1154
|
+
return next;
|
|
1155
|
+
});
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
1158
|
+
onChange?.(newValues, checkIsValid(newValues));
|
|
1159
|
+
},
|
|
1160
|
+
[values, touched, validateField, onChange, checkIsValid]
|
|
1161
|
+
);
|
|
1162
|
+
const handleBlur = react.useCallback(
|
|
1163
|
+
(name) => {
|
|
1164
|
+
setTouched((prev) => ({ ...prev, [name]: true }));
|
|
1165
|
+
if (validateOnBlur) {
|
|
1166
|
+
const error = validateField(name, values[name], values);
|
|
1167
|
+
if (error) {
|
|
1168
|
+
setErrors((prev) => ({ ...prev, [name]: error }));
|
|
1169
|
+
} else {
|
|
1170
|
+
setErrors((prev) => {
|
|
1171
|
+
const next = { ...prev };
|
|
1172
|
+
delete next[name];
|
|
1173
|
+
return next;
|
|
1174
|
+
});
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
},
|
|
1178
|
+
[validateOnBlur, values, validateField]
|
|
1179
|
+
);
|
|
1180
|
+
const handleSubmit = react.useCallback(
|
|
1181
|
+
(e) => {
|
|
1182
|
+
e.preventDefault();
|
|
1183
|
+
const allTouched = {};
|
|
1184
|
+
const newErrors = {};
|
|
1185
|
+
let isValid = true;
|
|
1186
|
+
for (const field of FIELDS) {
|
|
1187
|
+
allTouched[field.name] = true;
|
|
1188
|
+
const error = validateField(field.name, values[field.name], values);
|
|
1189
|
+
if (error) {
|
|
1190
|
+
newErrors[field.name] = error;
|
|
1191
|
+
isValid = false;
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
1194
|
+
setTouched(allTouched);
|
|
1195
|
+
setErrors(newErrors);
|
|
1196
|
+
if (isValid) onSubmit(values);
|
|
1197
|
+
},
|
|
1198
|
+
[values, validateField, onSubmit]
|
|
1199
|
+
);
|
|
1200
|
+
react.useImperativeHandle(ref, () => ({
|
|
1201
|
+
reset: () => {
|
|
1202
|
+
setValues({ currentPassword: "", newPassword: "", confirmNewPassword: "" });
|
|
1203
|
+
setErrors({});
|
|
1204
|
+
setTouched({});
|
|
1205
|
+
},
|
|
1206
|
+
setValues: (newVals) => {
|
|
1207
|
+
setValues((prev) => {
|
|
1208
|
+
const merged = { ...prev };
|
|
1209
|
+
for (const [key, value] of Object.entries(newVals)) {
|
|
1210
|
+
if (value !== void 0) {
|
|
1211
|
+
merged[key] = value;
|
|
1212
|
+
}
|
|
1213
|
+
}
|
|
1214
|
+
return merged;
|
|
1215
|
+
});
|
|
1216
|
+
}
|
|
1217
|
+
}), []);
|
|
1218
|
+
const styles = {
|
|
1219
|
+
fieldWrapper: classNames.fieldWrapper || "mb-4",
|
|
1220
|
+
label: classNames.label || "block text-sm font-medium mb-1",
|
|
1221
|
+
input: classNames.input || "w-full px-3 py-2 border rounded-md",
|
|
1222
|
+
inputError: classNames.inputError || "border-red-500",
|
|
1223
|
+
errorText: classNames.errorText || "mt-1 text-xs text-red-600",
|
|
1224
|
+
button: classNames.button || "w-full mt-4 px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 disabled:opacity-50"
|
|
1225
|
+
};
|
|
1226
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("form", { onSubmit: handleSubmit, className, noValidate: true, children: [
|
|
1227
|
+
FIELDS.map((field) => {
|
|
1228
|
+
const fieldId = `${formId}-${field.name}`;
|
|
1229
|
+
const errorId = `${fieldId}-error`;
|
|
1230
|
+
const value = values[field.name];
|
|
1231
|
+
const error = errors[field.name];
|
|
1232
|
+
const isTouched = touched[field.name];
|
|
1233
|
+
const showError = isTouched && error;
|
|
1234
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: styles.fieldWrapper, children: [
|
|
1235
|
+
/* @__PURE__ */ jsxRuntime.jsxs("label", { htmlFor: fieldId, className: styles.label, children: [
|
|
1236
|
+
field.label,
|
|
1237
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-red-500 ml-1", "aria-hidden": "true", children: "*" })
|
|
1238
|
+
] }),
|
|
1239
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1240
|
+
"input",
|
|
1241
|
+
{
|
|
1242
|
+
id: fieldId,
|
|
1243
|
+
name: field.name,
|
|
1244
|
+
type: "password",
|
|
1245
|
+
value,
|
|
1246
|
+
onChange: (e) => handleChange(field.name, e.target.value),
|
|
1247
|
+
onBlur: () => handleBlur(field.name),
|
|
1248
|
+
className: `${styles.input} ${showError ? styles.inputError : ""}`,
|
|
1249
|
+
"aria-invalid": showError ? "true" : "false",
|
|
1250
|
+
"aria-describedby": showError ? errorId : void 0,
|
|
1251
|
+
"aria-required": "true"
|
|
1252
|
+
}
|
|
1253
|
+
),
|
|
1254
|
+
showError && /* @__PURE__ */ jsxRuntime.jsx("p", { id: errorId, className: styles.errorText, role: "alert", children: error })
|
|
1255
|
+
] }, field.name);
|
|
1256
|
+
}),
|
|
1257
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "submit", className: styles.button, children: submitLabel })
|
|
1258
|
+
] });
|
|
1259
|
+
}
|
|
1260
|
+
);
|
|
1261
|
+
ResetPasswordForm.displayName = "ResetPasswordForm";
|
|
1091
1262
|
|
|
1092
1263
|
exports.BookingForm = BookingForm;
|
|
1093
1264
|
exports.ContactDetailsForm = ContactDetailsForm;
|
|
1094
1265
|
exports.RegistrationForm = RegistrationForm;
|
|
1266
|
+
exports.ResetPasswordForm = ResetPasswordForm;
|
|
1095
1267
|
exports.compose = compose;
|
|
1096
1268
|
exports.email = email;
|
|
1097
1269
|
exports.minLen = minLen;
|