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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@avoraui/av-data-table

v0.0.5

Published

A customizable Angular Data Table component

Readme

AvDataTable Component (AvoraUI)

A powerful, customizable Angular data table component with built-in pagination, event-driven actions, and reactive forms support. This component provides flexibility for users to implement custom business logic through event handlers rather than predefined CRUD operations.

Features

  • Pagination - Built-in pagination with customizable page sizes
  • Event-Driven Actions - Customizable add, modify, and delete event handlers
  • Reactive Forms Integration - Implements ControlValueAccessor
  • Flexible Column Configuration - Support for nested object properties
  • Customizable Styling - Configurable alignment and colors
  • Action Events - Optional action buttons with customizable event handlers
  • User-Controlled Operations - Flexible event system for custom business logic
  • Responsive Grid Layout - CSS Grid-based responsive design
  • Data Synchronization - Automatic sync between internal and external data sources

Dependencies

This component requires the following Angular Material modules:

import { MatCard } from "@angular/material/card";
import { MatButton } from "@angular/material/button";
import { MatIcon } from '@angular/material/icon';
🚨 Version 0.0.4 introduces a breaking change:
Component selector has changed from `aur-data-table` to `av-data-table`.  
Please update your templates accordingly.

Installation

  1. Copy the component files to your Angular project
  2. Import the component in your module or standalone component
  3. Ensure you have Angular Material (for pagination) installed:
ng add @angular/material

Basic Usage

1. Import and Configure

import { AvDataTable } from './path/to/av-data-table';

@Component({
  selector: 'app-example',
  template: `
    <av-data-table
      [TableHeaders]="headers"
      [TableColumns]="columns"
      [Data]="tableData"
      [PageSize]="10"
      [PageSizeOptions]="[5, 10, 25, 50]"
      [EnableActionColumn]="true"
      [EnableButtonDelete]="true"
      [EnableButtonModify]="true"
      (onModify)="handleModify($event)"
      (onItemRemoved)="handleRemove($event)"
      (onNewItemAdded)="handleAdd($event)">
    </av-data-table>
  `
})
export class ExampleComponent {
  // Component implementation
}

2. Define Headers and Columns

export interface Headers {
  label: string;
  align: 'left' | 'center' | 'right';
}

export interface Columns {
  field: string;
  align: 'left' | 'center' | 'right';
  color?: string;
}
export class ExampleComponent {
  headers: Headers[] = [
    { label: 'Name', align: 'left' },
    { label: 'Email', align: 'left' },
    { label: 'Department', align: 'left' },
    { label: 'Action', align: 'center' }
  ];

  columns: Columns[] = [
    { field: 'name', align: 'left', color: '#3182ce' },
    { field: 'email', align: 'left' },
    { field: 'department.name', align: 'left' }, // Nested property
  ];

  tableData = [
    { 
      name: 'Kasun Perera', 
      email: '[email protected]', 
      department: { name: 'Information Technology', code: 'IT' } 
    },
    { 
      name: 'Nimali Fernando', 
      email: '[email protected]', 
      department: { name: 'Human Resources', code: 'HR' } 
    },
    { 
      name: 'Rajitha Silva', 
      email: '[email protected]', 
      department: { name: 'Finance & Accounting', code: 'FIN' } 
    },
    { 
      name: 'Chaminda Jayawardena', 
      email: '[email protected]', 
      department: { name: 'Marketing & Sales', code: 'MKT' } 
    }
  ];
}

API Reference

Input Properties

| Property | Type | Default | Description | |----------|------|---------|-------------| | TableHeaders | Headers[] | [] | Array of header configurations | | TableColumns | Columns[] | [] | Array of column configurations | | Data | any[] | [] | Data source for the table | | PageSize | number | 5 | Number of items per page | | PageSizeOptions | number[] | [] | Available page size options | | currentPage | number | 0 | Current active page index | | EnableActionColumn | boolean | false | Show/hide action column | | EnableButtonDelete | boolean | false | Enable delete button in actions | | EnableButtonModify | boolean | false | Enable modify button in actions | | DisableRemove | boolean | false | Disable remove functionality | | DisableModify | boolean | false | Disable modify functionality |

Output Events

