Skip to content

white-devil1/ngx-signal-toast-workspace

Repository files navigation



 β–ˆβ–ˆβ–ˆβ•—   β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—  β–ˆβ–ˆβ•—      β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ•—  β–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—
 β–ˆβ–ˆβ–ˆβ–ˆβ•—  β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β• β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•      β–ˆβ–ˆβ•”β•β•β•β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β•β•β• β–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘
 β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ–ˆβ•— β•šβ–ˆβ–ˆβ–ˆβ•”β• β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘
 β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β•šβ•β•β•β•β•β•šβ•β•β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘
 β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•”β• β–ˆβ–ˆβ•—      β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—
 β•šβ•β•  β•šβ•β•β•β• β•šβ•β•β•β•β•β• β•šβ•β•  β•šβ•β•      β•šβ•β•β•β•β•β•β•β•šβ•β• β•šβ•β•β•β•β•β• β•šβ•β•  β•šβ•β•β•β•šβ•β•  β•šβ•β•β•šβ•β•β•β•β•β•β•

 β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—  β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—
    β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•”β•β•β•β•β•β•šβ•β•β–ˆβ–ˆβ•”β•β•β•
    β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—   β–ˆβ–ˆβ•‘
    β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•‘β•šβ•β•β•β•β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘
    β–ˆβ–ˆβ•‘   β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ•‘  β–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘
    β•šβ•β•    β•šβ•β•β•β•β•β• β•šβ•β•  β•šβ•β•β•šβ•β•β•β•β•β•β•   β•šβ•β•

The most powerful Angular 21 toast library β€” built entirely on Signals

Zero @angular/animations Β· Zero Zone.js dependency Β· Zero HTML tags to add

πŸš€ Quick Start Β· πŸ“– API Reference Β· 🎨 Themes Β· πŸ’‘ Examples Β· βš™οΈ Configuration



πŸ“‹ Table of Contents


πŸ€” Why ngx-signal-toast?

πŸ†š Comparison with Other Toast Libraries

Feature ngx-signal-toast ngx-toastr hot-toast
Angular 21 native βœ… ❌ ❌
Signals-first (no RxJS) βœ… ❌ ❌
Zoneless compatible βœ… ❌ ❌
@angular/animations free βœ… ❌ ❌
Auto-inject container βœ… ❌ ❌
8 built-in themes βœ… ❌ ❌
6 layout styles βœ… ❌ ❌
9 positions βœ… ❌ ❌
Native CSS animations βœ… ❌ ❌
SSR safe βœ… ⚠️ ⚠️
Zero dependencies βœ… ❌ ❌
Promise API βœ… ❌ βœ…
TypeScript 5.5+ βœ… ⚠️ ⚠️

✨ Features

  • 🎯 100% Signals β€” built with signal(), computed(), effect() β€” no RxJS at all
  • ⚑ Zoneless Ready β€” works perfectly with Angular's new zoneless change detection
  • 🎨 8 Beautiful Themes β€” Default, Glassmorphism, Neumorphism, Aurora, Neon, Luxury, Material, Brutalist
  • πŸ“ 6 Layout Styles β€” Default, Compact, Card, Pill, Sidebar, Banner
  • πŸ“ 9 Positions β€” all corners, edges, and center
  • 🎬 5 Animation Presets β€” Slide, Fade, Bounce, Zoom, Flip β€” all via native CSS (no @angular/animations)
  • πŸ”„ Promise API β€” loading β†’ success/error in one call
  • ⏸️ Pause on Hover β€” progress bar pauses when user hovers
  • 🎯 Action Buttons β€” add interactive buttons inside any toast
  • πŸ“ Update in Flight β€” update message/type/duration of an active toast
  • 🌍 RTL Support β€” full right-to-left text support
  • β™Ώ ARIA compliant β€” role="alert", aria-live, aria-label built-in
  • πŸ–₯️ SSR Safe β€” isPlatformBrowser guards throughout
  • 🎭 Custom Icons β€” emoji, component, or template ref
  • 🎨 Custom Body β€” inject your own component as toast body
  • πŸ”— Auto-inject β€” no <nst-toast-container> HTML tag needed
  • πŸ“¦ ~0 extra dependencies β€” only @angular/core and @angular/common

