import React, {Component} from 'react'; import './Grid.css'; import GridComponent from './GridComponent/GridComponent'; const DEFAULT_GRID_SIZE = 4; export default class Grid extends Component { resizeTimeout; state = { calculated: false, dimensions: { columns: 0, rows: 0 } }; calculateDimensions = size => { return { columns: Math.floor(size.width / this.getGridSize()), rows: Math.floor(size.height / this.getGridSize()) }; }; componentDidMount() { window.addEventListener('resize', this.handleResize); this.updateSizeAsync(); } componentWillUnmount() { window.removeEventListener('resize', this.handleResize); clearInterval(this.resizeTimeout); }; getGridSize = () => { return this.props.gridSize || DEFAULT_GRID_SIZE; }; getGridSizePx = () => { return this.getGridSize() + 'px '; }; getSize = () => { const elem = this.refs.GridOwner; return { height: elem ? elem.offsetHeight : 0, width: elem ? elem.offsetWidth : 0 }; }; handleResize = () => { clearTimeout(this.resizeTimeout); this.resizeTimeout = setTimeout(this.updateSizeAsync, 10); }; updateSize = () => { const state = { ...this.state }; const size = this.getSize(); const dimensions = this.calculateDimensions(size); if (state.dimensions !== dimensions) { this.setState({ calculated: true, dimensions: dimensions }) } }; updateSizeAsync = () => { return new Promise(() => { this.updateSize(); }); }; render() { let children = null; const dimensions = this.state.dimensions; if (this.state.calculated) { children = React.Children.map(this.props.children, (child, i) => { if (child) { let row = child.props.row || 0; if (typeof(row) === 'function') { row = row(dimensions); } let col = child.props.col || 0; if (typeof(col) === 'function') { col = col(dimensions); } let rowSpan = child.props.rowSpan; if (typeof(rowSpan) === 'function') { rowSpan = rowSpan(dimensions.rows - row, dimensions.rows); } let colSpan = child.props.colSpan; if (typeof(colSpan) === 'function') { colSpan = colSpan(dimensions.columns - col, dimensions.columns); } rowSpan = rowSpan ? (rowSpan === 'remain' ? (dimensions.rows - row) : rowSpan) : null; colSpan = colSpan ? (colSpan === 'remain' ? dimensions.columns - col : colSpan) : null; return ( {child} ); } else { return null; } }); } const gridSizePx = this.getGridSizePx(); let style = { style: { gridTemplateColumns: gridSizePx.repeat(dimensions.columns), gridTemplateRows: gridSizePx.repeat(dimensions.rows), gridAutoColumns: gridSizePx, gridAutoRows: gridSizePx, } }; if (this.props.noScroll) { style['style'].overflowX = 'visible'; style['style'].overflowY = 'visible'; } return (
{children}
) } };