List
The List
component is used to display a list of ListItem
s 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 itemsdisabled
- to display disabled/non-interactable list itemsfocused
- 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<...> |