πŸ“Œ Version & Requirements

Package Version
ngx-signal-toast 1.1.0
@angular/core >= 21.0.0
@angular/common >= 21.0.0
TypeScript >= 5.5
Node.js >= 20.0.0

⚠️ Angular 21 only. This library uses APIs introduced in Angular 21 (provideAppInitializer, signals-first DI). It will not work on older versions.


πŸ“¦ Installation

# npm
npm install ngx-signal-toast

# yarn
yarn add ngx-signal-toast

# pnpm
pnpm add ngx-signal-toast

Using ng-add (recommended)

ng add ngx-signal-toast

The schematic will automatically:

  • Add provideNgxSignalToast() to your app.config.ts
  • Ask you to choose a default theme and position

πŸš€ Quick Start

Step 1 β€” Register the provider

Open app.config.ts and add provideNgxSignalToast():

// app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';
import { provideNgxSignalToast } from 'ngx-signal-toast';

export const appConfig: ApplicationConfig = {
  providers: [
    provideRouter(routes),
    provideNgxSignalToast({
      position: 'top-right',
      duration: 4000,
      theme: 'default',
    }),
  ],
};

βœ… That's it. No <nst-toast-container> tag needed anywhere. The container is automatically injected into document.body.

Step 2 β€” Inject and use

// any.component.ts
import { Component, inject } from '@angular/core';
import { ToastService } from 'ngx-signal-toast';

@Component({
  selector: 'app-root',
  standalone: true,
  template: `<button (click)="showToast()">Show Toast</button>`,
})
export class AppComponent {
  private toast = inject(ToastService);

  showToast() {
    this.toast.success('Operation completed successfully!');
  }
}

πŸ”§ Basic Usage

import { Component, inject } from '@angular/core';
import { ToastService } from 'ngx-signal-toast';

@Component({ ... })
export class MyComponent {
  private toast = inject(ToastService);

  // Basic types
  showSuccess() { this.toast.success('Saved successfully!'); }
  showError()   { this.toast.error('Something went wrong.'); }
  showWarning() { this.toast.warning('Please review your input.'); }
  showInfo()    { this.toast.info('Update available.'); }
  showLoading() { this.toast.loading('Loading your data...'); }

  // With a title
  showWithTitle() {
    this.toast.success('Your file has been uploaded.', {
      title: 'Upload Complete',
    });
  }

  // Custom duration (milliseconds)
  showLong() {
    this.toast.info('This stays for 10 seconds.', { duration: 10000 });
  }

  // Permanent (never auto-dismiss)
  showPermanent() {
    this.toast.warning('Action required.', { duration: 0 });
  }
}

🎯 Toast Types

Method Icon Default Color Use Case
toast.success(msg) βœ“ checkmark Green #22c55e Operation completed
toast.error(msg) βœ— cross Red #f43f5e Something failed
toast.warning(msg) ⚠ triangle Amber #f59e0b Needs attention
toast.info(msg) β„Ή circle Blue #3b82f6 Informational
toast.loading(msg) ⟳ spinner Purple #8b5cf6 Async operation
toast.show(msg, opts) β˜… star Pink #ec4899 Custom / flexible

βš™οΈ Configuration

Pass options to provideNgxSignalToast() to set global defaults. Every option can be overridden per-toast.

provideNgxSignalToast({
  position:     'top-right',      // where toasts appear
  duration:     4000,             // auto-dismiss in ms (0 = never)
  theme:        'default',        // visual theme
  layout:       'default',        // layout style
  animation:    'slide',          // enter/leave animation
  maxToasts:    5,                // max visible at once
  showProgress: true,             // show countdown bar
  pauseOnHover: true,             // pause timer on hover
  closeOnClick: false,            // dismiss on toast click
  closable:     true,             // show close button
  dedupe:       false,            // prevent duplicate messages
  rtl:          false,            // right-to-left mode
  zIndex:       9999,             // CSS z-index of container
})

