mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
fix(chips): form field label pointing to non-existing elements (#9908)
Currently when a `mat-chip-list` is inside of a form field, the label of the form field has a `for` and `aria-owns` attributes that point to a non-existing element, because the `id` from the chip list isn't being used anywhere. These changes switch it to point to the chip list input, if it has any, otherwise it'll fall back to pointing to the chip list itself.
This commit is contained in:
committed by
Jeremy Elbourn
parent
c42549ee29
commit
9337ae181f
@@ -51,6 +51,10 @@ describe('MatChipInput', () => {
|
||||
chipInputDirective._keydown(ENTER_EVENT);
|
||||
expect(testChipInput.add).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should have a default id', () => {
|
||||
expect(inputNativeElement.getAttribute('id')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('[addOnBlur]', () => {
|
||||
|
||||
@@ -21,6 +21,9 @@ export interface MatChipInputEvent {
|
||||
value: string;
|
||||
}
|
||||
|
||||
// Increasing integer for generating unique ids.
|
||||
let nextUniqueId = 0;
|
||||
|
||||
/**
|
||||
* Directive that adds chip-specific behaviors to an input element inside `<mat-form-field>`.
|
||||
* May be placed inside or outside of an `<mat-chip-list>`.
|
||||
@@ -34,6 +37,7 @@ export interface MatChipInputEvent {
|
||||
'(blur)': '_blur()',
|
||||
'(focus)': '_focus()',
|
||||
'(input)': '_onInput()',
|
||||
'[id]': 'id',
|
||||
}
|
||||
})
|
||||
export class MatChipInput {
|
||||
@@ -73,6 +77,9 @@ export class MatChipInput {
|
||||
/** The input's placeholder text. */
|
||||
@Input() placeholder: string = '';
|
||||
|
||||
/** Unique id for the input. */
|
||||
@Input() id: string = `mat-chip-list-input-${nextUniqueId++}`;
|
||||
|
||||
/** Whether the input is empty. */
|
||||
get empty(): boolean { return !this._inputElement.value; }
|
||||
|
||||
|
||||
@@ -377,6 +377,17 @@ describe('MatChipList', () => {
|
||||
subscription.unsubscribe();
|
||||
});
|
||||
|
||||
it('should point the label id to the chip input', () => {
|
||||
const label = fixture.nativeElement.querySelector('label');
|
||||
const input = fixture.nativeElement.querySelector('input');
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(label.getAttribute('for')).toBeTruthy();
|
||||
expect(label.getAttribute('for')).toBe(input.getAttribute('id'));
|
||||
expect(label.getAttribute('aria-owns')).toBe(input.getAttribute('id'));
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('selection logic', () => {
|
||||
@@ -1054,12 +1065,13 @@ class StandardChipList {
|
||||
@Component({
|
||||
template: `
|
||||
<mat-form-field>
|
||||
<mat-label>Add a chip</mat-label>
|
||||
<mat-chip-list #chipList>
|
||||
<mat-chip>Chip 1</mat-chip>
|
||||
<mat-chip>Chip 1</mat-chip>
|
||||
<mat-chip>Chip 1</mat-chip>
|
||||
</mat-chip-list>
|
||||
<input matInput name="test" [matChipInputFor]="chipList"/>
|
||||
<input name="test" [matChipInputFor]="chipList"/>
|
||||
</mat-form-field>
|
||||
`
|
||||
})
|
||||
|
||||
@@ -87,7 +87,8 @@ export class MatChipListChange {
|
||||
'class': 'mat-chip-list',
|
||||
'(focus)': 'focus()',
|
||||
'(blur)': '_blur()',
|
||||
'(keydown)': '_keydown($event)'
|
||||
'(keydown)': '_keydown($event)',
|
||||
'[id]': '_uid',
|
||||
},
|
||||
providers: [{provide: MatFormFieldControl, useExisting: MatChipList}],
|
||||
styleUrls: ['chips.css'],
|
||||
@@ -130,7 +131,7 @@ export class MatChipList extends _MatChipListMixinBase implements MatFormFieldCo
|
||||
protected _chipInput: MatChipInput;
|
||||
|
||||
/** Uid of the chip list */
|
||||
protected _uid: string = `mat-chip-list-${nextUniqueId++}`;
|
||||
_uid: string = `mat-chip-list-${nextUniqueId++}`;
|
||||
|
||||
/** The aria-describedby attribute on the chip list for improved a11y. */
|
||||
_ariaDescribedby: string;
|
||||
@@ -206,13 +207,9 @@ export class MatChipList extends _MatChipListMixinBase implements MatFormFieldCo
|
||||
* Implemented as part of MatFormFieldControl.
|
||||
* @docs-private
|
||||
*/
|
||||
@Input()
|
||||
get id(): string { return this._id || this._uid; }
|
||||
set id(value: string) {
|
||||
this._id = value;
|
||||
this.stateChanges.next();
|
||||
get id(): string {
|
||||
return this._chipInput ? this._chipInput.id : this._uid;
|
||||
}
|
||||
protected _id: string;
|
||||
|
||||
/**
|
||||
* Implemented as part of MatFormFieldControl.
|
||||
|
||||
Reference in New Issue
Block a user