خالی
یک نگهدارندهٔ جای خالی برای جستجوهای بدون نتیجه، داشبوردهای خالی و صفحههای راهاندازی اولیه — آیکون، عنوان و اقدام در قابهای نئوبروتالیست.
import { IconFolderCode } from "@tabler/icons-react"
import { ArrowUpRightIcon } from "lucide-react"
حالت خالی جای خالی را وقتی چیزی برای رندر نیست پر میکند — اسلات برای آیکون یا آواتار، عنوان، توضیح و فراخوان به اقدام. مجموعهای از divهای ترکیبی بدونوابستگی (بدون primitive زیرین) با دستور پخت نئوبروتالیستی: حاشیههای ضخیم و تایپ heading پررنگ.
برای این موارد از آن استفاده کنید:
- جستجو و فیلتر بدون نتیجه — بگویید چرا فهرست خالی است و راه reset یا گسترش query را پیشنهاد دهید.
- صفحهٔ اولیناجرا — «هنوز پروژهای نیست» با دکمهٔ ساخت که به قدم بعدی اشاره میکند.
- صندوق و صف خالیشده — تأیید کنید فهرست خالی موفقیت است نه خطا.
نصب#
pnpm dlx shadcn@latest add https://neobrutalism.com/r/base/empty.jsonnpx shadcn@latest add https://neobrutalism.com/r/base/empty.jsonyarn dlx shadcn@latest add https://neobrutalism.com/r/base/empty.jsonbunx --bun shadcn@latest add https://neobrutalism.com/r/base/empty.json
کد زیر را کپی کرده و در پروژهٔ خود جایگذاری کنید.
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
function Empty({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="empty"
className={cn(
"flex w-full min-w-0 flex-1 flex-col items-center justify-center gap-4 rounded border-2 bg-card p-6 text-center text-balance",
className
)}
{...props}
/>
)
}
function EmptyHeader({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="empty-header"
className={cn("flex max-w-sm flex-col items-center gap-2", className)}
{...props}
/>
)
}
const emptyMediaVariants = cva(
"mb-2 flex shrink-0 items-center justify-center [&_svg]:pointer-events-none [&_svg]:shrink-0",
{
variants: {
variant: {
default: "bg-transparent",
icon: "flex size-8 shrink-0 items-center justify-center rounded-lg bg-muted text-foreground [&_svg:not([class*='size-'])]:size-4",
},
},
defaultVariants: {
variant: "default",
},
}
)
function EmptyMedia({
className,
variant = "default",
...props
}: React.ComponentProps<"div"> & VariantProps<typeof emptyMediaVariants>) {
return (
<div
data-slot="empty-icon"
data-variant={variant}
className={cn(emptyMediaVariants({ variant, className }))}
{...props}
/>
)
}
function EmptyTitle({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="empty-title"
className={cn(
"cn-font-heading text-sm font-medium tracking-tight",
className
)}
{...props}
/>
)
}
function EmptyDescription({ className, ...props }: React.ComponentProps<"p">) {
return (
<div
data-slot="empty-description"
className={cn(
"text-sm/relaxed text-muted-foreground [&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary",
className
)}
{...props}
/>
)
}
function EmptyContent({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="empty-content"
className={cn(
"flex w-full max-w-sm min-w-0 flex-col items-center gap-2.5 text-sm text-balance",
className
)}
{...props}
/>
)
}
export {
Empty,
EmptyHeader,
EmptyTitle,
EmptyDescription,
EmptyContent,
EmptyMedia,
}
مسیرهای import را مطابق با پیکربندی پروژهٔ خود بهروزرسانی کنید.
استفاده#
import {
Empty,
EmptyContent,
EmptyDescription,
EmptyHeader,
EmptyMedia,
EmptyTitle,
} from "@/components/ui/empty"<Empty>
<EmptyHeader>
<EmptyMedia variant="icon">
<Icon />
</EmptyMedia>
<EmptyTitle>No data</EmptyTitle>
<EmptyDescription>No data found</EmptyDescription>
</EmptyHeader>
<EmptyContent>
<Button>Add data</Button>
</EmptyContent>
</Empty>ترکیب#
برای ساخت یک حالت Empty از ترکیب زیر استفاده کنید:
Empty
├── EmptyHeader
│ ├── EmptyMedia
│ ├── EmptyTitle
│ └── EmptyDescription
└── EmptyContentنمونهها#
طرحکلی#
برای ایجاد یک حالت خالی با طرحکلی از کلاس کاربردی border استفاده کنید.
import { IconCloud } from "@tabler/icons-react"
import { Button } from "@/components/ui/button"پسزمینه#
برای افزودن یک پسزمینه به حالت خالی از کاربردیهای bg-* و bg-gradient-* استفاده کنید.
import { IconBell } from "@tabler/icons-react"
import { RefreshCcwIcon } from "lucide-react"
Avatar#
برای نمایش یک آواتار در حالت خالی از کامپوننت EmptyMedia استفاده کنید.
import {
Avatar,
AvatarFallback,گروه آواتار#
برای نمایش یک گروه آواتار در حالت خالی از کامپوننت EmptyMedia استفاده کنید.
import { PlusIcon } from "lucide-react"
import {InputGroup#
میتوانید یک کامپوننت InputGroup را به کامپوننت EmptyContent اضافه کنید.
import { SearchIcon } from "lucide-react"
import {RTL#
برای فعالسازی پشتیبانی RTL در Neobrutalism، راهنمای پیکربندی RTL را ببینید.
"use client"
import * as React from "react"دسترسیپذیری#
حالت خالی presentational است — divهای ساده بدون role یا رفتار صفحهکلید، پس چیزی برای سیمکشی نیست. آیکون تزئینی EmptyMedia را با aria-hidden="true" علامت بزنید و اقدامات داخل EmptyContent را بهصورت Button یا لینک واقعی نگه دارید تا focusable بمانند. وقتی empty state بعد از عملیات async جایگزین محتوا میشود (جستجویی که بدون نتیجه برمیگردد)، از طریق live region اعلامش کنید — خودِ تعویض DOM برای صفحهخوان خاموش است.
مرجع API#
Empty#
کامپوننت اصلی حالت خالی. کامپوننتهای EmptyHeader و EmptyContent را در بر میگیرد.
| Prop | Type | Default |
|---|---|---|
className | string |
<Empty>
<EmptyHeader />
<EmptyContent />
</Empty>EmptyHeader#
کامپوننت EmptyHeader رسانه، عنوان و توضیحات حالت خالی را در بر میگیرد.
| Prop | Type | Default |
|---|---|---|
className | string |
<EmptyHeader>
<EmptyMedia />
<EmptyTitle />
<EmptyDescription />
</EmptyHeader>EmptyMedia#
برای نمایش رسانهٔ حالت خالی مانند یک آیکون یا یک تصویر از کامپوننت EmptyMedia استفاده کنید. همچنین میتوانید از آن برای نمایش کامپوننتهای دیگر مانند یک آواتار استفاده کنید.
| Prop | Type | Default |
|---|---|---|
variant | "default" | "icon" | default |
className | string |
<EmptyMedia variant="icon">
<Icon />
</EmptyMedia><EmptyMedia>
<Avatar>
<AvatarImage src="..." />
<AvatarFallback>CN</AvatarFallback>
</Avatar>
</EmptyMedia>EmptyTitle#
برای نمایش عنوان حالت خالی از کامپوننت EmptyTitle استفاده کنید.
| Prop | Type | Default |
|---|---|---|
className | string |
<EmptyTitle>No data</EmptyTitle>EmptyDescription#
برای نمایش توضیحات حالت خالی از کامپوننت EmptyDescription استفاده کنید.
| Prop | Type | Default |
|---|---|---|
className | string |
<EmptyDescription>You do not have any notifications.</EmptyDescription>EmptyContent#
برای نمایش محتوای حالت خالی مانند یک دکمه، ورودی یا یک لینک از کامپوننت EmptyContent استفاده کنید.
| Prop | Type | Default |
|---|---|---|
className | string |
<EmptyContent>
<Button>Add Project</Button>
</EmptyContent>