Grid

by evgkch

HTML

<div id="app"></div>

CSS

body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}

li {
  margin: 8px 0;
}

h2 {
  font-weight: bold;
  margin-bottom: 15px;
}

.done {
  color: rgba(0, 0, 0, 0.3);
  text-decoration: line-through;
}

input {
  margin-right: 5px;
}
div {
  border: solid 1px black;
}

React

const Safe = {
  get(target, path){
    return _get(target, path.split('.'));
  	function _get(target, [firstProp, ...restProps]) {
    	return typeof target == 'object' && target != null
        ? target[firstProp]
            ? _get(target[firstProp], restProps)
            : target[firstProp]
        : target;
    }
  },
  setToArray(data, target, path){
  	_set(target, path.split('.'));
  	function _set(target, [firstIndex, ...restIndeces]){
    	if (restIndeces.length > 0)
      {
      	if (!Array.isArray(target[firstIndex]))
        	target[firstIndex] = [];
        _set(target[firstIndex], restIndeces)
      }
      else
      	target[firstIndex] = data;
    }
  },
};

const grid = [
	{
  	path: '1.1',
    flex: 2,    
    render: () => '1.1',
  },
  {
  	path: '1.2',
    flex: 10,
    render: () => '1.2',
  },
  {
  	path: '2.1',    
    render: () => '2.1',
  },
  {
  	path: '2.2',
    render: () => '2.2',
  },
  {
  	path: '2.3',
    render: () => '2.3',
  },
  {
  	path: '3.1.1',
    render: () => '3.1.1',
  },
  {
  	path: '3.1.2',
    render: () => '3.1.2',
  },
];

class Grid extends React.Component {

	get grid() {
  	const grid = [];
    this.props.grid.forEach((item, i) => {
    	Safe.setToArray(i, grid, item.path);
    });
    return grid;
  }

  constructor(props) {
    super(props);
    this.state = {
    	grid: this.grid,
    	flexBox: this.props.grid.map(item => item.flex || 1),
    };
    this.style = {
    	box: {
      	display: 'flex',
        justifyContent: 'center',
        alignItems: 'center',
      },
    };
  }
  
  renderGrid(grid) {
  	return grid.map((item, i) => {
    	if (Array.isArray(item))
      	return (
        	<div key={i}
          style={this.style.box}>
            {this.renderGrid(item)}
          </div>
        );
      else
      	return this.renderGridItem(item);
    });    
  }
  
  renderGridItem(item) {
  	const index = parseInt(item);
    const flex = this.state.flexBox[index];
    const el =...