fix(overlays): screen readers no longer read content behind overlays (#23284)

resolves #22714
This commit is contained in:
Liam DeBeasi
2021-05-11 09:51:37 -04:00
committed by GitHub
parent 9cb6c80b3d
commit a9b12a5aa4
2 changed files with 120 additions and 0 deletions

View File

@ -236,6 +236,41 @@ export const getOverlay = (doc: Document, overlayTag?: string, id?: string): HTM
: overlays.find(o => o.id === id);
};
/**
* When an overlay is presented, the main
* focus is the overlay not the page content.
* We need to remove the page content from the
* accessibility tree otherwise when
* users use "read screen from top" gestures with
* TalkBack and VoiceOver, the screen reader will begin
* to read the content underneath the overlay.
*
* We need a container where all page components
* exist that is separate from where the overlays
* are added in the DOM. For most apps, this element
* is the top most ion-router-outlet. In the event
* that devs are not using a router,
* they will need to add the "ion-view-container-root"
* id to the element that contains all of their views.
*
* TODO: If Framework supports having multiple top
* level router outlets we would need to update this.
* Example: One outlet for side menu and one outlet
* for main content.
*/
export const setRootAriaHidden = (hidden = false) => {
const root = getAppRoot(document);
const viewContainer = root.querySelector('ion-router-outlet, ion-nav, #ion-view-container-root');
if (!viewContainer) { return; }
if (hidden) {
viewContainer.setAttribute('aria-hidden', 'true');
} else {
viewContainer.removeAttribute('aria-hidden');
}
}
export const present = async (
overlay: OverlayInterface,
name: keyof IonicConfig,
@ -246,6 +281,9 @@ export const present = async (
if (overlay.presented) {
return;
}
setRootAriaHidden(true);
overlay.presented = true;
overlay.willPresent.emit();
@ -313,6 +351,9 @@ export const dismiss = async (
if (!overlay.presented) {
return false;
}
setRootAriaHidden(false);
overlay.presented = false;
try {