CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-react-table

Hooks for building lightweight, fast and extendable datagrids for React

Pending
Overview
Eval results
Files

filtering.mddocs/

Data Filtering

React Table provides comprehensive filtering capabilities through column-level filters and global search functionality. The filtering system supports multiple filter types, custom filter functions, and both manual and automatic filtering modes.

Capabilities

Column Filters (useFilters)

Enables individual column filtering with customizable filter types and automatic state management.

/**
 * Adds column filtering capabilities to the table
 * @param hooks - Hook registration object
 */
function useFilters(hooks: Hooks): void;

interface FilterInstance {
  /** Set filter value for a specific column */
  setFilter: (columnId: string, filterValue: any) => void;
  /** Set all column filters at once */
  setAllFilters: (filters: Filter[]) => void;
  /** Reset all filters to initial state */
  resetFilters: () => void;
  /** Rows before filtering was applied */
  preFilteredRows: Row[];
  /** Rows after column filtering */
  filteredRows: Row[];
}

interface FilterColumnInstance {
  /** Whether this column can be filtered */
  canFilter: boolean;
  /** Set this column's filter value */
  setFilter: (filterValue: any) => void;
  /** Current filter value for this column */
  filterValue: any;
  /** Rows before this column's filter was applied */
  preFilteredRows: Row[];
  /** Rows after this column's filter was applied */
  filteredRows: Row[];
}

interface Filter {
  /** Column ID to filter */
  id: string;
  /** Filter value */
  value: any;
}

Configuration Options:

interface FilterOptions {
  /** Disable automatic filtering (handle filtering externally) */
  manualFilters?: boolean;
  /** Whether columns can be filtered by default */
  defaultCanFilter?: boolean;
  /** Disable all filtering */
  disableFilters?: boolean;
  /** Custom filter type definitions */
  filterTypes?: Record<string, FilterFunction>;
  /** Auto-reset filters when data changes */
  autoResetFilters?: boolean;
  /** Initial filter state */
  initialState?: {
    filters?: Filter[];
  };
}

interface FilterFunction {
  (rows: Row[], columnIds: string[], filterValue: any): Row[];
  /** Function to determine when filter should be auto-removed */
  autoRemove?: (filterValue: any, column?: Column) => boolean;
}

Usage Example:

import React from 'react';
import { useTable, useFilters } from 'react-table';

function FilterableTable({ columns, data }) {
  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    rows,
    prepareRow,
    setFilter,
    setAllFilters,
  } = useTable(
    {
      columns,
      data,
      defaultCanFilter: true, // Enable filtering for all columns
    },
    useFilters
  );

  return (
    <div>
      {/* Filter Controls */}
      <div>
        <input
          placeholder="Filter by name..."
          onChange={(e) => setFilter('name', e.target.value)}
        />
        <button onClick={() => setAllFilters([])}>
          Clear All Filters
        </button>
      </div>

      <table {...getTableProps()}>
        <thead>
          {headerGroups.map(headerGroup => (
            <tr {...headerGroup.getHeaderGroupProps()}>
              {headerGroup.headers.map(column => (
                <th {...column.getHeaderProps()}>
                  {column.render('Header')}
                  {/* Column Filter */}
                  <div>
                    {column.canFilter && (
                      <input
                        value={column.filterValue || ''}
                        onChange={(e) => column.setFilter(e.target.value)}
                        placeholder={`Filter ${column.render('Header')}`}
                      />
                    )}
                  </div>
                </th>
              ))}
            </tr>
          ))}
        </thead>
        <tbody {...getTableBodyProps()}>
          {rows.map(row => {
            prepareRow(row);
            return (
              <tr {...row.getRowProps()}>
                {row.cells.map(cell => (
                  <td {...cell.getCellProps()}>
                    {cell.render('Cell')}
                  </td>
                ))}
              </tr>
            );
          })}
        </tbody>
      </table>
    </div>
  );
}

Global Filter (useGlobalFilter)

Provides global search functionality that filters across all filterable columns.

/**
 * Adds global filtering capabilities to the table
 * @param hooks - Hook registration object
 */
function useGlobalFilter(hooks: Hooks): void;

