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

@inandu-solutions/grid-angular

v1.2.2

Published

Standalone Angular data grid: sorting, free-text and per-column filtering, grouping, pagination, row virtualization, inline row editing/creation/deletion with validation, CSV/Excel/PDF export and print, i18n (5 languages) and 3 built-in themes, with a del

Readme

@inandu-solutions/grid-angular

A standalone Angular data grid built from two components — <inandu-grid> and <inandu-column> — with a deliberately small dependency footprint. No NgModules, signal-based inputs/outputs, and every feature opt-in. A lightweight, MIT-licensed alternative to the big commercial Angular grids.

npm downloads minzipped size license Angular live demo docs Open in StackBlitz

inandu-grid — sorting, filtering, grouping, sticky columns, export toolbar

This is the core (MIT) package. Commercial add-ons ship separately as @inandu-solutions/grid-pro (proprietary, private). The bare @inandu-solutions/grid name is reserved for a future framework-neutral umbrella. There are also React and Vue ports: inandu-grid-react, ships as @inandu-solutions/grid-react, and inandu-grid-vue, ships as @inandu-solutions/grid-vue.

▶️ Live demo: https://inandusolutions.github.io/inandu-grid/  ·  ⚡ StackBlitz: editable example  ·  📘 Full manual (every feature + API reference): https://inandusolutions.github.io/inandu-grid/manual.html

Hello grid

ng add @inandu-solutions/grid-angular
import { InanduGridComponent, InanduColumnComponent } from '@inandu-solutions/grid-angular';

@Component({
  imports: [InanduGridComponent, InanduColumnComponent],
  template: `
    <inandu-grid [data]="people" filter="true">
      <inandu-column field="name" title="Name" sortable="true" />
      <inandu-column field="age" title="Age" type="number" sortable="true" />
    </inandu-grid>
  `,
})
export class PeopleComponent {
  people = [{ name: 'Ada', age: 36 }, { name: 'Alan', age: 41 }];
}

Two standalone components, a plain array in, click-to-sort and free-text search out. Everything else — grouping, virtual scroll, inline editing, export, i18n, theming — is opt-in from here; see Quick start below and the manual.

Why this vs the big grids?

Row grouping, Excel export, cell-range selection and aggregation are all free here — no enterprise tier. Small dependency footprint, Angular-native (signals, standalone). Not a kitchen sink: no pivoting, no integrated charts. Server-side paging/sorting/filtering is supported — via serverSide + outputs, wired to any backend or to the .NET/EF Core companion inandu-grid-extensions. Fuller comparison table in the repo README.

row grouping in the inandu-grid demo

Grouping by a column — try every feature in the demo.

Features

| Area | How you turn it on | | --- | --- | | Sorting | <inandu-column sortable="true"> — click a header to cycle asc → desc; shift-click for multi-column sort | | Free-text search | <inandu-grid filter="true"> — one box, matches every column's formatted value | | Per-column filters | <inandu-column filter="yes"> — type-aware popup (text / number range / date range / boolean select), combined with AND | | Pagination | [paging]="{ pageSize: 25 }" — an InanduGridPagingOptions object; off entirely when unbound | | Server-side data | serverSide + [totalItems] + [loading] / [error] — the grid stops sorting/filtering/paging locally and emits (sortChange) / (pageChange) / (filterChange) for you to fetch each page. .NET backend? inandu-grid-extensions turns those requests into one paged SQL query. | | Row virtualization | virtualScroll — for large ungrouped datasets, via @angular/cdk virtual scroll | | Infinite scroll | infiniteScroll (+ infiniteScrollThreshold) — emits (loadMore) as the user nears the end | | Grouping | <inandu-column groupable="true"> — drag a header onto the drop zone | | Aggregates / totals row | showTotals + <inandu-column aggregate="sum"> (sum / avg / min / max / count) | | Column resize / reorder / show-hide | On by default; opt out per column with resize="false" / reorder="false" / hideable="false". Double-click a resize handle to fit the column to its content ([autosize]="false" to disable). Grid-level toggle popup via columnToggle="true" | | Row reorder | rowReorder — drag rows; emits (rowOrderChange) with the new order | | Pinned rows | [pinnedTopRows] / [pinnedBottomRows] — a T[] of display-only rows kept visible above/below the body; not part of data(), so sort/filter/paging ignore them (non-virtualized table only) | | Tree data | treeChildrenKey="children" — each row's nested children array is its subtree; rows get an expand/collapse toggle + depth indent. Filters keep a node when it or a descendant matches (and open the path); the sort orders each sibling level. treeDefaultExpanded="none"\|"all"\|<depth>. Non-virtualized, non-grouped, non-serverSide only | | Sticky columns | <inandu-column sticky="true"> (or sticky="right") — frozen while scrolling | | Row selection | selectable="true" — checkbox column + (selectionChange) output | | Clipboard & cell ranges | clipboard → (cellsPaste); cellRangeSelection → (cellRangeChange); add multiRange for Ctrl/Cmd-drag to select several rectangles at once — (cellRangesChange) / grid.cellRanges() give the whole list | | Inline editing / creation / deletion | <inandu-column editable="true">, grid-level creatable / deletable; emits rowSave / rowCreate / rowDelete / rowsDelete — the grid never mutates your data | | Validation | required / min / max / pattern / [validator] / [asyncValidator] per column, checked at save time. grid.validateCell(column, value, row?) runs the same synchronous chain against any value — for a whole-grid check | | Custom cell & header templates | <ng-template> with InanduCellTemplateContext / InanduHeaderTemplateContext | | Custom row actions | project your own buttons via the row-actions slot (InanduRowActionsContext) | | Export & print | exportable="true" — CSV (UTF-8 BOM), Excel (SpreadsheetML .xls, dependency-free), PDF (jspdf), and print. Real .xlsx is a @inandu-solutions/grid-pro feature. | | i18n | lang="es-AR" — 5 built-in languages (en, es, fr, it, zh) + [customTranslations]; each grid instance is isolated | | RTL | dir="rtl" (or "auto") | | Theming | theme="material" — 3 presets (material, dark, minimal), pure CSS; or bring your own .inandu-theme-<name> rule |

