license import { FocusableOption } from '@angular/cdk/a11y' ; import { coerceBooleanProperty } from '@angular/cdk/coercion' ; import { BACKSPACE , DELETE , SPACE } from '@angular/cdk/keycodes' ; import { Platform } from '@angular/cdk/platform' ; import { ContentChild , Directive , ElementRef , EventEmitter , forwardRef , Inject , Input , NgZone , OnDestroy , Optional , Output , } from '@angular/core' ; import { CanColor , CanColorCtor , CanDisable , CanDisableCtor , CanDisableRipple , CanDisableRippleCtor , MAT_RIPPLE_GLOBAL_OPTIONS , mixinColor , mixinDisabled , mixinDisableRipple , RippleConfig , RippleGlobalOptions , RippleRenderer , RippleTarget , } from '@angular/material/core' ; import { Subject } from 'rxjs' ; import { take } from 'rxjs/operators' ; /** Represents an event fired on an individual `mat-chip`. */ export interface MatChipEvent { /** The chip the event was fired on. */ chip : MatChip ; } /** Event object emitted by MatChip when selected or deselected. */ export class MatChipSelectionChange { constructor ( /** Reference to the chip that emitted the event. */ public source , /** Whether the chip that emitted the event is selected. */ public selected , /** Whether the selection change was a result of a user interaction. */ public isUserInput = false ) { } } docs-private export class MatChipBase { constructor ( public _elementRef ) { } } export const _MatChipMixinBase = mixinColor ( mixinDisableRipple ( mixinDisabled ( MatChipBase ) ) , 'primary' ) ; const CHIP_ATTRIBUTE_NAMES = [ 'mat-basic-chip' ] ; docs-private @ Directive ( { selector : 'mat-chip-avatar, [matChipAvatar]' , host : { 'class' : 'mat-chip-avatar' } } ) export class MatChipAvatar { } docs-private @ Directive ( { selector : 'mat-chip-trailing-icon, [matChipTrailingIcon]' , host : { 'class' : 'mat-chip-trailing-icon' } } ) export class MatChipTrailingIcon { } /**
 * Material design styled Chip component. Used inside the MatChipList component.
 */ @ Directive ( { selector : `mat-basic-chip, [mat-basic-chip], mat-chip, [mat-chip]` , inputs : [ 'color' , 'disabled' , 'disableRipple' ] , exportAs : 'matChip' , host : { 'class' : 'mat-chip' , '[attr.tabindex]' : 'disabled ? null : -1' , 'role' : 'option' , '[class.mat-chip-selected]' : 'selected' , '[class.mat-chip-with-avatar]' : 'avatar' , '[class.mat-chip-with-trailing-icon]' : 'trailingIcon || removeIcon' , '[class.mat-chip-disabled]' : 'disabled' , '[attr.disabled]' : 'disabled || null' , '[attr.aria-disabled]' : 'disabled.toString()' , '[attr.aria-selected]' : 'ariaSelected' , '(click)' : '_handleClick($event)' , '(keydown)' : '_handleKeydown($event)' , '(focus)' : 'focus()' , '(blur)' : '_blur()' , } , } ) export class MatChip extends _MatChipMixinBase implements FocusableOption , OnDestroy , CanColor , CanDisable , CanDisableRipple , RippleTarget { /** Reference to the RippleRenderer for the chip. */ private _chipRipple : RippleRenderer ; /** Whether the ripples are globally disabled through the RippleGlobalOptions */ private _ripplesGloballyDisabled = false ; docs-private rippleConfig : RippleConfig = { } ; docs-private get rippleDisabled ( ) : boolean { return this . disabled || this . disableRipple || this . _ripplesGloballyDisabled ; } /** Whether the chip has focus. */ _hasFocus : boolean = false ; /** Whether the chip list is selectable */ chipListSelectable : boolean = true ; /** The chip avatar */ @ ContentChild ( MatChipAvatar ) avatar : MatChipAvatar ; /** The chip's trailing icon. */ @ ContentChild ( MatChipTrailingIcon ) trailingIcon : MatChipTrailingIcon ; /** The chip's remove toggler. */ @ ContentChild ( forwardRef ( ( ) => MatChipRemove ) ) removeIcon : MatChipRemove ; /** Whether the chip is selected. */ @ Input ( ) get selected ( ) : boolean { return this . _selected ; } set selected ( value ) { const coercedValue = coerceBooleanProperty ( value ) ; if ( coercedValue !== this . _selected ) { this . _selected = coercedValue ; this . _dispatchSelectionChange ( ) ; } } protected _selected : boolean = false ; /** The value of the chip. Defaults to the content inside `<mat-chip>` tags. */ @ Input ( ) get value ( ) : any { return this . _value != undefined ? this . _value : this . _elementRef . nativeElement . textContent ; } set value ( value ) { this . _value = value ; } protected _value : any ; /**
     * Whether or not the chip is selectable. When a chip is not selectable,
     * changes to its selected state are always ignored. By default a chip is
     * selectable, and it becomes non-selectable if its parent chip list is
     * not selectable.
     */ @ Input ( ) get selectable ( ) : boolean { return this . _selectable && this . chipListSelectable ; } set selectable ( value ) { this . _selectable = coerceBooleanProperty ( value ) ; } protected _selectable : boolean = true ; /**
     * Determines whether or not the chip displays the remove styling and emits (removed) events.
     */ @ Input ( ) get removable ( ) : boolean { return this . _removable ; } set removable ( value ) { this . _removable = coerceBooleanProperty ( value ) ; } protected _removable : boolean = true ; /** Emits when the chip is focused. */ readonly _onFocus = new Subject < MatChipEvent > ( ) ; /** Emits when the chip is blured. */ readonly _onBlur = new Subject < MatChipEvent > ( ) ; /** Emitted when the chip is selected or deselected. */ @ Output ( ) readonly selectionChange : EventEmitter < MatChipSelectionChange > = new EventEmitter < MatChipSelectionChange > ( ) ; /** Emitted when the chip is destroyed. */ @ Output ( ) readonly destroyed : EventEmitter < MatChipEvent > = new EventEmitter < MatChipEvent > ( ) ; /** Emitted when a chip is to be removed. */ @ Output ( ) readonly removed : EventEmitter < MatChipEvent > = new EventEmitter < MatChipEvent > ( ) ; /** The ARIA selected applied to the chip. */ get ariaSelected ( ) : string | null { return this . selectable ? this . selected . toString ( ) : null ; } constructor ( public _elementRef , private _ngZone , platform , @ Optional ( ) @ Inject ( MAT_RIPPLE_GLOBAL_OPTIONS ) globalOptions ) { super ( _elementRef ) ; this . _addHostClassName ( ) ; this . _chipRipple = new RippleRenderer ( this , _ngZone , _elementRef , platform ) ; this . _chipRipple . setupTriggerEvents ( _elementRef . nativeElement ) ; if ( globalOptions ) { this . _ripplesGloballyDisabled = ! ! globalOptions . disabled ; this . rippleConfig = { animation : globalOptions . animation , terminateOnPointerUp : globalOptions . terminateOnPointerUp , } ; } } _addHostClassName ( ) { for ( const attr of CHIP_ATTRIBUTE_NAMES ) { if ( this . _elementRef . nativeElement . hasAttribute ( attr ) || this . _elementRef . nativeElement . tagName . toLowerCase ( ) === attr ) { ( this . _elementRef . nativeElement as HTMLElement ) . classList . add ( attr ) ; return ; } } ( this . _elementRef . nativeElement as HTMLElement ) . classList . add ( 'mat-standard-chip' ) ; } ngOnDestroy ( ) { this . destroyed . emit ( { chip : this } ) ; this . _chipRipple . _removeTriggerEvents ( ) ; } /** Selects the chip. */ select ( ) { if ( ! this . _selected ) { this . _selected = true ; this . _dispatchSelectionChange ( ) ; } } /** Deselects the chip. */ deselect ( ) { if ( this . _selected ) { this . _selected = false ; this . _dispatchSelectionChange ( ) ; } } /** Select this chip and emit selected event */ selectViaInteraction ( ) { if ( ! this . _selected ) { this . _selected = true ; this . _dispatchSelectionChange ( true ) ; } } /** Toggles the current selected state of this chip. */ toggleSelected ( isUserInput = false ) { this . _selected = ! this . selected ; this . _dispatchSelectionChange ( isUserInput ) ; return this . selected ; } /** Allows for programmatic focusing of the chip. */ focus ( ) { if ( ! this . _hasFocus ) { this . _elementRef . nativeElement . focus ( ) ; this . _onFocus . next ( { chip : this } ) ; } this . _hasFocus = true ; } /**
     * Allows for programmatic removal of the chip. Called by the MatChipList when the DELETE or
     * BACKSPACE keys are pressed.
     *
     * Informs any listeners of the removal request. Does not remove the chip from the DOM.
     */ remove ( ) { if ( this . removable ) { this . removed . emit ( { chip : this } ) ; } } /** Handles click events on the chip. */ _handleClick ( event ) { if ( this . disabled ) { event . preventDefault ( ) ; } else { event . stopPropagation ( ) ; } } /** Handle custom key presses. */ _handleKeydown ( event ) { if ( this . disabled ) { return ; } switch ( event . keyCode ) { case DELETE : case BACKSPACE : this . remove ( ) ; event . preventDefault ( ) ; break ; case SPACE : if ( this . selectable ) { this . toggleSelected ( true ) ; } event . preventDefault ( ) ; break ; } } _blur ( ) { this . _ngZone . onStable . asObservable ( ) . pipe ( take ( 1 ) ) . subscribe ( ( ) => { this . _ngZone . run ( ( ) => { this . _hasFocus = false ; this . _onBlur . next ( { chip : this } ) ; } ) ; } ) ; } private _dispatchSelectionChange ( isUserInput = false ) { this . selectionChange . emit ( { source : this , isUserInput , selected : this . _selected } ) ; } } /**
 * Applies proper (click) support and adds styling for use with the Material Design "cancel" icon
 * available at https://material.io/icons/#ic_cancel.
 *
 * Example:
 *
 *     `<mat-chip>
 *       <mat-icon matChipRemove>cancel</mat-icon>
 *     </mat-chip>`
 *
 * You *may* use a custom icon, but you may need to override the `mat-chip-remove` positioning
 * styles to properly center the icon within the chip.
 */ @ Directive ( { selector : '[matChipRemove]' , host : { 'class' : 'mat-chip-remove mat-chip-trailing-icon' , '(click)' : '_handleClick($event)' , } } ) export class MatChipRemove { constructor ( protected _parentChip ) { } /** Calls the parent chip's public `remove()` method if applicable. */ _handleClick ( event ) { if ( this . _parentChip . removable ) { this . _parentChip . remove ( ) ; } event . stopPropagation ( ) ; } }