This repository has been archived on 2025-09-19. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
repertory-ui/src/components/UI/Grid/Grid.js
2021-03-09 10:56:15 -06:00

145 lines
3.5 KiB
JavaScript

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 (
<GridComponent row={row}
col={col}
rowSpan={rowSpan}
colSpan={colSpan}
key={'gc_' + i}>
{child}
</GridComponent>
);
} 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 (
<div
ref='GridOwner'
className={'GridOwner'}>
<div className={'Grid'} {...style}>
{children}
</div>
</div>
)
}
};