---
type: doc
title: Item
description: A flexible container for displaying content items with various styles.
---

> Fulldev UI for Astro. The `@fulldev` registry in `components.json` points at `https://ui.full.dev/r/styles/{style}/{name}.json`; see [installation](/astro/docs/installation.md).

```astro title="src/components/examples/item/item-demo.astro"
---
import BadgeCheckIcon from "@lucide/astro/icons/badge-check"
import ChevronRightIcon from "@lucide/astro/icons/chevron-right"

import { Button } from "@/components/ui/button"
import {
  Item,
  ItemActions,
  ItemContent,
  ItemDescription,
  ItemMedia,
  ItemTitle,
} from "@/components/ui/item"
---

<div class="flex w-full max-w-md flex-col gap-6">
  <Item variant="outline">
    <ItemContent>
      <ItemTitle>Basic Item</ItemTitle>
      <ItemDescription>
        A simple item with title and description.
      </ItemDescription>
    </ItemContent>
    <ItemActions>
      <Button variant="outline" size="sm">
        Action
      </Button>
    </ItemActions>
  </Item>
  <Item variant="outline" size="sm" href="#">
    <ItemMedia>
      <BadgeCheckIcon class="size-5" />
    </ItemMedia>
    <ItemContent>
      <ItemTitle>Your profile has been verified.</ItemTitle>
    </ItemContent>
    <ItemActions>
      <ChevronRightIcon class="size-4" />
    </ItemActions>
  </Item>
</div>
```

## Installation

```bash
npx shadcn@latest add @fulldev/item
```

## Usage

```ts
import {
  Item,
  ItemActions,
  ItemContent,
  ItemDescription,
  ItemMedia,
  ItemTitle,
} from "@/components/ui/item"
```

```astro
<Item>
  <ItemMedia variant="icon">
    <InboxIcon />
  </ItemMedia>
  <ItemContent>
    <ItemTitle>Title</ItemTitle>
    <ItemDescription>Description</ItemDescription>
  </ItemContent>
  <ItemActions>
    <Button>Action</Button>
  </ItemActions>
</Item>
```

## Composition

```text
ItemGroup
└── Item
    ├── ItemHeader
    ├── ItemMedia
    ├── ItemContent
    │   ├── ItemTitle
    │   └── ItemDescription
    ├── ItemActions
    └── ItemFooter
```

## Item vs Field

Use `Field` for a form input such as a checkbox, input, radio or select. Use
`Item` to display content such as a title, description and actions.

## Variant

Use the `variant` prop to change the visual style of the item.

```astro title="src/components/examples/item/item-variant.astro"
---
import InboxIcon from "@lucide/astro/icons/inbox"

import {
  Item,
  ItemContent,
  ItemDescription,
  ItemMedia,
  ItemTitle,
} from "@/components/ui/item"
---

<div class="flex w-full max-w-md flex-col gap-6">
  <Item>
    <ItemMedia variant="icon">
      <InboxIcon />
    </ItemMedia>
    <ItemContent>
      <ItemTitle>Default Variant</ItemTitle>
      <ItemDescription>Transparent background with no border.</ItemDescription>
    </ItemContent>
  </Item>
  <Item variant="outline">
    <ItemMedia variant="icon">
      <InboxIcon />
    </ItemMedia>
    <ItemContent>
      <ItemTitle>Outline Variant</ItemTitle>
      <ItemDescription>Outlined style with a visible border.</ItemDescription>
    </ItemContent>
  </Item>
  <Item variant="muted">
    <ItemMedia variant="icon">
      <InboxIcon />
    </ItemMedia>
    <ItemContent>
      <ItemTitle>Muted Variant</ItemTitle>
      <ItemDescription>Muted background for secondary content.</ItemDescription>
    </ItemContent>
  </Item>
</div>
```

## Size

Use the `size` prop to change the size of the item: `default`, `sm` or `xs`.

```astro title="src/components/examples/item/item-size.astro"
---
import InboxIcon from "@lucide/astro/icons/inbox"

import {
  Item,
  ItemContent,
  ItemDescription,
  ItemMedia,
  ItemTitle,
} from "@/components/ui/item"
---

<div class="flex w-full max-w-md flex-col gap-6">
  <Item variant="outline">
    <ItemMedia variant="icon">
      <InboxIcon />
    </ItemMedia>
    <ItemContent>
      <ItemTitle>Default Size</ItemTitle>
      <ItemDescription>The standard size for most use cases.</ItemDescription>
    </ItemContent>
  </Item>
  <Item variant="outline" size="sm">
    <ItemMedia variant="icon">
      <InboxIcon />
    </ItemMedia>
    <ItemContent>
      <ItemTitle>Small Size</ItemTitle>
      <ItemDescription>A compact size for dense layouts.</ItemDescription>
    </ItemContent>
  </Item>
  <Item variant="outline" size="xs">
    <ItemMedia variant="icon">
      <InboxIcon />
    </ItemMedia>
    <ItemContent>
      <ItemTitle>Extra Small Size</ItemTitle>
      <ItemDescription>The most compact size available.</ItemDescription>
    </ItemContent>
  </Item>
</div>
```

