import * as React from 'react'; import { cva, type VariantProps } from 'class-variance-authority'; import { CheckCircle, Info, AlertTriangle, XCircle } from 'lucide-react'; import { cn } from '../../shared/utils'; const alertVariants = cva( 'relative w-full rounded-[var(--radius)] border-l-4 px-4 py-3 grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-5 [&>svg]:translate-y-0.5 [&>svg]:text-current', { variants: { variant: { default: 'bg-muted/50 border-l-border text-foreground [&>svg]:text-muted-foreground', success: 'bg-[color:var(--success)]/10 dark:bg-[color:var(--success)]/20 border-l-[color:var(--success)] text-foreground [&>svg]:text-[color:var(--success)]', info: 'bg-[color:var(--info)]/10 dark:bg-[color:var(--info)]/20 border-l-[color:var(--info)] text-foreground [&>svg]:text-[color:var(--info)]', warning: 'bg-[color:var(--warning)]/10 dark:bg-[color:var(--warning)]/20 border-l-[color:var(--warning)] text-foreground [&>svg]:text-[color:var(--warning)]', destructive: 'bg-[color:var(--destructive)]/10 dark:bg-[color:var(--destructive)]/20 border-l-[color:var(--destructive)] text-foreground [&>svg]:text-[color:var(--destructive)]', }, }, defaultVariants: { variant: 'default', }, } ); const alertIcons = { default: Info, success: CheckCircle, info: Info, warning: AlertTriangle, destructive: XCircle, } as const; type AlertVariantType = keyof typeof alertIcons; export interface AlertProps extends React.ComponentProps<'div'>, VariantProps { /** Custom icon. If not provided, a default semantic icon for the variant is used. Set to null to hide. */ icon?: React.ReactNode; } /** * Inline feedback banner for contextual status messages. * * @description * A non-transient, fixed-in-flow message block for critical validations or * contextual warnings. Contains a built-in icon based on the variant * (overridable via `icon` prop). Fills 100% of its container width. * * @ai-rules * 1. Always compose with `` + `` to preserve internal typography hierarchy. * 2. For transient feedback (success/error after submit), use `` (Sonner) instead. * 3. Available variants: `default`, `success`, `info`, `warning`, `destructive`. */ function Alert({ className, variant, icon, children, ...props }: AlertProps) { // Determine valid variant with safe fallback const alertVariant: AlertVariantType = variant && variant in alertIcons ? (variant as AlertVariantType) : 'default'; const DefaultIcon = alertIcons[alertVariant]; return (
{icon !== undefined ? icon : }
{children}
); } function AlertTitle({ className, ...props }: React.ComponentProps<'div'>) { return (
); } function AlertDescription({ className, ...props }: React.ComponentProps<'div'>) { return (
); } export { Alert, AlertTitle, AlertDescription };