Skip to Content

List

The List component is used to display a list of ListItems that may optionally have start/end icons and a description.

import * as React from 'react';
import { List, ListItem } from '@itwin/itwinui-react';

export default () => {
  return (
    <List>
      <ListItem>Milk</ListItem>
      <ListItem>Cheese</ListItem>
      <ListItem>Yogurt</ListItem>
    </List>
  );
};

The ListItem component may be used within a List for simple display purposes, or it may be seen as a low-level primitive for building more advanced interactive components (such as a custom dropdown menu or a listbox).

Usage

With subcomponents

The ListItem component comes with the following subcomponents which can be passed as children:

  • ListItem.Icon: Can be placed before or after the main text.
  • ListItem.Description: Description (sublabel) shown under the main text.
  • ListItem.Content: Wrapper for the main text and description. This content expands to fill up the available space and can be used to push an icon to the very end.

There is also a size prop which can be set to 'large' to ensure that all items have a uniform large size even when there is no description.

import * as React from 'react';
import { List, ListItem } from '@itwin/itwinui-react';
import { SvgPlaceholder, SvgCheckmarkSmall } from '@itwin/itwinui-icons-react';

export default () => {
  return (
    <List>
      <ListItem size='large'>
        <ListItem.Icon>
          <SvgPlaceholder />
        </ListItem.Icon>
        <ListItem.Content>
          <div>Milk</div>
          <ListItem.Description>Whole, almond or oat milk</ListItem.Description>
        </ListItem.Content>
      </ListItem>

      <ListItem size='large'>
        <ListItem.Icon>
          <SvgPlaceholder />
        </ListItem.Icon>
        <ListItem.Content>
          <div>Cheese</div>
          <ListItem.Description>Blue or feta</ListItem.Description>
        </ListItem.Content>
        <ListItem.Icon>
          <SvgCheckmarkSmall />
        </ListItem.Icon>
      </ListItem>

      <ListItem size='large'>
        <ListItem.Icon>
          <SvgPlaceholder />
        </ListItem.Icon>
        Yogurt
      </ListItem>
    </List>
  );
};

Actionable

ListItem has an actionable prop which can be set to true to provide hover styling.

Please note that this prop only provides the hover styling and does nothing else. Usually you want to combine this prop either with ListItem.Action (which lets you use an anchor or a button) or with a more advanced component, such as Select, which will do many additional things like set role=option, manage roving tabindex, and handle arrow-key navigation.

With ListItem.Action

When ListItem contains a link, it is recommended to use ListItem.Action instead of a regular anchor link. This component is a wrapper over LinkAction which increases the tap target size (clickable area) of the link to include the padding from list item, and ensures that there is proper hover and focus styling.

import * as React from 'react';
import { List, ListItem } from '@itwin/itwinui-react';

export default () => {
  return (
    <List>
      <ListItem actionable>
        <ListItem.Action href='https://itwinui.bentley.com/docs/button'>
          Buttons
        </ListItem.Action>
      </ListItem>
      <ListItem actionable>
        <ListItem.Action href='https://itwinui.bentley.com/docs/input'>
          Inputs
        </ListItem.Action>
      </ListItem>
      <ListItem actionable>
        <ListItem.Action href='https://itwinui.bentley.com/docs/dialog'>
          Dialog
        </ListItem.Action>
      </ListItem>
    </List>
  );
};

ListItem.Action supports the polymorphic as prop so it can also be rendered as a <button> if it performs an action on the same page.

Interactive states

In more advanced interactive components, your lists might need to show additional states. ListItem comes with the following props which change the visuals accordingly:

  • active - to display the currently active/selected list items
  • disabled - to display disabled/non-interactable list items
  • focused - to force focus styling on a list item

Please note again that these props only adjust the visual styling and do not hold any semantic information. When building accessibile interfaces, it is important to ensure that its various states are properly conveyed to non-sighted users. Since ListItem is intended to be a flexible low-level primitive, it cannot automatically handle these things for you so you must do it yourself.

For example, in addition to the active prop, you might want to use aria-selected and role='option' when building a custom select menu, or you might want to use aria-current when building a navigation list. In addition to the disabled prop, you might want to use the aria-disabled attribute on a <button> inside the list item and also remove its click handler. In addition to forcing focused visuals, you might want to use fully custom focus management. When building such advanced interfaces, we always recommend carefully researching accessibility patterns and testing them with screenreaders yourself and also with real disabled users to get feedback.

The example below shows the use of these props inside a ComboBox using its custom itemRenderer. Notice how we manually set role to be option - this allows us to use aria-selected and aria-disabled to go along with the active and disabled props. The ComboBox also has the correct attributes and includes built-in focus management so that the up/down arrow keys change the isFocused property; the only additional thing we had to add in our list item is the id which gets referenced by the aria-activedescendant attribute set on the input.

import * as React from 'react';
import { ComboBox, ListItem, VisuallyHidden } from '@itwin/itwinui-react';
import { SvgCheckmark } from '@itwin/itwinui-icons-react';

export default () => {
  const inputId = React.useId();

  return (
    <>
      <VisuallyHidden as='label' htmlFor={inputId}>
        Select a fruit
      </VisuallyHidden>

      <ComboBox
        options={fruits}
        inputProps={{ id: inputId, placeholder: 'Select a fruit' }}
        itemRenderer={(option, { id, isFocused, isSelected }) => {
          const { label, disabled } = option;

          return (
            <ListItem
              role='option'
              actionable
              id={id}
              focused={isFocused}
              active={isSelected}
              aria-selected={isSelected}
              disabled={disabled}
              aria-disabled={disabled}
            >
              <ListItem.Content>{label}</ListItem.Content>

              {isSelected && (
                <ListItem.Icon aria-hidden>
                  <SvgCheckmark />
                </ListItem.Icon>
              )}
            </ListItem>
          );
        }}
      />
    </>
  );
};

const fruits = [
  { label: 'Apple', value: 'apple' },
  { label: 'Banana', value: 'banana' },
  { label: 'Cantaloupe', value: 'cantaloupe' },
  { label: 'Grapefruit', value: 'grapefruit', disabled: true },
  { label: 'Lychee', value: 'lychee' },
  { label: 'Kiwi', value: 'kiwi' },
  { label: 'Orange', value: 'orange', disabled: true },
  { label: 'Strawberry', value: 'strawberry' },
  { label: 'Watermelon', value: 'watermelon' },
];

Props

List

Prop Description Default
as
"symbol" | "object" | "div" | "a" | "abbr" | "address" | "area" | "article" | "aside" | "audio" | "b" | "base" | "bdi" | "bdo" | "big" | "blockquote" | "body" | "br" | "button" | "canvas" | ... 158 more ... | FunctionComponent<...>

ListItem

Prop Description Default
size
Size of the ListItem. Can be explicitly specified to be 'large', but if a description is included in addition to the label, then it will automatically become large.
"default" | "large"
disabled
If true, the ListItem has disabled (dimmed) styling.
boolean
active
If true, the ListItem has active (selected) styling.
boolean
actionable
If true, the ListItem will get actionable styling, such as hover styling and cursor.
boolean
focused
If true, the ListItem has focus styling.
By default, focus styling is automatically applied if the item is focused, or if the item contains a LinkAction and it is focused. This prop is useful for custom focus management (e.g. using aria-activedescendant).
boolean
as
"symbol" | "object" | "div" | "a" | "abbr" | "address" | "area" | "article" | "aside" | "audio" | "b" | "base" | "bdi" | "bdo" | "big" | "blockquote" | "body" | "br" | "button" | "canvas" | ... 158 more ... | FunctionComponent<...>