Learn how to build a reusable toaster component in React that supports different notification types like success, error, and warning. It includes features like smooth fade-out animations, progress bars, and customizable positions. This is a quick and effective way to improve user experience in your web applications by providing non-intrusive notifications.
š¢ Key Features:
š Customizable Notification Types: Choose from success, error, warning, and info.
š Smooth Animations: Includes slide-in and fade-out animations.
š Position Control: Place the notification at any corner of the screen.
ā³ Progress Bar: Visualize the time remaining before the notification disappears.
ā²ļø Adjustable Duration: Set how long the notification stays visible.
"use client";
import { IconX } from "@tabler/icons-react";
import React, { useEffect, useState } from "react";
import styles from "./Toaster.module.css";
const Toaster = ({
message,
duration = 3,
onClose,
type = "success",
position = "top-right",
toasterStyle,
progressBarStyle,
}: {
message: string;
duration?: number;
onClose?: () => void;
type?: "success" | "error" | "warning" | "info";
position?: "top-right" | "top-left" | "bottom-right" | "bottom-left";
toasterStyle?: string;
progressBarStyle?: string;
}) => {
const [isVisible, setIsVisible] = useState(false);
const [isFading, setIsFading] = useState(false);
useEffect(() => {
setIsVisible(true);
const fadeTimer = setTimeout(() => {
setIsFading(true);
}, (duration - 0.5) * 1000);
const closeTimer = setTimeout(() => {
setIsVisible(false);
if (onClose) onClose();
}, duration * 1000);
return () => {
clearTimeout(fadeTimer);
clearTimeout(closeTimer);
};
}, [duration, onClose]);
const handleClose = () => {
setIsFading(true);
setTimeout(() => {
setIsVisible(false);
if (onClose) onClose();
}, 500);
};
if (!isVisible) return null;
return (
<div
className={`${styles.toaster} ${styles[type]} ${styles[position]} ${
isFading ? styles["fade-out"] : ""
} fixed rounded-md px-3 py-2 flex items-center justify-between gap-x-2 ${toasterStyle}`}
>
<span className="text-xs md:text-sm">{message}</span>
<span
onClick={handleClose}
className="cursor-pointer transition-opacity ease-in hover:opacity-70"
>
<IconX className="w-4 h-4" />
</span>
<div
className={`${styles["progress-bar"]} ${progressBarStyle}`}
style={{ animationDuration: `${duration - 0.5}s` }}
></div>
</div>
);
};
export default Toaster;
.toaster {
z-index: 1000;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
transform: translateX(150%);
animation: slideIn 0.5s ease-out forwards;
position: fixed;
min-width: 250px;
max-width: 400px;
padding: 12px;
border-radius: 6px;
font-size: 14px;
font-weight: 500;
display: flex;
align-items: center;
gap: 10px;
}
.fade-out {
animation: fadeOut 0.5s ease-in forwards;
}
.top-right {
top: 10px;
right: 10px;
}
.top-left {
top: 10px;
left: 10px;
}
.bottom-right {
bottom: 10px;
right: 10px;
}
.bottom-left {
bottom: 10px;
left: 10px;
}
.success {
background-color: #22c55e;
color: white;
}
.error {
background-color: #ef4444;
color: white;
}
.warning {
background-color: #f59e0b;
color: white;
}
.info {
background-color: #3b82f6;
color: white;
}
.progress-bar {
position: absolute;
bottom: 0;
left: 0;
height: 2px;
background-color: white;
animation: progress linear forwards;
}
@keyframes slideIn {
from {
transform: translateX(150%);
}
to {
transform: translateX(0);
}
}
@keyframes fadeOut {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
@keyframes progress {
from {
width: 0%;
}
to {
width: 100%;
}
}
Toaster notifications are a great way to keep users informed without interrupting their experience. By building a customizable toaster system in React, you can easily adapt it to fit your app's design and user needs. With features like smooth animations, customizable positions, progress bars, and adjustable durations, this simple component can significantly enhance your web application's user experience. Try implementing it in your next project for non-intrusive, yet effective notifications.
Top comments (0)