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]);