Skip to content

feat(hooks): reactive values + keepDirtyValues for useForm - #80

Merged
colorpulse6 merged 2 commits into
mainfrom
feat/reactive-values
Jun 9, 2026
Merged

feat(hooks): reactive values + keepDirtyValues for useForm#80
colorpulse6 merged 2 commits into
mainfrom
feat/reactive-values

Conversation

@colorpulse6

Copy link
Copy Markdown
Owner

Roadmap item B / P1 — reactive external values, the one real parity gap the audit + feature-inventory research both flagged (RHF values prop + resetOptions; Formik enableReinitialize).

What

A reactive values option on useForm for forms backed by props/server data:

useForm({ values: serverData, keepDirtyValues: true });
  • When values's content changes (deep-compared, so a new-object/same-content render is a no-op), the form re-syncs. It also seeds the initial state (precedence over defaultValues).
  • keepDirtyValues: true preserves fields the user is mid-editing while untouched fields sync.

Why it's clean

el-form tracks dirty via a mutation-driven set, so writing values through setFormState doesn't disturb dirty tracking — keepDirtyValues is a per-path "which value wins" merge (setNestedValue, nested-path aware). No dirty-baseline reconciliation needed.

Caveats (documented in the changeset + migration guide)

  • values replaces the whole value object (provide the full shape; omitted keys drop) — matches RHF.
  • isDirty is measured against the original defaultValues, not the latest synced values (consistent with el-form's existing reset({values})).
  • Don't put File/Blob in reactive values — the deep-compare can't distinguish files, so a swap won't re-sync (a pre-existing deepEqual limitation; flagged for a future fix).

Verification

  • 7 runtime tests: initial-seed precedence, content-change resync, the deep-compare no-clobber guard, both keepDirtyValues branches, undefined→defined, and nested dirty-field preservation.
  • build + hooks (123) + tsd + components (26) + umbrella (6) green; lint clean.
  • Independent review: SOUND — adversarially probed no-loop / no-mount-resync / nested-merge / no-regression; the only latent issue (File in deepEqual) is pre-existing and documented.

Design: docs/superpowers/specs/2026-06-09-reactive-values-design.md. Minor changeset (additive). Deferred: full resetOptions surface (keepErrors/keepTouched/…) — YAGNI for v1.

🤖 Generated with Claude Code

colorpulse6 and others added 2 commits June 9, 2026 20:51
Forms backed by props/server data can now pass a reactive `values` option:
when its content changes (deep-compared, so a new-object/same-content render
is a no-op), the form re-syncs; it also seeds the initial state (precedence
over defaultValues). `keepDirtyValues: true` preserves the user's in-progress
edits while untouched fields sync (RHF `values`+`resetOptions:{keepDirtyValues}`
/ Formik `enableReinitialize`).

Dirty tracking is a mutation-driven set, so writing values via setFormState
doesn't disturb it — keepDirty is a per-path "which value wins" merge
(setNestedValue, nested-path aware). 7 runtime tests. Minor, additive.

Notes: `values` replaces the whole value object; isDirty is vs the original
defaultValues (not synced values); File/Blob in reactive values won't re-sync
(deep-compare can't distinguish files).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@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 9, 2026
@colorpulse6
colorpulse6 merged commit 305822c into main Jun 9, 2026
8 checks passed
@colorpulse6
colorpulse6 deleted the feat/reactive-values branch June 9, 2026 19:00
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