πŸ“š All Options Reference

Global Config Options (provideNgxSignalToast)

Option Type Default Description
position ToastPosition 'top-right' Where toasts appear on screen
duration number 4000 Auto-dismiss time in ms. 0 = never
theme ToastTheme 'default' Visual theme
layout ToastLayout 'default' Layout style
animation ToastAnimationPreset 'slide' Enter/leave animation
maxToasts number 5 Max toasts visible at once
showProgress boolean true Show countdown progress bar
pauseOnHover boolean true Pause timer when hovering
closeOnClick boolean false Dismiss when toast is clicked
closable boolean true Show the Γ— close button
dedupe boolean false Suppress duplicate messages
rtl boolean false Right-to-left text direction
zIndex number 9999 CSS z-index of toast container

Per-Toast Options (ToastOptions)

All global options above plus:

Option Type Default Description
id string auto Custom ID for the toast
title string '' Bold title above the message
type ToastType 'info' Toast type (success/error/warning/info/loading/custom)
group string '' Group name for bulk dismiss
hideIcon boolean false Hide the type icon
iconEmoji string β€” Show an emoji as icon
iconComponent Type<any> β€” Angular component as icon
iconTemplate TemplateRef β€” Template ref as icon
bodyComponent Type<any> β€” Replace entire body with component
ariaLabel string message Accessibility label
data any β€” Attach any custom data
styles ToastCustomStyles β€” Per-toast style overrides
actions ToastAction[] [] Action buttons inside toast
onOpen () => void β€” Callback when toast appears
onClose () => void β€” Callback when toast dismisses

ToastCustomStyles

Property Type Description
accentColor string Icon and accent color (hex/rgb/hsl)
background string Toast background color
borderColor string Border color
borderRadius string | number Border radius (px or CSS string)
titleColor string Title text color
messageColor string Message text color
iconBackground string Icon wrapper background

🎨 Themes

Set globally or per-toast with theme: 'theme-name'.

Theme Description
default Clean, modern dark card with subtle shadow
glassmorphism Frosted glass with blur and transparency
neumorphism Soft shadow depth, tactile feel
aurora Gradient border, northern-lights inspired
neon Glowing neon borders on dark background
luxury Gold accents, premium feel
material Google Material Design style
brutalist Raw, bold, high-contrast editorial style
// Per-toast theme override
this.toast.success('Uploaded!', { theme: 'glassmorphism' });
this.toast.error('Failed!',     { theme: 'neon' });
this.toast.info('Note',         { theme: 'luxury' });

πŸ“ Layouts

Layout Description
default Standard card with icon, title, message
compact Slim single-line with small icon
card Colored top border accent bar
pill Rounded pill shape, centered content
sidebar Left colored stripe accent
banner Full-width banner style
this.toast.info('Compact notification', { layout: 'compact' });
this.toast.success('Card style!',        { layout: 'card' });
this.toast.warning('Full width alert',   { layout: 'banner' });

πŸ“ Positions

9 positions covering the entire viewport:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  top-left   top-center   top-right  β”‚
β”‚                                     β”‚
β”‚ center-left   center   center-right β”‚
β”‚                                     β”‚
β”‚ bottom-left bottom-center bot-right β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Position Value
Top Left 'top-left'
Top Center 'top-center'
Top Right 'top-right'
Center Left 'center-left'
Center 'center'
Center Right 'center-right'
Bottom Left 'bottom-left'
Bottom Center 'bottom-center'
Bottom Right 'bottom-right'
// Different positions per toast
this.toast.success('Top right',     { position: 'top-right' });
this.toast.error('Bottom center',   { position: 'bottom-center' });
this.toast.info('Center screen',    { position: 'center' });

🎬 Animations

All animations use native CSS β€” no @angular/animations package required.

