EXEPERTAI LAB

Research alpha

Time Machine
EXEPERTAI LAB
GALLERY / COLLECTION
← Browse Astryx gallery
Item·component·@astryxdesign/core

Item

A single, flexible item primitive that unifies the "start content + label + description + end content" pattern across Astryx. Use it wherever you need a structured row: dropdown menus, selectors, contact lists, notifications, file browsers, and activity feeds.

Open in Playground @astryxdesign/core/Item

Showcases and examples

5 documented examples

Item

Item API entry

Preview loads on approachPreview loads on approach
Exact source · item-showcase
// Copyright (c) Meta Platforms, Inc. and affiliates.

'use client';

import {Item} from '@astryxdesign/core/Item';
import {Avatar} from '@astryxdesign/core/Avatar';
import {Badge} from '@astryxdesign/core/Badge';
import {Icon} from '@astryxdesign/core/Icon';
import {Text} from '@astryxdesign/core/Text';
import {Stack} from '@astryxdesign/core/Layout';
import {UserIcon, DocumentIcon, BellIcon} from '@heroicons/react/24/outline';

export default function ItemShowcase() {
  return (
    <Stack gap={0}>
      <Item
        startContent={<Avatar name="Alice Johnson" size={40} />}
        label="Alice Johnson"
        description="Engineering Lead"
        endContent={<Badge label="Admin" />}
        onClick={() => {}}
      />
      <Item
        startContent={<Icon icon={BellIcon} size="sm" />}
        label="Build completed successfully"
        description="Pipeline #4521 — all 42 tests passed"
        endContent={<Text color="secondary">5h ago</Text>}
        descriptionLines={1}
        onClick={() => {}}
      />
      <Item
        startContent={<Icon icon={DocumentIcon} size="sm" />}
        label="design-spec.pdf"
        description="Modified 2 hours ago"
        endContent={<Text color="secondary">2.4 MB</Text>}
        isSelected
        onClick={() => {}}
      />
      <Item
        startContent={<Icon icon={UserIcon} size="sm" />}
        label="Compact menu item"
        density="compact"
        onClick={() => {}}
      />
    </Stack>
  );
}

Usage

A single, flexible item primitive that unifies the "start content + label + description + end content" pattern across Astryx. Use it wherever you need a structured row: dropdown menus, selectors, contact lists, notifications, file browsers, and activity feeds.

  • Use named slots (startContent, label, description, endContent) for the common layout. These cover the 80% case.
  • Use density="compact" for menus and dense lists, "balanced" for standard rows, and "spacious" for roomier layouts.
  • Set labelLines and descriptionLines to control truncation when content length varies.
  • Use align="start" when start or end content is taller than a single line of text.
  • Don't nest interactive elements (buttons, links) inside an interactive Item; it creates confusing focus and click targets.
  • Don't use Item for navigation between views; use proper navigation components instead.
  • Don't add read/unread or inbox-specific behavior directly; compose a thin wrapper like PreviewItem instead.

Typed props

PropType and behavior
labelReactNode · required
Primary text identifying this item. Accepts string (auto-truncated) or ReactNode (for rich content).
markerReactNode
Marker rendered before startContent as a direct flex child. Use for list bullets/counters that need custom baseline alignment.
startContentReactNode
Content rendered before the label/description area, such as an icon, avatar, or checkbox.
Slot: Avatar, Icon
descriptionReactNode
Secondary text: subtitle, description, or supporting info.
endContentReactNode
Content rendered after the label/description area, such as badges, metadata, timestamps, or action buttons.
Slot: Badge, Text
as'div' | 'li' | 'span' · default 'div'
HTML element to render as the root.
align'center' | 'start' · default 'center'
Vertical alignment of start/end content slots.
density'compact' | 'balanced' | 'spacious' · default 'balanced'
Spacing density. "compact" uses 4px block padding, "balanced" uses 8px, and "spacious" uses 12px block and inline padding.
labelLinesnumber
Max lines before label truncates with ellipsis.
descriptionLinesnumber
Max lines before description truncates with ellipsis.
layout'stacked' | 'inline' · default 'stacked'
How the label and description sit together. stacked puts the description on its own line below the label; inline keeps both on one line, description ellipsizing first, so the row fits a fixed-height host.
onClick(event: MouseEvent) => void
Click handler. Makes the item clickable with button semantics.
interactiveRefRefObject<HTMLElement | null>
Ref to a nested control (e.g. a checkbox in startContent) that owns the item's keyboard access and action. The row becomes an enlarged click/tap target that delegates surface clicks to it (useClickableContainer) and renders no invisible button/anchor, so the row adds no second tab stop (WCAG 4.1.2). Mutually exclusive with onClick/href; those are ignored when set.
hrefstring
Link URL. Makes the item a link via an invisible anchor element. The destination follows the shared navigation rule described on the Link href prop.
target'_blank' | '_self'
Link target. Only used with href. target="_blank" automatically adds noopener noreferrer.
relstring
Link relationship tokens. noopener noreferrer are merged automatically for target="_blank".
isHighlightedboolean · default false
Highlighted state (hover/keyboard focus appearance).
isSelectedboolean · default false
Selected state.
isDisabledboolean · default false
Disabled state.
refReact.Ref<HTMLDivElement>
Ref forwarded to the root element.
xstyleStyleXStyles
StyleX styles for layout customization. Must be a stylex.create() value.
data-testidstring
Test selector for automated testing frameworks.

Anatomy

Marker · optional

Optional list bullet/counter rendered before start content.

Start content · optional

Leading visual: avatar, icon, image, or checkbox.

Label · required

Primary text identifying the item.

Description · optional

Secondary supporting text below the label.

End content · optional

End-aligned content: badges, timestamps, or action buttons.

Theming

Targets

astryx-item

Visual props: density, align

Variables

--_item-label-color · private

Color of the label line. Unset by default (the label uses the primary text token); a parent sets it to recolor the label it renders, as the destructive dropdown/context menu item does.

Default: var(--color-text-primary)

--_item-description-color · private

Companion to --_item-label-color for the secondary description line.

Default: var(--color-text-secondary)

--_item-inset-inline · private

Inline inset of the row. Item derives its paddingInline from this variable, and List reads it to cancel the inset when edgeCompensation="inline". Set paddingInline on item in a theme and both stay in sync.

Default: var(--spacing-2) (var(--spacing-3) for density="spacious")

Derived properties

paddingInline

Uses --_item-inset-inline.