import { cn } from "@/lib/utils"; import { ExternalLink, LucideAlertOctagon, LucideAlertTriangle, LucideInfo, LucideLightbulb, LucideNotebookPen, } from "lucide-react"; import { createContext, useContext } from "react"; import { Card } from "./card"; const AdmonitionContext = createContext<{ type: string; size: "sm" | "md" | "lg"; } | null>(null); function useAdmonitionContext() { const ctx = useContext(AdmonitionContext); if (!ctx) { throw new Error( "Admonition subcomponents must be used within an ", ); } return ctx; } const ADMONITION_SIZES = { sm: "text-sm", md: "text-base", lg: "text-lg", } as const; // Admonition component based off Card function Admonition({ type, children, size = "md", }: { type: "note" | "tip" | "info" | "warning" | "danger"; children: React.ReactNode; size?: "sm" | "md" | "lg"; }) { const sizes = { sm: "py-2 px-3", md: "py-2 px-3", lg: "py-2 px-3", }; const colors = { note: "bg-blue-50 text-blue-800 dark:bg-blue-400/20 dark:text-blue-100 border-blue-400/40", tip: "bg-green-50 text-green-800 dark:bg-green-400/20 dark:text-green-100 border-green-400/40", info: "bg-blue-50 text-blue-800 dark:bg-blue-400/20 dark:text-blue-100 border-blue-400/40", warning: "bg-yellow-50 text-yellow-800 dark:bg-yellow-500/25 dark:text-yellow-100 border-yellow-400/40", danger: "bg-red-50 text-red-800 dark:bg-red-900/20 dark:text-red-100 border-red-400/40", } as const; const iconSize = { sm: "size-8 w-12", md: "size-12 w-16", lg: "size-14 w-20", }; const Icon = { note: LucideNotebookPen, tip: LucideLightbulb, info: LucideInfo, warning: LucideAlertTriangle, danger: LucideAlertOctagon, }[type as keyof typeof colors] || LucideInfo; return (
{children}
); } function AdmonitionTitle({ children }: { children: React.ReactNode }) { const ctx = useAdmonitionContext(); return (

{children}

); } function AdmonitionDescription({ children }: { children: React.ReactNode }) { const ctx = useAdmonitionContext(); const size = { sm: "text-sm", md: "text-sm", lg: "text-base", }[ctx.size]; const colors = { note: "text-blue-800/80 dark:text-blue-100/80", tip: "text-green-800/80 dark:text-green-100/80", info: "text-blue-800/80 dark:text-blue-100/80", warning: "text-yellow-800/80 dark:text-yellow-100/80", danger: "text-red-800/80 dark:text-red-100/80", } as const; return

{children}

; } function AdmonitionLink({ children, href, external = true, }: { children: React.ReactNode; href: string; external?: boolean; }) { const ctx = useAdmonitionContext(); const size = { sm: "text-sm", md: "text-sm", lg: "text-base", }[ctx.size]; const iconSize = { sm: "size-4 mb-1", md: "size-4 mb-1", lg: "size-6 mb-1.5", }[ctx.size]; const colors = { note: "text-blue-700/80 dark:text-blue-200/80", tip: "text-green-700/80 dark:text-green-200/80", info: "text-blue-700/80 dark:text-blue-200/80", warning: "text-yellow-700/80 dark:text-yellow-200/80", danger: "text-red-700/80 dark:text-red-200/80", } as const; return ( {children} ); } Admonition.Link = AdmonitionLink; Admonition.Description = AdmonitionDescription; Admonition.Title = AdmonitionTitle; export { Admonition };