Item

A flexible row primitive for lists, menus, and settings — media, title, description, and actions in one composable layout.

Email notifications
Payment method
<VStack gap={4}>  <Item>    <ItemMedia variant="icon">      <Bell />    </ItemMedia>    <ItemContent>      <ItemTitle>Email notifications</ItemTitle>      <ItemDescription>Statements, alerts, and approval requests.</ItemDescription>    </ItemContent>    <ItemActions>      <Switch defaultChecked />    </ItemActions>  </Item>  <Item>    <ItemMedia variant="icon">      <CreditCard />    </ItemMedia>    <ItemContent>      <ItemTitle>Payment method</ItemTitle>      <ItemDescription>Business current account · •••• 4291</ItemDescription>    </ItemContent>    <ItemActions>      <Button variant="outline" size="sm">Update</Button>    </ItemActions>  </Item></VStack>

Usage

import {
  Item,
  ItemActions,
  ItemContent,
  ItemDescription,
  ItemFooter,
  ItemHeader,
  ItemMedia,
  ItemTitle,
} from "@reva/ui";

Item is the system's general-purpose row. Compose it from a leading ItemMedia (icon, avatar, or image), an ItemContent block (ItemTitle + ItemDescription), and trailing ItemActions — then stack rows in a VStack, with a Separator between them when you want a divider. Reva re-exports the shadcn compound API; every subcomponent carries a data-slot for styling hooks.

Reach for Item before bending Alert or Card

Any labelled row — a settings toggle, a notification, a connected account, a team member, a file, a menu entry, a navigable link — is an Item. Don't restyle an Alert (which is for transient status messages) or hand-roll a Card + flex div to get this shape.

Keep buttons inside ItemActions at size="sm" (or xs in xs rows) — the default Button is too tall for a row and unbalances it.

Composition

Use the following composition to build an Item, then stack rows in a VStack with a Separator between them when you want a divider:

Item
├── ItemHeader        (optional, full-width strip on top)
├── ItemMedia         (icon · avatar · image)
├── ItemContent
│   ├── ItemTitle
│   └── ItemDescription
├── ItemActions       (Button size="sm", Switch, DropdownMenu, …)
└── ItemFooter        (optional, full-width strip on bottom)

Examples

Variants

default carries a subtle fill — the common row inside a list — muted a stronger fill for secondary content, outline draws a border (standalone row), and plain is transparent (sits flush, no fill).

plain
default
muted
outline
{/* variant: "plain" | "default" | "muted" | "outline" */}<Item variant="outline">  <ItemMedia variant="icon">    <ShieldCheck />  </ItemMedia>  <ItemContent>    <ItemTitle>Outline</ItemTitle>    <ItemDescription>A visible border — reads as a standalone row.</ItemDescription>  </ItemContent>  <ItemActions>    <Button variant="outline" size="sm">Manage</Button>  </ItemActions></Item>

Sizes

default, sm, and xs tighten gap and padding for denser layouts. Match the surrounding VStack gap to the row size when you stack them.

Statement ready
Statement ready
Statement ready
{/* size: "default" | "sm" | "xs" — match the button size to the row */}<Item size="xs">  <ItemMedia variant="icon">    <Bell />  </ItemMedia>  <ItemContent>    <ItemTitle>Statement ready</ItemTitle>    <ItemDescription>size="xs"</ItemDescription>  </ItemContent>  <ItemActions>    <Button variant="outline" size="xs">View</Button>  </ItemActions></Item>

Icon

ItemMedia variant="icon" sizes any Phosphor icon to the row and aligns it to the title.

Two-factor authentication
<Item>  <ItemMedia variant="icon">    <ShieldCheck />  </ItemMedia>  <ItemContent>    <ItemTitle>Two-factor authentication</ItemTitle>    <ItemDescription>Add a second step when signing in to keep the account secure.</ItemDescription>  </ItemContent>  <ItemActions>    <Button size="sm">Enable</Button>  </ItemActions></Item>

Avatar

Drop an Avatar into a plain ItemMedia for people rows.

AW
Anna Whitfield
<Item>  <ItemMedia>    <Avatar>      <AvatarFallback>AW</AvatarFallback>    </Avatar>  </ItemMedia>  <ItemContent>    <ItemTitle>Anna Whitfield</ItemTitle>    <ItemDescription>Relationship manager · Whitfield Wealth</ItemDescription>  </ItemContent>  <ItemActions>    <Button variant="outline" size="sm">Message</Button>  </ItemActions></Item>

Image

ItemMedia variant="image" clips a thumbnail to a rounded square that tracks the item size.

