@rachelallyson/hero-hook-form 1.2.0 → 2.0.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/CHANGELOG.md +80 -0
- package/dist/cypress/index.d.ts +141 -0
- package/dist/cypress/index.js +897 -0
- package/dist/index.d.ts +730 -5
- package/dist/index.js +1832 -220
- package/dist/react/index.d.ts +730 -5
- package/dist/react/index.js +1832 -220
- package/package.json +10 -3
- package/README.md +0 -412
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,86 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [2.0.0] - 2025-01-27
|
|
6
|
+
|
|
7
|
+
### 🎉 Major Release - Enhanced Form Experience
|
|
8
|
+
|
|
9
|
+
This is a major release with significant new features, performance improvements, and some breaking changes. See the [Migration Guide](./docs/migration-v2.md) for upgrade instructions.
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
#### Dynamic Form Sections
|
|
14
|
+
|
|
15
|
+
- **Conditional Fields**: Show/hide fields based on form data with `ConditionalField` component
|
|
16
|
+
- **Field Arrays**: Dynamic repeating field groups with `FieldArrayField` component
|
|
17
|
+
- **Dynamic Sections**: Grouped conditional fields with `DynamicSectionField` component
|
|
18
|
+
- Builder methods: `conditionalField()`, `fieldArray()`, `dynamicSection()`
|
|
19
|
+
|
|
20
|
+
#### Enhanced Form State Management
|
|
21
|
+
|
|
22
|
+
- **Enhanced Form State Hook**: `useEnhancedFormState` with comprehensive state tracking
|
|
23
|
+
- **Form Status Component**: `FormStatus` with loading, success, and error states
|
|
24
|
+
- **Automatic State Management**: Built-in loading indicators and success feedback
|
|
25
|
+
- **Toast Notifications**: Optional toast notifications with `FormToast` component
|
|
26
|
+
|
|
27
|
+
#### Performance Optimizations
|
|
28
|
+
|
|
29
|
+
- **Memoized Components**: All field components now use `React.memo` for better performance
|
|
30
|
+
- **Debounced Validation**: `useDebouncedValidation` hook for configurable validation delays
|
|
31
|
+
- **Performance Utilities**: `usePerformanceMonitor`, `useBatchedFieldUpdates`, and optimization helpers
|
|
32
|
+
- **Memory Optimization**: Better memory usage with proper cleanup and memoization
|
|
33
|
+
|
|
34
|
+
#### Type-Inferred Forms (Alternative API)
|
|
35
|
+
|
|
36
|
+
- **Type-Inferred Builder**: `TypeInferredBuilder` for automatic schema and field generation
|
|
37
|
+
- **Define Inferred Form**: `defineInferredForm` function for single-call form definition
|
|
38
|
+
- **Field Type Builders**: Individual field builders with proper type inference
|
|
39
|
+
- **Auto-Generated Schemas**: Automatic Zod schema generation from field definitions
|
|
40
|
+
|
|
41
|
+
#### Enhanced Validation Patterns
|
|
42
|
+
|
|
43
|
+
- **Cross-Field Validation**: Password confirmation, date ranges, conditional requirements
|
|
44
|
+
- **Validation Patterns**: Common patterns for emails, phones, passwords, credit cards
|
|
45
|
+
- **Async Validation**: Server-side validation integration with `asyncValidation` helpers
|
|
46
|
+
- **Validation Utilities**: Comprehensive validation utilities and error message helpers
|
|
47
|
+
|
|
48
|
+
#### New Hooks and Utilities
|
|
49
|
+
|
|
50
|
+
- `useEnhancedFormState`: Comprehensive form state management
|
|
51
|
+
- `useDebouncedValidation`: Debounced field validation
|
|
52
|
+
- `useInferredForm`: Type-inferred form hook
|
|
53
|
+
- `usePerformanceMonitor`: Performance monitoring utilities
|
|
54
|
+
- `useBatchedFieldUpdates`: Batched field updates for better performance
|
|
55
|
+
|
|
56
|
+
### Changed
|
|
57
|
+
|
|
58
|
+
#### Breaking Changes
|
|
59
|
+
|
|
60
|
+
- **Field Props**: `isDisabled` → `disabled` for consistency with HeroUI
|
|
61
|
+
- **Form State**: Enhanced form state structure with additional properties and methods
|
|
62
|
+
- **Field Configuration**: `FormFieldConfig` → `ZodFormFieldConfig` (removed `rules` property)
|
|
63
|
+
- **Type Definitions**: Updated type definitions for better TypeScript support
|
|
64
|
+
|
|
65
|
+
#### API Improvements
|
|
66
|
+
|
|
67
|
+
- **Consistent Naming**: Standardized prop names across all components
|
|
68
|
+
- **Better Type Safety**: Enhanced TypeScript support with better type inference
|
|
69
|
+
- **Simplified API**: Cleaner, more intuitive API design
|
|
70
|
+
- **Performance**: Significant performance improvements across all components
|
|
71
|
+
|
|
72
|
+
### Fixed
|
|
73
|
+
|
|
74
|
+
- **Memory Leaks**: Fixed potential memory leaks in form components
|
|
75
|
+
- **Type Safety**: Resolved TypeScript compilation issues
|
|
76
|
+
- **Build Process**: Improved build process and bundle optimization
|
|
77
|
+
- **Component Re-renders**: Reduced unnecessary re-renders with proper memoization
|
|
78
|
+
|
|
79
|
+
### Removed
|
|
80
|
+
|
|
81
|
+
- **Deprecated APIs**: Removed deprecated field prop names
|
|
82
|
+
- **Legacy Code**: Cleaned up legacy code and unused utilities
|
|
83
|
+
- **Redundant Types**: Simplified type definitions by removing redundant types
|
|
84
|
+
|
|
5
85
|
## [1.0.2] - 2025-01-27
|
|
6
86
|
|
|
7
87
|
### Enhanced
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript types for Cypress form testing helpers
|
|
3
|
+
*/
|
|
4
|
+
interface FormFieldData {
|
|
5
|
+
[key: string]: string | number | boolean | string[] | FileList | null;
|
|
6
|
+
}
|
|
7
|
+
interface FormFlowStep {
|
|
8
|
+
/** Type of interaction */
|
|
9
|
+
type: 'fill' | 'select' | 'check' | 'uncheck' | 'submit' | 'wait';
|
|
10
|
+
/** Field identifier (label, type, placeholder, etc.) */
|
|
11
|
+
field?: string;
|
|
12
|
+
/** Value to set or option to select */
|
|
13
|
+
value?: string | number | boolean;
|
|
14
|
+
/** Expected result after step */
|
|
15
|
+
expect?: string | boolean;
|
|
16
|
+
/** Wait time in milliseconds */
|
|
17
|
+
waitTime?: number;
|
|
18
|
+
}
|
|
19
|
+
interface FieldInteractionOptions {
|
|
20
|
+
/** Whether to clear field before typing */
|
|
21
|
+
clear?: boolean;
|
|
22
|
+
/** Whether to use force click for dropdowns */
|
|
23
|
+
force?: boolean;
|
|
24
|
+
/** Whether to wait for field to be visible */
|
|
25
|
+
waitForVisible?: boolean;
|
|
26
|
+
/** Custom timeout for this interaction */
|
|
27
|
+
timeout?: number;
|
|
28
|
+
}
|
|
29
|
+
interface CypressFormHelpers {
|
|
30
|
+
fillInputByType: (type: string, value: string, index?: number) => Cypress.Chainable<Element>;
|
|
31
|
+
fillInputByPlaceholder: (placeholder: string, value: string) => Cypress.Chainable<Element>;
|
|
32
|
+
fillInputByLabel: (label: string, value: string) => Cypress.Chainable<Element>;
|
|
33
|
+
fillTextarea: (value: string, index?: number) => Cypress.Chainable<Element>;
|
|
34
|
+
selectDropdownOption: (optionValue: string, dropdownIndex?: number) => Cypress.Chainable<Element>;
|
|
35
|
+
selectDropdownByLabel: (label: string, optionValue: string) => Cypress.Chainable<Element>;
|
|
36
|
+
checkCheckbox: (index?: number) => Cypress.Chainable<Element>;
|
|
37
|
+
checkCheckboxByLabel: (label: string) => Cypress.Chainable<Element>;
|
|
38
|
+
checkSwitch: (index?: number) => Cypress.Chainable<Element>;
|
|
39
|
+
uncheckCheckbox: (index?: number) => Cypress.Chainable<Element>;
|
|
40
|
+
uncheckSwitch: (index?: number) => Cypress.Chainable<Element>;
|
|
41
|
+
moveSlider: (value: number, index?: number) => Cypress.Chainable<Element>;
|
|
42
|
+
expectValidationError: (message: string) => Cypress.Chainable<Element>;
|
|
43
|
+
expectNoValidationErrors: () => Cypress.Chainable<Element>;
|
|
44
|
+
expectFieldError: (fieldLabel: string, errorMessage: string) => Cypress.Chainable<Element>;
|
|
45
|
+
expectFieldValid: (fieldLabel: string) => Cypress.Chainable<Element>;
|
|
46
|
+
triggerValidation: (submitButton?: boolean) => Cypress.Chainable<Element>;
|
|
47
|
+
submitForm: () => Cypress.Chainable<Element>;
|
|
48
|
+
submitAndExpectSuccess: (successIndicator?: string) => Cypress.Chainable<Element>;
|
|
49
|
+
submitAndExpectErrors: () => Cypress.Chainable<Element>;
|
|
50
|
+
resetForm: () => Cypress.Chainable<Element>;
|
|
51
|
+
interceptFormSubmission: (method: string, url: string, alias: string) => Cypress.Chainable<Element>;
|
|
52
|
+
verifyFormExists: () => Cypress.Chainable<Element>;
|
|
53
|
+
verifyFieldExists: (selector: string) => Cypress.Chainable<Element>;
|
|
54
|
+
verifyFieldValue: (selector: string, value: string) => Cypress.Chainable<Element>;
|
|
55
|
+
verifyFieldCount: (selector: string, count: number) => Cypress.Chainable<Element>;
|
|
56
|
+
getFormData: () => Cypress.Chainable<FormFieldData>;
|
|
57
|
+
fillCompleteForm: (formData: FormFieldData) => Cypress.Chainable<Element>;
|
|
58
|
+
testFieldInteraction: (fieldType: string, value: string) => Cypress.Chainable<Element>;
|
|
59
|
+
testFormFlow: (steps: FormFlowStep[]) => Cypress.Chainable<Element>;
|
|
60
|
+
}
|
|
61
|
+
declare global {
|
|
62
|
+
namespace Cypress {
|
|
63
|
+
interface Chainable extends CypressFormHelpers {
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* TypeScript declarations for Cypress form testing helpers
|
|
70
|
+
*/
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
declare global {
|
|
75
|
+
namespace Cypress {
|
|
76
|
+
interface Chainable {
|
|
77
|
+
// Field Interaction Helpers
|
|
78
|
+
fillInputByType(type: string, value: string, index?: number, options?: FieldInteractionOptions): Chainable<Element>;
|
|
79
|
+
fillInputByPlaceholder(placeholder: string, value: string, options?: FieldInteractionOptions): Chainable<Element>;
|
|
80
|
+
fillInputByLabel(label: string, value: string, options?: FieldInteractionOptions): Chainable<Element>;
|
|
81
|
+
fillTextarea(value: string, index?: number, options?: FieldInteractionOptions): Chainable<Element>;
|
|
82
|
+
selectDropdownOption(optionValue: string, dropdownIndex?: number): Chainable<Element>;
|
|
83
|
+
selectDropdownByLabel(label: string, optionValue: string): Chainable<Element>;
|
|
84
|
+
checkCheckbox(index?: number): Chainable<Element>;
|
|
85
|
+
checkCheckboxByLabel(label: string): Chainable<Element>;
|
|
86
|
+
checkSwitch(index?: number): Chainable<Element>;
|
|
87
|
+
uncheckCheckbox(index?: number): Chainable<Element>;
|
|
88
|
+
uncheckSwitch(index?: number): Chainable<Element>;
|
|
89
|
+
moveSlider(value: number, index?: number): Chainable<Element>;
|
|
90
|
+
|
|
91
|
+
// Validation & Error Testing Helpers
|
|
92
|
+
expectValidationError(message: string): Chainable<Element>;
|
|
93
|
+
expectNoValidationErrors(): Chainable<Element>;
|
|
94
|
+
expectFieldError(fieldLabel: string, errorMessage?: string): Chainable<Element>;
|
|
95
|
+
expectFieldValid(fieldLabel: string): Chainable<Element>;
|
|
96
|
+
triggerValidation(submitButton?: string): Chainable<Element>;
|
|
97
|
+
testRealTimeValidation(fieldLabel: string, invalidValue: string, expectedError?: string): Chainable<Element>;
|
|
98
|
+
testRequiredFieldValidation(fieldLabel: string, expectedError?: string): Chainable<Element>;
|
|
99
|
+
testEmailValidation(email: string, shouldBeValid: boolean): Chainable<Element>;
|
|
100
|
+
testPhoneValidation(phone: string, shouldBeValid: boolean): Chainable<Element>;
|
|
101
|
+
testPasswordValidation(password: string, shouldBeValid: boolean): Chainable<Element>;
|
|
102
|
+
testRequiredFieldsValidation(): Chainable<Element>;
|
|
103
|
+
|
|
104
|
+
// Form Submission Helpers
|
|
105
|
+
submitForm(): Chainable<Element>;
|
|
106
|
+
submitAndExpectSuccess(successIndicator?: string): Chainable<Element>;
|
|
107
|
+
submitAndExpectErrors(): Chainable<Element>;
|
|
108
|
+
resetForm(): Chainable<Element>;
|
|
109
|
+
interceptFormSubmission(method: string, url: string, alias: string): Chainable<Element>;
|
|
110
|
+
|
|
111
|
+
// Form State Helpers
|
|
112
|
+
verifyFormExists(): Chainable<Element>;
|
|
113
|
+
verifyFieldExists(selector: string): Chainable<Element>;
|
|
114
|
+
verifyFieldValue(selector: string, value: string): Chainable<Element>;
|
|
115
|
+
verifyFieldCount(selector: string, count: number): Chainable<Element>;
|
|
116
|
+
getFormData(): Chainable<FormFieldData>;
|
|
117
|
+
|
|
118
|
+
// Complex Form Flow Helpers
|
|
119
|
+
fillCompleteForm(formData: FormFieldData): Chainable<Element>;
|
|
120
|
+
testFieldInteraction(fieldType: string, value: string): Chainable<Element>;
|
|
121
|
+
testFormFlow(steps: FormFlowStep[]): Chainable<Element>;
|
|
122
|
+
|
|
123
|
+
// Legacy commands (backward compatibility)
|
|
124
|
+
fillField(label: string, value: string): Chainable<Element>;
|
|
125
|
+
selectOption(label: string, option: string): Chainable<Element>;
|
|
126
|
+
|
|
127
|
+
// Convenience commands
|
|
128
|
+
fillEmail(value: string): Chainable<Element>;
|
|
129
|
+
fillPhone(value: string): Chainable<Element>;
|
|
130
|
+
fillPassword(value: string): Chainable<Element>;
|
|
131
|
+
fillText(value: string): Chainable<Element>;
|
|
132
|
+
|
|
133
|
+
// Debug commands
|
|
134
|
+
logFormState(): Chainable<Element>;
|
|
135
|
+
waitForFormReady(): Chainable<Element>;
|
|
136
|
+
clearForm(): Chainable<Element>;
|
|
137
|
+
verifyFormValid(): Chainable<Element>;
|
|
138
|
+
screenshotForm(name?: string): Chainable<Element>;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|