JSFiddle - React, Tailwind, and code Playground

by Tom Randolph

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.16.6/lodash.min.js"></script>
<table>
    <thead id="table-head"></thead>
</table>

SCSS

table{
    font-family: helvetica, arial, sans-serif;
}

tbody td,
th{
    text-align: center;
}

tr{
    th{
        padding: 8px;
        background-color: #CCCCCC;
    }
    
    + tr{
        th{
            background-color: #DDDDDD;
        }
        
        + tr{
            th{
                background-color: #EEEEEE;
            }
        }
    }
}

JavaScript

function columnWidth( column, maximum = 1 ){
    var children = column.children || [];
    var childrenCount = children.length;
    var childrenWidth = 0;

    if( childrenCount ){
        childrenWidth = _.sum(
            _.map(
                children,
                ( childColumn ) => columnWidth( childColumn )
            )
        );

        maximum = _.max( [
            maximum,
            childrenCount,
            childrenWidth
        ] );
    }

    return maximum;
}

function columnDepth( column, maximum = 1 ){
    var children = column.children || [];

    if( children.length !== 0 ){
        maximum = 1;
    }

    return maximum;
}

function getRow( columns, depth ){
    if( depth > 0 && columns.length ){
        columns = getRow(
            _.flatMap( columns, "children" ),
            depth - 1
        );
    }
    else if( depth == 0 && columns.length ){
        columns = _.filter( columns, ( column ) => !!column );
    }

    return columns;
}

function extractDefinitionToRows( definition ){
    var rows = [];
    var row = 0;

    while( getRow( definition, row ).length ){
        rows.push( getRow( definition, row ) );
        row++;
    }

    return rows;
}

function extractDefinitionToWidths( definition ){
    var rows = extractDefinitionToRows( definition );

    return _.map(
        rows,
        ( columns ) => _.map(
            columns,
            ( column ) => columnWidth( column )
        )
    );
}

function extractDefinitionToDepths( definition ){
    var rows = extractDefinitionToRows( definition );

    return _.map(
        rows,
        ( columns, rowIdx ) => _.map(
            columns,
            ( column ) => columnDepth( column, rows.length - rowIdx )
        )
    );
}

var table = {
    "head": [
        {
            "display": "Column 1",
            "name": "col-key-1"
        },
        {
            "display": "Column 2",
            "name": "col-key-2",
            "children": [
                {
           ...