# List

> A list shows a set of rows, each with a line of text and optionally an icon, a second line, and something at the end.

Source: https://contributors.home-assistant.io/design/components/list/

Live demo of `ha-list`, `ha-list-item`, `ha-svg-icon`.

```html
<ha-list style="width: 100%">
  <ha-list-item graphic="icon" twoline hasMeta>
    <ha-svg-icon slot="graphic" path="M12,21L15.6,16.2C14.6,15.45 13.35,15 12,15C10.65,15 9.4,15.45 8.4,16.2L12,21M12,3C7.95,3 4.21,4.34 1.2,6.6L3,9C5.5,7.12 8.62,6 12,6C15.38,6 18.5,7.12 21,9L22.8,6.6C19.79,4.34 16.05,3 12,3M12,9C9.3,9 6.81,9.89 4.8,11.4L6.6,13.8C8.1,12.67 9.97,12 12,12C14.03,12 15.9,12.67 17.4,13.8L19.2,11.4C17.19,9.89 14.7,9 12,9Z"></ha-svg-icon>
    Network
    <span slot="secondary">Connected over Wi-Fi</span>
    <ha-svg-icon slot="meta" path="M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z"></ha-svg-icon>
  </ha-list-item>
  <ha-list-item graphic="icon" twoline hasMeta>
    <ha-svg-icon slot="graphic" path="M10,20V14H14V20H19V12H22L12,3L2,12H5V20H10Z"></ha-svg-icon>
    Location
    <span slot="secondary">Home</span>
    <ha-svg-icon slot="meta" path="M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z"></ha-svg-icon>
  </ha-list-item>
  <ha-list-item graphic="icon" twoline hasMeta>
    <ha-svg-icon slot="graphic" path="M12,15.5A3.5,3.5 0 0,1 8.5,12A3.5,3.5 0 0,1 12,8.5A3.5,3.5 0 0,1 15.5,12A3.5,3.5 0 0,1 12,15.5M19.43,12.97C19.47,12.65 19.5,12.33 19.5,12C19.5,11.67 19.47,11.34 19.43,11L21.54,9.37C21.73,9.22 21.78,8.95 21.66,8.73L19.66,5.27C19.54,5.05 19.27,4.96 19.05,5.05L16.56,6.05C16.04,5.66 15.5,5.32 14.87,5.07L14.5,2.42C14.46,2.18 14.25,2 14,2H10C9.75,2 9.54,2.18 9.5,2.42L9.13,5.07C8.5,5.32 7.96,5.66 7.44,6.05L4.95,5.05C4.73,4.96 4.46,5.05 4.34,5.27L2.34,8.73C2.21,8.95 2.27,9.22 2.46,9.37L4.57,11C4.53,11.34 4.5,11.67 4.5,12C4.5,12.33 4.53,12.65 4.57,12.97L2.46,14.63C2.27,14.78 2.21,15.05 2.34,15.27L4.34,18.73C4.46,18.95 4.73,19.03 4.95,18.95L7.44,17.94C7.96,18.34 8.5,18.68 9.13,18.93L9.5,21.58C9.54,21.82 9.75,22 10,22H14C14.25,22 14.46,21.82 14.5,21.58L14.87,18.93C15.5,18.67 16.04,18.34 16.56,17.94L19.05,18.95C19.27,19.03 19.54,18.95 19.66,18.73L21.66,15.27C21.78,15.05 21.73,14.78 21.54,14.63L19.43,12.97Z"></ha-svg-icon>
    System
    <span slot="secondary">Updates, backups, and logs</span>
    <ha-svg-icon slot="meta" path="M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z"></ha-svg-icon>
  </ha-list-item>
</ha-list>
```

## Overview

A list shows a set of similar things people scan, pick from, or open: providers to log in with, menu options, the devices in an area. Every row has the same structure, so the eye can run down the left edge and find what it needs.

