@rilaykit/forms 0.1.1-alpha.1 → 0.1.1

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/dist/index.d.mts CHANGED
@@ -1,210 +1,851 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { FormConfiguration, ValidationError, ValidationResult, FormFieldRow, ril, InputType, LayoutType, ValidationConfig, ConditionalConfig, FormFieldConfig } from '@rilaykit/core';
3
- export * from '@rilaykit/core';
4
- export { createZodValidator, ril } from '@rilaykit/core';
2
+ import { ril, FieldValidationConfig, ConditionalBehavior, FormFieldConfig, FormFieldRow, FormValidationConfig, FormConfiguration, ComponentRendererBaseProps, FormBodyRendererProps, FieldConditions, FormState, ValidationError, ValidationState, FieldState, ValidationResult, MonitoringConfig, FormPerformanceMetrics, FormRowRendererProps, FormSubmitButtonRendererProps } from '@rilaykit/core';
5
3
  import * as React$1 from 'react';
6
4
  import React__default from 'react';
7
-
8
- interface FormProps {
9
- formConfig: FormConfiguration;
10
- defaultValues?: Record<string, any>;
11
- onSubmit?: (data: Record<string, any>) => void | Promise<void>;
12
- onFieldChange?: (fieldId: string, value: any, formData: Record<string, any>) => void;
13
- className?: string;
14
- children: React.ReactNode;
15
- }
16
- declare function Form({ formConfig, defaultValues, onSubmit, onFieldChange, children }: FormProps): react_jsx_runtime.JSX.Element;
17
-
18
- interface FormBodyProps {
19
- className?: string;
20
- }
21
- declare function FormBody({ className }: FormBodyProps): React$1.ReactElement<any, string | React$1.JSXElementConstructor<any>>;
22
-
23
- interface FormFieldProps {
24
- fieldId: string;
25
- disabled?: boolean;
26
- customProps?: Record<string, any>;
27
- className?: string;
28
- }
29
- declare function FormField({ fieldId, disabled, customProps, className, }: FormFieldProps): react_jsx_runtime.JSX.Element | null;
30
-
31
- interface FormState {
32
- values: Record<string, any>;
33
- errors: Record<string, ValidationError[]>;
34
- warnings: Record<string, ValidationError[]>;
35
- touched: Set<string>;
36
- isValidating: Set<string>;
37
- isDirty: boolean;
38
- isValid: boolean;
39
- isSubmitting: boolean;
40
- }
41
- interface FormContextValue {
42
- formState: FormState;
43
- formConfig: FormConfiguration;
44
- setValue: (fieldId: string, value: any) => void;
45
- setError: (fieldId: string, errors: ValidationError[]) => void;
46
- setWarning: (fieldId: string, warnings: ValidationError[]) => void;
47
- clearError: (fieldId: string) => void;
48
- clearWarning: (fieldId: string) => void;
49
- markFieldTouched: (fieldId: string) => void;
50
- setFieldValidating: (fieldId: string, isValidating: boolean) => void;
51
- validateField: (fieldId: string, value?: any) => Promise<ValidationResult>;
52
- validateAllFields: () => Promise<boolean>;
53
- reset: (values?: Record<string, any>) => void;
54
- submit: (event?: React__default.FormEvent) => Promise<boolean>;
55
- }
56
- interface FormProviderProps {
57
- children: React__default.ReactNode;
58
- formConfig: FormConfiguration;
59
- defaultValues?: Record<string, any>;
60
- onSubmit?: (data: Record<string, any>) => void | Promise<void>;
61
- onFieldChange?: (fieldId: string, value: any, formData: Record<string, any>) => void;
62
- className?: string;
63
- }
64
- declare function FormProvider({ children, formConfig, defaultValues, onSubmit, onFieldChange, className, }: FormProviderProps): react_jsx_runtime.JSX.Element;
65
- declare function useFormContext(): FormContextValue;
66
-
67
- interface FormRowProps {
68
- row: FormFieldRow;
69
- className?: string;
70
- }
71
- declare function FormRow({ row, className }: FormRowProps): React$1.ReactElement<any, string | React$1.JSXElementConstructor<any>>;
72
-
73
- interface FormSubmitButtonProps {
74
- className?: string;
75
- children?: React__default.ReactNode;
76
- }
77
- declare function FormSubmitButton({ className, children }: FormSubmitButtonProps): React__default.ReactElement<any, string | React__default.JSXElementConstructor<any>>;
5
+ import * as zustand from 'zustand';
78
6
 
79
7
  /**
80
- * Form builder class for creating form configurations
81
- * Simplified API with matrix support
8
+ * Configuration for a form field with type safety
9
+ *
10
+ * @template C - The component configuration map
11
+ * @template T - The specific component type key
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * const fieldConfig: FieldConfig<MyComponents, 'text'> = {
16
+ * type: 'text',
17
+ * props: { placeholder: 'Enter your name' },
18
+ * validation: {
19
+ * validators: [required(), minLength(2)],
20
+ * validateOnChange: true,
21
+ * validateOnBlur: true
22
+ * }
23
+ * };
24
+ * ```
82
25
  */
