Skip to content

Version Packages - #2649

Merged
stipsan merged 1 commit into
mainfrom
changeset-release/main
Aug 10, 2026
Merged

Version Packages#2649
stipsan merged 1 commit into
mainfrom
changeset-release/main

Conversation

@squiggler-app

@squiggler-app squiggler-app Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

This PR was opened by the Changesets release GitHub action. When you're ready to do a release, you can merge this and the packages will be published to npm automatically. If you're not ready to do a release yet, that's fine, whenever you add more changesets to main, this PR will be updated.

Releases

@sanity/[email protected]

Major Changes

  • #2505 6069d4e Thanks @stipsan! - @sanity/ui 4.0. The full upgrade procedure is in the migration guide. TypeScript walks you through most of it: every removed or moved API stays in the types as a @deprecated tombstone whose message names its replacement.

    ESM-only. Node.js 22.12+ required.

    • The CommonJS build (.cjs / .d.cts) and the require export condition are removed — the package now ships ESM only.
    • Node.js below 22.12 is no longer supported (engines is now >=22.12, matching sanity).
    • TypeScript needs an exports-aware moduleResolution (node16, nodenext, or bundler): v4 resolves everything through package exports and no longer ships typesVersions, so the legacy node (node10) mode cannot resolve the subpath entry points' types.
    • What to do: run Node.js 22.12 or later — that's it. Modern Node supports require(esm), so require('@sanity/ui') keeps working; things only break if the Node.js version is too old.

    React 19.2+ required.

    • Peer dependency ranges are tightened to react: ^19.2 and react-dom: ^19.2. The 19.2 floor is set by the new <Activity> component, which shipped in React 19.2.0 and which v4 uses to keep closed Tooltip and Popover content mounted.
    • Components are compiled with the React Compiler targeting '19', which uses React's built-in runtime — the react-compiler-runtime dependency is dropped.
    • What to do: upgrade react and react-dom to 19.2 or later. No code changes needed.

    New required import: @sanity/ui/styles.css.

    Static styles (the ones that don't depend on theme or props) are now extracted into a stylesheet at build time instead of being injected at runtime. The stylesheet is not loaded automatically — add this import once, next to where the app renders <ThemeProvider>:

    import "@sanity/ui/styles.css";

    Without it, SrOnly, Spinner and internal text-overflow styling render unstyled. These components have moved off styled-components — more components follow in future 4.x minors, and UI5 ships without styled-components or any other runtime CSS-in-JS.

    Heavy components moved out of the root entry point.

    Importing @sanity/ui no longer pulls in @floating-ui/react-dom, motion or react-refractor — even without bundler treeshaking. What moved where:

    • @sanity/ui/toastToast, ToastProvider, useToast (motion)
    • @sanity/ui/popoverPopover (@floating-ui/react-dom, motion)
    • @sanity/ui/tooltipTooltip, TooltipDelayGroupProvider, useTooltipDelayGroup (@floating-ui/react-dom, motion)
    • @sanity/ui/menuMenu, MenuButton, MenuDivider, MenuGroup, MenuItem (renders Popover)
    • @sanity/ui/autocompleteAutocomplete (renders Popover)
    • @sanity/ui/breadcrumbsBreadcrumbs (renders Popover)
    • @sanity/ui/codeCode (lazy-loads react-refractor)

    Prop, context and message types moved along with their components (PopoverProps, ToastParams, MenuItemProps, AutocompleteState, TooltipDelayGroupContextValue, …). Update the imports:

    -import {MenuButton, ToastProvider, useToast} from '@sanity/ui'
    +import {MenuButton} from '@sanity/ui/menu'
    +import {ToastProvider, useToast} from '@sanity/ui/toast'

    Also part of this change: ErrorBoundary renders a plain <pre><code> instead of the Code primitive, keeping the root entry free of the react-refractor module graph.

    Deprecated props, hooks, and components are removed.

    Removed props stay on the public types as @deprecated never, so you get the migration message instead of a bare "does not exist" error. The removed hooks and ConditionalWrapper are still exported but throw when called. What to replace:

    • spacegap
    • Grid columns / rows / column* / row*gridTemplateColumns / gridTemplateRows / gridColumn* / gridRow*
    • Menu focusFirst / focusLastshouldFocus
    • MenuButton top-level popover props → popover={{…}}
    • Popover boundaryElementfloatingBoundary / referenceBoundary (and BoundaryElementProvider for max-width / constrainSize)
    • Tooltip allowedAutoPlacementsfallbackPlacements
    • useClickOutsideuseClickOutsideEvent
    • useElementRectuseElementSize
    • useForwardedRefuseRef + useImperativeHandle
    • useArrayProp(value)Array.isArray(value) ? value : [value]
    • ConditionalWrapper → inline the conditional wrapping logic

    The private @sanity/ui/_visual-editing entry point is removed.

    Import from @sanity/ui instead — except the moved components (Menu, MenuDivider, MenuGroup, MenuItem, Popover), which now live on @sanity/ui/menu and @sanity/ui/popover. The slim subset is no longer needed: displayName side effects are gone, so unused components tree-shake out of consuming bundles.

    The @juggle/resize-observer polyfill is removed — the native ResizeObserver is used directly.

    The internal _ResizeObserver export is gone. If you imported it, use the global ResizeObserver instead.

    Tooltip and Popover keep closed content mounted with React's <Activity>.

    • Internal state is preserved and hidden content pre-renders while closed.
    • With animate enabled, hiding is deferred until exit animations finish (via AnimateActivity, vendored from Motion).
    • Watch out: popovers with recursive content must gate the recursion on open — otherwise they render an infinitely deep hidden tree.

    All components are plain function components — ref is a regular prop (React 19 semantics).

    Refs keep working exactly as before. The one observable change: components no longer pass react-is checks such as isForwardRef.

@sanity/[email protected]

Patch Changes


Note

Medium Risk
Publishing @sanity/ui 4.0.0 is a major semver jump with wide breaking API and runtime requirements for all consumers; the PR itself is low-risk metadata, but merging triggers npm publication of that major.

Overview
This is an automated Version Packages release — no application code changes in the diff, only version bumps, changelogs, and removal of the consumed .changeset/ui-4.md entry.

@sanity/ui 4.0.0 is published with the full 4.0 migration notes now recorded in packages/ui/CHANGELOG.md: ESM-only and Node 22.12+, React 19.2+, required import "@sanity/ui/styles.css", heavy APIs moved to subpaths (@sanity/ui/menu, /toast, /popover, etc.), removed deprecated props/hooks and @sanity/ui/_visual-editing, Tooltip/Popover behavior via React <Activity>, and related breaking changes (see MIGRATION.md).

@sanity/themer 0.3.2 is a patch release that only reflects the updated @sanity/[email protected] workspace dependency in its changelog.

Reviewed by Cursor Bugbot for commit 27ad24c. Bugbot is set up for automated code reviews on this repo. Configure here.

@vercel

vercel Bot commented Aug 10, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
icons Ready Ready Preview Aug 10, 2026 10:00am
sanity-ui-storybook Ready Ready Preview Aug 10, 2026 10:00am
ui-docs Ready Ready Preview Aug 10, 2026 10:00am
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
sanity-ui-workshop Ignored Ignored Aug 10, 2026 10:00am

Request Review

@stipsan
stipsan merged commit f3bab23 into main Aug 10, 2026
15 checks passed
@stipsan
stipsan deleted the changeset-release/main branch August 10, 2026 10:04
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