cats-data-grid
v2.0.90
Published
Cats Data Grid is an Angular library for showing tabular and hierarchical data. It provides two standalone components:
Readme
Cats Data Grid
Cats Data Grid is an Angular library for showing tabular and hierarchical data. It provides two standalone components:
CatsDataGridComponentfor normal flat tables.CommonTreeTableComponentfor tree or parent-child tables.
The library supports sorting, filtering, pagination, row selection, column settings, column pinning, grouping, editable cells, skeleton loading, and custom cell renderers.
Requirements
- Angular
>=18 <22 @angular/core@angular/common
Install
npm install cats-data-gridIf you are using this library from the local workspace, build it first:
ng build cats-data-gridConfigure Assets And Styles
Add the library assets and styles to your application's angular.json.
For an installed npm package:
{
"assets": [
{
"glob": "**/*",
"input": "node_modules/cats-data-grid/assets"
}
],
"styles": ["node_modules/cats-data-grid/styles/_index.scss"]
}Import In Angular
The components are standalone, so import them in the component where you use them.
import { Component } from "@angular/core";
import { CatsDataGridComponent, CommonRendererComponent } from "cats-data-grid";
@Component({
selector: "app-users",
standalone: true,
imports: [CatsDataGridComponent],
templateUrl: "./users.component.html",
})
export class UsersComponent {
// Component code shown below.
}Basic Data Grid
Template
<cats-data-grid [rowData]="rowData" [colDefs]="colDefs" [totalRecords]="totalRecords" [paginationRequired]="true" [sortingRequired]="true" [filterRequired]="true" [checkBoxSelection]="true" [checkboxSelectionType]="'multiple'" [settingsRequired]="true" [threeDotsMenuRequired]="true" [pageSizeList]="[10, 20, 50]" [pageNumber]="pageNumber" [pageSize]="pageSize" [rowId]="'id'" (onPaginationChange)="onPaginationChange($event)" (onCheckboxSelection)="onCheckboxSelection($event)" (onRowClicked)="onRowClicked($event)" (onCellClicked)="onCellClicked($event)" (onCellEdit)="onCellEdit($event)" (onColConfigChange)="onColConfigChange($event)"></cats-data-grid>Component
import { Component } from "@angular/core";
import { CatsDataGridComponent, CommonRendererComponent } from "cats-data-grid";
@Component({
selector: "app-users",
standalone: true,
imports: [CatsDataGridComponent],
templateUrl: "./users.component.html",
})
export class UsersComponent {
pageNumber = 0;
pageSize = 20;
totalRecords = 3;
colDefs = [
{
headerName: "ID",
fieldName: "id",
width: 100,
filterType: "number",
headerLocked: true,
},
{
headerName: "Name",
fieldName: "name",
width: 200,
filterType: "text",
editable: true,
},
{
headerName: "Status",
fieldName: "status",
width: 160,
filterType: "set",
cellRenderer: CommonRendererComponent,
cellRendererParams: {
type: "tag",
},
},
{
headerName: "Action",
fieldName: "action",
width: 90,
filterable: false,
columnAction: false,
isAction: true,
cellRenderer: CommonRendererComponent,
cellRendererParams: {
type: "action-menu",
actions: [
{ label: "View", value: "view", image: "images/eye.svg" },
{ label: "Edit", value: "edit", image: "images/edit.svg" },
],
onAction: (event: any) => this.onAction(event),
},
},
];
rowData = [
{ id: 1, name: "Aarav", status: ["Active"] },
{ id: 2, name: "Diya", status: ["Pending"] },
{ id: 3, name: "Kabir", status: ["Inactive"] },
];
onPaginationChange(event: { page: number; pageSize: number }): void {
this.pageNumber = event.page;
this.pageSize = event.pageSize;
// Call your API here when using server-side pagination.
}
onCheckboxSelection(selectedRows: any[]): void {
console.log("Selected rows", selectedRows);
}
onRowClicked(event: any): void {
console.log("Row clicked", event.row);
}
onCellClicked(event: any): void {
console.log("Cell clicked", event.row, event.col);
}
onCellEdit(event: any): void {
console.log("Cell edited", event);
}
onColConfigChange(activeFields: string[]): void {
console.log("Visible columns", activeFields);
}
onAction(event: any): void {
console.log("Action clicked", event);
}
}Column Definition
Use colDefs to configure table columns.
| Property | Type | Description |
| -------------------- | --------------------------------------- | ---------------------------------------------------------------------- |
| headerName | string | Column title shown in the header. |
| fieldName | string | Field to read from row data. Dot paths like user.name are supported. |
| width | number | Column width in pixels. |
| minWidth | number | Minimum column width in pixels. |
| maxWidth | number | Maximum column width in pixels. |
| filterType | 'text' \| 'number' \| 'date' \| 'set' | Type of filter to show. |
| sortable | boolean | Enables or disables sorting for this column. |
| filterable | boolean | Enables or disables filtering for this column. |
| active | boolean | Shows or hides the column initially. |
| headerLocked | boolean | Keeps the column visible in column settings. |
| editable | boolean | Allows cell editing on double click. |
| category | string | Groups columns inside the column settings panel. |
| disableGrouping | boolean | Prevents this column from being used in grouping. |
| cellRenderer | any | Angular component or function used to render the cell. |
| cellRendererParams | object | Extra configuration passed to the renderer. |
| isAction | boolean | Marks the column as a sticky action column. |
| columnAction | boolean | Shows or hides the column menu for this column. |
Data Grid Inputs
| Input | Type | Default | Description |
| -------------------------- | ---------------- | ------------------- | -------------------------------------------------------------- |
| rowData | any[] | [] | Rows displayed in the grid. Required. |
| colDefs | any[] | [] | Column definitions. Required. |
| tableOptions | any | - | Extra options, such as custom row classes or no-data template. |
| totalRecords | number | 0 | Total record count for pagination. |
| sortingRequired | boolean | true | Enables sorting. |
| filterRequired | boolean | true | Enables filtering. |
| paginationRequired | boolean | true | Shows pagination. |
| checkBoxSelection | boolean | false | Shows row checkboxes. |
| checkboxSelectionType | string | 'multiple' | Use 'single' or 'multiple'. |
| settingsRequired | boolean | true | Enables column settings. |
| settingsClicked | boolean | false | Opens or closes the settings panel from parent component. |
| threeDotsMenuRequired | boolean | true | Shows the column action menu. |
| groupByRequired | boolean | false | Enables grouping UI. |
| groupByField | string | '' | Applies an initial group field. |
| dynamicGroupingFiltering | boolean | false | Emits grouping/filter events for server-side handling. |
| appliedFilters | ColumnFilter[] | [] | Pre-applied filters. |
| pageSizeList | number[] | [20, 50, 75, 100] | Page size options. |
| pageNumber | number | - | Current page number. |
| pageSize | number | - | Current page size. |
| resetPage | boolean | true | Resets page when total records change. |
| rowId | string | null | Unique row id field. |
| rowGripFieldName | string | - | Field used for row drag grip. |
| bigRows | boolean | false | Uses larger row height. |
| height | number | 400 | Grid height in pixels. |
| isRowsEditable | boolean | false | Enables row edit behavior. |
| showSkeleton | boolean | false | Shows skeleton loading rows. |
| skeletonRowsLength | number | 8 | Number of skeleton rows. |
| skeletonColsLength | number | 8 | Number of skeleton columns. |
Data Grid Events
| Event | Payload | Description |
| --------------------- | ---------------------------- | ------------------------------------------- |
| onPaginationChange | { page, pageSize } | Emits when page or page size changes. |
| onCheckboxSelection | any[] | Emits selected rows. |
| onRowClicked | { row } | Emits when a row is clicked. |
| onCellClicked | { row, col } | Emits when a cell is clicked. |
| onCellEdit | { row, col, changedValue } | Emits after editable cell value changes. |
| onColConfigChange | string[] | Emits visible column field names. |
| appliedFiltersEvent | ColumnFilter[] | Emits applied filters. |
| activeGroupsEvent | string[] | Emits active group fields. |
| onScrollEmitter | void | Emits when the table reaches bottom scroll. |
| filter | any | Emits filtered data/filter changes. |
| onHideSettings | boolean | Emits when settings panel is hidden. |
Built-In Cell Renderers
Import CommonRendererComponent and use it in cellRenderer.
Tag
{
headerName: 'Status',
fieldName: 'status',
filterType: 'set',
cellRenderer: CommonRendererComponent,
cellRendererParams: {
type: 'tag',
tagKey: 'name',
class: 'active',
},
}Link
{
headerName: 'Customer',
fieldName: 'customer.name',
cellRenderer: CommonRendererComponent,
cellRendererParams: {
type: 'link',
onLinkClick: (event: any) => this.onCustomerClick(event),
},
}Switch
{
headerName: 'Enabled',
fieldName: 'enabled',
cellRenderer: CommonRendererComponent,
cellRendererParams: {
type: 'switch',
onToggle: (event: any) => this.onStatusToggle(event),
},
}Action Menu
{
headerName: 'Action',
fieldName: 'action',
filterable: false,
columnAction: false,
isAction: true,
cellRenderer: CommonRendererComponent,
cellRendererParams: {
type: 'action-menu',
actions: [
{ label: 'View', value: 'view', image: 'images/eye.svg' },
{ label: 'Delete', value: 'delete', image: 'images/trash.svg' },
],
onAction: (event: any) => this.onAction(event),
},
}Tree Table
Use cats-tree-table when your data has children or nested rows.
Import
import { Component } from "@angular/core";
import { CatsTreeExpandEvent, CatsTreeSelectionChangeEvent, CatsTreeTableColumn, CommonTreeTableComponent } from "cats-data-grid";
@Component({
selector: "app-tree-demo",
standalone: true,
imports: [CommonTreeTableComponent],
templateUrl: "./tree-demo.component.html",
})
export class TreeDemoComponent {
// Component code shown below.
}Template
<cats-tree-table [data]="treeData" [columns]="columns" childrenField="children" labelField="name" [showCheckbox]="true" [sortingRequired]="true" [filterRequired]="true" [paginationRequired]="true" [totalRecords]="treeData.length" [pageSizeList]="[10, 20, 50]" [expandAllNodes]="false" [isExpandable]="isExpandable" [rowOptionsResolver]="rowOptionsResolver" [nodeIconResolver]="nodeIconResolver" [linkResolver]="linkResolver" (nodeToggle)="onNodeToggle($event)" (selectionChange)="onSelectionChange($event)" (linkClick)="onLinkClick($event)" (linkDoubleClick)="onLinkDoubleClick($event)"></cats-tree-table>Component
columns: CatsTreeTableColumn[] = [
{ fieldName: 'name', header: 'Name', width: 260, filterType: 'text' },
{ fieldName: 'type', header: 'Type', width: 140, filterType: 'set' },
{ fieldName: 'owner', header: 'Owner', width: 180, filterType: 'text' },
];
treeData = [
{
id: 1,
name: 'Network',
type: 'group',
owner: 'Admin',
children: [
{ id: 11, name: 'Router Template', type: 'template', owner: 'NOC' },
{ id: 12, name: 'Switch Template', type: 'template', owner: 'NOC' },
],
},
];
isExpandable = (node: any): boolean => {
return Array.isArray(node.children) && node.children.length > 0;
};
rowOptionsResolver = (node: any) => {
if (node.type === 'template') {
return { showCheckbox: false, showLink: true, showNodeIcon: true };
}
return { showCheckbox: true, showNodeIcon: true };
};
nodeIconResolver = (node: any, level: number, path: any[], expanded: boolean) => {
if (node.type === 'group') {
return expanded ? 'folder-minus.svg' : 'folder-plus.svg';
}
return 'file-text.svg';
};
linkResolver = (node: any): string | null => {
return node.type === 'template' ? `/templates/${node.id}` : null;
};
onNodeToggle(event: CatsTreeExpandEvent<any>): void {
console.log('Node toggled', event);
}
onSelectionChange(event: CatsTreeSelectionChangeEvent<any>): void {
console.log('Selection changed', event.selectedNodes);
}
onLinkClick(event: any): void {
console.log('Link clicked', event);
}
onLinkDoubleClick(event: any): void {
console.log('Link double clicked', event);
}Tree Table Inputs
| Input | Type | Default | Description |
| -------------------------- | ----------------------- | ----------------------------------------- | ------------------------------------------------------------------ |
| data | any[] | [] | Root nodes for the tree. |
| columns | CatsTreeTableColumn[] | [{ fieldName: 'name', header: 'Name' }] | Tree table columns. |
| idField | string | 'id' | Unique id field. |
| labelField | string | 'name' | Field displayed as the tree label. |
| childrenField | string | 'array' | Field containing child nodes. |
| treeColumnField | string | - | Column used as the tree column. |
| indentPx | number | 24 | Indentation per tree level. |
| showHeader | boolean | true | Shows the header row. |
| showCheckbox | boolean | false | Shows node checkboxes. |
| showNodeIcon | boolean | true | Shows node icons. |
| expandAllNodes | boolean | false | Expands all nodes. |
| expandAllControlRequired | boolean | true | Shows expand-all control. |
| isExpandable | function | checks children | Controls whether a node can expand. |
| rowOptionsResolver | function | {} | Controls checkbox, toggle, icon, link, and disabled state per row. |
| nodeIconResolver | function | null | Returns an icon path or file name for each node. |
| linkResolver | function | null | Returns the URL used for link rows. |
| iconBasePath | string | 'images' | Base folder for icon file names. |
| sortingRequired | boolean | true | Enables sorting. |
| filterRequired | boolean | false | Enables filtering. |
| paginationRequired | boolean | true | Shows pagination. |
| settingsRequired | boolean | true | Enables column settings. |
| threeDotsMenuRequired | boolean | true | Shows column action menu. |
| pageSizeList | number[] | [20, 50, 75, 100] | Page size options. |
| totalRecords | number | 0 | Total records for pagination. |
| showSkeleton | boolean | false | Shows loading skeleton. |
Tree Table Events
| Event | Payload | Description |
| -------------------- | ----------------------------------------------- | --------------------------------------- |
| nodeToggle | { node, level, path, expanded } | Emits when a node expands or collapses. |
| selectionChange | { node, level, path, checked, selectedNodes } | Emits when tree selection changes. |
| linkClick | { node, level, path, url, col } | Emits on link click. |
| linkDoubleClick | { node, level, path, url, col } | Emits on link double click. |
| onPaginationChange | { page, pageSize } | Emits when page changes. |
| onColConfigChange | string[] | Emits visible column field names. |
| onHideSettings | boolean | Emits when settings panel is hidden. |
Custom No Data Template
Pass a template from the parent component through tableOptions.
<cats-data-grid [rowData]="[]" [colDefs]="colDefs" [tableOptions]="tableOptions"></cats-data-grid>
<ng-template #noDataTemplate>
<div class="no-data">No records found</div>
</ng-template>import { AfterViewInit, ViewChild } from "@angular/core";
export class UsersComponent implements AfterViewInit {
@ViewChild("noDataTemplate") noDataTemplate!: any;
tableOptions: any = {};
ngAfterViewInit(): void {
this.tableOptions.noDataTemplate = this.noDataTemplate;
}
}Common Usage Tips
- Use
rowIdfor stable row selection and row drag behavior. - Use dot notation in
fieldNamefor nested object values. - Use
filterType: 'set'for columns with repeated predefined values. - Use
dynamicGroupingFilteringwhen grouping/filtering should be handled by an API. - Use
showSkeletonwhile data is loading. - Use
active: falseto hide a column initially. - Use
headerLocked: truefor columns that must always remain visible.
Build And Test
ng build cats-data-grid
ng test cats-data-gridLicense
MIT
