Skip to content

feat(deps): update react-hook-form to v8 beta and re-enable React Compiler - #1850

Closed
pedrobonamin wants to merge 2 commits into
mainfrom
cursor/react-hook-form-v8-1d31
Closed

feat(deps): update react-hook-form to v8 beta and re-enable React Compiler#1850
pedrobonamin wants to merge 2 commits into
mainfrom
cursor/react-hook-form-v8-1d31

Conversation

@pedrobonamin

@pedrobonamin pedrobonamin commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Summary

Self-contained alternative to #1841, based directly on main. Updates react-hook-form to 8.0.0-beta.3 for sanity-plugin-media only per the v7 → v8 migration guide and removes the temporary 'use no memo' compiler opt-out that #1840 shipped, so the plugin builds fully compiled again — without needing #1841's keepFieldsRef workaround at all.

The v8 beta lives in a named catalog (catalog:react-hook-form-v8); the default catalog stays on ^7.84.0, so sanity-plugin-dashboard-widget-vercel is untouched by this PR.

Why v8 makes the opt-out unnecessary

The bug behind #1840: DialogAssetEdit calls reset(generateDefaultValues(...)) in an effect (on mount and when the asset is updated elsewhere). v7's reset() empties react-hook-form's internal field registry and relies on the render-time register() calls re-running on the next render — which React Compiler memoizes away (keyed on the stable register reference). Fields stayed unregistered, so typing updated the DOM but never marked the form dirty, and Save stayed disabled. v8 has first-class React Compiler support: the compiled form works with a plain reset(). Verified both by an isolated repro harness compiled with babel-plugin-react-compiler (fails on v7, passes on v8) and in a real browser (video below).

Breaking changes audit

Checked every breaking change from the migration guide against the plugin:

Breaking change Impact here
register passes the input ref directly (not a partial ref object) None — the plugin spreads register() onto inputs / forwards ref as a prop; build + type-aware lint pass unchanged
useFieldArray: id renamed to key, keyName removed Not used
<Watch names> renamed to name Not used
watch(callback) subscription API removed Not used
setValue no longer updates useFieldArray fields Not applicable — the tags field uses Controller, not useFieldArray

So no source changes were required by the breaking changes themselves.

@hookform/resolvers peer dependency

No v8-compatible release exists yet (latest 5.7.1 declares react-hook-form: ^7.55.0; the beta/next dist-tags are old v1/v2-era lines). The resolver contract is unchanged and works with the beta (all resolver-based validation tests pass). Handled the same way as the Bynder plugin's React 19 peers:

  • allowed in this workspace via peerDependencyRules.allowedVersions with an explanatory comment
  • documented for consumers in a new "Peer dependency warnings" section in the plugin README.md (npm --legacy-peer-deps / pnpm peerDependencyRules.allowedVersions)

Also included

  • Remaining inline Footer/Header dialog components converted to plain JSX (DialogTagCreate, DialogTagEdit, DialogConfirm, DialogFolderCreate), matching what fix(media): enable Save when editing asset string fields #1840 already did for DialogAssetEdit. Inline components get a new identity whenever captured values change, remounting the footer subtree — including the Save button — on every form-state change. This also removes all the react/react-compiler lint suppressions that pattern required.

Notes

  • The named catalog pins the exact beta (8.0.0-beta.3) rather than a range, so consumers of the published plugin get a deterministic beta version.
  • The lockfile was edited surgically to avoid re-resolving unrelated floating tags (sanity@next); pnpm install --frozen-lockfile passes.

Test plan

  • pnpm --filter sanity-plugin-media exec vitest run — 205 tests pass
  • pnpm --filter sanity-plugin-dashboard-widget-vercel exec vitest run passes (still on v7)
  • pnpm format, pnpm lint (type-aware), pnpm knip, pnpm build, pnpm test run (1281 tests) all pass
  • pnpm peers check — no peer dependency issues
  • Verified installed versions: media resolves react-hook-form@8.0.0-beta.3, the Vercel dashboard widget resolves 7.84.0
  • Manual verification in dev/test-studio (pnpm dev, compiler on, no 'use no memo', plain reset()): typing enables Save; after an external API update resets the open form, typing re-enables Save and the edit persists — the exact scenario that broke v7 under the compiler:

