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

built-in-types.mddocs/

Built-in Types and Functions

React Table provides comprehensive built-in filter types, sort types, and aggregation functions that handle common data operations. These pre-built functions can be used directly or serve as examples for creating custom implementations.

Capabilities

Built-in Filter Types

Pre-built filter functions for common filtering scenarios. These can be referenced by string name in column definitions.

interface FilterTypes {
  /** Case-insensitive text search - checks if filter value is included in cell value */
  text: (rows: Row[], columnId: string, filterValue: string) => Row[];
  
  /** Case-insensitive exact text match */
  exactText: (rows: Row[], columnId: string, filterValue: string) => Row[];
  
  /** Case-sensitive exact text match */
  exactTextCase: (rows: Row[], columnId: string, filterValue: string) => Row[];
  
  /** Array includes filter value */
  includes: (rows: Row[], columnId: string, filterValue: any) => Row[];
  
  /** Array includes all filter values */
  includesAll: (rows: Row[], columnId: string, filterValue: any[]) => Row[];
  
  /** Array includes some filter values */
  includesSome: (rows: Row[], columnId: string, filterValue: any[]) => Row[];
  
  /** Cell value is included in filter value array */
  includesValue: (rows: Row[], columnId: string, filterValue: any[]) => Row[];
  
  /** Strict equality match (===) */
  exact: (rows: Row[], columnId: string, filterValue: any) => Row[];
  
  /** Loose equality match (==) */
  equals: (rows: Row[], columnId: string, filterValue: any) => Row[];
  
  /** Numeric range filter - value between min and max */
  between: (rows: Row[], columnId: string, filterValue: [number, number]) => Row[];
}

Usage Examples:

const columns = [
  {
    Header: 'Name',
    accessor: 'name',
    filter: 'text', // Case-insensitive text search
  },
  {
    Header: 'Status',
    accessor: 'status',
    filter: 'exactText', // Exact match for status values
  },
  {
    Header: 'Tags',
    accessor: 'tags',
    filter: 'includesAll', // All selected tags must be present
  },
  {
    Header: 'Category',
    accessor: 'category',
    filter: 'includesValue', // Category must be in selected list
  },
  {
    Header: 'Price',
    accessor: 'price',
    filter: 'between', // Price range filtering
  },
];

// Custom filter value examples
const filterExample = () => {
  const [filters, setFilters] = React.useState([
    { id: 'name', value: 'john' }, // Text search
    { id: 'status', value: 'Active' }, // Exact match
    { id: 'tags', value: ['urgent', 'featured'] }, // Include all tags
    { id: 'category', value: ['electronics', 'books'] }, // Category in list
    { id: 'price', value: [10, 100] }, // Price between 10 and 100
  ]);
  
  return { filters, setFilters };
};

Built-in Sort Types

Pre-built sorting functions for different data types and sorting scenarios.

interface SortTypes {
  /** 
   * Default alphanumeric sort - handles mixed strings and numbers intelligently
   * Sorts numbers numerically and strings alphabetically
   */
  alphanumeric: (rowA: Row, rowB: Row, columnId: string, desc?: boolean) => number;
  
  /** 
   * Date/time sorting - parses dates and sorts chronologically
   * Handles various date formats and ISO strings
   */
  datetime: (rowA: Row, rowB: Row, columnId: string, desc?: boolean) => number;
  
  /**
   * Basic comparison sort - uses simple comparison operators
   * Good for primitive values
   */
  basic: (rowA: Row, rowB: Row, columnId: string, desc?: boolean) => number;
  
  /**
   * String sort - case-insensitive string comparison
   * Converts values to strings before comparing
   */
  string: (rowA: Row, rowB: Row, columnId: string, desc?: boolean) => number;
  
  /**
   * Numeric sort - strips non-numeric characters and sorts numerically
   * Handles currency symbols, percentages, etc.
   */
  number: (rowA: Row, rowB: Row, columnId: string, desc?: boolean) => number;
}

/**
 * Default sorting function - alias for alphanumeric sort
 */
function defaultOrderByFn(
  rowA: Row,
  rowB: Row,
  columnId: string,
  desc?: boolean
): number;

Usage Examples:

