# popt
> Beautiful toast notifications with pill-to-card animations, spring physics, and zero dependencies.
## Overview
popt is a vanilla JavaScript toast notification library. It weighs ~10 KB minified JS and ~8 KB minified CSS with zero dependencies. It provides pill-to-card morphing animations using spring physics via CSS `linear()` easing.
## Install
npm install poptjs
ESM:
import popt from 'poptjs';
import 'poptjs/dist/popt.css';
CDN:
## API Reference
### Toast Methods
All methods accept a string (title-only) or an options object.
- popt.success(opts) — Green checkmark. For confirmations, saves.
- popt.error(opts) — Red X. For failures, declined payments.
- popt.warning(opts) — Orange alert. For low inventory, expiring sessions.
- popt.info(opts) — Blue info. For updates, announcements.
- popt.action(opts) — Purple arrow. Includes action button.
- popt.show(opts) — Gray default. Custom icon optional.
### Interactive Methods
- popt.confirm(opts) — Two-button confirmation dialog. Returns Promise. Resolves true on confirm, false on cancel/dismiss.
- popt.prompt(opts) — Input field with submit/cancel. Returns Promise. Resolves with input value on submit, null on cancel/dismiss.
- popt.promise(promise, handlers) — Async loading → success/error transition.
### Control Methods
- popt.dismiss() — Dismiss the most recent toast.
- popt.dismissAll() — Dismiss all active toasts.
- popt.destroy() — Dismiss all toasts and remove all containers from DOM.
- popt.isActive() — Returns true if any toast is visible.
- popt.getStackSize() — Returns the number of active toasts.
- popt.init(config) — Set global defaults. Returns popt for chaining.
### Toast Options Object
- title: string — Text shown in the pill header.
- description: string | HTMLElement — Expanded card body content.
- duration: number | null — Auto-dismiss in milliseconds. null = persistent (no auto-dismiss).
- button: { title: string, onClick: () => void | false } — Action button inside card. Return false from onClick to prevent auto-dismiss.
- cancel: { title: string, onClick: () => void } — Cancel button shown alongside action button.
- input: { type: string, placeholder: string, value: string } — Input field for prompt toasts.
- icon: string — Custom SVG string for badge icon.
- fill: string — Custom hex color for badge and progress bar.
- position: string — Override position for this specific toast.
- expandDelay: number — Delay in ms before pill expands to card.
- onDismiss: () => void — Callback fired when toast is dismissed.
### Init Config Options
- position: string (default: 'top-center') — Default toast position. Values: top-left, top-center, top-right, bottom-left, bottom-center, bottom-right.
- duration: number (default: 6000) — Default auto-dismiss in milliseconds.
- expandDelay: number (default: 1000) — Default pill-to-card expand delay.
- theme: 'dark' | 'light' | 'auto' (default: 'dark') — Color theme. 'auto' follows system prefers-color-scheme.
- maxToasts: number (default: 3) — Maximum visible toasts. Oldest dismissed when limit reached.
### Confirm Options (extends Toast Options)
- confirmText: string (default: 'Confirm') — Text for the confirm button.
- cancelText: string (default: 'Cancel') — Text for the cancel button.
### Prompt Options (extends Toast Options)
- placeholder: string — Input placeholder text.
- defaultValue: string — Initial input value.
- inputType: string (default: 'text') — Input type attribute.
- submitText: string (default: 'Submit') — Text for the submit button.
- cancelText: string (default: 'Cancel') — Text for the cancel button.
### Promise Handlers
- loading: string | { title, description } — Toast shown during loading.
- success: string | (data) => string | ToastOptions — Toast shown on resolve.
- error: string | (error) => string | ToastOptions — Toast shown on reject.
- onDismiss: () => void — Callback when toast is dismissed.
## Usage Examples
### Basic toast
popt.success('Event saved!');
### Toast with description
popt.error({
title: 'Payment declined',
description: 'Card ending in 4242 was declined.'
});
### Action button
popt.action({
title: 'Booking saved as draft',
description: 'Resume checkout anytime.',
button: {
title: 'Resume checkout',
onClick: () => window.location = '/checkout'
}
});
### Confirm dialog
const accepted = await popt.confirm({
title: 'Delete item?',
description: 'This action cannot be undone.',
confirmText: 'Delete',
cancelText: 'Keep it'
});
### Prompt input
const name = await popt.prompt({
title: 'Rename event',
description: 'Enter a new name.',
placeholder: 'Event name...',
submitText: 'Rename'
});
### Promise (async)
popt.promise(fetch('/api/booking'), {
loading: 'Processing...',
success: 'Booking confirmed!',
error: 'Something went wrong'
});
### Promise with dynamic messages
popt.promise(fetch('/api/tickets'), {
loading: 'Loading...',
success: (data) => ({ title: 'Loaded!', description: `${data.count} tickets found` }),
error: (err) => ({ title: 'Failed', description: err.message })
});
### Theme configuration
popt.init({ theme: 'light' });
popt.init({ theme: 'auto' });
### Full configuration
popt.init({
position: 'bottom-right',
duration: 4000,
expandDelay: 800,
theme: 'light',
maxToasts: 5
});
### Custom color
popt.show({
title: 'Custom notification',
fill: '#e040fb'
});
### Toast stacking
popt.success('First');
popt.info('Second');
popt.warning('Third');
### Persistent toast (no auto-dismiss)
popt.info({ title: 'Important', description: 'Must be manually closed.', duration: null });
## Features
- Pill-to-card morphing animation with spring physics
- Toast stacking with configurable max limit
- Dark, light, and auto themes (follows prefers-color-scheme)
- Swipe to dismiss on mobile (horizontal touch gesture)
- Pause timer on hover
- Progress bar synced with dismiss timer
- Promise support with loading/success/error transitions
- Confirm dialogs returning Promise
- Prompt input returning Promise
- Action buttons with optional dismiss prevention
- 6 positions (top/bottom + left/center/right)
- Safe area support for mobile notch
- Reduced motion support (prefers-reduced-motion)
- Accessible: role="status", aria-live="polite"
- Zero dependencies, vanilla JavaScript
- ESM + UMD + CDN (unpkg, jsdelivr)
- Full TypeScript definitions
## Links
- npm: https://www.npmjs.com/package/poptjs
- Demo: https://poptjs.emac.dev
- CDN (unpkg): https://unpkg.com/poptjs/dist/popt.min.js
- CDN (jsdelivr): https://cdn.jsdelivr.net/npm/poptjs/dist/popt.min.js