npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@lightfastgrid/angular

v0.2.0

Published

Angular package for LightFastGrid, a JavaScript data grid for large client-side datasets.

Readme

LightFastGrid for Angular

@lightfastgrid/angular integrates LightFastGrid with standalone Angular components. It is MIT licensed. The declared @angular/core and @angular/common peer range is exactly ^20.3.0 || ^21.0.0 || ^22.0.0.

Install

Install from npm when the package release is available:

npm install @lightfastgrid/angular @lightfastgrid/core
pnpm add @lightfastgrid/angular @lightfastgrid/core
yarn add @lightfastgrid/angular @lightfastgrid/core

Core is also a runtime dependency of the Angular package. Declare it directly because the example imports its CSS and types; pnpm's strict resolution does not expose nested dependencies to application imports.

Quick start

import { Component } from '@angular/core';
import { LightFastGridComponent } from '@lightfastgrid/angular';
import type { ColumnDef, RowData } from '@lightfastgrid/core';

type Order = { id: string; customer: string; total: number };

@Component({
  selector: 'orders-page',
  standalone: true,
  imports: [LightFastGridComponent],
  template: `
    <light-fast-grid
      [rows]="rows"
      [columns]="columns"
      [getRowId]="getRowId"
      [height]="420"
      [accessibility]="{ ariaLabel: 'Orders' }"
    />
  `,
})
export class OrdersPage {
  readonly rows: Order[] = [
    { id: 'order-1001', customer: 'Acme', total: 1200 },
    { id: 'order-1002', customer: 'Globex', total: 850 },
  ];
  readonly columns: ColumnDef[] = [
    { field: 'customer', headerName: 'Customer' },
    { field: 'total', headerName: 'Total' },
  ];
  readonly getRowId = (row: RowData): string => String(row.id);
}

Use OrdersPage in an existing Angular application's route or in another standalone component's imports. Declaring this class does not bootstrap an application; keep the application's own bootstrap and provider setup.

Sizing and theme CSS

light-fast-grid is a block host with default height 100%. A numeric height is CSS pixels. Class, style, id, and data attributes stay on this element. The host is a static ngSkipHydration boundary. Height and host attributes do not perform Core data work.

Import the default theme once in global application styles (for example, src/styles.css), not in component-scoped styles:

@import '@lightfastgrid/core/themes/default.css';

The Angular JavaScript entry does not import this CSS (it is not JS-imported). A blank or clipped Grid usually means the host or its parent has no real height.

Data updates and API readiness

Bindings are shallow. Replace the top-level rows array, columns array, or configuration object when changing declarative data; nested mutation is not watched. Core owns row identity, immutable diffing, transactions, and ordinary cell rendering. getRowId must return a unique stable value for each row.

Use #grid="lightFastGrid" or a typed view query to access grid.api. The stable handle becomes usable inside (gridReady). Before readiness and after disposal its methods throw LFG_ANGULAR_GRID_NOT_READY; there is no getInstance() or unsupported adaptor setter. Construction begins after afterNextRender in the browser. Initial-only options require component recreation to change.

The application chooses zone-based provideZoneChangeDetection() or provideZonelessChangeDetection() in its own bootstrap configuration. The package has no zone.js peer and does not choose change-detection mode.

Acceptance covered Angular 20.3.0/20.3.31, 21.0.0/21.2.23, and 22.0.0/22.1.6 with compatible isolated TypeScript tooling.

Optional Core booleans such as loading stay undefined when omitted. Bind [loading]="true"; do not rely on a bare boolean attribute.

There is no Grid during component construction or SSR.

Capabilities and limits

Core provides virtualized rows and columns, sorting, filtering, selection, editing, pagination, CSV export, keyboard navigation, and eligible Worker work. Angular templates are supported only for row actions, header actions, grid overlays, and cell-shell overlays; ordinary cells remain Core-rendered.