## Icon

Use `ItemMedia` with `variant="icon"` to display an icon.

```astro title="src/components/examples/item/item-icon.astro"
---
import ShieldAlertIcon from "@lucide/astro/icons/shield-alert"

import { Button } from "@/components/ui/button"
import {
  Item,
  ItemActions,
  ItemContent,
  ItemDescription,
  ItemMedia,
  ItemTitle,
} from "@/components/ui/item"
---

<div class="flex w-full max-w-lg flex-col gap-6">
  <Item variant="outline">
    <ItemMedia variant="icon">
      <ShieldAlertIcon />
    </ItemMedia>
    <ItemContent>
      <ItemTitle>Security Alert</ItemTitle>
      <ItemDescription>New login detected from unknown device.</ItemDescription>
    </ItemContent>
    <ItemActions>
      <Button size="sm" variant="outline">
        Review
      </Button>
    </ItemActions>
  </Item>
</div>
```

## Avatar

```astro title="src/components/examples/item/item-avatar.astro"
---
import Plus from "@lucide/astro/icons/plus"

import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
import { Button } from "@/components/ui/button"
import {
  Item,
  ItemActions,
  ItemContent,
  ItemDescription,
  ItemMedia,
  ItemTitle,
} from "@/components/ui/item"
---

<div class="flex w-full max-w-lg flex-col gap-6">
  <Item variant="outline">
    <ItemMedia>
      <Avatar class="size-10">
        <AvatarImage src="https://github.com/evilrabbit.png" />
        <AvatarFallback>ER</AvatarFallback>
      </Avatar>
    </ItemMedia>
    <ItemContent>
      <ItemTitle>Evil Rabbit</ItemTitle>
      <ItemDescription>Last seen 5 months ago</ItemDescription>
    </ItemContent>
    <ItemActions>
      <Button
        size="icon-sm"
        variant="outline"
        class="rounded-full"
        aria-label="Invite"
      >
        <Plus />
      </Button>
    </ItemActions>
  </Item>
  <Item variant="outline">
    <ItemMedia>
      <div class="flex -space-x-2 *:data-[slot=avatar]:ring-2 *:data-[slot=avatar]:ring-background *:data-[slot=avatar]:grayscale">
        <Avatar class="hidden sm:flex">
          <AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
          <AvatarFallback>CN</AvatarFallback>
        </Avatar>
        <Avatar class="hidden sm:flex">
          <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>
    </ItemMedia>
    <ItemContent>
      <ItemTitle>No Team Members</ItemTitle>
      <ItemDescription>
        Invite your team to collaborate on this project.
      </ItemDescription>
    </ItemContent>
    <ItemActions>
      <Button size="sm" variant="outline">
        Invite
      </Button>
    </ItemActions>
  </Item>
</div>
```

## Image

Use `ItemMedia` with `variant="image"` to display an image.

```astro title="src/components/examples/item/item-image.astro"
---
import {
  Item,
  ItemContent,
  ItemDescription,
  ItemGroup,
  ItemMedia,
  ItemTitle,
} from "@/components/ui/item"

const music = [
  {
    title: "Midnight City Lights",
    artist: "Neon Dreams",
    album: "Electric Nights",
    duration: "3:45",
  },
  {
    title: "Coffee Shop Conversations",
    artist: "The Morning Brew",
    album: "Urban Stories",
    duration: "4:05",
  },
  {
    title: "Digital Rain",
    artist: "Cyber Symphony",
    album: "Binary Beats",
    duration: "3:30",
  },
]
---

<div class="flex w-full max-w-md flex-col gap-6">
  <ItemGroup class="gap-4">
    {music.map((song) => (
      <Item variant="outline" href="#" role="listitem">
        <ItemMedia variant="image">
          <img
            src={`https://avatar.vercel.sh/${song.title}`}
            alt={song.title}
            width={32}
            height={32}
            class="object-cover grayscale"
          />
        </ItemMedia>
        <ItemContent>
          <ItemTitle class="line-clamp-1">
            {song.title} -{" "}
            <span class="text-muted-foreground">{song.album}</span>
          </ItemTitle>
          <ItemDescription>{song.artist}</ItemDescription>
        </ItemContent>
        <ItemContent class="flex-none text-center">
          <ItemDescription>{song.duration}</ItemDescription>
        </ItemContent>
      </Item>
    ))}
  </ItemGroup>