Requirements

| | | | --- | --- | | Angular | ^21.2.0 || ^22.0.0 (@angular/core + @angular/common are peer dependencies) | | Node | whatever your Angular 21 app already needs — ^20.19.0 \|\| ^22.12.0 \|\| >=24 | | Package manager | npm, pnpm or yarn | | Browsers | current Chrome, Firefox and Safari (Safari 16+ for fully correct sticky columns). No Internet Explorer. | | Standalone APIs | your app must be able to imports: [...] standalone components (Angular 14.1+ — always true on 21) |

Installation

ng add @inandu-solutions/grid-angular

Installs the package and scaffolds a ready-to-run GridDemoComponent (skip it with --skip-example). Show it by routing to GridDemoComponent or dropping <app-grid-demo></app-grid-demo> into a template, then ng serve.

Prefer to wire it up yourself:

npm install @inandu-solutions/grid-angular

You can also scaffold an example component into an existing app at any time:

ng generate @inandu-solutions/grid-angular:grid my-grid

Dependencies

Peer (you provide): @angular/core, @angular/common ^21.2.0 || ^22.0.0.

Bundled (installed automatically, nothing to configure — internal implementation details): @angular/cdk (virtual scroll), @ngx-translate/core (i18n), jspdf (PDF export — loaded lazily), and tslib.

Quick start

Both components are standalone — add them to your component's imports:

import { Component } from '@angular/core';
import { InanduGridComponent, InanduColumnComponent, InanduGridRow } from '@inandu-solutions/grid-angular';

@Component({
  selector: 'app-people',
  imports: [InanduGridComponent, InanduColumnComponent],
  template: `
    <inandu-grid
      [data]="rows"
      [paging]="{ pageSize: 10 }"
      filter="true"
      lang="en">
      <inandu-column field="name"   title="Name"   sortable="true"></inandu-column>
      <inandu-column field="age"    title="Age"    type="number"  sortable="true"></inandu-column>
      <inandu-column field="joined" title="Joined" type="date"    format="DD/MM/YYYY"></inandu-column>
      <inandu-column field="active" title="Active" type="boolean" format="Yes|No"></inandu-column>
    </inandu-grid>
  `,
})
export class PeopleComponent {
  rows: InanduGridRow[] = [
    { name: 'Ada Lovelace',   age: 36, joined: new Date(2021, 2, 14), active: true },
    { name: 'Alan Turing',    age: 41, joined: new Date(2019, 8, 1),  active: false },
    { name: 'Grace Hopper',   age: 45, joined: new Date(2020, 0, 20), active: true },
  ];
}

The grid only ever consumes a plain InanduGridRow[]. Fetching, persistence, and async concerns stay in your app: handle (rowSave), (rowCreate), (rowDelete), (selectionChange) and update your own array (and/or your backend) however you like.

Column value types & formatting

<inandu-column type="…" format="…"> controls how a cell's raw value is displayed:

  • number — format is a DecimalPipe-style digits string, e.g. format="1.2-2". Separators follow the app's LOCALE_ID.
  • date — format is a case-sensitive token pattern (YYYY, MM, DD, HH, mm, ss, sss), e.g. format="DD/MM/YYYY HH:mm". Raw value may be a Date, an ISO string, or a timestamp. Defaults to YYYY-MM-DD.
  • boolean — format is "<truthy>|<falsy>", e.g. format="Sí|No".
  • string (default) — raw value stringified as-is.

Public API

InanduGridComponent<T = InanduGridRow> and InanduColumnComponent are the two exported components. The main types (see public-api.ts for the full surface):

InanduGridRow                  // Record<string, unknown> — the default row type
InanduGridPagingOptions        // { pageSize?, show*Button?, *Label?, pageLabel? }
InanduGridRowSave<T>           // { row, values } — emitted by (rowSave)
InanduGridNewRowValues<T>      // parsed values — emitted by (rowCreate)
InanduGridSortCriterion        // { field, direction } — (sortChange), multi-sort
InanduGridPageState            // (pageChange), for serverSide
InanduGridFilterState          // (filterChange), for serverSide
InanduGridLoadMoreEvent        // (loadMore), for infiniteScroll
InanduGridCellPaste<T>         // (cellsPaste)
InanduGridCellRangeSelection<T>// (cellRangeChange)
InanduGridCustomTranslations   // [customTranslations]
InanduColumnType               // 'string' | 'number' | 'boolean' | 'date'
InanduColumnValidator          // (value, row) => string | null
InanduColumnAsyncValidator     // (value, row) => Promise<string | null>
InanduColumnAggregate          // 'sum' | 'avg' | 'min' | 'max' | 'count'
InanduCellTemplateContext / InanduHeaderTemplateContext / InanduRowActionsContext

(rowDelete) / (rowsDelete) emit row references; (selectionChange) and (rowOrderChange) emit T[].

Styling hooks

Every structural element carries a stable inandu-* class (inandu-grid, inandu-column, inandu-row, …) with no default rule attached — target them from your own global stylesheet, e.g.:

inandu-grid .inandu-row:nth-child(even) { background: #fafafa; }

Browser support

Chrome, Firefox, Safari (current). No IE.

Contributing & source

Source, issues, and the demo app: https://github.com/inandusolutions/inandu-grid

License

MIT © Inandu SAS