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

utilities.mddocs/

Utilities and Helpers

React Table provides a comprehensive set of utility functions, constants, and helper components that support table functionality and enable advanced customizations.

Capabilities

Core Constants and Defaults

Built-in constants and default configurations used throughout React Table.

/** Action type constants registry */
const actions: ActionTypes;

/** Default cell renderer that displays the cell value */
const defaultRenderer: ({ value }: { value: any }) => any;

/** Empty cell renderer that displays non-breaking space */
const emptyRenderer: () => React.ReactElement;

/** Default column configuration object */
const defaultColumn: Column;

Usage Example:

import { actions, defaultRenderer, defaultColumn } from 'react-table';

// Using actions in custom reducers
const customReducer = (state, action) => {
  if (action.type === actions.resetFilters) {
    // Custom reset logic
    return { ...state, customFilters: [] };
  }
  return state;
};

// Using default column config
const columns = [
  {
    Header: 'Name',
    accessor: 'name',
    Cell: defaultRenderer, // Explicit use of default renderer
  },
  {
    Header: 'Actions',
    id: 'actions',
    Cell: () => <button>Edit</button>,
  },
];

// Custom default column configuration
const customDefaultColumn = {
  ...defaultColumn,
  Cell: ({ value }) => value || '-', // Custom default for empty values
  Filter: ({ column: { filterValue, setFilter } }) => (
    <input
      value={filterValue || ''}
      onChange={e => setFilter(e.target.value)}
    />
  ),
};

Rendering Utilities

Flexible rendering utilities for components and dynamic content.

/**
 * Flexible component renderer that handles various component types
 * @param component - Component, element, string, or function to render
 * @param props - Props to pass to the component
 * @returns Rendered React element
 */
function flexRender(
  component: Renderer,
  props: any
): React.ReactElement;

/**
 * Creates a renderer function from a component
 * @param component - Component to wrap
 * @returns Renderer function
 */
function makeRenderer(component: Renderer): Function;

type Renderer = 
  | React.ComponentType<any>
  | React.ReactElement
  | string
  | ((props: any) => React.ReactElement);

Usage Example:

import { flexRender, makeRenderer } from 'react-table';

// Custom cell with dynamic rendering
const DynamicCell = ({ cell }) => {
  const { value, column } = cell;
  
  // Different renderers based on column type
  const renderer = column.cellType === 'button' 
    ? ({ value }) => <button>{value}</button>
    : column.cellType === 'link'
    ? ({ value }) => <a href={value}>{value}</a>
    : ({ value }) => <span>{value}</span>;
  
  return flexRender(renderer, { value });
};

// Using makeRenderer for consistent component wrapping
const StatusRenderer = makeRenderer(({ value }) => {
  const className = `status-${value.toLowerCase()}`;
  return <span className={className}>{value}</span>;
});

const columns = [
  {
    Header: 'Status',
    accessor: 'status',
    Cell: StatusRenderer,
  },
];

Prop Getter Utilities

Utilities for creating and managing prop getter functions.

/**
 * Creates a prop getter function that merges props from hooks and user input
 * @param hooks - Array of hook functions that return props
 * @param meta - Metadata passed to hooks
 * @returns Prop getter function
 */
function makePropGetter(
  hooks: Array<(props: any, meta: any) => any>,
  meta?: any
): PropGetter;

type PropGetter = (userProps?: any) => object;

Usage Example:

import { makePropGetter } from 'react-table';

// Custom prop getter for special row styling
const createRowPropGetter = (hooks, meta) => {
  const baseGetRowProps = makePropGetter(hooks, meta);
  
  return (userProps = {}) => {
    const props = baseGetRowProps(userProps);
    
    // Add custom row styling based on row data
    if (meta.row.original.status === 'error') {
      props.className = `${props.className || ''} error-row`.trim();
      props.style = {
        ...props.style,
        backgroundColor: '#ffebee',
      };
    }
    
    return props;
  };
};

Hook Utilities

Utilities for processing and executing hook functions.

/**
 * Executes reducer-type hooks in sequence
 * @param hooks - Array of reducer hooks
 * @param initial - Initial value
 * @param meta - Metadata passed to hooks
 * @param allowUndefined - Whether to allow undefined return values
 * @returns Final reduced value
 */
