List
A selectable list of rows (an APG listbox) in single or multiple selection; the selected row is the selection fill with a check glyph and an optional metadata column.
stable · light DOM · 4.0.0. Light DOM retains static content, native semantics, label relationships and host composition without duplicating controls.
Live variants
single
- default
- extended
- high-contrast
<j3w1-list id="example-list-single"><ul class="list" role="listbox" aria-label="Profiles">
<li class="list-option" role="option" aria-selected="true" tabindex="0"><span class="list-check" aria-hidden="true">✓</span><span class="list-label">default</span></li>
<li class="list-option list-option-demo-target" role="option" aria-selected="false" tabindex="-1"><span class="list-check" aria-hidden="true">✓</span><span class="list-label">extended</span></li>
<li class="list-option" role="option" aria-selected="false" tabindex="-1"><span class="list-check" aria-hidden="true">✓</span><span class="list-label">high-contrast</span></li>
<li class="list-option" role="option" aria-selected="false" aria-disabled="true" tabindex="-1"><span class="list-check" aria-hidden="true">✓</span><span class="list-label">print</span></li>
</ul></j3w1-list>multi
- FX-320 reflow
- FX-ZOOM-200 text zoom
- FX-RM reduced motion
- FX-TOUCH pointer
<j3w1-list id="example-list-multi"><ul class="list" role="listbox" aria-label="Fixtures" aria-multiselectable="true">
<li class="list-option" role="option" aria-selected="true" tabindex="0"><span class="list-check" aria-hidden="true">✓</span><span class="list-label">FX-320 reflow</span></li>
<li class="list-option list-option-demo-target" role="option" aria-selected="false" tabindex="-1"><span class="list-check" aria-hidden="true">✓</span><span class="list-label">FX-ZOOM-200 text zoom</span></li>
<li class="list-option" role="option" aria-selected="true" tabindex="-1"><span class="list-check" aria-hidden="true">✓</span><span class="list-label">FX-RM reduced motion</span></li>
<li class="list-option" role="option" aria-selected="false" aria-disabled="true" tabindex="-1"><span class="list-check" aria-hidden="true">✓</span><span class="list-label">FX-TOUCH pointer</span></li>
</ul></j3w1-list>with-meta
- text-field
- tabs
- menu
- chart
<j3w1-list id="example-list-with-meta"><ul class="list" role="listbox" aria-label="Components">
<li class="list-option" role="option" aria-selected="true" tabindex="0"><span class="list-check" aria-hidden="true">✓</span><span class="list-label">text-field</span><span class="list-meta">14 states</span></li>
<li class="list-option list-option-demo-target" role="option" aria-selected="false" tabindex="-1"><span class="list-check" aria-hidden="true">✓</span><span class="list-label">tabs</span><span class="list-meta">7 states</span></li>
<li class="list-option" role="option" aria-selected="false" tabindex="-1"><span class="list-check" aria-hidden="true">✓</span><span class="list-label">menu</span><span class="list-meta">8 states</span></li>
<li class="list-option" role="option" aria-selected="false" aria-disabled="true" tabindex="-1"><span class="list-check" aria-hidden="true">✓</span><span class="list-label">chart</span><span class="list-meta">R2</span></li>
</ul></j3w1-list>Install and register
Use the exact version. If npm publication is pending, install the release tarball from the installation guide.
npm install --save-exact @j3w1/ui@4.0.0import '@j3w1/ui/tokens.css';
import '@j3w1/ui/styles/list.css';
import '@j3w1/ui/register/list';Insert the maintained markup above after loading these imports. Its native children provide accessible names and form behavior; the empty custom tag alone does not create a control.
Copy the complete implementation
npx --package=@j3w1/ui@4.0.0 j3w1-ui copy list --out ./vendor/j3w1/listThe CLI verifies every file before writing and refuses overwrites. Serve the output over HTTP and open index.html. Keep its modules, CSS, tokens and licence notices together.
Public API
attributes
| Name | Type / signature | Meaning |
|---|---|---|
disabled | CustomEvent | Disable the native controls owned by this instance. |
loading | CustomEvent | Mark the primary control busy and prevent duplicate activation. |
properties
| Name | Type / signature | Meaning |
|---|---|---|
disabled | boolean | Delegates disabled state to native children. |
name | string | Native control name; application form keys remain explicit. |
methods
| Name | Type / signature | Meaning |
|---|---|---|
refresh | (): void | Reconnect behavior after replacing native child structure. |
focus | (options?: FocusOptions): void | Focus the first usable native control. |
events
| Name | Type / signature | Meaning |
|---|
Dependencies and verification
Registered components: none. Style dependencies: none.
Package presence establishes an available implementation. Actual passes depend on the tested artifact and environment. Read specification execution evidence; read packed-consumer evidence; inspect the complete state matrix.
Full implementation manifest, API and token dependency closure
Canonical specification
List list
A selectable list of rows (an APG listbox) in single or multiple selection; the selected row is the selection fill with a check glyph and an optional metadata column.
Report an issue with this component
Tokens
Focus a role to inspect its values; follow its link for persistent usage and source details.
| Part | Role | Value | Use |
|---|---|---|---|
root.bg | color.surface.defaultapproveduse | #0d0707 | D-041 surface.default: color.primitive.modern.panel. |
root.border | color.border.controlapproveduse | #c81a1a | D-041 owner correction: red control and floating-frame borders, distinct from rose text. |
row.text | color.text.defaultapproveduse | #e99499 | D-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills. |
row.bg-hover | color.interaction.hover.bgapproveduse | #1c1010 | D-041 interaction.hover.bg: color.primitive.modern.hover. |
row.divider | color.border.dividerapproveduse | #482b2b | D-041 border.divider: color.primitive.modern.divider. |
row.ring | color.interaction.focus.ringobserveduse | #e53935 | 1px dashed focus ring on controls and rows. |
row.text-disabled | color.text.disabledapproveduse | #a3676b | D-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills. |
selected.bg | color.interaction.selection.bgapproveduse | #531310 | Selected row, tab, workspace; D-027 recessed the fill, leaving the 2px indicator and the check to carry selection. |
selected.text | color.interaction.selection.textobserveduse | #f4eeee | Text on the selection. |
selected.ring | color.interaction.focus.ringobserveduse | #e53935 | 1px dashed focus ring on controls and rows. |
selected.inactive-bg | color.interaction.selection.inactive-bgobserveduse | #420f0c | Selection while the container is not focused. |
selected.inactive-text | color.interaction.selection.inactive-textapproveduse | #e99499 | D-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills. |
check.glyph | color.interaction.selection.textobserveduse | #f4eeee | Text on the selection. |
meta.text | color.text.mutedapproveduse | #d4868b | D-041 owner correction: rose is the default UI and reading foreground; near-white is reserved for document headings, highlights and contrast-critical fills. |
State matrix
Every declared state and combination, statically rendered; the default cell is live. Sizes: compact, comfortable (switch with the density control above).
| State | Single | Multi | With metadata |
|---|---|---|---|
default |
|
|
|
hover | |||
focus-visible | |||
selected | |||
selected+focus-visible | |||
selected+container-inactive | |||
disabled |
Purpose
Choose one or several rows from a short, visible set. It holds a selection
and never navigates: rows that lead somewhere are sidebar-nav, rows with
columns a table, a long set that needs filtering a combobox.
Anatomy
Parts as listed in the anatomy; on a selected row every part, metadata and
✓ included, takes color.interaction.selection.text.
States
| State | Visual | Non-colour channel |
|---|---|---|
| default | text color.text.default; no fill; check gutter empty | — |
| hover | background → color.interaction.hover.bg | cursor: pointer |
| focus-visible | 1px dashed color.interaction.focus.ring at −2px on the option | the ring |
| selected | fill color.interaction.selection.bg; text and glyph color.interaction.selection.text | aria-selected="true"; the ✓ glyph |
| selected+focus-visible | the fill and 1px dashed color.interaction.focus.ring at −2px | both visible at once |
| selected+container-inactive | fill color.interaction.selection.inactive-bg with color.interaction.selection.inactive-text; no ring | lightness drop between the two fills; the glyph stays |
| disabled | text color.text.disabled; no fill; no hover; still reachable by arrow keys | aria-disabled="true"; cursor: not-allowed |
Precedence: disabled > selected > hover; focus-visible is always drawn.
Keyboard
The list costs one tab stop (tabindex="0" on the selected or first
option, -1 on the rest). Disabled options are reached and announced, never
skipped.
Accessibility
aria-label or aria-labelledby names the listbox; every option carries
aria-selected, including "false". The ✓ is aria-hidden;
aria-selected is the state. Metadata sits inside the option so it is read
with the label. Text meets 4.5:1; frame and rings 3:1. Rows are at least 24
CSS pixels tall, with the check gutter as the leading target area.
Portability
Rows with a background, a glyph gutter and an outline; nothing else. Native
list views take the fill, inactive fill and divider colour and keep their
own keyboard model. The inactive fill applies when the list’s window or pane
loses focus; the web detects it with :focus-within on the pane.
Non-examples
A selected row marked by a border or check without the fill. Rounded row highlights. Muted metadata left on the selection fill. Every row a tab stop. Navigating on selection. Disabled rows removed from the arrow-key order. Hover that changes text colour. A frameless list on the canvas.
Contrast report
13 declared pairs measured on resolved sRGB values with the WCAG 2.x formula; 0 waived (decorative only), 0 failing. A pass is a design target for the named role, not an application-wide conformance claim.
| Pair | State | Kind | Foreground | Background | Ratio | Min | Result |
|---|---|---|---|---|---|---|---|
| list default text | default | text | color.text.default #e99499 | color.surface.default #0d0707 | 8.72 | 4.5 | pass |
| list default border | default | ui | color.border.control #c81a1a | color.surface.default #0d0707 | 3.44 | 3 | pass |
| list hover text | hover | text | color.text.default #e99499 | color.interaction.hover.bg #1c1010 | 8.10 | 4.5 | pass |
| list focus-visible text | focus-visible | text | color.text.default #e99499 | color.surface.default #0d0707 | 8.72 | 4.5 | pass |
| list focus-visible outline | focus-visible | ui | color.interaction.focus.ring #e53935 | color.surface.default #0d0707 | 4.73 | 3 | pass |
| list selected text | selected | text | color.interaction.selection.text #f4eeee | color.interaction.selection.bg #531310 | 12.47 | 4.5 | pass |
| list selected+focus-visible text | selected+focus-visible | text | color.interaction.selection.text #f4eeee | color.interaction.selection.bg #531310 | 12.47 | 4.5 | pass |
| list selected+focus-visible outline | selected+focus-visible | ui | color.interaction.focus.ring #e53935 | color.interaction.selection.bg #531310 | 3.38 | 3 | pass |
| list selected+container-inactive text | selected+container-inactive | text | color.interaction.selection.inactive-text #e99499 | color.interaction.selection.inactive-bg #420f0c | 7.02 | 4.5 | pass |
| metadata column on the list surface | — | text | color.text.muted #d4868b | color.surface.default #0d0707 | 7.22 | 4.5 | pass |
| metadata column on the hover fill | hover | text | color.text.muted #d4868b | color.interaction.hover.bg #1c1010 | 6.70 | 4.5 | pass |
| disabled option text (exempt; house floor 3:1) | disabled | ui | color.text.disabled #a3676b | color.surface.default #0d0707 | 4.48 | 3 | pass |
| row divider (decorative) | — | ui | color.border.divider #482b2b | color.surface.default #0d0707 | 1.58 | 1 | pass |
Keys
| Key | Action |
|---|---|
| Tab | Enters the list at the selected option, or the first option when nothing is selected; a second Tab leaves the list. |
| Down / Up | Moves focus to the next or previous option; in single selection the selection follows focus. |
| Home / End | Moves focus to the first or last option. |
| Space | Toggles the focused option in a multi-select list. |
| Shift+Down / Shift+Up | Extends the selection by one in a multi-select list. |
| Ctrl+A | Selects every option in a multi-select list. |
| A-Z | Moves focus to the next option starting with the typed character. |
For agents
Component JSON ·Implementation brief ·Build a task kit ·
Related: card select combobox tree table
Stress fixtures: FX-LONG FX-320 FX-ZOOM-200 FX-I18N FX-RTL FX-RM FX-HC FX-DENSITY FX-STATE-MATRIX