diff --git a/packages/react/src/floating-ui-react/components/FloatingFocusManager.test.tsx b/packages/react/src/floating-ui-react/components/FloatingFocusManager.test.tsx index 9708e2e0249..d923e7ec5ad 100644 --- a/packages/react/src/floating-ui-react/components/FloatingFocusManager.test.tsx +++ b/packages/react/src/floating-ui-react/components/FloatingFocusManager.test.tsx @@ -1921,7 +1921,7 @@ describe('FloatingFocusManager', () => { expect(screen.getByTestId('reference')).not.toHaveFocus(); }); - test('uses aria-hidden instead of inert on outside nodes if opened with hover and modal=true', async () => { + test('uses both aria-hidden and inert on outside nodes if opened with hover and modal=true', async () => { function App() { const [isOpen, setIsOpen] = React.useState(false); @@ -1952,7 +1952,7 @@ describe('FloatingFocusManager', () => { await userEvent.hover(screen.getByTestId('reference')); await flushMicrotasks(); - expect(screen.getByText('outside')).not.toHaveAttribute('inert'); + expect(screen.getByText('outside')).toHaveAttribute('inert'); expect(screen.getByText('outside')).toHaveAttribute('aria-hidden', 'true'); }); diff --git a/packages/react/src/floating-ui-react/components/FloatingFocusManager.tsx b/packages/react/src/floating-ui-react/components/FloatingFocusManager.tsx index 82ea513270c..415d528589e 100644 --- a/packages/react/src/floating-ui-react/components/FloatingFocusManager.tsx +++ b/packages/react/src/floating-ui-react/components/FloatingFocusManager.tsx @@ -629,12 +629,18 @@ export function FloatingFocusManager(props: FloatingFocusManagerProps): React.JS mark: false, }); + const inertCleanup = markOthers(insideElements, { + inert: modal && !isUntrappedTypeableCombobox, + mark: false, + }); + const markerInsideElements = [floating, ...portalNodes].filter((x): x is Element => x != null); const markerCleanup = markOthers(markerInsideElements); return () => { markerCleanup(); ariaHiddenCleanup(); + inertCleanup(); }; }, [ open, diff --git a/packages/react/src/floating-ui-react/utils/markOthers.test.ts b/packages/react/src/floating-ui-react/utils/markOthers.test.ts index 1997f1862ea..20910f7e7f2 100644 --- a/packages/react/src/floating-ui-react/utils/markOthers.test.ts +++ b/packages/react/src/floating-ui-react/utils/markOthers.test.ts @@ -400,3 +400,26 @@ test('uses shadow root host as avoid element when parent chain includes anchor', expect(outside.getAttribute('aria-hidden')).toBe(null); }); + + +test('marks background focus guards as inert but preserves active ones', () => { + const root = document.createElement('div'); + const inside = document.createElement('div'); + const focusGuardOutside = document.createElement('span'); + const focusGuardInside = document.createElement('span'); + + focusGuardOutside.setAttribute('data-base-ui-focus-guard', ''); + focusGuardInside.setAttribute('data-base-ui-focus-guard', ''); + + root.appendChild(inside); + root.appendChild(focusGuardOutside); + inside.appendChild(focusGuardInside); + document.body.appendChild(root); + + markOthers([inside, focusGuardInside], { inert: true }); + + expect(focusGuardOutside).toHaveAttribute('inert'); + expect(focusGuardInside).not.toHaveAttribute('inert'); + + document.body.removeChild(root); +});