function reduceHooks(
  hooks: Array<(prev: any, meta: any) => any>,
  initial: any,
  meta?: any,
  allowUndefined?: boolean
): any;

/**
 * Executes side-effect hooks (hooks that don't return values)
 * @param hooks - Array of side-effect hooks
 * @param context - Context object passed to hooks
 * @param meta - Metadata passed to hooks
 */
function loopHooks(
  hooks: Array<(context: any, meta: any) => void>,
  context: any,
  meta?: any
): void;

/**
 * Ensures plugins are in the correct order based on dependencies
 * @param plugins - Array of plugin functions
 * @param befores - Array of plugin names that must come before
 * @param pluginName - Name of the current plugin
 */
function ensurePluginOrder(
  plugins: PluginHook[],
  befores: string[],
  pluginName: string
): void;

Usage Example:

import { reduceHooks, loopHooks, ensurePluginOrder } from 'react-table';

// Custom plugin that depends on other plugins
function useCustomPlugin(hooks) {
  // Ensure this plugin comes after useSortBy
  ensurePluginOrder(hooks.plugins, ['useSortBy'], 'useCustomPlugin');
  
  hooks.useInstance.push((instance) => {
    // Add custom instance methods
    Object.assign(instance, {
      customMethod: () => {
        console.log('Custom method called');
      },
    });
  });
  
  hooks.stateReducers.push((newState, action, previousState, instance) => {
    if (action.type === 'customAction') {
      return {
        ...newState,
        customState: action.payload,
      };
    }
    return newState;
  });
}

useCustomPlugin.pluginName = 'useCustomPlugin';

React Hook Utilities

Specialized React hooks for table functionality.

/**
 * Gets the latest value reference to prevent stale closures
 * @param obj - Object to get latest reference for
 * @returns Function that returns the latest value
 */
function useGetLatest<T>(obj: T): () => T;

/**
 * Cross-platform layout effect (useLayoutEffect in browser, useEffect in SSR)
 */
const safeUseLayoutEffect: typeof React.useLayoutEffect;

/**
 * Layout effect that only runs when component is mounted
 * @param effect - Effect function
 * @param deps - Dependency array
 */
function useMountedLayoutEffect(
  effect: React.EffectCallback,
  deps?: React.DependencyList
): void;

/**
 * Creates an async debounced function
 * @param fn - Function to debounce
 * @param wait - Debounce delay in milliseconds
 * @returns Debounced function
 */
function useAsyncDebounce<T extends (...args: any[]) => any>(
  fn: T,
  wait: number
): T;

Usage Example:

import {
  useGetLatest,
  useMountedLayoutEffect,
  useAsyncDebounce,
} from 'react-table';

function CustomTableComponent({ data, onDataChange }) {
  const [localData, setLocalData] = React.useState(data);
  
  // Prevent stale closure issues
  const getLatestData = useGetLatest(localData);
  
  // Debounced save function
  const debouncedSave = useAsyncDebounce(async (newData) => {
    await onDataChange(newData);
  }, 1000);
  
  // Effect that only runs when mounted
  useMountedLayoutEffect(() => {
    const currentData = getLatestData();
    if (currentData !== data) {
      debouncedSave(currentData);
    }
  }, [localData]);
  
  return (
    <div>
      {/* Table implementation */}
    </div>
  );
}

State Update Utilities

Utilities for handling state updates and functional updates.

/**
 * Handles functional updates (updater functions or direct values)
 * @param updater - Update function or direct value
 * @param old - Previous value
 * @returns New value
 */
function functionalUpdate<T>(
  updater: T | ((old: T) => T),
  old: T
): T;

Usage Example:

import { functionalUpdate } from 'react-table';

// Custom state management with functional updates
function useCustomTableState(initialState) {
  const [state, setState] = React.useState(initialState);
  
  const updateState = React.useCallback((updater) => {
    setState(prevState => functionalUpdate(updater, prevState));
  }, []);
  
  return [state, updateState];
}

