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

ng-dynamic-datatable

v0.0.14

Published

Config-driven Angular DataTable library with sorting, searching, pagination, selection, and export.

Readme

ng-dynamic-datatable

Config-driven Angular DataTable library for rendering reusable tables from JSON data and column definitions.

The package is designed for Angular standalone applications and supports sorting, searching, pagination, selection, actions, and export.

Features

  • Dynamic columns from config
  • JSON data input
  • Column sorting
  • Global search across visible columns
  • Pagination
  • Rows per page selector
  • Checkbox row selection
  • Row action menu
  • CSV export
  • Excel export
  • Custom cell rendering with HTML strings

Package Name

Install the published package with:

npm install ng-dynamic-datatable

Do not use dynamic-datatable. The published npm package name is ng-dynamic-datatable.

Requirements

  • Angular 17.x, 18.x, or 19.x
  • @angular/common and @angular/core compatible with ^17.0.0 || ^18.0.0 || ^19.0.0
  • bootstrap is recommended for layout consistency
  • bootstrap-icons is recommended if you use action icons like bi bi-eye

Install In Your Angular App

npm install ng-dynamic-datatable
npm install bootstrap bootstrap-icons

Add Bootstrap styles in your Angular app configuration.

Example angular.json styles section:

{
  "styles": [
    "node_modules/bootstrap/dist/css/bootstrap.min.css",
    "node_modules/bootstrap-icons/font/bootstrap-icons.css",
    "src/styles.css"
  ]
}

Quick Start

Import the standalone component directly into your Angular component.

import { Component } from '@angular/core';
import {
  DynamicDatatableComponent,
  DynamicDataTableConfig,
  DataTableColumn,
  DataTableActionEvent
} from 'ng-dynamic-datatable';

@Component({
  selector: 'app-users',
  standalone: true,
  imports: [DynamicDatatableComponent],
  template: `
    <lib-dynamic-datatable
      [config]="config"
      [columns]="columns"
      [data]="rows"
      (actionSelected)="onAction($event)"
      (selectionChange)="onSelection($event)"
      (sortChange)="onSort($event)"
      (pageChange)="onPage($event)"
      (exportTriggered)="onExport($event)"
    ></lib-dynamic-datatable>
  `
})
export class UsersComponent {
  rows = [
    {
      id: 1,
      initials: 'AS',
      name: 'Aarav Sharma',
      designation: 'Tax Accountant',
      email: '[email protected]',
      salary: '19366.53',
      status: 'Resigned'
    },
    {
      id: 2,
      initials: 'AP',
      name: 'Ananya Patel',
      designation: 'Staff Accountant',
      email: '[email protected]',
      salary: '10745.32',
      status: 'Applied'
    }
  ];

  columns: DataTableColumn[] = [
    {
      key: 'name',
      label: 'Name',
      sortable: true,
      width: '240px',
      render: (row) => `
        <div class="demo-user">
          <div class="demo-avatar">${String(row['initials'] ?? '')}</div>
          <div>
            <div class="demo-name">${String(row['name'] ?? '')}</div>
            <div class="demo-subtitle">${String(row['designation'] ?? '')}</div>
          </div>
        </div>
      `
    },
    { key: 'email', label: 'Email', sortable: true, width: '260px' },
    { key: 'salary', label: 'Salary', sortable: true, width: '120px' },
    {
      key: 'status',
      label: 'Status',
      sortable: true,
      width: '120px',
      render: (row) => `<span class="demo-badge">${String(row['status'] ?? '')}</span>`
    }
  ];

  config: DynamicDataTableConfig = {
    title: 'Users',
    features: {
      export: true,
      sorting: true,
      searching: true,
      pagination: true,
      rowsPerPage: true,
      actions: true,
      checkboxSelection: true
    },
    rowsPerPageOptions: [5, 10, 25],
    defaultRowsPerPage: 10,
    exportOptions: {
      fileName: 'users-export',
      formats: ['csv', 'excel']
    },
    actions: [
      { label: 'Details', icon: 'bi bi-eye', id: 'details' },
      { label: 'Archive', icon: 'bi bi-archive', id: 'archive' },
      { label: 'Delete', icon: 'bi bi-trash', id: 'delete', danger: true }
    ]
  };

  onAction(event: DataTableActionEvent): void {
    console.log('Action event:', event);
  }

  onSelection(rows: unknown[]): void {
    console.log('Selected rows:', rows);
  }

  onSort(event: { key: string | null; direction: 'asc' | 'desc' }): void {
    console.log('Sort changed:', event);
  }

  onPage(page: number): void {
    console.log('Page changed:', page);
  }

  onExport(event: unknown): void {
    console.log('Export triggered:', event);
  }
}

