@@ -97,6 +97,26 @@ const resolveToolbar = (
9797 } ;
9898} ;
9999
100+ const MENU_VIEWPORT_PADDING = 10 ;
101+ const MENU_APPROX_WIDTH = 250 ;
102+ const MENU_APPROX_HEIGHT = 300 ;
103+
104+ const clampToViewport = ( rect : DOMRect ) : DOMRect => {
105+ const maxLeft = window . innerWidth - MENU_APPROX_WIDTH - MENU_VIEWPORT_PADDING ;
106+ const maxTop =
107+ window . innerHeight - MENU_APPROX_HEIGHT - MENU_VIEWPORT_PADDING ;
108+
109+ const clampedLeft = Math . min ( rect . left , maxLeft ) ;
110+ const clampedTop = Math . min ( rect . top , maxTop ) ;
111+
112+ return new DOMRect (
113+ Math . max ( clampedLeft , MENU_VIEWPORT_PADDING ) ,
114+ Math . max ( clampedTop , MENU_VIEWPORT_PADDING ) ,
115+ rect . width ,
116+ rect . height ,
117+ ) ;
118+ } ;
119+
100120const SuperDocTemplateBuilder = forwardRef <
101121 Types . SuperDocTemplateBuilderHandle ,
102122 Types . SuperDocTemplateBuilderProps
@@ -385,7 +405,9 @@ const SuperDocTemplateBuilder = forwardRef<
385405
386406 if ( text === trigger ) {
387407 const coords = e . view . coordsAtPos ( from ) ;
388- const bounds = new DOMRect ( coords . left , coords . top , 0 , 0 ) ;
408+ const bounds = clampToViewport (
409+ new DOMRect ( coords . left , coords . top , 0 , 0 ) ,
410+ ) ;
389411
390412 const cleanup = ( ) => {
391413 const editor = superdocRef . current ?. activeEditor ;
@@ -435,7 +457,9 @@ const SuperDocTemplateBuilder = forwardRef<
435457 updateMenuFilter ( queryText ) ;
436458
437459 const coords = e . view . coordsAtPos ( from ) ;
438- const bounds = new DOMRect ( coords . left , coords . top , 0 , 0 ) ;
460+ const bounds = clampToViewport (
461+ new DOMRect ( coords . left , coords . top , 0 , 0 ) ,
462+ ) ;
439463 setMenuPosition ( bounds ) ;
440464 } ) ;
441465
0 commit comments