List

Lines up rows on a phone, like recent activity or settings.

Examples

  • Round-upsSpare change to Vacation fund
  • Payment alerts

With a row menu

Styles

    • Corner CoffeeToday−$4.80
    • PaycheckYesterday+$2,140.00

    plaindefault

    • Corner CoffeeToday−$4.80
    • PaycheckYesterday+$2,140.00

    grouped

Trailing

    • Corner CoffeeToday−$4.80

    amountdefault

    • StatementsMonthly, as PDF

    chevron

    • Round-upsSpare change to savings

    switch

    • SRSam RiveraOwes you $12.50Pending

    badge

Tone

  • neutraldefault

  • accent

  • success

  • danger

States

Usage

When to use it
Use
Recent activity, accounts or friends, read one row at a time.
Use
A settings screen, where each row holds one switch or opens one page.
Use
A short choice on a phone, such as picking the account to pay from.
Not for
Many columns compared across rows on a wide screen. Use Table.
Not for
One choice from a few options inside a form. Use Radio.
Not for
A menu of commands behind a button. Use Dropdown menu.

Rules

9 rules
Must
Give a row one action: href, onClick or one trailing control, never two. Because a Switch inside the row button nests two controls, and one tap fires both.
Must
Show the chevron only on a row that opens another screen; href turns it on. Because the person taps a chevron row expecting a screen, and a Switch row opens nothing.
Must
Write a row amount as formatAmount text, signed for money in; use the Amount pill only when the row needs a tone, such as more than the balance. Because a column of plain figures stays quiet and lines up, and a pill on every row is noise.
Should
Keep the title to the name and put the date or category in description; both truncate.
Should
Use the same leading mark in every row of a list: all ListIcon or all Avatar.
Should
Use plain for a feed of rows; grouped only for a short settings group on the white page, never inside a Card or a Sheet.
Must
Give a trailing Switch an aria-label that repeats the row title. Because a bare Switch is read as "switch, off" with no setting named.
Should
Pull a plain list out by -mx-4 inside a padded Card or SheetBody, so row text lines up with the heading.
Never
Fill a row with lime to mark it; tone="accent" on its ListIcon is the most a row gets. Because the lime fill marks the one primary action, so a lime row reads as a button.

Accessibility

5 checks
The list is a ul with role list, so the count is announced even with list styles removed.
A row with href is one link and with onClick one button; its name is the title and the line under it.
A trailing Switch is the row control and needs its own aria-label.
The focus ring sits inside the row so the grouped card does not clip it.
Rows are at least 56px tall.

Edge cases

5 edge cases
Long title
Title and description truncate; the trailing value never shrinks.
Right to left
The mark sits at the start and the chevron flips.
No leading mark
The hairline starts at the text edge, 16px in.
Disabled row
It dims to half and stops responding; say why in description.
One row
No hairline is drawn; the last row never has one.

API

8 props
List.variant
'plain' | 'grouped' default 'plain'
ListItem.title
ReactNode
ListItem.description
ReactNode
ListItem.leading, trailing
ReactNode
ListItem.href, onClick
string, function
ListItem.chevron
boolean default true with href
ListItem.menu
ReactNode
ListIcon
{icon, tone?: 'neutral' | 'accent' | 'success' | 'danger'} default 'neutral'

Tokens

14 tokens
--surface
#f6f5f2
--surface-2
#efeeea
--surface-3
#e6e4df
--radius-panel
16px
--line
#e6e4df
--fg
#0f0f0d
--fg-3
#6b6a63
--text-base
16px
--text-sm
14px
--ring
var(--accent-line)
--accent-wash
#f5f9c4
--success-tint
#e5f5ea
--success-text
#17703a
--dur-instant
80ms

Install

For your coding agent

GitHub

Please star me pookie

141

A new design system every week

Leave your email before you copy the prompt.