Components
Alert
Alert
A customizable alert component with animated transitions, multiple types, and auto-dismiss functionality.
This is an alert message.
Installation
1
Install the packages
npm i motion clsx tailwind-merge react-icons2
Add util file
lib/util.ts
import { ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge";
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}
import { ClassValue, clsx } from "clsx";
import { twMerge } from "tailwind-merge";
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}
3
Copy and paste the following code into your project
alert.tsx
"use client";
import { cn } from "@/lib/utils";
import { motion, AnimatePresence } from "motion/react";
import React, { useState, useEffect } from "react";
import { FiX, FiCheckCircle, FiAlertCircle, FiInfo, FiAlertTriangle } from "react-icons/fi";
import ComponentContainer from "@/components/features/component-container";
interface AlertProps {
type?: "success" | "error" | "warning" | "info";
title?: string;
message?: string;
dismissible?: boolean;
autoClose?: boolean;
autoCloseDelay?: number;
onClose?: () => void;
}
const Alert: React.FC<AlertProps> = ({
type = "info",
title,
message = "This is an alert message.",
dismissible = true,
autoClose = false,
autoCloseDelay = 5000,
onClose = () => {}
}) => {
const [isVisible, setIsVisible] = useState(true);
useEffect(() => {
if (autoClose) {
const timer = setTimeout(() => {
setIsVisible(false);
onClose();
}, autoCloseDelay);
return () => clearTimeout(timer);
}
}, [autoClose, autoCloseDelay, onClose]);
const handleClose = () => {
setIsVisible(false);
onClose();
};
const icons = {
success: FiCheckCircle,
error: FiAlertCircle,
warning: FiAlertTriangle,
info: FiInfo,
};
const colors = {
success: "bg-green-500/10 border-green-500/20 text-green-400",
error: "bg-red-500/10 border-red-500/20 text-red-400",
warning: "bg-yellow-500/10 border-yellow-500/20 text-yellow-400",
info: "bg-blue-500/10 border-blue-500/20 text-blue-400",
};
const Icon = icons[type];
return (
<ComponentContainer className="md:py-20">
<div className="relative flex h-[12rem] w-full max-w-md items-center justify-center rounded-md border border-neutral-800 bg-neutral-900">
<AnimatePresence>
{isVisible && (
<motion.div
className={cn(
"w-full max-w-sm rounded-lg border p-4",
colors[type]
)}
initial={{ opacity: 0, y: -10, scale: 0.95 }}
animate={{ opacity: 1, y: 0, scale: 1 }}
exit={{ opacity: 0, y: -10, scale: 0.95 }}
transition={{ duration: 0.2, ease: "easeOut" }}
>
<div className="flex items-start gap-3">
<Icon className="h-5 w-5 flex-shrink-0 mt-0.5" />
<div className="flex-1">
{title && (
<h4 className="font-semibold text-sm mb-1">
{title}
</h4>
)}
<p className="text-sm opacity-90">
{message}
</p>
</div>
{dismissible && (
<button
onClick={handleClose}
className="flex-shrink-0 text-current opacity-70 hover:opacity-100 transition-opacity"
>
<FiX className="h-4 w-4" />
</button>
)}
</div>
</motion.div>
)}
</AnimatePresence>
</div>
</ComponentContainer>
);
};
export default Alert;"use client";
import { cn } from "@/lib/utils";
import { motion, AnimatePresence } from "motion/react";
import React, { useState, useEffect } from "react";
import { FiX, FiCheckCircle, FiAlertCircle, FiInfo, FiAlertTriangle } from "react-icons/fi";
import ComponentContainer from "@/components/features/component-container";
interface AlertProps {
type?: "success" | "error" | "warning" | "info";
title?: string;
message?: string;
dismissible?: boolean;
autoClose?: boolean;
autoCloseDelay?: number;
onClose?: () => void;
}
const Alert: React.FC<AlertProps> = ({
type = "info",
title,
message = "This is an alert message.",
dismissible = true,
autoClose = false,
autoCloseDelay = 5000,
onClose = () => {}
}) => {
const [isVisible, setIsVisible] = useState(true);
useEffect(() => {
if (autoClose) {
const timer = setTimeout(() => {
setIsVisible(false);
onClose();
}, autoCloseDelay);
return () => clearTimeout(timer);
}
}, [autoClose, autoCloseDelay, onClose]);
const handleClose = () => {
setIsVisible(false);
onClose();
};
const icons = {
success: FiCheckCircle,
error: FiAlertCircle,
warning: FiAlertTriangle,
info: FiInfo,
};
const colors = {
success: "bg-green-500/10 border-green-500/20 text-green-400",
error: "bg-red-500/10 border-red-500/20 text-red-400",
warning: "bg-yellow-500/10 border-yellow-500/20 text-yellow-400",
info: "bg-blue-500/10 border-blue-500/20 text-blue-400",
};
const Icon = icons[type];
return (
<ComponentContainer className="md:py-20">
<div className="relative flex h-[12rem] w-full max-w-md items-center justify-center rounded-md border border-neutral-800 bg-neutral-900">
<AnimatePresence>
{isVisible && (
<motion.div
className={cn(
"w-full max-w-sm rounded-lg border p-4",
colors[type]
)}
initial={{ opacity: 0, y: -10, scale: 0.95 }}
animate={{ opacity: 1, y: 0, scale: 1 }}
exit={{ opacity: 0, y: -10, scale: 0.95 }}
transition={{ duration: 0.2, ease: "easeOut" }}
>
<div className="flex items-start gap-3">
<Icon className="h-5 w-5 flex-shrink-0 mt-0.5" />
<div className="flex-1">
{title && (
<h4 className="font-semibold text-sm mb-1">
{title}
</h4>
)}
<p className="text-sm opacity-90">
{message}
</p>
</div>
{dismissible && (
<button
onClick={handleClose}
className="flex-shrink-0 text-current opacity-70 hover:opacity-100 transition-opacity"
>
<FiX className="h-4 w-4" />
</button>
)}
</div>
</motion.div>
)}
</AnimatePresence>
</div>
</ComponentContainer>
);
};
export default Alert;4
Update the import paths to match your project setup
Props
| Prop | Type | Default | Description |
|---|---|---|---|
| type | "success" | "error" | "warning" | "info" | "info" | The type of alert which determines the color and icon. |
| title | string | undefined | The title of the alert. |
| message | string | "This is an alert message." | The message content of the alert. |
| dismissible | boolean | true | Whether the alert can be dismissed by the user. |
| autoClose | boolean | false | Whether the alert should auto-close after a delay. |
| autoCloseDelay | number | 5000 | The delay in milliseconds before auto-closing. |
| onClose | () => void | () => {} | Callback function when the alert is closed. |