From 6f4e20b2850deaaf8436e9608ca62a77f3717886 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Gr=C3=A9lard?= Date: Wed, 6 Mar 2024 13:36:43 +0000 Subject: [PATCH] [DropdownMenu] Prevent scroll on initial menu focus Fixes #2331 --- .yarn/versions/2ab74363.yml | 13 +++++++++++++ packages/react/menu/src/Menu.tsx | 3 ++- .../react/roving-focus/src/RovingFocusGroup.tsx | 8 +++++--- 3 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 .yarn/versions/2ab74363.yml diff --git a/.yarn/versions/2ab74363.yml b/.yarn/versions/2ab74363.yml new file mode 100644 index 0000000000..c3dd303621 --- /dev/null +++ b/.yarn/versions/2ab74363.yml @@ -0,0 +1,13 @@ +releases: + "@radix-ui/react-context-menu": patch + "@radix-ui/react-dropdown-menu": patch + "@radix-ui/react-menu": patch + "@radix-ui/react-menubar": patch + "@radix-ui/react-radio-group": patch + "@radix-ui/react-roving-focus": patch + "@radix-ui/react-tabs": patch + "@radix-ui/react-toggle-group": patch + "@radix-ui/react-toolbar": patch + +declined: + - primitives diff --git a/packages/react/menu/src/Menu.tsx b/packages/react/menu/src/Menu.tsx index d92913113c..a184c6f5b3 100644 --- a/packages/react/menu/src/Menu.tsx +++ b/packages/react/menu/src/Menu.tsx @@ -468,7 +468,7 @@ const MenuContentImpl = React.forwardRef @@ -493,6 +493,7 @@ const MenuContentImpl = React.forwardRef void; onEntryFocus?: (event: Event) => void; + preventScrollOnEntryFocus?: boolean; } const RovingFocusGroupImpl = React.forwardRef< @@ -107,6 +108,7 @@ const RovingFocusGroupImpl = React.forwardRef< defaultCurrentTabStopId, onCurrentTabStopIdChange, onEntryFocus, + preventScrollOnEntryFocus = false, ...groupProps } = props; const ref = React.useRef(null); @@ -180,7 +182,7 @@ const RovingFocusGroupImpl = React.forwardRef< Boolean ) as typeof items; const candidateNodes = candidateItems.map((item) => item.ref.current!); - focusFirst(candidateNodes); + focusFirst(candidateNodes, preventScrollOnEntryFocus); } } @@ -314,12 +316,12 @@ function getFocusIntent(event: React.KeyboardEvent, orientation?: Orientation, d return MAP_KEY_TO_FOCUS_INTENT[key]; } -function focusFirst(candidates: HTMLElement[]) { +function focusFirst(candidates: HTMLElement[], preventScroll = false) { const PREVIOUSLY_FOCUSED_ELEMENT = document.activeElement; for (const candidate of candidates) { // if focus is already where we want to go, we don't want to keep going through the candidates if (candidate === PREVIOUSLY_FOCUSED_ELEMENT) return; - candidate.focus(); + candidate.focus({ preventScroll }); if (document.activeElement !== PREVIOUSLY_FOCUSED_ELEMENT) return; } }