Item
The row counterpart to Card — a media · content · actions strip for lists.
Usage
import {
Item,
ItemActions,
ItemContent,
ItemDescription,
ItemMedia,
ItemTitle,
} from "@kanzo-tech/ui";<Item variant="outline">
<ItemMedia>
<ScrollTextIcon />
</ItemMedia>
<ItemContent>
<ItemTitle>Something is eating the bell-ropes</ItemTitle>
<ItemDescription>Thornmarch · Nuisance</ItemDescription>
</ItemContent>
<ItemActions>
<Button size="sm" variant="outline">Claim</Button>
</ItemActions>
</Item>Where a Card is a self-contained block, an Item is a horizontal row
— the shape a list of records wants. Everything is a child, so a region can be wrapped, reordered
or dropped, and every part carries a data-slot for restyling.
Grouped
ItemGroup is a role="list" and each Item a role="listitem"; ItemSeparator divides them.
Variants
variant (default · outline · muted) is mirrored to data-variant.
Anatomy
ItemGroup
└── Item
├── ItemHeader (full-width row above the main line)
├── ItemMedia
├── ItemContent
│ ├── ItemTitle
│ └── ItemDescription
├── ItemActions
└── ItemFooter (full-width row below the main line)ItemHeader and ItemFooter break to their own line (basis-full), so a row can carry a
heading or a footer strip above/below its media · content · actions line.
API Reference
Item
Renders a div with role="listitem".
| Prop | Type | Default |
|---|---|---|
variant | "default" | "outline" | "muted" | "default" |
Owns the --space padding variable, so a consumer can retune the row's rhythm in one place.
ItemMedia
| Prop | Type | Default |
|---|---|---|
variant | "default" | "icon" | "image" | "default" |
image gives a 10×10 rounded, clipped frame for a thumbnail; default and icon size a child
svg to 4×4. Mirrored to data-variant.
ItemTitle
A flex row, so a title can carry a badge or a code span beside its text and they will be spaced.
It does not clamp: line-clamp sets display: -webkit-box, which would replace that row.
Where the title is a single unbounded string — something a user named — clamp it at the call site:
<ItemTitle className="line-clamp-1">{schedule.name}</ItemTitle>That trades the row for the clamp, which is the right trade for a title that is only text.
Other parts
ItemGroup renders a role="list" container; ItemSeparator wraps
Separator; ItemDescription renders a <p> and clamps at two lines
(line-clamp-none to undo it). The remaining parts render a div and take that element's props.
Every part's props are exported as an interface — ItemMediaProps and ItemProps — so a wrapper
can take the same props without restating them.
An empty state
A zero-state placeholder is a vertical Item — the same media · content · actions vocabulary,
centred — not a component of its own. There is one shape in it worth copying rather than
re-deriving: cap the description at max-w-[420px], or the sentence stretches the full width of
whatever table it is standing in for.
Put the title in the surrounding document outline with asChild: an empty state inside a section
under an h2 is an h3. That is the detail a props-shaped component used to decide for you, and
the reason it is better decided at the call site is that only the call site knows the outline.