Skip to content

Commit 82348df

Browse files
merge release-8.3.4 (#29981)
v8.3.4
2 parents 99fa7b0 + ffdaa3b commit 82348df

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
@@ -385,7 +385,7 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
385385
>
386386
<ion-backdrop tappable={this.backdropDismiss} />
387387

388-
<div tabindex="0"></div>
388+
<div tabindex="0" aria-hidden="true"></div>
389389

390390
<div class="action-sheet-wrapper ion-overlay-wrapper" ref={(el) => (this.wrapperEl = el)}>
391391
<div class="action-sheet-container">
@@ -446,7 +446,7 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
446446
</div>
447447
</div>
448448

449-
<div tabindex="0"></div>
449+
<div tabindex="0" aria-hidden="true"></div>
450450
</Host>
451451
);
452452
}

core/src/components/alert/alert.tsx

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

760-
<div tabindex="0"></div>
760+
<div tabindex="0" aria-hidden="true"></div>
761761

762762
<div class="alert-wrapper ion-overlay-wrapper" ref={(el) => (this.wrapperEl = el)}>
763763
<div class="alert-head">
@@ -779,7 +779,7 @@ export class Alert implements ComponentInterface, OverlayInterface {
779779
{this.renderAlertButtons()}
780780
</div>
781781

782-
<div tabindex="0"></div>
782+
<div tabindex="0" aria-hidden="true"></div>
783783
</Host>
784784
);
785785
}

core/src/components/backdrop/backdrop.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ export class Backdrop implements ComponentInterface {
5151
const mode = getIonMode(this);
5252
return (
5353
<Host
54-
tabindex="-1"
5554
aria-hidden="true"
5655
class={{
5756
[mode]: true,

core/src/components/input/input.tsx

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ import { getCounterText } from './input.utils';
3333
export class Input implements ComponentInterface {
3434
private nativeInput?: HTMLInputElement;
3535
private inputId = `ion-input-${inputIds++}`;
36+
private helperTextId = `${this.inputId}-helper-text`;
37+
private errorTextId = `${this.inputId}-error-text`;
3638
private inheritedAttributes: Attributes = {};
3739
private isComposing = false;
3840
private slotMutationController?: SlotMutationController;
@@ -573,9 +575,30 @@ export class Input implements ComponentInterface {
573575
* Renders the helper text or error text values
574576
*/
575577
private renderHintText() {
576-
const { helperText, errorText } = this;
578+
const { helperText, errorText, helperTextId, errorTextId } = this;
579+
580+
return [
581+
<div id={helperTextId} class="helper-text">
582+
{helperText}
583+
</div>,
584+
<div id={errorTextId} class="error-text">
585+
{errorText}
586+
</div>,
587+
];
588+
}
589+
590+
private getHintTextID(): string | undefined {
591+
const { el, helperText, errorText, helperTextId, errorTextId } = this;
592+
593+
if (el.classList.contains('ion-touched') && el.classList.contains('ion-invalid') && errorText) {
594+
return errorTextId;
595+
}
596+
597+
if (helperText) {
598+
return helperTextId;
599+
}
577600

578-
return [<div class="helper-text">{helperText}</div>, <div class="error-text">{errorText}</div>];
601+
return undefined;
579602
}
580603

581604
private renderCounter() {
@@ -777,6 +800,8 @@ export class Input implements ComponentInterface {
777800
onKeyDown={this.onKeydown}
778801
onCompositionstart={this.onCompositionStart}
779802
onCompositionend={this.onCompositionEnd}
803+
aria-describedby={this.getHintTextID()}
804+
aria-invalid={this.getHintTextID() === this.errorTextId}
780805
{...this.inheritedAttributes}
781806
/>
782807
{this.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
@@ -68,6 +68,19 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, screenshot, co
6868
await expect(helperText).toHaveText('my helper');
6969
await expect(errorText).toBeHidden();
7070
});
71+
test('input should have an aria-describedby attribute when helper text is present', async ({ page }) => {
72+
await page.setContent(
73+
`<ion-input helper-text="my helper" error-text="my error" label="my input"></ion-input>`,
74+
config
75+
);
76+
77+
const input = page.locator('ion-input input');
78+
const helperText = page.locator('ion-input .helper-text');
79+
const helperTextId = await helperText.getAttribute('id');
80+
const ariaDescribedBy = await input.getAttribute('aria-describedby');
81+
82+
expect(ariaDescribedBy).toBe(helperTextId);
83+
});
7184
test('error text should be visible when input is invalid', async ({ page }) => {
7285
await page.setContent(
7386
`<ion-input class="ion-invalid ion-touched" helper-text="my helper" error-text="my error" label="my input"></ion-input>`,
@@ -96,6 +109,48 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, screenshot, co
96109
const errorText = page.locator('ion-input .error-text');
97110
await expect(errorText).toHaveScreenshot(screenshot(`input-error-custom-color`));
98111
});
112+
test('input should have an aria-describedby attribute when error text is present', async ({ page }) => {
113+
await page.setContent(
114+
`<ion-input class="ion-invalid ion-touched" helper-text="my helper" error-text="my error" label="my input"></ion-input>`,
115+
config
116+
);
117+
118+
const input = page.locator('ion-input input');
119+
const errorText = page.locator('ion-input .error-text');
120+
const errorTextId = await errorText.getAttribute('id');
121+
const ariaDescribedBy = await input.getAttribute('aria-describedby');
122+
123+
expect(ariaDescribedBy).toBe(errorTextId);
124+
});
125+
test('input should have aria-invalid attribute when input is invalid', async ({ page }) => {
126+
await page.setContent(
127+
`<ion-input class="ion-invalid ion-touched" helper-text="my helper" error-text="my error" label="my input"></ion-input>`,
128+
config
129+
);
130+
131+
const input = page.locator('ion-input input');
132+
133+
await expect(input).toHaveAttribute('aria-invalid');
134+
});
135+
test('input should not have aria-invalid attribute when input is valid', async ({ page }) => {
136+
await page.setContent(
137+
`<ion-input helper-text="my helper" error-text="my error" label="my input"></ion-input>`,
138+
config
139+
);
140+
141+
const input = page.locator('ion-input input');
142+
143+
await expect(input).not.toHaveAttribute('aria-invalid');
144+
});
145+
test('input should not have aria-describedby attribute when no hint or error text is present', async ({
146+
page,
147+
}) => {
148+
await page.setContent(`<ion-input label="my input"></ion-input>`, config);
149+
150+
const input = page.locator('ion-input input');
151+
152+
await expect(input).not.toHaveAttribute('aria-describedby');
153+
});
99154
});
100155
test.describe('input: hint text rendering', () => {
101156
test.describe('regular inputs', () => {

core/src/components/loading/loading.tsx

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

359-
<div tabindex="0"></div>
359+
<div tabindex="0" aria-hidden="true"></div>
360360

361361
<div class="loading-wrapper ion-overlay-wrapper">
362362
{spinner && (
@@ -368,7 +368,7 @@ export class Loading implements ComponentInterface, OverlayInterface {
368368
{message !== undefined && this.renderLoadingMessage(msgId)}
369369
</div>
370370

371-
<div tabindex="0"></div>
371+
<div tabindex="0" aria-hidden="true"></div>
372372
</Host>
373373
);
374374
}

0 commit comments

Comments
 (0)