UI/UI
Alert
A versatile alert component for displaying important messages, notifications, and status updates.
This is a basic alert message.
Something went wrong. Please try again.
This action cannot be undone.
Your changes have been saved.
New features are now available.
<div className="space-y-4">
<Alert>This is a basic alert message.</Alert>
<Alert variant="destructive">
Something went wrong. Please try again.
</Alert>
<Alert variant="warning">This action cannot be undone.</Alert>
<Alert variant="success">Your changes have been saved.</Alert>
<Alert variant="info">New features are now available.</Alert>
</div>
Installation
Install following dependencies:
npm install class-variance-authority lucide-react motion
pnpm add class-variance-authority lucide-react motion
yarn add class-variance-authority lucide-react motion
bun add class-variance-authority lucide-react motion
Copy and paste the following code into your project.
"use client";
import * as React from "react";
import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/lib/utils";
import { type LucideIcon, X } from "lucide-react";
import { motion, AnimatePresence } from "motion/react";
const alertVariants = cva(
"relative w-full rounded-lg border p-4 text-sm transition-colors shadow-sm/2",
{
variants: {
variant: {
default:
"border-border bg-card text-card-foreground",
destructive:
"border-destructive bg-destructive/10 text-destructive [&>svg]:text-destructive",
warning:
"border-amber-200 bg-amber-50 text-amber-800 dark:border-amber-700 dark:bg-amber-950/30 dark:text-amber-200 [&>svg]:text-amber-600 dark:[&>svg]:text-amber-400",
success:
"border-green-200 bg-green-50 text-green-800 dark:border-green-700 dark:bg-green-950/30 dark:text-green-200 [&>svg]:text-green-600 dark:[&>svg]:text-green-400",
info: "border-blue-200 bg-blue-50 text-blue-800 dark:border-blue-700 dark:bg-blue-950/30 dark:text-blue-200 [&>svg]:text-blue-600 dark:[&>svg]:text-blue-400",
},
},
defaultVariants: {
variant: "default",
},
}
);
export interface AlertProps
extends React.HTMLAttributes<HTMLDivElement>,
VariantProps<typeof alertVariants> {
icon?: LucideIcon;
title?: string;
dismissible?: boolean;
onDismiss?: () => void;
}
const Alert = React.forwardRef<HTMLDivElement, AlertProps>(
(
{
className,
variant,
icon: Icon,
title,
dismissible,
onDismiss,
children,
...props
},
ref
) => {
const [isVisible, setIsVisible] = React.useState(true);
const handleDismiss = () => {
setIsVisible(false);
setTimeout(() => {
onDismiss?.();
}, 150); // Match the exit animation duration
};
// Extract motion-conflicting props
const {
onDrag,
onDragStart,
onDragEnd,
onAnimationStart,
onAnimationEnd,
onAnimationIteration,
onTransitionEnd,
...motionProps
} = props;
return (
<AnimatePresence>
{isVisible && (
<motion.div
ref={ref}
className={cn(alertVariants({ variant }), className)}
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.15, ease: "easeOut" }}
role="alert"
{...motionProps}
>
<div className="flex">
{Icon && (
<div className="flex-shrink-0">
<Icon className="h-4 w-4 mt-0.5" />
</div>
)}
<div className={cn("flex-1", Icon && "ml-3")}>
{title && <h3 className="text-sm font-medium mb-1">{title}</h3>}
<div
className={cn("text-sm", title && "text-muted-foreground")}
>
{children}
</div>
</div>
{dismissible && (
<div className="flex-shrink-0 ml-3">
<button
type="button"
className="inline-flex rounded-md p-1.5 transition-colors hover:bg-black/5 dark:hover:bg-white/5 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-ring"
onClick={handleDismiss}
aria-label="Dismiss alert"
>
<X className="h-4 w-4" />
</button>
</div>
)}
</div>
</motion.div>
)}
</AnimatePresence>
);
}
);
Alert.displayName = "Alert";
export { Alert, alertVariants };
npx hextaui@latest add alert
pnpm dlx hextaui@latest add alert
yarn dlx hextaui@latest add alert
bun x hextaui@latest add alert
Usage
import { Alert } from "@/components/ui/alert";
import { Database, Rocket } from "lucide-react";
Basic Alert
<Alert variant="default">This is a default alert.</Alert>
<Alert variant="destructive">This is a destructive alert.</Alert>
<Alert variant="warning">This is a warning alert.</Alert>
<Alert variant="success">This is a success alert.</Alert>
<Alert variant="info">This is an info alert.</Alert>
Alert with Icons
<Alert icon={Database} variant="warning" title="Database Alert">
This uses a Lucide icon component for maximum flexibility.
</Alert>
Examples
Variants
This is a basic alert message.
Something went wrong. Please try again.
This action cannot be undone.
Your changes have been saved.
New features are now available.
<div className="space-y-4">
<Alert>
This is a basic alert message.
</Alert>
<Alert variant="destructive">
Something went wrong. Please try again.
</Alert>
<Alert variant="warning">
This action cannot be undone.
</Alert>
<Alert variant="success">
Your changes have been saved.
</Alert>
<Alert variant="info">
New features are now available.
</Alert>
</div>
With Titles
System Update
A new version of the application is available. Please restart to apply updates.
Connection Failed
Unable to connect to the server. Please check your internet connection.
Data Loss Warning
You have unsaved changes. Leaving this page will discard your work.
Upload Complete
Your files have been successfully uploaded to the cloud storage.
Feature Preview
Try out our new dashboard features in beta mode.
<div className="space-y-4">
<Alert title="System Update">
A new version of the application is available. Please restart to apply
updates.
</Alert>
<Alert variant="destructive" title="Connection Failed">
Unable to connect to the server. Please check your internet connection.
</Alert>
<Alert variant="warning" title="Data Loss Warning">
You have unsaved changes. Leaving this page will discard your work.
</Alert>
<Alert variant="success" title="Upload Complete">
Your files have been successfully uploaded to the cloud storage.
</Alert>
<Alert variant="info" title="Feature Preview">
Try out our new dashboard features in beta mode.
</Alert>
</div>
With Icons
New Features Available
We've added new collaboration tools to help you work better with your team.
Payment Successful
Your subscription has been renewed for another year.
Storage Almost Full
You've used 95% of your storage space. Consider upgrading your plan.
Action Failed
Could not complete the requested action. Please try again later.
Network Connected
You are now connected to the secure network.
Database Backup Required
It's been 7 days since your last backup. Consider backing up your data.
Deployment Successful
Your application has been deployed to production successfully.
Break Time
You've been coding for 2 hours. Time for a coffee break!
import {
Info,
CheckCircle,
AlertTriangle,
X,
Wifi,
Database,
Rocket,
Coffee,
} from "lucide-react";
<div className="space-y-4">
{/* Using predefined icon names */}
<Alert icon={Info} variant="info" title="New Features Available">
We've added new collaboration tools to help you work better with your
team.
</Alert>
<Alert icon={CheckCircle} variant="success" title="Payment Successful">
Your subscription has been renewed for another year.
</Alert>
<Alert icon={AlertTriangle} variant="warning" title="Storage Almost Full">
You've used 95% of your storage space. Consider upgrading your plan.
</Alert>
<Alert icon={X} variant="destructive" title="Action Failed">
Could not complete the requested action. Please try again later.
</Alert>
{/* Using custom icon components */}
<Alert icon={Wifi} variant="info" title="Network Connected">
You are now connected to the secure network.
</Alert>
<Alert icon={Database} variant="warning" title="Database Backup Required">
It's been 7 days since your last backup. Consider backing up your data.
</Alert>
<Alert icon={Rocket} variant="success" title="Deployment Successful">
Your application has been deployed to production successfully.
</Alert>
<Alert icon={Coffee} variant="default" title="Break Time">
You've been coding for 2 hours. Time for a coffee break!
</Alert>
</div>
With Custom Icons
Code Review Ready
Your pull request is ready for code review by the team.
Feature Unlocked
Congratulations! You've unlocked premium features.
Performance Improved
Your application performance has increased by 40% this month.
Security Alert
We detected unusual login activity. Please verify your account.
Meeting Reminder
Your team standup meeting starts in 15 minutes.
import { Code, Sparkles, TrendingUp, Lock, Calendar } from "lucide-react";
<div className="space-y-4">
<Alert
icon={Code}
variant="info"
title="Code Review Ready"
>
Your pull request is ready for code review by the team.
</Alert>
<Alert
icon={Sparkles}
variant="success"
title="Feature Unlocked"
>
Congratulations! You've unlocked premium features.
</Alert>
<Alert
icon={TrendingUp}
variant="info"
title="Performance Improved"
>
Your application performance has increased by 40% this month.
</Alert>
<Alert
icon={Lock}
variant="warning"
title="Security Alert"
>
We detected unusual login activity. Please verify your account.
</Alert>
<Alert
icon={Calendar}
variant="default"
title="Meeting Reminder"
>
Your team standup meeting starts in 15 minutes.
</Alert>
</div>
Dismissible Alerts
Notification
You have 3 new messages in your inbox.
Achievement Unlocked
Congratulations! You've completed 100 tasks this month.
Storage Warning
Your storage is almost full. Consider upgrading your plan.
Thank You!
Thank you for being an awesome user! Your feedback helps us improve.
import { Bell, Trophy, HardDrive, Heart } from "lucide-react";
const handleDismiss = (message: string) => {
console.log(message);
};
<div className="space-y-4">
<Alert
icon={Bell}
variant="info"
title="Notification"
dismissible
onDismiss={() => handleDismiss("Alert dismissed")}
>
You have 3 new messages in your inbox.
</Alert>
<Alert
icon={Trophy}
variant="success"
title="Achievement Unlocked"
dismissible
onDismiss={() => handleDismiss("Achievement dismissed")}
>
Congratulations! You've completed 100 tasks this month.
</Alert>
<Alert
icon={HardDrive}
variant="warning"
title="Storage Warning"
dismissible
onDismiss={() => handleDismiss("Storage warning dismissed")}
>
Your storage is almost full. Consider upgrading your plan.
</Alert>
{/* Custom icons with dismissible */}
<Alert
icon={Heart}
variant="success"
title="Thank You!"
dismissible
onDismiss={() => handleDismiss("Thank you dismissed")}
>
Thank you for being an awesome user! Your feedback helps us improve.
</Alert>
</div>
Custom Styling
Custom border radius styling.
Alert with dashed border style.
Alert with enhanced shadow.
Custom gradient styling.
<div className="space-y-4">
<Alert className="rounded-xl border-2">
Custom border radius styling.
</Alert>
<Alert variant="info" className="border-dashed">
Alert with dashed border style.
</Alert>
<Alert variant="success" className="shadow-lg">
Alert with enhanced shadow.
</Alert>
<Alert className="bg-gradient-to-r from-purple-50 to-pink-50 border-purple-200 text-purple-800 dark:from-purple-950/20 dark:to-pink-950/20 dark:border-purple-800 dark:text-purple-200">
Custom gradient styling.
</Alert>
</div>
Real-world Examples
System Status
All Systems Operational
All services are running normally. Last updated 2 minutes ago.
Account Security
Password Expiring Soon
Your password will expire in 3 days. Update it now to maintain account security.
Billing Information
Payment Method Required
Your trial ends in 2 days. Add a payment method to continue using our services.
import { Server, Shield, CreditCard } from "lucide-react";
<div className="space-y-4">
<div className="space-y-2">
<h4 className="text-sm font-medium">System Status</h4>
<Alert icon={Server} variant="success" title="All Systems Operational">
All services are running normally. Last updated 2 minutes ago.
</Alert>
</div>
<div className="space-y-2">
<h4 className="text-sm font-medium">Account Security</h4>
<Alert icon={Shield} variant="warning" title="Password Expiring Soon">
Your password will expire in 3 days. Update it now to maintain account security.
</Alert>
</div>
<div className="space-y-2">
<h4 className="text-sm font-medium">Billing Information</h4>
<Alert icon={CreditCard} variant="destructive" title="Payment Method Required">
Your trial ends in 2 days. Add a payment method to continue using our services.
</Alert>
</div>
</div>
Alert Sizes
Compact alert for minimal space.
Standard size for most use cases.
Prominent alert for important messages.
<div className="space-y-4">
<Alert className="text-xs p-3">Compact alert for minimal space.</Alert>
<Alert>Standard size for most use cases.</Alert>
<Alert className="text-base p-5">
Prominent alert for important messages.
</Alert>
</div>
Props
Alert Props
Prop | Type | Default |
---|---|---|
children? | ReactNode | undefined |
className? | string | undefined |
onDismiss? | () => void | undefined |
dismissible? | boolean | false |
title? | string | undefined |
icon? | LucideIcon | undefined |
variant? | "default" | "destructive" | "warning" | "success" | "info" | "default" |
Edit on GitHub
Last updated on