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

action-buttons

v15.0.7

Published

This is an Angular Module containing Components/Services using Material

Readme

Action Buttons Component

Overview

The action-buttons library provides a Material Design-based component for displaying action buttons with various configurations including icons, labels, badges, colors, and disabled states. It implements Angular's ControlValueAccessor interface for seamless form integration.

Core Capabilities

🎯 Material Design Button Actions

  • Multiple Display Modes: Icon-only, labeled buttons, or combination
  • Badge Support: Display notification counts with badge overlays
  • Color Customization: Apply custom colors to individual buttons
  • State Management: Built-in support for disabled states
  • SVG Icons: Support for both Material Icons and custom SVG icons
  • Form Integration: Implements ControlValueAccessor for reactive forms

🔧 Features

ControlValueAccessor Implementation - Works with Angular forms
Material Design Integration - Uses Angular Material components
Badge Notifications - Visual notification indicators
Color Customization - Theme-aware button colors
SVG Icon Support - Works with Material Icons and custom SVGs
Responsive Design - Adapts to different screen sizes
Accessibility Ready - ARIA labels and keyboard navigation

Key Benefits

| Feature | Description | |---------|-------------| | Form Integration | Native Angular form control support | | Visual Feedback | Badge system for notifications/counts | | Flexible Styling | Color customization and Material Design theming | | Icon Support | Works with Material Icons and SVG icons | | State Management | Disabled states and conditional rendering |


Demo Component (ActionButtonsDemoComponent)

The demo component showcases various button configurations and states, providing interactive examples of the action buttons functionality.

Usage

To use the demo component in your application:

<app-action-buttons-demo></app-action-buttons-demo>

The demo includes:

  • Phone button (disabled state)
  • Messages button (with badge showing 6 notifications)
  • Alerts button (zero badge state)
  • Different color configurations
  • Disabled and enabled states

Summary

The action-buttons library provides a flexible, Material Design-compliant button component for Angular applications with badge support, color customization, and form integration.


Quick Start Guide

Installation & Setup (2 minutes)

1. Import Module

// app.module.ts
import { ActionButtonsModule } from 'action-buttons';

@NgModule({
  imports: [
    ActionButtonsModule
  ]
})
export class AppModule { }

2. No Module Configuration Required

The ActionButtonsModule does not require global configuration. Components can be used immediately after module import.

Quick Examples

Example 1: Basic Button Actions

import { Component } from '@angular/core';
import { ButtonAction } from 'action-buttons';

@Component({
  selector: 'app-buttons',
  template: `
    <app-action-buttons
      [data]="buttonActions"
      [disabled]="isDisabled">
    </app-action-buttons>
  `
})
export class ButtonsComponent {
  isDisabled = false;

  buttonActions: ButtonAction[] = [
    { icon: 'dialpad', label: 'Phone', disabled: true },
    { icon: 'voicemail', label: 'Messages', badge: 6, color: 'orange' },
    { icon: 'notifications_off', label: 'Alerts', badge: 0 }
  ];
}

Example 2: Form Control Integration

import { Component } from '@angular/core';
import { FormControl } from '@angular/forms';
import { ButtonAction } from 'action-buttons';

@Component({
  selector: 'app-form-buttons',
  template: `
    <app-action-buttons
      [formControl]="buttonControl"
      [data]="buttonActions">
    </app-action-buttons>
    
    <div>Selected: {{ buttonControl.value | json }}</div>
  `
})
export class FormButtonsComponent {
  buttonControl = new FormControl();
  
  buttonActions: ButtonAction[] = [
    { icon: 'edit', label: 'Edit', color: 'primary' },
    { icon: 'delete', label: 'Delete', color: 'warn' },
    { icon: 'share', label: 'Share', color: 'accent' }
  ];
}

Example 3: Dynamic Button States

import { Component } from '@angular/core';
import { ButtonAction } from 'action-buttons';

@Component({
  selector: 'app-dynamic-buttons',
  template: `
    <div class="button-controls">
      <button (click)="toggleDisabled()">
        {{ isDisabled ? 'Enable' : 'Disable' }} Buttons
      </button>
      <button (click)="addNotification()">Add Notification</button>
    </div>
    
    <app-action-buttons
      [data]="buttonActions"
      [disabled]="isDisabled">
    </app-action-buttons>
    
    <div *ngFor="let action of buttonActions; let i = index">
      {{ action.label }}: Badge = {{ action.badge || 0 }}
    </div>
  `
})
export class DynamicButtonsComponent {
  isDisabled = false;
  notificationCount = 3;