Q3 portfolio review
<Item>  <ItemMedia variant="image">    <img src={thumbnail} alt="" />  </ItemMedia>  <ItemContent>    <ItemTitle>Q3 portfolio review</ItemTitle>    <ItemDescription>PDF · 2.4 MB · Updated 25 Dec 2025</ItemDescription>  </ItemContent>  <ItemActions>    <Button variant="outline" size="sm">Open</Button>  </ItemActions></Item>

Group

Stack rows in a VStack and divide them with Separator. Here the container carries the border so the items read as one contained list.

AW
Anna Whitfield
JO
James Okafor
PL
Priya Lakshmi
<VStack gap={0} className="rounded-md border">  <Item variant="plain">    <ItemMedia>      <Avatar>        <AvatarFallback>AW</AvatarFallback>      </Avatar>    </ItemMedia>    <ItemContent>      <ItemTitle>Anna Whitfield</ItemTitle>      <ItemDescription>Relationship manager</ItemDescription>    </ItemContent>    <ItemActions>      <Button variant="ghost" size="sm">View</Button>    </ItemActions>  </Item>  <Separator />  {/* …more items… */}</VStack>

ItemHeader and ItemFooter are full-width strips that wrap above and below the body — useful for a label + badge on top and metadata + action on the bottom.

Investment mandate
Awaiting signature

Drafted 25 Dec 2025

<Item variant="outline">  <ItemHeader>    <ItemTitle>Investment mandate</ItemTitle>    <Badge variant="subtle" intent="neutral">Awaiting signature</Badge>  </ItemHeader>  <ItemContent>    <ItemDescription>The Vasquez household mandate is ready for the client to review and sign.</ItemDescription>  </ItemContent>  <ItemFooter>    <Text size="sm" color="muted-foreground">Drafted 25 Dec 2025</Text>    <Button size="sm">Send for signature</Button>  </ItemFooter></Item>

Pass asChild and wrap an anchor (or your router's Link) to make the whole row navigable — it picks up a hover background automatically. The groups below repeat the same two rows across every variant so you can compare the rest and hover states.

{/* asChild → navigable row; swap variant to compare: plain | default | muted | outline */}<VStack gap={2}>  <Item asChild variant="default">    <a href="/settings">      <ItemMedia variant="icon">        <Gear />      </ItemMedia>      <ItemContent>        <ItemTitle>Account settings</ItemTitle>        <ItemDescription>Profile, security, and notifications.</ItemDescription>      </ItemContent>      <ItemActions>        <CaretRight className="size-4 text-fg-muted" />      </ItemActions>    </a>  </Item>  <Item asChild variant="default">    <a href="/team">      <ItemMedia variant="icon">        <Users />      </ItemMedia>      <ItemContent>        <ItemTitle>Team & access</ItemTitle>        <ItemDescription>Invite colleagues and manage roles.</ItemDescription>      </ItemContent>      <ItemActions>        <CaretRight className="size-4 text-fg-muted" />      </ItemActions>    </a>  </Item></VStack>

Put a DropdownMenu in ItemActions for per-row overflow actions. Use an IconButton trigger so the row stays compact.

Business current account
<Item>  <ItemMedia variant="icon">    <CreditCard />  </ItemMedia>  <ItemContent>    <ItemTitle>Business current account</ItemTitle>    <ItemDescription>•••• 4291 · Primary</ItemDescription>  </ItemContent>  <ItemActions>    <DropdownMenu>      <DropdownMenuTrigger asChild>        <IconButton variant="ghost" size="sm" aria-label="Account actions">          <DotsThreeVertical />        </IconButton>      </DropdownMenuTrigger>      <DropdownMenuContent align="end">        <DropdownMenuLabel>Account</DropdownMenuLabel>        <DropdownMenuItem><PencilSimple />Edit details</DropdownMenuItem>        <DropdownMenuItem><SealCheck />Set as default</DropdownMenuItem>        <DropdownMenuSeparator />        <DropdownMenuItem variant="destructive"><Trash />Remove</DropdownMenuItem>      </DropdownMenuContent>    </DropdownMenu>  </ItemActions></Item>

Props

Component / propNotes
Itemvariant: plain | default | muted | outline; size: default | sm | xs; asChild to render as an anchor / Link
ItemMediavariant: default | icon | image — sizes icons to the row, or clips an <img> to a rounded square
ItemContentFlex column holding ItemTitle + ItemDescription
ItemTitletext-sm leading-snug font-semibold (compact-row title tier)
ItemDescriptiontext-sm text-fg-muted, clamped to two lines
ItemActionsTrailing controls row — keep buttons at size="sm"
ItemHeader, ItemFooterFull-width strips above / below the body (justify-between)

See packages/ui/src/components/item/item.tsx for the full prop surfaces.

On this page