Skip to main content
The Table component provides a set of composable sub-components for building accessible, semantic tables with consistent styling.

Basic usage

import { Table } from '@raystack/apsara';

function DataTable() {
  return (
    <Table>
      <Table.Header>
        <Table.Row>
          <Table.Head>Name</Table.Head>
          <Table.Head>Email</Table.Head>
          <Table.Head>Status</Table.Head>
        </Table.Row>
      </Table.Header>
      <Table.Body>
        <Table.Row>
          <Table.Cell>John Doe</Table.Cell>
          <Table.Cell>[email protected]</Table.Cell>
          <Table.Cell>Active</Table.Cell>
        </Table.Row>
        <Table.Row>
          <Table.Cell>Jane Smith</Table.Cell>
          <Table.Cell>[email protected]</Table.Cell>
          <Table.Cell>Active</Table.Cell>
        </Table.Row>
      </Table.Body>
    </Table>
  );
}

With section headers

Use Table.SectionHeader to group rows with labeled sections.
import { Table } from '@raystack/apsara';

function GroupedTable() {
  return (
    <Table>
      <Table.Header>
        <Table.Row>
          <Table.Head>Name</Table.Head>
          <Table.Head>Email</Table.Head>
          <Table.Head>Status</Table.Head>
        </Table.Row>
      </Table.Header>
      <Table.Body>
        <Table.SectionHeader colSpan={3}>Active Users</Table.SectionHeader>
        <Table.Row>
          <Table.Cell>John Doe</Table.Cell>
          <Table.Cell>[email protected]</Table.Cell>
          <Table.Cell>Active</Table.Cell>
        </Table.Row>
        <Table.SectionHeader colSpan={3}>Inactive Users</Table.SectionHeader>
        <Table.Row>
          <Table.Cell>Bob Wilson</Table.Cell>
          <Table.Cell>[email protected]</Table.Cell>
          <Table.Cell>Inactive</Table.Cell>
        </Table.Row>
      </Table.Body>
    </Table>
  );
}

With custom styling

Apply custom classes to any table component.
import { Table } from '@raystack/apsara';

function StyledTable() {
  return (
    <Table className="custom-table">
      <Table.Header>
        <Table.Row>
          <Table.Head className="text-left">Product</Table.Head>
          <Table.Head className="text-right">Price</Table.Head>
        </Table.Row>
      </Table.Header>
      <Table.Body>
        <Table.Row onClick={() => console.log('Row clicked')}>
          <Table.Cell className="font-bold">Widget</Table.Cell>
          <Table.Cell className="text-right">$29.99</Table.Cell>
        </Table.Row>
      </Table.Body>
    </Table>
  );
}

With spanning cells

Use colSpan and rowSpan attributes for merged cells.
import { Table } from '@raystack/apsara';

function SpanningTable() {
  return (
    <Table>
      <Table.Body>
        <Table.Row>
          <Table.Cell rowSpan={2}>Merged Vertically</Table.Cell>
          <Table.Cell>Cell 1</Table.Cell>
          <Table.Cell>Cell 2</Table.Cell>
        </Table.Row>
        <Table.Row>
          <Table.Cell colSpan={2}>Merged Horizontally</Table.Cell>
        </Table.Row>
      </Table.Body>
    </Table>
  );
}

API reference

Table (root)

className
string
Additional CSS classes to apply to the table element.
children
ReactNode
required
Table content, typically Table.Header and Table.Body.

Table.Header

className
string
Additional CSS classes to apply to the thead element.
children
ReactNode
required
Header content, typically Table.Row containing Table.Head cells.

Table.Body

children
ReactNode
required
Body content, typically multiple Table.Row elements.

Table.Row

className
string
Additional CSS classes to apply to the tr element.
onClick
() => void
Click handler for the row.
children
ReactNode
required
Row content, typically Table.Head or Table.Cell elements.

Table.Head

className
string
Additional CSS classes to apply to the th element.
colSpan
number
Number of columns the header cell should span.
children
ReactNode
required
Header cell content.

Table.Cell

className
string
Additional CSS classes to apply to the td element.
colSpan
number
Number of columns the cell should span.
rowSpan
number
Number of rows the cell should span.
children
ReactNode
required
Cell content.

Table.SectionHeader

colSpan
number
required
Number of columns the section header should span.
classNames
{ row?: string; cell?: string }
Custom classes for the row and cell elements.
children
ReactNode
required
Section header content.