Skip to content

shadcn.io is an independent project built on shadcn/ui

Free

Data Table with Filters for React

A users table with two search fields, Filter by name and Filter by email, over columns Name, Email, Role and Status.

Two search fields sit above a users table: Filter by name and Filter by email. The columns are Name, Email, Role and Status. John Doe is first, a Developer, and Active.

Filter from a text field when people know part of a name or an email. A Select fits a status with only a few values. On React, Base UI does not filter the rows.

Preview

Preview width

Installation

Sign in to get your install command
Free with an account. It carries your token, so the CLI installs everything in one go.
Use email insteadNo credit card

Usage

<div className="w-full max-w-4xl">
  <div className="flex items-center gap-4 py-4">
    <ColumnFilter column={table.getColumn("name")} label="Filter by name" />
    <ColumnFilter
      column={table.getColumn("email")}
      label="Filter by email"
    />
  </div>
  <div className="rounded-md border bg-background">
    <Table>
      <TableHeader>
        {table.getHeaderGroups().map((headerGroup) => (
          <TableRow key={headerGroup.id}>
            {headerGroup.headers.map((header) => (
              <TableHead key={header.id}>
                {header.isPlaceholder ? null : (
                  <table.FlexRender header={header} />
                )}
              </TableHead>
            ))}
          </TableRow>
        ))}
      </TableHeader>
      <TableBody>
        {rows.length > 0 ? (
          rows.map((row) => (
            <TableRow key={row.id}>
              {row.getAllCells().map((cell) => (
                <TableCell key={cell.id}>
                  <table.FlexRender cell={cell} />
                </TableCell>
{/* The rest of the file is under Installation. */}

FAQ

How do the inputs filter the table?

Each input belongs to a column, name or email. Its onChange calls column.setFilterValue and its value reads column.getFilterValue(). The table has columnFilteringFeature, createFilteredRowModel() and the includesString filter.

Can both inputs filter at once?

Yes. Each writes its own column's filter, and a row shows only when it matches both. Role and Status have no filter here.

How do I clear a filter?

Empty the input; an empty value removes that column's filter. The inputs are type="search", so browsers that support it show a clear button inside.

What appears when nothing matches?

The body renders one cell spanning every column with No results.

Which filter function runs?

includesString on both columns: it matches any part of the value and ignores case, so jo finds John Doe and Bob Johnson. Pick another of TanStack Table's filter functions, or write one, for exact or numeric matching.

Are the filters labeled?

Yes. Each input has an aria-label, Filter by name and Filter by email, and the same words as its placeholder. Tab moves between them and the table.

API Reference

Table

Sets colSpan={columns.length}. The rest is on the Table page.