Preset Enter Leave
slide Slides down from top + fade in Slides up + fade out
fade Fade in + slight scale Fade out + scale down
bounce Spring overshoot effect Shrink + fade
zoom Scale from 50% Scale to 50% + fade
flip 3D perspective rotate Rotate back + fade
this.toast.success('Bouncy!', { animation: 'bounce' });
this.toast.info('Flipping in', { animation: 'flip' });
this.toast.error('Zoomed', { animation: 'zoom' });

Accessibility: All animations are automatically disabled when the user has prefers-reduced-motion: reduce set in their OS settings.


πŸ”˜ Toast Actions

Add interactive buttons directly inside a toast:

this.toast.warning('Unsaved changes detected.', {
  title: 'Confirm Action',
  duration: 0,
  actions: [
    {
      label: 'Save',
      onClick: (id) => {
        this.saveData();
        // Toast auto-dismisses after action by default
      },
    },
    {
      label: 'Discard',
      style: 'danger',   // red danger style
      onClick: (id) => {
        this.discardChanges();
      },
      closeOnClick: true,
    },
  ],
});

ToastAction Options

Property Type Default Description
label string required Button text
onClick (id: string) => void required Click handler
style 'default' | 'danger' 'default' Button style
closeOnClick boolean true Auto-dismiss on click

πŸ”„ Promise Toast

Show loading β†’ automatically switch to success or error when the promise resolves:

// Basic promise
await this.toast.promise(
  this.apiService.saveData(payload),
  {
    loading: 'Saving your data...',
    success: 'Saved successfully!',
    error:   'Failed to save. Please try again.',
  }
);

// With dynamic messages based on result
await this.toast.promise(
  this.userService.createUser(form),
  {
    loading: 'Creating account...',
    success: (user) => `Welcome, ${user.name}!`,
    error:   (err)  => `Error: ${err.message}`,
  },
  {
    position: 'top-center',
    theme: 'glassmorphism',
  }
);

⏳ Loading Toast

For long-running async operations you control manually:

// Show loading toast β€” returns a ToastRef
const ref = this.toast.loading('Uploading file...');

try {
  await this.uploadService.upload(file, (progress) => {
    // Update the message dynamically
    ref.update({ message: `Uploading... ${progress}%` });
  });

  // Switch to success when done
  ref.update({
    type: 'success',
    message: 'File uploaded successfully!',
    duration: 4000,  // now auto-dismiss
  });

} catch (error) {
  // Switch to error on failure
  ref.update({
    type: 'error',
    message: 'Upload failed. Please try again.',
    duration: 5000,
  });
}

🎭 Custom Icons

Emoji Icon

this.toast.success('Great job!', {
  iconEmoji: 'πŸŽ‰',
});

this.toast.info('Check this out', {
  iconEmoji: 'πŸ‘€',
});

Angular Component as Icon

@Component({
  standalone: true,
  template: `<svg ...><!-- your SVG --></svg>`,
})
export class MyIconComponent {}

// Use it
this.toast.success('Custom icon!', {
  iconComponent: MyIconComponent,
});

Template Ref as Icon

<ng-template #starIcon>
  <span class="material-icons">star</span>
</ng-template>
@ViewChild('starIcon') starIcon!: TemplateRef<any>;

showToast() {
  this.toast.success('Starred!', {
    iconTemplate: this.starIcon,
  });
}

Hide Icon Entirely

this.toast.info('No icon here', { hideIcon: true });

πŸ–ŒοΈ Custom Styles

Override appearance per-toast using the styles option:

// Custom brand colors
this.toast.show('Custom branded toast!', {
  type: 'custom',
  styles: {
    accentColor:    '#FF6B6B',
    background:     '#1A1A2E',
    borderColor:    '#FF6B6B',
    borderRadius:   20,
    titleColor:     '#FFFFFF',
    messageColor:   '#CCCCCC',
    iconBackground: 'rgba(255,107,107,0.15)',
  },
});

