List
listPresents accessible named lists with structured items, metadata, actions, grid mode, empty states, and pagination or load-more controls.
Usage
Basic usage
Data driver: items + renderItem, with ListItem.Meta for avatar/title/description, and actions for right operation.
<List
bordered
items={people}
header={<span>Team Member</span>}
footer={<span>Total {people.length} people</span>}
renderItem={(p) => (
<ListItem actions={[<Button key="e" variant="ghost" size="sm">Edit</Button>]}>
<ListItem.Meta avatar={<Avatar fallback={p.initials} />} title={p.name} description={p.role} />
</ListItem>
)}
/>No borders + no separation
Remove the outer frame and row separators, suitable for embedding inside existing cards/panels.
<List
bordered={false}
split={false}
items={people}
renderItem={(p) => (
<ListItem>
<ListItem.Meta avatar={<Avatar fallback={p.initials} />} title={p.name} description={p.role} />
</ListItem>
)}
/>Grid card status
grid switches to a card grid (reusing the Grid primitive), and each card has its own border.
- ChenChen JingProduct Manager
- LiLi WeiFront-end Engineer
- WangWang FangDesigner
- ZhaoZhao QiangBackend Engineer
<List
grid={{ cols: 2, gap: 4 }}
items={people}
renderItem={(p) => (
<ListItem actions={[<Button key="v" variant="outline" size="sm">View</Button>]}>
<User name={p.name} description={p.role} avatarProps={{ fallback: p.initials }} />
</ListItem>
)}
/>Empty
When items is an empty array, there is a built-in <Empty> placeholder.
<List bordered items={[]} header={<span>Team Member</span>} renderItem={(p) => ...} />When to use
Use List for homogeneous member, message, setting, or resource entries. Use Table or EditableTable when headers, sorting, or editable columns matter. List is the lighter avatar-title-description-action pattern and can become a card grid.
Import
import { List, ListItem, ListItemMeta } from "@hulianui/ui"Props
ListProps<T>:
| Name | Type | Default | Description |
|---|---|---|---|
| items | T[] | — | Data-driven entries used with renderItem. |
| size | "sm" | "md" | "lg" | "md" | Row padding density. |
| bordered | boolean | false | Adds an outer border and radius; ignored in grid mode. |
| inset | boolean | Follows bordered | Horizontal padding for rows, header, and footer. |
| split | boolean | true | Row separators; ignored in grid mode. |
| grid | boolean | ListGridConfig | — | Card-grid mode; true uses three columns. |
| loadMore | ListLoadMore | — | Bottom load-more action and loading state. |
Slots
| Slot | Type | Description |
|---|---|---|
| renderItem | (item: T, index: number) => ReactNode | Renders each data item, usually as ListItem; omission treats the item as a React node. |
| children | ReactNode | Composed ListItem children, used only when items is absent. |
| header | ReactNode | Header content. |
| footer | ReactNode | Content at the very bottom. |
| empty | ReactNode | Empty state; omission uses built-in Empty. |
| pagination | ReactNode | Pagination content below the list. |
ListGridConfig has cols (default 3), gap (default 4, multiplied by 0.25rem), colGap, rowGap, and rows. ListLoadMore has onLoadMore*, loading, hasMore (default true), and text; its built-in Chinese text is "\u52a0\u8f7d\u66f4\u591a", meaning “Load more.”
ListItemProps has actions?: ReactNode[] and children. ListItemMetaProps has avatar, title, and description.
Usage notes
itemstakes precedence overchildren. Useitems + renderItemfor data and children for static composition.- Grid mode ignores
borderedandsplit; each card should own its border. - When
loadMore.hasMoreis false, the load-more action is not rendered. - The built-in empty title is
"\u6682\u65e0\u6570\u636e", meaning “No data.”
Accessible name
aria-label, aria-labelledby, and aria-describedby are forwarded to the node with role="list"; other native attributes remain on the outer container. This makes getByRole("list", { name: "…" }) work and prevents assistive technology from encountering an unnamed list (hulianui/hulian#60).
Related
Table · Book3D · ProTable · PricingTable · JsonViewer · EditableTable
Playground
<List
size="md"
bordered={true}
split={true}
items={people}
renderItem={(p) => (
<ListItem actions={[<Button variant="ghost" size="sm">Edit</Button>]}>
<ListItem.Meta avatar={<Avatar fallback={p.initials} />} title={p.name} description={p.role} />
</ListItem>
)}
/>