65 lines
1.9 KiB
TypeScript
65 lines
1.9 KiB
TypeScript
import { Info, AlertTriangle, XCircle, Lightbulb } from "lucide-react";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
type CalloutType = "info" | "warning" | "danger" | "tip";
|
|
|
|
interface CalloutProps {
|
|
type?: CalloutType;
|
|
title?: string;
|
|
children: React.ReactNode;
|
|
}
|
|
|
|
const configs: Record<
|
|
CalloutType,
|
|
{ icon: React.ElementType; borderColor: string; bgColor: string; titleColor: string; iconColor: string }
|
|
> = {
|
|
info: {
|
|
icon: Info,
|
|
borderColor: "border-blue-400",
|
|
bgColor: "bg-blue-50 dark:bg-blue-950/30",
|
|
titleColor: "text-blue-800 dark:text-blue-200",
|
|
iconColor: "text-blue-500",
|
|
},
|
|
warning: {
|
|
icon: AlertTriangle,
|
|
borderColor: "border-amber-400",
|
|
bgColor: "bg-amber-50 dark:bg-amber-950/30",
|
|
titleColor: "text-amber-800 dark:text-amber-200",
|
|
iconColor: "text-amber-500",
|
|
},
|
|
danger: {
|
|
icon: XCircle,
|
|
borderColor: "border-red-400",
|
|
bgColor: "bg-red-50 dark:bg-red-950/30",
|
|
titleColor: "text-red-800 dark:text-red-200",
|
|
iconColor: "text-red-500",
|
|
},
|
|
tip: {
|
|
icon: Lightbulb,
|
|
borderColor: "border-green-400",
|
|
bgColor: "bg-green-50 dark:bg-green-950/30",
|
|
titleColor: "text-green-800 dark:text-green-200",
|
|
iconColor: "text-green-500",
|
|
},
|
|
};
|
|
|
|
export function Callout({ type = "info", title, children }: CalloutProps) {
|
|
const { icon: Icon, borderColor, bgColor, titleColor, iconColor } = configs[type];
|
|
const defaultTitles: Record<CalloutType, string> = {
|
|
info: "Note",
|
|
warning: "Warning",
|
|
danger: "Danger",
|
|
tip: "Tip",
|
|
};
|
|
|
|
return (
|
|
<div className={cn("flex gap-3 rounded-lg border-l-4 p-4 my-4", borderColor, bgColor)}>
|
|
<Icon className={cn("h-5 w-5 mt-0.5 shrink-0", iconColor)} />
|
|
<div className="text-sm leading-relaxed">
|
|
<p className={cn("font-semibold mb-1", titleColor)}>{title ?? defaultTitles[type]}</p>
|
|
<div className="text-foreground/80">{children}</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|