  buttonActions: ButtonAction[] = [
    { icon: 'home', label: 'Home' },
    { icon: 'search', label: 'Search' },
    { icon: 'notifications', label: 'Notifications', badge: this.notificationCount }
  ];

  toggleDisabled() {
    this.isDisabled = !this.isDisabled;
  }

  addNotification() {
    this.notificationCount++;
    this.buttonActions[2].badge = this.notificationCount;
  }
}

Example 4: Custom Styled Buttons

import { Component } from '@angular/core';
import { ButtonAction } from 'action-buttons';

@Component({
  selector: 'app-styled-buttons',
  template: `
    <div class="button-groups">
      <!-- Primary Actions -->
      <h3>Primary Actions</h3>
      <app-action-buttons [data]="primaryActions"></app-action-buttons>
      
      <!-- Status Actions -->
      <h3>Status Actions</h3>
      <app-action-buttons [data]="statusActions"></app-action-buttons>
      
      <!-- Icon Only -->
      <h3>Icon Only</h3>
      <app-action-buttons [data]="iconOnlyActions"></app-action-buttons>
    </div>
  `,
  styles: [`
    .button-groups { margin: 2rem; }
    h3 { margin: 1rem 0 0.5rem; color: #666; }
  `]
})
export class StyledButtonsComponent {
  primaryActions: ButtonAction[] = [
    { icon: 'add', label: 'Add', color: 'primary' },
    { icon: 'edit', label: 'Edit', color: 'primary' },
    { icon: 'save', label: 'Save', color: 'primary' }
  ];

  statusActions: ButtonAction[] = [
    { icon: 'check_circle', label: 'Approved', color: 'green' },
    { icon: 'warning', label: 'Warning', color: 'orange' },
    { icon: 'error', label: 'Error', color: 'red' }
  ];

  iconOnlyActions: ButtonAction[] = [
    { icon: 'star', label: 'Favorite' },
    { icon: 'bookmark', label: 'Bookmark' },
    { icon: 'share', label: 'Share' }
  ];
}

Component API

Inputs

| Input | Type | Description | Default | | :--- | :--- | :--- | :--- | | data | ButtonAction[] | Array of button action configurations | [] | | disabled | boolean | Whether the entire component is disabled | false |

Outputs

| Output | Type | Description | | :--- | :--- | :--- | | selectionChange | EventEmitter<any> | Emits when a button is selected/clicked |


Model Structures

ButtonAction Interface

export interface ButtonActionInterface {
  label?: string;        // Button text label
  icon?: string;         // Material icon name or custom icon
  disabled?: boolean;    // Individual button disabled state
  badge?: number;        // Notification badge count (0 or positive number)
  color?: string;        // Custom color (CSS color value)
  svg?: boolean;         // Whether icon is SVG format
}

ButtonAction Class

export class ButtonAction implements ButtonActionInterface {
  constructor(
    public label?: string,
    public icon?: string,
    public disabled?: boolean = false,
    public badge?: number = 0,
    public color?: string,
    public svg?: boolean = false
  ) {}

  static adapt(data?: any): ButtonAction {
    return new ButtonAction(
      data?.label,
      data?.icon,
      (data?.disabled) ? data.disabled : false,
      (data?.badge) ? data.badge : 0,
      data?.color,
      (data?.svg) ? true : false
    );
  }
}

Usage Examples

// Basic button configuration
const basicButton: ButtonAction = new ButtonAction(
  'Click Me',           // label
  'touch_app',          // icon
  false,                // disabled
  0,                    // badge
  undefined,            // color
  false                 // svg
);

// Using the adapt method
const adaptedButton = ButtonAction.adapt({
  label: 'Save',
  icon: 'save',
  badge: 5,
  color: 'accent'
});

// Configuration with all options
const fullConfig: ButtonAction[] = [
  { label: 'Home', icon: 'home', disabled: false, badge: 0 },
  { label: 'Profile', icon: 'person', color: 'primary' },
  { label: 'Settings', icon: 'settings', badge: 3, color: 'warn' },
  { label: 'Custom SVG', icon: 'custom-icon', svg: true }
];

Module Configuration

ActionButtonsModule

No Global Configuration Required

The ActionButtonsModule does not provide a forRoot() method or global configuration options. All configuration is done at the component level through input properties.

Module Structure

