Skip to content

fix nuxt useForm#21

Merged
cobraprojects merged 2 commits into
mainfrom
fix-nuxt-useForm
May 5, 2026
Merged

fix nuxt useForm#21
cobraprojects merged 2 commits into
mainfrom
fix-nuxt-useForm

Conversation

@cobraprojects
Copy link
Copy Markdown
Owner

@cobraprojects cobraprojects commented May 5, 2026

Summary by CodeRabbit

  • Bug Fixes

    • Unified input binding so displayed form values are sourced consistently across frameworks.
  • Documentation

    • Updated client and server examples to reflect the unified value-binding approach and clarified blur-time validation behavior.
  • Refactor

    • Reworked form state syncing to improve reliability of displayed values, arrays, and mutation tracking.
  • Tests

    • Added and updated tests to verify reactive value bridging, array mutations, and blur-validation behavior.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 5, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: aed7ff3b-d467-4c71-87ad-5664865b9fca

📥 Commits

Reviewing files that changed from the base of the PR and between 62635b0 and e97af6f.

📒 Files selected for processing (5)
  • apps/blog-nuxt/pages/reset-password.vue
  • apps/docs/docs/forms/client-usage.md
  • apps/docs/docs/forms/server-validation.md
  • packages/adapter-nuxt/src/runtime/composables/forms.ts
  • packages/adapter-nuxt/tests/client.test.ts
🚧 Files skipped from review as they are similar to previous changes (4)
  • apps/blog-nuxt/pages/reset-password.vue
  • apps/docs/docs/forms/client-usage.md
  • apps/docs/docs/forms/server-validation.md
  • packages/adapter-nuxt/src/runtime/composables/forms.ts

📝 Walkthrough

Walkthrough

Form display bindings were migrated from form.fields.<name>.value to form.values.<name> across Next.js, Nuxt, and SvelteKit apps; the Nuxt adapter was reimplemented to expose a reactive values bridge; client error update behavior was made path-targeted; docs and tests updated accordingly.

Changes

Form Value Migration and Reactive Bridge

Layer / File(s) Summary
Client shape / error handling
packages/forms/src/client.ts
Added replaceErrorsForPath() and updated field set(...) to replace flattened errors only for the edited field when validateOn === 'change'.
Nuxt adapter core
packages/adapter-nuxt/src/runtime/composables/forms.ts
Replaced proxy-based view with an explicit rawValues + syncValuesView approach; added isLeafValue, getValueAtPath, defineLeafAccessor, createArrayMutationView and a versioned reactive wrapper delegating form methods.
Vue typings
packages/adapter-nuxt/src/vue-shim.d.ts
Exported reactive<TValue extends object>(target: TValue): TValue in the vue module typings.
Nuxt adapter tests and mocks
packages/adapter-nuxt/tests/client.test.ts
Added reactive stub to mocked vue, adjusted date/array assertions, and added tests asserting Vue-reactive usage and array mutation routing through setValue.
App pages — value bindings
apps/blog-next/app/.../page.tsx, apps/blog-nuxt/pages/*.vue, apps/blog-sveltekit/src/routes/*/+page.svelte
Replaced input/checkbox bindings from form.fields.<field>.value/bind:value/bind:checked with form.values.<field> and wired explicit onInput/onChange/onBlur to form.fields.* handlers where applicable; hidden token inputs also switched to form.values.token.
Docs — client usage & server validation
apps/docs/docs/forms/client-usage.md, apps/docs/docs/forms/server-validation.md
Updated framework examples to use form.values.* for displayed values, clarified validateOn: 'blur' behavior, and documented the distinction between form.values.* (display) and form.fields.* (lifecycle/touched handlers).
Form tests
packages/forms/tests/client.test.ts
Extended blur-validation tests to assert untouched field errors remain hidden during blur validation; added related assertions.

Sequence Diagram(s)

sequenceDiagram
    participant UI as Client UI
    participant Adapter as Nuxt Adapter (values bridge)
    participant Form as Form Instance
    participant Vue as Vue reactive runtime

    UI->>Adapter: read `form.values.field` (render)
    Note right of Adapter: Adapter getters read latest form.values via versioned bridge
    UI->>Adapter: onInput -> call `form.fields.field.onInput(value)`
    Adapter->>Form: `form.value.setValue(path, value)`
    Form->>Form: update internal state & run validations/subscribers
    Form->>Adapter: notify subscriber (new values)
    Adapter->>Vue: update `rawValues` and bump version (reactive)
    Vue->>UI: reactive update triggers re-render showing updated `form.values.field`
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Poem

