Desktop components

Lists & tables

Lists and tables present data in one or more columns of rows.

When to use them

Use a list for navigation and single-column content. Use a table when people compare values across columns.

Preview

  • Favorites
  • › Documents
  • › Downloads
  • › Desktop
  • › Screenshots
  • Applications
  • Network
Name Kind Size
Report.pagesDocument1.2 MB
Notes.txtPlain text4 KB
Design
Mockups.figDesign file48 MB
Icons.svgSVG image96 KB

Anatomy: list

A row is a 20px capsule with an 8px radius, on a 30px rhythm (5px block margin above and below). The label is 13px at weight 510. The disclosure chevron is 9px bold at 85% ink, in a 12px slot 9px from the capsule edge. Icons are 14px with a 2px radius. With a chevron and an icon, the icon starts 21px into the row and the label 41px. Each indent level adds 15px of leading padding.

ClassRole
.p-listThe row stack. Resets list styling.
.p-list-rowOne row. Flex container, radius 8px.
.p-list-chevronDisclosure slot, 9px bold at 85%.
.p-list-icon14px icon slot, 6px before the label.
.p-list-detailRight-aligned secondary text.
.p-list-group-titleGroup heading, 11px at weight 590, 50% opacity.
data-p-level="1..5"Indentation, 15px per level.

States: list

Selection uses a dedicated blue, #0165E2, darker than the control accent so white text holds contrast (5.3:1). All content in a selected row turns white, including the chevron and detail text.

StateClassValues
RestText rgba(0, 0, 0, 0.85), no fill
HoverFill rgba(0, 0, 0, 0.05)
Selected, focused.p-selectedFill #0165E2, white text
Selected, inactive.p-selected-quietFill rgba(0, 0, 0, 0.14), text unchanged. Use when the containing view loses focus.
Dimmed.p-dimmed or aria-disabled="true"Text at 50%, no pointer events

To retint the selection, override the token on the list: style="--p-list-selection: #AF52DE". Keep white text above 4.5:1 when you do.

Anatomy: table

Apply .p-table to a real <table>. Rows butt together on a dense 20px pitch, inset 10px from the table edge. There are no row hairlines. Instead, every other row is striped with an 8px-radius capsule at rgba(0, 0, 0, 0.05). The stripes count across group-title rows (tr.p-table-group), so the rhythm never breaks. Add .p-table-plain to turn the stripes off.

Cells are 13px at weight 510 with 8px horizontal padding. The first column reads at 85% ink and the others at 50%, so the name leads. Right-align numeric columns with .p-table-num.

The header is quiet: 19px cells in a 31px band, with no line under it. The sorted column is 11px bold at 85%, and the others are 11px at weight 510 at 50%. Column dividers are 1×19px at rgba(0, 0, 0, 0.1) on the leading edge of each column after the first, in the header only.

Sorting is declared, not styled by hand: set aria-sort="ascending" or descending on the sorted <th>. The column turns bold and its 9px chevron renders and flips. Screen readers announce the same attribute, so the visual and the announcement never drift apart.

A selected row (.p-selected on the <tr>) fills every cell in #0165E2 and rounds only the outer corners, 8px on the first and last cell. The row reads as one capsule spanning all columns. Use .p-selected-quiet when the table loses focus.

Dark mode

These values are derived rather than measured. Selection lifts to #0A6CF0, one step brighter in the same blue family, to hold against dark backgrounds. Stripes, hover and dividers become their white-alpha mirrors: stripes and hover rgba(255, 255, 255, 0.05), dividers rgba(255, 255, 255, 0.1), inactive selection rgba(255, 255, 255, 0.14). Text moves to rgba(255, 255, 255, 0.85), with secondary columns at 50%. Both .p-dark-mode and .p-auto-dark-mode are supported.

Code

<ul class="p-list">
  <li class="p-list-group-title">Favorites</li>
  <li class="p-list-row p-selected" aria-selected="true">
    <span class="p-list-chevron">›</span>
    <span class="p-list-icon"><img src="folder.png" alt="" /></span>
    Downloads
    <span class="p-list-detail">128</span>
  </li>
  <li class="p-list-row" data-p-level="1">Screenshots</li>
</ul>

<table class="p-table">
  <thead>
    <tr><th aria-sort="ascending">Name</th><th>Size</th></tr>
  </thead>
  <tbody>
    <tr class="p-selected"><td>Mockups.fig</td><td>48 MB</td></tr>
  </tbody>
</table>

For interactive lists give rows tabindex="0" and manage aria-selected. With prefers-contrast: more, the inactive selection gains a 1px outline so state never relies on the 14% fill alone, and table rows get a 1px rule so they don’t rely on the 5% stripes.

Copied