Purpose
ListItem is a clickable row for lists of entities, such as expenses, invoices, reimbursements,
purchase orders or bank accounts. Each row shows an avatar, a title with a subtitle, an amount or
other secondary details, and optional badges. Rows can be selected with a checkbox and marked as
active.
ListItem renders a single row. Render rows yourself, or use it as the item renderer of a list
component. For a plain bulleted or numbered list of text, use
List and List.Item instead.
Basic usage
import {ListItem} from '@pleo-io/telescope'
;<ListItem onClick={openExpense}>
<ListItem.Avatar name="Jenny Lindh" />
<ListItem.PrimaryColumn>
<ListItem.PrimaryTitle headingLevel="h3">Jenny Lindh</ListItem.PrimaryTitle>
<ListItem.Subtitle>Mileage ยท 244.3 km</ListItem.Subtitle>
</ListItem.PrimaryColumn>
<ListItem.SecondaryColumn>
<ListItem.SecondaryTitle>728,00 DKK</ListItem.SecondaryTitle>
<ListItem.Subtitle>For review: 58,00 DKK</ListItem.Subtitle>
</ListItem.SecondaryColumn>
</ListItem>onClick is wired to ListItem.PrimaryTitle, which stretches its click area over the whole row.
Always render a ListItem.PrimaryTitle when you pass onClick.
Layout and hover
The row's background extends 24px beyond its container on the left and right, so its content lines
up with the content around it. Give the container at least 24px of horizontal padding, so the
hover and active states don't overflow or get clipped. Check the hover state at all screen sizes
when you use ListItem in a custom layout.
Text in the primary column wraps on narrow rows and is truncated with an ellipsis once the row is at
least 360px wide. The row is a CSS container named list-item.
Set hasNoBackground to show the background only on hover.
Avatar and badge
ListItem.Avatar is a 48px Avatar and accepts its
props, except size. Add a ListItem.AvatarBadge inside it to show a small icon in the corner.
<ListItem.Avatar name="NeoTech Hypervalentix">
<ListItem.AvatarBadge Icon={ArrowCircleLeft} />
</ListItem.Avatar>Status
Set statusVariant="negative" to colour the avatar badge and the primary column subtitle with the
negative colour, for example for a cancelled transaction.
<ListItem statusVariant="negative" onClick={openTransaction}>
<ListItem.Avatar name="InnovaTech">
<ListItem.AvatarBadge Icon={CircleClose} />
</ListItem.Avatar>
<ListItem.PrimaryColumn>
<ListItem.PrimaryTitle headingLevel="h3">InnovaTech</ListItem.PrimaryTitle>
<ListItem.Subtitle>Transaction cancelled</ListItem.Subtitle>
</ListItem.PrimaryColumn>
<ListItem.SecondaryColumn>
<ListItem.SecondaryTitle strikethrough>728,00 DKK</ListItem.SecondaryTitle>
</ListItem.SecondaryColumn>
</ListItem>Badges
Put Badges in ListItem.BadgeContainer. They're shown
below the title, across both columns.
<ListItem.BadgeContainer>
<Badge variant="warning" Icon={Calendar}>
Overdue since 4 May
</Badge>
</ListItem.BadgeContainer>Selection and active state
Pass checkboxProps to show a checkbox at the start of the row. Clicking the checkbox doesn't
trigger the row's onClick. label is visually hidden and names the checkbox for screen readers.
When the checkbox is disabled, use tooltipContent to explain why.
<ListItem
onClick={openInvoice}
isActive={isInvoiceOpen}
checkboxProps={{
label: 'Select invoice',
checked: isSelected,
onChange: toggleSelected,
}}
>
{/* โฆ */}
</ListItem>Set isActive to highlight the row whose details are open, for example in a drawer.
Subcomponents
| Component | Description |
|---|---|
ListItem.Avatar | A 48px Avatar. |
ListItem.AvatarBadge | An icon in the corner of the avatar. Coloured by statusVariant. |
ListItem.PrimaryColumn | The main column, aligned to the start. |
ListItem.PrimaryTitle | The row's heading. Set headingLevel to fit the page. Triggers onClick. Supports strikethrough. |
ListItem.SecondaryColumn | The column aligned to the end, for example for amounts. |
ListItem.SecondaryTitle | A title for the secondary column. Supports strikethrough and color. |
ListItem.Subtitle | Smaller, quiet text below a title. |
ListItem.BadgeContainer | A wrapping row of badges below the columns. |
Accessibility
ListItem.PrimaryTitlerenders a heading with a button inside. Pick aheadingLevelthat fits the page structure, so screen reader users can jump between rows.- The row is reachable with the keyboard through that button, which shows the focus ring around the whole row.
- Give the checkbox a meaningful
label, for example "Select invoice from NeoTech". - Give icon-only avatars an
aria-labelon the icon.
API reference
A clickable row for lists of entities, such as expenses, invoices or accounts. Compose it with
ListItem.Avatar, ListItem.PrimaryColumn, ListItem.SecondaryColumn and
ListItem.BadgeContainer. The whole row is clickable through ListItem.PrimaryTitle.
For a plain bulleted or numbered list use List and List.Item instead.
| Prop | Type | Default |
|---|---|---|
checkboxPropsProps for the select checkbox. Renders a checkbox at the start of the row when set. | enumListItemCheckboxProps | undefined | |
children (required)The contents of the ListItem | enumnull, string, number, bigint, false, true, ReactElement<unknown, string | JSXElementConstructor<any>>, Iterable<ReactNode>, ReactPortal, Promise<AwaitedReactNode> | |
hasNoBackgroundWhether the ListItem has no background without hover | boolean | false |
isActiveWhether the ListItem is active, for example when its details are open | boolean | false |
onClickAction performed when the ListItem is clicked on. Wired to | enum() => void | |
statusVariantThe status variant of the Avatar badge and Primary column Subtitle | enum"neutral", "negative" | neutral |
testIdTest ID for the ListItem | enumstring | undefined |