license import { MDCComponent } from '@material/base/component' ; import { SpecificEventListener } from '@material/base/types' ; import { FocusTrap } from '@material/dom/focus-trap' ; import { MDCList , MDCListFactory } from '@material/list/component' ; import { MDCDrawerAdapter } from './adapter' ; import { MDCDismissibleDrawerFoundation } from './dismissible/foundation' ; import { MDCModalDrawerFoundation } from './modal/foundation' ; import * as util from './util' ; import { MDCDrawerFocusTrapFactory } from './util' ; const { cssClasses , strings } = MDCDismissibleDrawerFoundation ; events events export class MDCDrawer extends MDCComponent < MDCDismissibleDrawerFoundation > { static override attachTo ( root ) { return new MDCDrawer ( root ) ; } return get open ( ) : boolean { return this . foundation . isOpen ( ) ; } /**
     * Toggles the drawer open and closed.
     */ set open ( isOpen ) { if ( isOpen ) { this . foundation . open ( ) ; } else { this . foundation . close ( ) ; } } private previousFocus ? : Element | null ; private scrim ! : HTMLElement | null ; private innerList ? : MDCList ; private focusTrap ? : FocusTrap ; private focusTrapFactory ! : MDCDrawerFocusTrapFactory ; private handleScrimClick ? : SpecificEventListener < 'click' > ; private handleKeydown ! : SpecificEventListener < 'keydown' > ; private handleTransitionEnd ! : SpecificEventListener < 'transitionend' > ; get list ( ) : MDCList | undefined { return this . innerList ; } override initialize ( focusTrapFactory = ( el ) => new FocusTrap ( el ) , listFactory = ( el ) => new MDCList ( el ) ) { const listEl = this . root . querySelector ( strings . LIST_SELECTOR ) ; if ( listEl ) { this . innerList = listFactory ( listEl ) ; this . innerList . wrapFocus = true ; } this . focusTrapFactory = focusTrapFactory ; } override initialSyncWithDOM ( ) { const { MODAL } = cssClasses ; const { SCRIM_SELECTOR } = strings ; this . scrim = ( this . root . parentNode as Element ) . querySelector < HTMLElement > ( SCRIM_SELECTOR ) ; if ( this . scrim && this . root . classList . contains ( MODAL ) ) { this . handleScrimClick = ( ) => ( this . foundation as MDCModalDrawerFoundation ) . handleScrimClick ( ) ; this . scrim . addEventListener ( 'click' , this . handleScrimClick ) ; this . focusTrap = util . createFocusTrapInstance ( this . root as HTMLElement , this . focusTrapFactory ) ; } this . handleKeydown = ( evt ) => { this . foundation . handleKeydown ( evt ) ; } ; this . handleTransitionEnd = ( evt ) => { this . foundation . handleTransitionEnd ( evt ) ; } ; this . listen ( 'keydown' , this . handleKeydown ) ; this . listen ( 'transitionend' , this . handleTransitionEnd ) ; } override destroy ( ) { this . unlisten ( 'keydown' , this . handleKeydown ) ; this . unlisten ( 'transitionend' , this . handleTransitionEnd ) ; if ( this . innerList ) { this . innerList . destroy ( ) ; } const { MODAL } = cssClasses ; if ( this . scrim && this . handleScrimClick && this . root . classList . contains ( MODAL ) ) { this . scrim . removeEventListener ( 'click' , this . handleScrimClick ) ; this . open = false ; } } override getDefaultFoundation ( ) { const adapter = { addClass : ( className ) => { this . root . classList . add ( className ) ; } , removeClass : ( className ) => { this . root . classList . remove ( className ) ; } , hasClass : ( className ) => this . root . classList . contains ( className ) , elementHasClass : ( element , className ) => element . classList . contains ( className ) , saveFocus : ( ) => { this . previousFocus = document . activeElement ; } , restoreFocus : ( ) => { const previousFocus = this . previousFocus as HTMLOrSVGElement | null ; if ( previousFocus && previousFocus . focus && this . root . contains ( document . activeElement ) ) { previousFocus . focus ( ) ; } } , focusActiveNavigationItem : ( ) => { const activeNavItemEl = this . root . querySelector < HTMLElement > ( strings . LIST_ITEM_ACTIVATED_SELECTOR ) ; if ( activeNavItemEl ) { activeNavItemEl . focus ( ) ; } } , notifyClose : ( ) => { this . emit ( strings . CLOSE_EVENT , { } , true ) ; } , notifyOpen : ( ) => { this . emit ( strings . OPEN_EVENT , { } , true ) ; } , trapFocus : ( ) => { this . focusTrap ! . trapFocus ( ) ; } , releaseFocus : ( ) => { this . focusTrap ! . releaseFocus ( ) ; } , } ; const { DISMISSIBLE , MODAL } = cssClasses ; if ( this . root . classList . contains ( DISMISSIBLE ) ) { return new MDCDismissibleDrawerFoundation ( adapter ) ; } else if ( this . root . classList . contains ( MODAL ) ) { return new MDCModalDrawerFoundation ( adapter ) ; } else { throw new Error ( `MDCDrawer: Failed to instantiate component. Supported variants are ${ DISMISSIBLE } and ${ MODAL }.` ) ; } } }