react-snackbar-notifications
v1.0.0
Published
A customizable React snackbar notification component
Maintainers
Readme
React Snackbar Notifications
A highly customizable React snackbar notification component library with promise support, animations, themes, and TypeScript support.
✨ Features
- 🎨 Fully Customizable - Colors, animations, positioning, themes
- ⚡ Promise Support - Loading states with automatic success/error transitions
- 🎭 Rich Content - Support for React components, HTML, and custom icons
- 🎪 Animations - Multiple animation types (slide, fade, directional)
- 🎯 TypeScript - Full TypeScript support with type definitions
- 🔧 Callbacks - onShow, onClose, onHide event handlers
- 📱 Responsive - Works on all screen sizes
- 🚀 Lightweight - Minimal dependencies, optimized bundle size
- 🎨 CSS Framework Support - Compatible with Tailwind CSS and other frameworks
Installation
npm install react-snackbar-notificationsor
yarn add react-snackbar-notificationsQuick Start
import { SnackbarProvider, useSnackbar } from 'react-snackbar-notifications';
function App() {
return (
<SnackbarProvider
defaultOptions={{
position: 'top-right',
animation: 'slide',
autoHideDuration: 4000,
}}
>
<YourApp />
</SnackbarProvider>
);
}
function YourComponent() {
const { showSuccess, showError, showInfo, show } = useSnackbar();
return (
<div>
<button onClick={() => showSuccess('Operation successful!')}>
Show Success
</button>
<button onClick={() => showError('An error occurred!')}>
Show Error
</button>
<button onClick={() => showInfo('Here is some info.')}>
Show Info
</button>
{/* Custom notification with React component */}
<button onClick={() => show({
message: <div><strong>Custom Message</strong><br/>With HTML content</div>,
icon: '🚀',
position: 'top-center',
theme: { backgroundColor: '#8e44ad', textColor: '#ecf0f1' }
})}>
Show Custom
</button>
</div>
);
}🚀 Promise Support
Automatically handle loading states with promise resolution/rejection:
function PromiseExample() {
const { promise } = useSnackbar();
const handleSaveData = async () => {
try {
await promise(
// Your async operation
new Promise((resolve, reject) => {
setTimeout(() => {
Math.random() > 0.5 ? resolve('Data saved!') : reject(new Error('Save failed'));
}, 2000);
}),
{
loading: 'Saving your data...',
success: <b>Data saved successfully! 🎉</b>,
error: <b>Failed to save data. Please try again.</b>,
}
);
} catch (error) {
console.error('Promise failed:', error);
}
};
return (
<button onClick={handleSaveData}>
Save Data (with Promise)
</button>
);
}🎨 Advanced Customization
Custom Themes & Styling
const { show } = useSnackbar();
// Custom theme
const darkTheme = {
backgroundColor: '#1a1a1a',
textColor: '#ffffff',
borderRadius: '8px',
fontFamily: 'Inter, sans-serif'
};
show({
message: 'Dark themed notification',
type: 'info',
theme: darkTheme,
position: 'top-center',
animation: 'fade'
});
// Tailwind CSS support
show({
message: <span className="bg-blue-500 text-white px-2 py-1 rounded">Tailwind styled content</span>,
className: 'shadow-lg border-2 border-blue-200'
});React Components as Content
const { show } = useSnackbar();
const ComplexMessage = () => (
<div className="flex flex-col space-y-2">
<div className="font-bold text-lg">🚀 Launch Success!</div>
<div className="text-sm opacity-90">
Your rocket has been successfully launched into orbit.
</div>
<button className="bg-white text-black px-3 py-1 rounded text-sm self-start">
View Details
</button>
</div>
);
show({
message: <ComplexMessage />,
type: 'success',
position: 'top-center',
autoHideDuration: 6000
});Event Callbacks
const { show } = useSnackbar();
show({
message: 'Notification with callbacks',
type: 'success',
onShow: () => console.log('Notification shown!'),
onClose: () => console.log('User clicked close'),
onHide: () => console.log('Notification hidden')
});Loading States
const { showLoading } = useSnackbar();
// Manual loading state
const loadingId = showLoading('Processing your request...', {
autoHideDuration: 0 // Won't auto-hide
});
// Later, when done:
hide(loadingId);
showSuccess('Request completed!');📚 API Reference
SnackbarProvider
The root component that provides snackbar context to your application.
<SnackbarProvider defaultOptions={defaultOptions}>
<YourApp />
</SnackbarProvider>Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| children | React.ReactNode | - | Your app content |
| defaultOptions | Partial<SnackbarOptions> | {} | Default options applied to all notifications |
useSnackbar Hook
Access all snackbar functionality within components.
const {
show,
showSuccess,
showError,
showInfo,
showLoading,
promise,
hide
} = useSnackbar();Methods
| Method | Parameters | Returns | Description |
|--------|------------|---------|-------------|
| show | options: SnackbarOptions | string | Show custom notification, returns notification ID |
| showSuccess | message, options? | string | Show success notification |
| showError | message, options? | string | Show error notification |
| showInfo | message, options? | string | Show info notification |
| showLoading | message, options? | string | Show loading notification (no auto-hide) |
| hide | id: string | void | Manually hide notification by ID |
| promise | promise, messages, options? | Promise<T> | Handle promise with loading/success/error states |
SnackbarOptions
Complete type definition for notification options.
interface SnackbarOptions {
// Content
message: string | React.ReactNode;
type?: 'success' | 'error' | 'info' | 'loading';
// Behavior
autoHideDuration?: number; // ms (0 = no auto-hide)
position?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'top-center' | 'bottom-center';
animation?: 'slide' | 'fade' | 'slide-from-top' | 'slide-from-bottom' | 'slide-from-left' | 'slide-from-right';
// Appearance
theme?: Theme;
className?: string;
showProgressBar?: boolean; // default: true
showCloseIcon?: boolean; // default: true
// Icons
icon?: React.ReactNode;
closeIcon?: React.ReactNode;
// Callbacks
onShow?: () => void;
onClose?: () => void; // User clicked close
onHide?: () => void; // Notification hidden
}Theme Interface
interface Theme {
backgroundColor?: string;
textColor?: string;
borderRadius?: string;
fontFamily?: string;
}Promise Messages
interface PromiseMessages {
loading: string | React.ReactNode;
success: string | React.ReactNode;
error: string | React.ReactNode;
}SnackbarOptions
message: string | React.ReactNode - The notification message (supports React components).type: 'success' | 'error' | 'info' - Notification type.autoHideDuration: number - Auto-hide duration in ms (default: 4000).position: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'top-center' | 'bottom-center' - Position.animation: 'slide' | 'fade' - Animation type.theme: Theme - Custom styling.showProgressBar: boolean - Show/hide progress bar (default: true).showCloseIcon: boolean - Show/hide close button (default: true).icon: React.ReactNode - Custom icon on the left.closeIcon: React.ReactNode - Custom close icon.
Theme
backgroundColor: stringtextColor: stringborderRadius: stringfontFamily: string
🎯 Examples Gallery
Basic Usage
import { SnackbarProvider, useSnackbar } from 'react-snackbar-notifications';
function App() {
return (
<SnackbarProvider defaultOptions={{
position: 'top-right',
autoHideDuration: 4000
}}>
<MyComponent />
</SnackbarProvider>
);
}
function MyComponent() {
const { showSuccess, showError, showInfo } = useSnackbar();
return (
<div>
<button onClick={() => showSuccess('Data saved!')}>
Save Success
</button>
<button onClick={() => showError('Failed to save')}>
Save Error
</button>
</div>
);
}All Position Options
const { show } = useSnackbar();
const positions = [
'top-left', 'top-right', 'top-center',
'bottom-left', 'bottom-right', 'bottom-center'
];
positions.forEach(position => {
show({
message: `Position: ${position}`,
position: position as any,
autoHideDuration: 2000
});
});All Animation Types
const { show } = useSnackbar();
const animations = [
'slide', 'fade',
'slide-from-top', 'slide-from-bottom',
'slide-from-left', 'slide-from-right'
];
animations.forEach(animation => {
show({
message: `Animation: ${animation}`,
animation: animation as any,
position: 'top-right'
});
});Manual Loading Management
const { showLoading, showSuccess, hide } = useSnackbar();
const handleManualLoading = async () => {
// Show loading
const loadingId = showLoading('Processing...', {
autoHideDuration: 0 // Don't auto-hide
});
try {
await someAsyncOperation();
hide(loadingId); // Hide loading
showSuccess('Success!'); // Show success
} catch (error) {
hide(loadingId); // Hide loading
showError('Failed!'); // Show error
}
};Integration Examples
With Axios/Fetch
const { promise } = useSnackbar();
const fetchData = async () => {
await promise(
fetch('/api/data').then(res => res.json()),
{
loading: 'Loading data...',
success: 'Data loaded successfully!',
error: 'Failed to load data'
}
);
};With Form Submissions
const { promise } = useSnackbar();
const handleSubmit = async (formData) => {
await promise(
submitForm(formData),
{
loading: 'Submitting form...',
success: <div>✅ Form submitted successfully!</div>,
error: <div>❌ Submission failed. Please try again.</div>
}
);
};With File Uploads
const { promise } = useSnackbar();
const uploadFile = async (file) => {
const formData = new FormData();
formData.append('file', file);
await promise(
fetch('/api/upload', {
method: 'POST',
body: formData
}),
{
loading: `Uploading ${file.name}...`,
success: 'File uploaded successfully!',
error: 'Upload failed. Please try again.'
}
);
};Advanced Styling
const { show } = useSnackbar();
// Gradient theme
show({
message: 'Beautiful gradient!',
theme: {
backgroundColor: 'linear-gradient(45deg, #667eea 0%, #764ba2 100%)',
textColor: '#ffffff',
borderRadius: '12px'
}
});
// Custom close icon
show({
message: 'Custom close icon',
closeIcon: <span style={{ fontSize: '16px', color: 'red' }}>✖️</span>
});
// Multiple notifications
const showMultiple = () => {
['success', 'error', 'info'].forEach((type, index) => {
setTimeout(() => {
show({
message: `${type.toUpperCase()} notification`,
type: type as any,
position: index % 2 === 0 ? 'top-left' : 'top-right'
});
}, index * 500);
});
};🚀 Demo & Examples
Check out the live demo to see all features in action:
# Clone the repository
git clone https://github.com/your-repo/react-snackbar-notifications.git
cd react-snackbar-notifications
# Install dependencies
npm install
# Start the demo
npm run dev
# Open http://localhost:3000The demo includes examples for:
- ✅ Basic notifications (success, error, info)
- ✅ Promise support with loading states
- ✅ Custom themes and styling
- ✅ All position and animation options
- ✅ React components as content
- ✅ Event callbacks
- ✅ Tailwind CSS integration
🔧 TypeScript Support
This package is written in TypeScript and provides full type definitions:
import {
SnackbarProvider,
useSnackbar,
SnackbarOptions,
Theme
} from 'react-snackbar-notifications';
// All props and return values are fully typed
const { show, promise } = useSnackbar();
// Type-safe options
const options: SnackbarOptions = {
message: 'Hello TypeScript!',
type: 'success',
position: 'top-center',
autoHideDuration: 3000
};🌐 Browser Support
- ✅ Chrome 70+
- ✅ Firefox 65+
- ✅ Safari 12+
- ✅ Edge 79+
- ✅ Modern mobile browsers
📦 Bundle Size
- Main bundle: ~12KB (gzipped)
- ESM build: Available for tree shaking
- Zero dependencies (except React)
🛠️ Development
# Install dependencies
npm install
# Start development server with demo
npm run dev
# Build for production
npm run build
# Run tests
npm test
# Type checking
npm run type-check🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
📝 License
MIT License - feel free to use this in your commercial and personal projects!
🙏 Acknowledgments
Inspired by popular notification libraries like:
- react-hot-toast
- notistack
- Material-UI Snackbar
Built with ❤️ using React, TypeScript, and modern web standards.
