iOS-style notification stack system for React applications with bundled dependencies
npm install ios-notification-stackAn elegant, iOS-style notification system for React applications with zero Redux dependency. This package provides beautifully animated, stackable notifications with customizable positions, colors, and behaviors.
``bash`
npm install ios-notification-stackor
yarn add ios-notification-stack
- 📱 iOS-inspired notification design and animations
- 🔄 Simple context-based state management (no Redux required)
- 📍 Flexible positioning (top/bottom, left/center/right)
- 🎨 Customizable colors, sizes, and spacing
- 📚 Four notification types: success, error, warning, and info
- 📏 Configurable stacking behavior and card dimensions
- 🚀 Global API for adding notifications from anywhere
- ⚡ Per-notification configuration for fine-grained control
- 🔕 Notification muting with unread counter
- 🗂️ Customizable header text for expanded notifications
- 🔄 Multiple action button options (Collapse, Clear, Mute)
- 💾 Persistent mute state across sessions
- 🔍 Smart duplicate notification detection
- 🎭 Smooth spring animations and opacity effects
`javascript
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import "./index.css";
import App from "./App.jsx";
import {
NotificationProvider,
NotificationPortal,
} from "ios-notification-stack";
import "ios-notification-stack/dist/style.css";
createRoot(document.getElementById("root")).render(
width="350px"
cardHeight="80px"
cardSpacing={90}
stackOffset={3}
zIndex={9999}
duration={5000} // 5 seconds before notifications disappear
headerText="System Notifications" // Custom header text
actionButton="Mute" // "Collapse", "Clear", or "Mute"
customColors={{
error: "rgb(9, 9, 9)", // Dark black
success: "rgb(34, 197, 94)", // Bright green
warning: "rgb(250, 204, 21)", // Bright yellow
info: "rgb(79, 70, 229)", // Indigo
}}
>
);
`
`javascript
import React from "react";
import {
showSuccess,
showError,
showWarning,
showInfo,
showNotification,
} from "ios-notification-stack";
import "ios-notification-stack/dist/style.css";
function App() {
// Function to test all notification types
const testNotifications = () => {
showError("Something went wrong", {
title: "Error Title",
duration: 10000,
});
setTimeout(() => {
showSuccess("Everything is good", {
title: "Good Job",
duration: 8000,
});
}, 1000);
setTimeout(() => {
showInfo("Here's some important information", {
title: "Info Alert",
duration: 8000,
});
}, 1500);
setTimeout(() => {
showWarning("Please be careful with this action", {
title: "Warning",
duration: 8000,
});
}, 2000);
setTimeout(() => {
showNotification("error", "Custom notification with extended duration", {
title: "Custom Notification",
duration: 14000,
width: "700px", // Override default width
});
}, 3000);
};
return (
Click the button below to test all notification types:
onClick={testNotifications}
style={{
padding: "10px 20px",
backgroundColor: "#4F46E5",
color: "white",
border: "none",
borderRadius: "4px",
cursor: "pointer",
}}
>
Test All Notifications
export default App;
`
| Prop | Type | Default | Description |
| -------------- | ------ | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| position | string | "top-center" | Position of notifications. Options: "top-center", "top-right", "top-left", "bottom-right", "bottom-left", "bottom-center" |width
| | string | "350px" | Default width of notification cards |cardHeight
| | string | "80px" | Default height of each notification card |cardSpacing
| | number | 90 | Spacing between expanded cards (in pixels) |stackOffset
| | number | 3 | Offset for stacked cards (in pixels) |zIndex
| | number | 9999 | z-index for the notification container |duration
| | number | 5000 | Default duration for notifications (in milliseconds) |customColors
| | object | {} | Custom colors for different notification types |headerText
| | string | "Notifications" | Text to display in the expanded notification header |actionButton
| | string | "Collapse" | Default action button: "Collapse", "Clear", or "Mute" |
| Option | Type | Default | Description |
| ---------------- | -------- | --------------------- | ------------------------------------------------------ |
| title | string | Type-specific default | Title of the notification |duration
| | number | From provider config | How long to display the notification (in milliseconds) |autoRemove
| | boolean | true | Whether the notification should auto-remove |width
| | string | From provider config | Width of this specific notification |cardHeight
| | string | From provider config | Height of this specific notification |icon
| | element | null | Custom icon for the notification |priority
| | string | "normal" | Priority level: "low", "normal", or "high" |actionLabel
| | string | null | Text for action button |actionCallback
| | function | null | Callback for action button |
| Function | Parameters | Description |
| ----------------------- | -------------------------- | ------------------------------------------------- |
| showNotification | (type, message, options) | Generic function to show any type of notification |showSuccess
| | (message, options) | Show a success notification |showError
| | (message, options) | Show an error notification |showWarning
| | (message, options) | Show a warning notification |showInfo
| | (message, options) | Show an information notification |clearAllNotifications
| | () | Remove all notifications |toggleMute
| | () | Toggle between muted and unmuted states |
For components that need more control, you can use the provided hook:
`javascript
import { useNotification } from "ios-notification-stack";
function MyComponent() {
const {
showSuccess,
showError,
removeNotification,
clearAllNotifications,
toggleMute,
config,
} = useNotification();
// Check if notifications are muted
const isMuted = config.isMuted;
// Get unread count
const unreadCount = config.unreadCount;
// Now use these functions directly
const handleSuccess = () => {
showSuccess("Operation completed successfully!");
};
const toggleNotificationMute = () => {
toggleMute();
};
}
`
The package includes support for muting notifications. When muted, notifications are still tracked but not displayed, with an unread counter shown instead:
`javascript
// To toggle mute state programmatically:
import { toggleMute } from "ios-notification-stack";
function MuteButton() {
return ;
}
`
The mute state is automatically persisted in localStorage, so it will be maintained across page refreshes.
The system automatically detects and ignores duplicate notifications sent within a very short time (500ms), preventing notification spam when events trigger multiple times.
When notifications are expanded, users can:
- View all current notifications in a stack
- See a customizable header text
- Use a configurable action button (Collapse, Clear, or Mute)
The notification stack uses a minimal set of styles that can be easily customized. The default styling provides:
- Smooth spring animations using Framer Motion
- iOS-style card layout with rounded corners
- Stackable cards with shadow and opacity effects
- Text truncation for longer messages
You can customize the appearance by overriding the card styles or providing custom colors through the customColors` prop.
This project is licensed under the MIT License - see the LICENSE file for details.
Contributions are welcome! Please feel free to submit a Pull Request.
PARTH CHAWLA - @polo15s