# Table · HeroUI

> Tables display structured data in rows and columns with support for sorting, selection, column resizing, and infinite scrolling.

- Page: https://jiguang132.com/systems/heroui/docs/components/table
- Based on: HeroUI documentation (Apache-2.0) @ 60edd8ed751b1d2a270623fbb182bbcfa8baa9af

## Import

```tsx
import { Table } from '@heroui/react';
```

### Usage


> Example `table-basic`: interactive preview on https://jiguang132.com/systems/heroui/docs/components/table


### Anatomy

Import the Table component and access all parts using dot notation.

```tsx
import { Table } from '@heroui/react';

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>
);
```

### Secondary Variant


> Example `table-secondary-variant`: interactive preview on https://jiguang132.com/systems/heroui/docs/components/table


### Sorting

Columns can be made sortable using the `allowsSorting` prop on `Table.Column`. Use `sortDescriptor` and `onSortChange` on `Table.Content` to manage sort state. Wrap the label in `Table.SortableColumnHeader` and forward the `sortDirection` from the column's render prop to render the default ascending/descending indicator.


> Example `table-sorting`: interactive preview on https://jiguang132.com/systems/heroui/docs/components/table


### Selection

Enable row selection with `selectionMode` on `Table.Content`. Use `Checkbox` with `slot="selection"` for select-all and per-row checkboxes.


> Example `table-selection`: interactive preview on https://jiguang132.com/systems/heroui/docs/components/table


### Custom Cells


> Example `table-custom-cells`: interactive preview on https://jiguang132.com/systems/heroui/docs/components/table


### Expandable Rows

Rows can be nested to display hierarchical data. Use the `treeColumn` prop to designate a column, and render a `Button` with `slot="chevron"` in that column’s cells so users can expand and collapse the row. Use the `expandedKeys` prop to control which rows are expanded.


> Example `table-expandable-rows`: interactive preview on https://jiguang132.com/systems/heroui/docs/components/table


### Pagination

Use `Table.Footer` to add a pagination component below the table.


> Example `table-pagination`: interactive preview on https://jiguang132.com/systems/heroui/docs/components/table


### Column Resizing

Wrap the table in `Table.ResizableContainer` and add `Table.ColumnResizer` inside each resizable column.


> Example `table-column-resizing`: interactive preview on https://jiguang132.com/systems/heroui/docs/components/table


### Empty State

Use `renderEmptyState` on `Table.Body` to display a custom message when the table has no data.


> Example `table-empty-state`: interactive preview on https://jiguang132.com/systems/heroui/docs/components/table


### Async Loading

Use `Table.LoadMore` for infinite scrolling. It renders a sentinel row that triggers `onLoadMore` when scrolled into view.


> Example `table-async-loading`: interactive preview on https://jiguang132.com/systems/heroui/docs/components/table


### Virtualization

