Skip to content

Commit d185294

Browse files
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
1 parent e143b27 commit d185294

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
@@ -1081,7 +1081,7 @@ describe('MatMdcInput with forms', () => {
10811081
expect(describedBy).toBe(errorIds);
10821082
}));
10831083

1084-
it('should not set `aria-invalid` to true if the input is empty', fakeAsync(() => {
1084+
it('should set `aria-invalid` to true if the input is empty', fakeAsync(() => {
10851085
// Submit the form since it's the one that triggers the default error state matcher.
10861086
dispatchFakeEvent(fixture.nativeElement.querySelector('form'), 'submit');
10871087
fixture.detectChanges();
@@ -1090,7 +1090,7 @@ describe('MatMdcInput with forms', () => {
10901090
expect(testComponent.formControl.invalid).toBe(true, 'Expected form control to be invalid');
10911091
expect(inputEl.value).toBeFalsy();
10921092
expect(inputEl.getAttribute('aria-invalid'))
1093-
.toBe('false', 'Expected aria-invalid to be set to "false".');
1093+
.toBe('true', 'Expected aria-invalid to be set to "true"');
10941094

10951095
inputEl.value = 'not valid';
10961096
fixture.detectChanges();

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ import {MatInput as BaseMatInput} from '@angular/material/input';
3939
'[attr.readonly]': 'readonly && !_isNativeSelect || null',
4040
// Only mark the input as invalid for assistive technology if it has a value since the
4141
// state usually overlaps with `aria-required` when the input is empty and can be redundant.
42-
'[attr.aria-invalid]': 'errorState && !empty',
42+
'[attr.aria-invalid]': '(empty && required) ? null : errorState',
4343
'[attr.aria-required]': 'required',
4444
},
4545
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
@@ -83,7 +83,7 @@ const _MatInputBase = mixinErrorState(class {
8383
'[attr.readonly]': 'readonly && !_isNativeSelect || null',
8484
// Only mark the input as invalid for assistive technology if it has a value since the
8585
// state usually overlaps with `aria-required` when the input is empty and can be redundant.
86-
'[attr.aria-invalid]': 'errorState && !empty',
86+
'[attr.aria-invalid]': '(empty && required) ? null : errorState',
8787
'[attr.aria-required]': 'required',
8888
},
8989
providers: [{provide: MatFormFieldControl, useExisting: MatInput}],

0 commit comments

Comments
 (0)