Global Styles For Custom Rendered HTML

If you use the render function in a column, it returns an HTML string. Those styles should usually be defined in your app's global stylesheet, for example src/styles.css.

Example:

.demo-user {
  display: flex;
  align-items: center;
  gap: 10px;
}

.demo-avatar {
  width: 34px;
  height: 34px;
  border-radius: 999px;
  display: grid;
  place-items: center;
  color: #fff;
  background: linear-gradient(145deg, #4f46e5, #6d67ff);
  font-size: 12px;
  font-weight: 700;
}

.demo-name {
  font-weight: 600;
}

.demo-subtitle {
  font-size: 12px;
  color: #6d7895;
}

Inputs

config: DynamicDataTableConfig

Main table configuration.

columns: DataTableColumn[]

Column definitions for the table.

data: Record<string, unknown>[]

Array of row objects.

Outputs

actionSelected

Triggered when a row action is clicked.

Type:

DataTableActionEvent<T>

Shape:

{
  action: DataTableAction<T>;
  row: T;
  rowIndex: number;
}

selectionChange

Triggered when selected rows change.

sortChange

Triggered when sorting changes.

Shape:

{ key: string | null; direction: 'asc' | 'desc' }

pageChange

Triggered when the current page changes.

exportTriggered

Triggered before CSV or Excel export is downloaded.

Type Reference

DataTableColumn

export interface DataTableColumn<T extends Record<string, unknown> = Record<string, unknown>> {
  key: keyof T | string;
  label: string;
  sortable?: boolean;
  width?: string | number;
  render?: (row: T) => string;
}

DataTableAction

export interface DataTableAction<T extends Record<string, unknown> = Record<string, unknown>> {
  label: string;
  icon?: string;
  danger?: boolean;
  id?: string;
}

DynamicDataTableConfig

export interface DynamicDataTableConfig<T extends Record<string, unknown> = Record<string, unknown>> {
  title?: string;
  features?: {
    export?: boolean;
    sorting?: boolean;
    searching?: boolean;
    pagination?: boolean;
    rowsPerPage?: boolean;
    actions?: boolean;
    checkboxSelection?: boolean;
  };
  rowsPerPageOptions?: number[];
  defaultRowsPerPage?: number;
  exportOptions?: {
    fileName?: string;
    formats?: ('csv' | 'excel')[];
  };
  columns?: DataTableColumn<T>[];
  actions?: DataTableAction<T>[];
}

Public Methods

You can access the component instance with @ViewChild.

import { ViewChild } from '@angular/core';
import { DynamicDatatableComponent } from 'ng-dynamic-datatable';

@ViewChild(DynamicDatatableComponent)
private table?: DynamicDatatableComponent;

Available methods:

  • refresh()
  • updateData(newData)
  • updateConfig(newConfig)
  • getSelectedRows()
  • clearSelection()

Example:

reloadData(): void {
  this.table?.updateData([
    { id: 1, name: 'Updated User' }
  ]);
}

Local Development

1. Install workspace dependencies

From the workspace root:

npm install

If your workspace contains a separate Angular demo app, install its dependencies too.

2. Build the library

From the workspace root:

npx ng build dynamic-datatable

Build output is generated in:

dist/dynamic-datatable

3. Test inside a consumer Angular app

In a separate Angular app:

npm install ng-dynamic-datatable@latest

Then build the app:

npm run build

Publishing A New Version

1. Update version

Update the version in:

projects/dynamic-datatable/package.json

Example:

{
  "version": "0.0.7"
}

2. Build the library

npx ng build dynamic-datatable

3. Publish from the dist package

cd dist/dynamic-datatable
npm publish --access public

Important:

  • Always publish from dist/dynamic-datatable
  • Do not publish from the workspace root
  • Make sure you are logged into npm
  • Wait a few moments after publishing before installing the new version in another app

4. Upgrade a consuming Angular app

npm install ng-dynamic-datatable@latest
npm run build

If npm does not find the new version immediately, wait briefly and retry.

Troubleshooting

Icons are not showing

Install and include bootstrap-icons in your app styles.

Custom rendered HTML styles are not applied

Move those styles to the consuming app's global stylesheet.

Sorting does not work as expected

Ensure the column has sortable: true and that values are consistently formatted.

Action dropdown appears clipped

This usually depends on available space around the row and container overflow. Use the latest package version because menu positioning has been improved in recent patches.

Build Command

npx ng build dynamic-datatable

Exported API

This package exports:

  • DynamicDatatableComponent
  • DataTableColumn
  • DataTableAction
  • DynamicDataTableConfig
  • DataTableActionEvent
  • DataTableExportEvent

License

MIT