// Combine with emoji icon
this.toast.show('πŸš€ Deployment triggered!', {
  type: 'custom',
  title: 'CI/CD Pipeline',
  iconEmoji: 'πŸš€',
  styles: {
    accentColor: '#6C63FF',
    background: '#0F0F23',
  },
});

🎯 ToastRef β€” Update & Dismiss

Every toast.*() method returns a ToastRef for programmatic control:

const ref = this.toast.info('Processing...', { duration: 0 });

// Update any property of the active toast
ref.update({
  message: 'Almost done...',
  type: 'success',
  duration: 3000,   // starts auto-dismiss countdown
});

// Dismiss programmatically
ref.dismiss();

// Check the ID
console.log(ref.id); // 'nst-1-1234567890'

ToastRef API

Method Description
ref.id Unique string ID of this toast
ref.update(patch) Update any toast option on the fly
ref.dismiss() Dismiss this toast immediately

πŸ—‚οΈ Service Methods

// Show methods
toast.success(message, options?)  // β†’ ToastRef
toast.error(message, options?)    // β†’ ToastRef
toast.warning(message, options?)  // β†’ ToastRef
toast.info(message, options?)     // β†’ ToastRef
toast.loading(message, options?)  // β†’ ToastRef
toast.show(message, options?)     // β†’ ToastRef

// Promise helper
toast.promise(promise, messages, options?)  // β†’ Promise<T>

// Dismiss methods
toast.dismiss(id)           // dismiss one by ID
toast.dismissAll()          // dismiss all visible toasts
toast.dismissByType('error')  // dismiss all of a type
toast.dismissByGroup('auth')  // dismiss by group name

// State signals (read-only)
toast.toasts()     // Signal<Toast[]>
toast.count()      // Signal<number>
toast.isEmpty()    // Signal<boolean>

🎨 CSS Variables

Customize the look globally using CSS custom properties in your styles.css:

:root {
  /* Layout */
  --nst-gap:    10px;   /* gap between stacked toasts */

  /* Per-theme overrides */
  --nst-bg:     #1f2937;
  --nst-color:  #f9fafb;
  --nst-shadow: 0 20px 60px rgba(0, 0, 0, 0.4);
  --nst-radius: 14px;
  --nst-border: none;
  --nst-font:   'Your Font', system-ui, sans-serif;
}

πŸ–₯️ SSR Support

ngx-signal-toast is fully SSR-safe. All browser APIs are guarded with isPlatformBrowser. The container is only injected in browser environments. No extra configuration needed for Angular Universal or any SSR setup.

// Works in SSR β€” library handles this internally
provideNgxSignalToast({ theme: 'default' })

β™Ώ Accessibility

Feature Implementation
ARIA roles role="alert" for errors, role="status" for others
Live regions aria-live="assertive" for errors, aria-live="polite" for others
Labels aria-label on every toast (defaults to message text)
Close button aria-label="Close notification"
Reduced motion All animations disabled via @media (prefers-reduced-motion: reduce)
RTL support Full direction: rtl support via rtl: true option
Focus management Close button focusable with keyboard

πŸ’‘ Examples

E-commerce β€” Cart Notification

addToCart(product: Product) {
  this.cartService.add(product);
  this.toast.success(`${product.name} added to cart`, {
    title: 'Cart Updated',
    layout: 'card',
    theme: 'default',
    iconEmoji: 'πŸ›’',
    duration: 3000,
    actions: [{
      label: 'View Cart',
      onClick: () => this.router.navigate(['/cart']),
    }],
  });
}

Auth β€” Login Flow

async login(credentials: LoginForm) {
  await this.toast.promise(
    this.authService.login(credentials),
    {
      loading: 'Signing you in...',
      success: (user) => `Welcome back, ${user.firstName}!`,
      error: 'Invalid email or password.',
    },
    { position: 'top-center', theme: 'glassmorphism' }
  );
}

File Upload with Progress

