import { Required } from 'utility-types' ; import { TooltipPortalSettings , Placement } from './types' ; internal export const DEFAULT_POPPER_SETTINGS = { fallbackPlacements : [ Placement . Right , Placement . Left , Placement . Top , Placement . Bottom ] , placement : Placement . Right , offset : 10 , } ; internal export function getOrCreateNode ( id , className ? , parent = document . body , zIndex = 0 ) { const node = document . getElementById ( id ) ; if ( node ) { return node as HTMLDivElement ; } const newNode = document . createElement ( 'div' ) ; newNode . id = id ; if ( className ) { newNode . classList . add ( className ) ; } newNode . style . zIndex = `${ zIndex }` ; parent . appendChild ( newNode ) ; return newNode ; } link internal export function isHTMLElement ( value ) { return typeof value === 'object' && value !== null && value . hasOwnProperty ( 'nodeName' ) ; } param element { HTMLElement } param cousin { HTMLElement } returns { number } internal export function getElementZIndex ( element , cousin ) { /**
     * finding the z-index of `element` is not the full story
     * its the CSS stacking context that is important
     * take this DOM for example:
     * body
     *   section[z-index: 1000]
     *     p[z-index: 500]
     *       button
     *   div
     *
     * what z-index does the `div` need to display next to `button`?
     * the `div` and `section` are where the stacking context splits
     * so `div` needs to copy `section`'s z-index in order to
     * appear next to / over `button`
     *
     * calculate this by starting at `button` and finding its offsetParents
     * then walk the parents from top -> down until the stacking context
     * split is found, or if there is no split then a specific z-index is unimportant
     */ const nodesToInspect = [ ] ; while ( true ) { nodesToInspect . push ( element ) ; element = element . offsetParent as HTMLElement ; if ( ! element ) { break ; } if ( element . contains ( cousin ) ) { break ; } } for ( let i = nodesToInspect . length - 1 ; i >= 0 ; i -- ) { const node = nodesToInspect [ i ] ; const zIndex = window . document . defaultView ! . getComputedStyle ( node ) . getPropertyValue ( 'z-index' ) ; const parsedZIndex = parseInt ( zIndex , 10 ) ; if ( Number . isFinite ( parsedZIndex ) ) { return parsedZIndex ; } } return 0 ; }