diff --git a/static/app/utils/profiling/hooks/useKeyboardNavigation.tsx b/static/app/utils/profiling/hooks/useKeyboardNavigation.tsx index bf9ee30a808ef0..70b0e4f2892279 100644 --- a/static/app/utils/profiling/hooks/useKeyboardNavigation.tsx +++ b/static/app/utils/profiling/hooks/useKeyboardNavigation.tsx @@ -49,13 +49,32 @@ export function useKeyboardNavigation() { const {tabIndex, setTabIndex, onKeyDown} = useRovingTabIndex(items); + // There's no easy way to subscribe to the position of an element. + // Instead we just check if the menuRef is on screen each render. + // + // This assumes that the menuRef is positioned at (-9999, -9999) + // when it's first rendered. + const boundingRect = menuRef?.getBoundingClientRect(); + const offScreen = + !boundingRect || + (boundingRect.top < 0 && + boundingRect.bottom < 0 && + boundingRect.left < 0 && + boundingRect.right < 0); + useEffect(() => { - if (menuRef) { - if (tabIndex === null) { - menuRef.focus(); - } + // Make sure the menu is on screen before trying to focus it. + // Otherwise, it will scroll to the top of the page. This is + // because when the menuRef is first rendered, it is given a + // position at (-9999, -9999) while we try to determine its + // size so it can be properly position. + // + // This has the effect of waiting until the menuRef is correctly + // positioned before trying to focus. + if (menuRef && !offScreen && tabIndex === null) { + menuRef.focus(); } - }, [menuRef, tabIndex]); + }, [offScreen, menuRef, tabIndex]); function getMenuProps() { return {