🐰
I hop from field to field, so spry,
.fields...value waved goodbye.
Now .values.* leads the race,
A reactive bridge sets the pace.
Hooray — forms hop in better place!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix nuxt useForm' accurately reflects the primary change across the PR: updating the Nuxt form composable and all form pages to use form.values instead of form.fields.value for input bindings.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix-nuxt-useForm

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
apps/blog-nuxt/pages/reset-password.vue (1)

26-26: 💤 Low value

Use :value instead of v-model for the hidden token input.

<input type="hidden"> never fires input events, so the update half of v-model is a no-op. The SvelteKit equivalent correctly uses a one-way value={form.values.token} binding. Prefer :value="form.values.token" here for semantic accuracy.

♻️ Proposed fix
-      <input name="token" type="hidden" v-model="form.values.token">
+      <input name="token" type="hidden" :value="form.values.token">
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/blog-nuxt/pages/reset-password.vue` at line 26, Replace the two-way
binding on the hidden token input with a one-way value binding: change the input
that currently uses v-model="form.values.token" to use
:value="form.values.token" so the hidden input reflects the token without
relying on input events; locate the input element referencing form.values.token
and update it accordingly, and remove any now-unused assumptions about v-model
updating this field elsewhere (keep using form.values.token as the source of
truth).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/docs/docs/forms/client-usage.md`:
- Around line 211-213: The note incorrectly states that
form.fields.email.onBlur() is the touched-state bridge; update the wording to
clarify that onBlur() is the blur-validation hook used when validateOn: 'blur',
while touched state can also be set during input/value updates (e.g., via
form.values.email changes and form.fields.email.onInput), and apply the same
rewording to the corresponding note in server-validation.md so both files
consistently distinguish blur-triggered validation from general touched-state
transitions.

In `@packages/adapter-nuxt/src/runtime/composables/forms.ts`:
- Around line 33-38: Arrays are incorrectly treated as leaf values by
isLeafValue, so mutating methods on form.values arrays bypass the accessor
setter and never call setValue; update isLeafValue to not return true for arrays
and modify the accessor logic that exposes form.values (the bridge
getter/setter) to wrap returned arrays in a mutation-trapping proxy that
intercepts mutating methods (push, pop, splice, shift, unshift, sort, reverse,
fill, copyWithin) and calls the existing setValue/form client update path so
touched/dirty/validation/subscribers run; add a unit test that calls
form.values.tags.push(...) and asserts touched, dirty and validation state
update.

---

Nitpick comments:
In `@apps/blog-nuxt/pages/reset-password.vue`:
- Line 26: Replace the two-way binding on the hidden token input with a one-way
value binding: change the input that currently uses v-model="form.values.token"
to use :value="form.values.token" so the hidden input reflects the token without
relying on input events; locate the input element referencing form.values.token
and update it accordingly, and remove any now-unused assumptions about v-model
updating this field elsewhere (keep using form.values.token as the source of
truth).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2efcced5-5c73-4eb9-85c0-5e9ae7d551be

📥 Commits

Reviewing files that changed from the base of the PR and between e4180bd and 62635b0.

📒 Files selected for processing (22)
  • apps/blog-next/app/forgot-password/page.tsx
  • apps/blog-next/app/login/page.tsx
  • apps/blog-next/app/register/page.tsx
  • apps/blog-next/app/reset-password/page.tsx
  • apps/blog-next/app/verify-email/page.tsx
  • apps/blog-nuxt/pages/forgot-password.vue
  • apps/blog-nuxt/pages/login.vue
  • apps/blog-nuxt/pages/register.vue
  • apps/blog-nuxt/pages/reset-password.vue
  • apps/blog-nuxt/pages/verify-email.vue
  • apps/blog-sveltekit/src/routes/forgot-password/+page.svelte
  • apps/blog-sveltekit/src/routes/login/+page.svelte
  • apps/blog-sveltekit/src/routes/register/+page.svelte
  • apps/blog-sveltekit/src/routes/reset-password/+page.svelte
  • apps/blog-sveltekit/src/routes/verify-email/+page.svelte
  • apps/docs/docs/forms/client-usage.md
  • apps/docs/docs/forms/server-validation.md
  • packages/adapter-nuxt/src/runtime/composables/forms.ts
  • packages/adapter-nuxt/src/vue-shim.d.ts
  • packages/adapter-nuxt/tests/client.test.ts
  • packages/forms/src/client.ts
  • packages/forms/tests/client.test.ts

Comment thread apps/docs/docs/forms/client-usage.md Outdated
Comment thread packages/adapter-nuxt/src/runtime/composables/forms.ts
@cobraprojects
Copy link
Copy Markdown
Owner Author

@CodeRabbit review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 5, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@cobraprojects cobraprojects merged commit 1dabed6 into main May 5, 2026
1 check passed
@cobraprojects cobraprojects deleted the fix-nuxt-useForm branch May 5, 2026 17:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant