license import { MDCComponent } from '@material/base/component' ; import { SpecificEventListener } from '@material/base/types' ; import { FocusTrap } from '@material/dom/focus-trap' ; import { closest } from '@material/dom/ponyfill' ; import { MDCBannerAdapter } from './adapter' ; import { CloseReason , events , MDCBannerActionEventDetail , MDCBannerCloseEventDetail , MDCBannerFocusTrapFactory , selectors } from './constants' ; import { MDCBannerFoundation } from './foundation' ; /** Vanilla JS implementation of banner component. */ export class MDCBanner extends MDCComponent < MDCBannerFoundation > { static override attachTo ( root ) { return new MDCBanner ( root ) ; } override root ! : HTMLElement ; private handleContentClick ! : SpecificEventListener < 'click' > ; private primaryActionEl ! : HTMLElement ; private secondaryActionEl ! : HTMLElement | null ; private textEl ! : HTMLElement ; private contentEl ! : HTMLElement ; private focusTrap ! : FocusTrap ; private focusTrapFactory ! : MDCBannerFocusTrapFactory ; override initialize ( focusTrapFactory = ( el , focusOptions ) => new FocusTrap ( el , focusOptions ) ) { this . contentEl = this . root . querySelector ( selectors . CONTENT ) as HTMLElement ; this . textEl = this . root . querySelector ( selectors . TEXT ) as HTMLElement ; this . primaryActionEl = this . root . querySelector ( selectors . PRIMARY_ACTION ) as HTMLElement ; this . secondaryActionEl = this . root . querySelector ( selectors . SECONDARY_ACTION ) as HTMLElement ; this . focusTrapFactory = focusTrapFactory ; this . handleContentClick = ( evt ) => { const target = evt . target as Element ; if ( closest ( target , selectors . PRIMARY_ACTION ) ) { this . foundation . handlePrimaryActionClick ( ) ; } else if ( closest ( target , selectors . SECONDARY_ACTION ) ) { this . foundation . handleSecondaryActionClick ( ) ; } } ; } override initialSyncWithDOM ( ) { this . registerContentClickHandler ( this . handleContentClick ) ; this . focusTrap = this . focusTrapFactory ( this . root , { initialFocusEl : this . primaryActionEl } ) ; } override destroy ( ) { super . destroy ( ) ; this . deregisterContentClickHandler ( this . handleContentClick ) ; } layout ( ) { this . foundation . layout ( ) ; } /**
     * Opens the banner and fires events.OPENING to indicate the beginning of its
     * opening animation and then events.OPENED once the animation finishes.
     */ open ( ) { this . foundation . open ( ) ; } param reason close ( reason ) { this . foundation . close ( reason ) ; } override getDefaultFoundation ( ) { const adapter = { addClass : ( className ) => { this . root . classList . add ( className ) ; } , getContentHeight : ( ) => { return this . contentEl . offsetHeight ; } , notifyClosed : ( reason ) => { this . emit < MDCBannerCloseEventDetail > ( events . CLOSED , { reason } ) ; } , notifyClosing : ( reason ) => { this . emit < MDCBannerCloseEventDetail > ( events . CLOSING , { reason } ) ; } , notifyOpened : ( ) => { this . emit ( events . OPENED , { } ) ; } , notifyOpening : ( ) => { this . emit ( events . OPENING , { } ) ; } , notifyActionClicked : ( action ) => { this . emit < MDCBannerActionEventDetail > ( events . ACTION_CLICKED , { action } ) ; } , releaseFocus : ( ) => { this . focusTrap . releaseFocus ( ) ; } , removeClass : ( className ) => { this . root . classList . remove ( className ) ; } , setStyleProperty : ( propertyName , value ) => { this . root . style . setProperty ( propertyName , value ) ; } , trapFocus : ( ) => { this . focusTrap . trapFocus ( ) ; } , } ; return new MDCBannerFoundation ( adapter ) ; } get isOpen ( ) : boolean { return this . foundation . isOpen ( ) ; } getText ( ) { return this . textEl . textContent || '' ; } setText ( text ) { this . textEl . textContent = text ; } getPrimaryActionText ( ) { return this . primaryActionEl . textContent || '' ; } setPrimaryActionText ( actionButtonText ) { this . primaryActionEl . textContent = actionButtonText ; } /** Returns null if the banner has no secondary action. */ getSecondaryActionText ( ) { return this . secondaryActionEl ? this . secondaryActionEl . textContent || '' : null ; } setSecondaryActionText ( actionButtonText ) { if ( this . secondaryActionEl ) { this . secondaryActionEl . textContent = actionButtonText ; } } private registerContentClickHandler ( handler ) { this . contentEl . addEventListener ( 'click' , handler as EventListener ) ; } private deregisterContentClickHandler ( handler ) { this . contentEl . removeEventListener ( 'click' , handler as EventListener ) ; } }