Skip to content

fix: enable React Compiler for slate/ directory#2403

Open
christianhg wants to merge 2 commits intomainfrom
fix/react-compiler-slate
Open

fix: enable React Compiler for slate/ directory#2403
christianhg wants to merge 2 commits intomainfrom
fix/react-compiler-slate

Conversation

@christianhg
Copy link
Member

The React Compiler has been enabled for the editor package but the entire slate/ directory was excluded via a sources filter in package.config.ts. PR #2387 removed the biggest blocker (all WeakMap-based DOM mapping), so the remaining violations are smaller and more mechanical.

This PR fixes the remaining React Compiler violations in slate/ and removes the exclusion filter, bringing the vendored Slate layer under compiler optimization.

The critical fixes are render-time mutations of the editor singleton (editor.isNodeMapDirty, editor.readOnly, editor.forceRender) that have been moved into useIsomorphicLayoutEffect. The state.hasMarkPlaceholder field, which was mutated on a useMemo'd object during render, is now computed as a local variable and synced to a ref via a layout effect for the DOM selection sync to read.

The useDecorationsByChild helper in use-children.tsx used a ref-as-memoization-cache pattern that mutated useRef().current during render. This has been replaced with a useMemo that compares against a previous-value ref updated only in layout effects.

Three hooks use 'use no memo' as an escape hatch: useGenericSelector (the selector system core, same ref-during-render pattern as react-redux's useSelector), useDecorations (intentionally creates a new selector closure every render), and TextString (layout effect with no deps that must run on every render to sync DOM text content). useIsMounted was rewritten from a ref-read-during-render pattern to useState.

@changeset-bot
Copy link

changeset-bot bot commented Mar 20, 2026

🦋 Changeset detected

Latest commit: d136d23

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

This PR includes changesets to release 11 packages
Name Type
@portabletext/editor Patch
@portabletext/plugin-character-pair-decorator Patch
@portabletext/plugin-emoji-picker Patch
@portabletext/plugin-input-rule Patch
@portabletext/plugin-markdown-shortcuts Patch
@portabletext/plugin-one-line Patch
@portabletext/plugin-paste-link Patch
@portabletext/plugin-sdk-value Patch
@portabletext/plugin-typeahead-picker Patch
@portabletext/plugin-typography Patch
@portabletext/toolbar 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

@vercel
Copy link

vercel bot commented Mar 20, 2026

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

Project Deployment Actions Updated (UTC)
portable-text-editor-documentation Ready Ready Preview, Comment Mar 20, 2026 2:09pm
portable-text-example-basic Ready Ready Preview, Comment Mar 20, 2026 2:09pm
portable-text-playground Ready Ready Preview, Comment Mar 20, 2026 2:09pm

Request Review

@github-actions
Copy link
Contributor

github-actions bot commented Mar 20, 2026

📦 Bundle Stats — @portabletext/editor

Compared against main (055bdb16)

@portabletext/editor

Metric Value vs main (055bdb1)
Internal (raw) 763.1 KB +8.1 KB, +1.1%
Internal (gzip) 144.2 KB +2.2 KB, +1.6%
Bundled (raw) 1.37 MB +8.1 KB, +0.6%
Bundled (gzip) 307.0 KB +2.2 KB, +0.7%
Import time 99ms +1ms, +0.8%

@portabletext/editor/behaviors

Metric Value vs main (055bdb1)
Internal (raw) 467 B -
Internal (gzip) 207 B -
Bundled (raw) 424 B -
Bundled (gzip) 171 B -
Import time 6ms -0ms, -0.8%

@portabletext/editor/plugins

Metric Value vs main (055bdb1)
Internal (raw) 2.5 KB -
Internal (gzip) 910 B -
Bundled (raw) 2.3 KB -
Bundled (gzip) 839 B -
Import time 12ms -0ms, -0.6%

@portabletext/editor/selectors

Metric Value vs main (055bdb1)
Internal (raw) 60.2 KB -
Internal (gzip) 9.4 KB -
Bundled (raw) 56.7 KB -
Bundled (gzip) 8.6 KB -
Import time 10ms +0ms, +0.3%

@portabletext/editor/utils

Metric Value vs main (055bdb1)
Internal (raw) 24.2 KB -
Internal (gzip) 4.7 KB -
Bundled (raw) 22.2 KB -
Bundled (gzip) 4.4 KB -
Import time 9ms +0ms, +0.7%

🗺️ . · ./behaviors · ./plugins · ./selectors · ./utils · Artifacts

Details
  • Import time regressions over 10% are flagged with ⚠️
  • Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.

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