DocsGuides

Guides

Column Filtering Guide

How to use, customize, or disable filter features, client-side or server side, in Shadcn Table

Filtering is one of the most powerful features of Shadcn Table and is enabled by default. There is a lot of flexibility and customization available here. Whether you want to customize the powerful client-side filtering already built in or implement your own server-side filtering, Shadcn Table has got you covered.

Relevant Table Options

#
Prop Name
Type
Default Value
More Info Links
1Array<ST_FilterOption | string> | nullST Column Filtering Docs
2booleanfalseST Column Filtering Docs
3booleantrueST Column Filtering Docs
4booleantrueTanStack Filters Docs
5booleantrueST Column Filtering Docs
6booleantrueTanStack Filters Docs
7Record<string, FilterFn>TanStack Table Filters Docs
8booleanfalseTanStack Filtering Docs
9booleanTanStack Table Filters Docs
10number100TanStack Table Filtering Docs
11OnChangeFn<{ [key: string]: ST_FilterOption }>
12OnChangeFn<ColumnFiltersState>TanStack Table Filter Docs
13OnChangeFn<boolean>
14({ column, internalFilterOptions, onSelectFilterMode, table }) => ReactNode[]
15AutocompleteProps | ({ column, rangeFilterIndex, table }) => AutocompletePropsshadcn/ui Autocomplete Props
16CheckboxProps | ({ column, table}) => CheckboxPropsshadcn/ui Checkbox Props
17DatePickerProps | ({ column, rangeFilterIndex, table }) => DatePickerPropsshadcn/ui Date Picker Props
18DateTimePickerProps | ({ column, rangeFilterIndex, table }) => DateTimePickerPropsshadcn/ui Date Picker Props
19SliderProps | ({ column, table}) => SliderPropsshadcn/ui Slider Props
20TextFieldProps | ({ table, column, rangeFilterIndex}) => TextFieldPropsshadcn/ui TextField Props
21TimePickerProps | ({ column, rangeFilterIndex, table }) => TimePickerPropsshadcn/ui Date Picker Props

Relevant Column Options

#
Column Option
Type
Default Value
More Info Links
1Array<string>
2booleanST Column Filtering Docs
3booleanST Column Filtering Docs
4booleanST Column Filtering Docs
5({ column, header, table }) => ReactNodeST Column Filtering Docs
6ST_FilterFn'fuzzy'
7Array<string | { label: string; value: string }>
8'text' | 'select' | 'multi-select' | 'range' | 'range-slider' | 'checkbox' | 'autocomplete' | 'date' | 'date-range' | 'datetime' | 'datetime-range' | 'time' | 'time-range''text'
9
10AutocompleteProps | ({ column, rangeFilterIndex, table }) => AutocompletePropsshadcn/ui Date Picker Props
11CheckboxProps | ({ column, table }) => CheckboxPropsshadcn/ui Checkbox Props
12DatePickerProps | ({ column, rangeFilterIndex, table }) => DatePickerPropsshadcn/ui Date Picker Props
13DateTimePickerProps | ({ column, rangeFilterIndex, table }) => DateTimePickerPropsshadcn/ui Date Picker Props
14SliderProps | ({ column, table}) => SliderPropsshadcn/ui Slider Props
15TextFieldProps | ({ column, rangeFilterIndex, table }) => TextFieldPropsshadcn/ui TextField Props
16TimePickerProps | ({ column, rangeFilterIndex, table }) => TimePickerPropsshadcn/ui Date Picker Props

Relevant State Options

#
State Option
Type
Default Value
More Info Links
1{ [key: string]: ST_FilterFn }
2Array<{id: string, value: unknown}>{}TanStack Table Filters Docs
3booleanfalse

Disable Filtering Features

Various subsets of filtering features can be disabled. If you want to disable filtering completely, you can set the enableColumnFilters table option to false to remove all filters from each column. Alternatively, enableColumnFilter can be set to false for individual columns.

enableFilters can be set to false to disable both column filters and the global search filter.

Filter Variants

Shadcn Table has several built-in filter variants for advanced filtering. These can be specified on a per-column basis using the filterVariant option. The following variants are available:

  • 'text' - shows the default text field
  • 'autocomplete' - shows an autocomplete text field with the options from faceted values or specified in filterSelectOptions array.
  • 'select' - shows a select dropdown with the options from faceted values or specified in filterSelectOptions array.
  • 'multi-select' - shows a select dropdown with the options from faceted values or specified in filterSelectOptions and allows multiple selections with checkboxes
  • 'range' - shows min and max text fields for filtering a range of values
  • 'range-slider' - shows a slider for filtering a range of values
  • 'date' - shows a date picker for filtering by date values
  • 'datetime' - shows a date and time picker for filtering by date and time values
  • 'date-range' - shows a date range picker for filtering by date ranges
  • 'datetime-range' - shows a date and time range picker for filtering by date and time ranges
  • 'time' - shows a time picker for filtering by time values
  • 'time-range' - shows a time range picker for filtering by time ranges
  • 'checkbox' - shows a checkbox for filtering by 'true' or 'false' values
