export * from './presence-handler' ; export const nextTick = ( cb ) => Promise . resolve ( ) . then ( cb ) ; export const presence = ( element , hooks = { } ) => { const { afterSelf } = hooks ; return new Promise ( async ( resolve ) => { if ( typeof element . dataset . hold !== 'undefined' && 'MutationObserver' in window ) { const mo = new MutationObserver ( ( [ record ] ) => { if ( typeof ( record . target as HTMLElement ) . dataset . hold === 'undefined' ) { afterSelf ?. ( ) ; resolve ( ) ; } } ) ; mo . observe ( element , { attributeFilter : [ 'data-hold' ] , attributes : true , } ) ; return ; } if ( typeof element . getAnimations !== 'undefined' ) { Promise . all ( element . getAnimations ( ) . map ( anim => anim . finished ) ) . then ( ( ) => { afterSelf ?. ( ) ; resolve ( ) ; return ; } ) ; } else { const { animationName , animationDuration , transitionDuration , } = window . getComputedStyle ( element ) ; if ( animationName !== 'none' && animationDuration !== '0s' ) { listen ( 'animation' ) ; } else if ( transitionDuration !== '0s' ) { listen ( 'transition' ) ; } else { afterSelf ?. ( ) ; resolve ( ) ; } function listen ( name ) { element . addEventListener ( `${ name }end` , onEnd ( name ) ) ; } function onEnd ( name ) { return function ( event ) { if ( event . target !== element ) return ; element . removeEventListener ( `${ name }end` , this ) ; afterSelf ?. ( ) ; resolve ( ) ; return ; } ; } } } ) ; } ; const kebab = ( str ) => str . replace ( /([A-Z])/g , `-$1` ) . toLowerCase ( ) ; type Primitive = string | number | boolean | null | undefined ; export const setCustomProperties = ( el , props ? ) => { const customProps = convertToCustomProperties ( props ) ; for ( const [ key , value ] of Object . entries ( customProps ) ) { el . style . setProperty ( key , value ) ; } } ; const convertToCustomProperties = ( o , prefix = '--' , result = { } ) : Record < string , string > => { if ( o == null ) return result ; switch ( typeof o ) { case 'string' : { result [ kebab ( prefix ) ] = o ; return result ; } case 'number' : { result [ kebab ( prefix ) ] = o . toString ( 10 ) ; return result ; } case 'boolean' : { result [ kebab ( prefix ) ] = o ? `1` : `0` ; return result ; } default : break ; } if ( Array . isArray ( o ) || typeof o === 'object' ) { for ( let [ key , value ] of Object . entries ( o ) ) { const name = [ prefix , ! prefix . endsWith ( '-' ) && '-' , key ] . filter ( Boolean ) . join ( '' ) ; convertToCustomProperties ( value , name , result ) ; } return result ; } return result ; } ; export const isHTMLElement = ( node ) : node is HTMLElement => node && node . nodeType === node . ELEMENT_NODE && typeof ( node as HTMLElement ) . tagName !== 'undefined' ; export const hasData = ( el , key ) => typeof el . dataset [ key ] !== 'undefined' ; export function closest ( selector , base = this ) { try { function closestFrom ( el ) { if ( ! el || el === document || el === window ) return null ; let found = ( el as HTMLElement ) . closest ( selector ) ; return found ? found : closestFrom ( ( ( el as HTMLElement ) . getRootNode ( ) as any ) . host ) ; } return closestFrom ( base ) ; } catch ( e ) { return null ; } } export const getTopLevelChildren = ( el ) : HTMLAnimatePresenceElement [ ] => { const all = Array . from ( el . querySelectorAll ( 'animate-presence' ) ) ; const nested = Array . from ( el . querySelectorAll ( ':scope animate-presence animate-presence' ) ) ; return all . filter ( el => ! nested . includes ( el ) ) ; } ; export const exitChildren = async ( el ) => { return Promise . all ( getTopLevelChildren ( el ) . map ( ( el ) => el . exit ( ) ) ) ; } ; export const enterChildren = async ( el ) => { return Promise . all ( getTopLevelChildren ( el ) . map ( ( el ) => el . enter ( ) ) ) ; } ; export const injectGlobalStyle = ( ) => { let ss = document . head . querySelector ( '[data-ap-global]' ) ; if ( ss ) return ; ss = document . createElement ( 'style' ) ; ( ss as HTMLElement ) . dataset . apGlobal = '' ; ss . textContent = `animate-presence>[data-enter][style*="--i:"],animate-presence>[data-exit][style*="--i:"]{animation-fill-mode:both;}` ; document . head . appendChild ( ss ) ; } ;