@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 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
+ }