item
A component for displaying content with media, title, description, and actions.
The Item component is a straightforward flex container that can house nearly any type of content. Use it to display a title, description, and actions. Group it with the ItemGroup component to create a list of items.
You can pretty much achieve the same result with the div element and some classes, but I've built this so many times that I decided to create a component for it. Now I use it all the time.
Philosophy
The Item component is a universal list entry primitive. Rather than building separate list-item variants for every context (settings, menus, selections), Item provides a flexible container with consistent spacing, alignment, and interactive states. It's the atoms-level building block that higher-level components compose upon.
How It's Built
Installation
npx @gentleduck/cli add item
npx @gentleduck/cli add item
Usage
import {
Item,
ItemActions,
ItemContent,
ItemDescription,
ItemFooter,
ItemHeader,
ItemMedia,
ItemTitle,
} from "@/components/ui/item"import {
Item,
ItemActions,
ItemContent,
ItemDescription,
ItemFooter,
ItemHeader,
ItemMedia,
ItemTitle,
} from "@/components/ui/item"<Item>
<ItemHeader>Item Header</ItemHeader>
<ItemMedia />
<ItemContent>
<ItemTitle>Item</ItemTitle>
<ItemDescription>Item</ItemDescription>
</ItemContent>
<ItemActions />
<ItemFooter>Item Footer</ItemFooter>
</Item><Item>
<ItemHeader>Item Header</ItemHeader>
<ItemMedia />
<ItemContent>
<ItemTitle>Item</ItemTitle>
<ItemDescription>Item</ItemDescription>
</ItemContent>
<ItemActions />
<ItemFooter>Item Footer</ItemFooter>
</Item>Item vs Field
Use Field if you need to display a form input such as a checkbox, input, radio, or select.
If you only need to display content such as a title, description, and actions, use Item.
Examples
Variants
Size
The Item component has different sizes for different use cases. For example, you can use the sm size for a compact item or the default size for a standard item.
Icon
Avatar
Image
Group
Header
Link
To render an item as a link, use the asChild prop. The hover and focus states will be applied to the anchor element.
<Item asChild>
<a href="/dashboard">
<ItemMedia />
<ItemContent>
<ItemTitle>Dashboard</ItemTitle>
<ItemDescription>Overview of your account and activity.</ItemDescription>
</ItemContent>
<ItemActions />
</a>
</Item><Item asChild>
<a href="/dashboard">
<ItemMedia />
<ItemContent>
<ItemTitle>Dashboard</ItemTitle>
<ItemDescription>Overview of your account and activity.</ItemDescription>
</ItemContent>
<ItemActions />
</a>
</Item>Dropdown
API Reference
Item
The main component for displaying content with media, title, description, and actions.
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | -- | Additional class names for the item container |
variant | "default" | "muted" | "outline" | "default" | Visual variant of the item |
size | "default" | "sm" | "default" | Size of the item |
asChild | boolean | false | Render as a child element using Slot |
children | React.ReactNode | -- | Item content (media, content, actions, etc.) |
...props | React.HTMLProps<HTMLDivElement> | -- | Additional props to spread to the content div |
You can use the asChild prop to render a custom component as the item, for example a link. The hover and focus states will be applied to the custom component.
import {
Item,
ItemContent,
ItemDescription,
ItemMedia,
ItemTitle,
} from "@/components/ui/item"
export function ItemLink() {
return (
<Item asChild>
<a href="/dashboard">
<ItemMedia variant="icon">
<Home />
</ItemMedia>
<ItemContent>
<ItemTitle>Dashboard</ItemTitle>
<ItemDescription>
Overview of your account and activity.
</ItemDescription>
</ItemContent>
</a>
</Item>
)
}import {
Item,
ItemContent,
ItemDescription,
ItemMedia,
ItemTitle,
} from "@/components/ui/item"
export function ItemLink() {
return (
<Item asChild>
<a href="/dashboard">
<ItemMedia variant="icon">
<Home />
</ItemMedia>
<ItemContent>
<ItemTitle>Dashboard</ItemTitle>
<ItemDescription>
Overview of your account and activity.
</ItemDescription>
</ItemContent>
</a>
</Item>
)
}ItemGroup
A container that groups related items together with consistent styling.
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | -- | Additional class names for the group container |
children | React.ReactNode | -- | Item elements to group together |
...props | React.HTMLProps<HTMLDivElement> | -- | Additional props to spread to the content div |
ItemSeparator
A horizontal separator between items in a group.
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | -- | Additional class names for the separator |
...props | React.ComponentPropsWithoutRef<typeof Separator> | -- | Additional props inherited from Separator. |
ItemMedia
Displays media content such as icons, images, or avatars.
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | -- | Additional class names for the media container |
variant | "default" | "icon" | "image" | "default" | Visual variant of the media container |
children | React.ReactNode | -- | Media content (icon, image, avatar, etc.) |
...props | React.HTMLProps<HTMLDivElement> | -- | Additional props to spread to the content div |
ItemContent
Wraps the title and description of the item.
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | -- | Additional class names for the content wrapper |
children | React.ReactNode | -- | Title and description elements |
...props | React.HTMLProps<HTMLDivElement> | -- | Additional props to spread to the content div |
ItemTitle
Displays the title of the item.
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | -- | Additional class names for the title |
children | React.ReactNode | -- | Title text or elements |
...props | React.HTMLProps<HTMLDivElement> | -- | Additional props to spread to the content div |
ItemDescription
Displays the description of the item.
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | -- | Additional class names for the description |
children | React.ReactNode | -- | Description text or elements |
...props | React.HTMLProps<HTMLParagraphElement> | -- | Additional props to spread to the p element |
ItemActions
Displays action buttons or other interactive elements.
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | -- | Additional class names for the actions container |
children | React.ReactNode | -- | Action buttons or interactive elements |
...props | React.HTMLProps<HTMLDivElement> | -- | Additional props to spread to the content div |
ItemHeader
Displays a header spanning the full width of the item.
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | -- | Additional class names for the header |
children | React.ReactNode | -- | Header content |
...props | React.HTMLProps<HTMLDivElement> | -- | Additional props to spread to the content div |
ItemFooter
Displays a footer spanning the full width of the item.
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | -- | Additional class names for the footer |
children | React.ReactNode | -- | Footer content |
...props | React.HTMLProps<HTMLDivElement> | -- | Additional props to spread to the content div |
RTL Support
Direction is resolved through the shared primitives direction module. Use a local dir="rtl" override when the component exposes it, or set DirectionProvider at app/root level for global RTL/LTR behavior.