interface GlobalFilterInstance {
  /** Set the global filter value */
  setGlobalFilter: (filterValue: any) => void;
  /** Reset global filter to initial state */
  resetGlobalFilter: () => void;
  /** Rows before global filtering was applied */
  preGlobalFilteredRows: Row[];
  /** Rows after global filtering */
  globalFilteredRows: Row[];
}

Configuration Options:

interface GlobalFilterOptions {
  /** Disable automatic global filtering */
  manualGlobalFilter?: boolean;
  /** Global filter function or filter type name */
  globalFilter?: string | FilterFunction;
  /** Disable global filtering entirely */
  disableGlobalFilter?: boolean;
  /** Auto-reset global filter when data changes */
  autoResetGlobalFilter?: boolean;
  /** Initial global filter state */
  initialState?: {
    globalFilter?: any;
  };
}

Usage Example:

import React from 'react';
import { useTable, useFilters, useGlobalFilter } from 'react-table';

function GloballyFilterableTable({ columns, data }) {
  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    rows,
    prepareRow,
    setGlobalFilter,
    preGlobalFilteredRows,
    state: { globalFilter },
  } = useTable(
    {
      columns,
      data,
    },
    useFilters,
    useGlobalFilter
  );

  return (
    <div>
      {/* Global Search */}
      <div>
        <input
          value={globalFilter || ''}
          onChange={(e) => setGlobalFilter(e.target.value)}
          placeholder={`Search ${preGlobalFilteredRows.length} records...`}
        />
      </div>

      <table {...getTableProps()}>
        {/* Table implementation */}
      </table>
    </div>
  );
}

Built-in Filter Types

React Table includes several built-in filter functions for common use cases.

interface FilterTypes {
  /** Case-insensitive text contains filter */
  text: FilterFunction;
  /** Case-insensitive exact text match */
  exactText: FilterFunction;
  /** Case-sensitive exact text match */
  exactTextCase: FilterFunction;
  /** Array includes value filter */
  includes: FilterFunction;
  /** Array includes all values filter */
  includesAll: FilterFunction;
  /** Array includes some values filter */
  includesSome: FilterFunction;
  /** Value included in array filter */
  includesValue: FilterFunction;
  /** Strict equality filter */
  exact: FilterFunction;
  /** Loose equality filter */
  equals: FilterFunction;
  /** Numeric range filter */
  between: FilterFunction;
}

Filter Type Examples:

const columns = [
  {
    Header: 'Name',
    accessor: 'name',
    filter: 'text', // Case-insensitive contains
  },
  {
    Header: 'Status',
    accessor: 'status', 
    filter: 'exactText', // Exact match
  },
  {
    Header: 'Age',
    accessor: 'age',
    filter: 'between', // Numeric range
    Filter: ({ column: { filterValue = [], setFilter } }) => (
      <div>
        <input
          value={filterValue[0] || ''}
          type="number"
          onChange={(e) => setFilter([e.target.value, filterValue[1]])}
          placeholder="Min"
        />
        <input
          value={filterValue[1] || ''}
          type="number"
          onChange={(e) => setFilter([filterValue[0], e.target.value])}
          placeholder="Max"
        />
      </div>
    ),
  },
  {
    Header: 'Tags',
    accessor: 'tags',
    filter: 'includesSome', // Array intersection
  },
];

Custom Filter Functions

Create custom filter logic for specialized filtering needs.

/**
 * Custom filter function signature
 * @param rows - Array of rows to filter
 * @param columnIds - Array of column IDs being filtered
 * @param filterValue - The filter value
 * @returns Filtered array of rows
 */
interface CustomFilterFunction {
  (rows: Row[], columnIds: string[], filterValue: any): Row[];
  /** Auto-removal logic */
  autoRemove?: (filterValue: any, column?: Column) => boolean;
}

Custom Filter Examples:

// Custom filter for date ranges
const dateRangeFilter = (rows, columnIds, filterValue) => {
  const [startDate, endDate] = filterValue || [];
  
  if (!startDate && !endDate) return rows;
  
  return rows.filter(row => {
    return columnIds.some(columnId => {
      const cellValue = row.values[columnId];
      const date = new Date(cellValue);
      
      if (startDate && date < new Date(startDate)) return false;
      if (endDate && date > new Date(endDate)) return false;
      
      return true;
    });
  });
};

