C-16 · Components · Content
All elements · List on the Components page
Last checked 2026-10-22 · Awaiting approval · Accessibility tests
Approve List
Approving as
| Axis | Values |
|---|---|
data-divided · data-bordered · data-dense ·
data-interactive
|
layout flags |
__item[data-state=selected|dragging] · [aria-disabled] |
row state |
__leading · __body · __primary ·
__secondary · __trailing · __handle ·
__header
|
parts |
- Today
- jd Approve invoice INV-2026-0412Assigned by Jane Doe · Acme Holdings · due tomorrow High2h
- ak Index scanned batch #204114 pages · scan queue Medium5h
- mr Being draggeddata-state="dragging"
- Locked taskChecked out by another user
- Dense row1.2 MB
- Another dense row88 KB
Guidance
When to use
- Show a column of tasks, documents or people where each row has a primary line, a secondary line and a few trailing details.
-
Let users select rows with a leading checkbox for bulk actions, and open a row by clicking it
(
data-interactive). - Group rows under sticky headers such as Today and Yesterday with
__header. -
Reorder rows by drag with
__handle, showing the moving row withdata-state="dragging". - Fit more rows in a side pane with
data-dense.
When to consider something else
- When users compare values across rows or sort by columns, use Table. See Table.
- When there are many rows with inline editing, column sizing or virtual scrolling, use Data grid. See DataGrid.
- When the user picks one value from options inside a form, use Select. See Select.
- When each item needs media, a body and its own actions, use Card. See Card.
- When the items nest, use Tree. See Tree.
Usability
-
Put the one thing users scan for in
__primaryand keep__secondaryto one line of context. - Keep trailing details short: a status Chip and a time.
-
Mark a row the user cannot act on with
aria-disabled="true"and say why in the secondary line, as "Checked out by another user" does. - Show the number selected and the bulk actions in a toolbar above the list once any row is checked.
- Don't make the whole row a button and also put buttons inside it; use a link or button on the primary text and keep the rest plain.
- Don't rely on drag as the only way to reorder.
- Don't use dense rows with two lines of text.
Accessibility
Keyboard
| Keys | Action |
|---|---|
| Tab / Shift+Tab | Moves between each row's checkbox and the row's open control. |
| Space | Checks or unchecks the focused row checkbox. |
| Enter | Opens the row when its open control is a link or button. |
| Arrow Up / Arrow Down | Required for reorder: with the handle focused, the binding must offer a keyboard move, such as Alt+Arrow keys or Move up and Move down menu items. |
Roles and names
-
The list is a
ulwithli.qf-list__itemrows;__headeris anliand should also be marked up as a heading, or the list split into labelled groups. - Each row checkbox needs a unique name; the binding must label it with the row's primary text ("Select Approve invoice INV-2026-0412"), not "Select item" on every row.
-
data-state="selected"is visual only; the checked checkbox carries the state. If the list is a single-select picker, userole="listbox"witharia-selectedinstead. aria-disabled="true"on a row only styles it; disable the controls inside it too.-
Avatars need a name:
aria-hiddenwhen the name is already in the row text, or anaria-labelotherwise.
Focus
- Each interactive part inside a row is a Tab stop; a long list should use a roving model or Data grid so users are not forced through hundreds of stops.
- After a row is removed, move focus to the next row, or the previous one at the end.
- All controls show the shared focus ring; a sticky header must not cover the focused row (2.4.11).
Other requirements
- Dragging needs a single-pointer alternative, such as Move up and Move down actions (2.5.7).
- Selection must show by more than the fill: the checked checkbox does this (1.4.1); the fill needs 3:1 against the surface (1.4.11).
- Priority Chips must say the priority in words, not by color alone (1.4.1).
- Announce bulk-action results, such as "3 tasks approved", with a Toast or live region (4.1.3).
Test your implementation too. This guidance covers the element as specified here. How a screen composes it (labels, order, announcements) still needs its own keyboard and screen reader check.
Accessibility tests
Passed the gate (run 358b316 on 2026-10-22): no finding in any theme. Awaiting a person’s approval of the checklist below.
| Area | Automated | A person checks |
|---|---|---|
| General | Passed | Color is never the only cue, text alternatives say the same thing as the graphic, and the element reads the same in the light and the dark theme. |
| Zoom | Passed | At 200% zoom, at 320 CSS pixels wide and with the WCAG text-spacing overrides, nothing is lost, clipped or overlapping. |
| Keyboard | Passed | Every row of the Keyboard table works, focus is always visible and never trapped, and the tab order follows the reading order. (4 rows) |
| Screen reader | Passed | With NVDA or JAWS on Windows and VoiceOver on macOS, names, roles and states are announced as Roles and names says, and changes are announced once. (5 items) |
Approving. When the checklist passes on the checked run, record it with
bun run a11y:approve -- list --by "Your name" and commit
a11y/approvals.json with the rebuilt pages.
All test status
Package
Consumers link one stylesheet, css/classic/index.css, which includes every element. The
files below are where this element is defined.
Latest updates
No recorded changes yet.