diff --git a/src/shared/components/BlockEditor/SlashMenu.client.js b/src/shared/components/BlockEditor/SlashMenu.client.js index 98e2ae8..9add27a 100644 --- a/src/shared/components/BlockEditor/SlashMenu.client.js +++ b/src/shared/components/BlockEditor/SlashMenu.client.js @@ -66,7 +66,7 @@ export default function SlashMenu({ }, [allowed, query]); const listRef = useRef(null); - const [position, setPosition] = useState({ top: 0, left: 0, maxHeight: MENU_MAX_HEIGHT }); + const [position, setPosition] = useState({ top: 0, bottom: null, left: 0, maxHeight: MENU_MAX_HEIGHT }); // Scroll l'élément sélectionné dans la vue (interne au menu uniquement) useEffect(() => { @@ -76,6 +76,9 @@ export default function SlashMenu({ // Positionnement adaptatif : flip au-dessus si pas assez de place en bas, // clamp horizontalement, et limite la hauteur à l'espace disponible. + // Quand on est en mode « au-dessus », on ancre via `bottom` plutôt que + // `top` — sinon, quand le contenu rétrécit (filtrage par query), le bas + // de la boîte décolle du champ et flotte en l'air. useLayoutEffect(() => { if (!anchorRect || typeof window === 'undefined') return; const vh = window.innerHeight; @@ -83,14 +86,15 @@ export default function SlashMenu({ const spaceBelow = vh - anchorRect.bottom - VIEWPORT_MARGIN; const spaceAbove = anchorRect.top - VIEWPORT_MARGIN; - let top; + let top = null; + let bottom = null; let maxHeight; if (spaceBelow >= Math.min(MENU_MAX_HEIGHT, 200) || spaceBelow >= spaceAbove) { top = anchorRect.bottom + 6; maxHeight = Math.max(120, Math.min(MENU_MAX_HEIGHT, spaceBelow - 6)); } else { + bottom = vh - anchorRect.top + 6; maxHeight = Math.max(120, Math.min(MENU_MAX_HEIGHT, spaceAbove - 6)); - top = anchorRect.top - 6 - maxHeight; } let left = anchorRect.left; @@ -99,18 +103,21 @@ export default function SlashMenu({ } if (left < VIEWPORT_MARGIN) left = VIEWPORT_MARGIN; - setPosition({ top, left, maxHeight }); - }, [anchorRect, items.length]); + setPosition({ top, bottom, left, maxHeight }); + }, [anchorRect]); if (!anchorRect) return null; - const { top, left, maxHeight } = position; + const { top, bottom, left, maxHeight } = position; + const positionStyle = bottom != null + ? { bottom, left, width: MENU_WIDTH, maxHeight } + : { top, left, width: MENU_WIDTH, maxHeight }; if (items.length === 0) { return (
Aucune commande pour « {query} »
@@ -122,7 +129,7 @@ export default function SlashMenu({ ref={listRef} data-slash-menu className="fixed z-50 overflow-y-auto rounded-lg border border-neutral-200 dark:border-neutral-700 bg-white dark:bg-neutral-900 shadow-md py-1" - style={{ top, left, width: MENU_WIDTH, maxHeight }} + style={positionStyle} onMouseDown={(e) => e.preventDefault()} // ne pas voler le focus >