Shadcn React Table

Search documentation

Search the docs

Composition

<DataTable /> lays out the whole table for you. When you need a different layout — the search box in your page header, pagination somewhere else, your own toolbar — use the table's parts directly.

Reading the table from anywhere inside it

Components rendered inside <DataTable /> (cells, toolbar slots, menu items, detail panels) can get the instance with useDataTableInstance() instead of receiving table as a prop:

tsx
import { useDataTableInstance } from "@/components/ui/data-table"

function SelectedCount() {
  const table = useDataTableInstance<Person>()
  return (
    <table.Subscribe selector={(state) => state.rowSelection}>
      {(selection) => <span>{Object.keys(selection).length} selected</span>}
    </table.Subscribe>
  )
}

const table = useDataTable({
  data,
  columns,
  enableRowSelection: true,
  renderTopToolbarCustomActions: () => <SelectedCount />,
})

The instance itself never changes, so subscribe to the state you show (as above) to re-render when it changes.

Your own layout

Wrap your layout in DataTableProvider and place the parts where you want them. Each part takes the table:

tsx
import {
  DataTable,
  DataTableDensityToggle,
  DataTableGlobalFilter,
  DataTablePagination,
  DataTableProvider,
  DataTableViewOptions,
  useDataTable,
} from "@/components/ui/data-table"

function People() {
  const table = useDataTable({
    data,
    columns,
    enableTopToolbar: false,
    enableBottomToolbar: false,
  })
  return (
    <DataTableProvider table={table}>
      <header className="flex items-center gap-2">
        <h2 className="mr-auto">People</h2>
        <DataTableGlobalFilter table={table} />
        <DataTableViewOptions table={table} />
        <DataTableDensityToggle table={table} />
      </header>
      <DataTable table={table} />
      <footer>
        <DataTablePagination table={table} />
      </footer>
    </DataTableProvider>
  )
}

Here the built-in toolbars are turned off and the same controls appear in your own header and footer.

CompositionYour own toolbar built from the table's parts.
GitHub
Team directory
ID
AvaThompsonOwnerEngineeringactive22$45,000Jan 2, 2023
0%
LiamNguyenAdminMarketinginactive25$47,137Jan 13, 2023
9%
NoahSilvaEditorDesignpending28$49,274Jan 24, 2023
18%
EmmaCarterViewerSalesactive31$51,411Feb 4, 2023
27%
OliviaRossiOwnerSupportinactive34$53,548Feb 15, 2023
36%
WilliamWalkerAdminEngineeringpending37$55,685Feb 26, 2023
45%
SophiaPatelEditorMarketingactive40$57,822Mar 9, 2023
54%
JamesMullerViewerDesigninactive43$59,959Mar 20, 2023
63%
IsabellaParkOwnerSalespending46$62,096Mar 31, 2023
72%
LucasReyesAdminSupportactive49$64,233Apr 11, 2023
81%
$4,120,536
Rows per page
1–10 of 48

Fully headless

Render the rows with your own markup and keep only the parts you want from the table — here the search box and pagination. The instance drives both; wrap the part that reads state in table.Subscribe so it re-renders.

HeadlessYour own table markup, driven by the instance, with our search and pagination.
GitHub

My own table markup

NameEmailRole
Ava Thompsonava.thompson@example.comOwner
Liam Nguyenliam.nguyen@example.comAdmin
Noah Silvanoah.silva@example.comEditor
Emma Carteremma.carter@example.comViewer
Olivia Rossiolivia.rossi@example.comOwner
Rows per page
1–5 of 48

The parts

PartWhat it is
DataTableToolbarThe whole top toolbar
DataTableBottomToolbarThe whole bottom toolbar
DataTableGlobalFilterSearch box with its mode menu
DataTablePaginationPage size, range and page buttons
DataTableAlertBannerThe selection banner
DataTableViewOptionsShow / hide / reorder columns menu
DataTableDensityToggleDensity menu
DataTableFullscreenToggleFull screen button
DataTableFilterToggleShow / hide the filter row
DataTableAdvancedFilterToggleOpens the advanced filter panel
DataTableFilterPanelThe advanced filter panel
DataTableDropToGroupZoneDrop zone for grouping by drag
DataTableColumnActionsA column's actions menu (takes column)
DataTableColumnFilterA column's filter field (takes column)
DataTableFilterModeMenuA column's filter-mode menu (takes column)
DataTableEditModalThe edit / create dialog

The header, body and footer stay inside <DataTable />, which manages their scrolling, virtualization and keyboard navigation. To change how they look, use slotProps.