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.
This commit is contained in:
Kristiyan Kostadinov
2018-03-19 21:19:45 +01:00
committed by Andrew Seguin
parent 9a1ae9c5fb
commit 3c8a498422
6 changed files with 94 additions and 14 deletions
+19
View File
@@ -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<MatChipsDefaultOptions>('mat-chips-default-options');
+38 -8
View File
@@ -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', () => {
</mat-chip-list>
<input matInput [matChipInputFor]="chipList"
[matChipInputAddOnBlur]="addOnBlur"
[matChipInputSeparatorKeyCodes]="separatorKeys"
(matChipInputTokenEnd)="add($event)" />
`
})
class TestChipInput {
addOnBlur: boolean = false;
separatorKeys: number[] = [ENTER];
add(_: MatChipInputEvent) {
}
+7 -4
View File
@@ -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;
}
+11 -1
View File
@@ -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 {}
+18 -1
View File
@@ -20,7 +20,7 @@ _Hint: `<mat-basic-chip>` 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 `<mat-chip-list>`.
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"`
</mat-chip-list>
```
### 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 `<mat-chip>` 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
+1
View File
@@ -10,3 +10,4 @@ export * from './chips-module';
export * from './chip-list';
export * from './chip';
export * from './chip-input';
export * from './chip-default-options';