Create customizable grid table

by stitot

HTML

<script src="http://localhost:3031/grid/grid-lite.js"></script>

<div id="container" class="hcg-theme-default"></div>

<div>
    <div>
        <label for="select-distr">Column Distribution: </label>
        <select id="select-distr">
            <option selected>custom</option>
            <option>full</option>
            <option>fixed</option>
            <option>mixed</option>
        </select>
    </div>
    <div>
        <label for="select-virt">Virtualization: </label>
        <input type="checkbox" id="select-virt">
    </div>
</div>

CSS

@import url("http://localhost:3031/grid/css/grid.css");

.hcg-theme-default {
    --hcg-column-border-width: 1px;
}

body {
    background: #fff;
    font-family: sans-serif;
}

@media (prefers-color-scheme: dark) {
    body {
        background: #333;
        color: #eee;
    }
}

#container {
    height: 250px;
}

/* ============= */

JavaScript

class CustomDistributionStrategy extends Grid.ColumnDistribution.types.mixed {
	type = 'custom';

	resize(resizer, diff) {
        const column = resizer.draggedColumn;
        if (!column) {
            return;
        }

        this.columnWidths[column.id] = Math.max(
        	(resizer.columnStartWidth || 0) + diff,
            CustomDistributionStrategy.getMinWidth(column)
        );
        this.columnWidthUnits[column.id] = 0; // Always save in px
    }
}

Grid.ColumnDistribution.types.custom = CustomDistributionStrategy;

const grid = Grid.grid('container', {
    dataTable: {
        columns: {
            product: Array.from({ length: 40 }, (_, i) => `A${i}`),
            weight: Array.from({ length: 40 }, (_, i) => `B${i}`),
            price: Array.from({ length: 40 }, (_, i) => `C${i}`),
            icon: Array.from({ length: 40 }, (_, i) => `E${i}`),
            meta: Array.from({ length: 40 }, (_, i) => `F${i}`)
        }
    },
    rendering: {
    	columns: {
        	//distribution: 'custom'
        }
    },
    columns: [{
        id: 'product',
        header: {
        	format: '20% width'
        },
        width: '20%'
    }, {
        id: 'weight',
        header: {
        	format: '100px width'
        },
        width: '100px'
    }, {
        id: 'price',
        header: {
        	format: 'undefined width'
        },
    }, {
        id: 'icon',
        header: {
        	format: '15% width'
        },
        width: '15%'
    }, {
    	id: 'meta',
        header: {
        	format: 'undefined width'
        }
    }]
});

document.getElementById('select-distr').addEventListener('change', e => {
	grid.update({
    	rendering: {
        	columns: {
            	distribution: e.target.value
            }
        }
    })
});

document.getElementById('select-virt').addEventListener('change', e => {
	grid.update({
    	rendering: {
        	rows: {
                virtualization: e.target.checked
            }
        }
    })
})