// Usage
function MyTable() {
  const [tableState, setTableState] = useCustomTableState({
    filters: [],
    sortBy: [],
  });
  
  // Direct value update
  const clearFilters = () => {
    setTableState({ ...tableState, filters: [] });
  };
  
  // Functional update
  const addFilter = (filter) => {
    setTableState(prevState => ({
      ...prevState,
      filters: [...prevState.filters, filter],
    }));
  };
  
  return (
    <div>
      {/* Table implementation */}
    </div>
  );
}

Aggregation Functions

Built-in aggregation functions for grouped data.

interface AggregationFunctions {
  /** Sum of numeric values */
  sum: (leafValues: any[]) => number;
  /** Minimum value */
  min: (leafValues: any[]) => any;
  /** Maximum value */
  max: (leafValues: any[]) => any;
  /** Min-max range as string */
  minMax: (leafValues: any[]) => string;
  /** Average of values */
  average: (leafValues: any[]) => number;
  /** Median value */
  median: (leafValues: any[]) => number;
  /** Array of unique values */
  unique: (leafValues: any[]) => any[];
  /** Count of unique values */
  uniqueCount: (leafValues: any[]) => number;
  /** Total count */
  count: (leafValues: any[]) => number;
}

Usage Example:

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

function GroupedTable({ columns, data }) {
  const aggregationColumns = React.useMemo(() => [
    ...columns,
    {
      Header: 'Summary',
      columns: [
        {
          Header: 'Total Sales',
          accessor: 'sales',
          aggregate: 'sum',
          Aggregated: ({ value }) => `$${value.toLocaleString()}`,
        },
        {
          Header: 'Avg Rating',
          accessor: 'rating',
          aggregate: 'average',
          Aggregated: ({ value }) => Math.round(value * 100) / 100,
        },
        {
          Header: 'Count',
          accessor: 'id',
          aggregate: 'count',
          Aggregated: ({ value }) => `${value} items`,
        },
      ],
    },
  ], [columns]);
  
  const tableInstance = useTable(
    {
      columns: aggregationColumns,
      data,
    },
    useGroupBy
  );
  
  // Table implementation...
}

Custom Utility Creation

Patterns for creating custom utilities that integrate with React Table.

// Custom utility for table data export
function createExportUtility(tableInstance) {
  const exportToCSV = () => {
    const { flatHeaders, rows } = tableInstance;
    
    // Create CSV header
    const header = flatHeaders
      .filter(header => header.isVisible)
      .map(header => header.Header)
      .join(',');
    
    // Create CSV rows
    const csvRows = rows.map(row => {
      return flatHeaders
        .filter(header => header.isVisible)
        .map(header => {
          const cell = row.cells.find(cell => cell.column.id === header.id);
          return JSON.stringify(cell?.value || '');
        })
        .join(',');
    });
    
    // Combine and download
    const csvContent = [header, ...csvRows].join('\n');
    const blob = new Blob([csvContent], { type: 'text/csv' });
    const url = URL.createObjectURL(blob);
    
    const link = document.createElement('a');
    link.href = url;
    link.download = 'table-data.csv';
    link.click();
    
    URL.revokeObjectURL(url);
  };
  
  return { exportToCSV };
}

// Usage
function ExportableTable({ columns, data }) {
  const tableInstance = useTable({ columns, data });
  const { exportToCSV } = createExportUtility(tableInstance);
  
  return (
    <div>
      <button onClick={exportToCSV}>
        Export to CSV
      </button>
      {/* Table implementation */}
    </div>
  );
}

Types

interface ActionTypes {
  init: string;
  resetFilters: string;
  setFilter: string;
  setAllFilters: string;
  resetSortBy: string;
  setSortBy: string;
  toggleSortBy: string;
  resetGlobalFilter: string;
  setGlobalFilter: string;
  resetPage: string;
  gotoPage: string;
  setPageSize: string;
  toggleAllRowsSelected: string;
  toggleRowSelected: string;
  toggleAllRowsExpanded: string;
  toggleRowExpanded: string;
  setColumnOrder: string;
  resetSelectedRows: string;
  resetExpanded: string;
  resetGroupBy: string;
  setGroupBy: string;
  toggleGroupBy: string;
  resetRowState: string;
  setCellState: string;
  resetPivot: string;
  togglePivot: string;
}

interface UtilityMeta {
  instance: TableInstance;
  column?: Column;
  row?: Row;
  cell?: Cell;
}

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