license import { MDCComponent } from '@material/base/component' ; import { announce } from '@material/dom/announce' ; import { MDCChip , MDCChipFactory } from '../chip/component' ; import { MDCChipFoundation } from '../chip/foundation' ; import { MDCChipInteractionEvent , MDCChipNavigationEvent , MDCChipRemovalEvent , MDCChipSelectionEvent } from '../chip/types' ; import { MDCChipSetAdapter } from './adapter' ; import { MDCChipSetFoundation } from './foundation' ; const { INTERACTION_EVENT , SELECTION_EVENT , REMOVAL_EVENT , NAVIGATION_EVENT } = MDCChipFoundation . strings ; const { CHIP_SELECTOR } = MDCChipSetFoundation . strings ; let idCounter = 0 ; export class MDCChipSet extends MDCComponent < MDCChipSetFoundation > { static override attachTo ( root ) { return new MDCChipSet ( root ) ; } get chips ( ) : ReadonlyArray < MDCChip > { return this . chipsList . slice ( ) ; } return get selectedChipIds ( ) : ReadonlyArray < string > { return this . foundation . getSelectedChipIds ( ) ; } private chipsList ! : MDCChip [ ] ; private chipFactory ! : ( el : Element ) => MDCChip ; private handleChipInteraction ! : ( evt : MDCChipInteractionEvent ) => void ; private handleChipSelection ! : ( evt : MDCChipSelectionEvent ) => void ; private handleChipRemoval ! : ( evt : MDCChipRemovalEvent ) => void ; private handleChipNavigation ! : ( evt : MDCChipNavigationEvent ) => void ; param chipFactory override initialize ( chipFactory = ( el ) => new MDCChip ( el ) ) { this . chipFactory = chipFactory ; this . chipsList = this . instantiateChips ( this . chipFactory ) ; } override initialSyncWithDOM ( ) { for ( const chip of this . chipsList ) { if ( chip . id && chip . selected ) { this . foundation . select ( chip . id ) ; } } this . handleChipInteraction = ( evt ) => this . foundation . handleChipInteraction ( evt . detail ) ; this . handleChipSelection = ( evt ) => this . foundation . handleChipSelection ( evt . detail ) ; this . handleChipRemoval = ( evt ) => this . foundation . handleChipRemoval ( evt . detail ) ; this . handleChipNavigation = ( evt ) => this . foundation . handleChipNavigation ( evt . detail ) ; this . listen ( INTERACTION_EVENT , this . handleChipInteraction ) ; this . listen ( SELECTION_EVENT , this . handleChipSelection ) ; this . listen ( REMOVAL_EVENT , this . handleChipRemoval ) ; this . listen ( NAVIGATION_EVENT , this . handleChipNavigation ) ; } override destroy ( ) { for ( const chip of this . chipsList ) { chip . destroy ( ) ; } this . unlisten ( INTERACTION_EVENT , this . handleChipInteraction ) ; this . unlisten ( SELECTION_EVENT , this . handleChipSelection ) ; this . unlisten ( REMOVAL_EVENT , this . handleChipRemoval ) ; this . unlisten ( NAVIGATION_EVENT , this . handleChipNavigation ) ; super . destroy ( ) ; } /**
     * Adds a new chip object to the chip set from the given chip element.
     */ addChip ( chipEl ) { chipEl . id = chipEl . id || `mdc-chip-${ ++ idCounter }` ; this . chipsList . push ( this . chipFactory ( chipEl ) ) ; } override getDefaultFoundation ( ) { const adapter = { announceMessage : ( message ) => { announce ( message ) ; } , focusChipPrimaryActionAtIndex : ( index ) => { this . chipsList [ index ] . focusPrimaryAction ( ) ; } , focusChipTrailingActionAtIndex : ( index ) => { this . chipsList [ index ] . focusTrailingAction ( ) ; } , getChipListCount : ( ) => this . chips . length , getIndexOfChipById : ( chipId ) => { return this . findChipIndex ( chipId ) ; } , hasClass : ( className ) => this . root . classList . contains ( className ) , isRTL : ( ) => window . getComputedStyle ( this . root ) . getPropertyValue ( 'direction' ) === 'rtl' , removeChipAtIndex : ( index ) => { if ( index >= 0 && index < this . chips . length ) { this . chipsList [ index ] . destroy ( ) ; this . chipsList [ index ] . remove ( ) ; this . chipsList . splice ( index , 1 ) ; } } , removeFocusFromChipAtIndex : ( index ) => { this . chipsList [ index ] . removeFocus ( ) ; } , selectChipAtIndex : ( index , selected , shouldNotifyClients ) => { if ( index >= 0 && index < this . chips . length ) { this . chipsList [ index ] . setSelectedFromChipSet ( selected , shouldNotifyClients ) ; } } , } ; return new MDCChipSetFoundation ( adapter ) ; } /**
     * Instantiates chip components on all of the chip set's child chip elements.
     */ private instantiateChips ( chipFactory ) { const chipElements = [ ] . slice . call ( this . root . querySelectorAll ( CHIP_SELECTOR ) ) ; return chipElements . map ( ( el ) => { el . id = el . id || `mdc-chip-${ ++ idCounter }` ; return chipFactory ( el ) ; } ) ; } /**
     * Returns the index of the chip with the given id, or -1 if the chip does not exist.
     */ private findChipIndex ( chipId ) { for ( let i = 0 ; i < this . chips . length ; i ++ ) { if ( this . chipsList [ i ] . id === chipId ) { return i ; } } return - 1 ; } }