import * as React from "react" ; import { ElementPropsWithElementRefAndRenderer , ElementRef } from "./types" ; let doc = typeof document === "object" ? document : null ; export const isUndef = ( v ) : v is Exclude < typeof v , undefined > => { return typeof v === "undefined" ; } ; export const isFun = ( v ) : v is Function => { return typeof v === "function" ; } ; export const isNum = ( v ) : v is number => { return typeof v === "number" ; } ; description param props { ElementPropsWithElementRefAndRenderer } param elementRef { ElementRef } export const renderDivWithRenderer = ( props , elementRef ) => { if ( isFun ( props . renderer ) ) { props . elementRef = elementRef ; const renderer = props . renderer ! ; delete props . renderer ; return renderer ( props ) ; } delete props . elementRef ; return < div { ... props } ref = { elementRef } / > ; } ; const getInnerSize = ( el , dimension , padding1 , padding2 ) : number => { const styles = getComputedStyle ( el ) ; if ( styles . boxSizing === "border-box" ) { return Math . max ( 0 , ( parseFloat ( styles [ dimension ] as string ) || 0 ) - ( parseFloat ( styles [ padding1 ] as string ) || 0 ) - ( parseFloat ( styles [ padding2 ] as string ) || 0 ) ) ; } return parseFloat ( styles [ dimension ] as string ) || 0 ; } ; description export const getInnerHeight = ( el ) : number => { return getInnerSize ( el , "height" , "paddingTop" , "paddingBottom" ) ; } ; description export const getInnerWidth = ( el ) : number => { return getInnerSize ( el , "width" , "paddingLeft" , "paddingRight" ) ; } ; description export const uuid = ( ) => { let uuid = "" ; for ( let i = 0 ; i < 32 ; i ++ ) { if ( i === 8 || i === 20 ) { uuid += "-" + ( ( Math . random ( ) * 16 ) | 0 ) . toString ( 16 ) ; } else if ( i === 12 ) { uuid += "-4" ; } else if ( i === 16 ) { uuid += "-" + ( ( Math . random ( ) * 16 ) | ( 0 & 3 ) | 8 ) . toString ( 16 ) ; } else { uuid += ( ( Math . random ( ) * 16 ) | 0 ) . toString ( 16 ) ; } } return uuid ; } ; description param { number } contentSize param { number } viewportSize param { number } trackSize param { number } minimalSize param { number } maximalSize export const calcThumbSize = ( contentSize , viewportSize , trackSize , minimalSize ? , maximalSize ? ) : number => { if ( viewportSize >= contentSize ) { return 0 ; } let thumbSize = ( viewportSize / contentSize ) * trackSize ; isNum ( maximalSize ) && ( thumbSize = Math . min ( maximalSize ! , thumbSize ) ) ; isNum ( minimalSize ) && ( thumbSize = Math . max ( minimalSize ! , thumbSize ) ) ; return thumbSize ; } ; description param { number } contentSize param { number } viewportSize param { number } trackSize param { number } thumbSize param { number } scroll export const calcThumbOffset = ( contentSize , viewportSize , trackSize , thumbSize , scroll ) : number => { if ( ! scroll || ! thumbSize || viewportSize >= contentSize ) { return 0 ; } return ( ( trackSize - thumbSize ) * scroll ) / ( contentSize - viewportSize ) ; } ; description param { number } contentSize param { number } viewportSize param { number } trackSize param { number } thumbSize param { number } thumbOffset export const calcScrollForThumbOffset = ( contentSize , viewportSize , trackSize , thumbSize , thumbOffset ) : number => { if ( ! thumbOffset || ! thumbSize || viewportSize >= contentSize ) { return 0 ; } return ( thumbOffset * ( contentSize - viewportSize ) ) / ( trackSize - thumbSize ) ; } ; description export const _dbgSetDocument = ( v ) : Document | null => { if ( v === null || v instanceof HTMLDocument ) { return ( doc = v ) ; } throw new TypeError ( "override value expected to be an instance of HTMLDocument or null, got " + typeof v ) ; } ; description export const _dbgGetDocument = ( ) : Document | null => doc ; interface GetScrollbarWidthFN { _cache ? : number ; ( force ? ) : number | undefined ; } description export const getScrollbarWidth = ( force = false ) : number | undefined => { if ( ! doc ) { return ( getScrollbarWidth . _cache = 0 ) ; } if ( ! force && ! isUndef ( getScrollbarWidth . _cache ) ) { return getScrollbarWidth . _cache as number ; } let el = doc . createElement ( "div" ) ; el . setAttribute ( "style" , "position:absolute;width:100px;height:100px;top:-999px;left:-999px;overflow:scroll;" ) ; doc . body . appendChild ( el ) ; if ( el . clientWidth === 0 ) { doc . body . removeChild ( el ) ; return ; } getScrollbarWidth . _cache = 100 - el . clientWidth ; doc . body . removeChild ( el ) ; return getScrollbarWidth . _cache ; } ; interface ShouldReverseRtlScroll { _cache ? : boolean ; ( force ? ) : boolean ; } description export const shouldReverseRtlScroll = ( force = false ) : boolean => { if ( ! force && ! isUndef ( shouldReverseRtlScroll . _cache ) ) { return shouldReverseRtlScroll . _cache as boolean ; } if ( ! doc ) { return ( shouldReverseRtlScroll . _cache = false ) ; } const el = doc . createElement ( "div" ) ; const child = doc . createElement ( "div" ) ; el . appendChild ( child ) ; el . setAttribute ( "style" , "position:absolute;width:100px;height:100px;top:-999px;left:-999px;overflow:scroll;direction:rtl" ) ; child . setAttribute ( "style" , "width:1000px;height:1000px" ) ; doc . body . appendChild ( el ) ; el . scrollLeft = - 50 ; shouldReverseRtlScroll . _cache = el . scrollLeft === - 50 ; doc . body . removeChild ( el ) ; return shouldReverseRtlScroll . _cache ; } ;