From 1e052f25927667500e7c630ed9c17a9099ec440f Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Thu, 9 Oct 2025 19:26:36 +0000 Subject: [PATCH] Add viewport clamping to menu positioning Co-authored-by: caiopizzol --- src/index.tsx | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/index.tsx b/src/index.tsx index 197da12..5301516 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -97,6 +97,26 @@ const resolveToolbar = ( }; }; +const MENU_VIEWPORT_PADDING = 10; +const MENU_APPROX_WIDTH = 250; +const MENU_APPROX_HEIGHT = 300; + +const clampToViewport = (rect: DOMRect): DOMRect => { + const maxLeft = window.innerWidth - MENU_APPROX_WIDTH - MENU_VIEWPORT_PADDING; + const maxTop = + window.innerHeight - MENU_APPROX_HEIGHT - MENU_VIEWPORT_PADDING; + + const clampedLeft = Math.min(rect.left, maxLeft); + const clampedTop = Math.min(rect.top, maxTop); + + return new DOMRect( + Math.max(clampedLeft, MENU_VIEWPORT_PADDING), + Math.max(clampedTop, MENU_VIEWPORT_PADDING), + rect.width, + rect.height, + ); +}; + const SuperDocTemplateBuilder = forwardRef< Types.SuperDocTemplateBuilderHandle, Types.SuperDocTemplateBuilderProps @@ -385,7 +405,9 @@ const SuperDocTemplateBuilder = forwardRef< if (text === trigger) { const coords = e.view.coordsAtPos(from); - const bounds = new DOMRect(coords.left, coords.top, 0, 0); + const bounds = clampToViewport( + new DOMRect(coords.left, coords.top, 0, 0), + ); const cleanup = () => { const editor = superdocRef.current?.activeEditor; @@ -435,7 +457,9 @@ const SuperDocTemplateBuilder = forwardRef< updateMenuFilter(queryText); const coords = e.view.coordsAtPos(from); - const bounds = new DOMRect(coords.left, coords.top, 0, 0); + const bounds = clampToViewport( + new DOMRect(coords.left, coords.top, 0, 0), + ); setMenuPosition(bounds); });