List Item
Selectable row with icon slots, used on its own or as the option of list and select.
c2-list-item is the row that c2-list and c2-select are built from. On its own it is a self-contained toggle: a click, Enter or Space flips selected and fires selected-change. Inside a c2-list the list takes over: it matches each row’s value against its own, sets selected for you and handles the keyboard, so rows in a list never carry the attribute themselves. The default slot is the content, description a second muted line; prefix-icon and suffix-icon take an inline SVG, a c2-feather-* icon or a c2-mat-icon and are sized by --c2-list-item__icon--size. href turns the row into a link. label is the short text a select shows in its trigger when the row content is richer than a line of text. Rows expose role="button" with aria-pressed on their own and role="option" with aria-selected inside a list, and draw a focus ring for keyboard users.
Import
import '@c2n/components/list-item'The examples use icons from the separate @c2n/feather-icons package: npm install @c2n/feather-icons. The c2-mat-icon examples also need a Material icon font, which c2-mat-icon does not load: npm install @fontsource/material-icons, then import '@fontsource/material-icons'.
Usage
Rows stretch to their container, so give the wrapper a width. Hover, selected and disabled each have their own set of variables.
Behaviour
- Standalone: a click toggles
selectedand firesselected-changewithdetail.selectedanddetail.value. - In a list: the click bubbles to the
c2-list, which updates itsvalueand pushes the selected state back down. Listen toselection-changeon the list (or the select) instead. - Adjacent selection: in a
multiplelist, selected rows that touch lose the corner radius between them and read as one block; a selected row on its own keeps its full radius. The joined rows matchc2-list-item:state(joined-before)/:state(joined-after); earlier releases wrotejoined-before/joined-afterattributes on them instead (c2-list-item[joined-before]→c2-list-item:state(joined-before)). - Keyboard: a standalone row is a tab stop; Enter and Space toggle it. In a list the list moves focus with the arrow keys and selects with Enter or Space.
description: a second line under the content, muted and smaller;labelkeeps the select trigger to the first line.href: the row renders as a link (role="link"); inside a list it still takes part in the selection.label: what ac2-selectshows for the row. Without it the trigger shows the row’s text content, which for a two-line row would be both lines.data: any object you attach to the row; a list or select returns it inselection-changenext to the value.
const item = document.querySelector('c2-list-item')
item.addEventListener('selected-change', (event) => {
console.log(event.detail) // { selected: true, value: 'inbox' }
})