Alert
A shadcn-style alert component built with Ark UI primitives.
Alert
Default informational alert message.
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
const AlertDefault = () => (
<Alert className="w-full max-w-md">
<AlertTitle>Alert</AlertTitle>
<AlertDescription>Default informational alert message.</AlertDescription>
</Alert>
);
export default AlertDefault;
Installation
npx shadcn@latest add @ark-cn/alertInstall the dependency required by this primitive:
npm install @ark-ui/react class-variance-authorityCopy the component source into your app:
TSXcomponents/ui/alert.tsx
"use client";
import { ark } from "@ark-ui/react/factory";
import { cva, type VariantProps } from "class-variance-authority";
import type { ComponentProps, ReactElement } from "react";
import { cn } from "@/lib/utils";
const alertVariants = cva(
"relative grid w-full items-start gap-x-2 gap-y-0.5 rounded-xl border px-3.5 py-3 text-card-foreground text-sm has-[>svg]:has-data-[slot=alert-action]:grid-cols-[--spacing(4)_1fr_auto] has-[>svg]:grid-cols-[--spacing(4)_1fr] has-data-[slot=alert-action]:grid-cols-[1fr_auto] has-[>svg]:gap-x-2 [&>svg]:h-lh [&>svg]:w-4",
{
defaultVariants: {
variant: "default",
},
variants: {
variant: {
default:
"bg-transparent dark:bg-input/32 [&>svg]:text-muted-foreground",
error:
"border-destructive/32 bg-destructive/4 [&>svg]:text-destructive",
info: "border-info/32 bg-info/4 [&>svg]:text-info",
success: "border-success/32 bg-success/4 [&>svg]:text-success",
warning: "border-warning/32 bg-warning/4 [&>svg]:text-warning",
},
},
},
);
export const Alert = ({
className,
variant,
...props
}: ComponentProps<typeof ark.div> &
VariantProps<typeof alertVariants>): ReactElement => (
<ark.div
className={cn(alertVariants({ variant }), className)}
data-slot="alert"
role="alert"
{...props}
/>
);
export const AlertTitle = ({
className,
...props
}: ComponentProps<typeof ark.div>): ReactElement => (
<ark.div
className={cn("font-medium [svg~&]:col-start-2", className)}
data-slot="alert-title"
{...props}
/>
);
export const AlertDescription = ({
className,
...props
}: ComponentProps<typeof ark.div>): ReactElement => (
<ark.div
className={cn(
"flex flex-col gap-2.5 text-muted-foreground [svg~&]:col-start-2",
className,
)}
data-slot="alert-description"
{...props}
/>
);
export const AlertAction = ({
className,
...props
}: ComponentProps<typeof ark.div>): ReactElement => (
<ark.div
className={cn(
"flex gap-1 max-sm:col-start-2 max-sm:mt-2 sm:row-start-1 sm:row-end-3 sm:self-center sm:[[data-slot=alert-description]~&]:col-start-2 sm:[[data-slot=alert-title]~&]:col-start-2 sm:[svg~&]:col-start-2 sm:[svg~[data-slot=alert-description]~&]:col-start-3 sm:[svg~[data-slot=alert-title]~&]:col-start-3",
className,
)}
data-slot="alert-action"
{...props}
/>
);
Add the following CSS to your stylesheet (e.g. styles.css):
@theme inline {
--color-destructive-foreground: var(--destructive-foreground);
--color-info: var(--info);
--color-info-foreground: var(--info-foreground);
--color-success: var(--success);
--color-success-foreground: var(--success-foreground);
--color-warning: var(--warning);
--color-warning-foreground: var(--warning-foreground);
}
:root {
--destructive-foreground: var(--color-red-400);
--info: var(--color-blue-500);
--info-foreground: var(--color-blue-700);
--success: var(--color-emerald-500);
--success-foreground: var(--color-emerald-700);
--warning: var(--color-amber-500);
--warning-foreground: var(--color-amber-700);
}
.dark {
--destructive-foreground: var(--color-red-400);
--info: var(--color-blue-500);
--info-foreground: var(--color-blue-400);
--success: var(--color-emerald-500);
--success-foreground: var(--color-emerald-400);
--warning: var(--color-amber-500);
--warning-foreground: var(--color-amber-400);
}Update import aliases to match your project setup.
Usage
import * as Alert from "@/components/ui/alert"Read exported parts in src/components/ui/alert.tsx and compose the primitive according to the Ark UI pattern for this component.
Examples
Alert
Alert
Default informational alert message.
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
const AlertDefault = () => (
<Alert className="w-full max-w-md">
<AlertTitle>Alert</AlertTitle>
<AlertDescription>Default informational alert message.</AlertDescription>
</Alert>
);
export default AlertDefault;
With Icon
With Icon
Add an icon as the first child to provide quick context.
import { InfoIcon } from "lucide-react";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
const AlertWithIcon = () => (
<Alert className="w-full max-w-md">
<InfoIcon />
<AlertTitle>With Icon</AlertTitle>
<AlertDescription>
Add an icon as the first child to provide quick context.
</AlertDescription>
</Alert>
);
export default AlertWithIcon;
With Icon and Action Buttons
With Icon and Action Buttons
Pair the action area with primary and secondary actions.
import { ShieldAlertIcon } from "lucide-react";
import {
Alert,
AlertAction,
AlertDescription,
AlertTitle,
} from "@/components/ui/alert";
import { Button } from "@/components/ui/button";
const AlertWithIconActionButtons = () => (
<Alert className="w-full max-w-md">
<ShieldAlertIcon />
<AlertTitle>With Icon and Action Buttons</AlertTitle>
<AlertDescription>
Pair the action area with primary and secondary actions.
</AlertDescription>
<AlertAction>
<Button size="xs" variant="outline">
Dismiss
</Button>
<Button size="xs">Resolve</Button>
</AlertAction>
</Alert>
);
export default AlertWithIconActionButtons;
Success Alert
Success Alert
Your settings were saved successfully.
import { CheckCircle2Icon } from "lucide-react";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
const AlertSuccess = () => (
<Alert className="w-full max-w-md" variant="success">
<CheckCircle2Icon />
<AlertTitle>Success Alert</AlertTitle>
<AlertDescription>Your settings were saved successfully.</AlertDescription>
</Alert>
);
export default AlertSuccess;
Warning Alert
Warning Alert
Storage is almost full. Clean up large files.
import { CircleAlertIcon } from "lucide-react";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
const AlertWarning = () => (
<Alert className="w-full max-w-md" variant="warning">
<CircleAlertIcon />
<AlertTitle>Warning Alert</AlertTitle>
<AlertDescription>
Storage is almost full. Clean up large files.
</AlertDescription>
</Alert>
);
export default AlertWarning;
Error Alert
Error Alert
Unable to connect to the API right now.
import { ShieldAlertIcon } from "lucide-react";
import { Alert, AlertDescription, AlertTitle } from "../ui/alert";
const AlertError = () => (
<Alert className="w-full max-w-md" variant="error">
<ShieldAlertIcon />
<AlertTitle>Error Alert</AlertTitle>
<AlertDescription>Unable to connect to the API right now.</AlertDescription>
</Alert>
);
export default AlertError;