Cảnh báo
Một hộp chú thích hiển thị ngay trong biểu mẫu để thông báo lỗi, cảnh báo và xác nhận thành công — các ô có màu theo trạng thái, viền theo phong cách tân thô mộc và bóng đổ đậm.
import { CheckCircle2Icon, InfoIcon } from "lucide-react"
import {Alert là một callout nội dòng: một icon, một tiêu đề, một đoạn mô tả và một hành động tùy chọn, được xếp trên lưới CSS. Đây là một div role="alert" không cần thư viện phụ thuộc nào — không có primitive bên dưới, giống nhau ở cả hai backend — tạo kiểu theo công thức neobrutalist: viền dày, bóng đổ đậm và kiểu chữ đậm, kèm một trục status để tô màu cho lỗi, thành công, cảnh báo và thông tin.
Nên dùng khi:
- Lỗi form và lỗi request — nêu một lỗi kiểm tra dữ liệu hoặc một lệnh gọi API thất bại ngay bên cạnh thứ vừa hỏng.
- Xác nhận thành công và trạng thái — “đã lưu cài đặt”, “bản dùng thử sắp hết hạn”, “đã nhận thanh toán”, tô màu theo prop
status. - Callout kèm bước tiếp theo — một cảnh báo hoặc thông báo nâng cấp có mang nút
AlertAction(“Bật”, “Hoàn tác”, “Nâng cấp”).
Cài đặt#
pnpm dlx shadcn@latest add https://neobrutalism.com/r/base/alert.jsonnpx shadcn@latest add https://neobrutalism.com/r/base/alert.jsonyarn dlx shadcn@latest add https://neobrutalism.com/r/base/alert.jsonbunx --bun shadcn@latest add https://neobrutalism.com/r/base/alert.json
Sao chép và dán đoạn mã sau vào dự án của bạn.
import * as React from "react"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
// CSS-grid layout (shadcn-style): drop an icon as a direct child and the alert
// auto-arranges into an icon column + a content column — no manual flex wrapper.
// `has-[>svg]` adds the icon column only when an icon is present. NeoBrutalist
// chrome: hard 2px border, square corners, hard offset shadow.
const alertVariants = cva(
cn(
"group/alert relative grid w-full grid-cols-[0_1fr] items-start gap-y-1 rounded border-2 px-4 py-3 text-left text-sm shadow-md",
"has-[>svg]:grid-cols-[1.25rem_1fr] has-[>svg]:gap-x-3",
"has-data-[slot=alert-action]:pr-14",
"[&>svg]:size-5 [&>svg]:translate-y-0.5 [&>svg]:shrink-0 [&>svg]:text-current"
),
{
variants: {
// shadcn's variant axis (kept for API compatibility). `solid` is a Neobrutalism
// addition.
variant: {
default:
"border-border bg-background text-foreground *:data-[slot=alert-description]:text-muted-foreground",
destructive:
"border-red-900 bg-red-300 text-red-900 *:data-[slot=alert-description]:text-red-900/80",
solid:
"border-border bg-foreground text-background *:data-[slot=alert-description]:text-background/80",
},
// Neobrutalism status axis — additive; overrides the variant's colors when set.
status: {
error:
"border-red-900 bg-red-300 text-red-900 *:data-[slot=alert-description]:text-red-900/80",
success:
"border-green-900 bg-green-300 text-green-900 *:data-[slot=alert-description]:text-green-900/80",
warning:
"border-yellow-900 bg-yellow-300 text-yellow-900 *:data-[slot=alert-description]:text-yellow-900/80",
info: "border-blue-900 bg-blue-300 text-blue-900 *:data-[slot=alert-description]:text-blue-900/80",
},
},
defaultVariants: {
variant: "default",
},
}
)
function Alert({
className,
variant,
status,
...props
}: React.ComponentProps<"div"> & VariantProps<typeof alertVariants>) {
return (
<div
data-slot="alert"
role="alert"
className={cn(alertVariants({ variant, status }), className)}
{...props}
/>
)
}
function AlertTitle({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="alert-title"
className={cn(
"col-start-2 min-h-5 font-head text-base leading-tight tracking-tight [&_a]:underline [&_a]:underline-offset-3",
className
)}
{...props}
/>
)
}
function AlertDescription({
className,
...props
}: React.ComponentProps<"div">) {
return (
<div
data-slot="alert-description"
className={cn(
"col-start-2 grid justify-items-start gap-1 text-sm [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground [&_p]:leading-relaxed [&_p:not(:last-child)]:mb-4",
className
)}
{...props}
/>
)
}
function AlertAction({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="alert-action"
className={cn("absolute top-2 right-2", className)}
{...props}
/>
)
}
export { Alert, AlertTitle, AlertDescription, AlertAction, alertVariants }
Cập nhật các đường dẫn import cho khớp với cấu trúc dự án của bạn.
Cách dùng#
import {
Alert,
AlertAction,
AlertDescription,
AlertTitle,
} from "@/components/ui/alert"<Alert>
<InfoIcon />
<AlertTitle>Heads up!</AlertTitle>
<AlertDescription>
You can add components and dependencies to your app using the cli.
</AlertDescription>
<AlertAction>
<Button variant="outline">Enable</Button>
</AlertAction>
</Alert>Kết hợp#
Dùng cách kết hợp sau để dựng một Alert:
Alert
├── Icon
├── AlertTitle
├── AlertDescription
└── AlertActionVí dụ#
Cơ bản#
Một alert cơ bản với biểu tượng, tiêu đề và mô tả.
import { CheckCircle2Icon } from "lucide-react"
import {Phá hủy#
Dùng variant="destructive" để tạo một alert phá hủy.
import { AlertCircleIcon } from "lucide-react"
import {Hành động#
Dùng AlertAction để thêm một nút hoặc phần tử hành động khác vào alert.
import {
Alert,
AlertAction,Màu tùy chỉnh#
Bạn có thể tùy chỉnh màu của alert bằng cách thêm các lớp tùy chỉnh như bg-amber-50 dark:bg-amber-950 vào thành phần Alert.
import { AlertTriangleIcon } from "lucide-react"
import {RTL#
Để bật hỗ trợ RTL trong Neobrutalism, xem hướng dẫn cấu hình RTL.
"use client"
import * as React from "react"Khả năng truy cập#
Phần gốc của alert render role="alert", một live region assertive ngầm định: trình đọc màn hình đọc nội dung của nó ngay khoảnh khắc nó được chèn vào DOM. Thông báo chỉ phát khi phần tử được chèn động — một alert đã có sẵn lúc trang tải xong sẽ được đọc như văn bản thường, nên hãy render nó có điều kiện khi bạn muốn nó được đọc lên. role="alert" không bao giờ di chuyển focus; nếu người dùng buộc phải phản hồi trước khi tiếp tục, hãy dùng alert dialog thay thế, và hãy coi AlertAction là một lối tắt chứ không phải con đường duy nhất.
Tham chiếu API#
Alert#
Thành phần Alert hiển thị một thông báo nổi bật để thu hút sự chú ý của người dùng.
| Prop | Type | Default |
|---|---|---|
variant | "default" | "destructive" | "default" |
AlertTitle#
Thành phần AlertTitle hiển thị tiêu đề của alert.
| Prop | Type | Default |
|---|---|---|
className | string | - |
AlertDescription#
Thành phần AlertDescription hiển thị mô tả hoặc nội dung của alert.
| Prop | Type | Default |
|---|---|---|
className | string | - |
AlertAction#
Thành phần AlertAction hiển thị một phần tử hành động (như một nút) được định vị tuyệt đối ở góc trên bên phải của alert.
| Prop | Type | Default |
|---|---|---|
className | string | - |