Server rendering produces the surrounding Angular parent and an empty Grid host. Client hydration preserves that parent and creates one client Grid; this is not server-rendered cells or incremental hydration. A later nested user component constructor that throws can abort Angular view creation before an already-created sibling's DestroyRef or takeUntilDestroyed cleanup runs. Adaptor-owned resources are still released. A shared Core queued-scroll popup issue can immediately close a row-action menu when clicking a previously offscreen trigger during horizontal auto-scroll; it is not an Angular-only fix.

Inputs and update ownership

Bindings are shallow. Replace rows, columns, registries, and configuration objects to request an update; in-place mutation is not watched. One microtask coalesces a fixed inventory of changed inputs. The wrapper does not traverse or copy rows. Core owns row identity, immutable diffing, transactions, selection, sorting, filtering, workers, and ordinary cell rendering.

Live inputs are:

rows, immutableRows, columns, defaultColDef, rowSelection, columnSelection, columnOrder, rowDrag, rowClass, getRowClass, rowClassRules, pagination, paginationPageSize, paginationPageSizeOptions, theme, floatingFilters, columnGroupHeaders, quickFilter, quickFilterText, columnMenu, cellMenu, cellRenderers, headerRenderers, cellShellOverlays, csvExport, asyncTransactionWaitMillis, execution, loading, overlays, accessibility, and onBeforeCellEditCommit.

getRowId, rowPinning, initialSortModel, suppressRowVirtualization, and suppressColumnVirtualization are initial-only. Changing one after mount emits one development warning per key and requires component recreation. getParentId, mode, and rowModelType are reserved Core construction options; V1 does not invent tree or server-row behavior. height changes only the Angular host.

Undefined clears a changed live input according to Core semantics, except quickFilterText: undefined relinquishes declarative control and '' clears the current query. rows and columns clear to empty arrays. Equivalent pagination and quick-filter objects preserve imperative state. Optional Core booleans stay undefined when omitted.

onBeforeCellEditCommit is a synchronous input hook, not an output. Its latest function runs inside Angular while Core retains its existing exception policy.

API readiness and commands

Reference the exported component with #grid="lightFastGrid" or a typed view query. grid.api is stable for the Angular component lifetime and resolves the current client Grid at each call. It is ready inside (gridReady). Before that event and after disposal, every method throws an Error whose code is exactly LFG_ANGULAR_GRID_NOT_READY.

The handle exposes Core GridApi commands, including selection, sorting, filtering, transactions, pagination, CSV export, sizing, focus, and setOverlays. It intentionally exposes no mount, destroy, getInstance, raw Core Grid, or adaptor setters. Async transaction/search/export results, task identity, progress, cancellation, and errors remain Core-owned. Destroying the component invalidates wrapper delivery before Core and custom views are released, so late work cannot emit stale outputs into the removed parent.

Outputs

gridReady has no payload. Use (gridReady)="onReady()", not a required $event handler. The 23 output names are:

gridReady, columnResized, sortChanged, filterChanged, selectionChanged, columnSelectionChanged, columnOrderChanged, columnPinChanged, rowPinChanged, columnVisibilityChanged, rowOrderChanged, cellValueChanged, paginationChanged, focusedCellChanged, cellShellAction, rowDataUpdated, quickFilterChanged, quickSearchPendingChanged, asyncTransactionsFlushed, csvExportProgress, csvExportCompleted, csvExportCancelled, csvExportError.

Template markers

Row actions, header actions, grid overlays, and cell-shell overlays use typed ng-template markers (lfgRowAction, lfgHeaderAction, lfgOverlay, lfgCellShellOverlay). Registry factories receive the Core context with host stripped and must return { template } or null. Overlay visibility, precedence, host reuse, and cell-shell close/replacement scheduling stay in Core. Unchanged overlay inputs do not undo a live api.setOverlays call.

This standalone example adds a custom row-action template and a loading overlay to the same small Orders dataset. It includes its imports and sizing; use it in an existing Angular application as described above.

