CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-react-data-grid

Excel-like grid component built with React, with editors, keyboard navigation, copy & paste, and the like

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

utilities.mddocs/

Utilities and Constants

Helper constants, utilities, and configuration options for advanced grid customization and performance optimization.

Capabilities

Constants Collection

Built-in constants for configuring grid behavior and handling grid events.

const _constants = {
  /** Cell navigation modes */
  CellNavigationMode: {
    NONE: 'none';
    CHANGE_ROW: 'changeRow';
    LOOP_OVER_ROW: 'loopOverRow';
  };
  
  /** Grid update action types */
  UpdateActions: {
    CELL_UPDATE: 'CELL_UPDATE';
    COLUMN_FILL: 'COLUMN_FILL';
    COPY_PASTE: 'COPY_PASTE';
    CELL_DRAG: 'CELL_DRAG';
  };
  
  /** Event type constants */
  EventTypes: {
    SELECT_CELL: 'SELECT_CELL';
    SELECT_START: 'SELECT_START';
    SELECT_UPDATE: 'SELECT_UPDATE';
    SELECT_END: 'SELECT_END';
    DRAG_ENTER: 'DRAG_ENTER';
    SCROLL_TO_COLUMN: 'SCROLL_TO_COLUMN';
  };
  
  /** Header row type constants */
  HeaderRowType: {
    HEADER: 'header';
    FILTER: 'filter';
  };
  
  /** Cell expansion icons */
  CellExpand: {
    DOWN_TRIANGLE: '▼';
    RIGHT_TRIANGLE: '▶';
  };
  
  /** Drag and drop item types */
  DragItemTypes: {
    Column: 'column';
  };
};

CellNavigationMode

Constants for configuring cell navigation behavior.

/**
 * Cell navigation mode constants
 * Controls how keyboard navigation behaves between cells
 */
const CellNavigationMode = {
  /** No automatic navigation between cells */
  NONE: 'none';
  /** Tab key loops within the current row */
  LOOP_OVER_ROW: 'loopOverRow';
  /** Tab key moves to next/previous row when reaching row end */
  CHANGE_ROW: 'changeRow';
};

Usage Example:

import ReactDataGrid, { _constants } from 'react-data-grid';

const NavigationGrid = () => {
  return (
    <ReactDataGrid
      columns={columns}
      rowGetter={i => rows[i]}
      rowsCount={rows.length}
      minHeight={400}
      enableCellSelect={true}
      cellNavigationMode={_constants.CellNavigationMode.CHANGE_ROW}
    />
  );
};

UpdateActions

Constants identifying different types of grid data updates.

/**
 * Update action type constants
 * Used in onGridRowsUpdated events to identify update source
 */
const UpdateActions = {
  /** Single cell edit via editor */
  CELL_UPDATE: 'CELL_UPDATE';
  /** Multiple cells updated via column fill/drag down */
  COLUMN_FILL: 'COLUMN_FILL';
  /** Cells updated via copy/paste operation */
  COPY_PASTE: 'COPY_PASTE';
  /** Cells updated via drag and drop */
  CELL_DRAG: 'CELL_DRAG';
};

Usage Example:

import ReactDataGrid, { _constants } from 'react-data-grid';

const UpdateHandlingGrid = () => {
  const handleGridRowsUpdated = ({ fromRow, toRow, updated, action }) => {
    console.log('Update action:', action);
    
    switch (action) {
      case _constants.UpdateActions.CELL_UPDATE:
        console.log('Single cell updated');
        break;
      case _constants.UpdateActions.COLUMN_FILL:
        console.log('Column fill operation');
        break;
      case _constants.UpdateActions.COPY_PASTE:
        console.log('Copy/paste operation');
        break;
      case _constants.UpdateActions.CELL_DRAG:
        console.log('Drag operation');
        break;
    }
    
    // Handle the update
    updateRows(fromRow, toRow, updated);
  };
  
  return (
    <ReactDataGrid
      columns={columns}
      rowGetter={i => rows[i]}
      rowsCount={rows.length}
      minHeight={400}
      enableCellSelect={true}
      onGridRowsUpdated={handleGridRowsUpdated}
    />
  );
};

EventTypes

Constants for internal grid event types.

/**
 * Grid event type constants
 * Used internally for grid event system
 */
