Skip to content

Commit 372d20b

Browse files
committed
fix(material/chips): add only active autocomplete option on selection
close #32204, #13574
1 parent 4d55040 commit 372d20b

File tree

4 files changed

+44
-5
lines changed

4 files changed

+44
-5
lines changed

goldens/material/chips/index.api.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,15 @@ export class MatChip implements OnInit, AfterViewInit, AfterContentInit, DoCheck
132132
static ɵfac: i0.ɵɵFactoryDeclaration<MatChip, never>;
133133
}
134134

135+
// @public (undocumented)
136+
export class MatChipAutocompleteInput extends MatChipInput {
137+
_emitChipEnd(event?: KeyboardEvent): void;
138+
// (undocumented)
139+
static ɵdir: i0.ɵɵDirectiveDeclaration<MatChipAutocompleteInput, "input[matChipInputFor][matAutocomplete]", ["matChipInput", "matChipInputFor"], {}, {}, never, never, true, never>;
140+
// (undocumented)
141+
static ɵfac: i0.ɵɵFactoryDeclaration<MatChipAutocompleteInput, never>;
142+
}
143+
135144
// @public
136145
export class MatChipAvatar {
137146
// (undocumented)
@@ -288,6 +297,7 @@ export class MatChipInput implements MatChipTextControl, OnChanges, OnDestroy {
288297
protected _getReadonlyAttribute(): string | null;
289298
id: string;
290299
readonly inputElement: HTMLInputElement;
300+
protected _isSeparatorKey(event: KeyboardEvent): boolean;
291301
_keydown(event: KeyboardEvent): void;
292302
// (undocumented)
293303
static ngAcceptInputType_addOnBlur: unknown;
@@ -309,7 +319,7 @@ export class MatChipInput implements MatChipTextControl, OnChanges, OnDestroy {
309319
// (undocumented)
310320
setDescribedByIds(ids: string[]): void;
311321
// (undocumented)
312-
static ɵdir: i0.ɵɵDirectiveDeclaration<MatChipInput, "input[matChipInputFor]", ["matChipInput", "matChipInputFor"], { "chipGrid": { "alias": "matChipInputFor"; "required": false; }; "addOnBlur": { "alias": "matChipInputAddOnBlur"; "required": false; }; "separatorKeyCodes": { "alias": "matChipInputSeparatorKeyCodes"; "required": false; }; "placeholder": { "alias": "placeholder"; "required": false; }; "id": { "alias": "id"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "readonly": { "alias": "readonly"; "required": false; }; "disabledInteractive": { "alias": "matChipInputDisabledInteractive"; "required": false; }; }, { "chipEnd": "matChipInputTokenEnd"; }, never, never, true, never>;
322+
static ɵdir: i0.ɵɵDirectiveDeclaration<MatChipInput, "input[matChipInputFor]:not([matAutocomplete])", ["matChipInput", "matChipInputFor"], { "chipGrid": { "alias": "matChipInputFor"; "required": false; }; "addOnBlur": { "alias": "matChipInputAddOnBlur"; "required": false; }; "separatorKeyCodes": { "alias": "matChipInputSeparatorKeyCodes"; "required": false; }; "placeholder": { "alias": "placeholder"; "required": false; }; "id": { "alias": "id"; "required": false; }; "disabled": { "alias": "disabled"; "required": false; }; "readonly": { "alias": "readonly"; "required": false; }; "disabledInteractive": { "alias": "matChipInputDisabledInteractive"; "required": false; }; }, { "chipEnd": "matChipInputTokenEnd"; }, never, never, true, never>;
313323
// (undocumented)
314324
static ɵfac: i0.ɵɵFactoryDeclaration<MatChipInput, never>;
315325
}
@@ -541,7 +551,7 @@ export class MatChipsModule {
541551
// (undocumented)
542552
static ɵinj: i0.ɵɵInjectorDeclaration<MatChipsModule>;
543553
// (undocumented)
544-
static ɵmod: i0.ɵɵNgModuleDeclaration<MatChipsModule, never, [typeof MatRippleModule, typeof MatChipAction, typeof MatChip, typeof MatChipAvatar, typeof MatChipEdit, typeof MatChipEditInput, typeof MatChipGrid, typeof MatChipInput, typeof MatChipListbox, typeof MatChipOption, typeof MatChipRemove, typeof MatChipRow, typeof MatChipSet, typeof MatChipTrailingIcon], [typeof i2.BidiModule, typeof MatChip, typeof MatChipAvatar, typeof MatChipEdit, typeof MatChipEditInput, typeof MatChipGrid, typeof MatChipInput, typeof MatChipListbox, typeof MatChipOption, typeof MatChipRemove, typeof MatChipRow, typeof MatChipSet, typeof MatChipTrailingIcon]>;
554+
static ɵmod: i0.ɵɵNgModuleDeclaration<MatChipsModule, never, [typeof MatRippleModule, typeof MatChipAction, typeof MatChip, typeof MatChipAvatar, typeof MatChipEdit, typeof MatChipEditInput, typeof MatChipGrid, typeof MatChipAutocompleteInput, typeof MatChipInput, typeof MatChipListbox, typeof MatChipOption, typeof MatChipRemove, typeof MatChipRow, typeof MatChipSet, typeof MatChipTrailingIcon], [typeof i2.BidiModule, typeof MatChip, typeof MatChipAvatar, typeof MatChipEdit, typeof MatChipEditInput, typeof MatChipGrid, typeof MatChipAutocompleteInput, typeof MatChipInput, typeof MatChipListbox, typeof MatChipOption, typeof MatChipRemove, typeof MatChipRow, typeof MatChipSet, typeof MatChipTrailingIcon]>;
545555
}
546556

547557
// @public

src/material/chips/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ ng_project(
100100
"//:node_modules/@angular/forms",
101101
"//:node_modules/rxjs",
102102
"//src:dev_mode_types",
103+
"//src/material/autocomplete",
103104
"//src/material/core",
104105
"//src/material/form-field",
105106
],

src/material/chips/chip-input.ts

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
inject,
2020
} from '@angular/core';
2121
import {_IdGenerator} from '@angular/cdk/a11y';
22+
import {MatAutocompleteTrigger} from '../autocomplete';
2223
import {MatFormField, MAT_FORM_FIELD} from '../form-field';
2324
import {MatChipsDefaultOptions, MAT_CHIPS_DEFAULT_OPTIONS, SeparatorKey} from './tokens';
2425
import {MatChipGrid} from './chip-grid';
@@ -45,7 +46,7 @@ export interface MatChipInputEvent {
4546
* May be placed inside or outside of a `<mat-chip-grid>`.
4647
*/
4748
@Directive({
48-
selector: 'input[matChipInputFor]',
49+
selector: 'input[matChipInputFor]:not([matAutocomplete])',
4950
exportAs: 'matChipInput, matChipInputFor',
5051
host: {
5152
// TODO: eventually we should remove `mat-input-element` from here since it comes from the
@@ -242,7 +243,7 @@ export class MatChipInput implements MatChipTextControl, OnChanges, OnDestroy {
242243
}
243244

244245
/** Checks whether a keycode is one of the configured separators. */
245-
private _isSeparatorKey(event: KeyboardEvent): boolean {
246+
protected _isSeparatorKey(event: KeyboardEvent): boolean {
246247
if (!this.separatorKeyCodes) {
247248
return false;
248249
}
@@ -276,3 +277,29 @@ export class MatChipInput implements MatChipTextControl, OnChanges, OnDestroy {
276277
return this.readonly || (this.disabled && this.disabledInteractive) ? 'true' : null;
277278
}
278279
}
280+
281+
/**
282+
* Directive that adds chip-specific behaviors to an autocomplete input element inside
283+
* `<mat-form-field>`.
284+
* May be placed inside or outside of a `<mat-chip-grid>`.
285+
*/
286+
@Directive({
287+
selector: 'input[matChipInputFor][matAutocomplete]',
288+
exportAs: 'matChipInput, matChipInputFor',
289+
})
290+
export class MatChipAutocompleteInput extends MatChipInput {
291+
private readonly _autocompleteTrigger = inject(MatAutocompleteTrigger);
292+
293+
/** Checks to see if the (chipEnd) event needs to be emitted. */
294+
override _emitChipEnd(event?: KeyboardEvent) {
295+
if (
296+
(!event || (super._isSeparatorKey(event) && !event.repeat)) &&
297+
this._autocompleteTrigger.autocomplete.isOpen &&
298+
this._autocompleteTrigger.activeOption
299+
) {
300+
event?.preventDefault();
301+
} else {
302+
super._emitChipEnd(event);
303+
}
304+
}
305+
}

src/material/chips/chips-module.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {MAT_CHIPS_DEFAULT_OPTIONS, MatChipsDefaultOptions} from './tokens';
1414
import {MatChipEditInput} from './chip-edit-input';
1515
import {MatChipGrid} from './chip-grid';
1616
import {MatChipAvatar, MatChipEdit, MatChipRemove, MatChipTrailingIcon} from './chip-icons';
17-
import {MatChipInput} from './chip-input';
17+
import {MatChipAutocompleteInput, MatChipInput} from './chip-input';
1818
import {MatChipListbox} from './chip-listbox';
1919
import {MatChipRow} from './chip-row';
2020
import {MatChipOption} from './chip-option';
@@ -28,6 +28,7 @@ const CHIP_DECLARATIONS = [
2828
MatChipEdit,
2929
MatChipEditInput,
3030
MatChipGrid,
31+
MatChipAutocompleteInput,
3132
MatChipInput,
3233
MatChipListbox,
3334
MatChipOption,

0 commit comments

Comments
 (0)