Docs
Alert
Alert
Displays a callout for user attention.
Loading...
Installation
Copy and paste the following code into your project.
import React from "react";
import { Slot } from "@radix-ui/react-slot";
import type { VariantProps } from "cva";
import { cva } from "cva";
import {
AlertCircleIcon,
AlertTriangleIcon,
CheckCircle2Icon,
InfoIcon,
} from "lucide-react";
import { autoRef, cn } from "@/lib/utils";
/* -------------------------------------------------------------------------- */
/* Variants */
/* -------------------------------------------------------------------------- */
export const alertVariants = {
root: cva({
base: cn(
"relative grid w-full grid-cols-[auto_1fr] items-start gap-3 rounded-lg border p-4",
),
variants: {
type: {
default: "bg-background text-foreground",
error: "border-destructive bg-destructive/10 text-destructive",
info: "border-sky-400 bg-sky-500/10 text-sky-900",
warning: "border-orange-400 bg-orange-500/10 text-orange-800",
success: "border-green-600 bg-green-500/10 text-green-900",
},
},
defaultVariants: {
type: "info",
},
}),
title: cva({
base: "h-5 font-medium leading-[1.25rem] tracking-tight",
}),
description: cva({
base: "text-sm [&_p]:leading-relaxed",
}),
};
/* -------------------------------------------------------------------------- */
/* Components */
/* -------------------------------------------------------------------------- */
/* ---------------------------------- Root ---------------------------------- */
const IconWrapper = ({ children }: { children: React.ReactNode }) => {
return <Slot className="h-5 w-5">{children}</Slot>;
};
export type AlertProps = React.ComponentPropsWithRef<"div"> &
VariantProps<typeof alertVariants.root> & {
defaultIcon?: VariantProps<typeof alertVariants.root>["type"];
icon?: React.ReactNode | null;
};
export const Alert = autoRef(
({
ref,
className,
children,
type = "default",
defaultIcon,
icon,
...props
}: AlertProps) => {
const chosenIcon = defaultIcon ?? type;
let Icon;
switch (chosenIcon) {
case "default": {
Icon = null;
break;
}
case "error": {
Icon = (
<IconWrapper>
<AlertCircleIcon />
</IconWrapper>
);
break;
}
case "info": {
Icon = (
<IconWrapper>
<InfoIcon />
</IconWrapper>
);
break;
}
case "warning": {
Icon = (
<IconWrapper>
<AlertTriangleIcon />
</IconWrapper>
);
break;
}
case "success": {
Icon = (
<IconWrapper>
<CheckCircle2Icon />
</IconWrapper>
);
break;
}
}
if (icon !== undefined) {
Icon = icon === null ? null : <IconWrapper>{icon}</IconWrapper>;
}
return (
<div
ref={ref}
role="alert"
className={cn(alertVariants.root({ type }), className)}
{...props}
>
{Icon}
<div className="space-y-1">{children}</div>
</div>
);
},
);
/* ---------------------------------- Title --------------------------------- */
export type AlertTitleProps = React.ComponentPropsWithRef<"h5">;
export const AlertTitle = autoRef(
({ className, ...props }: AlertTitleProps) => {
return <h5 className={cn(alertVariants.title(), className)} {...props} />;
},
);
/* ------------------------------- Description ------------------------------ */
export type AlertDescriptionProps = React.ComponentPropsWithRef<"div">;
export const AlertDescription = autoRef(
({ className, ...props }: AlertDescriptionProps) => {
return (
<div className={cn(alertVariants.description(), className)} {...props} />
);
},
);
Update the import paths to match your project setup.
Anatomy
<Alert>
<AlertTitle />
<AlertDescription />
</Alert>
Examples
Types
Loading...
Icons
Loading...