Skip to main content
The Table component provides a flexible way to display tabular data with composition using TableHead, TableBody, TableRow, TableCell, and TableHeading components.

Basic Usage

import { Table, TableBody, TableRow, TableCell } from 'reshaped';

function App() {
  return (
    <Table>
      <TableBody>
        <TableRow>
          <TableCell>Cell 1</TableCell>
          <TableCell>Cell 2</TableCell>
          <TableCell>Cell 3</TableCell>
        </TableRow>
        <TableRow>
          <TableCell>Cell 4</TableCell>
          <TableCell>Cell 5</TableCell>
          <TableCell>Cell 6</TableCell>
        </TableRow>
      </TableBody>
    </Table>
  );
}

With Headers

Use TableHead and TableHeading for table headers:
import { 
  Table, 
  TableHead, 
  TableBody, 
  TableRow, 
  TableHeading, 
  TableCell 
} from 'reshaped';

function UsersTable() {
  return (
    <Table>
      <TableHead>
        <TableRow>
          <TableHeading>Name</TableHeading>
          <TableHeading>Email</TableHeading>
          <TableHeading>Status</TableHeading>
        </TableRow>
      </TableHead>
      <TableBody>
        <TableRow>
          <TableCell>John Doe</TableCell>
          <TableCell>[email protected]</TableCell>
          <TableCell>Active</TableCell>
        </TableRow>
        <TableRow>
          <TableCell>Jane Smith</TableCell>
          <TableCell>[email protected]</TableCell>
          <TableCell>Active</TableCell>
        </TableRow>
      </TableBody>
    </Table>
  );
}

Borders

Add borders to tables:
<Table border>
  <TableBody>
    <TableRow>
      <TableCell>Cell 1</TableCell>
      <TableCell>Cell 2</TableCell>
    </TableRow>
  </TableBody>
</Table>

<Table border columnBorder>
  <TableBody>
    <TableRow>
      <TableCell>Cell 1</TableCell>
      <TableCell>Cell 2</TableCell>
    </TableRow>
  </TableBody>
</Table>

Cell Alignment

Align cell content horizontally and vertically:
<Table border>
  <TableBody>
    <TableRow>
      <TableCell align="start">Start aligned</TableCell>
      <TableCell align="center">Center aligned</TableCell>
      <TableCell align="end">End aligned</TableCell>
    </TableRow>
    <TableRow>
      <TableCell verticalAlign="start">Top</TableCell>
      <TableCell verticalAlign="center">Middle</TableCell>
      <TableCell verticalAlign="end">Bottom</TableCell>
    </TableRow>
  </TableBody>
</Table>

Cell Width

Control column widths:
<Table border>
  <TableHead>
    <TableRow>
      <TableHeading width={200}>Fixed Width</TableHeading>
      <TableHeading width="auto">Auto Width</TableHeading>
      <TableHeading minWidth={150}>Min Width</TableHeading>
    </TableRow>
  </TableHead>
  <TableBody>
    <TableRow>
      <TableCell>Content 1</TableCell>
      <TableCell>Content 2</TableCell>
      <TableCell>Content 3</TableCell>
    </TableRow>
  </TableBody>
</Table>

Cell Padding

Customize cell padding:
<Table border>
  <TableBody>
    <TableRow>
      <TableCell padding={2}>Small padding</TableCell>
      <TableCell padding={4}>Default padding</TableCell>
      <TableCell padding={6}>Large padding</TableCell>
    </TableRow>
    <TableRow>
      <TableCell paddingInline={6} paddingBlock={2}>Custom padding</TableCell>
    </TableRow>
  </TableBody>
</Table>

Spanning Cells

Merge cells with rowSpan and colSpan:
<Table border>
  <TableBody>
    <TableRow>
      <TableCell rowSpan={2}>Spans 2 rows</TableCell>
      <TableCell>Cell 1</TableCell>
      <TableCell>Cell 2</TableCell>
    </TableRow>
    <TableRow>
      <TableCell colSpan={2}>Spans 2 columns</TableCell>
    </TableRow>
  </TableBody>
</Table>

Highlighted Rows

Highlight selected or active rows:
<Table border>
  <TableBody>
    <TableRow>Regular row</TableRow>
    <TableRow highlighted>Highlighted row</TableRow>
    <TableRow>Regular row</TableRow>
  </TableBody>
</Table>

Interactive Rows

