Skip to content

Commit 0bba6ea

Browse files
ByzantineFailureandrewseguin
authored andcommitted
fix(material/input): Do not set aria-invalid on required empty matInputs (#22802)
Updates the logic for setting `aria-invalid` on `matInput` to not set the attribute at all if the input is `required` and has no value. Prior to this PR `matInput` sets `aria-invalid="false"` for any empty `matInput`, including `required` ones. This suppresses screen readers' announcement to users that such inputs are in an invalid state. Fixes #22777 (cherry picked from commit d185294)
1 parent 046461b commit 0bba6ea

File tree

4 files changed

+6
-6
lines changed

4 files changed

+6
-6
lines changed

src/material-experimental/mdc-input/input.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1070,7 +1070,7 @@ describe('MatMdcInput with forms', () => {
10701070
expect(describedBy).toBe(errorIds);
10711071
}));
10721072

1073-
it('should not set `aria-invalid` to true if the input is empty', fakeAsync(() => {
1073+
it('should set `aria-invalid` to true if the input is empty', fakeAsync(() => {
10741074
// Submit the form since it's the one that triggers the default error state matcher.
10751075
dispatchFakeEvent(fixture.nativeElement.querySelector('form'), 'submit');
10761076
fixture.detectChanges();
@@ -1079,7 +1079,7 @@ describe('MatMdcInput with forms', () => {
10791079
expect(testComponent.formControl.invalid).toBe(true, 'Expected form control to be invalid');
10801080
expect(inputEl.value).toBeFalsy();
10811081
expect(inputEl.getAttribute('aria-invalid'))
1082-
.toBe('false', 'Expected aria-invalid to be set to "false".');
1082+
.toBe('true', 'Expected aria-invalid to be set to "true"');
10831083

10841084
inputEl.value = 'not valid';
10851085
fixture.detectChanges();

src/material-experimental/mdc-input/input.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ import {MatInput as BaseMatInput} from '@angular/material/input';
3535
'[attr.readonly]': 'readonly && !_isNativeSelect || null',
3636
// Only mark the input as invalid for assistive technology if it has a value since the
3737
// state usually overlaps with `aria-required` when the input is empty and can be redundant.
38-
'[attr.aria-invalid]': 'errorState && !empty',
38+
'[attr.aria-invalid]': '(empty && required) ? null : errorState',
3939
'[attr.aria-required]': 'required',
4040
},
4141
providers: [{provide: MatFormFieldControl, useExisting: MatInput}],

src/material/input/input.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1219,7 +1219,7 @@ describe('MatInput with forms', () => {
12191219
expect(describedBy).toBe(errorIds);
12201220
}));
12211221

1222-
it('should not set `aria-invalid` to true if the input is empty', fakeAsync(() => {
1222+
it('should set `aria-invalid` to true if the input is empty', fakeAsync(() => {
12231223
// Submit the form since it's the one that triggers the default error state matcher.
12241224
dispatchFakeEvent(fixture.nativeElement.querySelector('form'), 'submit');
12251225
fixture.detectChanges();
@@ -1228,7 +1228,7 @@ describe('MatInput with forms', () => {
12281228
expect(testComponent.formControl.invalid).toBe(true, 'Expected form control to be invalid');
12291229
expect(inputEl.value).toBeFalsy();
12301230
expect(inputEl.getAttribute('aria-invalid'))
1231-
.toBe('false', 'Expected aria-invalid to be set to "false".');
1231+
.toBe('true', 'Expected aria-invalid to be set to "true".');
12321232

12331233
inputEl.value = 'not valid';
12341234
fixture.detectChanges();

src/material/input/input.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ const _MatInputMixinBase: CanUpdateErrorStateCtor & typeof MatInputBase =
8686
'[attr.readonly]': 'readonly && !_isNativeSelect || null',
8787
// Only mark the input as invalid for assistive technology if it has a value since the
8888
// state usually overlaps with `aria-required` when the input is empty and can be redundant.
89-
'[attr.aria-invalid]': 'errorState && !empty',
89+
'[attr.aria-invalid]': '(empty && required) ? null : errorState',
9090
'[attr.aria-required]': 'required',
9191
},
9292
providers: [{provide: MatFormFieldControl, useExisting: MatInput}],

0 commit comments

Comments
 (0)