From 2599b47ed23457018a7f8523e3cd7cbf505398be Mon Sep 17 00:00:00 2001 From: Keilo75 <82605039+Keilo75@users.noreply.github.com> Date: Sat, 22 Oct 2022 11:20:58 +0200 Subject: [PATCH] [@mantine/hooks] use-focus-trap: Fix incorrect aria-hidden handling (#2735) * [@mantine/hooks] use-focus-trap: Fix aria-hidden="true" not being removed * [@mantine/hooks] use-focus-trap: Fix aria-hidden not being applied multiple times * [@mantine/core] FocusTrap: Add test for aria-hidden --- .../src/FocusTrap/FocusTrap.test.tsx | 23 +++++++++++++++++++ .../src/use-focus-trap/use-focus-trap.ts | 17 ++++++++------ 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/src/mantine-core/src/FocusTrap/FocusTrap.test.tsx b/src/mantine-core/src/FocusTrap/FocusTrap.test.tsx index 3ec47f2a411..75d4bdfdf53 100644 --- a/src/mantine-core/src/FocusTrap/FocusTrap.test.tsx +++ b/src/mantine-core/src/FocusTrap/FocusTrap.test.tsx @@ -51,6 +51,29 @@ describe('@mantine/core/FocusTrap', () => { expect(document.body).toHaveFocus(); }); + it('manages aria-hidden attributes', () => { + const adjacentDiv = document.createElement('div'); + adjacentDiv.setAttribute('data-testid', 'adjacent'); + document.body.appendChild(adjacentDiv); + + const { rerender } = render( + +
+ + ); + + const adjacent = screen.getByTestId('adjacent'); + expect(adjacent).toHaveAttribute('aria-hidden', 'true'); + + rerender( + +
+ + ); + + expect(adjacent).not.toHaveAttribute('aria-hidden'); + }); + it('has correct displayName', () => { expect(FocusTrap.displayName).toEqual('@mantine/core/FocusTrap'); }); diff --git a/src/mantine-hooks/src/use-focus-trap/use-focus-trap.ts b/src/mantine-hooks/src/use-focus-trap/use-focus-trap.ts index fc55a6b63f3..2f69fcad60a 100644 --- a/src/mantine-hooks/src/use-focus-trap/use-focus-trap.ts +++ b/src/mantine-hooks/src/use-focus-trap/use-focus-trap.ts @@ -13,18 +13,17 @@ export function useFocusTrap(active = true): (instance: HTMLElement | null) => v return; } - if (node === ref.current || node === null) { + if (node === null) { return; } - if (restoreAria.current) { - restoreAria.current(); + restoreAria.current = createAriaHider(node); + if (ref.current === node) { + return; } if (node) { - const processNode = (_node: HTMLElement) => { - restoreAria.current = createAriaHider(_node); - + const processNode = () => { let focusElement: HTMLElement = node.querySelector('[data-autofocus]'); if (!focusElement) { @@ -47,7 +46,7 @@ export function useFocusTrap(active = true): (instance: HTMLElement | null) => v // Delay processing the HTML node by a frame. This ensures focus is assigned correctly. setTimeout(() => { if (node.ownerDocument) { - processNode(node); + processNode(); } else if (process.env.NODE_ENV === 'development') { // eslint-disable-next-line no-console console.warn('[@mantine/hooks/use-focus-trap] Ref node is not part of the dom', node); @@ -76,6 +75,10 @@ export function useFocusTrap(active = true): (instance: HTMLElement | null) => v document.addEventListener('keydown', handleKeyDown); return () => { document.removeEventListener('keydown', handleKeyDown); + + if (restoreAria.current) { + restoreAria.current(); + } }; }, [active]);