@NgModule({
  imports: [
    CommonModule,
    FormsModule,
    ReactiveFormsModule,
    MatIconModule,
    MatButtonModule,
    MatBadgeModule,
  ],
  declarations: [
    ActionButtonsComponent,
    ActionButtonsDemoComponent,
  ],
  exports:[
    ActionButtonsComponent,
    ActionButtonsDemoComponent,
  ]
})
export class ActionButtonsModule { }

Dependencies

  • @angular/common: Core Angular functionality
  • @angular/forms: Form control integration
  • @angular/material: Material Design components
    • MatIconModule: Icon display
    • MatButtonModule: Button base component
    • MatBadgeModule: Badge notifications

Styling and Customization

CSS Classes and Styling

The component uses Material Design styling and can be customized using:

  1. Global Material Theme: Configure colors in your Angular Material theme
  2. Component-specific Styles: Add custom CSS classes
  3. Color Input: Use the color property for individual button styling

Example Customization

// Custom styles for action buttons
:host ::ng-deep .action-buttons {
  .mat-button-wrapper {
    display: flex;
    flex-direction: column;
    align-items: center;
  }
  
  .button-label {
    font-size: 0.75rem;
    margin-top: 4px;
  }
  
  .mat-badge-content {
    font-size: 0.6rem;
    font-weight: bold;
  }
}

Accessibility

ARIA Support

  • Buttons include proper ARIA labels
  • Keyboard navigation is supported
  • Screen reader friendly with label and icon descriptions
  • Badge notifications include appropriate ARIA live regions

Best Practices

  1. Provide meaningful labels for all buttons
  2. Use appropriate icons that match the button purpose
  3. Set badge counts appropriately for notification indicators
  4. Consider color contrast when using custom colors
  5. Test with screen readers to ensure accessibility

Integration Examples

With Other UI Components

// Integration with display-card
@Component({
  template: `
    <app-display-card [title]="'User Actions'">
      <app-action-buttons [data]="userActions"></app-action-buttons>
    </app-display-card>
  `
})
export class CardWithActionsComponent {
  userActions: ButtonAction[] = [
    { icon: 'edit', label: 'Edit Profile', color: 'primary' },
    { icon: 'security', label: 'Security', color: 'accent' },
    { icon: 'notifications', label: 'Notifications', badge: 2 }
  ];
}

With State Management

// Integration with HTTP Request Manager
@Component({
  template: `
    <app-action-buttons 
      [data]="actionButtons$ | async"
      (selectionChange)="handleAction($event)">
    </app-action-buttons>
  `
})
export class StateManagedButtonsComponent {
  actionButtons$ = this.actionStore.buttons$;
  
  constructor(private actionStore: ActionStore) {}
  
  handleAction(action: ButtonAction) {
    this.actionStore.executeAction(action);
  }
}

Testing

Unit Testing Example

import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ActionButtonsComponent } from './action-buttons.component';
import { ButtonAction } from './models/button-action.model';

describe('ActionButtonsComponent', () => {
  let component: ActionButtonsComponent;
  let fixture: ComponentFixture<ActionButtonsComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [ ActionButtonsComponent ]
    }).compileComponents();

    fixture = TestBed.createComponent(ActionButtonsComponent);
    component = fixture.componentInstance;
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });

  it('should display buttons from data input', () => {
    component.data = [
      { label: 'Test', icon: 'home' }
    ];
    fixture.detectChanges();
    
    const compiled = fixture.nativeElement;
    expect(compiled.textContent).toContain('Test');
  });

  it('should emit selection change when button is clicked', () => {
    spyOn(component.selectionChange, 'emit');
    component.data = [{ label: 'Test', icon: 'home' }];
    fixture.detectChanges();
    
    const button = fixture.nativeElement.querySelector('button');
    button.click();
    
    expect(component.selectionChange.emit).toHaveBeenCalled();
  });
});

Troubleshooting

Common Issues

  1. Icons not displaying: Ensure Material Icons are loaded in your index.html
  2. Badge not showing: Make sure MatBadgeModule is imported in your module
  3. Form control not working: Verify ReactiveFormsModule is imported
  4. Colors not applying: Check that custom colors are valid CSS color values

Performance Tips

  1. Use OnPush change detection for better performance with large button arrays
  2. Implement trackBy for dynamic button lists
  3. Avoid frequent data object recreation to prevent unnecessary re-renders
  4. Use immutable data patterns for button action updates