Upgrade blocknote dependencies from 0.31.1 to 0.47.0.#18207
Upgrade blocknote dependencies from 0.31.1 to 0.47.0.#18207FelixMalfait merged 12 commits intomainfrom
Conversation
…e ESM-only transitive dependency in CJS context
There was a problem hiding this comment.
2 issues found across 27 files
Prompt for AI agents (all issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="packages/twenty-front/src/modules/blocknote-editor/utils/getFirstNonEmptyLineOfRichText.ts">
<violation number="1" location="packages/twenty-front/src/modules/blocknote-editor/utils/getFirstNonEmptyLineOfRichText.ts:20">
P2: Link inline content is now ignored, so a line that only contains a link returns an empty string. Handle BlockNote’s `link` inline content by extracting its text (or href) instead of skipping it.</violation>
</file>
<file name="packages/twenty-front/src/modules/blocknote-editor/components/BlockEditorDropdownFocusEffect.tsx">
<violation number="1" location="packages/twenty-front/src/modules/blocknote-editor/components/BlockEditorDropdownFocusEffect.tsx:51">
P2: Avoid calling setState or triggering side effects during render. Move this logic into a useEffect that runs when isSlashMenuShowing changes to prevent render-time updates and potential loops.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
packages/twenty-front/src/modules/blocknote-editor/utils/getFirstNonEmptyLineOfRichText.ts
Outdated
Show resolved
Hide resolved
| ); | ||
|
|
||
| editor.suggestionMenus.on('update /', updateCallBack); | ||
| if (prevShowing !== isSlashMenuShowing) { |
There was a problem hiding this comment.
P2: Avoid calling setState or triggering side effects during render. Move this logic into a useEffect that runs when isSlashMenuShowing changes to prevent render-time updates and potential loops.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/twenty-front/src/modules/blocknote-editor/components/BlockEditorDropdownFocusEffect.tsx, line 51:
<comment>Avoid calling setState or triggering side effects during render. Move this logic into a useEffect that runs when isSlashMenuShowing changes to prevent render-time updates and potential loops.</comment>
<file context>
@@ -60,7 +48,10 @@ export const BlockEditorDropdownFocusEffect = ({
);
- editor.suggestionMenus.on('update /', updateCallBack);
+ if (prevShowing !== isSlashMenuShowing) {
+ setPrevShowing(isSlashMenuShowing);
+ syncSlashMenuState(isSlashMenuShowing);
</file context>
There was a problem hiding this comment.
BlockNote 0.47.0 replaced the event-based editor.suggestionMenus.on() API with useExtensionState(SuggestionMenu), a React-reactive hook — there is no event to subscribe to anymore. To synchronize this value with our Jotai store, we use React's documented pattern for adjusting state during render: a useState guard that compares the previous value and only syncs when it changes. This technically calls setState during render, but React explicitly supports this — it retries the render with updated state, and the guard prevents infinite loops. The store.set() calls are also safe, as Jotai batches updates without triggering synchronous re-renders.
There was a problem hiding this comment.
Thanks for the feedback! I've saved this as a new learning to improve future reviews.
Greptile SummaryThis PR successfully upgrades BlockNote from 0.31.1 to 0.47.0, migrating the codebase to the new extension API and leveraging built-in components to reduce custom code. Major Changes:
Critical Issue:
Confidence Score: 3/5
Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[BlockNote 0.31.1] --> B[BlockNote 0.47.0]
B --> C[New Extension API]
B --> D[Built-in Controllers]
B --> E[Mantine v8]
C --> C1[SuggestionMenu Extension]
C --> C2[useExtensionState Hook]
C1 --> F1[BlockEditorDropdownFocusEffect]
C1 --> F2[CustomAddBlockItem]
C2 --> F1
D --> D1[FormattingToolbarController]
D --> D2[SideMenuController]
D --> D3[DragHandleButton/Menu]
D1 --> G1[DashboardFormattingToolbar]
D2 --> G2[DashboardEditorSideMenu]
D3 --> G2
E --> H1[Added @mantine/core 8.3.11]
E --> H2[Added @mantine/hooks 8.3.11]
I[Server-Side] --> J[ESM/CJS Compatibility]
J --> K[Native import for ESM modules]
K --> L[transform-rich-text-v2.util]
M[UI Updates] --> N[New Block Types]
N --> N1[Heading 4-6]
N --> N2[Toggle List]
N --> N3[Divider]
N1 --> O[Added IconH4/H5/H6]
P[Dead Code Removal] --> P1[DashboardBlockDragHandleMenu]
P --> P2[DashboardBlockColorPicker]
P --> P3[FloatingConfig Files]
Last reviewed commit: c067bd8 |
| if (prevShowing !== isSlashMenuShowing) { | ||
| setPrevShowing(isSlashMenuShowing); | ||
| syncSlashMenuState(isSlashMenuShowing); | ||
| } |
There was a problem hiding this comment.
calling setState during render creates a React anti-pattern. This will trigger unnecessary re-renders and could cause infinite loops.
| if (prevShowing !== isSlashMenuShowing) { | |
| setPrevShowing(isSlashMenuShowing); | |
| syncSlashMenuState(isSlashMenuShowing); | |
| } | |
| useEffect(() => { | |
| syncSlashMenuState(isSlashMenuShowing); | |
| }, [isSlashMenuShowing, syncSlashMenuState]); |
There was a problem hiding this comment.
Replied to Cubic with reasoning.
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
|
Warning Review the following alerts detected in dependencies. According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.
|
...ules/page-layout/widgets/standalone-rich-text/components/StandaloneRichTextEditorContent.tsx
Show resolved
Hide resolved
There was a problem hiding this comment.
1 issue found across 2 files (changes from recent commits).
Prompt for AI agents (all issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="packages/twenty-front/src/modules/blocknote-editor/utils/getFirstNonEmptyLineOfRichText.ts">
<violation number="1">
P2: Guard against non-array `block.content` values before treating it as an array; the previous Array.isArray check was removed, so unexpected shapes will now cause runtime errors when reading `length` or iterating.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
|
Hey @mabdullahabaid! After you've done the QA of your Pull Request, you can mark it as done here. Thank you! |
https://sonarly.com/issue/14499?type=bug BlockNote 0.31.1's Enter key handler throws an unhandled `TransformError: Cannot join blockGroup onto blockContainer` when splitting blocks in rich text fields containing table blocks, crashing the editor. Fix: No code changes needed. The bug is in BlockNote 0.31.1's internal Enter key handler (`Ou` function), which calls `Transaction.split(pos, 2)` and produces an invalid `ReplaceStep` when table blocks are present in the document. This is a third-party library bug. The fix was already merged by Abdullah (@mabdullahabaid) in commit `4ed09a3feb` ("Upgrade blocknote dependencies from 0.31.1 to 0.47.0", PR #18207, Feb 27 2026). This upgrade brings in 16 minor versions of BlockNote fixes including improvements to block splitting, table handling, and the Enter key handler. The bug persists in production only because v1.18.1 (released Feb 20) predates the upgrade. Deploying the next release will resolve this issue for all users.
This PR pgrades all BlockNote packages (@blocknote/core, @blocknote/react, @blocknote/mantine, @blocknote/server-util, @blocknote/xl-docx-exporter, @blocknote/xl-pdf-exporter) to 0.47.0 and adapts the codebase to the new API.
Changes