shadcn/ui’nin Item bileşeni başlık, açıklama, medya ve aksiyon içeren liste satırları ya da kartlar kurmak için; Empty “henüz kayıt yok” türünden boş durum ekranları için; Kbd klavye tuşlarını göstermek için; Avatar ise kullanıcıyı temsil eden, görseli gösterilemediğinde yedek içeriğe düşen yuvarlak resim için kullanılır. Item, Empty ve Kbd Ekim 2025 sürüm notlarında eklenen yeni bileşenlerdendir; Avatar ise Radix UI’ye dayanan eski bir bileşendir ve bu üçünün örneklerinde sık sık birlikte görünür.
Bu yazıda dört bileşenin kurulumunu, parçalarını, varyantlarını ve resmî örneklerdeki kullanım kalıplarını anlatıyoruz. Bilgiler depo kopyası 19 Aralık 2025 tarihli belgelerden ve new-york-v4 kaynak kodundan alındı. Durum ve yükleniyor gösterimleri (Alert, Badge, Progress, Skeleton, Spinner) ayrı bir yazıda ele alınıyor; serinin tamamı shadcn/ui öğrenme rehberi sayfasında.
npx shadcn@latest add item
npx shadcn@latest add empty
npx shadcn@latest add kbd
npx shadcn@latest add avatarDört bileşen ayrı ayrı eklenir. Avatar’ın elle kurulumunda ayrıca @radix-ui/react-avatar paketi gerekir; Item, Empty ve Kbd ise ek bir npm paketine ihtiyaç duymaz. Item, kendi içinde Separator bileşenini kullanır.
Ekim 2025 bileşenlerinin fikri
Ekim 2025 sürüm notlarında yazar, bu turdaki bileşenleri her gün yeniden yazılan “sıkıcı” parçalara bakarak seçtiğini anlatır: Spinner, Kbd, Button Group, Input Group, Field, Item ve Empty. Notun vurguladığı nokta, bu bileşenlerin Radix, Base UI, React Aria gibi her bileşen kütüphanesiyle çalışmasıdır. Kaynak kodlarına bakınca nedeni anlaşılır: Kbd ve Empty yalnızca HTML öğeleri ve Tailwind sınıflarından oluşur; Item yalnızca asChild için Radix Slot ve ayırıcı için Separator kullanır. Yani bunlar davranış değil düzen bileşenleridir.
Item belgesinde yazar bunu açıkça söyler: aynı sonucu bir div ve birkaç sınıfla da elde edebilirsiniz, ama bunu o kadar çok kez yazmış ki bir bileşene dönüştürmüş. Bu bileşenlerin değeri, her projede tutarlı boşluk, hizalama ve odak stillerini tek bir yerden yönetmenizdir.
Item: liste satırı ve kart

