# List Item

Level: molecule.

## Purpose

`List Item` presents one independent row of structured information in a list.
Use it for static rows and for a single row-level action. Use a nested control
in a projected slot when selection belongs to that control; do not use this
component as a free-form custom-content container.

## Figma source

- Published master component set: `18149:157253`, key
  `0ae6158a858fcdf6b617bace023f91cfb3f117e2`.
- Verified mini-spec: `18172:21820`.
- Reusable Figma assembly details are in
  [`wbl-list-item.figma.md`](wbl-list-item.figma.md).

## Anatomy

1. Optional top slot above the text block.
2. Optional start slot and optional left icon.
3. Text block: optional top subtitle, optional title with title icon, and
   optional bottom subtitle.
4. Optional end slot and optional right icon.
5. Optional bottom slot below the text block.
6. Optional bottom separator.

Slots are structural opt-ins: their wrapper is rendered only when the matching
input is enabled. Start and end are semantic local names; they replace the
legacy left/right projection API.

## Variants and states

- `L`, `M`, and `S` define icon size and typography. `L` uses 24px side icons
  and 17/20 medium title text; `M` uses 20px side icons and 15/20 medium title
  text; `S` uses 16px side icons and 13/16 medium title text. The title icon is
  16px in every size.
- `alignment: 'start' | 'center'` aligns side anatomy against the expanded text
  block. The default is `start`.
- A static item has only default and disabled states. A clickable item adds
  hover and pressed feedback.
- `disabled` suppresses row activation, pointer affordance, and tab focus. It
  does not replace the disabled state of a control projected into a slot.
- `separator` draws only the bottom secondary stroke and is enabled by default.

## Behavior

- `itemClick` is emitted only from an enabled clickable row. Enter and Space
  activate the same action and Space prevents page scrolling.
- Clicks originating from a nested interactive element do not emit `itemClick`.
- A clickable item must not contain focusable controls in any projected slot.
  Checkbox, radio, switch, link, and similar interactive slot content require a
  non-clickable List Item; the projected control owns its interaction and state.
- Text parts truncate with ellipsis when the available inline size is exhausted;
  an icon or end slot must not be compressed by the text block.

## Tokens

- Base and interaction backgrounds: `--color-background-level-1-base`,
  `--color-background-level-1`, and `--color-background-dropdown-active`.
- Content colors: `--color-text-icon-primary` for title,
  `--color-text-icon-secondary` for subtitles and icons, and
  `--color-stroke-secondary` for the separator.
- Spacing uses `--space-50`, `--space-100`, and `--space-200` for local gaps
  and the established List Item padding token.
- Typography: `--typography-action-accent-minipig` (`L` title),
  `--typography-body-accent-buffalo` (`M` title),
  `--typography-description-accent-lion` (`S` title),
  `--typography-body-horse` (`L` subtitle), and
  `--typography-description-puma` (`M`/`S` subtitle).

## Accessibility

- A clickable item has button semantics and an accessible name from visible
  text. An enabled item receives tab focus and a visible `:focus-visible`
  indicator; a disabled one keeps `aria-disabled` but is removed from tab order.
- Do not expose an item with no enabled row action as a button.
- Decorative icons are hidden from assistive technology. Meaningful context
  belongs in text or in the accessible name of the projected control.
- The interactive-slot constraint in Behavior prevents invalid nested
  interactive semantics.

## Content guidance

- Use title for the primary identifier or action label; subtitles supply
  supporting context and are independently optional.
- Prefer a short title. Long text is intentionally truncated rather than
  changing the row geometry.
- Use only one interactive owner: the row or a projected control, never both.

## Local component contract

This is the active owned contract for `component.list-item`; it replaces the
legacy `state`, `error`, description, custom-body, left/right-content, and
legacy projection-marker API without compatibility aliases.

### Classes and selector

- `WblListItemComponent` — `wbl-list-item`
  (`src/app/design-system/patterns/list-item/list-item.component.ts`).

### Types

```ts
export type WblListItemSize = 'L' | 'M' | 'S';
export type WblListItemAlignment = 'start' | 'center';
```

### Inputs

- `size = input<WblListItemSize>('M')`
- `alignment = input<WblListItemAlignment>('start')`
- `clickable = input(false)`
- `disabled = input(false)`
- `separator = input(true)`
- `topSubtitle = input(false)` and `topSubtitleText = input('Top subtitle')`
- `title = input(true)` and `titleText = input('Title')`
- `bottomSubtitle = input(false)` and
  `bottomSubtitleText = input('Bottom subtitle')`
- `leftIcon = input(false)` and `leftIconName = input<WblIconName>('spark')`
- `titleIcon = input(false)` and `titleIconName = input<WblIconName>('spark')`
- `rightIcon = input(false)` and `rightIconName = input<WblIconName>('spark')`
- `topContent = input(false)`
- `startContent = input(false)`
- `bottomContent = input(false)`
- `endContent = input(false)`

### Models

- None.

### Output

- `itemClick = output<void>()`

### Slots and projection markers

- `[wblListItemTop]`, controlled by `topContent`.
- `[wblListItemStart]`, controlled by `startContent`.
- `[wblListItemBottom]`, controlled by `bottomContent`.
- `[wblListItemEnd]`, controlled by `endContent`.

### Local evidence

- Code: `src/app/design-system/patterns/list-item/list-item.component.ts`.
- Focused test: `src/app/design-system/patterns/list-item/list-item.component.spec.ts`.
- Public export: `src/app/design-system/index.ts`.
- Storybook: `storybook/stories/list-item.stories.ts`
  (`Design System/Patterns/wbl-list-item`).