import { Component, ViewChild } from '@angular/core';
import {
  type AngularCellRendererRegistry,
  type AngularGridOverlaysOptions,
  LightFastGridComponent,
  LightFastGridOverlayDirective,
  LightFastGridRowActionDirective,
} from '@lightfastgrid/angular';
import type { ColumnDef, RowData } from '@lightfastgrid/core';

type Order = { id: string; customer: string };

@Component({
  selector: 'orders-with-templates',
  standalone: true,
  imports: [
    LightFastGridComponent,
    LightFastGridRowActionDirective,
    LightFastGridOverlayDirective,
  ],
  template: `
    <ng-template lfgRowAction #rowAction="lfgRowAction" let-ctx>
      <button type="button" (click)="ctx.close()">{{ ctx.rowId }}</button>
    </ng-template>
    <ng-template lfgOverlay #overlay="lfgOverlay" let-ctx>
      <div>{{ ctx.kind }}</div>
    </ng-template>
    <light-fast-grid
      [rows]="rows"
      [columns]="columns"
      [getRowId]="getRowId"
      [cellRenderers]="cellRenderers"
      [overlays]="overlays"
      [height]="420"
      [accessibility]="{ ariaLabel: 'Orders' }"
    />
  `,
})
export class OrdersWithTemplates {
  @ViewChild('rowAction', { static: true })
  rowAction!: LightFastGridRowActionDirective;
  @ViewChild('overlay', { static: true })
  overlay!: LightFastGridOverlayDirective;

  readonly rows: Order[] = [{ id: 'order-1001', customer: 'Acme' }];
  readonly columns: ColumnDef[] = [
    { field: 'customer', headerName: 'Customer' },
    { field: 'actions', headerName: 'Actions', cellKind: 'actions', actionsKey: 'row' },
  ];
  readonly getRowId = (row: RowData): string => String(row.id);

  readonly cellRenderers: AngularCellRendererRegistry = {
    row: {
      kind: 'actions',
      mode: 'custom',
      render: () => ({ template: this.rowAction.template }),
    },
  };
  readonly overlays: AngularGridOverlaysOptions = {
    loading: {
      render: () => ({ template: this.overlay.template }),
    },
  };
}

The exact $implicit contexts are AngularRowActionRenderContext, AngularHeaderActionRenderContext, AngularOverlayRenderContext, and AngularCellShellOverlayRenderContext. They retain the documented Core grid API but never expose the Core DOM host. Templates retain their declaration injection context and support bindings, pipes, nested components, signals, and AsyncPipe. Initial content is mounted synchronously because row-action focus depends on DOM existing before the trigger click returns.

Each successful factory result may include cleanup. It runs exactly once when that Core host releases the Angular tree, including partial mount failure. The wrapper destroys embedded views, effects, subscriptions, and its private child root while preserving the reusable Core host. Open leases retain only active custom content; there is no historical lease list or view reuse.

User code that throws from a template, ngOnInit, or an initial effect is cleaned up while preserving the original thrown value. One Angular limitation is explicit: if a later nested component constructor throws, Angular can abort creation before DestroyRef callbacks or takeUntilDestroyed resources of an already-created sibling run. Ordinary Angular view creation behaves the same, and this package does not use private Angular view fields to work around it. The adaptor still releases everything it owns.

SSR and hydration

Server rendering produces the surrounding Angular parent and an empty light-fast-grid host. It does not construct Core Grid, render rows, or require browser globals. The host is a static ngSkipHydration boundary. During client hydration Angular preserves the surrounding parent DOM and initializes exactly one client Grid inside that boundary after render. Parent event handlers remain hydrated normally. Destroying the Angular application tears down the client Grid.

This is host-only SSR with a client-owned grid boundary. It is not server-rendered cells, incremental hydration, or deferred hydration.

Module format

Angular Package Format ESM/FESM plus index.d.ts. CommonJS is not supported. Consumers must compile with the Angular compiler / linker.

Links

License

MIT. See LICENSE.