async uploadFile(file: File) {
  const ref = this.toast.loading(`Uploading ${file.name}...`, {
    duration: 0,
    closable: false,
  });

  try {
    await this.fileService.upload(file, (pct) => {
      ref.update({ message: `Uploading ${file.name}... ${pct}%` });
    });
    ref.update({ type: 'success', message: 'Upload complete!', duration: 3000 });
  } catch {
    ref.update({ type: 'error', message: 'Upload failed.', duration: 5000 });
  }
}

Bulk Dismiss by Group

// Show several related toasts with a group name
this.toast.info('Step 1 complete', { group: 'wizard' });
this.toast.info('Step 2 complete', { group: 'wizard' });
this.toast.info('Step 3 complete', { group: 'wizard' });

// Later dismiss them all at once
this.toast.dismissByGroup('wizard');

RTL Support (Arabic / Hebrew)

// Set globally
provideNgxSignalToast({ rtl: true })

// Or per toast
this.toast.success('ΨͺΩ… الحفظ Ψ¨Ω†Ψ¬Ψ§Ψ­', { rtl: true });

Custom Full Body Component

@Component({
  standalone: true,
  template: `
    <div style="padding: 16px; display: flex; gap: 12px; align-items: center">
      <img src="/avatar.png" width="40" height="40" style="border-radius: 50%" />
      <div>
        <strong>John sent you a message</strong>
        <p style="margin: 0; opacity: 0.8; font-size: 13px">Hey, are you free today?</p>
      </div>
    </div>
  `,
})
export class MessageToastComponent {}

// Use it
this.toast.show('', {
  bodyComponent: MessageToastComponent,
  duration: 6000,
  theme: 'glassmorphism',
});

Reading Toast State in Template

@Component({
  template: `
    @if (!toast.isEmpty()) {
      <span>{{ toast.count() }} active notifications</span>
    }
    <button (click)="toast.dismissAll()">Clear All</button>
  `
})
export class NotificationBarComponent {
  toast = inject(ToastService);
}

πŸ“¦ TypeScript Types

import type {
  Toast,
  ToastRef,
  ToastOptions,
  ToastConfig,
  ToastAction,
  ToastCustomStyles,
  ToastType,           // 'success' | 'error' | 'warning' | 'info' | 'loading' | 'custom'
  ToastPosition,       // 'top-left' | 'top-center' | 'top-right' | ...
  ToastTheme,          // 'default' | 'glassmorphism' | 'neumorphism' | ...
  ToastLayout,         // 'default' | 'compact' | 'card' | 'pill' | 'sidebar' | 'banner'
  ToastAnimationPreset // 'slide' | 'fade' | 'bounce' | 'zoom' | 'flip'
} from 'ngx-signal-toast';

πŸ“ Changelog

v1.1.0

  • 🎬 Migrated from @angular/animations to native CSS animations
  • βœ… Removed @angular/animations peer dependency entirely
  • πŸ”§ Auto-inject container via provideAppInitializer β€” no HTML tag needed
  • πŸ” Split ToastStateService to resolve circular dependency (NG0200)
  • πŸŒ€ Fixed spinner animation interrupted by mouse interaction
  • β™Ώ Added prefers-reduced-motion support

v1.0.0

  • πŸŽ‰ Initial release
  • 8 themes, 6 layouts, 9 positions, 5 animations
  • Full Signals API, Promise helper, Toast actions
  • SSR support, RTL support

🀝 Contributing

Contributions are welcome! Please open an issue first to discuss what you would like to change.

# Clone and install
git clone https://github.com/your-org/ngx-signal-toast.git
cd ngx-signal-toast
npm install

# Build the library
ng build ngx-signal-toast --configuration production

# Run the demo
ng serve demo

# Run tests
ng test ngx-signal-toast

πŸ“„ License

MIT Β© 2025 ngx-signal-toast


Made with ❀️ for the Angular community

⭐ Support the Project

If you find this library useful:

⭐ Star the repository
πŸ› Report issues
πŸ’‘ Suggest features
🀝 Contribute improvements

About

Signal-first toast notification library for Angular 21 with zoneless support, zero dependencies, SSR safety and powerful theming.

Topics

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors