diff --git a/src/lib/chips/chip-input.spec.ts b/src/lib/chips/chip-input.spec.ts index 5f43c5b4e8f..ff5da838cd1 100644 --- a/src/lib/chips/chip-input.spec.ts +++ b/src/lib/chips/chip-input.spec.ts @@ -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]', () => { diff --git a/src/lib/chips/chip-input.ts b/src/lib/chips/chip-input.ts index 7c69709a2bd..742da25102f 100644 --- a/src/lib/chips/chip-input.ts +++ b/src/lib/chips/chip-input.ts @@ -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 ``. * May be placed inside or outside of an ``. @@ -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; } diff --git a/src/lib/chips/chip-list.spec.ts b/src/lib/chips/chip-list.spec.ts index 1e3d1e9339e..f2a6129d166 100644 --- a/src/lib/chips/chip-list.spec.ts +++ b/src/lib/chips/chip-list.spec.ts @@ -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: ` + Add a chip Chip 1 Chip 1 Chip 1 - + ` }) diff --git a/src/lib/chips/chip-list.ts b/src/lib/chips/chip-list.ts index 13cd2f7a0e6..3a38efc1410 100644 --- a/src/lib/chips/chip-list.ts +++ b/src/lib/chips/chip-list.ts @@ -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.