Table 表格
表格以行和列展示结构化数据,支持排序、选择、列宽调整与无限滚动。
用法
import { Table } from '@lenso/ui';此预览复用英文版适配,不代表中文源示例已完成本地实现。
"use client";
// Adapted from HeroUI v3.2.6 table-basic (Apache-2.0).import * as stylex from "@stylexjs/stylex";import { Table } from "@lenso/ui";
const rows = [ { key: "kate", name: "Kate Moore", role: "CEO", status: "Active", email: "[email protected]" }, { key: "john", name: "John Smith", role: "CTO", status: "Active", email: "[email protected]" }, { key: "sara", name: "Sara Johnson", role: "CMO", status: "On Leave", email: "[email protected]" }, { key: "michael", name: "Michael Brown", role: "CFO", status: "Active", email: "[email protected]", },] as const;const styles = stylex.create({ content: { minWidth: 600 } });
export function Basic() { return ( <Table> <Table.ScrollContainer> <Table.Content aria-label="Team members" xstyle={styles.content}> <Table.Header> <Table.Column columnKey="name">Name</Table.Column> <Table.Column columnKey="role">Role</Table.Column> <Table.Column columnKey="status">Status</Table.Column> <Table.Column columnKey="email">Email</Table.Column> </Table.Header> <Table.Body> <Table.Collection items={rows}> {(row) => ( <Table.Row itemKey={row.key}> <Table.Cell>{row.name}</Table.Cell> <Table.Cell>{row.role}</Table.Cell> <Table.Cell>{row.status}</Table.Cell> <Table.Cell>{row.email}</Table.Cell> </Table.Row> )} </Table.Collection> </Table.Body> </Table.Content> </Table.ScrollContainer> </Table> );}Local adaptation source above. Derived from HeroUI v3.2.6 source.
组件结构
import { Table } from '@lenso/ui';
export default () => ( <Table> <Table.ScrollContainer> <Table.Content aria-label="Example table"> <Table.Header> <Table.Column allowsSorting> {({ sortDirection }) => ( <Table.SortableColumnHeader sortDirection={sortDirection}> Name </Table.SortableColumnHeader> )} </Table.Column> <Table.Column>Role</Table.Column> </Table.Header> <Table.Body> <Table.Row> <Table.Cell>Kate Moore</Table.Cell> <Table.Cell>CEO</Table.Cell> </Table.Row> </Table.Body> </Table.Content> </Table.ScrollContainer> <Table.Footer>{/* Optional footer content */}</Table.Footer> </Table>);示例
次要变体
此预览复用英文版适配,不代表中文源示例已完成本地实现。
"use client";// HeroUI v3.2.6 secondary-variant adaptation (Apache-2.0).import { Table } from "@lenso/ui";import { Headers, Rows, styles, users } from "./data";export function SecondaryVariant() { return ( <Table variant="secondary"> <Table.ScrollContainer> <Table.Content aria-label="Team members" xstyle={styles.content}> <Headers /> <Table.Body> <Rows items={users.slice(0, 4)} /> </Table.Body> </Table.Content> </Table.ScrollContainer> </Table> );}Local adaptation source above. Derived from HeroUI v3.2.6 source.
异步加载
使用 Table.LoadMore 实现无限滚动。它会渲染一个哨兵行,滚动到视口时触发 onLoadMore。
此预览复用英文版适配,不代表中文源示例已完成本地实现。
"use client";// HeroUI v3.2.6 async-loading adaptation (Apache-2.0).import { useCallback, useEffect, useRef, useState } from "react";import { Spinner, Table } from "@lenso/ui";import { Rows, styles, users } from "./data";export function AsyncLoading() { const [count, setCount] = useState(6); const [loading, setLoading] = useState(false); const request = useRef<ReturnType<typeof setTimeout> | null>(null); useEffect( () => () => { if (request.current) clearTimeout(request.current); }, [], ); const loadMore = useCallback(() => { if (request.current || count >= users.length) return; setLoading(true); request.current = setTimeout(() => { request.current = null; setCount((previous) => previous + 6); setLoading(false); }, 1500); }, [count]); return ( <Table> <Table.ScrollContainer xstyle={styles.viewport}> <Table.Content aria-label="Async loading table" xstyle={styles.content}> <Table.Header xstyle={styles.sticky}> {["name", "role", "status", "email"].map((column) => ( <Table.Column key={column} columnKey={column}> {column[0]!.toUpperCase() + column.slice(1)} </Table.Column> ))} </Table.Header> <Table.Body> <Rows items={users.slice(0, count)} chips /> {count < users.length && ( <Table.LoadMore colSpan={4} loading={loading} hasMore onLoadMore={loadMore}> <Table.LoadMoreContent> <Spinner size="md" /> </Table.LoadMoreContent> </Table.LoadMore> )} </Table.Body> </Table.Content> </Table.ScrollContainer> </Table> );}Local adaptation source above. Derived from HeroUI v3.2.6 source.
排序
在 Table.Column 上使用 allowsSorting 属性可启用列排序。在 Table.Content 上使用 sortDescriptor 与 onSortChange 管理排序状态。将标签包裹在 Table.SortableColumnHeader 中,并将列 render prop 的 sortDirection 转发以渲染默认升序/降序指示器。
此预览复用英文版适配,不代表中文源示例已完成本地实现。
"use client";// HeroUI v3.2.6 sorting adaptation (Apache-2.0).import { useState } from "react";import { Table, type SortDescriptor } from "@lenso/ui";import { Headers, Rows, styles, users, type User } from "./data";export function Sorting() { const [sort, setSort] = useState<SortDescriptor>({ column: "name", direction: "ascending" }); const sorted = users .slice(0, 5) .sort( (a, b) => String(a[sort.column as keyof User]).localeCompare(String(b[sort.column as keyof User])) * (sort.direction === "ascending" ? 1 : -1), ); return ( <Table> <Table.ScrollContainer> <Table.Content aria-label="Sortable table" xstyle={styles.content} sortDescriptor={sort} onSortChange={setSort} > <Headers sorting /> <Table.Body> <Rows items={sorted} /> </Table.Body> </Table.Content> </Table.ScrollContainer> </Table> );}Local adaptation source above. Derived from HeroUI v3.2.6 source.
选择
在 Table.Content 上使用 selectionMode 启用行选择。使用 slot="selection" 的 Checkbox 实现全选与逐行勾选。
此预览复用英文版适配,不代表中文源示例已完成本地实现。
"use client";// HeroUI v3.2.6 selection adaptation (Apache-2.0).import { useState, type Key } from "react";import * as stylex from "@stylexjs/stylex";import { Table } from "@lenso/ui";import { Headers, Rows, styles, users } from "./data";export function SelectionDemo() { const [selected, setSelected] = useState<Set<Key>>(new Set()); return ( <div {...stylex.props(styles.stack)}> <Table> <Table.ScrollContainer> <Table.Content aria-label="Table with selection" xstyle={styles.content} selectionMode="multiple" selectedKeys={selected} onSelectionChange={setSelected} > <Headers selection /> <Table.Body> <Rows items={users.slice(0, 4)} selection /> </Table.Body> </Table.Content> </Table.ScrollContainer> </Table> <p {...stylex.props(styles.muted)}> Selected: {selected.size ? [...selected].join(", ") : "None"} </p> </div> );}Local adaptation source above. Derived from HeroUI v3.2.6 source.
可展开行
行可嵌套以展示层级数据。使用 treeColumn 指定列,并在该列单元格中渲染 slot="chevron" 的 Button,供用户展开/收起行。使用 expandedKeys 控制哪些行处于展开状态。
此预览复用英文版适配,不代表中文源示例已完成本地实现。
"use client";// HeroUI v3.2.6 expandable-rows adaptation (Apache-2.0).import { useState, type Key } from "react";import * as stylex from "@stylexjs/stylex";import { Icon } from "@iconify/react";import { Table } from "@lenso/ui";type Row = { key: string; title: string; type: string; date: string; children: Row[] };const file = (key: string, title: string, date: string, children: Row[] = []): Row => ({ key, title, date, children, type: children.length ? "Directory" : "File",});const rows = [ file("1", "Documents", "10/20/2025", [ file("2", "Project", "8/2/2025", [ file("3", "Weekly Report", "7/10/2025"), file("4", "Budget", "8/20/2025"), ]), ]), file("5", "Photos", "2/3/2026", [ file("6", "Image 1", "1/23/2026"), file("7", "Image 2", "2/3/2026"), ]),];const styles = stylex.create({ content: { minWidth: 520 }, title: { display: "flex", alignItems: "center", gap: 4 }, chevron: { transform: "rotate(90deg)" }, collapsed: { transform: { default: "none", ":dir(rtl)": "rotate(180deg)" } },});export function ExpandableRows() { const [expanded, setExpanded] = useState<Set<Key>>(new Set(["1"])); const renderRow = (item: Row): React.ReactNode => ( <Table.Row itemKey={item.key} textValue={item.title}> <Table.Cell columnKey="name"> {({ hasChildItems, isExpanded, isTreeColumn }) => ( <span {...stylex.props(styles.title)}> {hasChildItems && isTreeColumn && ( <Table.ExpandButton aria-label={`Toggle ${item.title}`}> <Icon icon="gravity-ui:chevron-right" width={16} aria-hidden="true" {...stylex.props(isExpanded ? styles.chevron : styles.collapsed)} /> </Table.ExpandButton> )} <span>{item.title}</span> </span> )} </Table.Cell> <Table.Cell>{item.type}</Table.Cell> <Table.Cell>{item.date}</Table.Cell> <Table.Collection items={item.children}>{renderRow}</Table.Collection> </Table.Row> ); return ( <Table> <Table.ScrollContainer> <Table.Content aria-label="Files" xstyle={styles.content} treeColumn="name" expandedKeys={expanded} onExpandedChange={setExpanded} > <Table.Header> <Table.Column columnKey="name">Name</Table.Column> <Table.Column columnKey="type">Type</Table.Column> <Table.Column columnKey="date">Date Modified</Table.Column> </Table.Header> <Table.Body items={rows}>{renderRow}</Table.Body> </Table.Content> </Table.ScrollContainer> </Table> );}Local adaptation source above. Derived from HeroUI v3.2.6 source.
分页
使用 Table.Footer 在表格下方添加分页组件。
此预览复用英文版适配,不代表中文源示例已完成本地实现。
"use client";// HeroUI v3.2.6 pagination adaptation (Apache-2.0).import { useState } from "react";import { Table } from "@lenso/ui";import { Headers, Pages, Rows, styles, users } from "./data";export function PaginationDemo() { const [page, setPage] = useState(1); return ( <Table> <Table.ScrollContainer> <Table.Content aria-label="Table with pagination" xstyle={styles.content}> <Headers /> <Table.Body> <Rows items={users.slice((page - 1) * 4, page * 4)} /> </Table.Body> </Table.Content> </Table.ScrollContainer> <Table.Footer> <Pages page={page} count={2} total={8} setPage={setPage} /> </Table.Footer> </Table> );}Local adaptation source above. Derived from HeroUI v3.2.6 source.
列宽调整
将表格包裹在 Table.ResizableContainer 中,并在每个可调整宽度的列内添加 Table.ColumnResizer。
此预览复用英文版适配,不代表中文源示例已完成本地实现。
"use client";// HeroUI v3.2.6 column-resizing adaptation (Apache-2.0).import { Table } from "@lenso/ui";import { Headers, Rows, styles, users } from "./data";export function ColumnResizing() { return ( <Table> <Table.ResizableContainer> <Table.Content aria-label="Table with resizable columns" xstyle={styles.resizing}> <Headers resizing /> <Table.Body> <Rows items={users.slice(0, 5)} chips /> </Table.Body> </Table.Content> </Table.ResizableContainer> </Table> );}Local adaptation source above. Derived from HeroUI v3.2.6 source.
空状态
在 Table.Body 上使用 renderEmptyState,在表格无数据时展示自定义消息。
此预览复用英文版适配,不代表中文源示例已完成本地实现。
"use client";// HeroUI v3.2.6 empty-state adaptation (Apache-2.0).import * as stylex from "@stylexjs/stylex";import { Icon } from "@iconify/react";import { EmptyState, Table } from "@lenso/ui";import { Headers, styles } from "./data";const empty = stylex.create({ root: { minHeight: 200 }, content: { minHeight: 140, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", gap: 16, textAlign: "center", color: "var(--muted)", },});export function EmptyStateDemo() { return ( <Table xstyle={empty.root}> <Table.ScrollContainer> <Table.Content aria-label="Empty table" xstyle={styles.content}> <Headers /> <Table.Body> <tr> <td colSpan={4}> <EmptyState xstyle={empty.content}> <Icon icon="gravity-ui:tray" width={24} aria-hidden="true" /> <span>No results found</span> </EmptyState> </td> </tr> </Table.Body> </Table.Content> </Table.ScrollContainer> </Table> );}Local adaptation source above. Derived from HeroUI v3.2.6 source.
虚拟滚动
Table 通过 Virtualizer 支持虚拟化,仅渲染视口内可见行,从而高效展示大数据集。
此预览复用英文版适配,不代表中文源示例已完成本地实现。
"use client";// HeroUI v3.2.6 virtualization adaptation (Apache-2.0); native row spacers.import { Table } from "@lenso/ui";import { styles } from "./data";const first = [ "Emma", "Liam", "Olivia", "Noah", "Ava", "James", "Sophia", "Oliver", "Isabella", "Lucas", "Mia", "Ethan", "Charlotte", "Mason", "Amelia", "Logan", "Harper", "Alexander", "Ella", "Benjamin",];const last = [ "Smith", "Johnson", "Williams", "Brown", "Jones", "Garcia", "Miller", "Davis", "Rodriguez", "Martinez", "Anderson", "Taylor", "Thomas", "Jackson", "White", "Harris", "Clark", "Lewis", "Robinson", "Walker",];const roles = [ "Software Engineer", "Senior Engineer", "Staff Engineer", "Product Manager", "Designer", "Data Analyst", "QA Engineer", "DevOps Engineer", "Marketing Manager", "Sales Representative",];const users = Array.from({ length: 1000 }, (_, index) => ({ key: index + 1, name: `${first[index % 20]} ${last[Math.floor(index / 20) % 20]}`, role: roles[index % 10], email: `${first[index % 20]!.toLowerCase()}.${last[Math.floor(index / 20) % 20]!.toLowerCase()}@acme.com`,}));export function Virtualization() { return ( <Table> <Table.ScrollContainer xstyle={styles.virtualViewport}> <Table.Content aria-label="Virtualized table with 1000 rows" xstyle={styles.resizing}> <Table.Header xstyle={styles.sticky}> <Table.Column columnKey="name" minWidth={160}> Name </Table.Column> <Table.Column columnKey="role" minWidth={220}> Role </Table.Column> <Table.Column columnKey="email" minWidth={240}> Email </Table.Column> </Table.Header> <Table.Body items={users} virtualized={{ height: 300, rowHeight: 42 }}> {(user) => ( <Table.Row itemKey={user.key}> <Table.Cell>{user.name}</Table.Cell> <Table.Cell>{user.role}</Table.Cell> <Table.Cell>{user.email}</Table.Cell> </Table.Row> )} </Table.Body> </Table.Content> </Table.ScrollContainer> </Table> );}Local adaptation source above. Derived from HeroUI v3.2.6 source.
TanStack Table
HeroUI 的 Table 作为无头表格库之上的渲染层。 本示例使用 TanStack Table 处理列定义、排序与分页,而 HeroUI 负责样式与无障碍。
此预览复用英文版适配,不代表中文源示例已完成本地实现。
"use client";// HeroUI v3.2.6 tanstack-table adaptation (Apache-2.0); retains the v9 data model.import { useState } from "react";import { Table, type SortDescriptor } from "@lenso/ui";import { createColumnHelper, createPaginatedRowModel, createSortedRowModel, flexRender, rowPaginationFeature, rowSortingFeature, sortFn_alphanumeric, tableFeatures, useTable, type SortingState,} from "@tanstack/react-table";import { Pages, Status, styles, users, type User } from "./data";const features = tableFeatures({ paginatedRowModel: createPaginatedRowModel(), rowPaginationFeature, rowSortingFeature, sortFns: { alphanumeric: sortFn_alphanumeric }, sortedRowModel: createSortedRowModel(),});const helper = createColumnHelper<typeof features, User>();const columns = helper.columns([ helper.accessor("name", { header: "Name" }), helper.accessor("role", { header: "Role" }), helper.accessor("status", { header: "Status", cell: (info) => <Status status={info.getValue()} />, }), helper.accessor("email", { header: "Email" }),]);const data = users.slice(0, 8);export function TanstackTable() { const [sorting, setSorting] = useState<SortingState>([]); const table = useTable({ columns, data, features, initialState: { pagination: { pageIndex: 0, pageSize: 4 } }, onSortingChange: setSorting, state: { sorting }, }); const first = sorting[0]; const descriptor: SortDescriptor | undefined = first ? { column: first.id, direction: first.desc ? "descending" : "ascending" } : undefined; return ( <Table> <Table.ScrollContainer> <Table.Content aria-label="TanStack Table example" xstyle={styles.content} sortDescriptor={descriptor} onSortChange={(next) => setSorting([{ id: String(next.column), desc: next.direction === "descending" }]) } > <Table.Header> {table.getHeaderGroups()[0]?.headers.map((header) => ( <Table.Column key={header.id} columnKey={header.id} allowsSorting={header.column.getCanSort()} > {({ sortDirection }) => ( <Table.SortableColumnHeader sortDirection={sortDirection}> {flexRender(header.column.columnDef.header, header.getContext())} </Table.SortableColumnHeader> )} </Table.Column> ))} </Table.Header> <Table.Body> {table.getRowModel().rows.map((row) => ( <Table.Row key={row.id} itemKey={row.id}> {row.getAllCells().map((cell) => ( <Table.Cell key={cell.id}> {flexRender(cell.column.columnDef.cell, cell.getContext())} </Table.Cell> ))} </Table.Row> ))} </Table.Body> </Table.Content> </Table.ScrollContainer> <Table.Footer> <Pages page={table.state.pagination.pageIndex + 1} count={table.getPageCount()} total={8} setPage={(page) => table.setPageIndex(page - 1)} /> </Table.Footer> </Table> );}Local adaptation source above. Derived from HeroUI v3.2.6 source.
自定义单元格
此预览复用英文版适配,不代表中文源示例已完成本地实现。
"use client";// HeroUI v3.2.6 custom-cells adaptation (Apache-2.0).import { useState, type Key } from "react";import * as stylex from "@stylexjs/stylex";import { Icon } from "@iconify/react";import { Avatar, Button, Table, type SortDescriptor } from "@lenso/ui";import { Status, styles, users, type User } from "./data";const workers = users.slice(0, 5).map((user, index) => ({ ...user, key: [4586932, 5273849, 7492836, 8293746, 1234567][index]!, role: [ "Chief Executive Officer", "Chief Technology Officer", "Chief Marketing Officer", "Chief Financial Officer", "Product Manager", ][index]!, color: ["red", "green", "blue", "purple", "orange"][index],}));export function CustomCells() { const [selected, setSelected] = useState<Set<Key>>(new Set()); const [sort, setSort] = useState<SortDescriptor>({ column: "name", direction: "ascending" }); const sorted = [...workers].sort( (a, b) => String(a[sort.column as keyof User]).localeCompare(String(b[sort.column as keyof User])) * (sort.direction === "ascending" ? 1 : -1), ); return ( <Table> <Table.ScrollContainer> <Table.Content aria-label="Table with custom cells" xstyle={styles.customCells} selectionMode="multiple" selectedKeys={selected} onSelectionChange={setSelected} sortDescriptor={sort} onSortChange={setSort} > <Table.Header> <Table.Column columnKey="selection" width={48}> <Table.SelectionCheckbox /> </Table.Column> {[ ["key", "Worker ID"], ["name", "Member"], ["role", "Role"], ["status", "Status"], ].map(([key, title]) => ( <Table.Column key={key} columnKey={key!} allowsSorting> {({ sortDirection }) => ( <Table.SortableColumnHeader sortDirection={sortDirection}> {title} </Table.SortableColumnHeader> )} </Table.Column> ))} <Table.Column columnKey="actions">Actions</Table.Column> </Table.Header> <Table.Body> {sorted.map((user) => ( <Table.Row key={user.key} itemKey={user.key}> <Table.Cell> <Table.SelectionCheckbox aria-label={`Select ${user.name}`} /> </Table.Cell> <Table.Cell> <div {...stylex.props(styles.row)}> #{user.key} <Button isIconOnly aria-label={`Copy ID #${user.key}`} size="sm" variant="ghost" > <Icon icon="gravity-ui:copy" width={16} aria-hidden="true" /> </Button> </div> </Table.Cell> <Table.Cell> <div {...stylex.props(styles.row)}> <Avatar size="sm"> <Avatar.Image alt={user.name} src={`https://heroui-assets.nyc3.cdn.digitaloceanspaces.com/avatars/${user.color}.jpg`} /> <Avatar.Fallback> {user.name .split(" ") .map((name) => name[0]) .join("")} </Avatar.Fallback> </Avatar> <div {...stylex.props(styles.detail)}> <span>{user.name}</span> <span {...stylex.props(styles.muted)}>{user.email}</span> </div> </div> </Table.Cell> <Table.Cell>{user.role}</Table.Cell> <Table.Cell> <Status status={user.status} /> </Table.Cell> <Table.Cell> <div {...stylex.props(styles.row)}> {(["View", "Edit", "Delete"] as const).map((action, index) => ( <Button key={action} isIconOnly aria-label={`${action} ${user.name}`} size="sm" variant={action === "Delete" ? "danger-soft" : "tertiary"} > <Icon icon={`gravity-ui:${["eye", "pencil", "trash-bin"][index]}`} width={16} aria-hidden="true" /> </Button> ))} </div> </Table.Cell> </Table.Row> ))} </Table.Body> </Table.Content> </Table.ScrollContainer> </Table> );}Local adaptation source above. Derived from HeroUI v3.2.6 source.
自定义样式
Tailwind CSS
此预览复用英文版适配,不代表中文源示例已完成本地实现。
"use client";// HeroUI v3.2.6 custom-styles adaptation (Apache-2.0).import { Table } from "@lenso/ui";import { Headers, Rows, styles, users } from "./data";export function CustomStyles() { return ( <Table xstyle={styles.customRoot}> <Table.ScrollContainer> <Table.Content aria-label="Team members" xstyle={styles.content}> <Headers custom email={false} /> <Table.Body> <Rows items={users.slice(0, 3)} custom email={false} /> </Table.Body> </Table.Content> </Table.ScrollContainer> </Table> );}Local adaptation source above. Derived from HeroUI v3.2.6 source.
全局 CSS
若要自定义组件类,可使用 @layer components 指令。了解更多。
@layer components { .table-root { @apply relative grid w-full overflow-clip; }
.table__header { @apply bg-gray-100; }
.table__column { @apply px-4 py-2.5 text-left text-xs font-medium text-gray-600; }
.table__row { @apply bg-white border-b border-gray-200; }
.table__cell { @apply px-4 py-3 text-sm; }
.table__footer { @apply flex items-center px-4 py-2.5; }}样式参考
HeroUI 遵循 BEM 方法论,确保组件变体与状态可复用且易于自定义。
CSS 类
Table 组件使用以下 CSS 类(查看源码样式):
基础类 [!toc]
.table-root- 根容器(命名为table-root而非table,因为table是 Tailwind CSS 内置的display: table工具类).table__scroll-container- 横向滚动包裹层与自定义滚动条.table__content-<table>元素.table__header- 表头行(<thead>).table__column- 列表头单元格(<th>).table__body- 表体(<tbody>).table__row- 行(<tr>).table__cell- 数据单元格(<td>).table__footer- 表底容器(位于 table 外部)
进阶类 [!toc]
.table__column-resizer- 列宽拖拽手柄.table__resizable-container- 启用列宽调整的包裹层.table__load-more- 无限滚动的哨兵行.table__load-more-content- 加载指示器的样式容器.table__sortable-column-header- 可排序列标签与指示器的包裹层.table__sortable-column-indicator- 排序方向 chevron(通过[data-direction="descending"]翻转)
变体类 [!toc]
.table-root--primary- 灰色背景容器与卡片式表体(默认).table-root--secondary- 无背景,独立圆角表头
交互状态
Table 同时支持 CSS 伪类与 data 属性,以提供更灵活的状态控制:
- 悬停:
:hover或[data-hovered="true"](行背景变化) - 已选中:
[data-selected="true"](行高亮) - 聚焦:
:focus-visible或[data-focus-visible="true"](行、列与单元格的内嵌焦点环) - 禁用:
:disabled或[aria-disabled="true"](降低透明度) - 可排序:
[data-allows-sorting="true"](列上的交互指针样式) - 拖动中:
[data-dragging="true"](降低透明度) - 放置目标:
[data-drop-target="true"](强调色背景)
API 参考
Table
| Prop | 类型 | 默认值 | 描述 |
|---|---|---|---|
variant | "primary" | "secondary" | "primary" | 视觉变体。Primary 为灰色背景容器;Secondary 为扁平透明行。 |
className | string | - | 根容器的额外 CSS 类。 |
children | React.ReactNode | - | 表格内容(ScrollContainer、Footer 等)。 |
Table.ScrollContainer
| Prop | 类型 | 默认值 | 描述 |
|---|---|---|---|
className | string | - | 额外的 CSS 类。 |
children | React.ReactNode | - | Table.Content 元素。 |
Table.Content
继承自 React Aria Table。
| Prop | 类型 | 默认值 | 描述 |
|---|---|---|---|
aria-label | string | - | 表格的无障碍标签。 |
selectionMode | "none" | "single" | "multiple" | "none" | 选择行为。 |
selectedKeys | Selection | - | 受控的已选中 key。 |
onSelectionChange | (keys: Selection) => void | - | 选择变化时的事件处理函数。 |
sortDescriptor | SortDescriptor | - | 当前排序状态。 |
onSortChange | (descriptor: SortDescriptor) => void | - | 排序变化时的事件处理函数。 |
className | string | - | 额外的 CSS 类。 |
Table.Header
| Prop | 类型 | 默认值 | 描述 |
|---|---|---|---|
columns | T[] | - | 渲染函数模式下的动态列数据。 |
children | React.ReactNode | (column: T) => React.ReactNode | - | 静态列或渲染函数。 |
Table.Column
继承自 React Aria Column。
| Prop | 类型 | 默认值 | 描述 |
|---|---|---|---|
id | string | - | 列标识符。 |
allowsSorting | boolean | false | 列是否可排序。 |
isRowHeader | boolean | false | 该列是否作为行表头。 |
defaultWidth | string | number | - | 可调整列的默认宽度。 |
minWidth | number | - | 可调整列的最小宽度。 |
children | React.ReactNode | (values: ColumnRenderProps) => React.ReactNode | - | 列内容或带排序方向的渲染函数。 |
Table.Body
继承自 React Aria TableBody。
| Prop | 类型 | 默认值 | 描述 |
|---|---|---|---|
items | T[] | - | 渲染函数模式下的动态行数据。 |
renderEmptyState | () => React.ReactNode | - | 表格为空时展示的内容。 |
children | React.ReactNode | (item: T) => React.ReactNode | - | 静态行或渲染函数。 |
Table.Row
继承自 React Aria Row。
| Prop | 类型 | 默认值 | 描述 |
|---|---|---|---|
id | string | number | - | 行标识符。 |
className | string | - | 额外的 CSS 类。 |
children | React.ReactNode | - | 行单元格。 |
Table.Cell
继承自 React Aria Cell。
| Prop | 类型 | 默认值 | 描述 |
|---|---|---|---|
className | string | - | 额外的 CSS 类。 |
children | React.ReactNode | - | 单元格内容。 |
Table.SortableColumnHeader
渲染可排序列的标签与升序 / 降序指示器。请在 Table.Column 的渲染函数回调中使用,并将 sortDirection 透传进来。
| Prop | 类型 | 默认值 | 描述 |
|---|---|---|---|
sortDirection | "ascending" | "descending" | - | 当前排序方向。请从 Table.Column 的渲染函数中透传。 |
showIndicator | boolean | true | 当存在排序方向时是否渲染指示器图标。 |
indicator | React.ReactNode | - | 自定义指示器元素。会覆盖默认的 chevron,并会被自动注入 data-direction 属性。 |
className | string | - | 包裹元素的额外 CSS 类。 |
children | React.ReactNode | - | 列标签内容。 |
Table.Footer
| Prop | 类型 | 默认值 | 描述 |
|---|---|---|---|
className | string | - | 额外的 CSS 类。 |
children | React.ReactNode | - | 表底内容(例如分页)。 |
Table.ColumnResizer
| Prop | 类型 | 默认值 | 描述 |
|---|---|---|---|
className | string | - | 额外的 CSS 类。 |
Table.ResizableContainer
继承自 React Aria ResizableTableContainer。
| Prop | 类型 | 默认值 | 描述 |
|---|---|---|---|
className | string | - | 额外的 CSS 类。 |
children | React.ReactNode | - | Table.Content 元素。 |
Table.LoadMore
继承自 React Aria TableLoadMoreItem。
| Prop | 类型 | 默认值 | 描述 |
|---|---|---|---|
isLoading | boolean | false | 数据是否正在加载。 |
onLoadMore | () => void | - | 哨兵行可见时的事件处理函数。 |
children | React.ReactNode | - | 加载指示器内容。 |
Table.LoadMoreContent
| Prop | 类型 | 默认值 | 描述 |
|---|---|---|---|
className | string | - | 额外的 CSS 类。 |
children | React.ReactNode | - | 加载指示器内容(例如 Spinner)。 |
Table.Collection
由 React Aria Collection 重新导出。用于在行内与静态单元格并存时渲染动态单元格(例如复选框)。
| Prop | 类型 | 默认值 | 描述 |
|---|---|---|---|
items | T[] | - | 集合条目。 |
children | (item: T) => React.ReactNode | - | 每个条目的渲染函数。 |
TableLayout
| Name | 类型 | 默认值 | 描述 |
|---|---|---|---|
rowHeight | number | undefined | 48 | 行的固定高度(px)。 |
estimatedRowHeight | number | undefined | — | 行高可变时的估算高度。 |
headingHeight | number | undefined | 48 | 分区表头的固定高度(px)。 |
estimatedHeadingHeight | number | undefined | — | 表头高度可变时的估算高度。 |
loaderHeight | number | undefined | 48 | 加载器元素的固定高度(px)。该加载器用于在根级或嵌套行/分区中渲染「加载更多」等加载行。 |
dropIndicatorThickness | number | undefined | 2 | 放置指示器的线条粗细。 |
gap | number | undefined | 0 | 条目之间的间距。 |
padding | number | undefined | 0 | 列表的内边距。 |