@rachelallyson/hero-hook-form 2.6.0 → 2.7.2
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 +53 -0
- package/dist/cypress/index.d.ts +62 -71
- package/dist/cypress/index.js +583 -70
- package/dist/index.d.ts +876 -101
- package/dist/index.js +1684 -719
- package/package.json +15 -12
- package/dist/react/index.d.ts +0 -3428
- package/dist/react/index.js +0 -3989
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,59 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [2.7.2] - 2026-01-21
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- **Critical Bug Fix: Input Name Attributes**: Fixed missing `name` prop forwarding in `InputField` component
|
|
10
|
+
- `CoercedInput` now properly passes `name={field.name}` to HeroUI Input components
|
|
11
|
+
- Fixes accessibility issues where form inputs had no name attribute in DOM
|
|
12
|
+
- Critical for form automation tools, accessibility compliance, and proper form submission
|
|
13
|
+
- Affects all input types (text, email, password, tel, number, etc.) in ZodForm
|
|
14
|
+
|
|
15
|
+
### Internal
|
|
16
|
+
|
|
17
|
+
- **Architecture Cleanup: Simplified HeroUI Integration**: Removed redundant dual-build system and `/react` subpath
|
|
18
|
+
- Eliminated duplicate `react/fields/` components and `tsconfig.react.json`
|
|
19
|
+
- Streamlined to single `#ui` alias approach that works with both individual `@heroui/*` packages and `@heroui/react`
|
|
20
|
+
- `@heroui/react` re-exports all components, making separate configurations unnecessary
|
|
21
|
+
- Cleaner codebase with same functionality and flexibility for users
|
|
22
|
+
|
|
23
|
+
## [2.7.0] - 2026-01-13
|
|
24
|
+
|
|
25
|
+
### Added
|
|
26
|
+
|
|
27
|
+
- **Enhanced FieldArrayConfig**: Added powerful new features for dynamic field arrays
|
|
28
|
+
- `enableReordering` - Enable up/down buttons to reorder array items
|
|
29
|
+
- `reorderButtonText` - Customize reorder button labels (`{ up?: string; down?: string }`)
|
|
30
|
+
- `renderItem` - Custom render function for array items with full control over layout
|
|
31
|
+
- `renderAddButton` - Custom render function for the add button
|
|
32
|
+
- `defaultItem` - Function to create default values when adding new array items
|
|
33
|
+
- Conditional fields now work within array items (automatic path resolution)
|
|
34
|
+
- Example: `{ type: "fieldArray", name: "slots", enableReordering: true, ... }`
|
|
35
|
+
|
|
36
|
+
- **SimpleForm Component**: New simplified API for single-field forms
|
|
37
|
+
- Perfect for search bars, message inputs, or simple single-field forms
|
|
38
|
+
- Uses `ZodForm` internally for consistent validation and error handling
|
|
39
|
+
- Example: `<SimpleForm schema={schema} field={FormFieldHelpers.input("message", "")} />`
|
|
40
|
+
|
|
41
|
+
- **syncArrays Utility**: Helper function for syncing arrays in edit forms
|
|
42
|
+
- Determines which items to create, update, or delete based on IDs
|
|
43
|
+
- Useful for edit forms where you need to sync array changes with a database
|
|
44
|
+
- Example: `const { toCreate, toUpdate, toDelete } = syncArrays({ existing, current, getId })`
|
|
45
|
+
|
|
46
|
+
- **createFieldArrayCustomConfig Helper**: Reduces boilerplate for custom field arrays
|
|
47
|
+
- Creates a `CustomFieldConfig` that uses `useFieldArray` internally
|
|
48
|
+
- Provides structured way to render custom array items with reordering
|
|
49
|
+
- Example: `createFieldArrayCustomConfig({ name: "slots", enableReordering: true, ... })`
|
|
50
|
+
|
|
51
|
+
### Fixed
|
|
52
|
+
|
|
53
|
+
- **Conditional Fields in Arrays**: Fixed path resolution for conditional fields within array items
|
|
54
|
+
- Uses `get()` from react-hook-form to correctly resolve nested paths like `"slots.0.slotType"`
|
|
55
|
+
- Conditional fields now work correctly within dynamic field arrays
|
|
56
|
+
- Example: Field with `dependsOn: "slotType"` in array item automatically resolves to `"slots.0.slotType"`
|
|
57
|
+
|
|
5
58
|
## [2.6.0] - 2026-01-13
|
|
6
59
|
|
|
7
60
|
### Added
|
package/dist/cypress/index.d.ts
CHANGED
|
@@ -1,80 +1,48 @@
|
|
|
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
1
|
/**
|
|
69
2
|
* TypeScript declarations for Cypress form testing helpers
|
|
70
3
|
*/
|
|
71
4
|
|
|
5
|
+
import type { FormFieldData, FormFlowStep, FieldInteractionOptions } from './types';
|
|
6
|
+
|
|
7
|
+
// Re-export types and helpers
|
|
8
|
+
export * from './types';
|
|
9
|
+
export * from './utils';
|
|
10
|
+
export * from './helpers';
|
|
11
|
+
|
|
12
|
+
// Export the main registration function
|
|
13
|
+
export function registerHeroFormCommands(): void;
|
|
72
14
|
|
|
15
|
+
// Export constants
|
|
16
|
+
export const SETUP_INSTRUCTIONS: {
|
|
17
|
+
installation: string;
|
|
18
|
+
import: string;
|
|
19
|
+
usage: string;
|
|
20
|
+
};
|
|
73
21
|
|
|
22
|
+
export const COMMANDS_REFERENCE: {
|
|
23
|
+
fieldInteractions: string[];
|
|
24
|
+
validation: string[];
|
|
25
|
+
submission: string[];
|
|
26
|
+
state: string[];
|
|
27
|
+
complex: string[];
|
|
28
|
+
convenience: string[];
|
|
29
|
+
debug: string[];
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
// Global type augmentations for Cypress
|
|
74
33
|
declare global {
|
|
75
34
|
namespace Cypress {
|
|
76
35
|
interface Chainable {
|
|
77
|
-
// Field Interaction Helpers
|
|
36
|
+
// Field Interaction Helpers - Name-based (recommended, most reliable)
|
|
37
|
+
fillInputByName(name: string, value: string, options?: FieldInteractionOptions): Chainable<Element>;
|
|
38
|
+
fillTextareaByName(name: string, value: string, options?: FieldInteractionOptions): Chainable<Element>;
|
|
39
|
+
selectDropdownByName(name: string, optionValue: string): Chainable<Element>;
|
|
40
|
+
checkCheckboxByName(name: string): Chainable<Element>;
|
|
41
|
+
checkSwitchByName(name: string): Chainable<Element>;
|
|
42
|
+
uncheckCheckboxByName(name: string): Chainable<Element>;
|
|
43
|
+
uncheckSwitchByName(name: string): Chainable<Element>;
|
|
44
|
+
|
|
45
|
+
// Field Interaction Helpers - Legacy methods (still supported)
|
|
78
46
|
fillInputByType(type: string, value: string, index?: number, options?: FieldInteractionOptions): Chainable<Element>;
|
|
79
47
|
fillInputByPlaceholder(placeholder: string, value: string, options?: FieldInteractionOptions): Chainable<Element>;
|
|
80
48
|
fillInputByLabel(label: string, value: string, options?: FieldInteractionOptions): Chainable<Element>;
|
|
@@ -87,6 +55,12 @@ declare global {
|
|
|
87
55
|
uncheckCheckbox(index?: number): Chainable<Element>;
|
|
88
56
|
uncheckSwitch(index?: number): Chainable<Element>;
|
|
89
57
|
moveSlider(value: number, index?: number): Chainable<Element>;
|
|
58
|
+
moveSliderByName(name: string, value: number): Chainable<Element>;
|
|
59
|
+
selectRadioByName(name: string, value: string): Chainable<Element>;
|
|
60
|
+
checkCheckboxInGroupByName(name: string, index?: number): Chainable<Element>;
|
|
61
|
+
selectAutocompleteByName(name: string, optionValue: string): Chainable<Element>;
|
|
62
|
+
fillDateInputByName(name: string): Chainable<Element>;
|
|
63
|
+
selectFileByName(name: string, filePath: string): Chainable<Element>;
|
|
90
64
|
|
|
91
65
|
// Validation & Error Testing Helpers
|
|
92
66
|
expectValidationError(message: string): Chainable<Element>;
|
|
@@ -104,14 +78,15 @@ declare global {
|
|
|
104
78
|
// Form Submission Helpers
|
|
105
79
|
submitForm(): Chainable<Element>;
|
|
106
80
|
submitAndExpectSuccess(successIndicator?: string): Chainable<Element>;
|
|
107
|
-
submitAndExpectErrors(): Chainable<Element>;
|
|
81
|
+
submitAndExpectErrors(errorMessage?: string, formIndex?: number): Chainable<Element>;
|
|
108
82
|
resetForm(): Chainable<Element>;
|
|
109
83
|
interceptFormSubmission(method: string, url: string, alias: string): Chainable<Element>;
|
|
110
84
|
|
|
111
85
|
// Form State Helpers
|
|
112
86
|
verifyFormExists(): Chainable<Element>;
|
|
113
87
|
verifyFieldExists(selector: string): Chainable<Element>;
|
|
114
|
-
|
|
88
|
+
verifyFieldValueByName(name: string, value: string): Chainable<Element>;
|
|
89
|
+
verifyFieldValue(type: string, value: string, index?: number): Chainable<Element>;
|
|
115
90
|
verifyFieldCount(selector: string, count: number): Chainable<Element>;
|
|
116
91
|
getFormData(): Chainable<FormFieldData>;
|
|
117
92
|
|
|
@@ -132,10 +107,26 @@ declare global {
|
|
|
132
107
|
|
|
133
108
|
// Debug commands
|
|
134
109
|
logFormState(): Chainable<Element>;
|
|
135
|
-
waitForFormReady(): Chainable<
|
|
110
|
+
waitForFormReady(timeout?: number): Chainable<JQuery<HTMLElement>>;
|
|
136
111
|
clearForm(): Chainable<Element>;
|
|
137
112
|
verifyFormValid(): Chainable<Element>;
|
|
138
113
|
screenshotForm(name?: string): Chainable<Element>;
|
|
114
|
+
|
|
115
|
+
// Utility Helpers (for better form testing)
|
|
116
|
+
waitForReactUpdate(timeout?: number): Chainable<void>;
|
|
117
|
+
waitForElementState(selector: string, state: 'visible' | 'hidden' | 'enabled' | 'disabled' | 'exist', timeout?: number): Chainable<JQuery<HTMLElement>>;
|
|
118
|
+
waitForDropdownOpen(timeout?: number): Chainable<JQuery<HTMLElement>>;
|
|
119
|
+
waitForDropdownClose(buttonSelector?: string, timeout?: number): Chainable<JQuery<HTMLElement>>;
|
|
120
|
+
getFormDataValue(fieldName: string): Chainable<string | File | null>;
|
|
121
|
+
verifyFormDataValue(fieldName: string, expectedValue: string | number, timeout?: number): Chainable<void>;
|
|
122
|
+
waitForValidation(shouldHaveErrors?: boolean, timeout?: number): Chainable<void>;
|
|
123
|
+
getFormDataArray(fieldName: string): Chainable<string[]>;
|
|
124
|
+
verifyFormDataArray(fieldName: string, expectedValues: string[], exactMatch?: boolean): Chainable<void>;
|
|
125
|
+
verifyFormDataFieldExists(fieldName: string): Chainable<void>;
|
|
126
|
+
verifyNameAttribute(fieldName: string, selector?: string): Chainable<void>;
|
|
127
|
+
verifyFormDataStructure(expectedData: Record<string, string | number | string[]>): Chainable<void>;
|
|
128
|
+
verifyFormCleared(fieldNames: string[]): Chainable<void>;
|
|
129
|
+
verifyDropdownNameAttribute(fieldName: string, labelText?: string): Chainable<void>;
|
|
139
130
|
}
|
|
140
131
|
}
|
|
141
132
|
}
|