Loading example

Faceted Values for Filter Variants

Faceted values are a list of unique values for a column that gets generated under the hood from table data when the enableFacetedValues table option is set to true. These values can be used to populate the select dropdowns for the 'select' and 'multi-select' filter variants, or the min and max values for the 'range-slider' variant. This means that you no longer need to manually specify the filterSelectOptions table option for these variants manually, especially if you are using client-side filtering.

Loading example

Custom Faceted Values

If you are using server-side pagination and filtering, you can still customize the faceted values output with the getFacetedUniqueValues and getFacetedMinMaxValues props.

const table = useShadcnTable({
  columns,
  data,
  enableFacetedValues: true,
  //if using server-side pagination and filtering
  getFacetedMinMaxValues: (table) => {
    //fetch min and max values from server
    return [minValue, maxValue];
  },
  //if using server-side filtering
  getFacetedUniqueValues: (table) => {
    const uniqueValueMap = new Map<string, number>();
    //fetch unique values from server, ideally including the count of each unique value
    return uniqueValueMap;
  },
})

Column Filter Display Modes

By default, column filters inputs show below the column header. You can switch to a more "excel-like" UI by setting the columnFilterDisplayMode table option to 'popover'. This will show a filter icon in the column header that can be clicked to open a popover with the filter input.

const table = useShadcnTable({
  columns,
  data,
  columnFilterDisplayMode: 'popover', //filter inputs will show in a popover (like excel)
});

Alternatively, if you want to render your own column filter UI in a separate sidebar, but still want to use the built-in filtering functionality, you can set the columnFilterDisplayMode table option to 'custom'.

const table = useShadcnTable({
  columns,
  data,
  columnFilterDisplayMode: 'custom', //render your own column filter UI (e.g. in a sidebar)
});
Loading example

Custom Filter Functions

You can specify either a pre-built filterFn that comes with Shadcn Table or pass in your own custom filter functions.

Custom Filter Functions Per Column

By default, Shadcn Table uses a fuzzy filtering algorithm based on the popular match-sorter library from Kent C. Dodds. However, Shadcn Table also comes with numerous other filter functions that you can specify per column in the filterFn column options.

Pre-built ST Filter Functions

Pre-built filter functions from Shadcn Table include between, betweenInclusive, contains, empty, endsWith, equals, fuzzy, greaterThan, greaterThanOrEqualTo, lessThan, lessThanOrEqualTo, notEmpty, notEquals, and startsWith. View these algorithms here

Pre-built TanStack Table Filter Functions

Pre-built filter functions from TanStack Table include includesString, includesStringSensitive, equalsString, equalsStringSensitive, arrIncludes, arrIncludesAll, arrIncludesSome, weakEquals, and inNumberRange. View more information about these algorithms in the TanStack Table Filter docs.

You can specify either a pre-built filter function, from Shadcn Table or TanStack Table, or you can even specify your own custom filter function in the filterFn column option.

const columns = [
  {
    accessorKey: 'firstName',
    header: 'First Name',
    // using a prebuilt filter function from Shadcn Table
    filterFn: 'startsWith',
  },
  {
    accessorKey: 'middleName',
    header: 'Middle Name',
    // using a prebuilt filter function from TanStack Table
    filterFn: 'includesStringSensitive',
  },
  {
    accessorKey: 'lastName',
    header: 'Last Name',
    // custom filter function
    filterFn: (row, id, filterValue) =>
      row.getValue(id).startsWith(filterValue),
  },
];

If you provide a custom filter function, it must have the following signature:

(row: Row<TData>, id: string, filterValue: string | number) => boolean;

This function will be used to filter 1 row at a time and should return a boolean indicating whether or not that row passes the filter.

Add Custom Filter Functions

You can add custom filter functions to the filterFns table option. These will be available to all columns to use. The filterFn table option on a column will override any filter function with the same name in the filterFns table option.

const columns = [
  {
    accessorKey: 'name',
    header: 'Name',
    filterFn: 'customFilterFn',
  },
];

const table = useShadcnTable({
  columns,
  data,
  filterFns: {
    customFilterFn: (row, id, filterValue) => {
      return row.customField === value;
    },
  },
});

Filter Modes

