Item
A composable row for lists with media, content and actions.
john@example.com
alice@example.com
Item is a composable row for heterogeneous lists (settings, contacts, notifications, dashboard cards). Media (icon/avatar/thumbnail) + Content (Title + Description) + Actions (buttons, switch, badge).
It differs from Card: Item is horizontal, dense, and meant to be stacked in a list. Card is a block, more visual.
Installation
$ bext ui add item
Copy and paste the following into src/components/ui/item.tsx.
Usage
Anatomy
<Item> ├── <ItemMedia><Avatar /></ItemMedia> // optional ├── <ItemContent> │ ├── <ItemTitle>John Doe</ItemTitle> │ └── <ItemDescription>john@example.com</ItemDescription> └── <ItemActions><Button /></ItemActions> // optional <ItemGroup> // role="list" wrapper for a stack of Items ├── <Item>...</Item> ├── <ItemSeparator /> └── <Item>...</Item>
API Reference
Item
| Prop | Type | Default | Description |
|---|---|---|---|
| variant | "default" | "outline" | "muted" | "default" | default: transparent. outline: visible border. muted: bg-muted/50. |
| size | "default" | "sm" | "default" | default: gap-4 p-4. sm: gap-2.5 px-4 py-3. |
| href | string | — | When set, the row is rendered as an <a> instead of a <div>. |
| children | ReactNode | — | ItemMedia, ItemContent and ItemActions, in that order. |
ItemMedia
| Prop | Type | Default | Description |
|---|---|---|---|
| variant | "default" | "icon" | "image" | "default" | icon: 32px bordered muted square. image: 40px thumbnail that crops its <img>. |
| children | ReactNode | — | Left slot (avatar, icon, thumbnail). |
ItemContent
| Prop | Type | Default | Description |
|---|---|---|---|
| children | ReactNode | — | Center: stacked Title + Description. |
ItemTitle
| Prop | Type | Default | Description |
|---|---|---|---|
| children | ReactNode | — | Primary line, text-sm font-medium. Rendered as a <div>. |
ItemDescription
| Prop | Type | Default | Description |
|---|---|---|---|
| children | ReactNode | — | Muted, text-sm, clamped to two lines. Rendered as a <p>. |
ItemActions
| Prop | Type | Default | Description |
|---|---|---|---|
| children | ReactNode | — | Right slot: buttons, switch, badge. |
ItemGroup
| Prop | Type | Default | Description |
|---|---|---|---|
| children | ReactNode | — | Stack of Items in a flex column with role="list". |
ItemSeparator
| Prop | Type | Default | Description |
|---|---|---|---|
| className | string | — | 1px line with role="separator" between two Items. |
ItemHeader / ItemFooter
| Prop | Type | Default | Description |
|---|---|---|---|
| children | ReactNode | — | Full-width row (basis-full, justify-between) above or below the main row. |
Data Attributes
Attributes you can target in custom CSS to override the style for each state.
| Attribute | On | Values | Description |
|---|---|---|---|
| data-slot | every sub-component | "item" | "item-media" | "item-content" | "item-title" | "item-description" | "item-actions" | "item-group" | "item-separator" | "item-header" | "item-footer" | Stable selector for custom styling. |
| data-variant | Item, ItemMedia | see the variant prop | Reflects the variant prop. |
| data-size | Item | "default" | "sm" | Reflects the size prop. |
Accessibility
ItemGroup sets role="list" on the container. Item sets no role and has no prop to add one, so the rows are not announced as list items: if the list semantics matter, write your own <ul> with one Item per <li> instead of using ItemGroup.
On This Page