Table

Rows and columns of data.

Source

Basic table

Use this for data in rows and columns. Use a caption and native header cells to describe the data.

Feature flags in this project
FlagStatusRollout
new-onboarding-flowEnabled100%
pricing-page-v2Enabled25%
hedgehog-modeDisabled0%
3 flags, 2 enabled

Surfaces

Use raised (the default) on the window background. Use plain inside a card, so there is no box in a box. Use outlined in a Section or another flat region.

raised · on the window
EventThis week
$pageview48,210
$autocapture31,904
insight viewed6,412
outlined · in a section
EventThis week
$pageview48,210
$autocapture31,904
insight viewed6,412
plain · inside a card
EventThis week
$pageview48,210
$autocapture31,904
insight viewed6,412

Density and stripes

Use compact for data that people scan, such as event lists and long API tables. Use default for tables that people read, such as pricing and comparisons. Stripes tint alternate rows.

default · read
EventLast 30 days
$pageview1,284,302
$autocapture902,118
$identify64,930
$feature_flag_called41,207
compact · scan
EventLast 30 days
$pageview1,284,302
$autocapture902,118
$identify64,930
$feature_flag_called41,207

Interactive rows

Move the pointer over a row to see its tint. Put links or buttons in the cells for actions.

ProductUse it forDocs
Product analyticsFunnels, trends, and retentionRead docs
Session replayWatch real user sessionsRead docs
Feature flagsRoll out changes safelyRead docs
SurveysAsk users questions in your appRead docs

Sortable headers

Click a header to sort. The caller keeps the sort state and orders the rows.

$pageview48,210
$autocapture31,904
insight viewed6,412
dashboard viewed3,870
survey sent912

Numeric columns and footer

Align numbers at the end of each column. Cells use tabular numerals, so digits line up.

Events by source, last 30 days
SourceEventsShare
Web (posthog-js)2,481,90362.4%
iOS812,44020.4%
Android401,22710.1%
Backend (posthog-python)282,0197.1%
Total3,977,589100.0%

Usage

These are defaults, not laws. Break one when you have a good reason, or when it makes the design more cohesive or more interesting.

  • To line up the columns of several tables, add table-fixed to Table.Root and give each table the same <colgroup> widths.
  • Name the table with Caption, and set scope="row" on row headers.
  • The table only shows data. Sorting, filtering, pagination, and number formats are yours to supply.
  • Cell styles use ! classes to beat prose table styles. Use ! to override them, such as !px-0.

API

Table is a site component. Its parts accept native table element props.

Table.Root

PropTypeDefaultDescription
appearance'plain' | 'outlined' | 'raised''raised'Sets the scroll container surface. Plain has no border or fill. Raised adds elevation.
density'compact' | 'default''default'Sets vertical cell padding.
stripedbooleanfalseAdds a tint to alternate body rows.
interactivebooleanfalseAdds a tint on body row hover.
stickyHeaderbooleanfalseKeeps the header at the top of the scroll container.
containerPropsHTMLAttributes<HTMLDivElement>–Sets scroll container attributes, className, and style. Set its maximum height for vertical scroll.

Table.Head

PropTypeDefaultDescription
align'start' | 'center' | 'end''start'Sets text alignment.
sort'ascending' | 'descending' | 'none'–Shows the sort carets and sets aria-sort. Omit it for a column that does not sort.
onSort() => void–Makes the header label a button. Set the next sort state in this callback.
scopestring'col'Identifies the cells that this header describes.

Table.Cell

PropTypeDefaultDescription
align'start' | 'center' | 'end''start'Sets text alignment.