Skip to content

fix: useEditorDOMElement hook#2619

Open
matthewlipski wants to merge 5 commits intomainfrom
rerender-on-mount
Open

fix: useEditorDOMElement hook#2619
matthewlipski wants to merge 5 commits intomainfrom
rerender-on-mount

Conversation

@matthewlipski
Copy link
Copy Markdown
Collaborator

@matthewlipski matthewlipski commented Apr 2, 2026

Summary

This PR adds a useEditorDOMElement hook which fetches the editor DOM element. It's necessary for certain cases where components rely on editor.domElement to be defined to attach event listeners. However, when it becomes defined, there is nothing which explicitly triggers a re-render, so the hook is needed to force that re-render.

Closes #2546

Rationale

See above.

Changes

  • Added useEditorDOMElement hook.
  • Replaced direct references to editor.domElement with the hook where necessary.

Impact

N/A

Testing

I wasn't able to reproduce the issue in #2546 locally, and have not seen other cases of this elsewhere. Therefore, no tests have been added.

Screenshots/Video

N/A

Checklist

  • Code follows the project's coding standards.
  • Unit tests covering the new feature have been added.
  • All existing tests pass.
  • The documentation has been updated to reflect the new feature

Additional Notes

Summary by CodeRabbit

  • New Features
    • Added useEditorDOMElement() hook to expose the editor's DOM element to React components.
    • Several UI components updated to use the new hook for event wiring and popover/keyboard positioning.
    • onMount() and onUnmount() now return the unsubscribe/removal token provided by the event system for easier listener cleanup.

@vercel
Copy link
Copy Markdown

vercel bot commented Apr 2, 2026

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

Project Deployment Actions Updated (UTC)
blocknote Ready Ready Preview Apr 20, 2026 1:53pm
blocknote-website Ready Ready Preview Apr 20, 2026 1:53pm

Request Review

@matthewlipski matthewlipski requested a review from nperez0111 April 2, 2026 12:23
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 2, 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: f502baf5-9b92-4bd3-88ed-ebff0f0c5ab2

📥 Commits

Reviewing files that changed from the base of the PR and between c20d1c1 and 88c14d4.

📒 Files selected for processing (2)
  • packages/react/src/components/SuggestionMenu/GridSuggestionMenu/hooks/useGridSuggestionMenuKeyboardNavigation.ts
  • packages/react/src/hooks/useEditorDomElement.ts
✅ Files skipped from review due to trivial changes (1)
  • packages/react/src/components/SuggestionMenu/GridSuggestionMenu/hooks/useGridSuggestionMenuKeyboardNavigation.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/react/src/hooks/useEditorDomElement.ts

📝 Walkthrough

Walkthrough

This PR adds a new React hook useEditorDOMElement() that tracks the editor DOM element and updates components to use it instead of editor.domElement. It also changes BlockNoteEditor.onMount / onUnmount to return the values produced by the internal event manager.

Changes

Cohort / File(s) Summary
Core Editor Return Values
packages/core/src/editor/BlockNoteEditor.ts
onMount and onUnmount now return the value from this._eventManager.onMount(...) / onUnmount(...) instead of returning void.
New Editor DOM Element Hook
packages/react/src/hooks/useEditorDomElement.ts, packages/react/src/index.ts
Added exported useEditorDOMElement(editor?) hook that resolves the editor instance, listens for TipTap "create" for headless editors, and returns a reactive editor.domElement value; re-exported from package index.
Link & Formatting Toolbar
packages/react/src/components/LinkToolbar/LinkToolbarController.tsx, packages/react/src/components/FormattingToolbar/DefaultButtons/CreateLinkButton.tsx
Switched DOM access to useEditorDOMElement() and updated effect dependency arrays to depend on the resolved editorDOMElement.
Floating UI / Popovers & Suggestion Menus
packages/react/src/components/Popovers/PositionPopover.tsx, packages/react/src/components/SuggestionMenu/.../GridSuggestionMenuController.tsx, packages/react/src/components/SuggestionMenu/SuggestionMenuController.tsx
FloatingUI reference/context elements now use editorDOMElement (e.g., .firstChild) via the new hook; useMemo/deps updated accordingly.
Keyboard Navigation Hooks
packages/react/src/components/SuggestionMenu/.../useGridSuggestionMenuKeyboardNavigation.ts, packages/react/src/components/SuggestionMenu/hooks/useSuggestionMenuKeyboardNavigation.ts
Keyboard event listeners now target editorDOMElement from the hook; one hook parameter renamed to _editor to indicate it's unused.

Sequence Diagram

sequenceDiagram
    participant Component as React Component
    participant Hook as useEditorDOMElement()
    participant Editor as BlockNoteEditor
    participant TipTap as TipTap Editor
    participant State as useEditorState()
    
    Component->>Hook: call useEditorDOMElement(editor?)
    Hook->>Editor: resolve editor (param or context)
    alt headless / TipTap not yet created
        Hook->>TipTap: register "create" on editor._tiptapEditor
        TipTap-->>Hook: emits "create"
        Hook->>Hook: set mounted/initialized state
    end
    Hook->>State: select ctx.editor?.domElement (reference equality)
    State-->>Hook: provides editorDOMElement
    Hook-->>Component: returns editorDOMElement
    Component->>Component: attach/remove event listeners / build references using editorDOMElement
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • nperez0111

Poem

