List
Usage
List presents a collection of related entries, and ListItem is one row inside it. The pair renders a semantic <ul> or <ol> and lays out every row as start content, label, description, and end content, so a settings screen, an inbox, or a set of steps does not have to rebuild that row layout each time.
One row needs nothing more than a label:
<script setup lang="ts">
import { List, ListItem } from '@astryx-vue/core/List'
</script>
<template>
<List header="Inbox">
<ListItem label="Mentions" description="Comments that name you" />
<ListItem label="Build finished" description="main passed every check" />
</List>
</template>description is the secondary line under the label. The startContent and endContent slots place an icon, an avatar, a badge, or an action at either end of the row, and label and description each have a same-named slot for content that needs richer markup than a string.
The list sets the density for all of its rows, and a single row can override it. compact uses 4px of block padding, balanced is the 8px default, and spacious uses 12px and widens the inline padding by one step as well. hasDividers rules a line between neighbouring rows, and the last row never draws one.
listStyle decides what appears in front of each row: disc draws a filled bullet, circle draws an outlined one, and decimal switches the list to an <ol> and numbers the rows, with start choosing the first number. The default none draws no marker at all.
A row becomes interactive in one of two ways. Give it onClick and a button appears inside the row, filling the content area, so keyboard users can tab to it and press Enter or Space; give it href and that same place becomes a link, with noopener and noreferrer added automatically when target="_blank". Clicking another control inside the row, such as a button in endContent, does not run the row's own action.
isSelected marks the row as selected. When the row carries a role that permits aria-selected — option, tab, or row, for instance — the state is written there; otherwise it falls back to aria-current="true", which is valid on any element, so assistive technology still hears which row is current. isDisabled makes the row inert and dims its content.
The header slot renders a title above the list and associates it through aria-labelledby, so a screen reader announces the title when it enters the list. edgeCompensation="inline" is for a list placed inside a padded container: it pulls every row toward the container's inline content edges so the row text lines up with a sibling heading, cancelling no more than the container padding each edge actually publishes.
The package also exports the more general Item primitive. ListItem is that primitive rendered as an <li> with the density and marker from its list; use Item directly when the same row layout is needed outside a list, or when you need its extra controls — as, align, labelLines, descriptionLines, and layout. Most screens only need List and ListItem.
Best practices
| Guidance | Practices |
|---|---|
| Do | Give the list a header. A screen reader announces it on entering the list, and sighted users get the context of the collection immediately. |
| Do | Put icons, avatars, badges, or timestamps in startContent and endContent, so the two ends of a row carry the category and the status. |
| Do | Use isSelected to distinguish the current row and let the component pick aria-selected or aria-current from the row's role, instead of writing ARIA by hand. |
| Do | Set descriptionLines when the length of the content varies, or rely on the default single-line truncation for string descriptions, so the row height does not jump. |
| Don't | Nest a second control inside an interactive row as its main action. The row's button already fills the content area, and two click targets make the focus order and the behaviour hard to predict. |
| Don't | Use a list for a single entry. A list means the entries belong together; a short paragraph reads more naturally for one item. |
| Don't | Mix interactive and static rows in one list without a visible difference, leaving users unsure which rows open something. |
Examples
Basic
- MentionsComments that name you 3
- Assigned to youTwo issues are waiting for a review 2
- Build finishedmain passed every check
A list with a header, rows that carry an icon on the left, and a badge or a chevron on the right.
Densities
- Design reviewToday at 14:00
- Release notesDraft shared with the team
- Design reviewToday at 14:00
- Release notesDraft shared with the team
- Design reviewToday at 14:00
- Release notesDraft shared with the team
The three density steps change the block padding of every row, and a single row can override the density its list sets.
Markers
- First point
- Second point
- Third point
- Nested point
- Nested point
- Nested point
- Third step
- Fourth step
- Fifth step
Disc and circle draw a bullet in front of each row, while decimal renders an ordered list whose numbering can start at any value.
Selection and interaction
Rows that carry a click handler become buttons with hover and pressed states; the selected row is marked, and the disabled row is inert.