Skip to content

Commit 8d2d176

Browse files
committed
Merge branch 'main' into chore-update-next-from-main
2 parents 4ddc053 + 6dc52d2 commit 8d2d176

39 files changed

+447
-119
lines changed

CHANGELOG.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,23 @@
33
All notable changes to this project will be documented in this file.
44
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
55

6+
## [8.3.4](https://github.com/ionic-team/ionic-framework/compare/v8.3.3...v8.3.4) (2024-10-30)
7+
8+
9+
### Bug Fixes
10+
11+
* **angular:** add missing 'compareWith' input to standalone ion-radio-group ([#29870](https://github.com/ionic-team/ionic-framework/issues/29870)) ([47ba703](https://github.com/ionic-team/ionic-framework/commit/47ba703a57d1ca506f943f6b790d0bf7583d79cb)), closes [#29826](https://github.com/ionic-team/ionic-framework/issues/29826)
12+
* **backdrop:** remove tabindex for improved accessibility ([#29956](https://github.com/ionic-team/ionic-framework/issues/29956)) ([7294e96](https://github.com/ionic-team/ionic-framework/commit/7294e969bb913692eaf28e54860614f445132713)), closes [#29773](https://github.com/ionic-team/ionic-framework/issues/29773)
13+
* **input, textarea:** ensure screen readers announce helper and error text when focused ([#29958](https://github.com/ionic-team/ionic-framework/issues/29958)) ([5a73145](https://github.com/ionic-team/ionic-framework/commit/5a7314553a8def87bd19275640c92dd72a6ef1a4))
14+
* **overlay:** hide from screen readers while animating ([#29951](https://github.com/ionic-team/ionic-framework/issues/29951)) ([cb60073](https://github.com/ionic-team/ionic-framework/commit/cb6007363a8d42b5f126945427c2bfc3d7209c21)), closes [#29857](https://github.com/ionic-team/ionic-framework/issues/29857)
15+
* **overlays:** do not hide root when toast appears ([#29962](https://github.com/ionic-team/ionic-framework/issues/29962)) ([322d7c9](https://github.com/ionic-team/ionic-framework/commit/322d7c98cf6613df0b0db3f119e3f892e6a17e7b)), closes [#29773](https://github.com/ionic-team/ionic-framework/issues/29773)
16+
* **overlays:** hide the focus trap div from screen readers ([#29970](https://github.com/ionic-team/ionic-framework/issues/29970)) ([c3b58f1](https://github.com/ionic-team/ionic-framework/commit/c3b58f1620bcb74db43e3983ef570b7b982abd83)), closes [#29858](https://github.com/ionic-team/ionic-framework/issues/29858)
17+
* **vue:** incorrect view rendered when using router.go(-n) ([#29877](https://github.com/ionic-team/ionic-framework/issues/29877)) ([e32fbe0](https://github.com/ionic-team/ionic-framework/commit/e32fbe02102fe80db29f73c26496a40852032354)), closes [#28201](https://github.com/ionic-team/ionic-framework/issues/28201) [#28201](https://github.com/ionic-team/ionic-framework/issues/28201) [#29847](https://github.com/ionic-team/ionic-framework/issues/29847)
18+
19+
20+
21+
22+
623
## [8.3.3](https://github.com/ionic-team/ionic-framework/compare/v8.3.2...v8.3.3) (2024-10-16)
724

825

core/CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,21 @@
33
All notable changes to this project will be documented in this file.
44
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
55

6+
## [8.3.4](https://github.com/ionic-team/ionic-framework/compare/v8.3.3...v8.3.4) (2024-10-30)
7+
8+
9+
### Bug Fixes
10+
11+
* **backdrop:** remove tabindex for improved accessibility ([#29956](https://github.com/ionic-team/ionic-framework/issues/29956)) ([7294e96](https://github.com/ionic-team/ionic-framework/commit/7294e969bb913692eaf28e54860614f445132713)), closes [#29773](https://github.com/ionic-team/ionic-framework/issues/29773)
12+
* **input, textarea:** ensure screen readers announce helper and error text when focused ([#29958](https://github.com/ionic-team/ionic-framework/issues/29958)) ([5a73145](https://github.com/ionic-team/ionic-framework/commit/5a7314553a8def87bd19275640c92dd72a6ef1a4))
13+
* **overlay:** hide from screen readers while animating ([#29951](https://github.com/ionic-team/ionic-framework/issues/29951)) ([cb60073](https://github.com/ionic-team/ionic-framework/commit/cb6007363a8d42b5f126945427c2bfc3d7209c21)), closes [#29857](https://github.com/ionic-team/ionic-framework/issues/29857)
14+
* **overlays:** do not hide root when toast appears ([#29962](https://github.com/ionic-team/ionic-framework/issues/29962)) ([322d7c9](https://github.com/ionic-team/ionic-framework/commit/322d7c98cf6613df0b0db3f119e3f892e6a17e7b)), closes [#29773](https://github.com/ionic-team/ionic-framework/issues/29773)
15+
* **overlays:** hide the focus trap div from screen readers ([#29970](https://github.com/ionic-team/ionic-framework/issues/29970)) ([c3b58f1](https://github.com/ionic-team/ionic-framework/commit/c3b58f1620bcb74db43e3983ef570b7b982abd83)), closes [#29858](https://github.com/ionic-team/ionic-framework/issues/29858)
16+
17+
18+
19+
20+
621
## [8.3.3](https://github.com/ionic-team/ionic-framework/compare/v8.3.2...v8.3.3) (2024-10-16)
722

823
**Note:** Version bump only for package @ionic/core

core/package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

core/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@ionic/core",
3-
"version": "8.3.3",
3+
"version": "8.3.4",
44
"description": "Base components for Ionic",
55
"keywords": [
66
"ionic",

core/src/components/action-sheet/action-sheet.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
388388
>
389389
<ion-backdrop tappable={this.backdropDismiss} />
390390

391-
<div tabindex="0"></div>
391+
<div tabindex="0" aria-hidden="true"></div>
392392

393393
<div class="action-sheet-wrapper ion-overlay-wrapper" ref={(el) => (this.wrapperEl = el)}>
394394
<div class="action-sheet-container">
@@ -449,7 +449,7 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
449449
</div>
450450
</div>
451451

452-
<div tabindex="0"></div>
452+
<div tabindex="0" aria-hidden="true"></div>
453453
</Host>
454454
);
455455
}

core/src/components/alert/alert.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -759,7 +759,7 @@ export class Alert implements ComponentInterface, OverlayInterface {
759759
>
760760
<ion-backdrop tappable={this.backdropDismiss} />
761761

762-
<div tabindex="0"></div>
762+
<div tabindex="0" aria-hidden="true"></div>
763763

764764
<div class="alert-wrapper ion-overlay-wrapper" ref={(el) => (this.wrapperEl = el)}>
765765
<div class="alert-head">
@@ -781,7 +781,7 @@ export class Alert implements ComponentInterface, OverlayInterface {
781781
{this.renderAlertButtons()}
782782
</div>
783783

784-
<div tabindex="0"></div>
784+
<div tabindex="0" aria-hidden="true"></div>
785785
</Host>
786786
);
787787
}

core/src/components/backdrop/backdrop.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ export class Backdrop implements ComponentInterface {
5656
const theme = getIonTheme(this);
5757
return (
5858
<Host
59-
tabindex="-1"
6059
aria-hidden="true"
6160
class={{
6261
[theme]: true,

core/src/components/input/input.tsx

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ import { getCounterText } from './input.utils';
3838
export class Input implements ComponentInterface {
3939
private nativeInput?: HTMLInputElement;
4040
private inputId = `ion-input-${inputIds++}`;
41+
private helperTextId = `${this.inputId}-helper-text`;
42+
private errorTextId = `${this.inputId}-error-text`;
4143
private inheritedAttributes: Attributes = {};
4244
private isComposing = false;
4345
private slotMutationController?: SlotMutationController;
@@ -655,9 +657,30 @@ export class Input implements ComponentInterface {
655657
* Renders the helper text or error text values
656658
*/
657659
private renderHintText() {
658-
const { helperText, errorText } = this;
660+
const { helperText, errorText, helperTextId, errorTextId } = this;
661+
662+
return [
663+
<div id={helperTextId} class="helper-text">
664+
{helperText}
665+
</div>,
666+
<div id={errorTextId} class="error-text">
667+
{errorText}
668+
</div>,
669+
];
670+
}
671+
672+
private getHintTextID(): string | undefined {
673+
const { el, helperText, errorText, helperTextId, errorTextId } = this;
674+
675+
if (el.classList.contains('ion-touched') && el.classList.contains('ion-invalid') && errorText) {
676+
return errorTextId;
677+
}
678+
679+
if (helperText) {
680+
return helperTextId;
681+
}
659682

660-
return [<div class="helper-text">{helperText}</div>, <div class="error-text">{errorText}</div>];
683+
return undefined;
661684
}
662685

663686
private renderCounter() {
@@ -905,6 +928,8 @@ export class Input implements ComponentInterface {
905928
onKeyDown={this.onKeydown}
906929
onCompositionstart={this.onCompositionStart}
907930
onCompositionend={this.onCompositionEnd}
931+
aria-describedby={this.getHintTextID()}
932+
aria-invalid={this.getHintTextID() === this.errorTextId}
908933
{...this.inheritedAttributes}
909934
/>
910935
{clearInput && !readonly && !disabled && (

core/src/components/input/test/bottom-content/input.e2e.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,19 @@ configs({ modes: ['md', 'ionic-md'], directions: ['ltr'] }).forEach(({ title, sc
9393
await expect(helperText).toHaveText('my helper');
9494
await expect(errorText).toBeHidden();
9595
});
96+
test('input should have an aria-describedby attribute when helper text is present', async ({ page }) => {
97+
await page.setContent(
98+
`<ion-input helper-text="my helper" error-text="my error" label="my input"></ion-input>`,
99+
config
100+
);
101+
102+
const input = page.locator('ion-input input');
103+
const helperText = page.locator('ion-input .helper-text');
104+
const helperTextId = await helperText.getAttribute('id');
105+
const ariaDescribedBy = await input.getAttribute('aria-describedby');
106+
107+
expect(ariaDescribedBy).toBe(helperTextId);
108+
});
96109
test('error text should be visible when input is invalid', async ({ page }) => {
97110
await page.setContent(
98111
`<ion-input class="ion-invalid ion-touched" helper-text="my helper" error-text="my error" label="my input"></ion-input>`,
@@ -122,6 +135,48 @@ configs({ modes: ['md', 'ionic-md'], directions: ['ltr'] }).forEach(({ title, sc
122135
const bottomEl = page.locator('ion-input .input-bottom');
123136
await expect(bottomEl).toHaveScreenshot(screenshot(`input-error-custom-color`));
124137
});
138+
test('input should have an aria-describedby attribute when error text is present', async ({ page }) => {
139+
await page.setContent(
140+
`<ion-input class="ion-invalid ion-touched" helper-text="my helper" error-text="my error" label="my input"></ion-input>`,
141+
config
142+
);
143+
144+
const input = page.locator('ion-input input');
145+
const errorText = page.locator('ion-input .error-text');
146+
const errorTextId = await errorText.getAttribute('id');
147+
const ariaDescribedBy = await input.getAttribute('aria-describedby');
148+
149+
expect(ariaDescribedBy).toBe(errorTextId);
150+
});
151+
test('input should have aria-invalid attribute when input is invalid', async ({ page }) => {
152+
await page.setContent(
153+
`<ion-input class="ion-invalid ion-touched" helper-text="my helper" error-text="my error" label="my input"></ion-input>`,
154+
config
155+
);
156+
157+
const input = page.locator('ion-input input');
158+
159+
await expect(input).toHaveAttribute('aria-invalid');
160+
});
161+
test('input should not have aria-invalid attribute when input is valid', async ({ page }) => {
162+
await page.setContent(
163+
`<ion-input helper-text="my helper" error-text="my error" label="my input"></ion-input>`,
164+
config
165+
);
166+
167+
const input = page.locator('ion-input input');
168+
169+
await expect(input).not.toHaveAttribute('aria-invalid');
170+
});
171+
test('input should not have aria-describedby attribute when no hint or error text is present', async ({
172+
page,
173+
}) => {
174+
await page.setContent(`<ion-input label="my input"></ion-input>`, config);
175+
176+
const input = page.locator('ion-input input');
177+
178+
await expect(input).not.toHaveAttribute('aria-describedby');
179+
});
125180
});
126181
test.describe('input: hint text rendering', () => {
127182
test.describe('regular inputs', () => {

core/src/components/loading/loading.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ export class Loading implements ComponentInterface, OverlayInterface {
358358
>
359359
<ion-backdrop visible={this.showBackdrop} tappable={this.backdropDismiss} />
360360

361-
<div tabindex="0"></div>
361+
<div tabindex="0" aria-hidden="true"></div>
362362

363363
<div class="loading-wrapper ion-overlay-wrapper">
364364
{spinner && (
@@ -370,7 +370,7 @@ export class Loading implements ComponentInterface, OverlayInterface {
370370
{message !== undefined && this.renderLoadingMessage(msgId)}
371371
</div>
372372

373-
<div tabindex="0"></div>
373+
<div tabindex="0" aria-hidden="true"></div>
374374
</Host>
375375
);
376376
}

0 commit comments

Comments
 (0)