diff --git a/src/demo-app/chips/chips-demo.html b/src/demo-app/chips/chips-demo.html index b55c55954aea..143fef9b4005 100644 --- a/src/demo-app/chips/chips-demo.html +++ b/src/demo-app/chips/chips-demo.html @@ -25,7 +25,7 @@

Advanced

Selected/Colored + (destroyed)="displayMessage('chip destroyed')" (removed)="toggleVisible()"> With Events cancel @@ -49,7 +49,7 @@

Form Field

+ [removable]="removable" (removed)="remove(person)"> {{person.name}} cancel @@ -70,7 +70,7 @@

Form Field

+ [removable]="removable" (removed)="remove(person)"> {{person.name}} cancel diff --git a/src/lib/chips/chip.spec.ts b/src/lib/chips/chip.spec.ts index 90c3bdfa873f..5d740b050b7a 100644 --- a/src/lib/chips/chip.spec.ts +++ b/src/lib/chips/chip.spec.ts @@ -2,7 +2,7 @@ import {async, ComponentFixture, TestBed} from '@angular/core/testing'; import {Component, DebugElement} from '@angular/core'; import {By} from '@angular/platform-browser'; import {createKeyboardEvent} from '@angular/cdk/testing'; -import {MdChipList, MdChip, MdChipEvent, MdChipsModule} from './index'; +import {MdChipList, MdChip, MdChipEvent, MdChipSelectionEvent, MdChipsModule} from './index'; import {SPACE, DELETE, BACKSPACE} from '@angular/material/core'; import {Directionality} from '@angular/material/core'; @@ -120,7 +120,7 @@ describe('Chips', () => { fixture.detectChanges(); expect(chipNativeElement.classList).toContain('mat-chip-selected'); - expect(testComponent.chipSelect).toHaveBeenCalledWith({chip: chipInstance}); + expect(testComponent.chipSelect).toHaveBeenCalledWith({chip: chipInstance, selected: true}); }); it('allows removal', () => { @@ -143,26 +143,25 @@ describe('Chips', () => { it('should selects/deselects the currently focused chip on SPACE', () => { const SPACE_EVENT: KeyboardEvent = createKeyboardEvent('keydown', SPACE) as KeyboardEvent; - const CHIP_EVENT: MdChipEvent = {chip: chipInstance}; + const CHIP_SELECT_EVENT: MdChipSelectionEvent = {chip: chipInstance, selected: true}; + const CHIP_DESELECT_EVENT: MdChipSelectionEvent = {chip: chipInstance, selected: false}; spyOn(testComponent, 'chipSelect'); - spyOn(testComponent, 'chipDeselect'); // Use the spacebar to select the chip chipInstance._handleKeydown(SPACE_EVENT); fixture.detectChanges(); expect(chipInstance.selected).toBeTruthy(); - expect(testComponent.chipSelect).toHaveBeenCalledTimes(1); - expect(testComponent.chipSelect).toHaveBeenCalledWith(CHIP_EVENT); + expect(testComponent.chipSelect).toHaveBeenCalledWith(CHIP_SELECT_EVENT); // Use the spacebar to deselect the chip chipInstance._handleKeydown(SPACE_EVENT); fixture.detectChanges(); expect(chipInstance.selected).toBeFalsy(); - expect(testComponent.chipDeselect).toHaveBeenCalledTimes(1); - expect(testComponent.chipDeselect).toHaveBeenCalledWith(CHIP_EVENT); + expect(testComponent.chipSelect).toHaveBeenCalledWith(CHIP_DESELECT_EVENT); + expect(testComponent.chipSelect).toHaveBeenCalledTimes(2); }); it('should have correct aria-selected', () => { @@ -280,9 +279,9 @@ describe('Chips', () => {
+ (focus)="chipFocus($event)" (destroyed)="chipDestroy($event)" + (selectionChange)="chipSelect($event)" + (removed)="chipRemove($event)"> {{name}}
@@ -300,7 +299,6 @@ class SingleChip { chipFocus: (event?: MdChipEvent) => void = () => {}; chipDestroy: (event?: MdChipEvent) => void = () => {}; chipSelect: (event?: MdChipEvent) => void = () => {}; - chipDeselect: (event?: MdChipEvent) => void = () => {}; chipRemove: (event?: MdChipEvent) => void = () => {}; } diff --git a/src/lib/chips/chip.ts b/src/lib/chips/chip.ts index 3a88bd516064..098a0c5fb014 100644 --- a/src/lib/chips/chip.ts +++ b/src/lib/chips/chip.ts @@ -34,6 +34,11 @@ export interface MdChipEvent { chip: MdChip; } +export interface MdChipSelectionEvent { + chip: MdChip; + selected: boolean; +} + // Boilerplate for applying mixins to MdChip. /** @docs-private */ export class MdChipBase { @@ -83,7 +88,12 @@ export class MdChip extends _MdChipMixinBase implements FocusableOption, OnDestr @Input() get selected(): boolean { return this._selected; } set selected(value: boolean) { this._selected = coerceBooleanProperty(value); - (this.selected ? this.select : this.deselect).emit({chip: this}); + if (this.selected) { + this.select.emit({chip: this}); + } else { + this.deselect.emit({chip: this}); + } + this.selectionChange.emit({chip: this, selected: this.selected}); } protected _selected: boolean = false; @@ -118,15 +128,39 @@ export class MdChip extends _MdChipMixinBase implements FocusableOption, OnDestr /** Emits when the chip is focused. */ _onFocus = new Subject(); - /** Emitted when the chip is selected. */ + /** + * Emitted when the chip is selected. + * @deprecated Use `selectionChange` instead. + */ @Output() select = new EventEmitter(); - /** Emitted when the chip is deselected. */ + /** Emitted when the chip is selected. */ + @Output() selectionChange = new EventEmitter(); + + /** + * Emitted when the chip is deselected. + * @deprecated Use `selectionChange` instead. + */ @Output() deselect = new EventEmitter(); - /** Emitted when the chip is destroyed. */ + /** + * Emitted when the chip is destroyed. + * @deprecated Use `destroyed` instead. + */ @Output() destroy = new EventEmitter(); + /** Emitted when the chip is destroyed. */ + @Output() destroyed = new EventEmitter(); + + /** + * Emitted when a chip is to be removed. + * @deprecated Use `removed` instead. + */ + @Output('remove') onRemove = new EventEmitter(); + + /** Emitted when a chip is to be removed. */ + @Output() removed = new EventEmitter(); + get ariaSelected(): string | null { return this.selectable ? this.selected.toString() : null; } @@ -135,11 +169,9 @@ export class MdChip extends _MdChipMixinBase implements FocusableOption, OnDestr super(renderer, elementRef); } - /** Emitted when a chip is to be removed. */ - @Output('remove') onRemove = new EventEmitter(); - ngOnDestroy(): void { this.destroy.emit({chip: this}); + this.destroyed.emit({chip: this}); } /** Toggles the current selected state of this chip. */ @@ -162,12 +194,13 @@ export class MdChip extends _MdChipMixinBase implements FocusableOption, OnDestr */ remove(): void { if (this.removable) { + this.removed.emit({chip: this}); this.onRemove.emit({chip: this}); } } /** Ensures events fire properly upon click. */ - _handleClick(event: Event) { + _handleClick(event: Event): void { // Check disabled if (this.disabled) { return; @@ -180,7 +213,7 @@ export class MdChip extends _MdChipMixinBase implements FocusableOption, OnDestr } /** Handle custom key presses. */ - _handleKeydown(event: KeyboardEvent) { + _handleKeydown(event: KeyboardEvent): void { if (this.disabled) { return; } @@ -231,7 +264,7 @@ export class MdChipRemove { constructor(protected _parentChip: MdChip) {} /** Calls the parent chip's public `remove()` method if applicable. */ - _handleClick() { + _handleClick(): void { if (this._parentChip.removable) { this._parentChip.remove(); }