Skip to content

Now in the official shadcn registry directory.

Start free

Item

A list and row primitive with 3 variants and 2 sizes, composed from media, content, title, description and actions parts, grouped with separators.

displaylayout
A free styled version is available
Billing

Visa ending in 4242

Notifications

Weekly product digest

Installation

Run the following command

npx shadcn@latest add @ai2/item

Dependencies, the @ai2/separator component used by ItemSeparator, the @ai2/tokens theme and the component file are installed together.

Usage

TS
import {
  Item,
  ItemActions,
  ItemContent,
  ItemDescription,
  ItemMedia,
  ItemTitle,
} from "@/components/ui/item"
import { CreditCard } from "lucide-react"

<Item variant="outline">
  <ItemMedia variant="icon">
    <CreditCard />
  </ItemMedia>
  <ItemContent>
    <ItemTitle>Billing</ItemTitle>
    <ItemDescription>Visa ending in 4242</ItemDescription>
  </ItemContent>
  <ItemActions>
    <Button variant="outline" size="sm">Manage</Button>
  </ItemActions>
</Item>

Every part is optional. Compose a row from the parts you need, then wrap several rows in an ItemGroup with ItemSeparator between them to build a list.

Examples

Variants

Default

Transparent surface.

Outline

Bordered standalone row.

Muted

Soft filled surface.

Sizes

Default size

Comfortable gap and padding.

Small size

Compact rows for dense lists.

Media

Icon media

A small bordered muted tile.

Image media

A rounded box clipping an image.

Group with separators

Billing

Visa ending in 4242

Notifications

Weekly product digest

With asChild, pass exactly one child element and put every row part inside it, so Radix Slot has a single node to merge the row styling onto.

Props

These axes live on the root Item.

PropTypeDefaultDescription
variant"default" | "outline" | "muted""default"Surface treatment on the row: transparent, bordered, or a soft muted fill.
size"default" | "sm""default"Row density. default uses gap-4 with p-4; sm tightens to gap-2.5 with px-4 py-3.
asChildbooleanfalseMerge the row styling onto the single child element (for example an a tag) via Radix Slot, so the whole row becomes one link or button.

ItemMedia carries its own variant axis. The remaining parts (ItemGroup, ItemContent, ItemTitle, ItemDescription, ItemActions, ItemHeader and ItemFooter) are plain wrappers, and ItemSeparator forwards to the ai2 Separator.

PropTypeDefaultDescription
variant"default" | "icon" | "image""default"Media treatment on ItemMedia. default is a transparent wrapper, icon is a small bordered muted tile, and image is a larger rounded box that clips an img to cover.

ai2 Item: a list and row primitive for React

The ai2 Item is a shadcn-compatible row primitive for React, styled with Tailwind CSS v4 on top of the shared ai2 token file. It is the building block for settings lists, notification feeds, file rows, command results and any horizontal row that pairs a piece of media with a title, a description and a set of actions.

Because it ships through the shadcn registry format, you install it with one CLI command, an MCP agent, or a copy-paste, and the source lands in your own project. You own the file; there is no runtime dependency on ai2 itself. The live example above is the exact component you get.

What is the ai2 Item?

It is a composition of ten parts. The row itself is Item, and it holds ItemMedia, ItemContent (which wraps ItemTitle and ItemDescription), ItemActions, plus ItemHeader and ItemFooter for full-width rows above and below the main content.

To build a list, wrap rows in ItemGroup and divide them with ItemSeparator, which is the ai2 Separator preset for zero vertical margin. The root carries two cva axes, variant and size, and asChild turns the whole row into a single link or button.

Why use it

  • Three surface variants: default is transparent for rows inside a bordered group, outline draws a border around a standalone row, and muted gives a soft filled surface.
  • Two density sizes: size="default" uses gap-4 and p-4 for comfortable rows; size="sm" tightens to gap-2.5 with px-4 py-3 for compact lists.
  • Three media treatments: ItemMedia offers default (transparent), icon (a small bordered tile) and image (a larger rounded box that clips an image to cover).
  • Groups and separators: ItemGroup lays out a role="list" column and ItemSeparator adds a flush divider, so a full settings list is a group of rows with separators between them.
  • Whole-row links: asChild merges the row onto an a or button element through Radix Slot, so the entire row is one accessible click target with hover styling.
  • Agent-readable metadata: The registry item describes the variant matrix and every part in plain words, so an MCP agent can find, inspect and install it without guessing.

Features

  • shadcn registry install: One command adds the component, the @ai2/separator dependency and the @ai2/tokens theme to your project.
  • Description-aware media: When a row has an ItemDescription, ItemMedia nudges to the top and self-aligns, so the media lines up with the title on multi-line rows.
  • Icon and remixicon compatible: The icon media tile sizes a lucide <svg> and a remixicon <i> child the same way, so it works with either icon family.
  • Focus ring on interactive rows: The row carries a focus-visible ring, so a row turned into a link or button through asChild is keyboard-accessible out of the box.
  • Data attributes for styling: The row exposes data-slot="item", data-variant and data-size, and every part has its own data-slot, so CSS overrides can target exact regions.
  • Exported cva functions: itemVariants and itemMediaVariants are exported, so you can reuse the row and media treatments on other elements.

Production tips

  • Use default inside a group: Rows in an ItemGroup usually want variant="default" so the group border and separators do the framing. Reserve outline for a single standalone row.
  • Match size to the list: Dense settings and command lists read best with size="sm"; the default size fits primary content rows and cards.
  • Reach for asChild for navigation: When a whole row should navigate, wrap a single a tag with asChild rather than nesting a stretched link, so the row itself is the click target.
  • Keep exactly one child under asChild: Radix Slot needs a single element child, so put all row parts inside the one a or button you pass, not as siblings of it.
  • Put secondary actions in ItemActions: ItemActions is a right-aligned flex row with a small gap, made for buttons or an icon menu, so every row in a list keeps the same rhythm.

Works with the rest of ai2

Item is a host for the rest of the registry. Drop an ai2 Avatar into the image media slot, a ai2 Badge next to the title, and ai2 Button or a ai2 Dropdown Menu into the actions slot.

The row divider reuses the ai2 Separator, and when a list has nothing to show, swap it for an ai2 Empty state. Everything shares one token source, so any combination stays consistent in both light and dark mode.

FAQs

Get new components in your inbox

Component drops, new themes and release notes. No spam, and you can unsubscribe from any email.

© 2026 ai2 design system · MIT licensed · Built with its own components