Components
Alert
Displays a callout for user attention. Use it to communicate status, warnings, or contextual information inline on a page.
example.tsx
Default Alert
This is a default alert message.
Default Alert
Default Alert
This is a default alert message.
Import
tsx
import {
AppAlert,
AppAlertContent,
AppAlertTitle,
AppAlertDescription,
} from "@/components/primitives/AppAlert"Variants
Use the variant prop to change the visual style.
Default
This is a default alert.
Destructive
This is a destructive alert.
Success
This is a success alert.
Warning
This is a warning alert.
Info
This is an info alert.
| Variant | When to use |
|---|---|
| default | Neutral or informational messages. Renders with brand primary background and icon color. |
| destructive | Errors, failures, or dangerous conditions. Renders with destructive background and icon color. |
| success | Confirmation that an action completed successfully. |
| warning | Caution — the action is allowed but has consequences. |
| info | Supplementary information the user should be aware of. |
With close button
Place an AppButton after AppAlertContent to add a dismiss action. The flex layout pushes it to the right automatically.
tsx
<AppAlert>
<InfoIcon className="w-8 h-8" />
<AppAlertContent>
<AppAlertTitle>Heads up</AppAlertTitle>
<AppAlertDescription>You have a new message.</AppAlertDescription>
</AppAlertContent>
<AppButton variant="ghost" size="icon" className="ml-auto shrink-0 rounded-full">
<XIcon className="h-4 w-4" />
</AppButton>
</AppAlert>API Reference
AppAlert extends all native <div> HTML attributes.
| Prop | Type | Default | Description |
|---|---|---|---|
| variant | "default" | "destructive" | "success" | "warning" | "info" | "default" | Visual style of the alert. |
| className | string | — | Additional Tailwind classes merged via cn(). Applied after variant classes, so it always wins. Use for one-off overrides; prefer a wrapper block for reusable changes. |
AppAlertContent groups AppAlertTitle and AppAlertDescription in a flex column and takes up the remaining horizontal space in the alert row. It extends all native <div> HTML attributes.
Source
src/components/primitives/AppAlert.tsx
import * as React from "react"
import { Alert, AlertTitle, AlertDescription } from "@/components/ui/alert"
import { cn } from "@/lib/utils"
const nativeVariantClasses = {
default: "bg-background [&>svg]:text-gray-400",
destructive: "bg-destructive/5 [&>svg]:text-destructive",
} as const
const extendedVariantClasses = {
success: "border text-green-700 dark:text-green-700 [&>svg]:text-green-700",
warning: "border text-amber-600 dark:text-amber-600 [&>svg]:text-amber-600",
info: "border text-blue-400 dark:text-blue-400 [&>svg]:text-blue-400",
} as const
type ExtendedVariant = "default" | "destructive" | keyof typeof extendedVariantClasses
type AppAlertProps = Omit<React.ComponentProps<typeof Alert>, "variant"> & {
variant?: ExtendedVariant
}
function AppAlert({ variant = "default", className, ...props }: AppAlertProps) {
const isExtended = variant in extendedVariantClasses
return (
<Alert
variant={isExtended ? "default" : (variant as "default" | "destructive")}
className={cn(
"flex items-center gap-3 px-3 py-2 [&>svg]:static [&>svg]:top-auto [&>svg]:left-auto [&>svg~*]:pl-0 [&>svg+div]:translate-y-0",
isExtended
? extendedVariantClasses[variant as keyof typeof extendedVariantClasses]
: nativeVariantClasses[variant as keyof typeof nativeVariantClasses],
className
)}
{...props}
/>
)
}
const AppAlertTitle = React.forwardRef<
React.ComponentRef<typeof AlertTitle>,
React.ComponentPropsWithoutRef<typeof AlertTitle>
>(({ className, ...props }, ref) => (
<AlertTitle
ref={ref}
className={cn("text-base font-bold mb-0", className)}
{...props}
/>
))
AppAlertTitle.displayName = "AppAlertTitle"
const AppAlertDescription = React.forwardRef<
React.ComponentRef<typeof AlertDescription>,
React.ComponentPropsWithoutRef<typeof AlertDescription>
>(({ className, ...props }, ref) => (
<AlertDescription
ref={ref}
className={cn("text-sm text-muted-foreground", className)}
{...props}
/>
))
AppAlertDescription.displayName = "AppAlertDescription"
const AppAlertContent = React.forwardRef<
HTMLDivElement,
React.HTMLAttributes<HTMLDivElement>
>(({ className, ...props }, ref) => (
<div
ref={ref}
className={cn("flex flex-col", className)}
{...props}
/>
))
AppAlertContent.displayName = "AppAlertContent"
export { AppAlert, AppAlertTitle, AppAlertDescription, AppAlertContent }
export type { AppAlertProps }