diff --git a/.changeset/fast-pots-say.md b/.changeset/fast-pots-say.md new file mode 100644 index 00000000000..3b4a1f51029 --- /dev/null +++ b/.changeset/fast-pots-say.md @@ -0,0 +1,5 @@ +--- +'@primer/react': patch +--- + +ActionMenu: Ensures that uncontrolled ActionMenu(s) retain tab-focus when fullscreen diff --git a/packages/react/src/ActionMenu/ActionMenu.tsx b/packages/react/src/ActionMenu/ActionMenu.tsx index 7ed22316759..7e97ae4d673 100644 --- a/packages/react/src/ActionMenu/ActionMenu.tsx +++ b/packages/react/src/ActionMenu/ActionMenu.tsx @@ -285,12 +285,25 @@ const Overlay: FCWithSlotMarker> = ({ } = React.useContext(MenuContext) as MandateProps const containerRef = React.useRef(null) - useMenuKeyboardNavigation(open, onClose, containerRef, anchorRef, isSubmenu) const isNarrow = useResponsiveValue({narrow: true}, false) - const responsiveVariant = useResponsiveValue(variant, {regular: 'anchored', narrow: 'anchored'}) const isNarrowFullscreen = !!isNarrow && variant.narrow === 'fullscreen' + const handleClose: MenuCloseHandler = React.useCallback( + gesture => { + // In narrow fullscreen mode, don't close on tab, let focus stay in the menu + if (isNarrowFullscreen && gesture === 'tab') { + return + } + onClose?.(gesture) + }, + [isNarrowFullscreen, onClose], + ) + + useMenuKeyboardNavigation(open, handleClose, containerRef, anchorRef, isSubmenu) + + const responsiveVariant = useResponsiveValue(variant, {regular: 'anchored', narrow: 'anchored'}) + // If the menu anchor is an icon button, we need to label the menu by tooltip that also labelled the anchor. const [anchorAriaLabelledby, setAnchorAriaLabelledby] = useState(null) useEffect(() => { @@ -311,7 +324,7 @@ const Overlay: FCWithSlotMarker> = ({ anchorId={anchorId} open={open} onOpen={onOpen} - onClose={onClose} + onClose={handleClose} align={align} side={side ?? (isSubmenu ? 'outside-right' : 'outside-bottom')} overlayProps={overlayProps}