</div>
```

## Group

Use `ItemGroup` to group related items together.

```astro title="src/components/examples/item/item-group.astro"
---
import PlusIcon from "@lucide/astro/icons/plus"

import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
import { Button } from "@/components/ui/button"
import {
  Item,
  ItemActions,
  ItemContent,
  ItemDescription,
  ItemGroup,
  ItemMedia,
  ItemTitle,
} from "@/components/ui/item"

const people = [
  {
    username: "shadcn",
    avatar: "https://github.com/shadcn.png",
    email: "shadcn@vercel.com",
  },
  {
    username: "maxleiter",
    avatar: "https://github.com/maxleiter.png",
    email: "maxleiter@vercel.com",
  },
  {
    username: "evilrabbit",
    avatar: "https://github.com/evilrabbit.png",
    email: "evilrabbit@vercel.com",
  },
]
---

<ItemGroup class="max-w-sm">
  {people.map((person) => (
    <Item variant="outline">
      <ItemMedia>
        <Avatar>
          <AvatarImage src={person.avatar} class="grayscale" />
          <AvatarFallback>{person.username.charAt(0)}</AvatarFallback>
        </Avatar>
      </ItemMedia>
      <ItemContent class="gap-1">
        <ItemTitle>{person.username}</ItemTitle>
        <ItemDescription>{person.email}</ItemDescription>
      </ItemContent>
      <ItemActions>
        <Button variant="ghost" size="icon" class="rounded-full">
          <PlusIcon />
        </Button>
      </ItemActions>
    </Item>
  ))}
</ItemGroup>
```

## Header

Use `ItemHeader` to add a header above the item content.

```astro title="src/components/examples/item/item-header.astro"
---
import {
  Item,
  ItemContent,
  ItemDescription,
  ItemGroup,
  ItemHeader,
  ItemTitle,
} from "@/components/ui/item"

const models = [
  {
    name: "v0-1.5-sm",
    description: "Everyday tasks and UI generation.",
    image:
      "https://images.unsplash.com/photo-1650804068570-7fb2e3dbf888?q=80&w=640&auto=format&fit=crop",
    credit: "Valeria Reverdo on Unsplash",
  },
  {
    name: "v0-1.5-lg",
    description: "Advanced thinking or reasoning.",
    image:
      "https://images.unsplash.com/photo-1610280777472-54133d004c8c?q=80&w=640&auto=format&fit=crop",
    credit: "Michael Oeser on Unsplash",
  },
  {
    name: "v0-2.0-mini",
    description: "Open Source model for everyone.",
    image:
      "https://images.unsplash.com/photo-1602146057681-08560aee8cde?q=80&w=640&auto=format&fit=crop",
    credit: "Cherry Laithang on Unsplash",
  },
]
---

<div class="flex w-full max-w-xl flex-col gap-6">
  <ItemGroup class="grid grid-cols-3 gap-4">
    {models.map((model) => (
      <Item variant="outline">
        <ItemHeader>
          <img
            src={model.image}
            alt={model.name}
            width={128}
            height={128}
            class="aspect-square w-full rounded-sm object-cover"
          />
        </ItemHeader>
        <ItemContent>
          <ItemTitle>{model.name}</ItemTitle>
          <ItemDescription>{model.description}</ItemDescription>
        </ItemContent>
      </Item>
    ))}
  </ItemGroup>
</div>
```

## Link

Pass `href` to render the item as an `a`. The hover and focus states apply to
the link.

```astro title="src/components/examples/item/item-link.astro"
---
import ChevronRightIcon from "@lucide/astro/icons/chevron-right"
import ExternalLinkIcon from "@lucide/astro/icons/external-link"

import {
  Item,
  ItemActions,
  ItemContent,
  ItemDescription,
  ItemTitle,
} from "@/components/ui/item"
---

<div class="flex w-full max-w-md flex-col gap-4">
  <Item href="#">
    <ItemContent>
      <ItemTitle>Visit our documentation</ItemTitle>
      <ItemDescription>
        Learn how to get started with our components.
      </ItemDescription>
    </ItemContent>
    <ItemActions>
      <ChevronRightIcon class="size-4" />
    </ItemActions>
  </Item>
  <Item variant="outline" href="#" target="_blank" rel="noopener noreferrer">
    <ItemContent>
      <ItemTitle>External resource</ItemTitle>
      <ItemDescription>
        Opens in a new tab with security attributes.
      </ItemDescription>
    </ItemContent>
    <ItemActions>
      <ExternalLinkIcon class="size-4" />
    </ItemActions>
  </Item>
</div>
```

## Dropdown

```astro title="src/components/examples/item/item-dropdown.astro"
---
import ChevronDownIcon from "@lucide/astro/icons/chevron-down"

