@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 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
@@ -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
- verifyFieldValue(selector: string, value: string): Chainable<Element>;
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<Element>;
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
  }