Components
Alert
Displays a callout for user attention. Use it for inline, persistent messages -- not for transient toasts or blocking dialogs.
Preview
Success! Your changes have been saved.
Rendered with live Folio tokens -- surface, border, and every variant color remap on theme change, no dark: classes.
Variants
Heads up
<Alert>
<CircleAlert />
<AlertTitle>Changes saved</AlertTitle>
<AlertDescription>Your edits are live.</AlertDescription>
</Alert>Draft
<Alert variant="muted">
<Info />
<AlertTitle>Draft</AlertTitle>
<AlertDescription>Only you can see this page.</AlertDescription>
</Alert>Something went wrong!
<Alert variant="destructive">
<CircleAlert />
<AlertTitle>Something went wrong</AlertTitle>
<AlertDescription>Your session has expired.</AlertDescription>
</Alert>Your subscription will expire in 3 days.
<Alert variant="warning">
<TriangleAlert />
<AlertTitle>Subscription expiring</AlertTitle>
<AlertDescription>Renew within 3 days.</AlertDescription>
</Alert>Payment received
// No success variant: color the default alert with tokens
<Alert className="border-success/30 bg-success-subtle text-success [&>svg]:text-success">
<CircleCheck />
<AlertTitle>Payment received</AlertTitle>
<AlertDescription>Your plan is now active.</AlertDescription>
</Alert>A new version is available
// No info variant: color the default alert with tokens
<Alert className="border-info/30 bg-info-subtle text-info [&>svg]:text-info">
<Info />
<AlertTitle>A new version is available</AlertTitle>
<AlertDescription>Refresh to get the latest.</AlertDescription>
</Alert>Every status variant tints its surface, softens the border to the feedback color, and colors the icon and title to match -- the body stays default for readability. Alert has no success or info variant, so those two use the same recipe with a className. The same recipe drives the Toast, so the two read as one system. All via tokens, so dark mode is automatic.
Composition
Title only
AlertTitle and AlertDescription are both optional -- drop the icon, the title, or both. With no icon the text fills the full width.
API
Don't and Do
Don't color the destructive alert with border-destructive dark:border-destructive -- the legacy alert.tsx does exactly this. Hardcoded dark: classes drift the moment the brand changes.
// One variant prop, token-driven, theme-agnostic
<Alert variant="destructive">…</Alert>import { Alert, AlertTitle, AlertDescription } from "@/components/shadcn/alert";
import { CircleAlert } from "lucide-react";
export function SavedAlert() {
return (
<Alert>
<CircleAlert />
<AlertTitle>Changes saved</AlertTitle>
<AlertDescription>Your edits are live.</AlertDescription>
</Alert>
);
}Drop the icon in as the first child -- the [&>svg] rules position it and pad the text. Folio tokens are baked in.