v8_demo_save_works_after_external_reset.mp4

To show artifacts inline, enable in settings.

Open in Web Open in Cursor 

@vercel

vercel Bot commented Aug 6, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
plugins-studio Ready Ready Preview Aug 6, 2026 10:07am
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
plugins-e2e-test-studio Ignored Ignored Aug 6, 2026 10:07am

Request Review

@pedrobonamin pedrobonamin added the 🤖 bot label Aug 6, 2026 — with Cursor
@changeset-bot

changeset-bot Bot commented Aug 6, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 5ddb277

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
sanity-plugin-media Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@socket-security

socket-security Bot commented Aug 6, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addednpm/​react-hook-form@​8.0.0-beta.39910010096100

View full report

@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown

✅ E2E Tests

🟢 26 passedview full reportview run

Studio: https://plugins-e2e-test-studio-agw69p2e8.sanity.dev

Datasets: pr-1850-chromium-31091878968, pr-1850-firefox-31091878968

@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 32% 5505 / 17203
🔵 Statements 31.77% 5809 / 18282
🔵 Functions 27.77% 1425 / 5131
🔵 Branches 23.33% 2828 / 12118
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
plugins/sanity-plugin-media/src/components/DialogAssetEdit/Details.tsx 78.94% 84.37% 85.71% 87.5% 17, 19-20
plugins/sanity-plugin-media/src/components/DialogConfirm/index.tsx 7.14% 0% 0% 7.14% 16-77
plugins/sanity-plugin-media/src/components/DialogFolderCreate/index.tsx 5% 0% 0% 5.88% 26-101
plugins/sanity-plugin-media/src/components/DialogTagCreate/index.tsx 100% 100% 100% 100%
plugins/sanity-plugin-media/src/components/DialogTagEdit/index.tsx 78.04% 52% 90% 77.5% 69, 88, 101-106, 114-116, 123, 161
Generated in workflow #8792 for commit 5ddb277 by the Vitest Coverage Report Action

@cursor
cursor Bot force-pushed the cursor/react-hook-form-v8-1d31 branch from 193b322 to d2f2c63 Compare August 6, 2026 08:46
@cursor cursor Bot changed the title feat(deps): update react-hook-form to v8 beta with React Compiler support feat(deps): update react-hook-form to v8 beta and re-enable React Compiler Aug 6, 2026
@cursor
cursor Bot changed the base branch from cursor/media-react-compiler-fix-1d31 to main August 6, 2026 08:46
…piler

Bump the react-hook-form catalog entry to 8.0.0-beta.3 for
sanity-plugin-media and sanity-plugin-dashboard-widget-vercel. v8 adds
first-class React Compiler support, so the temporary 'use no memo'
opt-out in the media asset details form is removed and the plugin ships
fully compiled again.

None of the v8 breaking changes affect this codebase: no useFieldArray,
Watch component, watch(callback), or setValue on field arrays; the
register() input-ref change is transparent to prop-spreading consumers.

Also convert the remaining inline Footer/Header dialog components to
plain JSX, dropping the react/react-compiler lint suppressions that
pattern required.

@hookform/resolvers has no v8-compatible release yet (peers ^7.0.0); the
resolver contract is unchanged and works with the beta, so allow it via
peerDependencyRules.allowedVersions.
@cursor
cursor Bot force-pushed the cursor/react-hook-form-v8-1d31 branch from d2f2c63 to 7bd4791 Compare August 6, 2026 08:59
@pedrobonamin
pedrobonamin marked this pull request as ready for review August 6, 2026 09:07
@pedrobonamin
pedrobonamin requested a review from a team as a code owner August 6, 2026 09:07
@pedrobonamin
pedrobonamin requested review from Copilot and stipsan and removed request for a team August 6, 2026 09:07

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Updates the monorepo’s react-hook-form catalog entry to 8.0.0-beta.3 to restore compatibility with React Compiler output in affected plugins, and refactors remaining inline dialog subcomponents to avoid remount churn.