Table supports virtualization through [Virtualizer](https://react-aria.adobe.com/Virtualizer), enabling efficient rendering of large datasets by displaying only the rows visible within the viewport.


> Example `table-virtualization`: interactive preview on https://jiguang132.com/systems/heroui/docs/components/table


### TanStack Table

HeroUI's Table works as a rendering layer on top of headless table libraries.
This example uses [TanStack Table](https://tanstack.com/table) for column
definitions, sorting, and pagination — while HeroUI handles styling and
accessibility.


> Example `table-tanstack-table`: interactive preview on https://jiguang132.com/systems/heroui/docs/components/table


## Styling

### Passing Tailwind CSS classes

You can customize individual Table parts:

```tsx
import { Table } from '@heroui/react';

function CustomTable() {
  return (
    <Table className="border border-purple-200">
      <Table.ScrollContainer>
        <Table.Content aria-label="Custom styled table">
          <Table.Header className="bg-purple-50">
            <Table.Column>Name</Table.Column>
          </Table.Header>
          <Table.Body>
            <Table.Row className="hover:bg-purple-50">
              <Table.Cell>Kate Moore</Table.Cell>
            </Table.Row>
          </Table.Body>
        </Table.Content>
      </Table.ScrollContainer>
    </Table>
  );
}
```

### Customizing the component classes

To customize the Table component classes, you can use the `@layer components` directive.
  
[Learn more](https://tailwindcss.com/docs/adding-custom-styles#adding-component-classes).

```css
@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 follows the [BEM](https://getbem.com/) methodology to ensure component variants and states are reusable and easy to customize.

### CSS Classes

The Table component uses these CSS classes ([View source styles](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/components/table.css)):

#### Base Classes
- `.table-root` - Root container (named `table-root` instead of `table` because `table` is a built-in Tailwind CSS utility class for `display: table`)
- `.table__scroll-container` - Horizontal scroll wrapper with custom scrollbar
- `.table__content` - The `<table>` element
- `.table__header` - Header row (`<thead>`)
- `.table__column` - Column header cell (`<th>`)
- `.table__body` - Body section (`<tbody>`)
- `.table__row` - Row element (`<tr>`)
- `.table__cell` - Data cell (`<td>`)
- `.table__footer` - Footer container (outside table)

#### Advanced Classes
- `.table__column-resizer` - Drag handle for column resizing
- `.table__resizable-container` - Wrapper enabling column resizing
- `.table__load-more` - Sentinel row for infinite scrolling
- `.table__load-more-content` - Styled container for the loading indicator
- `.table__sortable-column-header` - Sortable column label + indicator wrapper
- `.table__sortable-column-indicator` - Sort direction chevron (rotates via `[data-direction="descending"]`)

#### Variant Classes
- `.table-root--primary` - Gray background container with card-style body (default)
- `.table-root--secondary` - No background, standalone rounded headers

### Interactive States

The Table supports both CSS pseudo-classes and data attributes for flexibility:

- **Hover**: `:hover` or `[data-hovered="true"]` (row background change)
- **Selected**: `[data-selected="true"]` (row highlight)
- **Focus**: `:focus-visible` or `[data-focus-visible="true"]` (inset focus ring on rows, columns, and cells)
- **Disabled**: `:disabled` or `[aria-disabled="true"]` (reduced opacity)
- **Sortable**: `[data-allows-sorting="true"]` (interactive cursor on columns)
- **Dragging**: `[data-dragging="true"]` (reduced opacity)
- **Drop Target**: `[data-drop-target="true"]` (accent background)

## API Reference

### Table Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `variant` | `"primary" \| "secondary"` | `"primary"` | Visual variant. Primary has a gray background container; secondary is flat with transparent rows. |
| `className` | `string` | - | Additional CSS classes for the root container |
| `children` | `React.ReactNode` | - | Table content (ScrollContainer, Footer, etc.) |

### Table.ScrollContainer Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `className` | `string` | - | Additional CSS classes |
| `children` | `React.ReactNode` | - | Table.Content element |

### Table.Content Props

Inherits from [React Aria Table](https://react-spectrum.adobe.com/react-aria/Table.html).

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `aria-label` | `string` | - | Accessible label for the table |
| `selectionMode` | `"none" \| "single" \| "multiple"` | `"none"` | Selection behavior |
| `selectedKeys` | `Selection` | - | Controlled selected keys |
| `onSelectionChange` | `(keys: Selection) => void` | - | Selection change handler |
| `sortDescriptor` | `SortDescriptor` | - | Current sort state |
| `onSortChange` | `(descriptor: SortDescriptor) => void` | - | Sort change handler |
| `className` | `string` | - | Additional CSS classes |

### Table.Header Props

Inherits from [React Aria TableHeader](https://react-spectrum.adobe.com/react-aria/Table.html#tableheader).

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `columns` | `T[]` | - | Dynamic column data for render prop pattern |
| `children` | `React.ReactNode \| (column: T) => React.ReactNode` | - | Static columns or render prop |

### Table.Column Props

Inherits from [React Aria Column](https://react-spectrum.adobe.com/react-aria/Table.html#column).

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `id` | `string` | - | Column identifier |
| `allowsSorting` | `boolean` | `false` | Whether the column is sortable |
| `isRowHeader` | `boolean` | `false` | Whether this column is a row header |
| `defaultWidth` | `string \| number` | - | Default width for resizable columns |
| `minWidth` | `number` | - | Minimum width for resizable columns |
| `children` | `React.ReactNode \| (values: ColumnRenderProps) => React.ReactNode` | - | Column content or render prop with sort direction |

### Table.Body Props

Inherits from [React Aria TableBody](https://react-spectrum.adobe.com/react-aria/Table.html#tablebody).

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `items` | `T[]` | - | Dynamic row data for render prop pattern |
| `renderEmptyState` | `() => React.ReactNode` | - | Content to display when the table is empty |
| `children` | `React.ReactNode \| (item: T) => React.ReactNode` | - | Static rows or render prop |

### Table.Row Props

Inherits from [React Aria Row](https://react-spectrum.adobe.com/react-aria/Table.html#row).

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `id` | `string \| number` | - | Row identifier |
| `className` | `string` | - | Additional CSS classes |
| `children` | `React.ReactNode` | - | Row cells |

### Table.Cell Props

Inherits from [React Aria Cell](https://react-spectrum.adobe.com/react-aria/Table.html#cell).

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `className` | `string` | - | Additional CSS classes |
| `children` | `React.ReactNode` | - | Cell content |

### Table.SortableColumnHeader Props

Renders a sortable column label with an ascending/descending indicator. Use it inside a `Table.Column` render-prop callback and forward the `sortDirection` value.

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `sortDirection` | `"ascending" \| "descending"` | - | Current sort direction. Pass through from the `Table.Column` render prop. |
| `showIndicator` | `boolean` | `true` | Whether to render the sort indicator icon when a direction is set. |
| `indicator` | `React.ReactNode` | - | Custom indicator element. Overrides the default chevron and receives a `data-direction` attribute. |
| `className` | `string` | - | Additional CSS classes for the wrapper. |
| `children` | `React.ReactNode` | - | Column label content. |

### Table.Footer Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `className` | `string` | - | Additional CSS classes |
| `children` | `React.ReactNode` | - | Footer content (e.g., pagination) |

### Table.ColumnResizer Props

Inherits from [React Aria ColumnResizer](https://react-spectrum.adobe.com/react-aria/Table.html#columnresizer).

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `className` | `string` | - | Additional CSS classes |

### Table.ResizableContainer Props

Inherits from [React Aria ResizableTableContainer](https://react-spectrum.adobe.com/react-aria/Table.html#resizabletablecontainer).

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `className` | `string` | - | Additional CSS classes |
| `children` | `React.ReactNode` | - | Table.Content element |

### Table.LoadMore Props

Inherits from [React Aria TableLoadMoreItem](https://react-spectrum.adobe.com/react-aria/Table.html).

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `isLoading` | `boolean` | `false` | Whether data is currently loading |
| `onLoadMore` | `() => void` | - | Handler called when the sentinel row is visible |
| `children` | `React.ReactNode` | - | Loading indicator content |

### Table.LoadMoreContent Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `className` | `string` | - | Additional CSS classes |
| `children` | `React.ReactNode` | - | Loading indicator content (e.g., Spinner) |

### Table.Collection Props

Re-exported from React Aria `Collection`. Used to render dynamic cells within rows alongside static cells (e.g., checkboxes).

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `items` | `T[]` | - | Collection items |
| `children` | `(item: T) => React.ReactNode` | - | Render prop for each item |


### TableLayout

| Name | Type | Default | Description |
|------|------|---------|-------------|
| `rowHeight` | `number \| undefined` | 48 | The fixed height of a row in px. |
| `estimatedRowHeight` | `number \| undefined` | — | The estimated height of a row, when row heights are variable. |
| `headingHeight` | `number \| undefined` | 48 | The fixed height of a section header in px. |
| `estimatedHeadingHeight` | `number \| undefined` | — | The estimated height of a section header, when the height is variable. |
| `loaderHeight` | `number \| undefined` | 48 | The fixed height of a loader element in px. This loader is specifically for "load more" elements rendered when loading more rows at the root level or inside nested row/sections. |
| `dropIndicatorThickness` | `number \| undefined` | 2 | The thickness of the drop indicator. |
| `gap` | `number \| undefined` | 0 | The gap between items. |
| `padding` | `number \| undefined` | 0 | The padding around the list. |

---

Index of all JGuang resources: https://jiguang132.com/llms.txt
