ComponentsVertical List Cell
Lists

Vertical List Cell

The primitive behind every vertical list. A row cell rotated onto the vertical axis: a full-height column with a leading edge at the top, vertical title/subtitle, and a trailing accessory at the bottom.

Design question

A horizontal list cell is [leading] [title/subtitle] … [trailing accessory] laid out as a full-width row. What is its shape when the list stacks as columns and scrolls right-to-left?

Default

The primitive behind every vertical list. A cell is a full-height column — leading index at the top, vertical title + subtitle, and a trailing accessory (a down-pointing disclosure chevron, or a status pill) at the bottom. Cells stack as columns and the list scrolls right-to-left.

tsx
1import { VerticalListCell } from "@/components/ui/vertical-list-cell"
2
3export function ContentsList() {
4 return (
5 <div style={{ display: "flex", flexDirection: "row-reverse", gap: 12, overflowX: "auto" }}>
6 {chapters.map((c, i) => (
7 <VerticalListCell
8 key={c.title}

Guidance

Do
  • Put the leading element (index, icon, avatar) at the top — the reading-start edge
  • Point the disclosure chevron down (rotate 90°): 'forward' is downward along the vertical axis
  • Keep every cell the same height so the row of columns reads as one list
  • Give each cell a 44px+ hit target and stack cells right-to-left
Don't
  • Rotate a finished horizontal cell with transform: rotate(90deg)
  • Leave the chevron pointing right — it should follow the reading axis, not the scroll edge
  • Mix upright and vertical text within the same cell for title and subtitle

Accessibility

Container role='listbox' (or 'list'); each cell role='option' with aria-selected (or a plain button). Keyboard: arrow keys move selection; the visual R→L order must match DOM/tab order.

Open Question

When the accessory is an interactive control (toggle, stepper), should it keep the bottom position, or move beside the title so the primary tap target stays central?

← PreviousSkeleton