83
- declare class form {
26
+ type FieldConfig<C extends Record<string, any>, T extends keyof C> = {
27
+ /** Unique identifier for the field. Auto-generated if not provided */
28
+ id?: string;
29
+ /** Component type from the registered components */
30
+ type: T;
31
+ /** Component-specific properties */
32
+ props?: Partial<C[T]>;
33
+ /** Validation configuration for this field */
34
+ validation?: FieldValidationConfig;
35
+ /** Conditional behavior configuration for this field */
36
+ conditions?: ConditionalBehavior;
37
+ };
38
+ /**
39
+ * Form builder for creating type-safe form configurations
40
+ *
41
+ * DX Notes (How to create a form):
42
+ * - Recommended: use the static factory
43
+ *
44
+ * const rilConfig = ril
45
+ * .create()
46
+ * .addComponent('text', { name: 'Text', renderer: TextInput })
47
+ * .addComponent('email', { name: 'Email', renderer: EmailInput });
48
+ *
49
+ * const myForm = form
50
+ * .create(rilConfig, 'contact-form')
51
+ * .add({ id: 'firstName', type: 'text', props: { label: 'First name' } })
52
+ * .add(
53
+ * { id: 'email', type: 'email', props: { label: 'Email' } },
54
+ * { id: 'role', type: 'text', props: { label: 'Role' } }
55
+ * )
56
+ * .build();
57
+ *
58
+ * - Or instantiate directly:
59
+ *
60
+ * const myForm = new form(rilConfig, 'contact-form')
61
+ * .add({ id: 'firstName', type: 'text' })
62
+ * .build();
63
+ *
64
+ * Why we do not augment ril with .form():
65
+ * - Keep the API explicit and bundler-friendly (no prototype/module augmentation)
66
+ * - Better discoverability and IntelliSense via the builder class
67
+ *
68
+ * Typing & autocomplete:
69
+ * - Types flow from your ril configuration: once components are registered,
70
+ * the `type` and `props` of `.add({ ... })` are fully typed.
71
+ *
72
+ * Adding fields:
73
+ * - Variadic: .add(fieldA, fieldB) => same row (max 3 per row)
74
+ * - Array: .add([fieldA, fieldB]) => explicit single row
75
+ * - >3 fields (variadic) => split across multiple rows automatically
76
+ *
77
+ * Output of .build(): FormConfiguration<C>
78
+ * - id, rows, allFields, renderConfig (from ril), optional validation
79
+ */
80
+ declare class form<C extends Record<string, any> = Record<string, never>> {
81
+ /** The ril configuration instance containing component definitions */
84
82
  private config;
83
+ /** Array of form rows containing field configurations */
85
84
  private rows;
85
+ /** Unique identifier for this form */
86
86
  private formId;
87
- private rowCounter;
88
- constructor(config: ril, formId?: string);
89
- static create(config: ril, formId?: string): form;
90
- /**
91
- * Add a single field (takes full width)
92
- * @param fieldId - Unique field identifier
93
- * @param componentSubType - Component subtype (e.g., 'text', 'email')
94
- * @param props - Props to pass to the component
95
- * @param options - Additional options
96
- * @returns form instance for chaining
97
- */
98
- addField(fieldId: string, componentSubType: InputType | LayoutType, props?: Record<string, any>, options?: {
99
- validation?: ValidationConfig;
100
- conditional?: ConditionalConfig;
101
- }): this;
102
- /**
103
- * Add multiple fields on the same row (max 3 fields)
87
+ /** Generator for creating unique IDs */
88
+ private idGenerator;
89
+ /** Form-level validation configuration */
90
+ private formValidation?;
91
+ /**
92
+ * Creates a new form builder instance
93
+ *
94
+ * @param config - The ril configuration containing component definitions
95
+ * @param formId - Optional unique identifier for the form. Auto-generated if not provided
96
+ *
97
+ * @example
98
+ * ```typescript
99
+ * const builder = new form(rilConfig, 'my-form');
100
+ * ```
101
+ */
102
+ constructor(config: ril<C>, formId?: string);
103
+ /**
104
+ * Static factory to create a new form builder
105
+ *
106
+ * Usage (recommended):
107
+ *
108
+ * const myForm = form
109
+ * .create(rilConfig, 'my-form')
110
+ * .add({ id: 'email', type: 'email', props: { label: 'Email' } })
111
+ * .build();
112
+ *
113
+ * Why prefer this over `new form(...)`?
114
+ * - Clearer intent and better discoverability
115
+ * - Consistent with other builder APIs
116
+ */
117
+ static create<Cm extends Record<string, any> = Record<string, never>>(config: ril<Cm>, formId?: string): form<Cm>;
118
+ /**
119
+ * Converts a FieldConfig to a FormFieldConfig
120
+ *
121
+ * This internal method handles the transformation from the builder's field
122
+ * configuration format to the final form field configuration, including
123
+ * component lookup, prop merging, ID generation, and validation setup.
124
+ *
125
+ * The validation system combines component-level validation (defined in the component config)
126
+ * with field-level validation (defined in the field config). Component validators are
127
+ * applied first, followed by field validators.
128
+ *
129
+ * @template T - The component type
130
+ * @param fieldConfig - The field configuration to convert
131
+ * @returns A complete FormFieldConfig ready for use
132
+ * @throws Error if the specified component type is not registered
133
+ *
134
+ * @internal
135
+ */
136
+ private createFormField;
137
+ /**
138
+ * Creates a form row with the specified fields and options
139
+ *
140
+ * This internal method handles row creation,
141
+ * proper spacing, and alignment configuration.
142
+ *
143
+ * @template T - The component type
104
144
  * @param fieldConfigs - Array of field configurations for the row
105
- * @param rowOptions - Row configuration options
106
- * @returns form instance for chaining
107
- */
108
- addRowFields(fieldConfigs: Array<{
109
- fieldId: string;
110
- componentSubType: InputType | LayoutType;
111
- props?: Record<string, any>;
112
- validation?: ValidationConfig;
113
- conditional?: ConditionalConfig;
114
- }>, rowOptions?: {
115
- spacing?: 'tight' | 'normal' | 'loose';
116
- alignment?: 'start' | 'center' | 'end' | 'stretch';
117
- }): this;
118
- /**
119
- * Add multiple fields, each on its own row
145
+ * @returns A complete FormFieldRow configuration
146
+ * @throws Error if no fields provided or more than 3 fields specified
147
+ *
148
+ * @internal
149
+ */
150
+ private createRow;
151
+ /**
152
+ * Universal method for adding fields to the form
153
+ *
154
+ * This is the primary method for adding fields to your form. It supports multiple
155
+ * usage patterns for maximum flexibility:
156
+ *
157
+ * - Single field: Creates a new row with one field
158
+ * - Multiple fields (≤3): Creates one row with all fields
159
+ * - Multiple fields (>3): Creates separate rows for each field
160
+ * - Array with options: Explicit control over row configuration
161
+ *
162
+ * @template T - The component type
163
+ * @param fields - Field configurations (variadic or array)
164
+ * @returns The form builder instance for method chaining
165
+ * @throws Error if no fields provided or invalid configuration
166
+ *
167
+ * @example
168
+ * ```typescript
169
+ * // Single field on its own row
170
+ * builder.add({ type: 'text', props: { label: 'Name' } });
171
+ *
172
+ * // Multiple fields on same row (max 3)
173
+ * builder.add(
174
+ * { type: 'text', props: { label: 'First Name' } },
175
+ * { type: 'text', props: { label: 'Last Name' } }
176
+ * );
177
+ *
178
+ * // Array syntax with row options
179
+ * builder.add([
180
+ * { type: 'email', props: { label: 'Email' } },
181
+ * { type: 'phone', props: { label: 'Phone' } }
182
+ * ], { spacing: 'loose', alignment: 'center' });
183
+ * ```
184
+ */
185
+ add<T extends keyof C & string>(...fields: FieldConfig<C, T>[]): this;
186
+ add<T extends keyof C & string>(fields: FieldConfig<C, T>[]): this;
187
+ /**
188
+ * Adds multiple fields on separate rows
189
+ *
190
+ * This method is useful when you want to ensure each field gets its own row,
191
+ * regardless of the number of fields. It's an alternative to the add() method
192
+ * when you need explicit control over row separation.
193
+ *
194
+ * @template T - The component type
120
195
  * @param fieldConfigs - Array of field configurations
121
- * @returns form instance for chaining
196
+ * @returns The form builder instance for method chaining
197
+ *
198
+ * @example
199
+ * ```typescript
200
+ * // Each field will be on its own row
201
+ * builder.addSeparateRows([
202
+ * { type: 'text', props: { label: 'Field 1' } },
203
+ * { type: 'text', props: { label: 'Field 2' } },
204
+ * { type: 'text', props: { label: 'Field 3' } }
205
+ * ]);
206
+ * ```
122
207
  */
123
- addFields(fieldConfigs: Array<{
124
- fieldId: string;
125
- componentSubType: InputType | LayoutType;
126
- props?: Record<string, any>;
127
- validation?: ValidationConfig;
128
- conditional?: ConditionalConfig;
129
- }>): this;
208
+ addSeparateRows<T extends keyof C & string>(fieldConfigs: FieldConfig<C, T>[]): this;
130
209
  /**
131
- * Set form ID
132
- * @param id - Form identifier
133
- * @returns form instance for chaining
210
+ * Sets the form identifier
211
+ *
212
+ * @param id - The new form identifier
213
+ * @returns The form builder instance for method chaining
214
+ *
215
+ * @example
216
+ * ```typescript
217
+ * builder.setId('user-profile-form');
218
+ * ```
134
219
  */
135
220
  setId(id: string): this;
136
221
  /**
137
- * Update field configuration
138
- * @param fieldId - Field identifier
139
- * @param updates - Updates to apply
140
- * @returns form instance for chaining
222
+ * Updates an existing field's configuration
223
+ *
224
+ * This method allows you to modify field properties after the field has been added to the form.
225
+ *
226
+ * @param fieldId - The unique identifier of the field to update
227
+ * @param updates - Partial field configuration with updates to apply
228
+ * @returns The form builder instance for method chaining
229
+ * @throws Error if the field with the specified ID is not found
230
+ *
231
+ * @example
232
+ * ```typescript
233
+ * builder.updateField('email-field', {
234
+ * props: { placeholder: 'Enter your email address' },
235
+ * });
236
+ * ```
141
237
  */
142
238
  updateField(fieldId: string, updates: Partial<Omit<FormFieldConfig, 'id'>>): this;
143
239
  /**
144
- * Remove a field from the form
145
- * @param fieldId - Field identifier
146
- * @returns form instance for chaining
240
+ * Finds a field by its unique identifier
241
+ *
242
+ * This internal method searches through all rows to locate a field
243
+ * with the specified ID.
244
+ *
245
+ * @param fieldId - The field identifier to search for
246
+ * @returns The field configuration if found, null otherwise
247
+ *
248
+ * @internal
249
+ */
250
+ private findField;
251
+ /**
252
+ * Removes a field from the form
253
+ *
254
+ * This method removes the specified field and cleans up any empty rows
255
+ * that result from the removal. The form structure is automatically
256
+ * reorganized to maintain consistency.
257
+ *
258
+ * @param fieldId - The unique identifier of the field to remove
259
+ * @returns The form builder instance for method chaining
260
+ *
261
+ * @example
262
+ * ```typescript
263
+ * builder.removeField('unwanted-field-id');
264
+ * ```
147
265
  */
148
266
  removeField(fieldId: string): this;
149
267
  /**
150
- * Get field configuration by ID
151
- * @param fieldId - Field identifier
152
- * @returns Field configuration or undefined
268
+ * Retrieves a field configuration by its ID
269
+ *
270
+ * @param fieldId - The unique identifier of the field
271
+ * @returns The field configuration if found, undefined otherwise
272
+ *
273
+ * @example
274
+ * ```typescript
275
+ * const emailField = builder.getField('email-field');
276
+ * if (emailField) {
277
+ * console.log('Email field props:', emailField.props);
278
+ * }
279
+ * ```
153
280
  */
154
281
  getField(fieldId: string): FormFieldConfig | undefined;
155
282
  /**
156
- * Get all fields as a flat array
157
- * @returns Array of field configurations
283
+ * Gets all fields as a flat array
284
+ *
285
+ * This method flattens the row structure to provide a simple array
286
+ * of all field configurations in the form, maintaining their order.
287
+ *
288
+ * @returns Array of all field configurations in the form
289
+ *
290
+ * @example
291
+ * ```typescript
292
+ * const allFields = builder.getFields();
293
+ * console.log(`Form has ${allFields.length} fields`);
294
+ * ```
158
295
  */
159
296
  getFields(): FormFieldConfig[];
160
297
  /**
161
- * Get all rows
162
- * @returns Array of row configurations
298
+ * Gets all rows in the form
299
+ *
300
+ * Returns a copy of the internal rows array to prevent external
301
+ * modification while allowing inspection of the form structure.
302
+ *
303
+ * @returns Array of all form rows
304
+ *
305
+ * @example
306
+ * ```typescript
307
+ * const rows = builder.getRows();
308
+ * console.log(`Form has ${rows.length} rows`);
309
+ * ```
163
310
  */
164
311
  getRows(): FormFieldRow[];
165
312
  /**
166
- * Clear all fields and rows
167
- * @returns form instance for chaining
313
+ * Clears all fields and rows from the form
314
+ *
315
+ * This method resets the form to an empty state and resets the ID generator
316
+ * to ensure clean ID generation for subsequent fields.
317
+ *
318
+ * @returns The form builder instance for method chaining
319
+ *
320
+ * @example
321
+ * ```typescript
322
+ * builder.clear().add({ type: 'text', props: { label: 'New start' } });
323
+ * ```
168
324
  */
169
325
  clear(): this;
170
326
  /**
171
- * Clone the current form builder
172
- * @param newFormId - ID for the cloned form
173
- * @returns New form instance
327
+ * Configures validation for the entire form
328
+ *
329
+ * This method sets up form-level validation that will be applied when the
330
+ * form is submitted or when validation is explicitly triggered. Form validators
331
+ * receive all form data and can perform cross-field validation.
332
+ *
333
+ * @param validationConfig - Form validation configuration
334
+ * @returns The form builder instance for method chaining
335
+ *
336
+ * @example
337
+ * ```typescript
338
+ * builder.setValidation({
339
+ * validators: [
340
+ * (formData, context) => {
341
+ * if (!formData.email && !formData.phone) {
342
+ * return createErrorResult('Either email or phone is required');
343
+ * }
344
+ * return createSuccessResult();
345
+ * }
346
+ * ],
347
+ * validateOnSubmit: true
348
+ * });
349
+ * ```
350
+ */
351
+ setValidation(validationConfig: FormValidationConfig): this;
352
+ /**
353
+ * Adds validators to the form-level validation
354
+ *
355
+ * This method allows adding validators to an existing validation configuration
356
+ * without replacing the entire configuration.
357
+ *
358
+ * @param validators - Array of form validators to add
359
+ * @returns The form builder instance for method chaining
360
+ *
361
+ * @example
362
+ * ```typescript
363
+ * builder.addValidators([
364
+ * customFormValidator,
365
+ * anotherFormValidator
366
+ * ]);
367
+ * ```
368
+ */
369
+ /**
370
+ * Adds validation to a specific field by ID
371
+ *
372
+ * This method allows adding validation to a field after it has been created,
373
+ * useful for dynamic validation requirements.
374
+ *
375
+ * @param fieldId - The ID of the field to add validation to
376
+ * @param validationConfig - Field validation configuration
377
+ * @returns The form builder instance for method chaining
378
+ * @throws Error if the field with the specified ID is not found
379
+ *
380
+ * @example
381
+ * ```typescript
382
+ * builder.addFieldValidation('email', {
383
+ * validators: [required(), email()],
384
+ * validateOnBlur: true
385
+ * });
386
+ * ```
387
+ */
388
+ /** @deprecated Use updateField with new validation.validate property instead */
389
+ addFieldValidation(fieldId: string, validationConfig: any): this;
390
+ /**
391
+ * Adds conditions to a specific field by ID
392
+ *
393
+ * This method allows adding conditional behavior to a field after it has been created,
394
+ * useful for dynamic conditional requirements.
395
+ *
396
+ * @param fieldId - The ID of the field to add conditions to
397
+ * @param conditions - Conditional behavior configuration
398
+ * @returns The form builder instance for method chaining
399
+ * @throws Error if the field with the specified ID is not found
400
+ *
401
+ * @example
402
+ * ```typescript
403
+ * builder.addFieldConditions('phone', {
404
+ * visible: when('contactMethod').equals('phone').build(),
405
+ * required: when('contactMethod').equals('phone').build()
406
+ * });
407
+ * ```
408
+ */
409
+ addFieldConditions(fieldId: string, conditions: ConditionalBehavior): this;
410
+ /**
411
+ * Creates a deep copy of the current form builder
412
+ *
413
+ * This method creates a completely independent copy of the form builder,
414
+ * including all field configurations and internal state. The cloned
415
+ * builder can be modified without affecting the original.
416
+ *
417
+ * @param newFormId - Optional new form ID for the clone
418
+ * @returns A new form builder instance with copied configuration
419
+ *
420
+ * @example
421
+ * ```typescript
422
+ * const originalForm = builder.clone();
423
+ * const modifiedForm = builder.clone('modified-form')
424
+ * .add({ type: 'text', props: { label: 'Additional field' } });
425
+ * ```
174
426
  */
175
- clone(newFormId?: string): form;
427
+ clone(newFormId?: string): form<C>;
176
428
  /**
177
- * Validate the form configuration
178
- * @returns Array of validation errors
429
+ * Checks the current form configuration for basic structural issues.
430
+ *
431
+ * @returns Array of error messages (empty if valid)
179
432
  */
180
433
  validate(): string[];
181
434
  /**
182
- * Build the final form configuration with matrix support
183
- * @returns Complete form configuration with matrix structure
435
+ * Builds the final form configuration
436
+ *
437
+ * This method creates the complete form
438
+ * configuration object ready for rendering. It includes all field
439
+ * configurations, render settings, validation configuration, and metadata.
440
+ *
441
+ * @returns Complete form configuration ready for use
442
+ *
443
+ * @example
444
+ * ```typescript
445
+ * const formConfig = builder.build();
446
+ * // Use formConfig with your form renderer
447
+ * ```
448
+ *
449
+ * @remarks
450
+ * The returned configuration includes:
451
+ * - Form ID and metadata
452
+ * - All rows with their field configurations
453
+ * - Flattened array of all fields for easy access
454
+ * - Component configuration reference
455
+ * - Render configuration for customization
456
+ * - Form-level validation configuration
184
457
  */
185
- build(): FormConfiguration;
458
+ build(): FormConfiguration<C>;
186
459
  /**
187
- * Export form configuration as JSON
188
- * @returns JSON representation of the form
460
+ * Exports the form configuration as JSON
461
+ *
462
+ * This method serializes the form configuration to a plain JavaScript
463
+ * object suitable for storage, transmission, or debugging.
464
+ *
465
+ * @returns Plain object representation of the form
466
+ *
467
+ * @example
468
+ * ```typescript
469
+ * const formJson = builder.toJSON();
470
+ * localStorage.setItem('savedForm', JSON.stringify(formJson));
471
+ * ```
189
472
  */
190
473
  toJSON(): any;
191
474
  /**
192
- * Import form configuration from JSON
193
- * @param json - JSON representation of the form
194
- * @returns form instance for chaining
475
+ * Imports form configuration from JSON
476
+ *
477
+ * This method restores form state from a previously exported JSON
478
+ * configuration. It's useful for loading saved forms or restoring
479
+ * form state from external sources.
480
+ *
481
+ * @param json - The JSON object containing form configuration
482
+ * @returns The form builder instance for method chaining
483
+ *
484
+ * @example
485
+ * ```typescript
486
+ * const savedForm = JSON.parse(localStorage.getItem('savedForm'));
487
+ * builder.fromJSON(savedForm);
488
+ * ```
489
+ *
490
+ * @remarks
491
+ * - Only imports basic form structure (ID and rows)
492
+ * - Does not validate imported configuration
493
+ * - Existing form content is replaced
195
494
  */
196
495
  fromJSON(json: any): this;
197
496
  /**
198
- * Get form statistics
199
- * @returns Object with form statistics
497
+ * Gets comprehensive statistics about the form
498
+ *
499
+ * This method provides useful metrics about the form structure,
500
+ * helpful for analytics, debugging, or UI display purposes.
501
+ *
502
+ * @returns Object containing form statistics
503
+ *
504
+ * @example
505
+ * ```typescript
506
+ * const stats = builder.getStats();
507
+ * console.log(`Form has ${stats.totalFields} fields in ${stats.totalRows} rows`);
508
+ * console.log(`Average fields per row: ${stats.averageFieldsPerRow.toFixed(1)}`);
509
+ * ```
510
+ *
511
+ * @remarks
512
+ * Statistics include:
513
+ * - Total number of fields and rows
514
+ * - Average fields per row
515
+ * - Maximum and minimum fields in any row
516
+ * - Useful for form complexity analysis
200
517
  */
201
518
  getStats(): {
519
+ /** Total number of fields across all rows */
202
520
  totalFields: number;
521
+ /** Total number of rows in the form */
203
522
  totalRows: number;
523
+ /** Average number of fields per row */
204
524
  averageFieldsPerRow: number;
525
+ /** Maximum number of fields in any single row */
205
526
  maxFieldsInRow: number;
527
+ /** Minimum number of fields in any single row */
206
528
  minFieldsInRow: number;
207
529
  };
208
530
  }
209
531
 
210
- export { Form, FormBody, type FormBodyProps, form as FormBuilder, type FormContextValue, FormField, type FormFieldProps, type FormProps, FormProvider, type FormProviderProps, FormRow, type FormRowProps, type FormState, FormSubmitButton, type FormSubmitButtonProps, form, useFormContext };
532
+ interface FormProps {
533
+ formConfig: FormConfiguration<any> | form<any>;
534
+ defaultValues?: Record<string, any>;
535
+ onSubmit?: (data: Record<string, any>) => void | Promise<void>;
536
+ onFieldChange?: (fieldId: string, value: any, formData: Record<string, any>) => void;
537
+ className?: string;
538
+ children: React.ReactNode;
539
+ }
540
+ declare function Form({ formConfig, defaultValues, onSubmit, onFieldChange, children }: FormProps): react_jsx_runtime.JSX.Element;
541
+
542
+ declare const FormBody: React__default.NamedExoticComponent<ComponentRendererBaseProps<FormBodyRendererProps>>;
543
+
544
+ interface FormFieldProps {
545
+ fieldId: string;
546
+ disabled?: boolean;
547
+ customProps?: Record<string, unknown>;
548
+ className?: string;
549
+ forceVisible?: boolean;
550
+ }
551
+ declare const FormField: React__default.NamedExoticComponent<FormFieldProps>;
552
+
553
+ interface ConditionEvaluationResult {
554
+ visible: boolean;
555
+ disabled: boolean;
556
+ required: boolean;
557
+ readonly: boolean;
558
+ }
559
+ /**
560
+ * Hook to evaluate conditional behaviors based on form data
561
+ *
562
+ * @param conditions - The conditional behavior configuration
563
+ * @param formData - Current form data to evaluate against
564
+ * @param defaultState - Default state when no conditions are provided
565
+ * @returns Evaluated condition results
566
+ */
567
+ declare function useConditionEvaluation(conditions?: ConditionalBehavior, formData?: Record<string, any>, defaultState?: Partial<ConditionEvaluationResult>): ConditionEvaluationResult;
568
+ /**
569
+ * Hook to evaluate conditions for multiple fields at once
570
+ *
571
+ * @param fieldsWithConditions - Map of field IDs to their conditional behaviors
572
+ * @param formData - Current form data
573
+ * @returns Map of field IDs to their evaluated conditions
574
+ */
575
+ declare function useMultipleConditionEvaluation(fieldsWithConditions: Record<string, ConditionalBehavior | undefined>, formData?: Record<string, any>): Record<string, ConditionEvaluationResult>;
576
+
577
+ interface UseFieldConditionsLazyOptions {
578
+ /**
579
+ * The field's conditional behavior configuration
580
+ */
581
+ conditions?: ConditionalBehavior;
582
+ /**
583
+ * Whether to skip evaluation (e.g., if field has no conditions)
584
+ */
585
+ skip?: boolean;
586
+ }
587
+ /**
588
+ * Lazy condition evaluation hook with caching
589
+ *
590
+ * This hook:
591
+ * 1. Only evaluates conditions when called
592
+ * 2. Caches the result based on form values hash
593
+ * 3. Returns cached result if values haven't changed
594
+ *
595
+ * @param fieldId - The field ID
596
+ * @param options - Configuration options
597
+ * @returns The evaluated field conditions
598
+ *
599
+ * @example
600
+ * ```tsx
601
+ * const conditions = useFieldConditionsLazy('myField', {
602
+ * conditions: fieldConfig.conditions
603
+ * });
604
+ *
605
+ * if (!conditions.visible) return null;
606
+ * ```
607
+ */
608
+ declare function useFieldConditionsLazy(fieldId: string, options?: UseFieldConditionsLazyOptions): FieldConditions;
609
+ /**
610
+ * Hook to create a lazy condition evaluator function
611
+ *
612
+ * This is useful when you need to evaluate conditions for multiple fields
613
+ * on-demand, without triggering re-renders.
614
+ *
615
+ * @returns A function that evaluates conditions for a given field
616
+ */
617
+ declare function useConditionEvaluator(): (fieldId: string, conditions?: ConditionalBehavior) => FieldConditions;
618
+ /**
619
+ * Hook that provides both current conditions and a way to force re-evaluation
620
+ */
621
+ declare function useFieldConditionsWithRefresh(fieldId: string, conditions?: ConditionalBehavior): {
622
+ conditions: FieldConditions;
623
+ refresh: () => FieldConditions;
624
+ };
625
+
626
+ interface UseFormConditionsProps {
627
+ formConfig: FormConfiguration;
628
+ formValues: Record<string, any>;
629
+ }
630
+ interface UseFormConditionsReturn {
631
+ fieldConditions: Record<string, ConditionEvaluationResult>;
632
+ hasConditionalFields: boolean;
633
+ getFieldCondition: (fieldId: string) => ConditionEvaluationResult | undefined;
634
+ isFieldVisible: (fieldId: string) => boolean;
635
+ isFieldDisabled: (fieldId: string) => boolean;
636
+ isFieldRequired: (fieldId: string) => boolean;
637
+ isFieldReadonly: (fieldId: string) => boolean;
638
+ }
639
+ /**
640
+ * Hook to manage conditional behaviors for form fields
641
+ *
642
+ * This hook evaluates conditions for all form fields and provides
643
+ * convenient methods to check field states.
644
+ *
645
+ * @param props - Configuration for form conditions
646
+ * @returns Object containing field conditions and helper methods
647
+ *
648
+ * @example
649
+ * ```tsx
650
+ * const {
651
+ * fieldConditions,
652
+ * isFieldVisible,
653
+ * isFieldDisabled
654
+ * } = useFormConditions({
655
+ * formConfig,
656
+ * formValues
657
+ * });
658
+ *
659
+ * // Check if a field should be visible
660
+ * if (!isFieldVisible('phoneField')) {
661
+ * return null;
662
+ * }
663
+ * ```
664
+ */
665
+ declare function useFormConditions({ formConfig, formValues, }: UseFormConditionsProps): UseFormConditionsReturn;
666
+
667
+ interface FormStoreState extends FormState {
668
+ _defaultValues: Record<string, unknown>;
669
+ _fieldConditions: Record<string, FieldConditions>;
670
+ _setValue: (fieldId: string, value: unknown) => void;
671
+ _setTouched: (fieldId: string) => void;
672
+ _setErrors: (fieldId: string, errors: ValidationError[]) => void;
673
+ _clearErrors: (fieldId: string) => void;
674
+ _setValidationState: (fieldId: string, state: ValidationState) => void;
675
+ _setSubmitting: (isSubmitting: boolean) => void;
676
+ _reset: (values?: Record<string, unknown>) => void;
677
+ _setFieldConditions: (fieldId: string, conditions: FieldConditions) => void;
678
+ _updateIsValid: () => void;
679
+ }
680
+ type FormStore = ReturnType<typeof createFormStore>;
681
+ declare function createFormStore(initialValues?: Record<string, unknown>): Omit<zustand.StoreApi<FormStoreState>, "subscribe"> & {
682
+ subscribe: {
683
+ (listener: (selectedState: FormStoreState, previousSelectedState: FormStoreState) => void): () => void;
684
+ <U>(selector: (state: FormStoreState) => U, listener: (selectedState: U, previousSelectedState: U) => void, options?: {
685
+ equalityFn?: ((a: U, b: U) => boolean) | undefined;
686
+ fireImmediately?: boolean;
687
+ } | undefined): () => void;
688
+ };
689
+ };
690
+ declare const FormStoreContext: React$1.Context<(Omit<zustand.StoreApi<FormStoreState>, "subscribe"> & {
691
+ subscribe: {
692
+ (listener: (selectedState: FormStoreState, previousSelectedState: FormStoreState) => void): () => void;
693
+ <U>(selector: (state: FormStoreState) => U, listener: (selectedState: U, previousSelectedState: U) => void, options?: {
694
+ equalityFn?: ((a: U, b: U) => boolean) | undefined;
695
+ fireImmediately?: boolean;
696
+ } | undefined): () => void;
697
+ };
698
+ }) | null>;
699
+ /**
700
+ * Get the form store from context
701
+ * @throws Error if used outside of FormProvider
702
+ */
703
+ declare function useFormStore(): FormStore;
704
+ /**
705
+ * Select a single field value - re-renders only when this field's value changes
706
+ */
707
+ declare function useFieldValue<T = unknown>(fieldId: string): T;
708
+ /**
709
+ * Select field errors - re-renders only when this field's errors change
710
+ */
711
+ declare function useFieldErrors(fieldId: string): ValidationError[];
712
+ /**
713
+ * Select field touched state - re-renders only when this field's touched state changes
714
+ */
715
+ declare function useFieldTouched(fieldId: string): boolean;
716
+ /**
717
+ * Select field validation state - re-renders only when this field's validation state changes
718
+ */
719
+ declare function useFieldValidationState(fieldId: string): ValidationState;
720
+ /**
721
+ * Select field conditions - re-renders only when this field's conditions change
722
+ */
723
+ declare function useFieldConditions(fieldId: string): FieldConditions;
724
+ /**
725
+ * Select complete field state - uses individual selectors to avoid object recreation
726
+ */
727
+ declare function useFieldState(fieldId: string): FieldState;
728
+ /**
729
+ * Select form submitting state
730
+ */
731
+ declare function useFormSubmitting(): boolean;
732
+ /**
733
+ * Select form valid state
734
+ */
735
+ declare function useFormValid(): boolean;
736
+ /**
737
+ * Select form dirty state
738
+ */
739
+ declare function useFormDirty(): boolean;
740
+ /**
741
+ * Select all form values - uses shallow comparison
742
+ */
743
+ declare function useFormValues(): Record<string, unknown>;
744
+ /**
745
+ * Select form state for submit button - minimal re-renders
746
+ */
747
+ declare function useFormSubmitState(): {
748
+ isSubmitting: boolean;
749
+ isValid: boolean;
750
+ isDirty: boolean;
751
+ };
752
+ interface UseFieldActionsResult {
753
+ setValue: (value: unknown) => void;
754
+ setTouched: () => void;
755
+ setErrors: (errors: ValidationError[]) => void;
756
+ clearErrors: () => void;
757
+ setValidationState: (state: ValidationState) => void;
758
+ }
759
+ /**
760
+ * Get stable action references for a field
761
+ * Actions don't cause re-renders
762
+ */
763
+ declare function useFieldActions(fieldId: string): UseFieldActionsResult;
764
+ interface UseFormActionsResult {
765
+ setValue: (fieldId: string, value: unknown) => void;
766
+ setTouched: (fieldId: string) => void;
767
+ setErrors: (fieldId: string, errors: ValidationError[]) => void;
768
+ setSubmitting: (isSubmitting: boolean) => void;
769
+ reset: (values?: Record<string, unknown>) => void;
770
+ setFieldConditions: (fieldId: string, conditions: FieldConditions) => void;
771
+ }
772
+ /**
773
+ * Get stable form-level action references
774
+ * Actions don't cause re-renders
775
+ */
776
+ declare function useFormActions(): UseFormActionsResult;
777
+ /**
778
+ * Get the raw store for advanced use cases (like validation hooks)
779
+ */
780
+ declare function useFormStoreApi(): FormStore;
781
+
782
+ interface UseFormSubmissionWithStoreProps {
783
+ store: FormStore;
784
+ onSubmit?: (data: Record<string, unknown>) => void | Promise<void>;
785
+ validateForm: () => Promise<ValidationResult>;
786
+ }
787
+ declare function useFormSubmissionWithStore({ store, onSubmit, validateForm, }: UseFormSubmissionWithStoreProps): {
788
+ submit: (event?: React__default.FormEvent) => Promise<boolean>;
789
+ };
790
+
791
+ interface UseFormValidationWithStoreProps {
792
+ formConfig: FormConfiguration;
793
+ store: FormStore;
794
+ conditionsHelpers: Omit<UseFormConditionsReturn, 'fieldConditions'>;
795
+ }
796
+ declare function useFormValidationWithStore({ formConfig, store, conditionsHelpers, }: UseFormValidationWithStoreProps): {
797
+ validateField: (fieldId: string, value?: unknown) => Promise<ValidationResult>;
798
+ validateForm: () => Promise<ValidationResult>;
799
+ };
800
+
801
+ interface UseFormMonitoringProps {
802
+ formConfig: FormConfiguration;
803
+ monitoring?: MonitoringConfig;
804
+ enabled?: boolean;
805
+ }
806
+ interface UseFormMonitoringReturn {
807
+ trackFormRender: (renderCount?: number) => void;
808
+ trackFormValidation: (validationErrors: number, fieldCount?: number) => void;
809
+ trackFormSubmission: (success: boolean, fieldCount?: number) => void;
810
+ trackFieldChange: (fieldId: string, componentType: string) => void;
811
+ startPerformanceTracking: (label: string) => void;
812
+ endPerformanceTracking: (label: string) => FormPerformanceMetrics | null;
813
+ }
814
+ declare function useFormMonitoring({ formConfig, enabled, }: UseFormMonitoringProps): UseFormMonitoringReturn;
815
+
816
+ interface FormConfigContextValue {
817
+ formConfig: FormConfiguration;
818
+ conditionsHelpers: Omit<UseFormConditionsReturn, 'fieldConditions'>;
819
+ validateField: (fieldId: string, value?: unknown) => Promise<ValidationResult>;
820
+ validateForm: () => Promise<ValidationResult>;
821
+ submit: (event?: React__default.FormEvent) => Promise<boolean>;
822
+ }
823
+ /**
824
+ * Access form configuration and validation methods
825
+ */
826
+ declare function useFormConfigContext(): FormConfigContextValue;
827
+ interface FormProviderProps {
828
+ children: React__default.ReactNode;
829
+ formConfig: FormConfiguration;
830
+ defaultValues?: Record<string, unknown>;
831
+ onSubmit?: (data: Record<string, unknown>) => void | Promise<void>;
832
+ onFieldChange?: (fieldId: string, value: unknown, formData: Record<string, unknown>) => void;
833
+ className?: string;
834
+ }
835
+ declare function FormProvider({ children, formConfig, defaultValues, onSubmit, onFieldChange, className, }: FormProviderProps): react_jsx_runtime.JSX.Element;
836
+
837
+ interface FormRowProps extends ComponentRendererBaseProps<FormRowRendererProps> {
838
+ row: FormFieldRow;
839
+ }
840
+ declare const FormRow: React__default.NamedExoticComponent<FormRowProps>;
841
+
842
+ interface FormSubmitButtonProps extends ComponentRendererBaseProps<FormSubmitButtonRendererProps> {
843
+ /**
844
+ * Override the isSubmitting state from form context
845
+ * If provided, this value will be used instead of the form's isSubmitting state
846
+ */
847
+ isSubmitting?: boolean;
848
+ }
849
+ declare const FormSubmitButton: React__default.NamedExoticComponent<FormSubmitButtonProps>;
850
+
851
+ export { type ConditionEvaluationResult, type FieldConfig, Form, FormBody, form as FormBuilder, type FormConfigContextValue, FormField, FormProvider, type FormProviderProps, FormRow, type FormStore, FormStoreContext, type FormStoreState, FormSubmitButton, type UseFieldActionsResult, type UseFieldConditionsLazyOptions, type UseFormActionsResult, type UseFormConditionsProps, type UseFormConditionsReturn, type UseFormMonitoringProps, type UseFormMonitoringReturn, type UseFormSubmissionWithStoreProps, type UseFormValidationWithStoreProps, createFormStore, form, useConditionEvaluation, useConditionEvaluator, useFieldActions, useFieldConditions, useFieldConditionsLazy, useFieldConditionsWithRefresh, useFieldErrors, useFieldState, useFieldTouched, useFieldValidationState, useFieldValue, useFormActions, useFormConditions, useFormConfigContext, useFormDirty, useFormMonitoring, useFormStore, useFormStoreApi, useFormSubmissionWithStore, useFormSubmitState, useFormSubmitting, useFormValid, useFormValidationWithStore, useFormValues, useMultipleConditionEvaluation };