Skip to content

feat(hooks): formState completeness + validation modes (isValidating, dirtyFields, onTouched, reValidateMode)#92

Merged
colorpulse6 merged 13 commits into
mainfrom
feat/formstate-validation-modes
Jun 13, 2026
Merged

feat(hooks): formState completeness + validation modes (isValidating, dirtyFields, onTouched, reValidateMode)#92
colorpulse6 merged 13 commits into
mainfrom
feat/formstate-validation-modes

Conversation

@colorpulse6

Copy link
Copy Markdown
Owner

RHF-parity polish for el-form-react-hooks — four additive, backward-compatible features. A form that uses none of them behaves exactly as before.

Features

Feature Behavior
formState.isValidating true while validation is in flight. onChange/onBlur wrap only their async pass (validateFieldAsync); submit/handleSubmit/trigger() wrap the whole validation pass. Counter-based (pendingValidationsRef + runValidating), reset by reset().
reactive formState.dirtyFields Flat path-keyed Partial<Record<string, boolean>> (e.g. { "profile.name": true }) — the reactive twin of getDirtyFields(). Written in lockstep with isDirty via a single dirtyState.statePatch() helper that replaces the ad-hoc isDirty: size>0 writes, so the two can never drift.
mode: "onTouched" Validate a field on its first blur, then on every change once touched.
opt-in reValidateMode "onChange" | "onBlur" | "onSubmit". Once the form has been submitted, pins post-submit re-validation to the chosen event. Default undefined = unchanged. validateOn overrides it.

shouldValidate precedence (final): validateOn > onSubmit > reValidateMode (when submitted) > smart-validation (with the onTouched gate) > mode.

Notes

  • Built on top of the async-validation-dispatch fix (fix(hooks): async validators now actually run #90); the branch was rebased onto it and the isValidating task rewritten to wrap the new async methods rather than the sync pass (which would flicker the flag on every keystroke).
  • Final whole-branch review caught one integration bug: the external-values overwrite sync cleared isDirty but left the new reactive dirtyFields stale — the one write site not routed through statePatch(). Fixed (6cdd5c2) with a regression test.

Testing

  • 154/154 hooks tests pass (new: formstate-completeness, isValidating, onTouched, reValidateMode, + strengthened valuesSync). All TDD, each new test verified to fail without its implementation.
  • Lint clean · build:packages success (new fields confirmed in dist/index.d.ts) · docs build passes.
  • Docs updated (form-state, use-form, llms.txt/llms-full.txt, changelog) and accuracy-reviewed against source.
  • Changeset: el-form-react-hooks minor.

🤖 Generated with Claude Code

colorpulse6 and others added 13 commits June 13, 2026 08:38
isValidating + reactive dirtyFields on formState, plus mode:'onTouched' and
opt-in reValidateMode. el-form-consistent MVP (flat dirtyFields, form-level
isValidating boolean). Bundles the two smallest RHF-parity items.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
7 TDD tasks: additive fields+defaults, reactive dirtyFields, isValidating
counter, mode:onTouched, reValidateMode, docs+changeset, verification.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…reset)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Final-review fix: the values-prop overwrite sync (keepDirtyValues:false) cleared
the dirty Set + isDirty but left formState.dirtyFields stale, the one write site
not routed through statePatch(). Route it through statePatch() so dirtyFields
clears in lockstep with isDirty; lock in with a valuesSync assertion. Also refine
the runValidating comment (submit/trigger wrap the whole pass) and document that
validateOn overrides reValidateMode.
@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@github-actions github-actions Bot added the ready to publish This PR contains a Changeset and is ready to be published. label Jun 13, 2026
@colorpulse6
colorpulse6 merged commit 2bcd9ad into main Jun 13, 2026
8 checks passed
@colorpulse6
colorpulse6 deleted the feat/formstate-validation-modes branch June 13, 2026 08:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready to publish This PR contains a Changeset and is ready to be published.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant