import * as React from "react"; import { useState } from "react"; import { motion, AnimatePresence } from "framer-motion"; import { ChevronDown, ChevronUp } from "lucide-react"; import { cva, type VariantProps } from "class-variance-authority"; import { cn } from "@/lib/utils"; import { ErrorState } from "./types"; const alertVariants = cva( "relative w-full rounded-lg border px-4 py-3 text-sm 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-4 [&>svg]:translate-y-0.5 [&>svg]:text-current", { variants: { variant: { default: "bg-card text-card-foreground border-border", destructive: "border-destructive/50 bg-destructive/10 text-destructive dark:border-red-400 dark:bg-red-950/50 dark:text-red-300 [&>svg]:text-destructive dark:[&>svg]:text-red-400", warning: "border-yellow-500/50 bg-yellow-50 text-yellow-900 dark:border-yellow-500 dark:bg-yellow-950 dark:text-yellow-100 [&>svg]:text-yellow-600 dark:[&>svg]:text-yellow-400", info: "border-blue-500/50 bg-blue-50 text-blue-900 dark:border-blue-500 dark:bg-blue-950 dark:text-blue-100 [&>svg]:text-blue-600 dark:[&>svg]:text-blue-400", success: "border-green-500/50 bg-green-50 text-green-900 dark:border-green-500 dark:bg-green-950 dark:text-green-100 [&>svg]:text-green-600 dark:[&>svg]:text-green-400", }, }, defaultVariants: { variant: "default", }, }, ); interface CollapsibleAlertProps extends React.ComponentProps<"div">, VariantProps { errorState: ErrorState; icon?: React.ReactNode; title?: string; } function CollapsibleAlert({ className, variant, errorState, icon, title = "An error occurred:", ...props }: CollapsibleAlertProps) { const [isExpanded, setIsExpanded] = useState(false); const hasDetails = Boolean(errorState.details); return (
{icon}
{title}
{errorState.message}
{hasDetails && ( <> {isExpanded && (
{errorState.details}
)}
setIsExpanded(!isExpanded)} className="flex items-center gap-1 text-xs text-current/70 transition-colors duration-200 hover:text-current" initial={{ scale: 1 }} whileHover={{ scale: 1.02 }} whileTap={{ scale: 0.98 }} > {isExpanded ? ( <> Hide details ) : ( <> Show details )} )}
); } export { CollapsibleAlert };