@@ -16,8 +16,14 @@ import {takeUntil} from 'rxjs/operators';
1616
1717let uid = 0 ;
1818
19+ /** Represents an event fired on an individual `mat-chip`. */
20+ export interface MatChipCellEvent {
21+ /** The chip the event was fired on. */
22+ chip : MatChipCell ;
23+ }
24+
1925/**
20- * Dummy directive to add CSS class to chip leading icon.
26+ * Directive to add CSS classes to chip leading icon.
2127 * @docs -private
2228 */
2329@Directive ( {
@@ -27,23 +33,26 @@ let uid = 0;
2733 }
2834} )
2935export class MatChipAvatar {
30- _classes : { [ key : string ] : boolean } = { } ;
36+ constructor ( private _changeDetectorRef : ChangeDetectorRef ,
37+ private _elementRef : ElementRef ) { }
3138
3239 /** Sets whether the given CSS class should be applied to the leading icon. */
3340 setClass ( cssClass : string , active : boolean ) {
3441 const element = this . _elementRef . nativeElement ;
3542 active ? element . addClass ( cssClass ) : element . removeClass ( cssClass ) ;
3643 this . _changeDetectorRef . markForCheck ( ) ;
3744 }
38-
39- constructor ( private _changeDetectorRef : ChangeDetectorRef ,
40- private _elementRef : ElementRef ) { }
4145}
4246
4347/**
44- * Dummy directive to add CSS class to chip trailing icon.
48+ * Directive to add CSS class to chip trailing icon and notify parent chip
49+ * about trailing icon interactions.
50+ *
51+ * If matChipRemove is used to add this directive, the parent chip will be
52+ * removed when the trailing icon is clicked.
53+ *
4554 * @docs -private
46- */
55+ z */
4756@Directive ( {
4857 selector : 'mat-chip-trailing-icon, [matChipTrailingIcon], [matChipRemove]' ,
4958 host : {
@@ -56,8 +65,16 @@ export class MatChipAvatar {
5665} )
5766export class MatChipTrailingIcon {
5867 @Output ( ) interaction = new EventEmitter < MouseEvent | KeyboardEvent > ( ) ;
68+ shouldRemove ! : boolean ;
69+
70+ constructor ( _elementRef : ElementRef ) {
71+ this . shouldRemove = _elementRef . nativeElement . getAttribute ( 'matChipRemove' ) !== null ;
72+ }
5973}
6074
75+ /**
76+ * Material design styled Chip component. Used inside the MatChipGrid component.
77+ */
6178@Component ( {
6279 selector : 'mat-chip-cell, mat-basic-chip-cell' ,
6380 templateUrl : 'chip-cell.html' ,
@@ -67,9 +84,6 @@ export class MatChipTrailingIcon {
6784 '[id]' : 'id' ,
6885 '[class.mat-chip-disabled]' : 'disabled' ,
6986 '[class.mat-chip-selected]' : 'selected' ,
70- '(click)' : '_chipFoundation.handleInteraction($event)' ,
71- '(keydown)' : '_chipFoundation.handleInteraction($event)' ,
72- '(transitionend)' : '_chipFoundation.handleTransitionEnd($event)'
7387 } ,
7488} )
7589export class MatChipCell implements AfterContentInit , AfterViewInit , OnDestroy {
@@ -93,34 +107,22 @@ export class MatChipCell implements AfterContentInit, AfterViewInit, OnDestroy {
93107 this . _changeDetectorRef . markForCheck ( ) ;
94108 }
95109
96- /**
97- * EventEmitters used to notify the parent chip-set of an event on the chip.
98- */
99- @Output ( ) removal = new EventEmitter < string > ( ) ;
100- @Output ( ) trailingIconInteraction = new EventEmitter < string > ( ) ;
101- @Output ( ) interaction = new EventEmitter < string > ( ) ;
102- @Output ( ) selection = new EventEmitter < { id : string , selected : boolean } > ( ) ;
103-
104110 /** Whether the chip is selected. */
111+ @Input ( )
105112 get selected ( ) : boolean {
106113 return this . _chipFoundation . isSelected ( ) ;
107114 }
108-
109- @Input ( )
110- /** Sets selected state on the chip. */
111115 set selected ( selected : boolean ) {
112116 this . _chipFoundation . setSelected ( selected ) ;
113117 }
114118
115- /** Whether a trailing icon click should trigger exit/removal of the chip. */
116- get shouldRemoveOnTrailingIconClick ( ) : boolean {
117- return this . _chipFoundation . getShouldRemoveOnTrailingIconClick ( ) ;
118- }
119-
120- /** Sets whether a trailing icon click should trigger exit/removal of the chip. */
121- set shouldRemoveOnTrailingIconClick ( shouldRemove : boolean ) {
122- this . _chipFoundation . setShouldRemoveOnTrailingIconClick ( shouldRemove ) ;
123- }
119+ /**
120+ * EventEmitters used to notify the parent chip-set of an event on the chip.
121+ */
122+ @Output ( ) removal = new EventEmitter < string > ( ) ;
123+ @Output ( ) trailingIconInteraction = new EventEmitter < string > ( ) ;
124+ @Output ( ) interaction = new EventEmitter < string > ( ) ;
125+ @Output ( ) selection = new EventEmitter < { id : string , selected : boolean } > ( ) ;
124126
125127 /** The MDC foundation containing business logic for MDC chip. */
126128 _chipFoundation : MDCChipFoundation ;
@@ -131,6 +133,12 @@ export class MatChipCell implements AfterContentInit, AfterViewInit, OnDestroy {
131133 */
132134 _classes : { [ key : string ] : boolean } = { } ;
133135
136+ /** Emitted when the chip is destroyed. */
137+ @Output ( ) readonly destroyed : EventEmitter < MatChipCellEvent > = new EventEmitter < MatChipCellEvent > ( ) ;
138+
139+ /** Emitted when a chip is to be removed. */
140+ @Output ( ) readonly removed : EventEmitter < MatChipCellEvent > = new EventEmitter < MatChipCellEvent > ( ) ;
141+
134142 /** Subject that emits when the component has been destroyed. */
135143 private _destroyed = new Subject < void > ( ) ;
136144
@@ -143,10 +151,12 @@ export class MatChipCell implements AfterContentInit, AfterViewInit, OnDestroy {
143151 /** The chip's trailing icon. */
144152 @ContentChild ( MatChipTrailingIcon , { static : false } ) trailingIcon : MatChipTrailingIcon ;
145153
154+ /** The div element that is styled as an MDC chip. */
146155 @ViewChild ( 'wrapper' ) _wrapper ! : ElementRef ;
147- /**
148- * Implementation of the MDC chip adapter interface.
149- * These methods are called by the chip foundation.
156+
157+ /**
158+ * Implementation of the MDC chip adapter interface.
159+ * These methods are called by the chip foundation.
150160 */
151161 private _chipAdapter : MDCChipAdapter = {
152162 addClass : ( className ) => this . _setClass ( className , true ) ,
@@ -160,14 +170,19 @@ export class MatChipCell implements AfterContentInit, AfterViewInit, OnDestroy {
160170 notifyInteraction : ( ) => this . interaction . emit ( this . id ) ,
161171 notifySelection : ( ) => this . selection . emit ( { id : this . id , selected : this . selected } ) ,
162172 notifyTrailingIconInteraction : ( ) => this . trailingIconInteraction . emit ( this . id ) ,
163- notifyRemoval : ( ) => this . removal . emit ( this . id ) ,
173+ notifyRemoval : ( ) => {
174+ this . removed . emit ( { chip : this } ) ;
175+ this . removal . emit ( this . id ) ;
176+ } ,
164177 getComputedStyleValue : ( propertyName ) => {
165- return window . getComputedStyle ( this . _elementRef . nativeElement ) . getPropertyValue ( propertyName ) ;
178+ return window . getComputedStyle ( this . _wrapper . nativeElement ) . getPropertyValue ( propertyName ) ;
166179 } ,
167180 setStyleProperty : ( propertyName : string , value : string ) => {
168- this . _elementRef . nativeElement . style . setProperty ( propertyName , value ) ;
181+ this . _wrapper . nativeElement . style . setProperty ( propertyName , value ) ;
169182 } ,
170183 hasLeadingIcon : ( ) => { return ! ! this . leadingIcon } ,
184+ // The 2 functions below are used by the MDC ripple, which we aren't using,
185+ // so they will never be called
171186 getRootBoundingClientRect : ( ) => this . _elementRef . nativeElement . getBoundingClientRect ( ) ,
172187 getCheckmarkBoundingClientRect : ( ) => { return null } ,
173188 } ;
@@ -183,9 +198,14 @@ export class MatChipCell implements AfterContentInit, AfterViewInit, OnDestroy {
183198
184199 ngAfterContentInit ( ) {
185200 if ( this . trailingIcon ) {
201+ this . _chipFoundation . setShouldRemoveOnTrailingIconClick ( this . trailingIcon . shouldRemove ) ;
186202 this . trailingIcon . interaction
187203 . pipe ( takeUntil ( this . _destroyed ) )
188- . subscribe ( ( event ) => this . _chipFoundation . handleTrailingIconInteraction ( event ) ) ;
204+ . subscribe ( ( event ) => {
205+ if ( ! this . disabled ) {
206+ this . _chipFoundation . handleTrailingIconInteraction ( event ) ;
207+ }
208+ } ) ;
189209 }
190210 }
191211
@@ -195,27 +215,30 @@ export class MatChipCell implements AfterContentInit, AfterViewInit, OnDestroy {
195215 }
196216
197217 ngOnDestroy ( ) {
218+ this . destroyed . emit ( { chip : this } ) ;
198219 this . _destroyed . next ( ) ;
199220 this . _destroyed . complete ( ) ;
200221 this . _chipFoundation . destroy ( ) ;
201222 }
202223
203224 /**
204225 * Begins the exit animation which leads to removal of the chip.
205- * If shouldRemoveOnTrailingIconClick is set to false , you must manually call
226+ * If you aren't using the matChipRemove Directive , you must manually call
206227 * this method to remove the chip.
207228 */
208229 beginExit ( ) {
209230 this . _chipFoundation . beginExit ( ) ;
210231 }
211232
233+ /** Whether this chip is a basic (unstyled) chip. */
212234 _isBasicChip ( ) {
213235 const basicChipAttrName = 'mat-basic-chip-cell' ;
214236 const element = this . _elementRef . nativeElement as HTMLElement ;
215237 return element . hasAttribute ( basicChipAttrName ) ||
216238 element . tagName . toLowerCase ( ) === basicChipAttrName ;
217239 }
218240
241+ /** Adds a class to non-basic chips. */
219242 _addHostClassName ( ) {
220243 if ( ! this . _isBasicChip ( ) ) {
221244 this . _elementRef . nativeElement . classList . add ( 'mat-standard-chip-cell' ) ;
@@ -237,12 +260,17 @@ export class MatChipCell implements AfterContentInit, AfterViewInit, OnDestroy {
237260 exitDuration : 150 /* MDCRippleFoundation.numbers.FG_DEACTIVATION_MS */ ,
238261 } ,
239262 } ,
240- rippleDisabled : this . _isBasicChip ( )
263+ rippleDisabled : this . disabled || this . _isBasicChip ( ) ,
241264 } ;
242265
243266 this . _rippleRenderer =
244267 new RippleRenderer ( rippleTarget , this . _ngZone , this . _wrapper , this . _platform ) ;
245268 this . _rippleRenderer . setupTriggerEvents ( this . _wrapper . nativeElement ) ;
246269 }
270+
271+ /** Forwards interaction events to the MDC chip foundation. */
272+ _handleInteraction ( event : MouseEvent | KeyboardEvent ) {
273+ if ( ! this . disabled ) this . _chipFoundation . handleInteraction ( event ) ;
274+ }
247275}
248276
0 commit comments