@bookinglab/booking-ui-react 1.0.2 → 1.1.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 +128 -0
- package/dist/index.d.cts +136 -1
- package/dist/index.d.ts +136 -1
- package/dist/index.js +330 -35
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +644 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +6 -6
- package/dist/index.cjs +0 -360
- package/dist/index.cjs.map +0 -1
package/README.md
CHANGED
|
@@ -182,6 +182,128 @@ type FormValues = Record<number, string | number | boolean>;
|
|
|
182
182
|
- Error messages display after field is touched
|
|
183
183
|
- Hidden conditional fields are excluded from validation
|
|
184
184
|
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## RegistrationForm
|
|
188
|
+
|
|
189
|
+
A reusable, accessible registration form component with built-in validation, customizable fields, and programmatic control.
|
|
190
|
+
|
|
191
|
+
### Props
|
|
192
|
+
|
|
193
|
+
| Prop | Type | Default | Description |
|
|
194
|
+
|------|------|---------|-------------|
|
|
195
|
+
| `fields` | `FieldConfig[]` | Default fields | Custom field configuration |
|
|
196
|
+
| `onSubmit` | `(values: FormValues) => void` | required | Callback fired when form is submitted with valid values |
|
|
197
|
+
| `onChange` | `(values: FormValues, isValid: boolean) => void` | `undefined` | Callback fired on every field change |
|
|
198
|
+
| `validateOnBlur` | `boolean` | `true` | Whether to validate fields on blur |
|
|
199
|
+
| `submitLabel` | `string` | `"Submit"` | Text for the submit button |
|
|
200
|
+
| `className` | `string` | `""` | Class name for the form element |
|
|
201
|
+
| `classNames` | `RegistrationFormClassNames` | `undefined` | Custom class names for styling |
|
|
202
|
+
|
|
203
|
+
### Default Fields
|
|
204
|
+
|
|
205
|
+
| Field | Label | Type | Required | Validation |
|
|
206
|
+
|-------|-------|------|----------|------------|
|
|
207
|
+
| `firstName` | First name | text | Yes | required |
|
|
208
|
+
| `lastName` | Last name | text | Yes | required |
|
|
209
|
+
| `email` | Email address | email | Yes | required, email format |
|
|
210
|
+
| `phone` | Contact number | tel | No | phone format (if provided) |
|
|
211
|
+
| `address1` | Address 1 | text | Yes | required |
|
|
212
|
+
| `address2` | Address 2 | text | No | none |
|
|
213
|
+
| `city` | Town/City | text | Yes | required |
|
|
214
|
+
| `postcode` | Postcode | text | Yes | required, UK postcode |
|
|
215
|
+
|
|
216
|
+
### Custom Fields
|
|
217
|
+
|
|
218
|
+
Override default fields by passing a `fields` prop:
|
|
219
|
+
|
|
220
|
+
```tsx
|
|
221
|
+
import { RegistrationForm, FieldConfig } from '@bookinglab/booking-ui-react';
|
|
222
|
+
|
|
223
|
+
const customFields: FieldConfig[] = [
|
|
224
|
+
{ name: 'username', label: 'Username', type: 'text', required: true },
|
|
225
|
+
{ name: 'email', label: 'Email', type: 'email', required: true },
|
|
226
|
+
{
|
|
227
|
+
name: 'age',
|
|
228
|
+
label: 'Age',
|
|
229
|
+
type: 'text',
|
|
230
|
+
validate: (value) => {
|
|
231
|
+
const num = parseInt(value, 10);
|
|
232
|
+
if (isNaN(num) || num < 18) return 'Must be 18 or older';
|
|
233
|
+
return null;
|
|
234
|
+
}
|
|
235
|
+
},
|
|
236
|
+
];
|
|
237
|
+
|
|
238
|
+
<RegistrationForm fields={customFields} onSubmit={handleSubmit} />
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Ref Methods
|
|
242
|
+
|
|
243
|
+
Access imperative methods via `ref`:
|
|
244
|
+
|
|
245
|
+
```tsx
|
|
246
|
+
import { useRef } from 'react';
|
|
247
|
+
import { RegistrationForm, RegistrationFormRef } from '@bookinglab/booking-ui-react';
|
|
248
|
+
|
|
249
|
+
function MyComponent() {
|
|
250
|
+
const formRef = useRef<RegistrationFormRef>(null);
|
|
251
|
+
|
|
252
|
+
return (
|
|
253
|
+
<>
|
|
254
|
+
<RegistrationForm ref={formRef} onSubmit={handleSubmit} />
|
|
255
|
+
<button onClick={() => formRef.current?.reset()}>Reset Form</button>
|
|
256
|
+
<button onClick={() => formRef.current?.setValues({ email: 'test@example.com' })}>
|
|
257
|
+
Pre-fill Email
|
|
258
|
+
</button>
|
|
259
|
+
</>
|
|
260
|
+
);
|
|
261
|
+
}
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
| Method | Description |
|
|
265
|
+
|--------|-------------|
|
|
266
|
+
| `reset()` | Clear all values, errors, and touched state |
|
|
267
|
+
| `setValues(values)` | Programmatically set field values |
|
|
268
|
+
|
|
269
|
+
### Styling
|
|
270
|
+
|
|
271
|
+
Override styles using the `classNames` prop:
|
|
272
|
+
|
|
273
|
+
```tsx
|
|
274
|
+
<RegistrationForm
|
|
275
|
+
onSubmit={handleSubmit}
|
|
276
|
+
classNames={{
|
|
277
|
+
fieldWrapper: 'mb-6',
|
|
278
|
+
label: 'text-white font-bold',
|
|
279
|
+
input: 'border-2 border-gray-400 rounded-lg p-3',
|
|
280
|
+
inputError: 'border-red-500',
|
|
281
|
+
errorText: 'text-red-400 text-sm',
|
|
282
|
+
button: 'bg-primary text-white py-3 px-6 rounded-lg',
|
|
283
|
+
}}
|
|
284
|
+
/>
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
### Validators
|
|
288
|
+
|
|
289
|
+
The package exports reusable validators:
|
|
290
|
+
|
|
291
|
+
```typescript
|
|
292
|
+
import { required, email, phone, ukPostcode, minLen, compose } from '@bookinglab/booking-ui-react';
|
|
293
|
+
|
|
294
|
+
// Use in custom fields
|
|
295
|
+
const fields = [
|
|
296
|
+
{
|
|
297
|
+
name: 'password',
|
|
298
|
+
label: 'Password',
|
|
299
|
+
type: 'text',
|
|
300
|
+
validate: compose(required, minLen(8)),
|
|
301
|
+
},
|
|
302
|
+
];
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
---
|
|
306
|
+
|
|
185
307
|
## Requirements
|
|
186
308
|
|
|
187
309
|
- React 17.0.0 or higher
|
|
@@ -200,6 +322,12 @@ import type {
|
|
|
200
322
|
FormErrors,
|
|
201
323
|
BookingFormProps,
|
|
202
324
|
BookingFormClassNames,
|
|
325
|
+
FieldConfig,
|
|
326
|
+
RegistrationFormProps,
|
|
327
|
+
RegistrationFormRef,
|
|
328
|
+
RegistrationFormValues,
|
|
329
|
+
RegistrationFormErrors,
|
|
330
|
+
RegistrationFormClassNames,
|
|
203
331
|
} from '@bookinglab/booking-ui-react';
|
|
204
332
|
```
|
|
205
333
|
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,78 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Configuration for a single form field
|
|
6
|
+
*/
|
|
7
|
+
interface FieldConfig {
|
|
8
|
+
/** Unique field name (used as key in values object) */
|
|
9
|
+
name: string;
|
|
10
|
+
/** Display label for the field */
|
|
11
|
+
label: string;
|
|
12
|
+
/** Input type */
|
|
13
|
+
type: 'text' | 'email' | 'tel';
|
|
14
|
+
/** Whether the field is required */
|
|
15
|
+
required?: boolean;
|
|
16
|
+
/** Placeholder text */
|
|
17
|
+
placeholder?: string;
|
|
18
|
+
/** Custom validation function - returns error message or null */
|
|
19
|
+
validate?: (value: string) => string | null;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Form values keyed by field name
|
|
23
|
+
*/
|
|
24
|
+
type RegistrationFormValues = Record<string, string>;
|
|
25
|
+
/**
|
|
26
|
+
* Form errors keyed by field name
|
|
27
|
+
*/
|
|
28
|
+
type RegistrationFormErrors = Record<string, string>;
|
|
29
|
+
/**
|
|
30
|
+
* Custom class names for styling form elements
|
|
31
|
+
*/
|
|
32
|
+
interface RegistrationFormClassNames {
|
|
33
|
+
/** Wrapper for each form field */
|
|
34
|
+
fieldWrapper?: string;
|
|
35
|
+
/** All labels */
|
|
36
|
+
label?: string;
|
|
37
|
+
/** All input elements */
|
|
38
|
+
input?: string;
|
|
39
|
+
/** Input elements in error state */
|
|
40
|
+
inputError?: string;
|
|
41
|
+
/** Help text below fields */
|
|
42
|
+
helpText?: string;
|
|
43
|
+
/** Error message text */
|
|
44
|
+
errorText?: string;
|
|
45
|
+
/** Submit button */
|
|
46
|
+
button?: string;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Props for the RegistrationForm component
|
|
50
|
+
*/
|
|
51
|
+
interface RegistrationFormProps {
|
|
52
|
+
/** Custom field configuration (overrides defaults) */
|
|
53
|
+
fields?: FieldConfig[];
|
|
54
|
+
/** Callback fired when form is submitted with valid values */
|
|
55
|
+
onSubmit: (values: RegistrationFormValues) => void;
|
|
56
|
+
/** Callback fired on every field change */
|
|
57
|
+
onChange?: (values: RegistrationFormValues, isValid: boolean) => void;
|
|
58
|
+
/** Whether to validate on blur (default: true) */
|
|
59
|
+
validateOnBlur?: boolean;
|
|
60
|
+
/** Text for the submit button */
|
|
61
|
+
submitLabel?: string;
|
|
62
|
+
/** Class name for the form element */
|
|
63
|
+
className?: string;
|
|
64
|
+
/** Custom class names for styling individual elements */
|
|
65
|
+
classNames?: RegistrationFormClassNames;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Imperative handle methods exposed via ref
|
|
69
|
+
*/
|
|
70
|
+
interface RegistrationFormRef {
|
|
71
|
+
/** Reset all form values and errors */
|
|
72
|
+
reset: () => void;
|
|
73
|
+
/** Programmatically set form values */
|
|
74
|
+
setValues: (values: Partial<RegistrationFormValues>) => void;
|
|
75
|
+
}
|
|
2
76
|
|
|
3
77
|
interface QuestionOption {
|
|
4
78
|
id: number;
|
|
@@ -90,4 +164,65 @@ interface BookingUIConfig {
|
|
|
90
164
|
*/
|
|
91
165
|
declare function BookingForm({ questions, onSubmit, submitLabel, className, labelClassName, classNames: classNamesProp, }: BookingFormProps): react_jsx_runtime.JSX.Element;
|
|
92
166
|
|
|
93
|
-
|
|
167
|
+
/**
|
|
168
|
+
* A reusable, accessible registration form component.
|
|
169
|
+
*
|
|
170
|
+
* Features:
|
|
171
|
+
* - Customizable fields via props
|
|
172
|
+
* - Built-in validation with blur and submit triggers
|
|
173
|
+
* - Full accessibility support (ARIA attributes, keyboard navigation)
|
|
174
|
+
* - Imperative handle for programmatic control (reset, setValues)
|
|
175
|
+
* - Granular styling via classNames prop
|
|
176
|
+
*
|
|
177
|
+
* @example
|
|
178
|
+
* ```tsx
|
|
179
|
+
* const formRef = useRef<RegistrationFormRef>(null);
|
|
180
|
+
*
|
|
181
|
+
* <RegistrationForm
|
|
182
|
+
* ref={formRef}
|
|
183
|
+
* onSubmit={(values) => console.log(values)}
|
|
184
|
+
* onChange={(values, isValid) => console.log(isValid)}
|
|
185
|
+
* submitLabel="Register"
|
|
186
|
+
* />
|
|
187
|
+
*
|
|
188
|
+
* // Programmatic control
|
|
189
|
+
* formRef.current?.reset();
|
|
190
|
+
* formRef.current?.setValues({ email: 'test@example.com' });
|
|
191
|
+
* ```
|
|
192
|
+
*/
|
|
193
|
+
declare const RegistrationForm: React.ForwardRefExoticComponent<RegistrationFormProps & React.RefAttributes<RegistrationFormRef>>;
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Validation helper functions for form fields
|
|
197
|
+
* Each validator returns an error message string if invalid, or null if valid
|
|
198
|
+
*/
|
|
199
|
+
/**
|
|
200
|
+
* Validates that a value is not empty
|
|
201
|
+
*/
|
|
202
|
+
declare function required(value: string): string | null;
|
|
203
|
+
/**
|
|
204
|
+
* Validates email format (RFC 5322 compliant)
|
|
205
|
+
*/
|
|
206
|
+
declare function email(value: string): string | null;
|
|
207
|
+
/**
|
|
208
|
+
* Validates phone number format (international)
|
|
209
|
+
* Accepts formats like: +44 1234 567890, 01onal234 567890, +1-234-567-8900
|
|
210
|
+
*/
|
|
211
|
+
declare function phone(value: string): string | null;
|
|
212
|
+
/**
|
|
213
|
+
* Validates UK postcode format
|
|
214
|
+
* Accepts formats like: SW1A 1AA, SW1A1AA, M1 1AA, B33 8TH
|
|
215
|
+
*/
|
|
216
|
+
declare function ukPostcode(value: string): string | null;
|
|
217
|
+
/**
|
|
218
|
+
* Creates a minimum length validator
|
|
219
|
+
* @param min - Minimum number of characters required
|
|
220
|
+
*/
|
|
221
|
+
declare function minLen(min: number): (value: string) => string | null;
|
|
222
|
+
/**
|
|
223
|
+
* Combines multiple validators into one
|
|
224
|
+
* Returns the first error encountered, or null if all pass
|
|
225
|
+
*/
|
|
226
|
+
declare function compose(...validators: Array<(value: string) => string | null>): (value: string) => string | null;
|
|
227
|
+
|
|
228
|
+
export { BookingForm, type BookingFormClassNames, type BookingFormProps, type BookingUIConfig, type FieldConfig, 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 };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,78 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Configuration for a single form field
|
|
6
|
+
*/
|
|
7
|
+
interface FieldConfig {
|
|
8
|
+
/** Unique field name (used as key in values object) */
|
|
9
|
+
name: string;
|
|
10
|
+
/** Display label for the field */
|
|
11
|
+
label: string;
|
|
12
|
+
/** Input type */
|
|
13
|
+
type: 'text' | 'email' | 'tel';
|
|
14
|
+
/** Whether the field is required */
|
|
15
|
+
required?: boolean;
|
|
16
|
+
/** Placeholder text */
|
|
17
|
+
placeholder?: string;
|
|
18
|
+
/** Custom validation function - returns error message or null */
|
|
19
|
+
validate?: (value: string) => string | null;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Form values keyed by field name
|
|
23
|
+
*/
|
|
24
|
+
type RegistrationFormValues = Record<string, string>;
|
|
25
|
+
/**
|
|
26
|
+
* Form errors keyed by field name
|
|
27
|
+
*/
|
|
28
|
+
type RegistrationFormErrors = Record<string, string>;
|
|
29
|
+
/**
|
|
30
|
+
* Custom class names for styling form elements
|
|
31
|
+
*/
|
|
32
|
+
interface RegistrationFormClassNames {
|
|
33
|
+
/** Wrapper for each form field */
|
|
34
|
+
fieldWrapper?: string;
|
|
35
|
+
/** All labels */
|
|
36
|
+
label?: string;
|
|
37
|
+
/** All input elements */
|
|
38
|
+
input?: string;
|
|
39
|
+
/** Input elements in error state */
|
|
40
|
+
inputError?: string;
|
|
41
|
+
/** Help text below fields */
|
|
42
|
+
helpText?: string;
|
|
43
|
+
/** Error message text */
|
|
44
|
+
errorText?: string;
|
|
45
|
+
/** Submit button */
|
|
46
|
+
button?: string;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Props for the RegistrationForm component
|
|
50
|
+
*/
|
|
51
|
+
interface RegistrationFormProps {
|
|
52
|
+
/** Custom field configuration (overrides defaults) */
|
|
53
|
+
fields?: FieldConfig[];
|
|
54
|
+
/** Callback fired when form is submitted with valid values */
|
|
55
|
+
onSubmit: (values: RegistrationFormValues) => void;
|
|
56
|
+
/** Callback fired on every field change */
|
|
57
|
+
onChange?: (values: RegistrationFormValues, isValid: boolean) => void;
|
|
58
|
+
/** Whether to validate on blur (default: true) */
|
|
59
|
+
validateOnBlur?: boolean;
|
|
60
|
+
/** Text for the submit button */
|
|
61
|
+
submitLabel?: string;
|
|
62
|
+
/** Class name for the form element */
|
|
63
|
+
className?: string;
|
|
64
|
+
/** Custom class names for styling individual elements */
|
|
65
|
+
classNames?: RegistrationFormClassNames;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Imperative handle methods exposed via ref
|
|
69
|
+
*/
|
|
70
|
+
interface RegistrationFormRef {
|
|
71
|
+
/** Reset all form values and errors */
|
|
72
|
+
reset: () => void;
|
|
73
|
+
/** Programmatically set form values */
|
|
74
|
+
setValues: (values: Partial<RegistrationFormValues>) => void;
|
|
75
|
+
}
|
|
2
76
|
|
|
3
77
|
interface QuestionOption {
|
|
4
78
|
id: number;
|
|
@@ -90,4 +164,65 @@ interface BookingUIConfig {
|
|
|
90
164
|
*/
|
|
91
165
|
declare function BookingForm({ questions, onSubmit, submitLabel, className, labelClassName, classNames: classNamesProp, }: BookingFormProps): react_jsx_runtime.JSX.Element;
|
|
92
166
|
|
|
93
|
-
|
|
167
|
+
/**
|
|
168
|
+
* A reusable, accessible registration form component.
|
|
169
|
+
*
|
|
170
|
+
* Features:
|
|
171
|
+
* - Customizable fields via props
|
|
172
|
+
* - Built-in validation with blur and submit triggers
|
|
173
|
+
* - Full accessibility support (ARIA attributes, keyboard navigation)
|
|
174
|
+
* - Imperative handle for programmatic control (reset, setValues)
|
|
175
|
+
* - Granular styling via classNames prop
|
|
176
|
+
*
|
|
177
|
+
* @example
|
|
178
|
+
* ```tsx
|
|
179
|
+
* const formRef = useRef<RegistrationFormRef>(null);
|
|
180
|
+
*
|
|
181
|
+
* <RegistrationForm
|
|
182
|
+
* ref={formRef}
|
|
183
|
+
* onSubmit={(values) => console.log(values)}
|
|
184
|
+
* onChange={(values, isValid) => console.log(isValid)}
|
|
185
|
+
* submitLabel="Register"
|
|
186
|
+
* />
|
|
187
|
+
*
|
|
188
|
+
* // Programmatic control
|
|
189
|
+
* formRef.current?.reset();
|
|
190
|
+
* formRef.current?.setValues({ email: 'test@example.com' });
|
|
191
|
+
* ```
|
|
192
|
+
*/
|
|
193
|
+
declare const RegistrationForm: React.ForwardRefExoticComponent<RegistrationFormProps & React.RefAttributes<RegistrationFormRef>>;
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Validation helper functions for form fields
|
|
197
|
+
* Each validator returns an error message string if invalid, or null if valid
|
|
198
|
+
*/
|
|
199
|
+
/**
|
|
200
|
+
* Validates that a value is not empty
|
|
201
|
+
*/
|
|
202
|
+
declare function required(value: string): string | null;
|
|
203
|
+
/**
|
|
204
|
+
* Validates email format (RFC 5322 compliant)
|
|
205
|
+
*/
|
|
206
|
+
declare function email(value: string): string | null;
|
|
207
|
+
/**
|
|
208
|
+
* Validates phone number format (international)
|
|
209
|
+
* Accepts formats like: +44 1234 567890, 01onal234 567890, +1-234-567-8900
|
|
210
|
+
*/
|
|
211
|
+
declare function phone(value: string): string | null;
|
|
212
|
+
/**
|
|
213
|
+
* Validates UK postcode format
|
|
214
|
+
* Accepts formats like: SW1A 1AA, SW1A1AA, M1 1AA, B33 8TH
|
|
215
|
+
*/
|
|
216
|
+
declare function ukPostcode(value: string): string | null;
|
|
217
|
+
/**
|
|
218
|
+
* Creates a minimum length validator
|
|
219
|
+
* @param min - Minimum number of characters required
|
|
220
|
+
*/
|
|
221
|
+
declare function minLen(min: number): (value: string) => string | null;
|
|
222
|
+
/**
|
|
223
|
+
* Combines multiple validators into one
|
|
224
|
+
* Returns the first error encountered, or null if all pass
|
|
225
|
+
*/
|
|
226
|
+
declare function compose(...validators: Array<(value: string) => string | null>): (value: string) => string | null;
|
|
227
|
+
|
|
228
|
+
export { BookingForm, type BookingFormClassNames, type BookingFormProps, type BookingUIConfig, type FieldConfig, 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 };
|