UNPKG

@bigfishtv/cockpit

Version:

81 lines (71 loc) 1.74 kB
import React, { Component } from 'react' import PropTypes from 'prop-types' /** * This component uses the ResizeObserver API to * detect when its size changes (due to children) * and ensures it never shrinks below the tallest * content height. This is helpful to prevent * visual jerkiness due to content height shrinking * and forcing the browser to "scroll up". * * Can be used as a normal component which will * render a div of its own. * * <MinimumHeight> * <Child /> * <Child /> * </MinimumHeight> * * Alternative usage is to use a function as a child. * * <MinimumHeight> * {(forwardRef, minHeight) => ( * <main ref={forwardRef} style={{ minHeight }}> * <Child /> * <Child /> * </main> * )} * </MinimumHeight> */ export default class MinimumHeight extends Component { static propTypes = { minHeight: PropTypes.number, } static defaultProps = { minHeight: 0, } state = { minHeight: this.props.minHeight, } componentWillUnmount() { if (this.ro && this.el) { this.ro.unobserve(this.el) } } registerElement = el => { if (!el && this.el && this.ro) { this.ro.unobserve(this.el) } this.el = el if (this.el && !this.ro) { this.ro = new window.ResizeObserver(entries => { const height = entries[0].contentRect.height if (height > this.state.minHeight) { this.setState({ minHeight: height }) } }) this.ro.observe(this.el) } } render() { if (typeof this.props.children === 'function') { return this.props.children(this.registerElement, this.state.minHeight) } else { return ( <div ref={this.registerElement} style={{ minHeight: this.state.minHeight }}> {this.props.children} </div> ) } } }