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:
- Global Material Theme: Configure colors in your Angular Material theme
- Component-specific Styles: Add custom CSS classes
- Color Input: Use the
colorproperty 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
- Provide meaningful labels for all buttons
- Use appropriate icons that match the button purpose
- Set badge counts appropriately for notification indicators
- Consider color contrast when using custom colors
- 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
- Icons not displaying: Ensure Material Icons are loaded in your index.html
- Badge not showing: Make sure MatBadgeModule is imported in your module
- Form control not working: Verify ReactiveFormsModule is imported
- Colors not applying: Check that custom colors are valid CSS color values
Performance Tips
- Use OnPush change detection for better performance with large button arrays
- Implement trackBy for dynamic button lists
- Avoid frequent data object recreation to prevent unnecessary re-renders
- Use immutable data patterns for button action updates
