diff --git a/.changeset/evil-webs-create.md b/.changeset/evil-webs-create.md
new file mode 100644
index 0000000000..0ed36a703a
--- /dev/null
+++ b/.changeset/evil-webs-create.md
@@ -0,0 +1,5 @@
+---
+'@backstage/ui': patch
+---
+
+Fix scroll jumping when opening menu in Backstage UI.
diff --git a/packages/ui/src/components/Menu/Menu.stories.tsx b/packages/ui/src/components/Menu/Menu.stories.tsx
index a9a45402d1..7171b3ef83 100644
--- a/packages/ui/src/components/Menu/Menu.stories.tsx
+++ b/packages/ui/src/components/Menu/Menu.stories.tsx
@@ -412,3 +412,38 @@ export const VirtualizedMaxHeight: Story = {
);
},
};
+
+export const WithScroll: Story = {
+ args: {
+ children: null,
+ },
+ decorators: [
+ Story => (
+
+
+
+ ),
+ ],
+ render: () => (
+
+
+
+
+ ),
+};
diff --git a/packages/ui/src/components/Menu/Menu.tsx b/packages/ui/src/components/Menu/Menu.tsx
index 574a26393c..696fb7997e 100644
--- a/packages/ui/src/components/Menu/Menu.tsx
+++ b/packages/ui/src/components/Menu/Menu.tsx
@@ -33,6 +33,7 @@ import {
RouterProvider,
Virtualizer,
ListLayout,
+ OverlayTriggerStateContext,
} from 'react-aria-components';
import { useStyles } from '../../hooks/useStyles';
import type {
@@ -54,6 +55,7 @@ import {
} from '@remixicon/react';
import { useNavigate, useHref } from 'react-router-dom';
import { isExternalLink } from '../../utils/isExternalLink';
+import { useRef, useEffect, useContext } from 'react';
// The height will be used for virtualized menus. It should match the size set in CSS for each menu item.
const rowHeight = 32;
@@ -86,6 +88,33 @@ export const Menu = (props: MenuProps