Skip to content

Commit d0ba963

Browse files
fix(header): hide from screen readers when collapsed (#25744)
1 parent 2ddaf7a commit d0ba963

File tree

4 files changed

+129
-7
lines changed

4 files changed

+129
-7
lines changed

core/src/components/header/header.utils.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,10 +164,14 @@ export const handleToolbarIntersection = (
164164
};
165165

166166
export const setHeaderActive = (headerIndex: HeaderIndex, active = true) => {
167+
const headerEl = headerIndex.el;
168+
167169
if (active) {
168-
headerIndex.el.classList.remove('header-collapse-condense-inactive');
170+
headerEl.classList.remove('header-collapse-condense-inactive');
171+
headerEl.removeAttribute('aria-hidden');
169172
} else {
170-
headerIndex.el.classList.add('header-collapse-condense-inactive');
173+
headerEl.classList.add('header-collapse-condense-inactive');
174+
headerEl.setAttribute('aria-hidden', 'true');
171175
}
172176
};
173177

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { expect } from '@playwright/test';
2+
import { test } from '@utils/test/playwright';
3+
4+
test.describe('header: condense', () => {
5+
test('should be hidden from screen readers when collapsed', async ({ page }, testInfo) => {
6+
test.skip(testInfo.project.metadata.mode === 'md', 'Logic only applies to iOS mode');
7+
test.skip(testInfo.project.metadata.rtl === true, 'No RTL-specific logic');
8+
9+
await page.goto('/src/components/header/test/condense');
10+
const header = page.locator('#collapsibleHeader');
11+
const content = page.locator('ion-content');
12+
13+
await expect(header).toHaveAttribute('aria-hidden', 'true');
14+
15+
await content.evaluate((el: HTMLIonContentElement) => el.scrollToBottom());
16+
await page.waitForChanges();
17+
18+
/**
19+
* Playwright can't do .not.toHaveAttribute() because a value is expected,
20+
* and toHaveAttribute can't accept a value of type null.
21+
*/
22+
const ariaHidden = await header.getAttribute('aria-hidden');
23+
expect(ariaHidden).toBeNull();
24+
25+
await content.evaluate((el: HTMLIonContentElement) => el.scrollToTop());
26+
await page.waitForChanges();
27+
28+
await expect(header).toHaveAttribute('aria-hidden', 'true');
29+
});
30+
});
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<!DOCTYPE html>
2+
<html lang="en" dir="ltr">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<title>Header - Condense</title>
6+
<meta
7+
name="viewport"
8+
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
9+
/>
10+
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet" />
11+
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet" />
12+
<script src="../../../../../scripts/testing/scripts.js"></script>
13+
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
14+
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
15+
<style>
16+
.red {
17+
background-color: #ea445a;
18+
}
19+
20+
.green {
21+
background-color: #76d672;
22+
}
23+
24+
.blue {
25+
background-color: #3478f6;
26+
}
27+
28+
.yellow {
29+
background-color: #ffff80;
30+
}
31+
32+
.pink {
33+
background-color: #ff6b86;
34+
}
35+
36+
.purple {
37+
background-color: #7e34f6;
38+
}
39+
40+
.black {
41+
background-color: #000;
42+
}
43+
44+
.orange {
45+
background-color: #f69234;
46+
}
47+
48+
.grid {
49+
display: grid;
50+
grid-template-columns: 1fr 1fr;
51+
grid-gap: 10px;
52+
}
53+
54+
.grid-item {
55+
height: 200px;
56+
}
57+
</style>
58+
</head>
59+
60+
<body>
61+
<ion-app>
62+
<div class="ion-page">
63+
<ion-header translucent="true" id="collapsibleHeader">
64+
<ion-toolbar>
65+
<ion-title>Mailboxes</ion-title>
66+
</ion-toolbar>
67+
</ion-header>
68+
<ion-content fullscreen="true">
69+
<ion-header collapse="condense">
70+
<ion-toolbar>
71+
<ion-title size="large">Mailboxes</ion-title>
72+
</ion-toolbar>
73+
</ion-header>
74+
<div class="grid ion-padding">
75+
<div class="grid-item red"></div>
76+
<div class="grid-item green"></div>
77+
<div class="grid-item blue"></div>
78+
<div class="grid-item yellow"></div>
79+
<div class="grid-item pink"></div>
80+
<div class="grid-item purple"></div>
81+
<div class="grid-item black"></div>
82+
<div class="grid-item orange"></div>
83+
</div>
84+
</ion-content>
85+
<ion-footer translucent="true">
86+
<ion-toolbar>
87+
<ion-title>Updated Just Now</ion-title>
88+
</ion-toolbar>
89+
</ion-footer>
90+
</div>
91+
</ion-app>
92+
</body>
93+
</html>

core/src/components/header/test/fade/index.html

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,6 @@
6666
</ion-toolbar>
6767
</ion-header>
6868
<ion-content fullscreen="true">
69-
<ion-header collapse="condense">
70-
<ion-toolbar>
71-
<ion-title size="large">Mailboxes</ion-title>
72-
</ion-toolbar>
73-
</ion-header>
7469
<div class="grid ion-padding">
7570
<div class="grid-item red"></div>
7671
<div class="grid-item green"></div>

0 commit comments

Comments
 (0)