import React from 'react' ; import { findDOMNode } from 'react-dom' ; import { clamp } from './math' ; import { debounce } from './event' ; import { getWindow } from './window' ; export type WindowRect = { top : number ; left : number ; height : number ; width : number ; } ; export function getWindowRect ( ) { const environment = getWindow ( ) ; return { top : environment . scrollY , left : environment . scrollX , height : environment . innerHeight , width : environment . innerWidth , } ; } export function getRectFor ( node ? ) { const rect = findDOMNode ( node ) as Element ; if ( ! rect ) { return { } as ClientRect ; } return rect . getBoundingClientRect ( ) ; } param { number } wait return { Shape } export function useWindowSize ( wait = 100 ) { const environment = getWindow ( ) ; const [ size , setSize ] = React . useState ( getWindowRect ( ) ) ; const handleResize = debounce ( ( ) => { setSize ( getWindowRect ( ) ) ; } , wait ) ; React . useEffect ( ( ) => { environment . addEventListener ( 'resize' , handleResize ) ; return ( ) => { environment . removeEventListener ( 'resize' , handleResize ) ; } ; } , [ ] ) ; return size ; } param { React Node return { Shape } export function getPreferredDirectionFor ( node ? ) { const windowRect = getWindowRect ( ) ; const elementRect = getRectFor ( node ) ; const rightOffset = windowRect . width - elementRect . right ; const bottomOffset = windowRect . height - elementRect . bottom ; return { top : bottomOffset < elementRect . top , left : rightOffset < elementRect . left , right : rightOffset >= elementRect . left , bottom : bottomOffset >= elementRect . top , } ; } param { React Node return { Shape } export function getPositionFor ( node ? , { fixed = false } = { } ) { const windowRect = getWindowRect ( ) ; const elementRect = getRectFor ( node ) ; return { top : elementRect . top + ( fixed ? 0 : windowRect . top ) , left : elementRect . left + ( fixed ? 0 : windowRect . left ) , width : elementRect . width , height : elementRect . height , } ; } param { number } min param { number } max param { number } n return { number } example export function lerp ( min , max , n ) { const value = ( max - min ) * n + min ; return clamp ( value , min , max ) ; } /**
 * Rounds a number to the nearest baseline ceiling
 */ export function roundToBaseline ( n , base = 4 ) { return Math . ceil ( n / base ) * base ; }