license import { MDCFoundation } from '@material/base/foundation' ; import { MDCBannerAdapter } from './adapter' ; import { Action , CloseReason , cssClasses , numbers } from './constants' ; const { OPENING , OPEN , CLOSING } = cssClasses ; /**
 * Foundation class for banner. Responsibilities include opening and closing the
 * banner.
 */ export class MDCBannerFoundation extends MDCFoundation < MDCBannerAdapter > { static override get defaultAdapter ( ) : MDCBannerAdapter { return { addClass : ( ) => undefined , getContentHeight : ( ) => 0 , notifyClosed : ( ) => undefined , notifyClosing : ( ) => undefined , notifyOpened : ( ) => undefined , notifyOpening : ( ) => undefined , notifyActionClicked : ( ) => undefined , releaseFocus : ( ) => undefined , removeClass : ( ) => undefined , setStyleProperty : ( ) => undefined , trapFocus : ( ) => undefined , } ; } private isOpened = false ; private animationFrame = 0 ; private animationTimer = 0 ; constructor ( adapter ? ) { super ( { ... MDCBannerFoundation . defaultAdapter , ... adapter } ) ; } override destroy ( ) { cancelAnimationFrame ( this . animationFrame ) ; this . animationFrame = 0 ; clearTimeout ( this . animationTimer ) ; this . animationTimer = 0 ; } open ( ) { this . isOpened = true ; this . adapter . notifyOpening ( ) ; this . adapter . removeClass ( CLOSING ) ; this . adapter . addClass ( OPENING ) ; const contentHeight = this . adapter . getContentHeight ( ) ; this . animationFrame = requestAnimationFrame ( ( ) => { this . adapter . addClass ( OPEN ) ; this . adapter . setStyleProperty ( 'height' , `${ contentHeight }px` ) ; this . animationTimer = setTimeout ( ( ) => { this . handleAnimationTimerEnd ( ) ; this . adapter . trapFocus ( ) ; this . adapter . notifyOpened ( ) ; } , numbers . BANNER_ANIMATION_OPEN_TIME_MS ) ; } ) ; } param reason close ( reason ) { if ( ! this . isOpened ) { return ; } cancelAnimationFrame ( this . animationFrame ) ; this . animationFrame = 0 ; this . isOpened = false ; this . adapter . notifyClosing ( reason ) ; this . adapter . addClass ( CLOSING ) ; this . adapter . setStyleProperty ( 'height' , '0' ) ; this . adapter . removeClass ( OPEN ) ; this . adapter . removeClass ( OPENING ) ; clearTimeout ( this . animationTimer ) ; this . animationTimer = setTimeout ( ( ) => { this . adapter . releaseFocus ( ) ; this . handleAnimationTimerEnd ( ) ; this . adapter . notifyClosed ( reason ) ; } , numbers . BANNER_ANIMATION_CLOSE_TIME_MS ) ; } isOpen ( ) { return this . isOpened ; } handlePrimaryActionClick ( disableAutoClose = false ) { if ( disableAutoClose ) { this . adapter . notifyActionClicked ( Action . PRIMARY ) ; } else { this . close ( CloseReason . PRIMARY ) ; } } handleSecondaryActionClick ( disableAutoClose = false ) { if ( disableAutoClose ) { this . adapter . notifyActionClicked ( Action . SECONDARY ) ; } else { this . close ( CloseReason . SECONDARY ) ; } } layout ( ) { const contentHeight = this . adapter . getContentHeight ( ) ; this . adapter . setStyleProperty ( 'height' , `${ contentHeight }px` ) ; } private handleAnimationTimerEnd ( ) { this . animationTimer = 0 ; this . adapter . removeClass ( OPENING ) ; this . adapter . removeClass ( CLOSING ) ; } }