@mateogasme/astro-toast
v1.1.1
Published
A minimal, beautiful toast library for Astro
Maintainers
Readme
astro-toast
A minimal, beautiful toast notification library for Astro. Lightweight, accessible, and zero dependencies.
Installation
pnpm add @mateogasme/astro-toastnpm install @mateogasme/astro-toastyarn add @mateogasme/astro-toastQuick Start
1. Add the <Toaster /> component and import the styles in your layout:
---
// src/layouts/Layout.astro
import Toaster from '@mateogasme/astro-toast/Toaster'
import '@mateogasme/astro-toast/styles'
---
<html lang="en">
<body>
<slot />
<Toaster />
</body>
</html>2. Show a toast from any client-side script:
<button id="btn">Show toast</button>
<script>
import { toast } from '@mateogasme/astro-toast'
document.getElementById('btn')?.addEventListener('click', () => {
toast('Event has been created')
})
</script>Toast Types
import { toast } from '@mateogasme/astro-toast'
toast('Default notification')
toast.success('Event has been created')
toast.error('Something went wrong')
toast.warning('Please review your input')
toast.info('New version available')
toast.loading('Uploading file...')Each type renders with its own icon and, when richColors is enabled, a distinct color palette.
Description
Add secondary text below the toast message:
toast('Event created', {
description: 'Monday, January 3rd at 6:00 PM'
})Action & Cancel Buttons
toast('File deleted', {
action: {
label: 'Undo',
onClick: () => undoDelete()
},
cancel: {
label: 'Dismiss',
onClick: () => console.log('Dismissed')
}
})Promise
Handle async operations with automatic loading → success/error transitions:
toast.promise(fetchData(), {
loading: 'Loading data...',
success: 'Data loaded successfully',
error: 'Failed to load data'
})Success and error messages can be dynamic:
toast.promise(saveUser(userData), {
loading: 'Saving...',
success: (user) => `${user.name} has been saved`,
error: (err) => `Error: ${err.message}`
})toast.promise returns the original promise, so you can chain it:
const data = await toast.promise(fetchData(), {
loading: 'Loading...',
success: 'Done!',
error: 'Failed'
})Custom HTML
Render arbitrary HTML inside a toast:
toast.custom('<div style="padding: 16px">Custom HTML content</div>')Dismiss
// Dismiss a specific toast by ID
const id = toast('Hello')
toast.dismiss(id)
// Dismiss all toasts
toast.dismiss()Runtime Configuration
Update Toaster settings dynamically from client-side code:
toast.configure({
position: 'top-center',
richColors: true,
duration: 6000
})Toaster Props
Configure the <Toaster /> component:
<Toaster
position="bottom-right"
theme="system"
visibleToasts={3}
richColors={false}
closeButton={false}
offset="24px"
dir="ltr"
gap={14}
duration={4000}
expand={false}
/>| Prop | Type | Default | Description |
|------|------|---------|-------------|
| position | 'top-left' \| 'top-center' \| 'top-right' \| 'bottom-left' \| 'bottom-center' \| 'bottom-right' | 'bottom-right' | Where toasts appear on screen |
| theme | 'light' \| 'dark' \| 'system' | 'system' | Color theme |
| visibleToasts | number | 3 | Max visible toasts at once |
| richColors | boolean | false | Use colored backgrounds per toast type |
| closeButton | boolean | false | Show close button on all toasts |
| offset | string | '24px' | Distance from viewport edge |
| dir | 'ltr' \| 'rtl' | 'ltr' | Text direction |
| gap | number | 14 | Gap between toasts in px |
| duration | number | 4000 | Default auto-dismiss duration in ms |
| expand | boolean | false | Start with toasts expanded instead of stacked |
Toast Options
Every toast function accepts an optional second argument:
| Option | Type | Description |
|--------|------|-------------|
| id | string | Custom toast ID (prevents duplicates) |
| type | ToastType | Override the toast type |
| duration | number | Override auto-dismiss duration (ms) |
| description | string | Secondary text below the message |
| closeButton | boolean | Show close button for this toast |
| position | Position | Override position for this toast |
| action | { label: string, onClick: () => void } | Primary action button |
| cancel | { label: string, onClick: () => void } | Secondary cancel button |
| className | string | Additional CSS class |
| unstyled | boolean | Remove all default styles |
| onDismiss | (toast) => void | Callback when manually dismissed |
| onAutoClose | (toast) => void | Callback when auto-closed by timer |
CSS Customization
astro-toast uses CSS custom properties. Override them to match your design:
[data-astro-toaster] {
--toast-gray0: #fff;
--toast-gray3: hsl(0, 0%, 95.1%);
--toast-gray11: hsl(0, 0%, 43.5%);
--toast-gray12: hsl(0, 0%, 9%);
}Status colors (used with richColors):
[data-astro-toaster] {
--toast-success-bg: hsl(143, 85%, 96%);
--toast-success-border: hsl(145, 92%, 87%);
--toast-success-text: hsl(140, 100%, 27%);
--toast-error-bg: hsl(359, 100%, 97%);
--toast-error-border: hsl(359, 100%, 94%);
--toast-error-text: hsl(360, 100%, 45%);
--toast-warning-bg: hsl(49, 100%, 97%);
--toast-warning-border: hsl(49, 91%, 84%);
--toast-warning-text: hsl(31, 92%, 45%);
--toast-info-bg: hsl(208, 100%, 97%);
--toast-info-border: hsl(221, 91%, 93%);
--toast-info-text: hsl(210, 92%, 45%);
}Features
- Swipe to dismiss
- Pause timer on hover
- Pause timer on tab hidden
- Keyboard accessible (Tab focus, Escape to dismiss)
- RTL support
- Reduced motion support (
prefers-reduced-motion) - Dark / light / system theme
- Rich colors mode
- Stacked & expanded layouts
- Mobile responsive (full-width below 600px)
- SSR safe
- Zero dependencies
Requirements
- Astro 5.0 or higher
Credits
Design inspired by Sonner by Emil Kowalski. Implementation is original.
License
MIT