import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
import { buttonVariants } from "@/components/ui/button"
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuGroup,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
import {
  Item,
  ItemContent,
  ItemDescription,
  ItemMedia,
  ItemTitle,
} from "@/components/ui/item"

const people = [
  {
    username: "shadcn",
    avatar: "https://github.com/shadcn.png",
    email: "shadcn@vercel.com",
  },
  {
    username: "maxleiter",
    avatar: "https://github.com/maxleiter.png",
    email: "maxleiter@vercel.com",
  },
  {
    username: "evilrabbit",
    avatar: "https://github.com/evilrabbit.png",
    email: "evilrabbit@vercel.com",
  },
]
---

<DropdownMenu>
  <DropdownMenuTrigger class={buttonVariants({ variant: "outline" })}>
    Select <ChevronDownIcon />
  </DropdownMenuTrigger>
  <DropdownMenuContent class="w-48" align="end">
    <DropdownMenuGroup>
      {people.map((person) => (
        <DropdownMenuItem as="div">
          <Item size="xs" class="w-full p-2">
            <ItemMedia>
              <Avatar class="size-[--spacing(6.5)]">
                <AvatarImage src={person.avatar} class="grayscale" />
                <AvatarFallback>{person.username.charAt(0)}</AvatarFallback>
              </Avatar>
            </ItemMedia>
            <ItemContent class="gap-0">
              <ItemTitle>{person.username}</ItemTitle>
              <ItemDescription class="leading-none">
                {person.email}
              </ItemDescription>
            </ItemContent>
          </Item>
        </DropdownMenuItem>
      ))}
    </DropdownMenuGroup>
  </DropdownMenuContent>
</DropdownMenu>
```

## RTL

```astro title="src/components/examples/item/item-rtl.astro"
---
import BadgeCheckIcon from "@lucide/astro/icons/badge-check"
import ChevronRightIcon from "@lucide/astro/icons/chevron-right"

import { Button } from "@/components/ui/button"
import {
  Item,
  ItemActions,
  ItemContent,
  ItemDescription,
  ItemMedia,
  ItemTitle,
} from "@/components/ui/item"

const translations = {
  en: {
    dir: "ltr",
    values: {
      basicItem: "Basic Item",
      basicItemDesc: "A simple item with title and description.",
      action: "Action",
      verifiedTitle: "Your profile has been verified.",
    },
  },
  ar: {
    dir: "rtl",
    values: {
      basicItem: "عنصر أساسي",
      basicItemDesc: "عنصر بسيط يحتوي على عنوان ووصف.",
      action: "إجراء",
      verifiedTitle: "تم التحقق من ملفك الشخصي.",
    },
  },
  he: {
    dir: "rtl",
    values: {
      basicItem: "פריט בסיסי",
      basicItemDesc: "פריט פשוט עם כותרת ותיאור.",
      action: "פעולה",
      verifiedTitle: "הפרופיל שלך אומת.",
    },
  },
} as const

const { dir, values: t } = translations.ar
---

<div class="flex w-full max-w-md flex-col gap-6" dir={dir}>
  <Item variant="outline" dir={dir}>
    <ItemContent>
      <ItemTitle>{t.basicItem}</ItemTitle>
      <ItemDescription>{t.basicItemDesc}</ItemDescription>
    </ItemContent>
    <ItemActions>
      <Button variant="outline" size="sm">
        {t.action}
      </Button>
    </ItemActions>
  </Item>
  <Item variant="outline" size="sm" href="#" dir={dir}>
    <ItemMedia>
      <BadgeCheckIcon class="size-5" />
    </ItemMedia>
    <ItemContent>
      <ItemTitle>{t.verifiedTitle}</ItemTitle>
    </ItemContent>
    <ItemActions>
      <ChevronRightIcon class="size-4" />
    </ItemActions>
  </Item>
</div>
```

## API Reference

Source: [`src/components/ui/item`](https://github.com/fulldotdev/ui/tree/main/src/components/ui/item)

### Item

| Prop      | Type                                | Default     |
| --------- | ----------------------------------- | ----------- |
| `variant` | `"default" \| "outline" \| "muted"` | `"default"` |
| `size`    | `"default" \| "sm" \| "xs"`         | `"default"` |
| `href`    | `string`                            |             |

`Item` renders a `div`, or an `a` when you pass `href`. It writes `data-variant`
and `data-size`. `ItemGroup` renders a `div` with `role="list"`.

### ItemMedia

| Prop      | Type                             | Default     |
| --------- | -------------------------------- | ----------- |
| `variant` | `"default" \| "icon" \| "image"` | `"default"` |

## Install what this page shows

```bash
npx shadcn@latest add @fulldev/item-examples
```