Enable Column Filter Modes (Filter Switching)

If you want to let the user switch between multiple different filter modes from a drop-down menu on the Filter Textfield, you can enable that with the enableColumnFilterModes table option or column option. This will enable the filter icon in the filter text field to open a drop-down menu with the available filter modes when clicked.

const table = useShadcnTable({
  columns,
  data,
  enableColumnFilterModes: true,
});

Customize Filter Modes

You can narrow down the available filter mode options by setting the columnFilterModeOptions table option or a column specific columnFilterModeOptions option.

const columns = [
  {
    accessorKey: 'firstName',
    header: 'First Name',
    columnFilterModeOptions: ['fuzzy', 'contains', 'startsWith'],
  },
  {
    accessorKey: 'age',
    header: 'Age',
    columnFilterModeOptions: ['between', 'lessThan', 'greaterThan'],
  },
];

Render Custom Filter Mode Menu

You can also render custom menu items in the filter mode drop-down menu by setting the renderColumnFilterModeMenuItems table option or column option. This option is a function that takes in the column and returns an array of MenuItem components. This is useful if you want to add custom filter modes that are not included in Shadcn Table, or if you just want to render the menu in your own custom way

const columns = [
  {
    accessorKey: 'firstName',
    header: 'First Name',
    renderColumnFilterModeMenuItems: ({ column, onSelectFilterMode }) => [
      <MenuItem
        key="startsWith"
        onClick={() => onSelectFilterMode('startsWith')}
      >
        Start With
      </MenuItem>,
      <MenuItem
        key="endsWith"
        onClick={() => onSelectFilterMode('yourCustomFilterFn')}
      >
        Your Custom Filter Fn
      </MenuItem>,
    ],
  },
];

const table = useShadcnTable({
  columns,
  data,
  enableColumnFilterModes: true,
  // renderColumnFilterModeMenuItems could go here if you want to apply to all columns
});

return <ShadcnTable table={table} />;
Loading example

Expanded Leaf Row Filtering Options

If you are using the filtering features along-side either the grouping or expanding features, then there are a few behaviors and customizations you should be aware of.

Check out the Expanded Leaf Row Filtering Behavior docs to learn more about the filterFromLeafRows and maxLeafRowFilterDepth props.

Manual Server-Side Column Filtering

A very common use case when you have a lot of data is to filter the data on the server, instead of client-side. In this case, you will want to set the manualFiltering table option to true and manage the columnFilters state yourself like so (can work in conjunction with manual global filtering).

// You can manage and have control over the columnFilters state yourself
const [columnFilters, setColumnFilters] = useState([]);
const [data, setData] = useState([]); //data will get updated after re-fetching

useEffect(() => {
  const fetchData = async () => {
    // send api requests when columnFilters state changes
    const filteredData = await fetch();
    setData([...filteredData]);
  };
}, [columnFilters]);

const table = useShadcnTable({
  columns,
  data, // this will already be filtered on the server
  manualFiltering: true, //turn off client-side filtering
  onColumnFiltersChange: setColumnFilters, //hoist internal columnFilters state to your state
  state: { columnFilters }, //pass in your own managed columnFilters state
});

return <ShadcnTable table={table} />;

Specifying manualFiltering turns off all client-side filtering and assumes that the data you pass to <ShadcnTable /> is already filtered.

See either the React Query or useEffect fetching examples to see fully server-side filtering, pagination, and sorting in action.

Customize shadcn/ui Filter components

You can customize the shadcn/ui filter components by setting the stFilterTextFieldProps table option or column option.

You can also turn a filter textfield into a select dropdown by setting the filterSelectOptions table option or column option.

Loading example

Custom Filter Components

If you need custom filter components that are much more complex than text-boxes and dropdowns, you can create and pass in your own filter components using the Filter column option.

Filter Match Highlighting

Filter Match Highlighting is a new featured enabled by default that will highlight text in the table body cells that matches the current filter query with a shade of the theme.palette.warning.main color.

Filter Match Highlighting will only work on columns with the default text filter variant. Also, if you are using a custom Cell render override for a column, you will need to use the renderedCellValue table option instead of cell.getValue() in order to preserve the filter match highlighting.

const columns = [
  {
    accessorKey: 'name',
    header: 'Name',
    Cell: ({ renderedCellValue }) => <span>{renderedCellValue}</span>, // use renderedCellValue instead of cell.getValue()
  },
];

Disable Filter Match Highlighting

This feature can be disabled by setting the enableFilterMatchHighlighting table option to false.

const table = useShadcnTable({
  columns,
  data,
  enableFilterMatchHighlighting: false,
});

View Extra Storybook Examples

On this page