From 3c8a4984223507f89453faee1e84859fcd2ba43f Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Mon, 19 Mar 2018 21:19:45 +0100 Subject: [PATCH] feat(chips): allow for separatorKeyCodes to be configured globally (#10264) Adds the `MAT_CHIPS_DEFAULT_OPTIONS` injection token that allows consumers to override `separatorKeyCodes`, as well as any other options that we decide to add in the future, for the entire module. Fixes #10256. --- src/lib/chips/chip-default-options.ts | 19 +++++++++++ src/lib/chips/chip-input.spec.ts | 46 ++++++++++++++++++++++----- src/lib/chips/chip-input.ts | 11 ++++--- src/lib/chips/chips-module.ts | 12 ++++++- src/lib/chips/chips.md | 19 ++++++++++- src/lib/chips/public-api.ts | 1 + 6 files changed, 94 insertions(+), 14 deletions(-) create mode 100644 src/lib/chips/chip-default-options.ts diff --git a/src/lib/chips/chip-default-options.ts b/src/lib/chips/chip-default-options.ts new file mode 100644 index 00000000000..643f5fde94b --- /dev/null +++ b/src/lib/chips/chip-default-options.ts @@ -0,0 +1,19 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +import {InjectionToken} from '@angular/core'; + +/** Default options, for the chips module, that can be overridden. */ +export interface MatChipsDefaultOptions { + /** The list of key codes that will trigger a chipEnd event. */ + separatorKeyCodes: number[]; +} + +/** Injection token to be used to override the default options for the chips module. */ +export const MAT_CHIPS_DEFAULT_OPTIONS = + new InjectionToken('mat-chips-default-options'); diff --git a/src/lib/chips/chip-input.spec.ts b/src/lib/chips/chip-input.spec.ts index ff5da838cd1..4dcc805e23f 100644 --- a/src/lib/chips/chip-input.spec.ts +++ b/src/lib/chips/chip-input.spec.ts @@ -7,6 +7,7 @@ import {async, ComponentFixture, TestBed} from '@angular/core/testing'; import {By} from '@angular/platform-browser'; import {MatChipInput, MatChipInputEvent} from './chip-input'; import {MatChipsModule} from './index'; +import {MAT_CHIPS_DEFAULT_OPTIONS, MatChipsDefaultOptions} from './chip-default-options'; describe('MatChipInput', () => { @@ -44,7 +45,7 @@ describe('MatChipInput', () => { describe('basic behavior', () => { it('emits the (chipEnd) on enter keyup', () => { - let ENTER_EVENT = createKeyboardEvent('keydown', ENTER, inputNativeElement) as any; + let ENTER_EVENT = createKeyboardEvent('keydown', ENTER, inputNativeElement); spyOn(testChipInput, 'add'); @@ -79,12 +80,12 @@ describe('MatChipInput', () => { }); }); - describe('[separatorKeysCodes]', () => { + describe('[separatorKeyCodes]', () => { it('does not emit (chipEnd) when a non-separator key is pressed', () => { - let ENTER_EVENT = createKeyboardEvent('keydown', ENTER, inputNativeElement) as any; + let ENTER_EVENT = createKeyboardEvent('keydown', ENTER, inputNativeElement); spyOn(testChipInput, 'add'); - testChipInput.separatorKeys = [COMMA]; + chipInputDirective.separatorKeyCodes = [COMMA]; fixture.detectChanges(); chipInputDirective._keydown(ENTER_EVENT); @@ -92,15 +93,46 @@ describe('MatChipInput', () => { }); it('emits (chipEnd) when a custom separator keys is pressed', () => { - let COMMA_EVENT = createKeyboardEvent('keydown', COMMA, inputNativeElement) as any; + let COMMA_EVENT = createKeyboardEvent('keydown', COMMA, inputNativeElement); spyOn(testChipInput, 'add'); - testChipInput.separatorKeys = [COMMA]; + chipInputDirective.separatorKeyCodes = [COMMA]; fixture.detectChanges(); chipInputDirective._keydown(COMMA_EVENT); expect(testChipInput.add).toHaveBeenCalled(); }); + + it('emits (chipEnd) when the separator keys are configured globally', () => { + fixture.destroy(); + + TestBed + .resetTestingModule() + .configureTestingModule({ + imports: [MatChipsModule, PlatformModule], + declarations: [TestChipInput], + providers: [{ + provide: MAT_CHIPS_DEFAULT_OPTIONS, + useValue: ({separatorKeyCodes: [COMMA]} as MatChipsDefaultOptions) + }] + }) + .compileComponents(); + + fixture = TestBed.createComponent(TestChipInput); + testChipInput = fixture.debugElement.componentInstance; + fixture.detectChanges(); + + inputDebugElement = fixture.debugElement.query(By.directive(MatChipInput)); + chipInputDirective = inputDebugElement.injector.get(MatChipInput) as MatChipInput; + inputNativeElement = inputDebugElement.nativeElement; + + spyOn(testChipInput, 'add'); + fixture.detectChanges(); + + chipInputDirective._keydown(createKeyboardEvent('keydown', COMMA, inputNativeElement)); + expect(testChipInput.add).toHaveBeenCalled(); + }); + }); }); @@ -110,13 +142,11 @@ describe('MatChipInput', () => { ` }) class TestChipInput { addOnBlur: boolean = false; - separatorKeys: number[] = [ENTER]; add(_: MatChipInputEvent) { } diff --git a/src/lib/chips/chip-input.ts b/src/lib/chips/chip-input.ts index 742da25102f..28f807d2b18 100644 --- a/src/lib/chips/chip-input.ts +++ b/src/lib/chips/chip-input.ts @@ -7,9 +7,9 @@ */ import {coerceBooleanProperty} from '@angular/cdk/coercion'; -import {ENTER} from '@angular/cdk/keycodes'; -import {Directive, ElementRef, EventEmitter, Input, Output} from '@angular/core'; +import {Directive, ElementRef, EventEmitter, Input, Output, Inject} from '@angular/core'; import {MatChipList} from './chip-list'; +import {MAT_CHIPS_DEFAULT_OPTIONS, MatChipsDefaultOptions} from './chip-default-options'; /** Represents an input event on a `matChipInput`. */ @@ -68,7 +68,8 @@ export class MatChipInput { * Defaults to `[ENTER]`. */ // TODO(tinayuangao): Support Set here - @Input('matChipInputSeparatorKeyCodes') separatorKeyCodes: number[] = [ENTER]; + @Input('matChipInputSeparatorKeyCodes') + separatorKeyCodes: number[] = this._defaultOptions.separatorKeyCodes; /** Emitted when a chip is to be added. */ @Output('matChipInputTokenEnd') @@ -86,7 +87,9 @@ export class MatChipInput { /** The native input element to which this directive is attached. */ protected _inputElement: HTMLInputElement; - constructor(protected _elementRef: ElementRef) { + constructor( + protected _elementRef: ElementRef, + @Inject(MAT_CHIPS_DEFAULT_OPTIONS) private _defaultOptions: MatChipsDefaultOptions) { this._inputElement = this._elementRef.nativeElement as HTMLInputElement; } diff --git a/src/lib/chips/chips-module.ts b/src/lib/chips/chips-module.ts index 80e21b45a04..5de02d47271 100644 --- a/src/lib/chips/chips-module.ts +++ b/src/lib/chips/chips-module.ts @@ -12,6 +12,8 @@ import {ErrorStateMatcher} from '@angular/material/core'; import {MatChip, MatChipAvatar, MatChipRemove, MatChipTrailingIcon} from './chip'; import {MatChipInput} from './chip-input'; import {MatChipList} from './chip-list'; +import {MAT_CHIPS_DEFAULT_OPTIONS, MatChipsDefaultOptions} from './chip-default-options'; +import {ENTER} from '@angular/cdk/keycodes'; const CHIP_DECLARATIONS = [ MatChipList, @@ -26,6 +28,14 @@ const CHIP_DECLARATIONS = [ imports: [PlatformModule], exports: CHIP_DECLARATIONS, declarations: CHIP_DECLARATIONS, - providers: [ErrorStateMatcher] + providers: [ + ErrorStateMatcher, + { + provide: MAT_CHIPS_DEFAULT_OPTIONS, + useValue: { + separatorKeyCodes: [ENTER] + } as MatChipsDefaultOptions + } + ] }) export class MatChipsModule {} diff --git a/src/lib/chips/chips.md b/src/lib/chips/chips.md index b2df618ea0f..c14445de141 100644 --- a/src/lib/chips/chips.md +++ b/src/lib/chips/chips.md @@ -20,7 +20,7 @@ _Hint: `` receives the `mat-basic-chip` CSS class in addition to Chips can be selected via the `selected` property. Selection can be disabled by setting `selectable` to `false` on the ``. -Whenever the selection state changes, a `ChipSelectionChange` event will be emitted via +Whenever the selection state changes, a `ChipSelectionChange` event will be emitted via `(selectionChange)`. ### Disabled chips @@ -67,6 +67,23 @@ the `mat-chip-list-stacked` class, as well as the `aria-orientation="vertical"` ``` +### Specifying global configuration defaults +Default options for the chips module can be specified using the `MAT_CHIPS_DEFAULT_OPTIONS` +injection token. + +```ts +@NgModule({ + providers: [ + { + provide: MAT_CHIPS_DEFAULT_OPTIONS, + useValue: { + separatorKeyCodes: [ENTER, COMMA] + } + } + ] +}) +``` + ### Theming The selected color of an `` can be changed by using the `color` property. By default, chips use a neutral background color based on the current theme (light or dark). This can be changed to diff --git a/src/lib/chips/public-api.ts b/src/lib/chips/public-api.ts index 940403e4c0b..fd202e54df0 100644 --- a/src/lib/chips/public-api.ts +++ b/src/lib/chips/public-api.ts @@ -10,3 +10,4 @@ export * from './chips-module'; export * from './chip-list'; export * from './chip'; export * from './chip-input'; +export * from './chip-default-options';