import React from 'react' ; export type IReactComponent < P = any > = React . StatelessComponent < P > | React . ComponentClass < P > | React . ClassicComponentClass < P > ; function computeHeight ( node ) { const { style } = node ; style . height = '100%' ; const totalHeight = parseInt ( `${ getComputedStyle ( node ) . height }` , 10 ) ; const padding = parseInt ( `${ getComputedStyle ( node ) . paddingTop }` , 10 ) + parseInt ( `${ getComputedStyle ( node ) . paddingBottom }` , 10 ) ; return totalHeight - padding ; } function getAutoHeight ( n ) { if ( ! n ) { return 0 ; } const node = n ; let height = computeHeight ( node ) ; const parentNode = node . parentNode as HTMLDivElement ; if ( parentNode ) { height = computeHeight ( parentNode ) ; } return height ; } type AutoHeightProps = { height ? : number ; } ; function autoHeight ( ) { return < P extends AutoHeightProps > ( WrappedComponent ) : React . ComponentClass < P > => { class AutoHeightComponent extends React . Component < P & AutoHeightProps > { state = { computedHeight : 0 , } ; root : HTMLDivElement | undefined = undefined ; componentDidMount ( ) { const { height } = this . props ; if ( ! height ) { let h = getAutoHeight ( this . root ) ; this . setState ( { computedHeight : h } ) ; if ( h < 1 ) { h = getAutoHeight ( this . root ) ; this . setState ( { computedHeight : h } ) ; } } } handleRoot = ( node ) => { this . root = node ; } ; render ( ) { const { height } = this . props ; const { computedHeight } = this . state ; const h = height || computedHeight ; return ( < div ref = { this . handleRoot } > { h > 0 && < WrappedComponent { ... this . props } height = { h } / > } < /div>); } } return AutoHeightComponent ; } ; } export default autoHeight ;