| Event | Type | Description | |-------|------|-------------| | onModify | EventEmitter<{index: number, modifiedItem: any, disabled: boolean}> | Emitted when modify button is clicked - allows custom handling like opening edit forms, viewing details, etc. | | onItemRemoved | EventEmitter<{index: number, dataSize: number, removedItem: any, disabled: boolean}> | Emitted when delete button is clicked - allows custom removal logic, confirmations, API calls, etc. | | onNewItemAdded | EventEmitter<{index: number, dataSize: number, removedItem: any}> | Emitted when new item events occur - allows custom add item logic |

Interfaces

interface Headers {
  label: string;
  align: 'left' | 'center' | 'right';
}

interface Columns {
  field: string;
  align: 'left' | 'center' | 'right';
  color?: string;
}

Advanced Usage

Nested Object Properties

The component supports accessing nested object properties using dot notation:

columns: Columns[] = [
  { field: 'employee.profile.firstName' },
  { field: 'employee.contact.address.city' },
  { field: 'employee.roles.name' }, // Will join array values with commas
  { field: 'department.name' } // Access nested department name
];

Reactive Forms Integration

The component implements ControlValueAccessor, making it compatible with Angular Reactive Forms:

import { FormBuilder, FormGroup } from '@angular/forms';

export class ExampleComponent {
  form: FormGroup;

  constructor(private fb: FormBuilder) {
    this.form = this.fb.group({
      tableData: [[]] // Initial empty array
    });
  }
}
<form [formGroup]="form">
  <av-data-table 
    formControlName="tableData"
    [TableHeaders]="headers"
    [TableColumns]="columns">
  </av-data-table>
</form>

Event Handling

The component provides flexible event handlers that allow you to implement custom business logic:

handleModify(event: {index: number, modifiedItem: any, disabled: boolean}) {
  if (event.disabled) {
    console.log('Modify action is disabled');
    return;
  }
  
  // Example: Open edit dialog with the selected row data
  console.log('Modifying employee:', event.modifiedItem.name);
  console.log('Employee data:', event.modifiedItem);
  
  // You can:
  // - Open a modal/dialog for editing
  // - Navigate to an edit page
  // - Show detailed view
  // - Perform any custom logic with the row data
  this.openEditDialog(event.modifiedItem, event.index);
}

handleRemove(event: {index: number, dataSize: number, removedItem: any, disabled: boolean}) {
  if (event.disabled) {
    console.log('Remove action is disabled');
    return;
  }
  
  // Example: Custom confirmation and API call
  const employee = event.removedItem;
  const confirmed = confirm(`Are you sure you want to remove ${employee.name}?`);
  
  if (confirmed) {
    // You can:
    // - Make API calls to delete from server
    // - Update other related data
    // - Show success/error messages
    // - Perform cleanup operations
    console.log(`${employee.name} removed from ${employee.department.name}`);
    console.log('Remaining employees:', event.dataSize);
    
    // Example API call
    this.employeeService.deleteEmployee(employee.id).subscribe({
      next: () => console.log('Successfully deleted from server'),
      error: (err) => console.error('Deletion failed:', err)
    });
  }
}

handleAdd(event: {index: number, dataSize: number}) {
  // Example: Trigger add new employee flow
  console.log('Adding new employee...');
  
  // You can:
  // - Open add employee dialog
  // - Navigate to create page  
  // - Show form modal
  // - Perform any custom add logic
  this.openAddEmployeeDialog();
}

Custom Styling

The component uses CSS classes that you can override:

/* Header alignment */
.header-text-left { text-align: left; }
.header-text-center { text-align: center; }
.header-text-right { text-align: right; }

/* Data cell alignment */
.text-left { text-align: left; }
.text-center { text-align: center; }
.text-right { text-align: right; }

/* Grid layout customization */
.table-grid {
  display: grid;
  gap: 1rem;
  /* grid-template-columns is set dynamically */
}

Requirements

  • Angular 17+
  • Angular Material (for pagination component)
  • Modern browser with CSS Grid support

Browser Support

  • Chrome/Edge 57+
  • Firefox 52+
  • Safari 10.1+

License

This project is licensed under the MIT License - see the LICENSE file for details.

Changelog

v0.0.5

  • Initial release
  • Basic table functionality with pagination
  • CRUD operations support
  • Reactive forms integration
  • Nested object property access