angular data grid
Angular Data Grid: A Component For Every View
The Angular data grid, licensed per domain. Lattice Grid gives Angular a standalone component for every view it draws: the grid, the stat tiles, a chart, the board, the plan, the dashboard layout and the tab strip. Each one is compiled ahead of time, the way every Angular library you install is, so the build that goes to production is the build you already run.
Add it to an Angular app
One package. The Angular components are part of it, at their own import path, so there is one install, one version number and one licence to keep track of.
npm install @toclocoinc/lattice-grid
Import the components from @toclocoinc/lattice-grid/angular and load the
stylesheet with import '@toclocoinc/lattice-grid/css'. Angular is an optional
peer dependency, so a project that is not an Angular one installs nothing extra and sees no
warning, and the components themselves ask only for Angular 17 or newer. They run in the
browser, so a server-rendered page sends the empty host element and the view is built on
hydration.
import { Component, viewChild } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { createGrid } from '@toclocoinc/lattice-grid';
import { createKPI } from '@toclocoinc/lattice-grid/modules/kpi';
import { createChart } from '@toclocoinc/lattice-grid/modules/charts';
import '@toclocoinc/lattice-grid/css';
import {
LatticeGridComponent, LatticeKpiComponent, LatticeChartComponent, provideLattice,
} from '@toclocoinc/lattice-grid/angular';
@Component({
selector: 'app-dashboard',
imports: [LatticeGridComponent, LatticeKpiComponent, LatticeChartComponent],
template: `
<lattice-grid #grid name="quakes" [config]="config" [quickFilter]="search()"
(cell-changed)="save($event)" />
<lattice-kpi gridName="quakes" [config]="{ tiles }" />
<lattice-chart gridName="quakes" [config]="{ type: 'bar', x: 'region', y: 'count' }" />
`,
})
export class Dashboard {
// The live grid, the same object createGrid returns.
grid = viewChild<LatticeGridComponent>('grid');
}
// Each factory is injected rather than imported by the library, so an
// application that shows a grid downloads the grid and never the board,
// the plan or the chart types.
bootstrapApplication(Dashboard, {
providers: [provideLattice({ createGrid, createKPI, createChart })],
});
A component per view, not a grid and seven lifecycle hooks
<lattice-grid> is the grid, and [latticeGrid] puts the same
thing on an element your template already owns. Beside them are
<lattice-kpi>, <lattice-chart>,
<lattice-kanban>, <lattice-gantt>,
<lattice-layout> and <lattice-tabs>, so a whole dashboard
is a template rather than a page of ngAfterViewInit and
ngOnDestroy pairs written once per view. Every grid event is an output under its
kebab-case name, so (cell-changed), (cell-edit-start) and
(selection-changed) bind the way any Angular output does, and
(grid-ready) hands you the live grid.
Views find their grid, whatever order they mount in
Give a grid a name and any grid-bound view takes that name through
gridName. A stat panel written above its grid in the template mounts itself the
moment the grid arrives, which is the case a template reference cannot answer. A tab's content
is your own <ng-template latticeTab="id">, rendered inside the strip with
your injectors above it, and configuration-driven tabs still work on the same strip. The data
router is a service: put provideLatticeRouter in a component's providers and one
feed drives every view underneath it, created and torn down with that component.
Fast by default, in a zone or without one
The grid paints on its own schedule rather than Angular's, so scrolling a million rows costs
no change detection and an output nobody bound costs nothing at all. Zoneless change detection
and OnPush both work with nothing to configure, and a host component that never
re-renders still holds a fully live grid. A changed input reaches the view already on screen,
so scroll position, selection, expansion and any open editor survive it, and an input a view
cannot take while it is running is named in a warning rather than dropped in silence.
ngOnDestroy takes the whole thing down and leaves no interval or listener behind.
The integration reference lists every component, its
inputs and its outputs, and the module map shows what each view costs
to add. If you would rather not take a component at all, createGrid works on a
host element you own, and the custom elements give you a tag
per view with no bundler. Type declarations ship with the package.
One grid, every framework
Lattice Grid is not framework-coupled. The same engine renders in Angular, in another
framework, or on a plain HTML page, and behaves identically in each, so a team moving between
them learns one API and tests one set of behaviours. What changes is only the way a view is
declared: an Angular template, a
React component, a Vue component,
a Svelte component, or a
<lattice-grid> tag on a page with no build step at all. Type declarations
ship with the package, so TypeScript projects get full IntelliSense with no extra setup.
Priced per domain, not per developer
A licence covers the domain the grid runs on, not the person: add developers, contractors and agencies without adding cost, and without an audit conversation. Development on localhost is free and needs no key. Deployment is $1,000 per domain, or $10,000 for a wildcard covering every subdomain, both with a year of support and unlimited developers.
Read the docs See it running Free on localhost. See pricing.
By feature
Full source, a live embed and Angular-specific caveats for each: