Skip to content

Commit

Permalink
chore(git): update next from main (#29982)
Browse files Browse the repository at this point in the history
  • Loading branch information
brandyscarney authored Oct 30, 2024
2 parents 4ddc053 + 379587d commit 51cb777
Show file tree
Hide file tree
Showing 40 changed files with 447 additions and 119 deletions.
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,23 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

## [8.3.4](https://github.com/ionic-team/ionic-framework/compare/v8.3.3...v8.3.4) (2024-10-30)


### Bug Fixes

* **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)
* **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)
* **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))
* **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)
* **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)
* **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)
* **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)





## [8.3.3](https://github.com/ionic-team/ionic-framework/compare/v8.3.2...v8.3.3) (2024-10-16)


Expand Down
15 changes: 15 additions & 0 deletions core/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,21 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.

## [8.3.4](https://github.com/ionic-team/ionic-framework/compare/v8.3.3...v8.3.4) (2024-10-30)


### Bug Fixes

* **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)
* **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))
* **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)
* **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)
* **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)





## [8.3.3](https://github.com/ionic-team/ionic-framework/compare/v8.3.2...v8.3.3) (2024-10-16)

**Note:** Version bump only for package @ionic/core
Expand Down
4 changes: 2 additions & 2 deletions core/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@ionic/core",
"version": "8.3.3",
"version": "8.3.4",
"description": "Base components for Ionic",
"keywords": [
"ionic",
Expand Down
4 changes: 2 additions & 2 deletions core/src/components/action-sheet/action-sheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
>
<ion-backdrop tappable={this.backdropDismiss} />

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

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

<div tabindex="0"></div>
<div tabindex="0" aria-hidden="true"></div>
</Host>
);
}
Expand Down
4 changes: 2 additions & 2 deletions core/src/components/alert/alert.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -759,7 +759,7 @@ export class Alert implements ComponentInterface, OverlayInterface {
>
<ion-backdrop tappable={this.backdropDismiss} />

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

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

<div tabindex="0"></div>
<div tabindex="0" aria-hidden="true"></div>
</Host>
);
}
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 0 additions & 1 deletion core/src/components/backdrop/backdrop.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ export class Backdrop implements ComponentInterface {
const theme = getIonTheme(this);
return (
<Host
tabindex="-1"
aria-hidden="true"
class={{
[theme]: true,
Expand Down
29 changes: 27 additions & 2 deletions core/src/components/input/input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ import { getCounterText } from './input.utils';
export class Input implements ComponentInterface {
private nativeInput?: HTMLInputElement;
private inputId = `ion-input-${inputIds++}`;
private helperTextId = `${this.inputId}-helper-text`;
private errorTextId = `${this.inputId}-error-text`;
private inheritedAttributes: Attributes = {};
private isComposing = false;
private slotMutationController?: SlotMutationController;
Expand Down Expand Up @@ -655,9 +657,30 @@ export class Input implements ComponentInterface {
* Renders the helper text or error text values
*/
private renderHintText() {
const { helperText, errorText } = this;
const { helperText, errorText, helperTextId, errorTextId } = this;

return [
<div id={helperTextId} class="helper-text">
{helperText}
</div>,
<div id={errorTextId} class="error-text">
{errorText}
</div>,
];
}

private getHintTextID(): string | undefined {
const { el, helperText, errorText, helperTextId, errorTextId } = this;

if (el.classList.contains('ion-touched') && el.classList.contains('ion-invalid') && errorText) {
return errorTextId;
}

if (helperText) {
return helperTextId;
}

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

private renderCounter() {
Expand Down Expand Up @@ -905,6 +928,8 @@ export class Input implements ComponentInterface {
onKeyDown={this.onKeydown}
onCompositionstart={this.onCompositionStart}
onCompositionend={this.onCompositionEnd}
aria-describedby={this.getHintTextID()}
aria-invalid={this.getHintTextID() === this.errorTextId}
{...this.inheritedAttributes}
/>
{clearInput && !readonly && !disabled && (
Expand Down
55 changes: 55 additions & 0 deletions core/src/components/input/test/bottom-content/input.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,19 @@ configs({ modes: ['md', 'ionic-md'], directions: ['ltr'] }).forEach(({ title, sc
await expect(helperText).toHaveText('my helper');
await expect(errorText).toBeHidden();
});
test('input should have an aria-describedby attribute when helper text is present', async ({ page }) => {
await page.setContent(
`<ion-input helper-text="my helper" error-text="my error" label="my input"></ion-input>`,
config
);

const input = page.locator('ion-input input');
const helperText = page.locator('ion-input .helper-text');
const helperTextId = await helperText.getAttribute('id');
const ariaDescribedBy = await input.getAttribute('aria-describedby');

expect(ariaDescribedBy).toBe(helperTextId);
});
test('error text should be visible when input is invalid', async ({ page }) => {
await page.setContent(
`<ion-input class="ion-invalid ion-touched" helper-text="my helper" error-text="my error" label="my input"></ion-input>`,
Expand Down Expand Up @@ -122,6 +135,48 @@ configs({ modes: ['md', 'ionic-md'], directions: ['ltr'] }).forEach(({ title, sc
const bottomEl = page.locator('ion-input .input-bottom');
await expect(bottomEl).toHaveScreenshot(screenshot(`input-error-custom-color`));
});
test('input should have an aria-describedby attribute when error text is present', async ({ page }) => {
await page.setContent(
`<ion-input class="ion-invalid ion-touched" helper-text="my helper" error-text="my error" label="my input"></ion-input>`,
config
);

const input = page.locator('ion-input input');
const errorText = page.locator('ion-input .error-text');
const errorTextId = await errorText.getAttribute('id');
const ariaDescribedBy = await input.getAttribute('aria-describedby');

expect(ariaDescribedBy).toBe(errorTextId);
});
test('input should have aria-invalid attribute when input is invalid', async ({ page }) => {
await page.setContent(
`<ion-input class="ion-invalid ion-touched" helper-text="my helper" error-text="my error" label="my input"></ion-input>`,
config
);

const input = page.locator('ion-input input');

await expect(input).toHaveAttribute('aria-invalid');
});
test('input should not have aria-invalid attribute when input is valid', async ({ page }) => {
await page.setContent(
`<ion-input helper-text="my helper" error-text="my error" label="my input"></ion-input>`,
config
);

const input = page.locator('ion-input input');

await expect(input).not.toHaveAttribute('aria-invalid');
});
test('input should not have aria-describedby attribute when no hint or error text is present', async ({
page,
}) => {
await page.setContent(`<ion-input label="my input"></ion-input>`, config);

const input = page.locator('ion-input input');

await expect(input).not.toHaveAttribute('aria-describedby');
});
});
test.describe('input: hint text rendering', () => {
test.describe('regular inputs', () => {
Expand Down
4 changes: 2 additions & 2 deletions core/src/components/loading/loading.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ export class Loading implements ComponentInterface, OverlayInterface {
>
<ion-backdrop visible={this.showBackdrop} tappable={this.backdropDismiss} />

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

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

<div tabindex="0"></div>
<div tabindex="0" aria-hidden="true"></div>
</Host>
);
}
Expand Down
4 changes: 2 additions & 2 deletions core/src/components/picker-legacy/picker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ export class Picker implements ComponentInterface, OverlayInterface {
>
<ion-backdrop visible={this.showBackdrop} tappable={this.backdropDismiss}></ion-backdrop>

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

<div class="picker-wrapper ion-overlay-wrapper" role="dialog">
<div class="picker-toolbar">
Expand All @@ -396,7 +396,7 @@ export class Picker implements ComponentInterface, OverlayInterface {
</div>
</div>

<div tabindex="0"></div>
<div tabindex="0" aria-hidden="true"></div>
</Host>
);
}
Expand Down
55 changes: 55 additions & 0 deletions core/src/components/textarea/test/bottom-content/textarea.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,19 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, screenshot, co
await expect(helperText).toHaveText('my helper');
await expect(errorText).toBeHidden();
});
test('textarea should have an aria-describedby attribute when helper text is present', async ({ page }) => {
await page.setContent(
`<ion-textarea helper-text="my helper" error-text="my error" label="my textarea"></ion-textarea>`,
config
);

const textarea = page.locator('ion-textarea textarea');
const helperText = page.locator('ion-textarea .helper-text');
const helperTextId = await helperText.getAttribute('id');
const ariaDescribedBy = await textarea.getAttribute('aria-describedby');

expect(ariaDescribedBy).toBe(helperTextId);
});
test('error text should be visible when textarea is invalid', async ({ page }) => {
await page.setContent(
`<ion-textarea class="ion-invalid ion-touched" helper-text="my helper" error-text="my error" label="my textarea"></ion-textarea>`,
Expand Down Expand Up @@ -55,6 +68,48 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, screenshot, co
const errorText = page.locator('ion-textarea .error-text');
await expect(errorText).toHaveScreenshot(screenshot(`textarea-error-custom-color`));
});
test('textarea should have an aria-describedby attribute when error text is present', async ({ page }) => {
await page.setContent(
`<ion-textarea class="ion-invalid ion-touched" helper-text="my helper" error-text="my error" label="my textarea"></ion-textarea>`,
config
);

const textarea = page.locator('ion-textarea textarea');
const errorText = page.locator('ion-textarea .error-text');
const errorTextId = await errorText.getAttribute('id');
const ariaDescribedBy = await textarea.getAttribute('aria-describedby');

expect(ariaDescribedBy).toBe(errorTextId);
});
test('textarea should have aria-invalid attribute when input is invalid', async ({ page }) => {
await page.setContent(
`<ion-textarea class="ion-invalid ion-touched" helper-text="my helper" error-text="my error" label="my textarea"></ion-textarea>`,
config
);

const textarea = page.locator('ion-textarea textarea');

await expect(textarea).toHaveAttribute('aria-invalid');
});
test('textarea should not have aria-invalid attribute when input is valid', async ({ page }) => {
await page.setContent(
`<ion-textarea helper-text="my helper" error-text="my error" label="my textarea"></ion-textarea>`,
config
);

const textarea = page.locator('ion-textarea textarea');

await expect(textarea).not.toHaveAttribute('aria-invalid');
});
test('textarea should not have aria-describedby attribute when no hint or error text is present', async ({
page,
}) => {
await page.setContent(`<ion-textarea label="my textarea"></ion-textarea>`, config);

const textarea = page.locator('ion-textarea textarea');

await expect(textarea).not.toHaveAttribute('aria-describedby');
});
});
test.describe('textarea: hint text rendering', () => {
test.describe('regular textareas', () => {
Expand Down
29 changes: 27 additions & 2 deletions core/src/components/textarea/textarea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ import type { TextareaChangeEventDetail, TextareaInputEventDetail } from './text
export class Textarea implements ComponentInterface {
private nativeInput?: HTMLTextAreaElement;
private inputId = `ion-textarea-${textareaIds++}`;
private helperTextId = `${this.inputId}-helper-text`;
private errorTextId = `${this.inputId}-error-text`;
/**
* `true` if the textarea was cleared as a result of the user typing
* with `clearOnEdit` enabled.
Expand Down Expand Up @@ -601,9 +603,30 @@ export class Textarea implements ComponentInterface {
* Renders the helper text or error text values
*/
private renderHintText() {
const { helperText, errorText } = this;
const { helperText, errorText, helperTextId, errorTextId } = this;

return [
<div id={helperTextId} class="helper-text">
{helperText}
</div>,
<div id={errorTextId} class="error-text">
{errorText}
</div>,
];
}

private getHintTextID(): string | undefined {
const { el, helperText, errorText, helperTextId, errorTextId } = this;

if (el.classList.contains('ion-touched') && el.classList.contains('ion-invalid') && errorText) {
return errorTextId;
}

if (helperText) {
return helperTextId;
}

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

private renderCounter() {
Expand Down Expand Up @@ -742,6 +765,8 @@ export class Textarea implements ComponentInterface {
onBlur={this.onBlur}
onFocus={this.onFocus}
onKeyDown={this.onKeyDown}
aria-describedby={this.getHintTextID()}
aria-invalid={this.getHintTextID() === this.errorTextId}
{...this.inheritedAttributes}
>
{value}
Expand Down
Loading

0 comments on commit 51cb777

Please sign in to comment.