Skip to content

Commit

Permalink
fix(header): use aria attributes to hide small title when collapsed (#…
Browse files Browse the repository at this point in the history
…30027)

Issue number: resolves #29347 

---------

<!-- Please do not submit updates to dependencies unless it fixes an
issue. -->

<!-- Please try to limit your pull request to one type (bugfix, feature,
etc). Submit multiple pull requests if needed. -->

## What is the current behavior?
<!-- Please describe the current behavior that you are modifying. -->

Focusable elements like buttons cannot be accessed within the
`ion-header` when it's collapsed. They're only accessible once the small
title is displayed.

## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->

- Moved the `aria-hidden` from the header to `ion-title`, this aligns
with native.
- Updated existing test.

## Does this introduce a breaking change?

- [ ] Yes
- [x] No

<!--
  If this introduces a breaking change:
1. Describe the impact and migration path for existing applications
below.
  2. Update the BREAKING.md file with the breaking change.
3. Add "BREAKING CHANGE: [...]" to the commit description when merging.
See
https://github.com/ionic-team/ionic-framework/blob/main/docs/CONTRIBUTING.md#footer
for more information.
-->


## Other information

<!-- Any other information that is important to this PR such as
screenshots of how the component looks before and after the change. -->

Dev build: `8.4.1-dev.11732064156.12837790`
  • Loading branch information
thetaPC authored Nov 21, 2024
1 parent 470decc commit 23763ab
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 6 deletions.
25 changes: 23 additions & 2 deletions core/src/components/header/header.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,13 +167,34 @@ 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');

/**
* 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');
}
});
}
};

Expand Down
14 changes: 10 additions & 4 deletions core/src/components/header/test/condense/header.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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`));

Expand All @@ -24,15 +30,15 @@ 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) => {
await el.scrollToTop();
});
await page.locator('#smallTitleHeader.header-collapse-condense-inactive').waitFor();

await expect(smallTitleHeader).toHaveAttribute('aria-hidden', 'true');
await expect(smallTitle).toHaveAttribute('aria-hidden', 'true');
});
});
});

0 comments on commit 23763ab

Please sign in to comment.