@avoraui/av-notifications
v0.0.3
Published
A flexible Angular notification service with toast-style alerts, multiple positioning options, and theme support. Built with Angular Material for modern web applications.
Maintainers
Readme
AvNotification Service (AvoraUI)
A flexible and customizable Angular notification service that provides toast-style notifications with multiple positioning options, themes, and animation effects. Built with Angular Material Dialog for optimal performance and accessibility.
Features
- ✅ Multiple Notification Types: Success, Error, and Warning notifications
- ✅ Flexible Positioning: 8 different position options (top, bottom, corners, sides)
- ✅ Theme Support: Light, dark, and auto themes
- ✅ Auto-close Functionality: Configurable duration with optional manual close
- ✅ Animation Effects: Smooth entrance and exit animations
- ✅ Stack Management: Multiple notifications with proper stacking
- ✅ Material Design: Built with Angular Material components
- ✅ Memory Efficient: Automatic cleanup and tracking of active notifications
- ✅ Accessibility: Full keyboard navigation and screen reader support
Dependencies
This service requires the following Angular Material modules:
import { MatDialog, MatDialogModule } from "@angular/material/dialog";
import { MatButton } from "@angular/material/button";
import { MatIcon } from '@angular/material/icon';
import { MatCard } from "@angular/material/card";Required Dependencies:
@angular/animations: "^20.1.3"
Installation
- Ensure you have Angular Material installed in your project
- Install Angular Animations:
npm install @angular/animations@^20.1.3 - Import the notification service in your module or inject it directly (standalone service)
- Add the notification components to your module declarations
Quick Start
Basic Usage
import { AvNotificationService } from '@avoraui/av-notifications';
export class MyComponent {
constructor(private notificationService: AvNotificationService) {}
showNotifications() {
// Success notification
this.notificationService.showSuccess('Operation completed successfully!');
// Error notification
this.notificationService.showFailure('Something went wrong!');
// Warning notification
this.notificationService.showWarning('Please check your input!');
}
}Advanced Configuration
All Available Options
export class AdvancedNotificationComponent {
constructor(private notificationService: AvNotificationService) {}
showCustomNotifications() {
// Success with custom configuration
this.notificationService.showSuccess('File uploaded successfully!', {
position: 'top-right',
duration: 8000,
theme: 'dark',
showCloseButton: true,
autoClose: true,
animationDuration: 500
});
// Error with persistent notification (no auto-close)
this.notificationService.showFailure('Critical system error occurred', {
position: 'center',
autoClose: false,
theme: 'light',
showCloseButton: true
});
// Warning with custom positioning
this.notificationService.showWarning('Session will expire in 5 minutes', {
position: 'bottom-left',
duration: 10000,
theme: 'auto',
animationDuration: 300
});
}
}Configuration Options
NotificationConfig Interface
| Property | Type | Required | Default | Description |
|----------|------|----------|---------|-------------|
| message | string | Yes | - | The notification message to display |
| type | NotificationType | Yes | - | Type of notification (success, error, warning) |
| position | NotificationPosition | No | 'top' | Position where notification appears |
| duration | number | No | 5000 | Auto-close duration in milliseconds |
| animationDuration | number | No | 300 | Animation duration in milliseconds |
| showCloseButton | boolean | No | true | Whether to show manual close button |
| autoClose | boolean | No | true | Whether notification auto-closes |
| theme | NotificationTheme | No | 'auto' | Visual theme (light, dark, auto) |
Position Options
type NotificationPosition =
| 'top' // Top center
| 'bottom' // Bottom center
| 'left' // Left center
| 'right' // Right center
| 'top-left' // Top left corner
| 'top-right' // Top right corner
| 'bottom-left' // Bottom left corner
| 'bottom-right'; // Bottom right cornerNotification Types
type NotificationType = 'success' | 'error' | 'warning';Theme Options
type NotificationTheme = 'light' | 'dark' | 'auto';Service Methods
Core Methods
// Show success notification
showSuccess(message: string, options?: Partial<NotificationConfig>): MatDialogRef<any>
// Show error notification
showFailure(message: string, options?: Partial<NotificationConfig>): MatDialogRef<any>
// Show warning notification
showWarning(message: string, options?: Partial<NotificationConfig>): MatDialogRef<any>Management Methods
// Close all active notifications
closeAll(): void
// Close notifications by type
closeByType(type: NotificationType): void
// Get count of active notifications
getActiveCount(): number
// Check if notifications are active
hasActiveNotifications(type?: NotificationType): booleanReal-World Examples
E-commerce Application
export class EcommerceService {
constructor(private notificationService: AvNotificationService) {}
// Product added to cart
addToCart(product: Product) {
this.cartService.add(product).subscribe({
next: () => {
this.notificationService.showSuccess(`${product.name} added to cart!`, {
position: 'top-right',
duration: 3000,
theme: 'light'
});
},
error: () => {
this.notificationService.showFailure('Failed to add product to cart', {
position: 'top-right',
duration: 5000,
theme: 'light'
});
}
});
}
// Low stock warning
checkStockLevels() {
this.notificationService.showWarning('Only 2 items left in stock!', {
position: 'bottom-right',
duration: 8000,
theme: 'auto',
showCloseButton: true
});
}
// Payment processing
processPayment() {
this.notificationService.showSuccess('Payment processed successfully!', {
position: 'center',
duration: 4000,
theme: 'dark',
animationDuration: 500
});
}
}Form Validation
export class UserFormComponent {
constructor(private notificationService: AvNotificationService) {}
onSubmit(formData: UserForm) {
if (this.validateForm(formData)) {
this.userService.save(formData).subscribe({
next: () => {
this.notificationService.showSuccess('User profile updated successfully!', {
position: 'top',
duration: 6000,
theme: 'light'
});
},
error: (error) => {
this.notificationService.showFailure(`Update failed: ${error.message}`, {
position: 'top',
autoClose: false,
theme: 'light',
showCloseButton: true
});
}
});
} else {
this.notificationService.showWarning('Please fill in all required fields', {
position: 'top-left',
duration: 4000,
theme: 'auto'
});
}
}
}File Upload Progress
export class FileUploadComponent {
constructor(private notificationService: AvNotificationService) {}
uploadFile(file: File) {
// Start upload notification
const uploadingRef = this.notificationService.showSuccess('Starting file upload...', {
position: 'bottom-right',
duration: 2000,
theme: 'dark'
});
this.fileService.upload(file).subscribe({
next: (progress) => {
if (progress === 100) {
this.notificationService.showSuccess('File uploaded successfully!', {
position: 'bottom-right',
duration: 5000,
theme: 'light',
animationDuration: 400
});
}
},
error: () => {
this.notificationService.showFailure('Upload failed. Please try again.', {
position: 'bottom-right',
autoClose: false,
theme: 'light',
showCloseButton: true
});
}
});
}
}System Notifications
export class SystemNotificationService {
constructor(private notificationService: AvNotificationService) {}
// Session timeout warning
showSessionTimeout() {
this.notificationService.showWarning('Your session will expire in 2 minutes', {
position: 'top',
duration: 10000,
theme: 'auto',
showCloseButton: true,
animationDuration: 300
});
}
// Maintenance mode
showMaintenanceMode() {
this.notificationService.showWarning('System maintenance scheduled for tonight', {
position: 'bottom',
autoClose: false,
theme: 'dark',
showCloseButton: true
});
}
// Connection status
showConnectionLost() {
this.notificationService.showFailure('Connection lost. Attempting to reconnect...', {
position: 'top-right',
autoClose: false,
theme: 'light',
showCloseButton: false
});
}
showConnectionRestored() {
this.notificationService.showSuccess('Connection restored!', {
position: 'top-right',
duration: 3000,
theme: 'light'
});
}
}Advanced Usage
Managing Multiple Notifications
export class NotificationManagerComponent {
constructor(private notificationService: AvNotificationService) {}
showBulkOperationResults() {
// Clear any existing notifications
this.notificationService.closeAll();
// Show results
this.notificationService.showSuccess('5 items processed successfully', {
position: 'top-right',
duration: 4000
});
this.notificationService.showWarning('2 items skipped (duplicates)', {
position: 'top-right',
duration: 6000
});
this.notificationService.showFailure('1 item failed to process', {
position: 'top-right',
duration: 8000
});
}
clearSpecificNotifications() {
// Close only error notifications
this.notificationService.closeByType('error');
// Check if any notifications are still active
const hasActiveNotifications = this.notificationService.hasActiveNotifications();
console.log('Active notifications:', hasActiveNotifications);
// Get count of active notifications
const count = this.notificationService.getActiveCount();
console.log('Total active notifications:', count);
}
}Custom Styling Integration
// Custom notification styles
.notification-dialog {
&.notification-top-right {
margin-right: 24px !important;
margin-top: 24px !important;
}
&.notification-success {
.mat-mdc-dialog-container {
background: linear-gradient(135deg, #4caf50, #45a049);
color: white;
}
}
&.notification-theme-dark {
.mat-mdc-dialog-container {
background: #333;
color: #fff;
}
}
}Browser Support
- Chrome/Edge 57+
- Firefox 52+
- Safari 10.1+
- Modern browsers with CSS Grid and Flexbox support
Requirements
- Angular 17+
- Angular Material
- Modern browser with CSS Grid support
Performance Considerations
- Notifications are automatically tracked and cleaned up
- Object URLs are properly revoked to prevent memory leaks
- Efficient dialog positioning with CSS transforms
- Minimal DOM impact with Angular Material's overlay system
Accessibility Features
- Full keyboard navigation support
- Screen reader compatibility
- High contrast theme support
- Focus management for modal notifications
- ARIA labels and descriptions
Best Practices
Do's
// ✅ Use appropriate notification types
this.notificationService.showSuccess('Data saved successfully');
this.notificationService.showFailure('Validation error occurred');
this.notificationService.showWarning('Session expiring soon');
// ✅ Configure duration based on content importance
this.notificationService.showSuccess('Quick action completed', { duration: 3000 });
this.notificationService.showFailure('Critical error', { autoClose: false });
// ✅ Use consistent positioning
this.notificationService.showSuccess('Success', { position: 'top-right' });
this.notificationService.showFailure('Error', { position: 'top-right' });Don'ts
// ❌ Don't show too many notifications at once
// Instead, use closeAll() or batch them appropriately
// ❌ Don't use very short durations for important messages
this.notificationService.showFailure('Critical error', { duration: 1000 }); // Too short
// ❌ Don't forget to handle notification cleanup in components
// Always let the service manage notification lifecycleTroubleshooting
Common Issues
- Notifications not appearing
- Ensure Angular Material Dialog is imported
- Check that notification components are declared
- Verify CSS z-index values
- Styling issues
- Import Angular Material themes
- Check for CSS conflicts with custom styles
- Ensure proper theme configuration
- Performance issues
- Use
closeAll()before showing bulk notifications - Avoid very short animation durations
- Monitor active notification count
License
This project is licensed under the MIT License - see the LICENSE file for details.
Changelog
v0.0.3
- Success, error, and warning notification types
- 8 positioning options
- Theme support (light, dark, auto)
- Animation controls
- Stack management
- Accessibility features