Item, neredeyse her türlü içeriği barındırabilen basit bir flex kapsayıcıdır. Başlık, açıklama ve aksiyon göstermek için kullanılır; birden fazla Item, ItemGroup ile bir listeye dönüştürülür. Bileşenin parçaları ve kaynak koddaki rolleri:
| Parça | Görevi | Kaynak koddan not |
|---|---|---|
| Item | Ana kapsayıcı | variant, size ve asChild alır; data-variant ve data-size yazar |
| ItemMedia | İkon, görsel ya da avatar alanı | variant: default, icon, image |
| ItemContent | Başlık ve açıklamayı sarar | Yalnızca başlık varsa atlanabilir |
| ItemTitle | Başlık | Kalın, küçük metin |
| ItemDescription | Açıklama | Soluk renk, en fazla iki satır (line-clamp-2) |
| ItemActions | Buton ve etkileşimli öğeler | Yatay, aralıklı flex |
| ItemHeader / ItemFooter | Satırın üstünde ya da altında tam genişlik alan | basis-full ile yeni satıra geçer |
| ItemGroup | Item listesini sarar | role=list taşır |
| ItemSeparator | Grup içinde ayırıcı | Yatay Separator |
Varyantlar ve boyutlar
Belgedeki API tablosuna göre Item üç varyant (default, outline, muted) ve iki boyut (default, sm) alır; ikisinin de varsayılanı "default"’tur. Kaynak kodda default saydam arka plandır, outline görünür bir kenarlık ekler, muted soluk bir arka plan verir. sm boyutu dikey iç boşluğu ve öğeler arası aralığı azaltır; belge bunu kompakt öğeler için önerir. ItemMedia varyantlarından icon kenarlıklı ve arka planlı küçük bir kare, image ise içindeki img öğesini kare içine kırpan bir alan üretir.
import { BadgeCheckIcon, ChevronRightIcon } from "lucide-react"
import { Button } from "@/components/ui/button"
import {
Item,
ItemActions,
ItemContent,
ItemDescription,
ItemMedia,
ItemTitle,
} from "@/components/ui/item"
export function ItemOrnegi() {
return (
<div className="flex w-full max-w-md flex-col gap-6">
<Item variant="outline">
<ItemContent>
<ItemTitle>Temel öğe</ItemTitle>
<ItemDescription>
Başlık ve açıklama içeren basit bir öğe.
</ItemDescription>
</ItemContent>
<ItemActions>
<Button variant="outline" size="sm">
İşlem
</Button>
</ItemActions>
</Item>
<Item variant="outline" size="sm" asChild>
<a href="#">
<ItemMedia>
<BadgeCheckIcon className="size-5" />
</ItemMedia>
<ItemContent>
<ItemTitle>Profiliniz doğrulandı.</ItemTitle>
</ItemContent>
<ItemActions>
<ChevronRightIcon className="size-4" />
</ItemActions>
</a>
</Item>
</div>
)
}Bu, resmî item-demo dosyasının Türkçeleştirilmiş hâlidir. İkinci öğe asChild ile bir bağlantıya dönüşür. Belgeye göre bu durumda üzerine gelme ve odak stilleri bağlantı öğesine uygulanır; kaynak koddaki [a]:hover:bg-accent/50 sınıfı da yalnızca öğe bir a olduğunda çalışan üzerine gelme rengidir. Kaynakta ayrıca küçük bir hizalama inceliği vardır: öğede bir ItemDescription bulunuyorsa ItemMedia ortalanmak yerine yukarı yaslanır, böylece iki satırlık metinle ikon üst kenardan hizalı kalır.
ItemGroup ile liste
Resmî item-group örneği, kişileri avatar, ad, e-posta ve bir “ekle” butonuyla listeler; son öğe dışında her öğeden sonra bir ItemSeparator koyar. Kalıp şöyle özetlenebilir:
import * as React from "react"
import { PlusIcon } from "lucide-react"
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
import { Button } from "@/components/ui/button"
import {
Item,
ItemActions,
ItemContent,
ItemDescription,
ItemGroup,
ItemMedia,
ItemSeparator,
ItemTitle,
} from "@/components/ui/item"
const kisiler = [
{ username: "shadcn", avatar: "https://github.com/shadcn.png", email: "shadcn@vercel.com" },
{ username: "maxleiter", avatar: "https://github.com/maxleiter.png", email: "maxleiter@vercel.com" },
]
export function KisiListesi() {
return (
<ItemGroup>
{kisiler.map((kisi, index) => (
<React.Fragment key={kisi.username}>
<Item>
<ItemMedia>
<Avatar>
<AvatarImage src={kisi.avatar} />
<AvatarFallback>{kisi.username.charAt(0)}</AvatarFallback>
</Avatar>
</ItemMedia>
<ItemContent className="gap-1">
<ItemTitle>{kisi.username}</ItemTitle>
<ItemDescription>{kisi.email}</ItemDescription>
</ItemContent>
<ItemActions>
<Button variant="ghost" size="icon" className="rounded-full">
<PlusIcon />
</Button>
</ItemActions>
</Item>
{index !== kisiler.length - 1 && <ItemSeparator />}
</React.Fragment>
))}
</ItemGroup>
)
}React.Fragment, her öğe ile ayırıcısını tek bir anahtar altında döndürmek için kullanılır. ItemGroup kaynakta role="list" taşır; bu, öğelerin bir liste oluşturduğunu yardımcı teknolojilere bildirir. Belgede ayrıca simge, görsel, başlık (header) ve açılır menü (dropdown) içeren Item örnekleri de bulunur.
Item mı, Field mı?
Belge bu iki bileşeni net bir kuralla ayırır: onay kutusu, metin girişi, radyo düğmesi ya da seçim kutusu gibi bir form girdisi gösterecekseniz Field; yalnızca başlık, açıklama ve aksiyon gibi içerik gösterecekseniz Item kullanın. Field bileşeni Field yazısında anlatılıyor.
Empty: boş durum ekranı

