Skip to main content

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

Loading diagram...

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>

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

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>

Notes

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.

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.

Motion

Use MotionItem and MotionItemGroup for staggered fade-up entrance animations powered by motion. Pass index to MotionItem for stagger delay.

API Reference

Item

The main component for displaying content with media, title, description, and actions.

PropTypeDefaultDescription
classNamestring-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
asChildbooleanfalseRender as a child element using Slot
childrenReact.ReactNode-Item content (media, content, actions, etc.)
...propsReact.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.

PropTypeDefaultDescription
classNamestring-Additional class names for the group container
childrenReact.ReactNode-Item elements to group together
...propsReact.HTMLProps<HTMLDivElement>-Additional props to spread to the content div

ItemSeparator

A horizontal separator between items in a group.

PropTypeDefaultDescription
classNamestring-Additional class names for the separator
...propsReact.ComponentPropsWithoutRef<typeof Separator>-Additional props inherited from Separator.

ItemMedia

Displays media content such as icons, images, or avatars.

PropTypeDefaultDescription
classNamestring-Additional class names for the media container
variant"default" | "icon" | "image""default"Visual variant of the media container
childrenReact.ReactNode-Media content (icon, image, avatar, etc.)
...propsReact.HTMLProps<HTMLDivElement>-Additional props to spread to the content div

ItemContent

Wraps the title and description of the item.

PropTypeDefaultDescription
classNamestring-Additional class names for the content wrapper
childrenReact.ReactNode-Title and description elements
...propsReact.HTMLProps<HTMLDivElement>-Additional props to spread to the content div

ItemTitle

Displays the title of the item.

PropTypeDefaultDescription
classNamestring-Additional class names for the title
childrenReact.ReactNode-Title text or elements
...propsReact.HTMLProps<HTMLDivElement>-Additional props to spread to the content div

ItemDescription

Displays the description of the item.

PropTypeDefaultDescription
classNamestring-Additional class names for the description
childrenReact.ReactNode-Description text or elements
...propsReact.HTMLProps<HTMLParagraphElement>-Additional props to spread to the p element

ItemActions

Displays action buttons or other interactive elements.

PropTypeDefaultDescription
classNamestring-Additional class names for the actions container
childrenReact.ReactNode-Action buttons or interactive elements
...propsReact.HTMLProps<HTMLDivElement>-Additional props to spread to the content div

ItemHeader

Displays a header spanning the full width of the item.

PropTypeDefaultDescription
classNamestring-Additional class names for the header
childrenReact.ReactNode-Header content
...propsReact.HTMLProps<HTMLDivElement>-Additional props to spread to the content div

ItemFooter

Displays a footer spanning the full width of the item.

PropTypeDefaultDescription
classNamestring-Additional class names for the footer
childrenReact.ReactNode-Footer content
...propsReact.HTMLProps<HTMLDivElement>-Additional props to spread to the content div

MotionItem

Same props as Item plus an optional index prop for stagger delay (40ms per index). Adds fadeUp entrance animation. Requires the motion package.

MotionItemGroup

Same props as ItemGroup. Adds fadeUp entrance animation. Requires the motion package.