license import { MDCComponent } from '@material/base/component' ; import { CustomEventListener , SpecificEventListener } from '@material/base/types' ; import { MDCTabScroller , MDCTabScrollerFactory } from '@material/tab-scroller/component' ; import { MDCTab , MDCTabFactory } from '@material/tab/component' ; import { MDCTabFoundation } from '@material/tab/foundation' ; import { MDCTabInteractionEvent } from '@material/tab/types' ; import { MDCTabBarAdapter } from './adapter' ; import { MDCTabBarFoundation } from './foundation' ; import { MDCTabBarActivatedEventDetail } from './types' ; const { strings } = MDCTabBarFoundation ; let tabIdCounter = 0 ; export class MDCTabBar extends MDCComponent < MDCTabBarFoundation > { static override attachTo ( root ) { return new MDCTabBar ( root ) ; } private tabList ! : MDCTab [ ] ; private tabScroller ! : MDCTabScroller | null ; private handleTabInteraction ! : CustomEventListener < MDCTabInteractionEvent > ; private handleKeyDown ! : SpecificEventListener < 'keydown' > ; set focusOnActivate ( focusOnActivate ) { for ( const tab of this . tabList ) { tab . focusOnActivate = focusOnActivate ; } } set useAutomaticActivation ( useAutomaticActivation ) { this . foundation . setUseAutomaticActivation ( useAutomaticActivation ) ; } override initialize ( tabFactory = ( el ) => new MDCTab ( el ) , tabScrollerFactory = ( el ) => new MDCTabScroller ( el ) ) { this . tabList = this . instantiateTabs ( tabFactory ) ; this . tabScroller = this . instantiatetabScroller ( tabScrollerFactory ) ; } override initialSyncWithDOM ( ) { this . handleTabInteraction = ( evt ) => { this . foundation . handleTabInteraction ( evt ) ; } ; this . handleKeyDown = ( evt ) => { this . foundation . handleKeyDown ( evt ) ; } ; this . listen ( MDCTabFoundation . strings . INTERACTED_EVENT , this . handleTabInteraction ) ; this . listen ( 'keydown' , this . handleKeyDown ) ; for ( let i = 0 ; i < this . tabList . length ; i ++ ) { if ( this . tabList [ i ] . active ) { this . scrollIntoView ( i ) ; break ; } } } override destroy ( ) { super . destroy ( ) ; this . unlisten ( MDCTabFoundation . strings . INTERACTED_EVENT , this . handleTabInteraction ) ; this . unlisten ( 'keydown' , this . handleKeyDown ) ; for ( const tab of this . tabList ) { tab . destroy ( ) ; } if ( this . tabScroller ) { this . tabScroller . destroy ( ) ; } } override getDefaultFoundation ( ) { const adapter = { scrollTo : ( scrollX ) => { this . tabScroller ! . scrollTo ( scrollX ) ; } , incrementScroll : ( scrollXIncrement ) => { this . tabScroller ! . incrementScroll ( scrollXIncrement ) ; } , getScrollPosition : ( ) => this . tabScroller ! . getScrollPosition ( ) , getScrollContentWidth : ( ) => this . tabScroller ! . getScrollContentWidth ( ) , getOffsetWidth : ( ) => ( this . root as HTMLElement ) . offsetWidth , isRTL : ( ) => window . getComputedStyle ( this . root ) . getPropertyValue ( 'direction' ) === 'rtl' , setActiveTab : ( index ) => { this . foundation . activateTab ( index ) ; } , activateTabAtIndex : ( index , clientRect ) => { this . tabList [ index ] . activate ( clientRect ) ; } , deactivateTabAtIndex : ( index ) => { this . tabList [ index ] . deactivate ( ) ; } , focusTabAtIndex : ( index ) => { this . tabList [ index ] . focus ( ) ; } , getTabIndicatorClientRectAtIndex : ( index ) => this . tabList [ index ] . computeIndicatorClientRect ( ) , getTabDimensionsAtIndex : ( index ) => this . tabList [ index ] . computeDimensions ( ) , getPreviousActiveTabIndex : ( ) => { for ( let i = 0 ; i < this . tabList . length ; i ++ ) { if ( this . tabList [ i ] . active ) { return i ; } } return - 1 ; } , getFocusedTabIndex : ( ) => { const tabElements = this . getTabElements ( ) ; const activeElement = document . activeElement ! ; return tabElements . indexOf ( activeElement ) ; } , getIndexOfTabById : ( id ) => { for ( let i = 0 ; i < this . tabList . length ; i ++ ) { if ( this . tabList [ i ] . id === id ) { return i ; } } return - 1 ; } , getTabListLength : ( ) => this . tabList . length , notifyTabActivated : ( index ) => this . emit < MDCTabBarActivatedEventDetail > ( strings . TAB_ACTIVATED_EVENT , { index } , true ) , } ; return new MDCTabBarFoundation ( adapter ) ; } param index activateTab ( index ) { this . foundation . activateTab ( index ) ; } param index scrollIntoView ( index ) { this . foundation . scrollIntoView ( index ) ; } /**
     * Returns all the tab elements in a nice clean array
     */ private getTabElements ( ) { return [ ] . slice . call ( this . root . querySelectorAll ( strings . TAB_SELECTOR ) ) ; } /**
     * Instantiates tab components on all child tab elements
     */ private instantiateTabs ( tabFactory ) { return this . getTabElements ( ) . map ( ( el ) => { el . id = el . id || `mdc-tab-${ ++ tabIdCounter }` ; return tabFactory ( el ) ; } ) ; } /**
     * Instantiates tab scroller component on the child tab scroller element
     */ private instantiatetabScroller ( tabScrollerFactory ) { const tabScrollerElement = this . root . querySelector ( strings . TAB_SCROLLER_SELECTOR ) ; if ( tabScrollerElement ) { return tabScrollerFactory ( tabScrollerElement ) ; } return null ; } }