const EventTypes = {
  /** Cell selection event */
  SELECT_CELL: 'SELECT_CELL';
  /** Selection range start event */
  SELECT_START: 'SELECT_START';
  /** Selection range update event */
  SELECT_UPDATE: 'SELECT_UPDATE';
  /** Selection range end event */
  SELECT_END: 'SELECT_END';
  /** Drag enter event */
  DRAG_ENTER: 'DRAG_ENTER';
  /** Scroll to column event */
  SCROLL_TO_COLUMN: 'SCROLL_TO_COLUMN';
};

Row Comparison Utility

Performance optimization utility for determining when rows should re-render.

/**
 * Row comparison utility for performance optimization
 * Determines whether a row component should update based on prop changes
 * @param nextProps - New props for the row
 * @param currentProps - Current props for the row  
 * @returns boolean indicating whether the row should update
 */
const RowComparer: (nextProps: any, currentProps: any) => boolean;

Usage Example:

import React, { memo } from 'react';
import ReactDataGrid, { RowComparer } from 'react-data-grid';

// Optimized row component using RowComparer
const OptimizedRow = memo((props) => {
  return <Row {...props} />;
}, RowComparer);

const PerformanceOptimizedGrid = () => {
  return (
    <ReactDataGrid
      columns={columns}
      rowGetter={i => rows[i]}
      rowsCount={rows.length}
      minHeight={400}
      rowComponent={OptimizedRow}
    />
  );
};

Helper Utilities

Test utilities and helper functions for grid development and testing.

const _helpers = {
  /** Test utilities for grid components */
  test: {
    /** Helper utilities for creating grid props in tests */
    GridPropHelpers: {
      /** Create basic column definitions for testing */
      createColumns: (count: number) => Column[];
      /** Create basic row data for testing */
      createRows: (count: number, columns: Column[]) => any[];
      /** Create minimal grid props for testing */
      createGridProps: (overrides?: Partial<ReactDataGridProps>) => ReactDataGridProps;
    };
  };
};

Testing Example:

import { _helpers } from 'react-data-grid';
import { render } from '@testing-library/react';

const { GridPropHelpers } = _helpers.test;

describe('Grid Tests', () => {
  test('renders basic grid', () => {
    const columns = GridPropHelpers.createColumns(3);
    const rows = GridPropHelpers.createRows(10, columns);
    const props = GridPropHelpers.createGridProps({
      columns,
      rowGetter: i => rows[i],
      rowsCount: rows.length
    });
    
    const { container } = render(<ReactDataGrid {...props} />);
    expect(container).toBeInTheDocument();
  });
});

Column and Shape Utilities

PropTypes shapes and validation helpers for column definitions.

const shapes = {
  /** PropTypes shape for column definitions */
  Column: PropTypes.shape({
    key: PropTypes.string.isRequired,
    name: PropTypes.node.isRequired,
    width: PropTypes.number,
    resizable: PropTypes.bool,
    sortable: PropTypes.bool,
    filterable: PropTypes.bool,
    editable: PropTypes.bool,
    formatter: PropTypes.node,
    editor: PropTypes.node,
    headerRenderer: PropTypes.node,
    frozen: PropTypes.bool,
    events: PropTypes.object
  });
};

Utility Functions

Additional utility functions for common grid operations.

/**
 * Utility functions for grid operations
 */
interface GridUtils {
  /** Calculate column widths based on content */
  calculateColumnWidths: (columns: Column[], rows: any[]) => Column[];
  
  /** Sort rows by column */
  sortRows: (rows: any[], sortColumn: string, sortDirection: SortDirection) => any[];
  
  /** Filter rows based on filter criteria */
  filterRows: (rows: any[], filters: Filter[]) => any[];
  
  /** Export grid data to CSV */
  exportToCSV: (columns: Column[], rows: any[], filename?: string) => void;
  
  /** Import CSV data to grid format */
  importFromCSV: (csvData: string, columns: Column[]) => any[];
}

Utility Usage Examples:

import ReactDataGrid, { _constants } from 'react-data-grid';

