Alert
A persistent message that helps people recover or continue.
statusmessage
Preview
Alert preview
Live · keyboard ready
Heads up
Your trial ends in three days. Add a payment method to keep the workspace.
Deployed
manicat-library is live on manicat.dev.
Slow build
The last build took 4 minutes 12 seconds.
Build failed
Two components failed to typecheck.
When to use
- Persistent, in-flow messages about a page or form, such as an expiring card.
- Status that changes over time, where one alert should morph between tones.
- Dismissible notices that should collapse and close the gap below them.
When not to use
- Use toast or toast-stack for transient results of an action.
- Use empty-state when there is no content to show.
- Use dialog when people must respond before continuing.
shadcn CLI
Also installs (1)
- manicat-foundation
Manual install(+)
registry.jsonjson
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "alert",
"type": "registry:ui",
"title": "Alert",
"description": "A persistent message that helps people recover or continue.",
"categories": [
"feedback"
],
"dependencies": [
"lucide-react",
"motion"
],
"registryDependencies": [
"https://manicat.viraza.net/r/manicat-foundation.json"
],
"files": [
{
"path": "registry/components/alert/alert.tsx",
"type": "registry:component",
"target": "@components/manicat/alert/alert.tsx"
},
{
"path": "registry/components/alert/alert.module.css",
"type": "registry:component",
"target": "@components/manicat/alert/alert.module.css"
}
],
"docs": "Docs and live preview: https://uiarc.dev/components/alert",
"meta": {
"tier": "free",
"kind": "component",
"docs": "https://manicat.viraza.net/components/alert",
"markdown": "https://uiarc.dev/components/alert/markdown",
"tags": [
"status",
"message"
]
}
}Usage
Install the component, then copy this into your app. Change the content and the props to fit your screen.
example.tsxtsx
"use client";
import { useState } from "react";
import { Alert } from "@/components/manicat/alert/alert";
export function AlertExample() {
const [open, setOpen] = useState(true);
return (
<div className="grid w-full max-w-lg gap-3">
<Alert tone="info" title="Heads up" onDismiss={() => setOpen(false)} open={open}>
Your trial ends in three days. Add a payment method to keep the workspace.
</Alert>
<Alert tone="success" title="Deployed">
manicat-library is live on manicat.dev.
</Alert>
<Alert tone="warning" title="Slow build">
The last build took 4 minutes 12 seconds.
</Alert>
<Alert tone="danger" title="Build failed">
Two components failed to typecheck.
</Alert>
</div>
);
}
Examples
Real screens rather than isolated props. Switch to Code to copy a whole example into your project.
Dismissible banner A trial warning the user can dismiss, with a call to action inside.
Dismissible banner
A trial warning the user can dismiss, with a call to action inside. preview
Live · keyboard ready
Your trial ends in 3 days
Add a payment method to keep your workspace and its 14 projects.
dismissible-banner-a-trial-warning-the-user-can-dismiss-with-a-call-to-action-inside-.tsxtsx
Deploy result Success and failure side by side, so the tones read as a set.
Deploy result
Success and failure side by side, so the tones read as a set. preview
Live · keyboard ready
Deployed to production
v2.4.0 is live. Cache purged in 3 regions.
Build failed
Type error in src/billing.ts:42, “amount” is possibly undefined.
deploy-result-success-and-failure-side-by-side-so-the-tones-read-as-a-set-.tsxtsx
"use client";
import { Alert } from "@/components/manicat/alert/alert";
export function AlertResultExample() {
return (
<div className="grid w-full max-w-lg gap-3">
<Alert tone="success" title="Deployed to production">
v2.4.0 is live. Cache purged in 3 regions.
</Alert>
<Alert tone="danger" title="Build failed">
Type error in src/billing.ts:42, “amount” is possibly undefined.
</Alert>
</div>
);
}
Keyboard interactions
| Keys | Action |
|---|---|
| Enter / Space | Activates the dismiss button when present. |
Accessibility
- Danger alerts use role="alert" and interrupt; other tones use role="status" and announce politely.
- Outgoing copies are aria-hidden while they fade, so the live region reads only the current text.
- The dismiss button is labelled "Dismiss: <title>"; the tone icon is aria-hidden.
Motion
- Presence collapses or expands the height on a smooth spring with a fade, so content below closes the gap.
- Tone changes morph the icon through a small scale and blur; copy changes rise in while the height springs to fit.
- Reduced motion swaps content with short fades and no height animation.
Responsive behavior
- The alert fills its container and the copy wraps; the icon and dismiss button keep fixed sizes.
- Hover styles on the dismiss button apply only on hover-capable fine pointers.
Performance
- A ResizeObserver lets the height spring when copy changes; keep only a few alerts mounted per page.
Notes for AI
- Use for persistent, in-flow messages tied to a page or form. Use toast or toast-stack for transient results of an action.
- Keep one Alert mounted and change tone, title, and children to morph between states instead of swapping components.