const columns = [
  {
    Header: 'Product Name',
    accessor: 'name',
    sortType: 'alphanumeric', // Mixed text and numbers
  },
  {
    Header: 'Created Date',
    accessor: 'createdAt',
    sortType: 'datetime', // Date sorting
  },
  {
    Header: 'Price',
    accessor: 'price',
    sortType: 'number', // Numeric sorting (handles $1,234.56)
  },
  {
    Header: 'Category',
    accessor: 'category',
    sortType: 'string', // Case-insensitive string sort
  },
  {
    Header: 'Rating',
    accessor: 'rating',
    sortType: 'basic', // Simple numeric comparison
  },
  {
    Header: 'SKU',
    accessor: 'sku',
    // Custom sort function
    sortType: (rowA, rowB, columnId) => {
      const a = rowA.values[columnId];
      const b = rowB.values[columnId];
      
      // Extract numeric part from SKU for sorting
      const numA = parseInt(a.replace(/[^0-9]/g, ''), 10);
      const numB = parseInt(b.replace(/[^0-9]/g, ''), 10);
      
      return numA > numB ? 1 : -1;
    },
  },
];

// Sorting with initial state
const table = useTable(
  {
    columns,
    data,
    initialState: {
      sortBy: [
        { id: 'createdAt', desc: true }, // Newest first
        { id: 'name', desc: false }, // Then alphabetical
      ],
    },
  },
  useSortBy
);

Built-in Aggregation Functions

Pre-built aggregation functions for grouped data calculations.

interface AggregationTypes {
  /**
   * Sum all numeric values
   * @param leafValues - Array of values to sum
   * @returns Sum of all values
   */
  sum: (leafValues: any[]) => number;
  
  /**
   * Find minimum value
   * @param leafValues - Array of values
   * @returns Minimum value
   */
  min: (leafValues: any[]) => any;
  
  /**
   * Find maximum value
   * @param leafValues - Array of values
   * @returns Maximum value
   */
  max: (leafValues: any[]) => any;
  
  /**
   * Create min-max range string
   * @param leafValues - Array of values
   * @returns String in format "min - max"
   */
  minMax: (leafValues: any[]) => string;
  
  /**
   * Calculate average of values
   * @param leafValues - Array of numeric values
   * @returns Average value
   */
  average: (leafValues: any[]) => number;
  
  /**
   * Calculate median value
   * @param leafValues - Array of numeric values
   * @returns Median value
   */
  median: (leafValues: any[]) => number;
  
  /**
   * Get array of unique values
   * @param leafValues - Array of values
   * @returns Array of unique values
   */
  unique: (leafValues: any[]) => any[];
  
  /**
   * Count unique values
   * @param leafValues - Array of values
   * @returns Number of unique values
   */
  uniqueCount: (leafValues: any[]) => number;
  
  /**
   * Count all values
   * @param leafValues - Array of values
   * @returns Total count of values
   */
  count: (leafValues: any[]) => number;
}

Usage Examples:

import { useTable, useGroupBy } from 'react-table';

const columns = [
  {
    Header: 'Category',
    accessor: 'category',
  },
  {
    Header: 'Product',
    accessor: 'product',
  },
  {
    Header: 'Sales',
    accessor: 'sales',
    aggregate: 'sum', // Sum all sales in group
    Aggregated: ({ value }) => (
      <span style={{ fontWeight: 'bold' }}>
        Total: ${value.toLocaleString()}
      </span>
    ),
  },
  {
    Header: 'Quantity',
    accessor: 'quantity',
    aggregate: 'sum',
    Aggregated: ({ value }) => `${value} units`,
  },
  {
    Header: 'Price Range',
    accessor: 'price',
    aggregate: 'minMax', // Show price range
    Aggregated: ({ value }) => `$${value}`,
  },
  {
    Header: 'Avg Rating',
    accessor: 'rating',
    aggregate: 'average',
    Aggregated: ({ value }) => (
      <span>{Math.round(value * 10) / 10} ⭐</span>
    ),
  },
  {
    Header: 'Products',
    accessor: 'product',
    aggregate: 'uniqueCount', // Count unique products
    Aggregated: ({ value }) => `${value} products`,
  },
  {
    Header: 'Top Sellers',
    accessor: 'product',
    aggregate: 'unique', // List unique products
    Aggregated: ({ value }) => (
      <ul style={{ margin: 0, paddingLeft: '20px' }}>
        {value.slice(0, 3).map((product, i) => (
          <li key={i}>{product}</li>
        ))}
        {value.length > 3 && <li>+{value.length - 3} more</li>}
      </ul>
    ),
  },
  {
    Header: 'Custom Metric',
    accessor: 'sales',
    // Custom aggregation function
    aggregate: (leafValues, childRows) => {
      const total = leafValues.reduce((sum, val) => sum + val, 0);
      const count = leafValues.length;
      const avg = total / count;
      
      return {
        total,
        average: avg,
        count,
        efficiency: total / count > 1000 ? 'High' : 'Low',
      };
    },
    Aggregated: ({ value }) => (
      <div>
        <div>Total: ${value.total}</div>
        <div>Avg: ${Math.round(value.average)}</div>
        <div>Efficiency: {value.efficiency}</div>
      </div>
    ),
  },
];