> [!NOTE]
> `ha-list` and `ha-list-item` are the older lists, built on Material Web Components. The frontend is moving to a newer list family: `ha-list-base`, `ha-list-item-base`, `ha-list-item-button`, `ha-list-selectable`, and `ha-list-nav`. Many lists in the frontend already use it. For new code, use the new family: see [the new list family](https://contributors.home-assistant.io/design/components/list/#the-new-list-family) at the end of this page. Most of this page covers the older list, since a good number of screens still use it.

## When to use

Use a list for:

- A set of similar items that people scan, pick from, or open
- Navigation to the next level, with a chevron at the end of each row
- Rows that only show information, like a value or a message

Don't use a list for:

- Actions on one item. Put them in a [dropdown](https://contributors.home-assistant.io/design/components/dropdown/).
- Picking one option from a few that need explaining. Use a [select box](https://contributors.home-assistant.io/design/components/select-box/).
- Content that people show and hide. Use an [expansion panel](https://contributors.home-assistant.io/design/components/expansion-panel/).

## Anatomy

1. **List**: the container, with 8px of padding at the top and bottom
2. **Row**: one item of the list
3. **Graphic**: optional, an icon, avatar, or control at the start of the row
4. **First line**: the main text of the row
5. **Second line**: optional, a short detail below the first line
6. **Meta**: optional, content at the end, like a chevron or a short value

## Variants

### Rows

Start with the text, then add only what helps people recognize a row:

- An **icon** at the start.
- A **second line**, for a short detail, like a state or a description.
- Something at the **end**, like a chevron when the row opens something, or a short value.

Live demo of `ha-list`, `ha-list-item`, `ha-svg-icon`.

```html
<ha-list style="width: 100%">
  <ha-list-item>Just text</ha-list-item>
  <ha-list-item twoline>
    Two lines
    <span slot="secondary">With a second line of detail</span>
  </ha-list-item>
  <ha-list-item graphic="icon">
    <ha-svg-icon slot="graphic" path="M12,2A7,7 0 0,0 5,9C5,11.38 6.19,13.47 8,14.74V17A1,1 0 0,0 9,18H15A1,1 0 0,0 16,17V14.74C17.81,13.47 19,11.38 19,9A7,7 0 0,0 12,2M9,21A1,1 0 0,0 10,22H14A1,1 0 0,0 15,21V20H9V21Z"></ha-svg-icon>
    With an icon
  </ha-list-item>
  <ha-list-item hasMeta>
    With something at the end
    <span slot="meta">3</span>
  </ha-list-item>
  <ha-list-item disabled>Disabled</ha-list-item>
</ha-list>
```

### Graphic size

A row reserves room at the start for its graphic, in one of these sizes: an icon, an avatar (a round image), a medium or large image, or a control like a checkbox.

### Rows that only show information

A row that does nothing when selected, like a row that only shows a value or a message, can be made non-interactive. It then has no ripple and no keyboard focus.

## Behavior

- **Hover and pressed**: an interactive row shows a ripple. It is black unless the theme sets another color. The dark theme sets it to a light gray. An activated row uses the primary color for its ripple.
- **Focus**: one row at a time is in the tab order. Arrow keys move focus between the rows.
- **Activated**: in a list where a row can be activated, the selected row gets a primary tint at 12% opacity, and its graphic turns to the primary color.
- **Disabled**: the text turns to the disabled text color, and the row can't be selected.
- **Long text**: the first line is cut off with an ellipsis when it doesn't fit. The second line is cut off too, unless the row lets it wrap. Then the row grows with it.

## Specs

| Property | Value | Token |
| --- | --- | --- |
| Row height, one line | 48px | None |
| Row height, one line with an icon or avatar | 48px | None |
| Row height, two lines | 72px | None |
| Row height, one line with a medium or large graphic | 72px | None |
| Padding left and right | 20px | `--mdc-list-side-padding` |
| List padding top and bottom | 8px | `--mdc-list-vertical-padding` |
| Icon size | 24px | `--mdc-list-item-graphic-size` |
| Avatar size | 40px | `--mdc-list-item-graphic-size` |
| Medium and large graphic size | 56px | `--mdc-list-item-graphic-size` |
| Space between icon and text, one line | 20px | `--mdc-list-item-graphic-margin` |
| Space between icon and text, two lines | 32px | `--mdc-list-item-graphic-margin` |
| Meta size | 24px | `--mdc-list-item-meta-size` |
| First line font size | 1rem | `--mdc-typography-subtitle1-font-size` |
| Second line font size | 0.875rem | `--mdc-typography-body2-font-size` |
| Disabled text color | `#bdbdbd` in the light theme, `#6f6f6f` in the dark theme | `--disabled-text-color` |
| Activated tint | 12% opacity | `--mdc-ripple-activated-opacity` |

## Guidelines

Do and don't, as live demos.

**Do:** Keep the first line short, and put details on the second line.

```html
<ha-list style="width: 100%">
    <ha-list-item twoline>Network<span slot="secondary">Connected over Wi-Fi</span></ha-list-item>
  </ha-list>
```

**Don't:** Put everything in a first line that gets cut off.

```html
<ha-list style="width: 100%">
    <ha-list-item>Network settings, connected over Wi-Fi to your home network</ha-list-item>
  </ha-list>
```

See [UI text](https://contributors.home-assistant.io/design/ui-text/) for how to write labels.

## Accessibility

### Keyboard

| Key | Action |
| --- | --- |
| <kbd>Tab</kbd> | Moves focus into the list, to one row, and out of it again. |
| <kbd>Arrow down</kbd> and <kbd>Arrow up</kbd> | Move focus to the next or previous row. A list can let focus wrap from the last row to the first, and back. |
| <kbd>Home</kbd> and <kbd>End</kbd> | Move focus to the first or last row. |
| <kbd>Enter</kbd> or <kbd>Space</kbd> | Activates the focused row. |

### Focus

One row at a time is in the tab order. Arrow keys move focus between the rows.

### Target size

A row is at least 48px high, and as wide as the list.

### Screen readers

By default, a screen reader gets no list structure: the list and its rows have no role, so it hears the text of the rows. Disabled rows are announced as disabled. The list can get a role and a name in code, see below.

### In the code

- The list and its rows have no role by default. Set `innerRole` on the list and `itemRoles` for the rows, like `listbox` and `option`, and `innerAriaLabel` for the name of the list.
- A disabled row has `aria-disabled="true"`.
- With the role `option`, a selected row has `aria-selected="true"`.
- A row with `noninteractive` can't take focus.

## Related

- [Dropdown](https://contributors.home-assistant.io/design/components/dropdown/): a menu of actions
- [Select box](https://contributors.home-assistant.io/design/components/select-box/): picking one option from a few
- [Expansion panel](https://contributors.home-assistant.io/design/components/expansion-panel/): content that people show and hide

## In code

The element is `<ha-list>`, with `<ha-list-item>` rows. Both extend the [Material Web Components list](https://github.com/material-components/material-web/tree/mwc/packages/list).

```html
<ha-list>
  <ha-list-item graphic="icon" twoline hasMeta>
    <ha-svg-icon slot="graphic" path="..."></ha-svg-icon>
    Network
    <span slot="secondary">Connected over Wi-Fi</span>
    <ha-svg-icon slot="meta" path="..."></ha-svg-icon>
  </ha-list-item>
</ha-list>
```

Attribute names are case-insensitive in HTML, so `hasMeta` and `hasmeta` are the same.

### Attributes of ha-list

- `activatable`: shows the selected row as activated.
- `multi`: allows selecting more than one row.
- `wrapFocus`: arrow keys wrap from the last row to the first, and back.
- `rootTabbable`: makes the list itself focusable, instead of the first row.
- `noninteractive`: turns off selection and keyboard navigation for the whole list.
- `innerRole` and `innerAriaLabel`: the role and the accessible name of the inner list element.
- `itemRoles`: the role given to every row, like `option`.

### Attributes of ha-list-item

- `graphic`: reserves room for content in the `graphic` slot. `icon`, `avatar`, `medium`, `large`, or `control`.
- `twoline`: shows the `secondary` slot as a second line.
- `multiline-secondary`: lets the second line wrap, instead of cutting it off.
- `hasMeta`: shows the `meta` slot at the end.
- `noninteractive`: the row can't be selected or focused.
- `disabled`: disables the row.
- `selected` and `activated`: the selection state.
- `value`: a value that identifies the row.

### Slots of ha-list-item

- Default: the first line of text.
- `secondary`: the second line, when `twoline` is set.
- `graphic`: an icon, avatar, or control at the start, when `graphic` is set.
- `meta`: content at the end, when `hasMeta` is set.

### Events

- `action` on `ha-list`: a row was activated. `detail.index` is the index of the row.
- `selected` on `ha-list`: the selection changed. `detail.index` is the selected index, or a set of indexes with `multi`.
- `request-selected` on `ha-list-item`: the row asks to be selected or deselected. `detail.selected` is the new state, and `detail.source` says whether it came from an `interaction` or a `property` change.

### Styling

- `--mdc-list-side-padding`: the padding on both sides of a row. Defaults to `20px`.
- `--mdc-list-side-padding-left` and `--mdc-list-side-padding-right`: the padding of one side.
- `--mdc-list-item-graphic-margin`: the space between the graphic and the text.
- `--mdc-list-item-meta-display`: the display of the meta slot.

Source: [`src/components/ha-list.ts`](https://github.com/home-assistant/frontend/blob/dev/src/components/ha-list.ts) and [`src/components/ha-list-item.ts`](https://github.com/home-assistant/frontend/blob/dev/src/components/ha-list-item.ts)

## The new list family

The new lists are accessible and keyboard friendly from the start. Pick the container by what the list means, then the item by what a row does. They are not part of the live components on this site yet, so there is no demo.

### Containers

- `<ha-list-base>`: a plain list, with the role `list`. The arrow keys move focus between rows, <kbd>Home</kbd> and <kbd>End</kbd> jump to the first and last enabled row, <kbd>Page up</kbd> and <kbd>Page down</kbd> move a page, and <kbd>Enter</kbd> or <kbd>Space</kbd> activates the focused row. Only one row is in the tab order at a time.
- `<ha-list-selectable>`: a list people pick from, with the role `listbox`. Its rows are `<ha-list-item-option>`. Set `multi` to allow picking more than one.
- `<ha-list-nav>`: a list of links, wrapped in a `<nav>` landmark. Its rows are `<ha-list-item-button>` with an `href`. Name the landmark with `aria-label`.

Attributes of the containers:

- `wrap-focus`: the arrow keys wrap around at the ends.
- `virtual-focus`: focus stays outside the list, like in the search field of a picker. The list marks the row the keyboard points at with `active`, and scrolls it into view. The element that has focus moves it with `moveActiveItem()`.
- `aria-label`: the accessible name.
- `multi`: on `ha-list-selectable` only, allows picking more than one option.

Events:

- `ha-list-activated`: <kbd>Enter</kbd> or <kbd>Space</kbd> on a focused row. `detail` has the `index` and the `item`.
- `ha-list-item-selected` and `ha-list-item-deselected`: on `ha-list-selectable`, an option was picked or unpicked. `detail` is the index of the option. Deselected only fires with `multi`.

Styling: `--ha-list-gap` sets the space between rows, `--ha-list-padding` the padding around the list. Both default to `0`.

### Items

Every item has the same row layout, with these slots and attributes:

- `start`: the leading part, like an icon or an avatar.
- `end`: the trailing part, like a value or a chevron.
- `headline` and `supporting-text`: the first and second line, as an attribute or a slot.
- `content`: replaces the whole middle part.
- `disabled`: dims the row and blocks the pointer.

The items:

- `<ha-list-item-base>`: a row that only shows information, with the role `listitem`. Set `interactive` to put it in the keyboard navigation of the list without an action, like a row people can sort.
- `<ha-list-item-button>`: a row that does something. It renders a link when it has an `href`, and a button otherwise. The whole row is the target.
- `<ha-list-item-option>`: a row people can pick, with the role `option` and `aria-selected`. The list owns the selection. With `appearance="checkbox"` it shows a checkbox, at the `start` or the `end` with `selection-position`. The default appearance, `line`, highlights the selected row.

Styling of the rows:

- `--ha-row-item-min-height`: the minimum height of a row. Defaults to `48px`.
- `--ha-row-item-padding-block`, `--ha-row-item-padding-inline`, and `--ha-row-item-gap`: the padding of a row, and the space between its parts.
- `--ha-list-item-focus-background` and `--ha-list-item-active-background`: the background on keyboard focus, and of the `active` row.
- `--ha-list-item-selected-background`: the background of a selected option, with `appearance="line"`.

Source: [`src/components/list/`](https://github.com/home-assistant/frontend/tree/dev/src/components/list) and [`src/components/item/`](https://github.com/home-assistant/frontend/tree/dev/src/components/item)