Make rows clickable:
function InteractiveTable() {
  const [selected, setSelected] = React.useState(null);

  const users = [
    { id: 1, name: 'John Doe', email: '[email protected]' },
    { id: 2, name: 'Jane Smith', email: '[email protected]' },
    { id: 3, name: 'Bob Johnson', email: '[email protected]' },
  ];

  return (
    <Table border>
      <TableHead>
        <TableRow>
          <TableHeading>Name</TableHeading>
          <TableHeading>Email</TableHeading>
        </TableRow>
      </TableHead>
      <TableBody>
        {users.map(user => (
          <TableRow
            key={user.id}
            highlighted={selected === user.id}
            onClick={() => setSelected(user.id)}
          >
            <TableCell>{user.name}</TableCell>
            <TableCell>{user.email}</TableCell>
          </TableRow>
        ))}
      </TableBody>
    </Table>
  );
}

Complete Example

Full-featured data table:
import { 
  Table, 
  TableHead, 
  TableBody, 
  TableRow, 
  TableHeading, 
  TableCell,
  Badge,
  Text 
} from 'reshaped';

function OrdersTable({ orders }) {
  const statusColors = {
    pending: 'warning',
    completed: 'positive',
    cancelled: 'critical',
  };

  return (
    <Table border columnBorder>
      <TableHead>
        <TableRow>
          <TableHeading>Order ID</TableHeading>
          <TableHeading>Customer</TableHeading>
          <TableHeading align="end">Amount</TableHeading>
          <TableHeading>Status</TableHeading>
          <TableHeading>Date</TableHeading>
        </TableRow>
      </TableHead>
      <TableBody>
        {orders.map(order => (
          <TableRow key={order.id}>
            <TableCell>
              <Text variant="body-3" weight="medium">
                #{order.id}
              </Text>
            </TableCell>
            <TableCell>
              <Text variant="body-3">{order.customer}</Text>
            </TableCell>
            <TableCell align="end">
              <Text variant="body-3" weight="semibold">
                ${order.amount.toFixed(2)}
              </Text>
            </TableCell>
            <TableCell>
              <Badge 
                color={statusColors[order.status]} 
                size="small"
              >
                {order.status}
              </Badge>
            </TableCell>
            <TableCell>
              <Text variant="caption-1" color="neutral-faded">
                {order.date}
              </Text>
            </TableCell>
          </TableRow>
        ))}
      </TableBody>
    </Table>
  );
}

Props

Table

border
boolean
default:"false"
Add border around the table.
columnBorder
boolean
default:"false"
Add border between table columns.
className
string
default:"undefined"
Additional classname for the root element.
attributes
object
default:"undefined"
Additional attributes for the root element.
children
ReactNode
required
Node for inserting children.

TableRow

highlighted
boolean
default:"false"
Indicate that the row is selected or active.
onClick
function
default:"undefined"
Callback when the row is clicked. Makes the row interactive.
className
string
default:"undefined"
Additional classname for the row element.
attributes
object
default:"undefined"
Additional attributes for the row element.
children
ReactNode
required
Node for inserting children.

TableCell / TableHeading

align
string
default:"undefined"
Align the cell content horizontally.Options: start, center, end
verticalAlign
string
default:"undefined"
Align the cell content vertically.Options: start, center, end
width
string | number | 'auto'
default:"undefined"
Width of the cell. Can be a number (base unit multiplier), string (CSS value), or ‘auto’.
minWidth
string | number
default:"undefined"
Minimum width of the cell. Can be a number (base unit multiplier) or string (CSS value).
padding
number
default:"undefined"
Padding of the cell, base unit token number multiplier.
paddingInline
number
default:"undefined"
Horizontal padding of the cell, base unit token number multiplier.
paddingBlock
number
default:"undefined"
Vertical padding of the cell, base unit token number multiplier.
rowSpan
number
default:"undefined"
Merge the cell with cells below.
colSpan
number
default:"undefined"
Merge the cell with cells to the right.
className
string
default:"undefined"
Additional classname for the cell element.
attributes
object
default:"undefined"
Additional attributes for the cell element.
children
ReactNode
default:"undefined"
Node for inserting children.

TableHead / TableBody

className
string
default:"undefined"
Additional classname for the element.
attributes
object
default:"undefined"
Additional attributes for the element.
children
ReactNode
required
Node for inserting children.

Build docs developers (and LLMs) love