license import { MDCComponent } from '@material/base/component' ; import { SpecificEventListener } from '@material/base/types' ; import { MDCRipple , MDCRippleFactory } from '@material/ripple/component' ; import { MDCTopAppBarAdapter } from './adapter' ; import { cssClasses , strings } from './constants' ; import { MDCFixedTopAppBarFoundation } from './fixed/foundation' ; import { MDCTopAppBarBaseFoundation } from './foundation' ; import { MDCShortTopAppBarFoundation } from './short/foundation' ; import { MDCTopAppBarFoundation } from './standard/foundation' ; export class MDCTopAppBar extends MDCComponent < MDCTopAppBarBaseFoundation > { static override attachTo ( root ) { return new MDCTopAppBar ( root ) ; } private handleNavigationClick ! : SpecificEventListener < 'click' > ; private handleWindowResize ! : SpecificEventListener < 'resize' > ; private handleTargetScroll ! : SpecificEventListener < 'scroll' > ; private navIcon ! : Element | null ; private iconRipples ! : MDCRipple [ ] ; private scrollTarget ! : EventTarget ; override initialize ( rippleFactory = ( el ) => MDCRipple . attachTo ( el ) ) { this . navIcon = this . root . querySelector ( strings . NAVIGATION_ICON_SELECTOR ) ; const icons = [ ] . slice . call ( this . root . querySelectorAll ( strings . ACTION_ITEM_SELECTOR ) ) ; if ( this . navIcon ) { icons . push ( this . navIcon ) ; } this . iconRipples = icons . map ( ( icon ) => { const ripple = rippleFactory ( icon ) ; ripple . unbounded = true ; return ripple ; } ) ; this . scrollTarget = window ; } override initialSyncWithDOM ( ) { this . handleNavigationClick = this . foundation . handleNavigationClick . bind ( this . foundation ) ; this . handleWindowResize = this . foundation . handleWindowResize . bind ( this . foundation ) ; this . handleTargetScroll = this . foundation . handleTargetScroll . bind ( this . foundation ) ; this . scrollTarget . addEventListener ( 'scroll' , this . handleTargetScroll as EventListener ) ; if ( this . navIcon ) { this . navIcon . addEventListener ( 'click' , this . handleNavigationClick as EventListener ) ; } const isFixed = this . root . classList . contains ( cssClasses . FIXED_CLASS ) ; const isShort = this . root . classList . contains ( cssClasses . SHORT_CLASS ) ; if ( ! isShort && ! isFixed ) { window . addEventListener ( 'resize' , this . handleWindowResize as EventListener ) ; } } override destroy ( ) { for ( const iconRipple of this . iconRipples ) { iconRipple . destroy ( ) ; } this . scrollTarget . removeEventListener ( 'scroll' , this . handleTargetScroll as EventListener ) ; if ( this . navIcon ) { this . navIcon . removeEventListener ( 'click' , this . handleNavigationClick as EventListener ) ; } const isFixed = this . root . classList . contains ( cssClasses . FIXED_CLASS ) ; const isShort = this . root . classList . contains ( cssClasses . SHORT_CLASS ) ; if ( ! isShort && ! isFixed ) { window . removeEventListener ( 'resize' , this . handleWindowResize as EventListener ) ; } super . destroy ( ) ; } setScrollTarget ( target ) { this . scrollTarget . removeEventListener ( 'scroll' , this . handleTargetScroll as EventListener ) ; this . scrollTarget = target ; this . handleTargetScroll = this . foundation . handleTargetScroll . bind ( this . foundation ) ; this . scrollTarget . addEventListener ( 'scroll' , this . handleTargetScroll as EventListener ) ; } override getDefaultFoundation ( ) { const adapter = { hasClass : ( className ) => this . root . classList . contains ( className ) , addClass : ( className ) => this . root . classList . add ( className ) , removeClass : ( className ) => this . root . classList . remove ( className ) , setStyle : ( property , value ) => ( this . root as HTMLElement ) . style . setProperty ( property , value ) , getTopAppBarHeight : ( ) => this . root . clientHeight , notifyNavigationIconClicked : ( ) => this . emit ( strings . NAVIGATION_EVENT , { } ) , getViewportScrollY : ( ) => { const win = this . scrollTarget as Window ; const el = this . scrollTarget as Element ; return win . pageYOffset !== undefined ? win . pageYOffset : el . scrollTop ; } , getTotalActionItems : ( ) => this . root . querySelectorAll ( strings . ACTION_ITEM_SELECTOR ) . length , } ; let foundation ; if ( this . root . classList . contains ( cssClasses . SHORT_CLASS ) ) { foundation = new MDCShortTopAppBarFoundation ( adapter ) ; } else if ( this . root . classList . contains ( cssClasses . FIXED_CLASS ) ) { foundation = new MDCFixedTopAppBarFoundation ( adapter ) ; } else { foundation = new MDCTopAppBarFoundation ( adapter ) ; } return foundation ; } }