Grid Basics
Learn the fundamentals of container sizing, row/column configuration, and grid lifecycle.
Grid Basics
This guide covers the essential concepts for setting up and working with ZenGrid, including container requirements, data configuration, and lifecycle management.
Container Requirements
ZenGrid requires an explicit container size to render properly. The container element must have defined width and height in CSS.
<div id="grid-container" style="width: 800px; height: 600px;"></div>#grid-container { width: 100%; height: 100vh; /* or use specific dimensions */}Without explicit dimensions, the grid cannot calculate the viewport and virtual scrolling will not work correctly.
Row and Column Configuration
Configure the grid dimensions using rowCount and colCount:
import { createGrid } from '@zengrid/core';
const grid = createGrid({ container: document.getElementById('grid-container')!, rowCount: 1000, colCount: 10, data: (row, col) => `Cell ${row},${col}`, columns: [ { field: 'id', header: 'ID', width: 80 }, { field: 'name', header: 'Name', width: 150 }, { field: 'value', header: 'Value', width: 120 } ]});Data Callback
The data callback provides cell values on-demand during rendering:
const grid = createGrid({ container: element, rowCount: 5000, colCount: 8, data: (row, col) => { // Return cell value for the given row and column if (col === 0) return row + 1; // ID column if (col === 1) return `Item ${row}`; // Name column return Math.random() * 100; // Other columns }});The data callback is invoked only for visible cells, making it efficient for large datasets.
Column Definitions
Define columns with the ColumnDef interface:
import { ColumnDef } from '@zengrid/core';
const columns: ColumnDef[] = [ { field: 'id', header: 'ID', width: 80, type: 'number' }, { field: 'name', header: 'Name', width: 200, type: 'text' }, { field: 'active', header: 'Active', width: 100, type: 'checkbox' }];Built-in Renderers
ZenGrid includes several built-in cell renderers:
- text - Plain text display (default)
- number - Formatted number display
- checkbox - Interactive checkbox
- button - Clickable button
- link - Hyperlink with URL
- progress-bar - Progress indicator (0-100)
- chip - Tag/badge display
- select - Dropdown selection
- dropdown - Autocomplete dropdown
- date - Formatted date display
const columns: ColumnDef[] = [ { field: 'status', header: 'Status', type: 'chip', width: 120 }, { field: 'progress', header: 'Progress', type: 'progress-bar', width: 150 }, { field: 'action', header: 'Action', type: 'button', width: 100 }, { field: 'url', header: 'Link', type: 'link', width: 180 }, { field: 'created', header: 'Created', type: 'date', width: 140 }];Grid Lifecycle
Rendering
Call render() to initially render or re-render the entire grid:
grid.render();Refreshing
Use refresh() to update the grid after data changes:
// Update datagrid.setData(newData);
// Refresh the gridgrid.refresh();Dynamic Configuration
Update grid options dynamically with updateOptions():
grid.updateOptions({ rowCount: 2000, colCount: 12, overscanRows: 20});Cache Management
Clear the renderer cache when changing renderers or resetting state:
grid.clearCache();The renderer cache stores renderer instances for reuse. Clear it when switching renderer types or resetting the grid state.
Grid Inspection
Get current grid dimensions and statistics:
// Get dimensionsconst dimensions = grid.getDimensions();console.log(dimensions); // { width: 800, height: 600 }
// Get statisticsconst stats = grid.getStats();console.log(stats);// {// totalRows: 1000,// totalCols: 10,// visibleRows: 15,// visibleCols: 8,// renderedCells: 120// }Cleanup
Always call destroy() when removing the grid to clean up event listeners and resources:
// Clean up when donegrid.destroy();Failing to call destroy() can lead to memory leaks from retained event listeners and DOM references.
Complete Example
import { createGrid, ColumnDef } from '@zengrid/core';
const container = document.getElementById('grid')!;
const columns: ColumnDef[] = [ { field: 'id', header: 'ID', width: 80, type: 'number' }, { field: 'name', header: 'Name', width: 200, type: 'text' }, { field: 'status', header: 'Status', width: 120, type: 'chip' }, { field: 'progress', header: 'Progress', width: 150, type: 'progress-bar' }];
const grid = createGrid({ container, rowCount: 10000, colCount: 4, columns, data: (row, col) => { if (col === 0) return row + 1; if (col === 1) return `Item ${row}`; if (col === 2) return row % 2 === 0 ? 'Active' : 'Inactive'; if (col === 3) return (row % 100); return ''; }});
grid.render();
// Update latersetTimeout(() => { grid.updateOptions({ rowCount: 20000 }); grid.refresh();}, 5000);
// Cleanup on page unloadwindow.addEventListener('beforeunload', () => { grid.destroy();});