From cd688114df84e4f0f24d9bdacbeb81dbb965958f Mon Sep 17 00:00:00 2001 From: Maria Hutt Date: Fri, 15 Nov 2024 11:27:09 -0800 Subject: [PATCH 01/19] fix(overlays): announce info after opening an overlay --- core/src/utils/overlays.ts | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/core/src/utils/overlays.ts b/core/src/utils/overlays.ts index 8aaaad05038..95bb3f2c57d 100644 --- a/core/src/utils/overlays.ts +++ b/core/src/utils/overlays.ts @@ -524,7 +524,7 @@ export const present = async ( document.body.classList.add(BACKDROP_NO_SCROLL); hideUnderlyingOverlaysFromScreenReaders(overlay.el); - hideAnimatingOverlayFromScreenReaders(overlay.el); + // hideAnimatingOverlayFromScreenReaders(overlay.el); overlay.presented = true; overlay.willPresent.emit(); @@ -677,7 +677,7 @@ export const dismiss = async ( * the dismiss animation. This is because the overlay will be removed * from the DOM after the animation is complete. */ - hideAnimatingOverlayFromScreenReaders(overlay.el); + // hideAnimatingOverlayFromScreenReaders(overlay.el); // Overlay contents should not be clickable during dismiss overlay.el.style.setProperty('pointer-events', 'none'); @@ -977,15 +977,15 @@ export const createTriggerController = () => { * * @param overlay - The overlay that is being animated. */ -const hideAnimatingOverlayFromScreenReaders = (overlay: HTMLIonOverlayElement) => { - if (doc === undefined) return; - - /** - * Once the animation is complete, this attribute will be removed. - * This is done at the end of the `present` method. - */ - overlay.setAttribute('aria-hidden', 'true'); -}; +// const hideAnimatingOverlayFromScreenReaders = (overlay: HTMLIonOverlayElement) => { +// if (doc === undefined) return; + +// /** +// * Once the animation is complete, this attribute will be removed. +// * This is done at the end of the `present` method. +// */ +// overlay.setAttribute('aria-hidden', 'true'); +// }; /** * Ensure that underlying overlays have aria-hidden if necessary so that screen readers From ff0b38f1009f0b07e57856717f881a814d34cad7 Mon Sep 17 00:00:00 2001 From: Maria Hutt Date: Fri, 15 Nov 2024 12:09:39 -0800 Subject: [PATCH 02/19] refactor(overlays): hide animating during dismiss --- core/src/utils/overlays.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/core/src/utils/overlays.ts b/core/src/utils/overlays.ts index 95bb3f2c57d..01b3f02c588 100644 --- a/core/src/utils/overlays.ts +++ b/core/src/utils/overlays.ts @@ -677,7 +677,7 @@ export const dismiss = async ( * the dismiss animation. This is because the overlay will be removed * from the DOM after the animation is complete. */ - // hideAnimatingOverlayFromScreenReaders(overlay.el); + hideAnimatingOverlayFromScreenReaders(overlay.el); // Overlay contents should not be clickable during dismiss overlay.el.style.setProperty('pointer-events', 'none'); @@ -977,15 +977,15 @@ export const createTriggerController = () => { * * @param overlay - The overlay that is being animated. */ -// const hideAnimatingOverlayFromScreenReaders = (overlay: HTMLIonOverlayElement) => { -// if (doc === undefined) return; - -// /** -// * Once the animation is complete, this attribute will be removed. -// * This is done at the end of the `present` method. -// */ -// overlay.setAttribute('aria-hidden', 'true'); -// }; +const hideAnimatingOverlayFromScreenReaders = (overlay: HTMLIonOverlayElement) => { + if (doc === undefined) return; + + /** + * Once the animation is complete, this attribute will be removed. + * This is done at the end of the `present` method. + */ + overlay.setAttribute('aria-hidden', 'true'); +}; /** * Ensure that underlying overlays have aria-hidden if necessary so that screen readers From 2031ebb2d42d291bc5c760f7153edcbe83521e27 Mon Sep 17 00:00:00 2001 From: Maria Hutt Date: Fri, 15 Nov 2024 12:44:41 -0800 Subject: [PATCH 03/19] refactor(overlays): move animating hide --- core/src/utils/overlays.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/src/utils/overlays.ts b/core/src/utils/overlays.ts index 01b3f02c588..e06d45a4e23 100644 --- a/core/src/utils/overlays.ts +++ b/core/src/utils/overlays.ts @@ -524,7 +524,6 @@ export const present = async ( document.body.classList.add(BACKDROP_NO_SCROLL); hideUnderlyingOverlaysFromScreenReaders(overlay.el); - // hideAnimatingOverlayFromScreenReaders(overlay.el); overlay.presented = true; overlay.willPresent.emit(); @@ -536,6 +535,8 @@ export const present = async ( ? overlay.enterAnimation : config.get(name, mode === 'ios' ? iosEnterAnimation : mdEnterAnimation); + hideAnimatingOverlayFromScreenReaders(overlay.el); + const completed = await overlayAnimation(overlay, animationBuilder, overlay.el, opts); if (completed) { overlay.didPresent.emit(); From b7fb436d7b79436374004caa98e9776ca5e179d2 Mon Sep 17 00:00:00 2001 From: Maria Hutt Date: Fri, 15 Nov 2024 12:57:16 -0800 Subject: [PATCH 04/19] refactor(overlays): show overlay after animation --- core/src/utils/overlays.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/utils/overlays.ts b/core/src/utils/overlays.ts index e06d45a4e23..da7a63bd00d 100644 --- a/core/src/utils/overlays.ts +++ b/core/src/utils/overlays.ts @@ -539,6 +539,7 @@ export const present = async ( const completed = await overlayAnimation(overlay, animationBuilder, overlay.el, opts); if (completed) { + overlay.el.removeAttribute('aria-hidden'); overlay.didPresent.emit(); overlay.didPresentShorthand?.emit(); } From 6d88238a440692ccb08d829c9fb533e76c39e9c8 Mon Sep 17 00:00:00 2001 From: Maria Hutt Date: Fri, 15 Nov 2024 14:04:50 -0800 Subject: [PATCH 05/19] refactor(overlays): move hidden --- core/src/utils/overlays.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/src/utils/overlays.ts b/core/src/utils/overlays.ts index da7a63bd00d..666234f6d2b 100644 --- a/core/src/utils/overlays.ts +++ b/core/src/utils/overlays.ts @@ -535,7 +535,7 @@ export const present = async ( ? overlay.enterAnimation : config.get(name, mode === 'ios' ? iosEnterAnimation : mdEnterAnimation); - hideAnimatingOverlayFromScreenReaders(overlay.el); + // hideAnimatingOverlayFromScreenReaders(overlay.el); const completed = await overlayAnimation(overlay, animationBuilder, overlay.el, opts); if (completed) { @@ -749,6 +749,8 @@ const overlayAnimation = async ( const aniRoot = overlay.el; const animation = animationBuilder(aniRoot, opts); + aniRoot.setAttribute('aria-hidden', 'true'); + if (!overlay.animated || !config.getBoolean('animated', true)) { animation.duration(0); } @@ -767,6 +769,8 @@ const overlayAnimation = async ( await animation.play(); + aniRoot.removeAttribute('aria-hidden'); + return true; }; From 9545d1ac2b1e1c919dec6d912e2ca8e1ccfc4c2e Mon Sep 17 00:00:00 2001 From: Maria Hutt Date: Fri, 15 Nov 2024 14:22:48 -0800 Subject: [PATCH 06/19] refactor(overlays): move hidden again --- core/src/utils/overlays.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/utils/overlays.ts b/core/src/utils/overlays.ts index 666234f6d2b..347ba2d52c8 100644 --- a/core/src/utils/overlays.ts +++ b/core/src/utils/overlays.ts @@ -749,8 +749,6 @@ const overlayAnimation = async ( const aniRoot = overlay.el; const animation = animationBuilder(aniRoot, opts); - aniRoot.setAttribute('aria-hidden', 'true'); - if (!overlay.animated || !config.getBoolean('animated', true)) { animation.duration(0); } @@ -767,6 +765,8 @@ const overlayAnimation = async ( const activeAni = activeAnimations.get(overlay) || []; activeAnimations.set(overlay, [...activeAni, animation]); + aniRoot.setAttribute('aria-hidden', 'true'); + await animation.play(); aniRoot.removeAttribute('aria-hidden'); From 16369895f28daacea143597e0c75ee9bd899f0d7 Mon Sep 17 00:00:00 2001 From: Maria Hutt Date: Mon, 18 Nov 2024 10:50:59 -0800 Subject: [PATCH 07/19] refactor(overlays): add afterAddWrite --- core/src/utils/overlays.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/core/src/utils/overlays.ts b/core/src/utils/overlays.ts index 347ba2d52c8..fc412962e67 100644 --- a/core/src/utils/overlays.ts +++ b/core/src/utils/overlays.ts @@ -539,7 +539,6 @@ export const present = async ( const completed = await overlayAnimation(overlay, animationBuilder, overlay.el, opts); if (completed) { - overlay.el.removeAttribute('aria-hidden'); overlay.didPresent.emit(); overlay.didPresentShorthand?.emit(); } @@ -753,6 +752,8 @@ const overlayAnimation = async ( animation.duration(0); } + aniRoot.setAttribute('aria-hidden', 'true'); + if (overlay.keyboardClose) { animation.beforeAddWrite(() => { const activeElement = baseEl.ownerDocument!.activeElement as HTMLElement; @@ -762,15 +763,15 @@ const overlayAnimation = async ( }); } + animation.afterAddWrite(() => { + aniRoot.removeAttribute('aria-hidden'); + }); + const activeAni = activeAnimations.get(overlay) || []; activeAnimations.set(overlay, [...activeAni, animation]); - aniRoot.setAttribute('aria-hidden', 'true'); - await animation.play(); - aniRoot.removeAttribute('aria-hidden'); - return true; }; From 53176723efe546d11d3adf7ffdab6dfde38e6b55 Mon Sep 17 00:00:00 2001 From: Maria Hutt Date: Mon, 18 Nov 2024 11:21:38 -0800 Subject: [PATCH 08/19] refactor(overlays): update addWrites --- core/src/utils/overlays.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/core/src/utils/overlays.ts b/core/src/utils/overlays.ts index fc412962e67..47b701ced92 100644 --- a/core/src/utils/overlays.ts +++ b/core/src/utils/overlays.ts @@ -752,19 +752,21 @@ const overlayAnimation = async ( animation.duration(0); } - aniRoot.setAttribute('aria-hidden', 'true'); + animation.beforeAddWrite(() => { + console.log('beforeAddWrite'); + aniRoot.setAttribute('aria-hidden', 'true'); - if (overlay.keyboardClose) { - animation.beforeAddWrite(() => { + if (overlay.keyboardClose) { const activeElement = baseEl.ownerDocument!.activeElement as HTMLElement; if (activeElement?.matches('input,ion-input, ion-textarea')) { activeElement.blur(); } - }); - } + } + }); animation.afterAddWrite(() => { aniRoot.removeAttribute('aria-hidden'); + console.log('afterAddWrite'); }); const activeAni = activeAnimations.get(overlay) || []; From a639c85e4e343dcba6401ea946a345ff2b2a29b6 Mon Sep 17 00:00:00 2001 From: Maria Hutt Date: Mon, 18 Nov 2024 11:46:42 -0800 Subject: [PATCH 09/19] refactor(overlays): use different el --- core/src/utils/overlays.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/utils/overlays.ts b/core/src/utils/overlays.ts index 47b701ced92..83f60d68674 100644 --- a/core/src/utils/overlays.ts +++ b/core/src/utils/overlays.ts @@ -754,7 +754,7 @@ const overlayAnimation = async ( animation.beforeAddWrite(() => { console.log('beforeAddWrite'); - aniRoot.setAttribute('aria-hidden', 'true'); + baseEl.setAttribute('aria-hidden', 'true'); if (overlay.keyboardClose) { const activeElement = baseEl.ownerDocument!.activeElement as HTMLElement; @@ -765,7 +765,7 @@ const overlayAnimation = async ( }); animation.afterAddWrite(() => { - aniRoot.removeAttribute('aria-hidden'); + baseEl.removeAttribute('aria-hidden'); console.log('afterAddWrite'); }); From 6b8bd241e4dafcc39553da62674fb7fd6d6d180b Mon Sep 17 00:00:00 2001 From: Maria Hutt Date: Mon, 18 Nov 2024 11:57:09 -0800 Subject: [PATCH 10/19] refactor(overlays): move set and remove --- core/src/utils/overlays.ts | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/core/src/utils/overlays.ts b/core/src/utils/overlays.ts index 83f60d68674..0d0edeac9c3 100644 --- a/core/src/utils/overlays.ts +++ b/core/src/utils/overlays.ts @@ -114,6 +114,7 @@ export const createOverlay = ( return window.customElements.whenDefined(tagName).then(() => { const element = document.createElement(tagName) as HTMLIonOverlayElement; element.classList.add('overlay-hidden'); + element.setAttribute('aria-hidden', 'true'); /** * Convert the passed in overlay options into props @@ -744,6 +745,7 @@ const overlayAnimation = async ( ): Promise => { // Make overlay visible in case it's hidden baseEl.classList.remove('overlay-hidden'); + baseEl.removeAttribute('aria-hidden'); const aniRoot = overlay.el; const animation = animationBuilder(aniRoot, opts); @@ -753,9 +755,6 @@ const overlayAnimation = async ( } animation.beforeAddWrite(() => { - console.log('beforeAddWrite'); - baseEl.setAttribute('aria-hidden', 'true'); - if (overlay.keyboardClose) { const activeElement = baseEl.ownerDocument!.activeElement as HTMLElement; if (activeElement?.matches('input,ion-input, ion-textarea')) { @@ -764,11 +763,6 @@ const overlayAnimation = async ( } }); - animation.afterAddWrite(() => { - baseEl.removeAttribute('aria-hidden'); - console.log('afterAddWrite'); - }); - const activeAni = activeAnimations.get(overlay) || []; activeAnimations.set(overlay, [...activeAni, animation]); From cd84ab677ffba3ac29c0991ec73c10b0745d1ea0 Mon Sep 17 00:00:00 2001 From: Maria Hutt Date: Mon, 18 Nov 2024 12:57:22 -0800 Subject: [PATCH 11/19] refactor(overlays): add RAF --- core/src/utils/overlays.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/core/src/utils/overlays.ts b/core/src/utils/overlays.ts index 0d0edeac9c3..f946dc56191 100644 --- a/core/src/utils/overlays.ts +++ b/core/src/utils/overlays.ts @@ -114,7 +114,6 @@ export const createOverlay = ( return window.customElements.whenDefined(tagName).then(() => { const element = document.createElement(tagName) as HTMLIonOverlayElement; element.classList.add('overlay-hidden'); - element.setAttribute('aria-hidden', 'true'); /** * Convert the passed in overlay options into props @@ -745,7 +744,6 @@ const overlayAnimation = async ( ): Promise => { // Make overlay visible in case it's hidden baseEl.classList.remove('overlay-hidden'); - baseEl.removeAttribute('aria-hidden'); const aniRoot = overlay.el; const animation = animationBuilder(aniRoot, opts); @@ -755,6 +753,9 @@ const overlayAnimation = async ( } animation.beforeAddWrite(() => { + console.log('beforeAddWrite'); + baseEl.setAttribute('aria-hidden', 'true'); + if (overlay.keyboardClose) { const activeElement = baseEl.ownerDocument!.activeElement as HTMLElement; if (activeElement?.matches('input,ion-input, ion-textarea')) { @@ -763,6 +764,13 @@ const overlayAnimation = async ( } }); + animation.afterAddWrite(() => { + requestAnimationFrame(() => { + baseEl.removeAttribute('aria-hidden'); + console.log('afterAddWrite'); + }); + }); + const activeAni = activeAnimations.get(overlay) || []; activeAnimations.set(overlay, [...activeAni, animation]); From 7099fb7fa4b55a8eb7d70568b47e2d1c5ddb4143 Mon Sep 17 00:00:00 2001 From: Maria Hutt Date: Mon, 18 Nov 2024 13:27:13 -0800 Subject: [PATCH 12/19] refactor(overlays): use child --- core/src/utils/overlays.ts | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/core/src/utils/overlays.ts b/core/src/utils/overlays.ts index f946dc56191..f68d62aaaa7 100644 --- a/core/src/utils/overlays.ts +++ b/core/src/utils/overlays.ts @@ -754,7 +754,10 @@ const overlayAnimation = async ( animation.beforeAddWrite(() => { console.log('beforeAddWrite'); - baseEl.setAttribute('aria-hidden', 'true'); + const overlayWrapper = baseEl.querySelector('.ion-overlay-wrapper'); + if (overlayWrapper) { + overlayWrapper.setAttribute('aria-hidden', 'true'); + } if (overlay.keyboardClose) { const activeElement = baseEl.ownerDocument!.activeElement as HTMLElement; @@ -765,10 +768,11 @@ const overlayAnimation = async ( }); animation.afterAddWrite(() => { - requestAnimationFrame(() => { - baseEl.removeAttribute('aria-hidden'); - console.log('afterAddWrite'); - }); + const overlayWrapper = baseEl.querySelector('.ion-overlay-wrapper'); + if (overlayWrapper) { + overlayWrapper.removeAttribute('aria-hidden'); + } + console.log('afterAddWrite'); }); const activeAni = activeAnimations.get(overlay) || []; From 78da3f678c1ecdba71f8a66c6b4c6e3d364da104 Mon Sep 17 00:00:00 2001 From: Maria Hutt Date: Mon, 18 Nov 2024 13:50:12 -0800 Subject: [PATCH 13/19] refactor(overlays): hide only for md mode --- core/src/utils/overlays.ts | 39 ++++++++++++++------------------------ 1 file changed, 14 insertions(+), 25 deletions(-) diff --git a/core/src/utils/overlays.ts b/core/src/utils/overlays.ts index f68d62aaaa7..f196fb13f27 100644 --- a/core/src/utils/overlays.ts +++ b/core/src/utils/overlays.ts @@ -524,6 +524,7 @@ export const present = async ( document.body.classList.add(BACKDROP_NO_SCROLL); hideUnderlyingOverlaysFromScreenReaders(overlay.el); + hideAnimatingOverlayFromScreenReaders(overlay.el); overlay.presented = true; overlay.willPresent.emit(); @@ -535,8 +536,6 @@ export const present = async ( ? overlay.enterAnimation : config.get(name, mode === 'ios' ? iosEnterAnimation : mdEnterAnimation); - // hideAnimatingOverlayFromScreenReaders(overlay.el); - const completed = await overlayAnimation(overlay, animationBuilder, overlay.el, opts); if (completed) { overlay.didPresent.emit(); @@ -752,28 +751,14 @@ const overlayAnimation = async ( animation.duration(0); } - animation.beforeAddWrite(() => { - console.log('beforeAddWrite'); - const overlayWrapper = baseEl.querySelector('.ion-overlay-wrapper'); - if (overlayWrapper) { - overlayWrapper.setAttribute('aria-hidden', 'true'); - } - - if (overlay.keyboardClose) { + if (overlay.keyboardClose) { + animation.beforeAddWrite(() => { const activeElement = baseEl.ownerDocument!.activeElement as HTMLElement; if (activeElement?.matches('input,ion-input, ion-textarea')) { activeElement.blur(); } - } - }); - - animation.afterAddWrite(() => { - const overlayWrapper = baseEl.querySelector('.ion-overlay-wrapper'); - if (overlayWrapper) { - overlayWrapper.removeAttribute('aria-hidden'); - } - console.log('afterAddWrite'); - }); + }); + } const activeAni = activeAnimations.get(overlay) || []; activeAnimations.set(overlay, [...activeAni, animation]); @@ -995,11 +980,15 @@ export const createTriggerController = () => { const hideAnimatingOverlayFromScreenReaders = (overlay: HTMLIonOverlayElement) => { if (doc === undefined) return; - /** - * Once the animation is complete, this attribute will be removed. - * This is done at the end of the `present` method. - */ - overlay.setAttribute('aria-hidden', 'true'); + const mode = getIonMode(overlay); + + if (mode === 'md') { + /** + * Once the animation is complete, this attribute will be removed. + * This is done at the end of the `present` method. + */ + overlay.setAttribute('aria-hidden', 'true'); + } }; /** From 4cdb33aefa2791055df3f274db5e38fc0c7d7dbc Mon Sep 17 00:00:00 2001 From: Maria Hutt Date: Mon, 18 Nov 2024 14:05:20 -0800 Subject: [PATCH 14/19] refactor(overlays): comment out --- core/src/utils/overlays.ts | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/core/src/utils/overlays.ts b/core/src/utils/overlays.ts index f196fb13f27..708be620cf6 100644 --- a/core/src/utils/overlays.ts +++ b/core/src/utils/overlays.ts @@ -524,7 +524,7 @@ export const present = async ( document.body.classList.add(BACKDROP_NO_SCROLL); hideUnderlyingOverlaysFromScreenReaders(overlay.el); - hideAnimatingOverlayFromScreenReaders(overlay.el); + // hideAnimatingOverlayFromScreenReaders(overlay.el); overlay.presented = true; overlay.willPresent.emit(); @@ -677,7 +677,7 @@ export const dismiss = async ( * the dismiss animation. This is because the overlay will be removed * from the DOM after the animation is complete. */ - hideAnimatingOverlayFromScreenReaders(overlay.el); + // hideAnimatingOverlayFromScreenReaders(overlay.el); // Overlay contents should not be clickable during dismiss overlay.el.style.setProperty('pointer-events', 'none'); @@ -977,19 +977,19 @@ export const createTriggerController = () => { * * @param overlay - The overlay that is being animated. */ -const hideAnimatingOverlayFromScreenReaders = (overlay: HTMLIonOverlayElement) => { - if (doc === undefined) return; - - const mode = getIonMode(overlay); - - if (mode === 'md') { - /** - * Once the animation is complete, this attribute will be removed. - * This is done at the end of the `present` method. - */ - overlay.setAttribute('aria-hidden', 'true'); - } -}; +// const hideAnimatingOverlayFromScreenReaders = (overlay: HTMLIonOverlayElement) => { +// if (doc === undefined) return; + +// const mode = getIonMode(overlay); + +// if (mode === 'md') { +// /** +// * Once the animation is complete, this attribute will be removed. +// * This is done at the end of the `present` method. +// */ +// overlay.setAttribute('aria-hidden', 'true'); +// } +// }; /** * Ensure that underlying overlays have aria-hidden if necessary so that screen readers From b914f867b360ecb2a220723cd97bddb984712652 Mon Sep 17 00:00:00 2001 From: Maria Hutt Date: Mon, 18 Nov 2024 14:17:30 -0800 Subject: [PATCH 15/19] refactor(overlays): more commenting --- core/src/utils/overlays.ts | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/core/src/utils/overlays.ts b/core/src/utils/overlays.ts index 708be620cf6..6b518eb11ee 100644 --- a/core/src/utils/overlays.ts +++ b/core/src/utils/overlays.ts @@ -524,7 +524,7 @@ export const present = async ( document.body.classList.add(BACKDROP_NO_SCROLL); hideUnderlyingOverlaysFromScreenReaders(overlay.el); - // hideAnimatingOverlayFromScreenReaders(overlay.el); + hideAnimatingOverlayFromScreenReaders(overlay.el); overlay.presented = true; overlay.willPresent.emit(); @@ -677,7 +677,7 @@ export const dismiss = async ( * the dismiss animation. This is because the overlay will be removed * from the DOM after the animation is complete. */ - // hideAnimatingOverlayFromScreenReaders(overlay.el); + hideAnimatingOverlayFromScreenReaders(overlay.el); // Overlay contents should not be clickable during dismiss overlay.el.style.setProperty('pointer-events', 'none'); @@ -977,19 +977,20 @@ export const createTriggerController = () => { * * @param overlay - The overlay that is being animated. */ -// const hideAnimatingOverlayFromScreenReaders = (overlay: HTMLIonOverlayElement) => { -// if (doc === undefined) return; - -// const mode = getIonMode(overlay); - -// if (mode === 'md') { -// /** -// * Once the animation is complete, this attribute will be removed. -// * This is done at the end of the `present` method. -// */ -// overlay.setAttribute('aria-hidden', 'true'); -// } -// }; +const hideAnimatingOverlayFromScreenReaders = (overlay: HTMLIonOverlayElement) => { + if (doc === undefined) return; + + const mode = getIonMode(overlay); + console.log('mode', mode); + + // if (mode === 'md') { + // /** + // * Once the animation is complete, this attribute will be removed. + // * This is done at the end of the `present` method. + // */ + // overlay.setAttribute('aria-hidden', 'true'); + // } +}; /** * Ensure that underlying overlays have aria-hidden if necessary so that screen readers From f8e620fd6a02ec7bbf482c103f086fdc171e0364 Mon Sep 17 00:00:00 2001 From: Maria Hutt Date: Mon, 18 Nov 2024 14:26:53 -0800 Subject: [PATCH 16/19] refactor(overlays): md comment --- core/src/utils/overlays.ts | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/core/src/utils/overlays.ts b/core/src/utils/overlays.ts index 6b518eb11ee..02e7c88f989 100644 --- a/core/src/utils/overlays.ts +++ b/core/src/utils/overlays.ts @@ -983,13 +983,14 @@ const hideAnimatingOverlayFromScreenReaders = (overlay: HTMLIonOverlayElement) = const mode = getIonMode(overlay); console.log('mode', mode); - // if (mode === 'md') { - // /** - // * Once the animation is complete, this attribute will be removed. - // * This is done at the end of the `present` method. - // */ - // overlay.setAttribute('aria-hidden', 'true'); - // } + if (mode === 'md') { + console.log('in md'); + /** + * Once the animation is complete, this attribute will be removed. + * This is done at the end of the `present` method. + */ + overlay.setAttribute('aria-hidden', 'true'); + } }; /** From 8a7db47348f5404e065e5fad471a6f4750f915cc Mon Sep 17 00:00:00 2001 From: Maria Hutt Date: Mon, 18 Nov 2024 16:41:29 -0800 Subject: [PATCH 17/19] refactor(overlays): verify baseEl --- core/src/utils/overlays.ts | 39 ++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/core/src/utils/overlays.ts b/core/src/utils/overlays.ts index 02e7c88f989..497600cff14 100644 --- a/core/src/utils/overlays.ts +++ b/core/src/utils/overlays.ts @@ -524,7 +524,6 @@ export const present = async ( document.body.classList.add(BACKDROP_NO_SCROLL); hideUnderlyingOverlaysFromScreenReaders(overlay.el); - hideAnimatingOverlayFromScreenReaders(overlay.el); overlay.presented = true; overlay.willPresent.emit(); @@ -536,6 +535,8 @@ export const present = async ( ? overlay.enterAnimation : config.get(name, mode === 'ios' ? iosEnterAnimation : mdEnterAnimation); + // hideAnimatingOverlayFromScreenReaders(overlay.el); + const completed = await overlayAnimation(overlay, animationBuilder, overlay.el, opts); if (completed) { overlay.didPresent.emit(); @@ -751,14 +752,26 @@ const overlayAnimation = async ( animation.duration(0); } - if (overlay.keyboardClose) { - animation.beforeAddWrite(() => { + animation.beforeAddWrite(() => { + console.log('beforeAddWrite'); + baseEl.setAttribute('aria-hidden', 'true'); + // add class 'test' to baseEl + baseEl.classList.add('test'); + + if (overlay.keyboardClose) { const activeElement = baseEl.ownerDocument!.activeElement as HTMLElement; if (activeElement?.matches('input,ion-input, ion-textarea')) { activeElement.blur(); } - }); - } + } + }); + + animation.afterAddWrite(() => { + baseEl.removeAttribute('aria-hidden'); + // add test2 class to baseEl + baseEl.classList.add('test2'); + console.log('afterAddWrite'); + }); const activeAni = activeAnimations.get(overlay) || []; activeAnimations.set(overlay, [...activeAni, animation]); @@ -980,17 +993,11 @@ export const createTriggerController = () => { const hideAnimatingOverlayFromScreenReaders = (overlay: HTMLIonOverlayElement) => { if (doc === undefined) return; - const mode = getIonMode(overlay); - console.log('mode', mode); - - if (mode === 'md') { - console.log('in md'); - /** - * Once the animation is complete, this attribute will be removed. - * This is done at the end of the `present` method. - */ - overlay.setAttribute('aria-hidden', 'true'); - } + /** + * Once the animation is complete, this attribute will be removed. + * This is done at the end of the `present` method. + */ + overlay.setAttribute('aria-hidden', 'true'); }; /** From 9d1aae38c88cdbb101667298e937269e894f295e Mon Sep 17 00:00:00 2001 From: Maria Hutt Date: Mon, 18 Nov 2024 16:59:55 -0800 Subject: [PATCH 18/19] refactor(overlays): check for mode --- core/src/utils/overlays.ts | 45 ++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/core/src/utils/overlays.ts b/core/src/utils/overlays.ts index 497600cff14..930daeac50c 100644 --- a/core/src/utils/overlays.ts +++ b/core/src/utils/overlays.ts @@ -524,6 +524,7 @@ export const present = async ( document.body.classList.add(BACKDROP_NO_SCROLL); hideUnderlyingOverlaysFromScreenReaders(overlay.el); + hideAnimatingOverlayFromScreenReaders(overlay.el); overlay.presented = true; overlay.willPresent.emit(); @@ -535,8 +536,6 @@ export const present = async ( ? overlay.enterAnimation : config.get(name, mode === 'ios' ? iosEnterAnimation : mdEnterAnimation); - // hideAnimatingOverlayFromScreenReaders(overlay.el); - const completed = await overlayAnimation(overlay, animationBuilder, overlay.el, opts); if (completed) { overlay.didPresent.emit(); @@ -752,26 +751,14 @@ const overlayAnimation = async ( animation.duration(0); } - animation.beforeAddWrite(() => { - console.log('beforeAddWrite'); - baseEl.setAttribute('aria-hidden', 'true'); - // add class 'test' to baseEl - baseEl.classList.add('test'); - - if (overlay.keyboardClose) { + if (overlay.keyboardClose) { + animation.beforeAddWrite(() => { const activeElement = baseEl.ownerDocument!.activeElement as HTMLElement; if (activeElement?.matches('input,ion-input, ion-textarea')) { activeElement.blur(); } - } - }); - - animation.afterAddWrite(() => { - baseEl.removeAttribute('aria-hidden'); - // add test2 class to baseEl - baseEl.classList.add('test2'); - console.log('afterAddWrite'); - }); + }); + } const activeAni = activeAnimations.get(overlay) || []; activeAnimations.set(overlay, [...activeAni, animation]); @@ -986,18 +973,28 @@ export const createTriggerController = () => { * If the overlay is being presented, it prevents focus rings from appearing * in incorrect positions due to the transition (specifically `transform` * styles), ensuring that when aria-hidden is removed, the focus rings are - * correctly displayed in the final location of the elements. + * correctly displayed in the final location of the elements. This only + * applies to Android devices. + * + * If this solution is applied to iOS devices, then it leads to a bug where + * the overlays cannot be accessed by screen readers. This is due to + * VoiceOver not being able to update the accessibility tree when the + * `aria-hidden` is removed. * * @param overlay - The overlay that is being animated. */ const hideAnimatingOverlayFromScreenReaders = (overlay: HTMLIonOverlayElement) => { if (doc === undefined) return; - /** - * Once the animation is complete, this attribute will be removed. - * This is done at the end of the `present` method. - */ - overlay.setAttribute('aria-hidden', 'true'); + const mode = getIonMode(overlay); + + if (mode === 'md') { + /** + * Once the animation is complete, this attribute will be removed. + * This is done at the end of the `present` method. + */ + overlay.setAttribute('aria-hidden', 'true'); + } }; /** From 70e160c35fa19d2a24509725ee2a3ebaa9185d47 Mon Sep 17 00:00:00 2001 From: Maria Hutt Date: Tue, 19 Nov 2024 08:23:16 -0800 Subject: [PATCH 19/19] refactor(overlays): use isPlatform --- core/src/utils/overlays.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/core/src/utils/overlays.ts b/core/src/utils/overlays.ts index 930daeac50c..25a6597d1ad 100644 --- a/core/src/utils/overlays.ts +++ b/core/src/utils/overlays.ts @@ -32,6 +32,7 @@ import { removeEventListener, } from './helpers'; import { printIonWarning } from './logging'; +import { isPlatform } from './platform'; let lastOverlayIndex = 0; let lastId = 0; @@ -986,9 +987,7 @@ export const createTriggerController = () => { const hideAnimatingOverlayFromScreenReaders = (overlay: HTMLIonOverlayElement) => { if (doc === undefined) return; - const mode = getIonMode(overlay); - - if (mode === 'md') { + if (isPlatform('android')) { /** * Once the animation is complete, this attribute will be removed. * This is done at the end of the `present` method.