// Usage with grouping
function GroupedSalesTable({ data }) {
  const table = useTable(
    {
      columns,
      data,
      initialState: {
        groupBy: ['category'], // Group by category
      },
    },
    useGroupBy
  );
  
  // Implementation...
}

Custom Type Creation

Examples of creating custom filter types, sort types, and aggregation functions.

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

// Custom sort for version numbers (e.g., "1.2.3")
const versionSort = (rowA, rowB, columnId) => {
  const versionA = rowA.values[columnId];
  const versionB = rowB.values[columnId];
  
  const parseVersion = (version) => {
    return version.split('.').map(part => parseInt(part, 10));
  };
  
  const partsA = parseVersion(versionA);
  const partsB = parseVersion(versionB);
  
  for (let i = 0; i < Math.max(partsA.length, partsB.length); i++) {
    const a = partsA[i] || 0;
    const b = partsB[i] || 0;
    
    if (a !== b) {
      return a > b ? 1 : -1;
    }
  }
  
  return 0;
};

// Custom aggregation for weighted average
const weightedAverageAggregator = (leafValues, childRows) => {
  let totalValue = 0;
  let totalWeight = 0;
  
  childRows.forEach((row, index) => {
    const value = leafValues[index];
    const weight = row.original.weight || 1; // Default weight of 1
    
    totalValue += value * weight;
    totalWeight += weight;
  });
  
  return totalWeight > 0 ? totalValue / totalWeight : 0;
};

// Usage of custom types
const customColumns = [
  {
    Header: 'Release Date',
    accessor: 'releaseDate',
    filter: dateRangeFilter,
    Filter: ({ column }) => (
      <DateRangePicker
        startDate={column.filterValue?.[0]}
        endDate={column.filterValue?.[1]}
        onChange={([start, end]) => column.setFilter([start, end])}
      />
    ),
  },
  {
    Header: 'Version',
    accessor: 'version',
    sortType: versionSort,
  },
  {
    Header: 'Score',
    accessor: 'score',
    aggregate: weightedAverageAggregator,
    Aggregated: ({ value }) => `Weighted Avg: ${value.toFixed(2)}`,
  },
];

Types

// Filter function signature
type FilterFunction = (
  rows: Row[],
  columnId: string,
  filterValue: any,
  addMeta?: (meta: any) => void
) => Row[];

// Sort function signature  
type SortFunction = (
  rowA: Row,
  rowB: Row,
  columnId: string,
  desc?: boolean
) => number;

// Aggregation function signature
type AggregationFunction = (
  leafValues: any[],
  childRows: Row[]
) => any;

// Global filter function signature
type GlobalFilterFunction = (
  rows: Row[],
  columnIds: string[],
  filterValue: any,
  addMeta?: (meta: any) => void
) => Row[];

interface Column {
  /** Filter type or custom filter function */
  filter?: string | FilterFunction;
  /** Sort type or custom sort function */
  sortType?: string | SortFunction;
  /** Aggregation type or custom aggregation function */
  aggregate?: string | AggregationFunction;
  /** Whether values should be sorted in descending order first */
  sortDescFirst?: boolean;
  /** Whether to invert the sort direction */
  sortInverted?: boolean;
}

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