Stacked List
The StackedList component provides a way to display entities in a vertically stacked list format. It supports flexible item rendering, integration with links or actions, and customizable layouts for presenting structured data consistently.
It is composed of several subcomponents such as StackedList.Root, StackedList.Header, StackedList.Item, and StackedList.Field to offer a structured and customizable interface.
Variations
Item paddings
The StackedList.Item can receive different paddings through the paddingX and paddingY props to match your design solution.
They support the following values: 4xs, 3xs, 2xs, xs, sm, md, lg, xl, 2xl, 3xl, 4xl, 0.
Linked item
The StackedList.Item accepts the linkProps and to props, which allow you to turn the entire item into a link.
If either of these props is provided, the whole item becomes clickable and navigates according to the link configuration. You can still use links and buttons inside as child elements — they will remain fully functional.
Disable hover
The StackedList.Item accepts the disableHover prop, which allows you to turn off the hover effect.
Title color
The StackedList.Field can receive a titleColor prop, which allows you to override the default title color.
Truncating
By default, both title and description have truncation enabled.
To disable it, pass the disableTruncate prop to StackedList.Field.
Field position
The StackedList.Field component accepts the right prop, which positions the field on the right side of the Item.
With pagination
The StackedList.Root component can accept pagination props to enable pagination functionality within the list.
With tooltip
The StackedList.Item component can accept a tooltipProps prop to display content in a tooltip.
Installation
import { StackedList } from '@harnessio/ui/components'
//...
return ( <StackedList.Root> <StackedList.Header> <StackedList.Field title="Title" /> </StackedList.Header> <StackedList.Item thumbnail={<IconV2 name="connectors" size="xs" />} actions={<Button>Action</Button>} to="/" > <StackedList.Field title="Item 1" description="Description 1" /> </StackedList.Item>
<StackedList.Item thumbnail={<IconV2 name="star" size="xs" />} actions={<Button>Action</Button>} to="/" > <StackedList.Field title="Item 2" description="Description 2" /> </StackedList.Item>
<StackedList.Item thumbnail={<IconV2 name="check" size="xs" />} actions={<Button>Action</Button>} to="/" > <StackedList.Field title="Item 3" description="Description 3" /> </StackedList.Item> </StackedList.Root>)Anatomy
All parts of the StackedList component can be imported and composed as required.
<StackedList.Root> <StackedList.Header> <StackedList.Field /> </StackedList.Header>
<StackedList.Item> <StackedList.Field /> <StackedList.Field /> </StackedList.Item>
<StackedList.Item> <StackedList.Field /> </StackedList.Item></StackedList.Root>StackedList.Rootis the outer container. It draws the list border and rounded corners and can host pagination viapaginationProps.StackedList.Headeris an item that renders at the top as a heading row. It reuses theItemprops but always has hover disabled and defaults itspaddingYtoxs.StackedList.Itemis a single row. Provideto/linkPropsto make the whole row a navigable link, oronClickto make it a button; addthumbnailandactionsfor leading and trailing content.StackedList.Fieldrenders atitleand/ordescriptioninsideTextcomponents for consistent typography. Userightto push a field to the trailing edge of the row.
Best practices
Do
- Keep each item’s fields consistent across the list so rows scan as a single column of information.
- Use
rightfields for secondary metadata (timestamps, counts, status) that should align to the trailing edge. - Make the whole row navigable with
to/linkPropsrather than burying the primary link inside the row.
Don’t
- Don’t disable truncation everywhere — long, unbounded titles break the list’s even rhythm. Reserve
disableTruncatefor rows that genuinely need the full text. - Don’t overload a row with competing actions; keep the
actionsslot to one or two clear controls.
Accessibility
Keyboard
- When an item is a link (
to/linkProps) or a button (onClick), it is focusable and activates withEnter(andSpacefor buttons), following normal link/button semantics. - Controls placed in
actionsremain independently focusable within the row.
Labeling
StackedListrenders plain containers with no list/row roles, so the accessible name of each row comes from its visibletitle/descriptiontext and any labels on the controls inside it.- Give icon-only
actionsandthumbnailcontrols their own accessible labels.
Focus & states
- Rows show a hover affordance by default;
disableHoverremoves it for non-interactive rows. Removing hover does not change focus behavior for any interactive elements inside.
Properties
Root
Contains StackedList.Item and StackedList.Field components.
Prop | Required | Default | Type |
|---|---|---|---|
| className | false | undefined | string |
| border | false | undefined | false |
| rounded | false | undefined | 'top' |
| paginationProps | false | undefined | PaginationProps |
Root also accepts standard <div> attributes.
Header
Contains StackedList.Field components.
All props are the same as in StackedList.Item, except that disableHover is always true and paddingY defaults to 'xs'.
Item
Contains StackedList.Field components.
Prop | Required | Default | Type |
|---|---|---|---|
| className | false | undefined | string |
| thumbnail | false | undefined | ReactNode |
| actions | false | undefined | ReactNode |
| asChild | false | undefined | boolean |
| to | false | undefined | string |
| linkProps | false | undefined | Omit<LinkProps, 'to'> |
| onClick | false | undefined | () => void |
| disableHover | false | false | boolean |
| paddingX | false | 'md' | '4xs' | '3xs' | '2xs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' | '0' |
| paddingY | false | 'md' | '4xs' | '3xs' | '2xs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl' | '0' |
| tooltipProps | false | undefined | TooltipProps |
Field
Prop | Required | Default | Type |
|---|---|---|---|
| className | false | undefined | string |
| title | false | undefined | ReactNode |
| description | false | undefined | ReactNode |
| titleColor | false | 'foreground-1' | 'inherit' | 'foreground-1' | 'foreground-2' | 'foreground-3' | 'foreground-4' | 'disabled' | 'success' | 'warning' | 'merged' | 'danger' | 'brand' |
| right | false | undefined | boolean |
| disableTruncate | false | false | boolean |