Item

A flexible list-row primitive with optional leading media, a content column, and trailing actions.

Overview

Item is a flexible list-row primitive: a horizontal band of optional leading media, a growing content column, and trailing actions. Compose it from ItemMedia, ItemContent, ItemTitle, ItemDescription, and ItemActions. Use it for settings rows, member lists, selectable options, and similar list-like UI.

Anatomy

A flex row (<div>) laying out three optional slots left to right:

The outline variant paints a hand-drawn border via @ghds/sketch-core; all colors, spacing, and sketch parameters come from @ghds/tokens (comp.item.*).

Variants & States

Three surface variants — default (transparent), muted (subtle fill), outline (hand-drawn border) — plus a selected boolean that fills the selected background.

State Status Notes
Selected Implemented The selected boolean fills comp.item.bg.selected.
Hover Not implemented Item paints no hover state itself — wire it in your composition if needed.
Focus Not implemented Renders a plain div; add focus styling when you make it interactive.
Disabled Not implemented
Loading Not implemented
Error Not implemented

Usage

Do

  • Compose rows from ItemMedia / ItemContent / ItemTitle / ItemDescription / ItemActions rather than styling raw divs.
  • Set the appropriate role on the container (listitem, option, …) to match how the list is used.
  • Use selected together with aria-selected when the row is a selectable option.

Don't

  • Don't rely on Item for interaction semantics — it renders a plain div, so add role, tabIndex, and handlers yourself.
  • Don't mix outline and non-outline rows in the same list; keep one variant per list for a consistent rhythm.

Accessibility

Content

ItemTitle is the primary line — a short label, not a sentence. ItemDescription is a muted secondary line for supporting detail. Keep media to a single icon/avatar and actions to one or two controls so the row stays scannable.

Props API

React@ghds/react

PropTypeDefaultDescription
variant'default' | 'muted' | 'outline''default'Surface treatment: transparent, subtle fill, or hand-drawn border.
selectedbooleanfalseMarks the row as the selected/active one (fills the selected background).
...restHTMLAttributes<HTMLDivElement>Native <div> attributes (role, onClick, tabIndex, …) pass through.

Web Components@ghds/web-components

PropTypeDefaultDescription
variant'default' | 'muted' | 'outline''default'Reflected attribute; surface treatment.
selectedbooleanfalseReflected attribute; fills the selected background.
slotsmedia, title, description, (default), actionsSlot content into media / title / description / actions; the default slot is extra body content.

React Native@ghds/react-native

PropTypeDefaultDescription
variant'default' | 'muted' | 'outline''default'Surface treatment.
selectedbooleanfalseFills the selected background.
onPress(event: GestureResponderEvent) => voidWhen set, the row is exposed as a button (Pressable).
childrenReactNodeCompose with ItemMedia / ItemContent / ItemTitle / ItemDescription / ItemActions.
accessibilityLabelstringAccessible label for the row.
testIDstringTest handle for queries.

The subcomponents — ItemMedia, ItemContent, ItemTitle, ItemDescription, ItemActions — each accept the standard HTMLAttributes<HTMLDivElement> and render a styled <div>.

Code examples

// React — @ghds/react
import { Item, ItemContent, ItemTitle, ItemDescription, ItemActions } from '@ghds/react/item';
import { Badge } from '@ghds/react/badge';

<Item variant="outline">
  <ItemContent>
    <ItemTitle>GyeongHo Kim</ItemTitle>
    <ItemDescription>Maintainer · 3 open PRs</ItemDescription>
  </ItemContent>
  <ItemActions>
    <Badge variant="success">Online</Badge>
  </ItemActions>
</Item>;
<!-- Web Components — @ghds/web-components -->
<script type="module">
  import '@ghds/web-components/item';
</script>
<gh-item variant="outline">
  <span slot="title">GyeongHo Kim</span>
  <span slot="description">Maintainer · 3 open PRs</span>
</gh-item>
// React Native — @ghds/react-native
import { Item, ItemContent, ItemTitle, ItemDescription } from '@ghds/react-native/item';

<Item variant="outline" onPress={() => {}} accessibilityLabel="GyeongHo Kim">
  <ItemContent>
    <ItemTitle>GyeongHo Kim</ItemTitle>
    <ItemDescription>Maintainer · 3 open PRs</ItemDescription>
  </ItemContent>
</Item>;

Live Demo

React and Web Components render live below, driven by the same tokens — toggle dark mode in the header to see both respond identically. React Native can’t run in a browser without additional react-native-web wiring (not set up in this site), so its usage is shown as a code sample instead.

React @ghds/react

Web Components @ghds/web-components

GH
GyeongHo Kim Maintainer · 3 open PRs
Muted row A subtle filled background. Selected row Marked as the active choice.