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, key0ae6158a858fcdf6b617bace023f91cfb3f117e2. - Verified mini-spec:
18172:21820. - Reusable Figma assembly details are in
wbl-list-item.figma.md.
Anatomy
- Optional top slot above the text block.
- Optional start slot and optional left icon.
- Text block: optional top subtitle, optional title with title icon, and optional bottom subtitle.
- Optional end slot and optional right icon.
- Optional bottom slot below the text block.
- 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, andSdefine icon size and typography.Luses 24px side icons and 17/20 medium title text;Muses 20px side icons and 15/20 medium title text;Suses 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 isstart.- A static item has only default and disabled states. A clickable item adds hover and pressed feedback.
disabledsuppresses row activation, pointer affordance, and tab focus. It does not replace the disabled state of a control projected into a slot.separatordraws only the bottom secondary stroke and is enabled by default.
Behavior
itemClickis 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-primaryfor title,--color-text-icon-secondaryfor subtitles and icons, and--color-stroke-secondaryfor the separator. - Spacing uses
--space-50,--space-100, and--space-200for local gaps and the established List Item padding token. - Typography:
--typography-action-accent-minipig(Ltitle),--typography-body-accent-buffalo(Mtitle),--typography-description-accent-lion(Stitle),--typography-body-horse(Lsubtitle), and--typography-description-puma(M/Ssubtitle).
Accessibility
- A clickable item has button semantics and an accessible name from visible
text. An enabled item receives tab focus and a visible
:focus-visibleindicator; a disabled one keepsaria-disabledbut 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
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)andtopSubtitleText = input('Top subtitle')title = input(true)andtitleText = input('Title')bottomSubtitle = input(false)andbottomSubtitleText = input('Bottom subtitle')leftIcon = input(false)andleftIconName = input<WblIconName>('spark')titleIcon = input(false)andtitleIconName = input<WblIconName>('spark')rightIcon = input(false)andrightIconName = 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 bytopContent.[wblListItemStart], controlled bystartContent.[wblListItemBottom], controlled bybottomContent.[wblListItemEnd], controlled byendContent.
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).