Repository navigation
fix: register inline content spec extensions and mount their content correctly - #3251
Conversation
Once the editor has mounted, TipTap renders a React node view synchronously, before it creates the contentDOM, so the contentRef call can't mount it. TipTap then mounts it into a [data-node-view-content] element or, failing that, into the node view's root. Inline content specs didn't set that attribute (block specs do since TypeCellOS#1954), so the content ended up outside the element the spec rendered for it, e.g. the source of inline math showed next to its preview after an undo, until the next re-render.
createReactInlineContentSpec accepts extensions and keeps them on the spec, but ExtensionManager only collected them from block specs, so they were silently dropped. This left the math-block inline input rules ($...$ and \(...\)) unregistered.
|
@RovshanMuradov is attempting to deploy a commit to the TypeCell Team on Vercel. A member of the Team first needs to authorize it. |
|
Important Review skippedReview was skipped due to path filters ⛔ Files ignored due to path filters: 1
CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including
|
| Layer / File(s) | Summary |
|---|---|
Add extension support to style specs packages/core/src/schema/styles/*, packages/react/src/schema/ReactStyleSpec.tsx, packages/core/src/schema/inlineContent/types.ts |
Style spec types and creation functions accept optional extensions and include them in the returned spec. The built-in text and link inline-content types now derive their fields from InlineContentSpec. |
Register extensions from specs packages/core/src/editor/managers/ExtensionManager/index.ts, packages/core/src/editor/managers/ExtensionManager/ExtensionManager.node.test.ts |
ExtensionManager registers extensions declared by block, inline-content, and style specs. Tests mount editors to check extension and plugin registration, replacement, removal, state retention, and ordering. |
Mark React inline-content target packages/react/src/schema/ReactInlineContentSpec.tsx, packages/react/src/schema/ReactInlineContentSpec.browser.test.tsx |
The content element receives data-node-view-content in addition to data-editable. Browser tests cover plain and styled inline content during insertion and undo. |
Priority:
Estimated code review effort: 3 (Moderate) | ~20 minutes
Change: Bug fix
Sequence Diagram(s)
sequenceDiagram
participant Editor
participant ExtensionManager
participant SpecCollections
participant ProseMirrorState
Editor->>ExtensionManager: Construct manager
ExtensionManager->>SpecCollections: Read block, inline-content, and style specs
ExtensionManager->>ProseMirrorState: Register spec-declared extensions and plugins
Possibly related PRs
- TypeCellOS/BlockNote#3236: Both changes modify extension registration and plugin behavior in ExtensionManager.
- TypeCellOS/BlockNote#3252: Both changes set
data-node-view-contentfor React inline content.
Suggested reviewers: nperez0111
Merge Risk: 
Minimal · up to 78d1f
-
No actionable merge-blocking issue is established; the change appears ready for normal checks.
Pre-merge checks: 
4 · 
1
-
Failed checks: 1 warning Passed checks: 4 passed-
Full details: Description check
-
Explanation
The description explains the bugs, causes, fixes, testing, and impact in sufficient detail. It omits explicit Rationale, Changes, Impact, and Additional Notes headings, and the checklist conflicts with the reported test results because existing tests are marked unchecked.
-
-
Finishing Touches: 💡 1
-
🛠️ Fix failing CI checks: 💡
-
- Commit to this branch
- Create a new PR
🧪 Generate unit tests (beta)
-
- Create a new PR
-
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
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.
A rabbit hops past specs in flight
Style extensions join the write
Inline content finds its place
Marked for React’s node-view space
Tests remount and check the flow
Then undo brings text aglow
Comment @coderabbitai help to get the list of available commands.
@blocknote/ariakit
@blocknote/code-block
@blocknote/core
@blocknote/diagram-block
@blocknote/mantine
@blocknote/math-block
@blocknote/react
@blocknote/server-util
@blocknote/shadcn
@blocknote/xl-ai
@blocknote/xl-docx-exporter
@blocknote/xl-email-exporter
@blocknote/xl-multi-column
@blocknote/xl-odt-exporter
@blocknote/xl-pdf-exporter
@blocknote/xl-typst-exporter
commit: |
|
@nperez0111 sorry for some reason my push failed, I had tests localy. But overall it looks good to go now |
|
No worries, this is a great catch @RovshanMuradov thanks for submitting a PR for this. I also added support for style specs to provide extensions too which is a shortcoming of the API |
|
@nperez0111 createStyleSpec now takes extensions, but vanilla createInlineContentSpec doesn't. Intentional, or should I add it? |
thanks, I'm working on my project and I want to make sure math works smoothly. I will create couple PR's later too. I had other fixes on my project but I always forget to contribute |
Not intentional, that'd be good to add too! |
I'd be happy to take more fixes for math @RovshanMuradov |
done #3253 |
Summary
This PR fixes two bugs in React inline content specs, one commit each. Both show up on inline math from
@blocknote/math-block:$x^2$or\(x^2\)never turns into a formula.The follow-up commits also let style specs declare
extensions, and register the extensions of block, inline content and style specs in one loop.1. Formulas typed with
$...$don't renderCause:
createReactInlineContentSpecacceptsextensions, butExtensionManageronly registers extensions from block specs. SoMathInlineInputRulesExtensionnever runs.Fix:
ExtensionManageralso registers extensions frominlineContentSpecs, through the sameaddExtensionpath as block specs. Key de-duplication anddisableExtensionsapply, so apps that already pass the extension to the editor are unaffected.2. Raw source shows next to the formula
Repro on
main: in the math example, delete a paragraph with inline math, then undo.e^{i\pi} + 1 = 0shows beside the formula.Cause: inline content inserted after the editor mounts renders before TipTap creates its
contentDOM. TipTap then mounts the content into a[data-node-view-content]element, or the node view root if there is none. Block specs set this attribute (#1954); inline content specs don't.Fix:
createReactInlineContentSpecsetsdata-node-view-contenton the content element, ascreateReactBlockSpecdoes.Fix 1 makes this bug reachable by just typing, so both land together.
Testing
/custom-schema/math-blockand confirmed both fixed on this branch.ExtensionManager.node.test.tscovers registering extensions from block, inline content and style specs.ReactInlineContentSpec.browser.test.tsxchecks thatplainandstyledinline content mounts inside itscontentRefafter insertion and after undo.@blocknote/core(1418) and@blocknote/react(21) unit tests pass; the browser test passes in Chromium and Firefox.Screenshots/Video
The video shows both bugs on
mainfirst, then the same steps on this branch.screenrecording-2026-10-24_08-13-48.mp4
Checklist
Summary by CodeRabbit