npm package: @mateogasme/astro-toast
Description: A minimal, beautiful toast library for Astro
Latest version: 1.1.1

# astro-toast

A minimal, beautiful toast notification library for [Astro](https://astro.build). Lightweight, accessible, and zero dependencies.

## Installation

```bash
pnpm add @mateogasme/astro-toast
```

```bash
npm install @mateogasme/astro-toast
```

```bash
yarn add @mateogasme/astro-toast
```

## Quick Start

**1. Add the `<Toaster />` component and import the styles in your layout:**

```astro
---
// 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:**

```astro
<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

```ts
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:

```ts
toast('Event created', {
  description: 'Monday, January 3rd at 6:00 PM'
})
```

## Action & Cancel Buttons

```ts
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:

```ts
toast.promise(fetchData(), {
  loading: 'Loading data...',
  success: 'Data loaded successfully',
  error: 'Failed to load data'
})
```

Success and error messages can be dynamic:

```ts
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:

```ts
const data = await toast.promise(fetchData(), {
  loading: 'Loading...',
  success: 'Done!',
  error: 'Failed'
})
```

## Custom HTML

Render arbitrary HTML inside a toast:

```ts
toast.custom('<div style="padding: 16px">Custom HTML content</div>')
```

## Dismiss

```ts
// 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:

```ts
toast.configure({
  position: 'top-center',
  richColors: true,
  duration: 6000
})
```

## Toaster Props

Configure the `<Toaster />` component:

```astro
<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:

```css
[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`):

```css
[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](https://sonner.emilkowal.ski) by [Emil Kowalski](https://emilkowal.ski). Implementation is original.

## License

MIT