fix(a11y): recover mobile drawer focus after visible transition

This commit is contained in:
cesnimda
2026-10-10 22:02:53 +02:00
parent 0401bc36ea
commit b377f0f62f
2 changed files with 9 additions and 1 deletions
@@ -7,3 +7,11 @@ The unchanged native reduced-motion drawer case still fails. A nonmutating test
The instrument calls the original HTMLElement focus implementation without changing its arguments/behaviour. It records only synthetic fixture DOM states. The existing hard/soft assertions are unchanged; no sleep, skip or expected-failure marker is added. This is transition/entry handling, not evidence that all navigation permanently traps the user.
PRES-E07 remains FAIL at this RED checkpoint. A minimal successor must focus from the visible entering phase, preserve a user's already-selected internal focus, and leave MUI containment/Escape/restoration protection enabled. Human screen-reader/device acceptance remains incomplete; production remains NO-GO.
## Verified successor
The existing `onEntered` callback now also recovers focus when the active element is outside the drawer. It retains internal user-selected focus. Testing `onEntering` established that its ancestor can still be hidden; that attempted implementation was not committed. Waiting for the existing completed transition is the correct lifecycle boundary. MUI autofocus, containment, Escape and focus restoration remain enabled.
Fresh native assertions pass 2/2: keyboard opening under reduced motion selects Dashboard, Escape returns to Open navigation, and emulated touch mode/orientation navigation retains focus. The shell's three focused unit suites pass 10/10 and the production frontend build passes. One preceding run failed before exercising the drawer because a prebuilt export pointed at port 5202 instead of the fixture API at 5302; its trace establishes the setup error. The corrected native run uses the matching build, no retry, relaxed assertion or arbitrary delay.
The bounded defect is repaired. PRES-E07 can return to PARTIAL, with human screen-reader and physical-device obligations still open. This is not production or complete accessibility acceptance.
+1 -1
View File
@@ -615,7 +615,7 @@ export default function AppShell({
slotProps={{
paper: { "aria-label": t("navigation") },
transition: { onEntered: (node: HTMLElement) => {
if (node === document.activeElement) node.querySelector<HTMLElement>('[role="button"]')?.focus();
if (node === document.activeElement || !node.contains(document.activeElement)) node.querySelector<HTMLElement>('[role="button"]')?.focus();
} },
}}
sx={{