🐰 I hopped in code to find the place,
A DOM was missing from the race,
I listen for TipTap's gentle chime,
Now hover menus show on time! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.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
Title check ✅ Passed The title 'fix: useEditorDOMElement hook' accurately describes the primary change—a fix that introduces and utilizes the new useEditorDOMElement hook to resolve the link hover menu issue.
Description check ✅ Passed The PR description covers the template sections (Summary, Rationale, Changes, Impact, Testing) adequately. It clearly explains the hook's purpose, acknowledges the inability to reproduce the issue locally, and documents testing limitations.
Linked Issues check ✅ Passed The PR successfully addresses #2546 by introducing the useEditorDOMElement hook and replacing direct editor.domElement references with it, ensuring components trigger re-renders when the DOM element becomes available, which should resolve the link hover menu inconsistency.
Out of Scope Changes check ✅ Passed All changes are directly related to the linked issue #2546. The modifications to BlockNoteEditor.onMount/onUnmount return values enable proper cleanup of hook listeners, and updates to React components consistently apply the new useEditorDOMElement hook—no unrelated changes detected.

✏️ 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 rerender-on-mount

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.

Comment thread packages/react/src/editor/BlockNoteView.tsx
Copy link
Copy Markdown
Contributor

@nperez0111 nperez0111 left a comment

Choose a reason for hiding this comment

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

I'd prefer a different solution here, this is too much. Especially for an issue we can't reliably reproduce

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Apr 16, 2026

Open in StackBlitz

@blocknote/ariakit

npm i https://pkg.pr.new/@blocknote/ariakit@2619

@blocknote/code-block

npm i https://pkg.pr.new/@blocknote/code-block@2619

@blocknote/core

npm i https://pkg.pr.new/@blocknote/core@2619

@blocknote/mantine

npm i https://pkg.pr.new/@blocknote/mantine@2619

@blocknote/react

npm i https://pkg.pr.new/@blocknote/react@2619

@blocknote/server-util

npm i https://pkg.pr.new/@blocknote/server-util@2619

@blocknote/shadcn

npm i https://pkg.pr.new/@blocknote/shadcn@2619

@blocknote/xl-ai

npm i https://pkg.pr.new/@blocknote/xl-ai@2619

@blocknote/xl-docx-exporter

npm i https://pkg.pr.new/@blocknote/xl-docx-exporter@2619

@blocknote/xl-email-exporter

npm i https://pkg.pr.new/@blocknote/xl-email-exporter@2619

@blocknote/xl-multi-column

npm i https://pkg.pr.new/@blocknote/xl-multi-column@2619

@blocknote/xl-odt-exporter

npm i https://pkg.pr.new/@blocknote/xl-odt-exporter@2619

@blocknote/xl-pdf-exporter

npm i https://pkg.pr.new/@blocknote/xl-pdf-exporter@2619

commit: 88c14d4

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)
packages/react/src/components/SuggestionMenu/hooks/useSuggestionMenuKeyboardNavigation.ts (1)

9-9: Consider removing _editor from the signature if external consumers don't depend on it.

Since the hook is exported publicly and the parameter is unused, removal would be a breaking change. If this hook isn't consumed by external packages, dropping the argument would simplify the API and avoid confusion for maintainers.

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@packages/react/src/components/SuggestionMenu/GridSuggestionMenu/hooks/useGridSuggestionMenuKeyboardNavigation.ts`:
- Around line 8-15: The hook useGridSuggestionMenuKeyboardNavigation currently
accepts an explicit _editor argument but ignores it by always using
useEditorDOMElement() from context; update the implementation to pass the
explicit editor through to useEditorDOMElement (i.e., call
useEditorDOMElement(editor) or similar) and modify useEditorDOMElement to accept
an optional editorOverride parameter that falls back to useBlockNoteEditor when
not provided so keyboard listeners target the provided editor instance and
restore correct behavior for multi-editor/custom usage.

In `@packages/react/src/hooks/useEditorDomElement.ts`:
- Around line 24-33: The handler passed to editor._tiptapEditor.on("create")
uses setInitialized(true) which is idempotent and prevents re-renders after the
first create; change the effect to update state with a non-idempotent update
(e.g. flip a boolean or increment a counter) so each "create" event forces a
render. Update the useEffect in useEditorDomElement.ts around setInitialized and
the editor._tiptapEditor.on/off("create") handlers to call setInitialized(prev
=> !prev) or setInitialized(n => n + 1) instead of setInitialized(true) so
descendant consumers see a fresh editor.domElement on every create.
🪄 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: c1dc22a0-e78c-431f-8f52-e29b4f4e4561

📥 Commits

Reviewing files that changed from the base of the PR and between 58457e2 and c20d1c1.

📒 Files selected for processing (10)
  • packages/core/src/editor/BlockNoteEditor.ts
  • packages/react/src/components/FormattingToolbar/DefaultButtons/CreateLinkButton.tsx
  • packages/react/src/components/LinkToolbar/LinkToolbarController.tsx
  • packages/react/src/components/Popovers/PositionPopover.tsx
  • packages/react/src/components/SuggestionMenu/GridSuggestionMenu/GridSuggestionMenuController.tsx
  • packages/react/src/components/SuggestionMenu/GridSuggestionMenu/hooks/useGridSuggestionMenuKeyboardNavigation.ts
  • packages/react/src/components/SuggestionMenu/SuggestionMenuController.tsx
  • packages/react/src/components/SuggestionMenu/hooks/useSuggestionMenuKeyboardNavigation.ts
  • packages/react/src/hooks/useEditorDomElement.ts
  • packages/react/src/index.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/core/src/editor/BlockNoteEditor.ts

Comment thread packages/react/src/hooks/useEditorDomElement.ts Outdated
@matthewlipski matthewlipski changed the title fix: Editor re-render on mount fix: useEditorDOMElement hook Apr 17, 2026
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.

Link: no menu appears on hover

2 participants