// Auto-remove when both dates are empty
dateRangeFilter.autoRemove = (value) => {
  return !value || (!value[0] && !value[1]);
};

// Custom filter for fuzzy matching
const fuzzyTextFilter = (rows, columnIds, filterValue) => {
  const searchTerm = filterValue.toLowerCase();
  
  return rows.filter(row => {
    return columnIds.some(columnId => {
      const cellValue = String(row.values[columnId]).toLowerCase();
      
      // Simple fuzzy matching: allow 1 character difference per 4 characters
      const maxDistance = Math.floor(searchTerm.length / 4);
      return levenshteinDistance(cellValue, searchTerm) <= maxDistance;
    });
  });
};

fuzzyTextFilter.autoRemove = val => !val;

// Register custom filters
const table = useTable(
  {
    columns,
    data,
    filterTypes: {
      dateRange: dateRangeFilter,
      fuzzy: fuzzyTextFilter,
    },
  },
  useFilters
);

Column Filter Configuration

Configure filtering behavior at the column level.

interface ColumnFilterConfig {
  /** Filter type name or custom filter function */
  filter?: string | FilterFunction;
  /** Whether this column can be filtered */
  disableFilters?: boolean;
  /** Custom Filter component for UI */
  Filter?: React.ComponentType<{
    column: Column;
    filterValue: any;
    setFilter: (value: any) => void;
    preFilteredRows: Row[];
  }>;
}

Column Filter Examples:

const columns = [
  {
    Header: 'Product Name',
    accessor: 'name',
    filter: 'text',
    // Custom filter UI component
    Filter: ({ column: { filterValue, setFilter, preFilteredRows } }) => {
      const count = preFilteredRows.length;
      return (
        <input
          value={filterValue || ''}
          onChange={(e) => setFilter(e.target.value || undefined)}
          placeholder={`Search ${count} products...`}
        />
      );
    },
  },
  {
    Header: 'Category',
    accessor: 'category',
    filter: 'exactText',
    // Dropdown filter
    Filter: ({ column: { filterValue, setFilter, preFilteredRows } }) => {
      const options = React.useMemo(() => {
        const opts = new Set();
        preFilteredRows.forEach(row => opts.add(row.values.category));
        return [...opts.values()];
      }, [preFilteredRows]);

      return (
        <select
          value={filterValue || ''}
          onChange={(e) => setFilter(e.target.value || undefined)}
        >
          <option value="">All</option>
          {options.map(option => (
            <option key={option} value={option}>
              {option}
            </option>
          ))}
        </select>
      );
    },
  },
  {
    Header: 'Price',
    accessor: 'price',
    disableFilters: true, // Disable filtering for this column
  },
];

Manual Filtering

Take control of filtering logic for server-side or custom implementations.

function ManuallyFilteredTable({ columns, data }) {
  const [filters, setFilters] = React.useState([]);
  const [globalFilter, setGlobalFilter] = React.useState('');

  // Fetch filtered data based on current filters
  const filteredData = React.useMemo(() => {
    return fetchFilteredData(data, filters, globalFilter);
  }, [data, filters, globalFilter]);

  const {
    getTableProps,
    getTableBodyProps,
    headerGroups,
    rows,
    prepareRow,
  } = useTable(
    {
      columns,
      data: filteredData,
      manualFilters: true, // Disable automatic filtering
      manualGlobalFilter: true,
      // Provide current filter state
      state: {
        filters,
        globalFilter,
      },
    },
    useFilters,
    useGlobalFilter
  );

  return (
    <div>
      <input
        value={globalFilter}
        onChange={(e) => setGlobalFilter(e.target.value)}
        placeholder="Global search..."
      />
      
      <table {...getTableProps()}>
        {/* Table implementation */}
      </table>
    </div>
  );
}

Types

interface TableState {
  /** Column filter configurations */
  filters: Filter[];
  /** Global filter value */
  globalFilter: any;
}

interface Filter {
  /** Column ID */
  id: string;
  /** Filter value */
  value: any;
}

interface FilterMeta {
  instance: TableInstance;
  column: Column;
}

Install with Tessl CLI

npx tessl i tessl/npm-react-table

docs

built-in-types.md

column-management.md

core-table.md

filtering.md

grouping.md

index.md

layout.md

pagination.md

row-features.md

sorting.md

utilities.md

tile.json