@aspect-ui-01/toast
v0.6.0
Published
Lightweight framework-agnostic toast notifications (~2KB)
Maintainers
Readme
@aspect-ui-01/toast
Lightweight, framework-agnostic toast notifications built with Web Components.
Highlights
- 🪶 ~2.5 KB gzipped — zero dependencies
- 🌐 Universal — Angular, React, Vue, Svelte, Astro, vanilla JS
- 📱 Responsive — different options for mobile/desktop
- ♿ Accessible — ARIA compliant, respects
prefers-reduced-motion - 🎨 Themeable — CSS custom properties
- 🔒 Encapsulated — Shadow DOM, no style leaks
- ⚡ Lazy loading — optional deferred loading (~1 KB initial)
Installation
# pnpm
pnpm add @aspect-ui-01/toast
# npm
npm install @aspect-ui-01/toast
# yarn
yarn add @aspect-ui-01/toastQuick Start
1. Add the component to your HTML
<ui-toast></ui-toast>2. Import and use
import { toast } from '@aspect-ui-01/toast';
toast.success('Item added to cart');
toast.error('Payment failed');
toast.warning('Low stock');
toast.info('Processing...');API Reference
Methods
| Method | Description | Returns |
|--------|-------------|---------|
| toast.success(message, options?) | Show success toast | string (toast id) |
| toast.error(message, options?) | Show error toast | string (toast id) |
| toast.warning(message, options?) | Show warning toast | string (toast id) |
| toast.info(message, options?) | Show info toast | string (toast id) |
| toast.remove(id) | Remove specific toast | void |
| toast.clear() | Remove all toasts | void |
Options
interface ToastOptions {
duration?: number; // Auto-dismiss delay in ms (0 = persistent)
position?: ToastPosition; // Toast placement
animation?: ToastAnimation;// Entry animation
showCloseButton?: boolean; // Show close button (default: true)
width?: string; // Toast width (default: '20rem')
// Responsive overrides
mobile?: DeviceOptions;
desktop?: DeviceOptions;
}
interface DeviceOptions {
position?: ToastPosition;
animation?: ToastAnimation;
width?: string;
duration?: number;
showCloseButton?: boolean;
}Positions
type ToastPosition =
| 'top-right' // Default (desktop)
| 'top-left'
| 'top-center' // Default (mobile)
| 'bottom-right'
| 'bottom-left'
| 'bottom-center';Animations
type ToastAnimation =
| 'fade'
| 'slide-left'
| 'slide-right'
| 'zoom';Default Durations
| Type | Duration |
|------|----------|
| success | 3000ms |
| error | 6000ms |
| warning | 5000ms |
| info | 4000ms |
Usage Examples
Basic
import { toast } from '@aspect-ui-01/toast';
// Simple
toast.success('Saved!');
// With duration
toast.info('Processing...', { duration: 5000 });
// Persistent (no auto-dismiss)
toast.error('Connection lost', { duration: 0 });
// Custom position
toast.warning('Low stock', { position: 'bottom-center' });
// Custom animation
toast.success('Done!', { animation: 'zoom' });Responsive Options
// Different settings for mobile/desktop
toast.success('Order placed', {
mobile: {
position: 'top-center',
width: '100%'
},
desktop: {
position: 'top-right',
width: '22rem'
},
});
// Base options with device overrides
toast.info('Syncing...', {
duration: 5000,
mobile: { position: 'bottom-center' },
desktop: { position: 'top-right' },
});Programmatic Control
// Store toast id
const id = toast.info('Uploading...', { duration: 0 });
// Later, remove it
toast.remove(id);
// Or clear all
toast.clear();Framework Integration
Angular
// app.module.ts
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core';
import '@aspect-ui-01/toast';
@NgModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}<!-- app.component.html -->
<ui-toast></ui-toast>// any.component.ts
import { toast } from '@aspect-ui-01/toast';
export class MyComponent {
notify() {
toast.success('Hello from Angular!');
}
}React
import '@aspect-ui-01/toast';
import { toast } from '@aspect-ui-01/toast';
// TypeScript: add to global.d.ts
declare namespace JSX {
interface IntrinsicElements {
'ui-toast': React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;
}
}
function App() {
return (
<>
<ui-toast />
<button onClick={() => toast.success('Hello from React!')}>
Show Toast
</button>
</>
);
}Vue
<template>
<ui-toast />
<button @click="notify">Show Toast</button>
</template>
<script setup>
import '@aspect-ui-01/toast';
import { toast } from '@aspect-ui-01/toast';
const notify = () => toast.success('Hello from Vue!');
</script>Svelte
<script>
import '@aspect-ui-01/toast';
import { toast } from '@aspect-ui-01/toast';
</script>
<ui-toast />
<button on:click={() => toast.success('Hello from Svelte!')}>
Show Toast
</button>Astro
---
// Layout.astro
---
<html>
<body>
<slot />
<ui-toast></ui-toast>
</body>
</html>
<script>
import '@aspect-ui-01/toast';
</script>---
// Page.astro
---
<button id="toast-btn">Show Toast</button>
<script>
import { toast } from '@aspect-ui-01/toast';
document.getElementById('toast-btn')?.addEventListener('click', () => {
toast.success('Hello from Astro!');
});
</script>Vanilla JS / CDN
<script type="module">
import { toast } from 'https://unpkg.com/@aspect-ui-01/toast';
document.querySelector('#btn').onclick = () => {
toast.success('Hello from vanilla JS!');
};
</script>
<ui-toast></ui-toast>
<button id="btn">Show Toast</button>Lazy Loading
For performance-critical applications, use lazy loading to defer component registration:
import { toast, registerToast } from '@aspect-ui-01/toast/lazy';
// Register when needed (once)
registerToast();
// Then use normally
toast.success('Hello!');Bundle Size Comparison
| Import | Initial Load | |--------|-------------| | Default | ~2.5 KB | | Lazy | ~1 KB (component deferred) |
Theming
Customize appearance with CSS custom properties:
ui-toast {
/* Colors */
--toast-success: #16a34a;
--toast-error: #dc2626;
--toast-warning: #d97706;
--toast-info: #2563eb;
/* Layout */
--toast-radius: 8px;
--toast-shadow: 0 8px 24px rgb(0 0 0 / 15%);
--toast-max-width: 25rem;
--toast-z-index: 999999;
/* Typography */
--toast-font-size: 0.9rem;
--toast-line-height: 1.35rem;
--toast-letter-spacing: 0;
}Responsive Theming
ui-toast {
--toast-font-size: 0.875rem;
}
@media (min-width: 768px) {
ui-toast {
--toast-font-size: 0.9rem;
--toast-max-width: 28rem;
}
}Dark Mode
@media (prefers-color-scheme: dark) {
ui-toast {
--toast-success: #22c55e;
--toast-error: #f87171;
--toast-warning: #fbbf24;
--toast-info: #60a5fa;
--toast-shadow: 0 8px 24px rgb(0 0 0 / 40%);
}
}Accessibility
- Uses
role="alert"for screen readers aria-live="polite"for non-intrusive announcements- Respects
prefers-reduced-motion— animations disabled - Keyboard accessible close button with visible focus state
- Color contrast meets WCAG AA standards
Browser Support
| Browser | Version | |---------|---------| | Chrome | 67+ | | Firefox | 63+ | | Safari | 13.1+ | | Edge | 79+ |
No polyfills required for modern browsers.
TypeScript
Full TypeScript support with exported types:
import { toast } from '@aspect-ui-01/toast';
import type {
ToastOptions,
ToastPosition,
ToastAnimation
} from '@aspect-ui-01/toast';
const options: ToastOptions = {
duration: 5000,
position: 'top-center',
animation: 'zoom',
};
toast.success('Typed!', options);SSR Compatibility
Works with SSR frameworks (Astro, Next.js, Nuxt, SvelteKit). The component includes SSR guards and only registers in browser environments.
Contributing
Contributions welcome!
# Clone
git clone https://github.com/aspect-ui-1/toast.git
cd toast
# Install
pnpm install
# Dev
pnpm dev
# Test
pnpm test
# Build
pnpm buildLicense
MIT © Aspect UI
