Item
A row for lists, settings and menus that lines up media, a title, a description and actions without the CSS headache.
Add a second lock to your account. Future you will say thanks.
Usage
import {
Item,
ItemActions,
ItemContent,
ItemDescription,
ItemMedia,
ItemTitle,
} from '@vitnode/core/components/ui/item'<Item variant="outline">
<ItemMedia variant="icon">
<ShieldCheck />
</ItemMedia>
<ItemContent>
<ItemTitle>Two-factor authentication</ItemTitle>
<ItemDescription>Add a second lock to your account.</ItemDescription>
</ItemContent>
<ItemActions>
<Button size="sm" variant="outline">
Enable
</Button>
</ItemActions>
</Item>Every app grows a dozen "icon, text, button on the right" rows. Item is that
row, built once.
ItemContentstacks title and description and takes the free space.ItemTitleis one line and truncates.ItemDescriptionshows up to two muted lines. Links inside get underlined.ItemActionsholds buttons, badges or a chevron at the end.
Variants
No border, no background. Blends right into the page.
A subtle border for rows that need a little structure.
A soft background for secondary or grouped content.
<Item variant="muted">...</Item>Sizes
3 unread messages are waiting.
3 unread messages are waiting.
sm and xs shrink padding and gaps. Image media shrinks too, and xs also
uses smaller description text.
<Item size="sm">...</Item>Media
default - leaves your avatar alone
icon - sizes a bare SVG
image - crops to a rounded square
With a description present, media aligns to the top of the text.
<ItemMedia variant="image">
<img alt="" src="/cover.webp" />
</ItemMedia>As a link
Pass an element to render, such as an <a>, a router Link or a <button>.
Put the row's content inside it so the link wraps everything. Links get a hover
background.
<Item
render={
<a href="/docs/ui/avatar">
<ItemContent>
<ItemTitle>Read the Avatar docs</ItemTitle>
</ItemContent>
<ItemActions>
<ChevronRight aria-hidden className="size-4" />
</ItemActions>
</a>
}
/>Groups
bot@vitnode.com
ada@example.com
grace@example.com
ItemGroup stacks items. ItemSeparator draws a line between them.
<ItemGroup aria-label="Team members">
<Item role="listitem">...</Item>
<ItemSeparator />
<Item role="listitem">...</Item>
</ItemGroup>Header and footer
Sent every Monday to 1,204 subscribers. Nobody has unsubscribed this week, which we choose to take personally.
ItemHeader and ItemFooter span the full width, above or below the content.
<Item variant="outline">
<ItemHeader>
<Badge variant="success">Active</Badge>
</ItemHeader>
<ItemContent>...</ItemContent>
<ItemFooter>
<Button size="sm">Edit</Button>
</ItemFooter>
</Item>Accessibility
ItemGrouphasrole="list". Give eachItemrole="listitem"and the group anaria-label.- One interactive element per row: either the whole row is a link or button,
or it holds buttons in
ItemActions. Never a button inside a link. - Icon-only buttons need an
aria-labelthat names the row, like "Invite Ada Lovelace", not "Invite". - Decorative icons get
aria-hidden. Links that open a new tab say so insr-onlytext. - Rows rendered as links or buttons show a focus ring.
Props
Item
Prop
Type
ItemMedia
Prop
Type