Empty, bir listede hiç kayıt olmadığında ya da arama sonuç vermediğinde gösterilecek boş durum ekranları içindir. Yapısı iki bölümlüdür: medya, başlık ve açıklamayı saran EmptyHeader ve buton, girdi ya da bağlantı gibi eylemleri barındıran EmptyContent.
import { FolderCodeIcon } from "lucide-react"
import { Button } from "@/components/ui/button"
import {
Empty,
EmptyContent,
EmptyDescription,
EmptyHeader,
EmptyMedia,
EmptyTitle,
} from "@/components/ui/empty"
export function ProjeYok() {
return (
<Empty>
<EmptyHeader>
<EmptyMedia variant="icon">
<FolderCodeIcon />
</EmptyMedia>
<EmptyTitle>Henüz proje yok</EmptyTitle>
<EmptyDescription>
Henüz bir proje oluşturmadınız. İlk projenizi oluşturarak başlayın.
</EmptyDescription>
</EmptyHeader>
<EmptyContent>
<div className="flex gap-2">
<Button>Proje oluştur</Button>
<Button variant="outline">Proje içe aktar</Button>
</div>
</EmptyContent>
</Empty>
)
}Resmî empty-demo dosyası ikon olarak @tabler/icons-react paketinden IconFolderCode kullanır; bu paket projenizde yoksa yukarıdaki gibi lucide-react’ten benzer bir ikon seçebilirsiniz (ikon adının paketinizde bulunduğunu kontrol edin). EmptyMedia iki varyant alır: default saydam bir alan, icon ise içindeki SVG’yi size-6 boyutunda, soluk arka planlı yuvarlak köşeli bir kutuda gösterir. Varsayılan varyantta medya alanına bir Avatar ya da avatar grubu da koyabilirsiniz; belgede bunun için iki ayrı örnek vardır.
Kaynak koddaki Empty kapsayıcısı içeriği ortalar, metni dengeler (text-balance) ve geniş ekranda iç boşluğu artırır. Sınıflarında border-dashed bulunur ama kenarlık genişliği yoktur; belgenin “Outline” örneği bu yüzden kesikli çerçeve için border sınıfını eklemenizi söyler. Arka plan için de belge bg-* ve bg-gradient-* sınıflarını önerir.
<Empty className="border border-dashed">
<EmptyHeader>
<EmptyTitle>Bulut depolama boş</EmptyTitle>
<EmptyDescription>
Dosyalarınıza her yerden erişmek için yükleyin.
</EmptyDescription>
</EmptyHeader>
<EmptyContent>
<Button variant="outline" size="sm">
Dosya yükle
</Button>
</EmptyContent>
</Empty>Empty, data table rehberindeki “sonuç yok” hücresinin daha zengin bir karşılığı olarak da düşünülebilir: tablo boş kaldığında kullanıcıya ne yapabileceğini söyleyen bir eylem butonu sunar. Belgede EmptyContent içine bir Input Group konan, arama sonuçları ve e-posta aboneliği gibi durumlar için düşünülmüş bir örnek de vardır.
Kbd: klavye tuşları
Kbd, kullanıcının klavyeden gireceği metni ya da kısayolu göstermek içindir. Kaynakta adına uygun olarak HTML kbd öğesini çizer: soluk arka planlı, küçük, yuvarlak köşeli bir kutu. Birden fazla tuşu birlikte göstermek için KbdGroup kullanılır; kaynak koda bakınca onun da bir kbd öğesi olarak çizildiği görülür.
import { Kbd, KbdGroup } from "@/components/ui/kbd"
export function Kisayollar() {
return (
<div className="flex flex-col items-center gap-4">
<KbdGroup>
<Kbd>⌘</Kbd>
<Kbd>⇧</Kbd>
<Kbd>⌥</Kbd>
<Kbd>⌃</Kbd>
</KbdGroup>
<KbdGroup>
<Kbd>Ctrl</Kbd>
<span>+</span>
<Kbd>B</Kbd>
</KbdGroup>
</div>
)
}Kbd’nin kaynak kodunda üç ilginç ayrıntı vardır. Birincisi pointer-events-none ve select-none: tuş kutuları tıklanmaz ve metin seçimine girmez, yani bir butonun içine konduğunda tıklamayı engellemez. İkincisi, içine konan ve kendi boyut sınıfı olmayan SVG ikonlar size-3 boyutuna getirilir. Üçüncüsü, Kbd bir tooltip-content slot’unun içindeyse renklerini otomatik olarak değiştirir; böylece koyu arka planlı ipucu kutusunda da okunur kalır. Bu son ayrıntı, data-slot özniteliklerinin pratikte nasıl kullanıldığının güzel bir örneğidir.
Belge Kbd’nin Button, Tooltip ve Input Group içinde kullanımını gösterir. Butonda kısayolu metnin yanına koymak için resmî örnek className="pr-2" ile sağ boşluğu daraltır:
import { Button } from "@/components/ui/button"
import { Kbd, KbdGroup } from "@/components/ui/kbd"
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from "@/components/ui/tooltip"
export function KisayolButonlari() {
return (
<div className="flex flex-wrap items-center gap-4">
<Button variant="outline" size="sm" className="pr-2">
İptal <Kbd>Esc</Kbd>
</Button>
<Tooltip>
<TooltipTrigger asChild>
<Button size="sm" variant="outline">
Yazdır
</Button>
</TooltipTrigger>
<TooltipContent>
<div className="flex items-center gap-2">
Belgeyi yazdır{" "}
<KbdGroup>
<Kbd>Ctrl</Kbd>
<Kbd>P</Kbd>
</KbdGroup>
</div>
</TooltipContent>
</Tooltip>
</div>
)
}Kbd yalnızca kısayolu görsel olarak gösterir; tuşa basıldığında bir şey yapmaz. Kısayolun kendisini (örneğin Ctrl+P’ye basınca yazdırma) kendi kodunuzla dinlemeniz gerekir. Tooltip’in sağlayıcı gereksinimleri için Popover, Tooltip ve Hover Card yazısına, Ctrl/Cmd+K ile açılan komut paleti için Command yazısına bakabilirsiniz.
Avatar: kullanıcı görseli ve yedek içerik
Avatar, belgedeki tanımıyla kullanıcıyı temsil eden ve yedek (fallback) içeriği olan bir görsel öğesidir. Radix UI’nin Avatar ilkeline dayanır ve üç parçadan oluşur: kapsayıcı Avatar, görsel AvatarImage ve görsel gösterilemediğinde yerine çıkan AvatarFallback. Yedek içerik genellikle kullanıcının baş harfleridir.
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
<Avatar>
<AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
<AvatarFallback>CN</AvatarFallback>
</Avatar>Kaynak koda göre kapsayıcı varsayılan olarak size-8 boyutunda ve tam yuvarlaktır (rounded-full). Görsel kare oranlı ve tam boyutludur; yedek içerik soluk arka planlı, ortalanmış bir dairedir. Resmî avatar-demo dosyası iki özelleştirme kalıbı gösterir: className="rounded-lg" ile köşeleri yumuşatılmış kare avatar ve üst üste binen bir avatar grubu.
<div className="*:data-[slot=avatar]:ring-background flex -space-x-2 *:data-[slot=avatar]:ring-2 *:data-[slot=avatar]:grayscale">
<Avatar>
<AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
<AvatarFallback>CN</AvatarFallback>
</Avatar>
<Avatar>
<AvatarImage src="https://github.com/maxleiter.png" alt="@maxleiter" />
<AvatarFallback>LR</AvatarFallback>
</Avatar>
<Avatar>
<AvatarImage src="https://github.com/evilrabbit.png" alt="@evilrabbit" />
<AvatarFallback>ER</AvatarFallback>
</Avatar>
</div>Bu grup kalıbında -space-x-2 avatarları birbirinin üzerine bindirir; *:data-[slot=avatar]: önekli sınıflar ise yalnızca data-slot="avatar" taşıyan doğrudan çocuklara arka plan renginde bir halka (ring) ve gri tonlama uygular. Halka, üst üste binen avatarları birbirinden ayırır. alt özniteliğini her görsele vermeyi unutmayın; görselin ne olduğunu anlatan metin erişilebilirlik için gereklidir (WCAG temelleri).
Dördünü birlikte kullanmak
Bu bileşenler birbirini tamamlayacak şekilde tasarlanmıştır ve resmî örneklerde sık sık iç içe geçer: Item’ın medya alanında Avatar, Empty’nin medya alanında avatar grubu, Item ve Empty içinde Spinner, butonlarda ve ipuçlarında Kbd. Örneğin bir ekip üyeleri sayfasında, üyeler varken ItemGroup içinde avatarlı satırlar, hiç üye yokken “Henüz ekip üyesi yok” diyen ve “Üye davet et” butonu sunan bir Empty, butonun yanında da davet kısayolunu gösteren bir Kbd kullanabilirsiniz. Hepsi aynı tema değişkenlerini (--muted, --accent, --border) kullandığı için yan yana tutarlı görünürler.
Sık yapılan hatalar