Changes:

  • Bump react-hook-form from ^7.84.08.0.0-beta.3 (catalog + lockfile) and allow @hookform/resolvers’ peer mismatch via peerDependencyRules.allowedVersions.
  • Remove the React Compiler opt-out ('use no memo') from DialogAssetEdit/Details.
  • Replace inline Footer/Header component definitions with plain JSX nodes passed to Dialog props.

Reviewed changes

Copilot reviewed 8 out of 9 changed files in this pull request and generated no comments.

Show a summary per file
File Description
pnpm-workspace.yaml Pins react-hook-form to 8.0.0-beta.3 and adds an allowed peer override for @hookform/resolvers.
pnpm-lock.yaml Updates lockfile resolution entries to match the new react-hook-form version.
plugins/sanity-plugin-media/src/components/DialogTagEdit/index.tsx Converts inline Footer component to a JSX node passed via footer.
plugins/sanity-plugin-media/src/components/DialogTagCreate/index.tsx Converts inline Footer component to a JSX node passed via footer.
plugins/sanity-plugin-media/src/components/DialogFolderCreate/index.tsx Converts inline Footer component to a JSX node passed via footer.
plugins/sanity-plugin-media/src/components/DialogConfirm/index.tsx Converts inline Footer/Header components to JSX nodes passed via footer/header.
plugins/sanity-plugin-media/src/components/DialogAssetEdit/Details.tsx Removes the React Compiler opt-out directive/comments.
.changeset/vercel-widget-react-hook-form-v8.md Adds a changeset for the Vercel dashboard widget dependency update.
.changeset/media-react-hook-form-v8.md Adds a changeset for the media plugin update + compiler re-enable.
Files not reviewed (1)
  • pnpm-lock.yaml: Generated file

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@stipsan stipsan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It looks like @hookform/resolvers doesn't allow v8 in its peer deps, so we have to document in the plugin how to handle peer dep errors (like we already do in bynder for react 19) before we can ship this.
Alternatively there might be a beta of @hookform/resolvers that we could use

Comment thread .changeset/vercel-widget-react-hook-form-v8.md Outdated
Comment thread pnpm-workspace.yaml
Comment on lines +176 to +178
# @hookform/resolvers has no react-hook-form v8 compatible release yet (peers ^7.0.0);
# the resolver contract is unchanged and it works with the v8 beta
'@hookform/resolvers>react-hook-form': '8.0.0-beta.3'

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

For this change to make sense we have to document the peer dep warning in the plugin README.md, similar to what bynder does regarding react 19 peer deps

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good point, given this will land into a warning in user land I think we should skip it until react-hook-form v8 is out of beta, which will probably land with the fix for the peer dep.

The fix is already in place, this was only to re enable the compiler, but this is not a hot path , this is in the edit dialog.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

there is not beta of @hookform/resolvers

…ent the peer warning

Address review feedback on the v8 upgrade:

- Move the react-hook-form v8 beta to a named catalog
  (catalog:react-hook-form-v8) so only sanity-plugin-media upgrades;
  sanity-plugin-dashboard-widget-vercel stays on the default catalog (v7)
  and its changeset is dropped.
- Document the @hookform/resolvers peer dependency warning (and how to
  allow it with npm/pnpm) in the plugin README, mirroring the Bynder
  plugin's React 19 section. No v8-compatible @hookform/resolvers release
  exists yet (latest 5.7.1 declares react-hook-form ^7.55.0).

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 10 changed files in this pull request and generated no new comments.

Files not reviewed (1)
  • pnpm-lock.yaml: Generated file
Suppressed comments (1)

plugins/sanity-plugin-media/README.md:65

  • The README states that @hookform/resolvers declares a peer dependency of react-hook-form ^7.55.0, but the actual peer range for the version used here (@hookform/resolvers@4.1.3) is ^7.0.0 (see pnpm-lock.yaml). This should be corrected so consumers aren’t misled about the peer conflict.
The plugin uses [`react-hook-form`](https://react-hook-form.com/) v8 together with [`@hookform/resolvers`](https://www.npmjs.com/package/@hookform/resolvers), which doesn't declare react-hook-form v8 in its peer dependencies yet (it declares `react-hook-form ^7.55.0`), even though the resolver contract is unchanged and works fine with v8. Until a v8-compatible release is published, tell your package manager to allow it:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants