fix(17): WR-01 exclude hidden/zero-size nodes from focus-trap boundaries
This commit is contained in:
@@ -26,7 +26,17 @@ export function useFocusTrap(
|
|||||||
dialogRef.current.querySelectorAll<HTMLElement>(
|
dialogRef.current.querySelectorAll<HTMLElement>(
|
||||||
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])',
|
'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])',
|
||||||
),
|
),
|
||||||
).filter((el) => !el.hasAttribute('disabled') && el.getAttribute('tabindex') !== '-1');
|
).filter((el) => {
|
||||||
|
// Exclude disabled / explicitly-untabbable nodes …
|
||||||
|
if (el.hasAttribute('disabled') || el.getAttribute('tabindex') === '-1') return false;
|
||||||
|
// … and nodes that are not actually rendered/visible (WR-01). A focusable
|
||||||
|
// inside a hidden/collapsed block would otherwise become the computed
|
||||||
|
// first/last and `last.focus()` would no-op, leaking Tab to background
|
||||||
|
// content that `aria-modal="true"` promises is unreachable.
|
||||||
|
if (el.hasAttribute('hidden') || el.offsetParent === null) return false;
|
||||||
|
const r = el.getBoundingClientRect();
|
||||||
|
return r.width > 0 && r.height > 0;
|
||||||
|
});
|
||||||
|
|
||||||
if (focusable.length === 0) return;
|
if (focusable.length === 0) return;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user