- Form alanları için Item kullanmak. Belge girdiler için
Field, içerik içinItemkullanılmasını söyler. - Bağlantılı Item’ı
aetiketiyle sarmak. Doğru yol<Item asChild>içineakoymaktır; böylece üzerine gelme ve odak stilleri bağlantıya uygulanır. - Uzun açıklama yazmak.
ItemDescriptionkaynakta iki satırla sınırlıdır; fazlası kesilir. - Empty’de kesikli çerçevenin görünmemesi. Kapsayıcıda yalnızca
border-dashedvardır; çerçeve içinbordersınıfını eklemeniz gerekir. - Resmî demodaki ikon paketini kurmadan kopyalamak.
empty-demo@tabler/icons-reactkullanır; projenizde bu paket yoksa içe aktarma hata verir. - Kbd’nin kısayolu çalıştırdığını varsaymak. Kbd yalnızca görünümdür; klavye olayını ayrıca dinlemeniz gerekir.
- Avatar görseline
altvermemek. Resmî örneklerde herAvatarImagebiraltmetni taşır.
Sık Sorulan Sorular
Item bileşeni bir div’den ne farkı var?
Belgenin kendisi aynı sonucun bir div ve birkaç sınıfla da alınabileceğini kabul eder. Fark, boşluk, hizalama, odak halkası, bağlantı stilleri ve medya hizalaması gibi ayrıntıların tek bir bileşende toplanması ve varyantlarla tutarlı biçimde değiştirilebilmesidir.
Empty bileşenini tablo içinde kullanabilir miyim?
Empty bir düzen bileşenidir ve kaynakta yalnızca div öğelerinden oluşur; herhangi bir kapsayıcının içine, örneğin boş bir tablonun tek hücresine konabilir. Belge Spinner ile birlikte “işleniyor” durumu gösteren bir Empty örneği de verir.
Kbd içinde Mac tuş sembolleri kullanabilir miyim?
Evet. Resmî kbd-demo örneği ⌘, ⇧, ⌥ ve ⌃ sembollerini doğrudan metin olarak kullanır; “Ctrl” gibi yazılı tuş adları da aynı şekilde çalışır.
Avatar görseli yüklenemezse ne olur?
Bileşen, belgedeki tanımı gereği yedek içeriğe sahiptir: görsel gösterilemediğinde AvatarFallback içindeki baş harfler görünür. Bu davranışın ayrıntıları Avatar’ın dayandığı Radix UI ilkelinin belgesinde anlatılır.
Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.
İlgili içerikler: shadcn/ui öğrenme rehberi · Alert, Badge, Progress, Skeleton, Spinner · Field bileşeni · Popover ve Tooltip · Command paleti · Yenilikler ve sürüm geçmişi