Experience System
Components

Item

A flexible row for media, title, description, and actions. Group items with ItemGroup and ItemSeparator.

Basic item

Your profile has been verified.

Installation

The component is exported from @by/experience-system. Add the package with your package manager:

pnpm add @by/experience-system

In this monorepo, depend on the workspace package (for example via workspace:* or your catalog) so imports resolve to packages/experience-system.

Composition

Use the following composition to build an Item row (see also shadcn/ui Item):

ItemGroup (optional)
├── ItemSeparator (optional, between rows)
└── Item
    ├── ItemHeader (optional)
    ├── ItemMedia (optional)
    ├── ItemContent
    │   ├── ItemTitle
    │   └── ItemDescription
    ├── ItemActions (optional)
    └── ItemFooter (optional)

Item vs Field: use Field (and form primitives) when the row centers on an input, checkbox, radio, or select. Use Item for read-only or action-oriented rows (navigation, summaries, list cells). With asChild on Item, the row merges onto a single child via Radix UI Slot.

Usage

import {
  Item,
  ItemActions,
  ItemContent,
  ItemDescription,
  ItemGroup,
  ItemHeader,
  ItemMedia,
  ItemSeparator,
  ItemTitle,
} from '@by/experience-system';

Item and its parts are client components ('use client' in the package). Use them inside a Client Component or a dynamic import when using the Next.js App Router.

<Item variant="outline">
  <ItemMedia variant="icon">{/* icon */}</ItemMedia>
  <ItemContent>
    <ItemTitle>Title</ItemTitle>
    <ItemDescription>Supporting text.</ItemDescription>
  </ItemContent>
  <ItemActions>{/* buttons */}</ItemActions>
</Item>

Examples

The live preview at the top of this page uses item-usage.

Variants

Surface styles for the whole row: default (transparent), outline (border), soft (subtle fill).

Default variant

Transparent background with no border.

Outline variant

Outlined style with a visible border.

Soft variant

Soft background for secondary content.

Sizes

Use the size prop on Item for md, sm, or xs padding and density.

Medium

The baseline size for most use cases (`md`).

Small Size

A compact size for dense layouts.

Extra Small Size

The most compact size available.

With icon

Use ItemMedia with variant="icon" for a contained icon well.

Security alert

New login detected from unknown device.

Image

Use ItemMedia with variant="image" for thumbnails (for example album art). Rows can be asChild links.

Group

ItemGroup sets role="list"; add role="listitem" on each Item when it represents a list row. Use ItemSeparator between rows.

With paddings

s
shadcn

shadcn@vercel.com

m
maxleiter

maxleiter@vercel.com

e
evilrabbit

evilrabbit@vercel.com

Without paddings

s
shadcn

shadcn@vercel.com

m
maxleiter

maxleiter@vercel.com

e
evilrabbit

evilrabbit@vercel.com

Use ItemHeader for content above the main body (for example a cover image), then ItemContent with ItemTitle and ItemDescription.

v0-1.5-sm
v0-1.5-sm

Everyday tasks and UI generation.

v0-1.5-lg
v0-1.5-lg

Advanced thinking or reasoning.

v0-2.0-mini
v0-2.0-mini

Open Source model for everyone.

Item with asChild wraps an anchor so focus and hover styles apply to the link. Pair with ItemActions for trailing affordances (chevron, external icon).

API Reference

Subsection titles name the exports from @by/experience-system. Item uses Radix UI Slot when asChild is true. ItemSeparator wraps the Experience System Separator (Radix Separator under the hood).

Item

Root row.

PropTypeDefault
variantdefault | outline | muted
sizedefault | sm | xs
asChildbooleanfalse
classNamestring

Also accepts standard div attributes.

Data attributeValues
data-slotitem
data-variantmirrors variant when set
data-sizemirrors size when set

ItemGroup

Vertical stack for related items.

Data attributeValues
data-slotitem-group

Renders role="list". Also accepts standard div attributes.

ItemSeparator

Horizontal rule between items.

Data attributeValues
data-slotitem-separator

Forwards to Separator with orientation="horizontal". Also accepts Separator props where applicable.

ItemMedia

Leading media slot.

PropTypeDefault
variantdefault | icon | image | avatar
classNamestring
Data attributeValues
data-slotitem-media
data-variantmirrors variant

Also accepts standard div attributes.

ItemContent

Main column; typically holds ItemTitle and ItemDescription.

Data attributeValues
data-slotitem-content

ItemTitle

Primary line (div).

Data attributeValues
data-slotitem-title

Also accepts standard div attributes.

ItemDescription

Secondary line (renders a p).

Data attributeValues
data-slotitem-description

Also accepts standard p attributes.

ItemActions

End-aligned actions (buttons, icons, menus).

Data attributeValues
data-slotitem-actions

ItemHeader

Optional block above ItemContent.

Data attributeValues
data-slotitem-header

ItemFooter

Optional metadata below ItemContent.

Data attributeValues
data-slotitem-footer

Accessibility

  • Keep a single ItemTitle (or equivalent heading) per row for a clear scan order.
  • Decorative icons in ItemMedia or ItemActions should use aria-hidden; meaningful icons need an accessible name.
  • When ItemGroup is a list, mark each Item with role="listitem" if the DOM structure does not already imply list items.
  • For asChild links, ensure the child a has a visible focus ring (handled via Item styles) and descriptive link text.

Source in the repo: packages/experience-system/src/components/Item/Item.tsx and variants.ts. Agent-oriented usage notes: packages/experience-system/src/components/Item/Item.instructions.md.