From 2837790d27594f49783e34fa8e62631b4141f76b Mon Sep 17 00:00:00 2001 From: Maria Hutt Date: Tue, 19 Nov 2024 16:53:26 -0800 Subject: [PATCH 1/3] fix(header): aria hide the ion-title --- core/src/components/header/header.utils.ts | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/core/src/components/header/header.utils.ts b/core/src/components/header/header.utils.ts index f1b6273ef5e..e28555ebabf 100644 --- a/core/src/components/header/header.utils.ts +++ b/core/src/components/header/header.utils.ts @@ -167,13 +167,25 @@ export const handleToolbarIntersection = ( export const setHeaderActive = (headerIndex: HeaderIndex, active = true) => { const headerEl = headerIndex.el; + const toolbars = headerIndex.toolbars; + const ionTitles = toolbars.map((toolbar) => toolbar.ionTitleEl); if (active) { headerEl.classList.remove('header-collapse-condense-inactive'); - headerEl.removeAttribute('aria-hidden'); + + ionTitles.forEach((ionTitle) => { + if (ionTitle) { + ionTitle.removeAttribute('aria-hidden'); + } + }); } else { headerEl.classList.add('header-collapse-condense-inactive'); - headerEl.setAttribute('aria-hidden', 'true'); + + ionTitles.forEach((ionTitle) => { + if (ionTitle) { + ionTitle.setAttribute('aria-hidden', 'true'); + } + }); } }; From cbc7323d1cd27ad7f648bd6997e775f7edb3cec0 Mon Sep 17 00:00:00 2001 From: Maria Hutt Date: Wed, 20 Nov 2024 11:20:08 -0800 Subject: [PATCH 2/3] docs(header): add comment --- core/src/components/header/header.utils.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/core/src/components/header/header.utils.ts b/core/src/components/header/header.utils.ts index e28555ebabf..af2e4b1acdb 100644 --- a/core/src/components/header/header.utils.ts +++ b/core/src/components/header/header.utils.ts @@ -181,6 +181,15 @@ export const setHeaderActive = (headerIndex: HeaderIndex, active = true) => { } else { headerEl.classList.add('header-collapse-condense-inactive'); + /** + * The small title should only be accessed by screen readers + * when the large title collapses into the small title due + * to scrolling. + * + * Originally, the header was given `aria-hidden="true"` + * but this caused issues with screen readers not being + * able to access any focusable elements within the header. + */ ionTitles.forEach((ionTitle) => { if (ionTitle) { ionTitle.setAttribute('aria-hidden', 'true'); From 3029fea28236c9e82e5d315942e67f3bfd3d0b19 Mon Sep 17 00:00:00 2001 From: Maria Hutt Date: Wed, 20 Nov 2024 11:45:02 -0800 Subject: [PATCH 3/3] test(header): update to check title --- .../components/header/test/condense/header.e2e.ts | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/core/src/components/header/test/condense/header.e2e.ts b/core/src/components/header/test/condense/header.e2e.ts index 791c1b720af..b57d1ee58f7 100644 --- a/core/src/components/header/test/condense/header.e2e.ts +++ b/core/src/components/header/test/condense/header.e2e.ts @@ -3,13 +3,19 @@ import { configs, test } from '@utils/test/playwright'; configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, screenshot, config }) => { test.describe(title('header: condense'), () => { - test('should be hidden from screen readers when collapsed', async ({ page }) => { + test('should hide small title from screen readers when collapsed', async ({ page }) => { + test.info().annotations.push({ + type: 'issue', + description: 'https://github.com/ionic-team/ionic-framework/issues/29347', + }); + await page.goto('/src/components/header/test/condense', config); const largeTitleHeader = page.locator('#largeTitleHeader'); const smallTitleHeader = page.locator('#smallTitleHeader'); + const smallTitle = smallTitleHeader.locator('ion-title'); const content = page.locator('ion-content'); - await expect(smallTitleHeader).toHaveAttribute('aria-hidden', 'true'); + await expect(smallTitle).toHaveAttribute('aria-hidden', 'true'); await expect(largeTitleHeader).toHaveScreenshot(screenshot(`header-condense-large-title-initial-diff`)); @@ -24,7 +30,7 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, screenshot, c * Playwright can't do .not.toHaveAttribute() because a value is expected, * and toHaveAttribute can't accept a value of type null. */ - const ariaHidden = await smallTitleHeader.getAttribute('aria-hidden'); + const ariaHidden = await smallTitle.getAttribute('aria-hidden'); expect(ariaHidden).toBeNull(); await content.evaluate(async (el: HTMLIonContentElement) => { @@ -32,7 +38,7 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, screenshot, c }); await page.locator('#smallTitleHeader.header-collapse-condense-inactive').waitFor(); - await expect(smallTitleHeader).toHaveAttribute('aria-hidden', 'true'); + await expect(smallTitle).toHaveAttribute('aria-hidden', 'true'); }); }); });