From b4e07737773052decad05b278a04015255f16965 Mon Sep 17 00:00:00 2001 From: Matthew Lipski Date: Thu, 4 Dec 2025 18:03:34 +0100 Subject: [PATCH 1/2] Fixed suggestion menu positioning --- .../SuggestionMenuController.tsx | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/packages/react/src/components/SuggestionMenu/SuggestionMenuController.tsx b/packages/react/src/components/SuggestionMenu/SuggestionMenuController.tsx index 151bbea5f7..6aa7e130b6 100644 --- a/packages/react/src/components/SuggestionMenu/SuggestionMenuController.tsx +++ b/packages/react/src/components/SuggestionMenu/SuggestionMenuController.tsx @@ -5,7 +5,7 @@ import { } from "@blocknote/core/extensions"; import { UseFloatingOptions, - flip, + autoPlacement, offset, shift, size, @@ -127,18 +127,22 @@ export function SuggestionMenuController< offset(10), // Flips the menu placement to maximize the space available, and prevents // the menu from being cut off by the confines of the screen. - flip({ - mainAxis: true, - crossAxis: false, + autoPlacement({ + allowedPlacements: ["bottom-start", "top-start"], + padding: 10, }), shift(), size({ - apply({ availableHeight, elements }) { - Object.assign(elements.floating.style, { - maxHeight: `${availableHeight - 10}px`, - minHeight: "300px", - }); + apply(p) { + // Because the height of the suggestion menu is dynamic and based + // on the number of items, the `flip` middleware gets confused + // when the height is set on the initial render. Therefore, it's + // set right after instead. + setTimeout(() => { + p.elements.floating.style.maxHeight = `${p.availableHeight}px`; + }, 10); }, + padding: 10, }), ], }, From e2d8ffd414045ce4a267fc58f8fd8cc9671c0339 Mon Sep 17 00:00:00 2001 From: Matthew Lipski Date: Thu, 4 Dec 2025 18:12:15 +0100 Subject: [PATCH 2/2] Added same changes to `GridSuggestionMenuController` --- .../GridSuggestionMenuController.tsx | 21 ++++++++++++------- .../SuggestionMenuController.tsx | 6 +++--- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/packages/react/src/components/SuggestionMenu/GridSuggestionMenu/GridSuggestionMenuController.tsx b/packages/react/src/components/SuggestionMenu/GridSuggestionMenu/GridSuggestionMenuController.tsx index d6e87bf8e4..f25b62e8d2 100644 --- a/packages/react/src/components/SuggestionMenu/GridSuggestionMenu/GridSuggestionMenuController.tsx +++ b/packages/react/src/components/SuggestionMenu/GridSuggestionMenu/GridSuggestionMenuController.tsx @@ -1,6 +1,6 @@ import { BlockSchema, InlineContentSchema, StyleSchema } from "@blocknote/core"; import { SuggestionMenu } from "@blocknote/core/extensions"; -import { flip, offset, shift, size } from "@floating-ui/react"; +import { autoPlacement, offset, shift, size } from "@floating-ui/react"; import { FC, useEffect, useMemo } from "react"; import { useBlockNoteEditor } from "../../../hooks/useBlockNoteEditor.js"; @@ -126,17 +126,22 @@ export function GridSuggestionMenuController< offset(10), // Flips the menu placement to maximize the space available, and prevents // the menu from being cut off by the confines of the screen. - flip({ - mainAxis: true, - crossAxis: false, + autoPlacement({ + allowedPlacements: ["bottom-start", "top-start"], + padding: 10, }), shift(), size({ - apply({ availableHeight, elements }) { - Object.assign(elements.floating.style, { - maxHeight: `${availableHeight - 10}px`, - }); + apply(p) { + // Because the height of the suggestion menu is dynamic and based + // on the number of items, the `autoPlacement` middleware gets + // confused when the height is set on the initial render. + // Therefore, it's set right after instead. + setTimeout(() => { + p.elements.floating.style.maxHeight = `${p.availableHeight}px`; + }, 10); }, + padding: 10, }), ], }, diff --git a/packages/react/src/components/SuggestionMenu/SuggestionMenuController.tsx b/packages/react/src/components/SuggestionMenu/SuggestionMenuController.tsx index 6aa7e130b6..5960dc010c 100644 --- a/packages/react/src/components/SuggestionMenu/SuggestionMenuController.tsx +++ b/packages/react/src/components/SuggestionMenu/SuggestionMenuController.tsx @@ -135,9 +135,9 @@ export function SuggestionMenuController< size({ apply(p) { // Because the height of the suggestion menu is dynamic and based - // on the number of items, the `flip` middleware gets confused - // when the height is set on the initial render. Therefore, it's - // set right after instead. + // on the number of items, the `autoPlacement` middleware gets + // confused when the height is set on the initial render. + // Therefore, it's set right after instead. setTimeout(() => { p.elements.floating.style.maxHeight = `${p.availableHeight}px`; }, 10);