Item
A flexible row primitive for lists, menus, and settings — media, title, description, and actions in one composable layout.
Statements, alerts, and approval requests.
Business current account · •••• 4291
<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).
No fill — sits flush inside a list.
A subtle fill — the default for most rows.
A stronger fill for secondary rows.
A visible border — reads as a standalone row.
{/* 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.
size="default"
size="sm"
{/* 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.
Add a second step when signing in to keep the account secure.
<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.
Relationship manager · Whitfield Wealth
<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.

PDF · 2.4 MB · Updated 25 Dec 2025
<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.
Relationship manager
Investment analyst
Compliance lead
<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>Header
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.
The Vasquez household mandate is ready for the client to review and sign.
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>Link
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.
plain
Profile, security, and notifications.
Invite colleagues and manage roles.
default
Profile, security, and notifications.
Invite colleagues and manage roles.
{/* 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>Dropdown
Put a DropdownMenu in ItemActions for per-row overflow actions. Use an IconButton trigger so the row stays compact.
•••• 4291 · Primary
<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 / prop | Notes |
|---|---|
Item | variant: plain | default | muted | outline; size: default | sm | xs; asChild to render as an anchor / Link |
ItemMedia | variant: default | icon | image — sizes icons to the row, or clips an <img> to a rounded square |
ItemContent | Flex column holding ItemTitle + ItemDescription |
ItemTitle | text-sm leading-snug font-semibold (compact-row title tier) |
ItemDescription | text-sm text-fg-muted, clamped to two lines |
ItemActions | Trailing controls row — keep buttons at size="sm" |
ItemHeader, ItemFooter | Full-width strips above / below the body (justify-between) |
See packages/ui/src/components/item/item.tsx for the full prop surfaces.