// Advanced grid with multiple utilities
const AdvancedUtilityGrid = () => {
  const [rows, setRows] = useState(initialRows);
  const [sortColumn, setSortColumn] = useState('');
  const [sortDirection, setSortDirection] = useState('NONE');
  const [filters, setFilters] = useState([]);
  
  // Custom sort implementation
  const handleGridSort = (columnKey, direction) => {
    setSortColumn(columnKey);
    setSortDirection(direction);
    
    const sortedRows = [...rows].sort((a, b) => {
      const aValue = a[columnKey];
      const bValue = b[columnKey];
      
      if (direction === 'ASC') {
        return aValue < bValue ? -1 : aValue > bValue ? 1 : 0;
      } else {
        return aValue > bValue ? -1 : aValue < bValue ? 1 : 0;
      }
    });
    
    setRows(sortedRows);
  };
  
  // Export functionality
  const exportData = () => {
    const csv = convertToCSV(columns, rows);
    downloadCSV(csv, 'grid-data.csv');
  };
  
  // Filter functionality
  const handleFilter = (filter) => {
    const newFilters = [...filters, filter];
    setFilters(newFilters);
    
    const filteredRows = initialRows.filter(row => {
      return newFilters.every(f => {
        const cellValue = String(row[f.columnKey]).toLowerCase();
        const filterTerm = f.filterTerm.toLowerCase();
        return cellValue.includes(filterTerm);
      });
    });
    
    setRows(filteredRows);
  };
  
  return (
    <div>
      <div style={{ marginBottom: '10px' }}>
        <button onClick={exportData}>Export to CSV</button>
        <span style={{ marginLeft: '20px' }}>
          Showing {rows.length} of {initialRows.length} rows
        </span>
      </div>
      
      <ReactDataGrid
        columns={columns}
        rowGetter={i => rows[i]}
        rowsCount={rows.length}
        minHeight={400}
        enableCellSelect={true}
        cellNavigationMode={_constants.CellNavigationMode.CHANGE_ROW}
        sortColumn={sortColumn}
        sortDirection={sortDirection}
        onGridSort={handleGridSort}
        onFilter={handleFilter}
        onGridRowsUpdated={({ action, ...args }) => {
          console.log('Update action:', action);
          if (action === _constants.UpdateActions.COPY_PASTE) {
            console.log('Paste operation detected');
          }
          handleRowUpdate(args);
        }}
      />
    </div>
  );
};

// Helper functions
const convertToCSV = (columns, rows) => {
  const headers = columns.map(col => col.name).join(',');
  const csvRows = rows.map(row => 
    columns.map(col => JSON.stringify(row[col.key] || '')).join(',')
  );
  return [headers, ...csvRows].join('\n');
};

const downloadCSV = (csv, filename) => {
  const blob = new Blob([csv], { type: 'text/csv' });
  const url = window.URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = filename;
  a.click();
  window.URL.revokeObjectURL(url);
};

Performance Optimization Utilities

Utilities and patterns for optimizing grid performance with large datasets.

// Virtual scrolling configuration
const largeDatasetGrid = {
  // Overscan configuration for virtual scrolling
  overScan: {
    colsStart: 2,    // Columns to render before viewport
    colsEnd: 2,      // Columns to render after viewport  
    rowsStart: 5,    // Rows to render before viewport
    rowsEnd: 5       // Rows to render after viewport
  }
};

// Memory-efficient row getter
const memoizedRowGetter = useMemo(() => {
  const cache = new Map();
  return (index) => {
    if (!cache.has(index)) {
      cache.set(index, processRowData(rawData[index]));
    }
    return cache.get(index);
  };
}, [rawData]);

// Optimized column definitions
const optimizedColumns = useMemo(() => 
  columns.map(col => ({
    ...col,
    formatter: col.formatter ? memo(col.formatter) : undefined
  })), 
  [columns]
);

Configuration Presets

Common configuration presets for different use cases.

// Preset configurations
const GridPresets = {
  // Basic read-only grid
  ReadOnly: {
    enableCellSelect: false,
    cellNavigationMode: _constants.CellNavigationMode.NONE
  },
  
  // Excel-like editing grid
  ExcelLike: {
    enableCellSelect: true,
    cellNavigationMode: _constants.CellNavigationMode.CHANGE_ROW,
    enableCellAutoFocus: true
  },
  
  // Selection-focused grid
  Selection: {
    enableCellSelect: true,
    rowSelection: {
      showCheckbox: true,
      enableShiftSelect: true
    }
  },
  
  // Performance-optimized for large datasets
  HighPerformance: {
    enableCellAutoFocus: false,
    overScan: { colsStart: 1, colsEnd: 1, rowsStart: 2, rowsEnd: 2 }
  }
};

Install with Tessl CLI

npx tessl i tessl/npm-react-data-grid

docs

components.md

core-grid.md

editors.md

formatters.md

index.md

selection.md

utilities.md

tile.json