Skip to content

Commit 19d63f6

Browse files
authored
fix(a11y): improve support for ids with special characters when getting label element (#22680)
resolves #22678
1 parent 343f855 commit 19d63f6

File tree

2 files changed

+104
-3
lines changed

2 files changed

+104
-3
lines changed

core/src/utils/helpers.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ export const getAriaLabel = (componentEl: HTMLElement, inputId: string): { label
133133
: inputId + '-lbl';
134134

135135
let label = labelledBy !== null && labelledBy.trim() !== ''
136-
? document.querySelector(`#${labelledBy}`)
136+
? document.getElementById(labelledBy)
137137
: findItemLabel(componentEl);
138138

139139
if (label) {
@@ -147,10 +147,15 @@ export const getAriaLabel = (componentEl: HTMLElement, inputId: string): { label
147147
// if there is no label, check to see if the user has provided
148148
// one by setting an id on the component and using the label element
149149
} else if (componentId.trim() !== '') {
150-
label = document.querySelector(`label[for=${componentId}]`);
150+
label = document.querySelector(`label[for="${componentId}"]`);
151151

152152
if (label) {
153-
label.id = labelId = `${componentId}-lbl`;
153+
if (label.id !== '') {
154+
labelId = label.id;
155+
} else {
156+
label.id = labelId = `${componentId}-lbl`;
157+
}
158+
154159
labelText = label.textContent;
155160
}
156161
}

core/src/utils/test/aria.spec.ts

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import { newSpecPage } from '@stencil/core/testing';
2+
import { getAriaLabel } from '../helpers';
3+
import { Item } from '../../components/item/item.tsx';
4+
import { Label } from '../../components/label/label.tsx';
5+
import { Toggle } from '../../components/toggle/toggle.tsx';
6+
7+
describe('getAriaLabel()', () => {
8+
it('should correctly link component to label', async () => {
9+
const page = await newSpecPage({
10+
components: [Item, Label, Toggle],
11+
html: `
12+
<ion-item>
13+
<ion-label>My Label</ion-label>
14+
<ion-toggle></ion-toggle>
15+
</ion-item>
16+
`
17+
});
18+
19+
const toggle = page.body.querySelector('ion-toggle');
20+
21+
const { label, labelId, labelText } = getAriaLabel(toggle, 'ion-tg-0');
22+
23+
expect(labelText).toEqual('My Label');
24+
expect(labelId).toEqual('ion-tg-0-lbl');
25+
expect(label).toEqual(page.body.querySelector('ion-label'));
26+
});
27+
28+
it('should correctly link component when using custom label', async () => {
29+
const page = await newSpecPage({
30+
components: [Toggle],
31+
html: `
32+
<div id="my-label">Hello World</div>
33+
<ion-toggle aria-labelledby="my-label"></ion-toggle>
34+
`
35+
});
36+
37+
const toggle = page.body.querySelector('ion-toggle');
38+
39+
const { label, labelId, labelText } = getAriaLabel(toggle, 'ion-tg-0');
40+
41+
expect(labelText).toEqual('Hello World');
42+
expect(labelId).toEqual('my-label');
43+
expect(label).toEqual(page.body.querySelector('#my-label'));
44+
});
45+
46+
it('should correctly link component when special characters are used', async () => {
47+
const page = await newSpecPage({
48+
components: [Toggle],
49+
html: `
50+
<div id="id.1">Hello World</div>
51+
<ion-toggle aria-labelledby="id.1"></ion-toggle>
52+
`
53+
});
54+
55+
const toggle = page.body.querySelector('ion-toggle');
56+
57+
const { label, labelId, labelText } = getAriaLabel(toggle, 'ion-tg-0');
58+
59+
expect(labelText).toEqual('Hello World');
60+
expect(labelId).toEqual('id.1');
61+
});
62+
63+
it('should only set the label id if one was not set already', async () => {
64+
const page = await newSpecPage({
65+
components: [Toggle],
66+
html: `
67+
<label id="my-id" for="id.1">Hello World</label>
68+
<ion-toggle id="id.1"></ion-toggle>
69+
`
70+
});
71+
72+
const toggle = page.body.querySelector('ion-toggle');
73+
74+
const { label, labelId, labelText } = getAriaLabel(toggle, 'ion-tg-0');
75+
76+
expect(labelText).toEqual('Hello World');
77+
expect(labelId).toEqual('my-id');
78+
});
79+
80+
it('should set label id', async () => {
81+
const page = await newSpecPage({
82+
components: [Toggle],
83+
html: `
84+
<label for="id.1">Hello World</label>
85+
<ion-toggle id="id.1"></ion-toggle>
86+
`
87+
});
88+
89+
const toggle = page.body.querySelector('ion-toggle');
90+
91+
const { label, labelId, labelText } = getAriaLabel(toggle, 'ion-tg-0');
92+
93+
expect(labelText).toEqual('Hello World');
94+
expect(labelId).toEqual('id.1-lbl');
95+
});
96+
});

0 commit comments

Comments
 (0)