İçeriğe atla

Boş

Sonuçsuz aramalar, boş gösterge panelleri ve ilk çalıştırma ekranları için yer tutucu — neobrütalist çerçeveler içinde yer alan simge, başlık ve eylem.

import { IconFolderCode } from "@tabler/icons-react"
import { ArrowUpRightIcon } from "lucide-react"

Boş durum bileşeni, gösterilecek bir şey olmadığında ortaya çıkan boşluğu doldurur — simge veya avatar için bir yuva, bir başlık, bir açıklama ve bir eylem çağrısı. Birleştirilebilir, bağımlılıksız div öğelerinden oluşur (altta bir primitif yoktur) ve neobrütalist reçeteye göre stillendirilmiştir: kalın kenarlıklar ve vurgulu başlık tipografisi.

Şu durumlarda tercih edin:

  • Sonuçsuz aramalar ve filtreler — listenin neden boş olduğunu söyleyin ve sorguyu sıfırlamanın ya da genişletmenin bir yolunu sunun.
  • İlk kullanım ekranları — bir sonraki adımı işaret eden oluşturma düğmesiyle birlikte “Henüz proje yok” mesajı.
  • Temizlenmiş gelen kutuları ve kuyruklar — boş listenin bir hata değil, başarı olduğunu vurgulayın.

Kurulum

pnpm dlx shadcn@latest add https://neobrutalism.com/r/base/empty.json
npx shadcn@latest add https://neobrutalism.com/r/base/empty.json
yarn dlx shadcn@latest add https://neobrutalism.com/r/base/empty.json
bunx --bun shadcn@latest add https://neobrutalism.com/r/base/empty.json

Aşağıdaki kodu kopyalayıp projenize yapıştırın.

components/ui/empty.tsx
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,
}

İçe aktarma yollarını proje kurulumunuza uyacak şekilde güncelleyin.

Kullanım

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>

Kompozisyon

Bir Empty durumu oluşturmak için aşağıdaki kompozisyonu kullanın:

Empty
├── EmptyHeader
│   ├── EmptyMedia
│   ├── EmptyTitle
│   └── EmptyDescription
└── EmptyContent

Örnekler

Ana Hat

Ana hatlı bir boş durum oluşturmak için border yardımcı sınıfını kullanın.

import { IconCloud } from "@tabler/icons-react"

import { Button } from "@/components/ui/button"

Arka Plan

Boş duruma bir arka plan eklemek için bg-* ve bg-gradient-* yardımcı sınıflarını kullanın.

import { IconBell } from "@tabler/icons-react"
import { RefreshCcwIcon } from "lucide-react"

Avatar

Boş durumda bir avatar görüntülemek için EmptyMedia bileşenini kullanın.

import {
  Avatar,
  AvatarFallback,

Avatar Grubu

Boş durumda bir avatar grubu görüntülemek için EmptyMedia bileşenini kullanın.

import { PlusIcon } from "lucide-react"

import {

InputGroup

EmptyContent bileşenine bir InputGroup bileşeni ekleyebilirsiniz.

import { SearchIcon } from "lucide-react"

import {

RTL

Neobrutalism'de RTL desteğini etkinleştirmek için RTL yapılandırma kılavuzuna bakın.

"use client"

import * as React from "react"

Erişilebilirlik

Boş durum bileşeni yalnızca görseldir — rol veya klavye davranışı taşımayan düz div öğelerinden oluştuğu için bağlanacak bir şey yoktur. Tamamen dekoratif bir EmptyMedia simgesini aria-hidden="true" ile işaretleyin ve EmptyContent içindeki eylemleri, odaklanabilir kalmaları için gerçek Button veya bağlantı öğeleri olarak tutun. Boş durum, eşzamansız bir işlemin ardından içeriğin yerini aldığında (örneğin sonuç döndürmeyen bir arama) bunu bir canlı bölge (live region) aracılığıyla duyurun — DOM değişiminin kendisi ekran okuyucular için sessizdir.

API Referansı

Empty

Boş durumun ana bileşeni. EmptyHeader ve EmptyContent bileşenlerini sarmalar.

PropTypeDefault
classNamestring
<Empty>
  <EmptyHeader />
  <EmptyContent />
</Empty>

EmptyHeader

EmptyHeader bileşeni, boş durumun medyasını, başlığını ve açıklamasını sarmalar.

PropTypeDefault
classNamestring
<EmptyHeader>
  <EmptyMedia />
  <EmptyTitle />
  <EmptyDescription />
</EmptyHeader>

EmptyMedia

Boş durumun medyasını (bir simge veya görsel gibi) görüntülemek için EmptyMedia bileşenini kullanın. Ayrıca avatar gibi diğer bileşenleri görüntülemek için de kullanabilirsiniz.

PropTypeDefault
variant"default" | "icon"default
classNamestring
<EmptyMedia variant="icon">
  <Icon />
</EmptyMedia>
<EmptyMedia>
  <Avatar>
    <AvatarImage src="..." />
    <AvatarFallback>CN</AvatarFallback>
  </Avatar>
</EmptyMedia>

EmptyTitle

Boş durumun başlığını görüntülemek için EmptyTitle bileşenini kullanın.

PropTypeDefault
classNamestring
<EmptyTitle>No data</EmptyTitle>

EmptyDescription

Boş durumun açıklamasını görüntülemek için EmptyDescription bileşenini kullanın.

PropTypeDefault
classNamestring
<EmptyDescription>You do not have any notifications.</EmptyDescription>

EmptyContent

Boş durumun içeriğini (bir düğme, giriş veya bağlantı gibi) görüntülemek için EmptyContent bileşenini kullanın.

PropTypeDefault
classNamestring
<EmptyContent>
  <Button>Add Project</Button>
</EmptyContent>