A lightweight, type-safe toast notification system for React applications using Valtio state management and Tailwind CSS.
- 🎯 Built with TypeScript for full type safety
- 🎨 Styled with Tailwind CSS
- 🔄 Valtio state management
- 🎭 Smooth animations
- ♿ Accessible (WAI-ARIA compliant)
- 📱 Responsive design
- 🎛 Customizable duration and positioning
- 🔄 Queue management for multiple toasts
- 🎨 Themeable with custom styles
- 📦 Zero dependencies (except peer dependencies)
npm install valtio-toast
# or
yarn add valtio-toast
import { ToastProvider } from 'valtio-toast';
import { useToast } from 'valtio-toast';
import 'valtio-toast/dist/styles.css';
// Wrap your app with ToastProvider
function App() {
return (
<ToastProvider>
<YourApp />
</ToastProvider>
);
}
// Use in any component
function YourComponent() {
const toast = useToast();
const handleClick = () => {
toast.show({
type: 'success',
message: 'Operation successful!',
duration: 5000 // optional, defaults to 5000ms
});
};
return <button onClick={handleClick}>Show Toast</button>;
}
Prop | Type | Default | Description |
---|---|---|---|
position | ToastPosition | 'top-right' | Position of toasts |
maxToasts | number | 5 | Maximum number of toasts shown at once |
children | ReactNode | - | Child components |
Returns an object with the following methods:
interface ToastMethods {
show: (options: ToastOptions) => string;
success: (message: string, duration?: number) => string;
error: (message: string, duration?: number) => string;
warning: (message: string, duration?: number) => string;
info: (message: string, duration?: number) => string;
remove: (id: string) => void;
removeAll: () => void;
}
interface ToastOptions {
type: 'success' | 'error' | 'warning' | 'info';
message: string;
duration?: number;
position?: ToastPosition;
onClose?: () => void;
}
Add these custom animations to your tailwind.config.js
:
module.exports = {
theme: {
extend: {
keyframes: {
'toast-enter': {
'0%': { transform: 'translateX(100%)', opacity: 0 },
'100%': { transform: 'translateX(0)', opacity: 1 }
},
'toast-exit': {
'0%': { transform: 'translateX(0)', opacity: 1 },
'100%': { transform: 'translateX(100%)', opacity: 0 }
}
},
animation: {
'toast-enter': 'toast-enter 0.3s ease-out',
'toast-exit': 'toast-exit 0.3s ease-in'
}
}
}
};
import { createTheme } from 'valtio-toast';
const customTheme = createTheme({
success: {
background: 'bg-emerald-50',
border: 'border-emerald-200',
text: 'text-emerald-800'
},
// ... other types
});
<ToastProvider theme={customTheme}>
<App />
</ToastProvider>
import { createToastComponent } from 'valtio-toast';
const CustomToast = createToastComponent(({ message, type }) => (
<div className="custom-toast">
{message}
</div>
));
<ToastProvider component={CustomToast}>
<App />
</ToastProvider>
const toast = useToast();
// Configure queue behavior
toast.configure({
maxToasts: 3,
queueMode: 'replace-oldest'
});
const toast = useToast();
// Success toast
toast.success('Profile updated successfully');
// Error toast
toast.error('Failed to save changes');
// Warning toast
toast.warning('Your session will expire soon');
// Info toast
toast.info('New features available');
toast.show({
type: 'success',
message: 'Quick notification',
duration: 2000 // 2 seconds
});
toast.show({
type: 'info',
message: 'Processing...',
onClose: () => {
console.log('Toast closed');
}
});
Contributions are welcome! Please read our Contributing Guide for details.
MIT © [Bhanu Pratap Chaudhary]