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

editors.mddocs/

Editors and Editing

Cell editing functionality providing built-in editors and infrastructure for custom cell editing components with keyboard navigation support.

Capabilities

Built-in Editors

Pre-built editor components for common cell editing scenarios.

const editors = {
  /** Simple text input editor for string values */
  SimpleTextEditor: React.ComponentType<EditorProps>;
  /** Checkbox editor for boolean values */
  CheckboxEditor: React.ComponentType<EditorProps>;
  /** Base class for creating custom editors */
  EditorBase: React.ComponentType<EditorProps>;
};

interface EditorProps {
  /** Current cell value to edit */
  value: any;
  /** Function to handle key down events */
  onKeyDown: (event: KeyboardEvent) => void;
  /** Function called when editor loses focus */
  onBlur: () => void;
  /** Function to commit the edited value */
  commit: () => void;
  /** Column definition for the cell being edited */
  column: Column;
  /** Complete row data object */
  row?: any;
  /** DOM element where editor should be rendered */
  editorPortalTarget?: Element;
}

SimpleTextEditor

Basic text input editor for editing string values with Enter/Escape key support.

/**
 * Simple text input editor for string cell values
 * Commits on Enter key, cancels on Escape key
 */
const SimpleTextEditor: React.ComponentType<EditorProps>;

Usage Example:

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

const columns = [
  { key: 'id', name: 'ID' },
  { 
    key: 'name', 
    name: 'Name', 
    editor: <editors.SimpleTextEditor />,
    editable: true 
  },
  { 
    key: 'description', 
    name: 'Description', 
    editor: <editors.SimpleTextEditor />,
    editable: true 
  }
];

// The editor will automatically be used when editable: true is set
<ReactDataGrid
  columns={columns}
  rowGetter={i => rows[i]}
  rowsCount={rows.length}
  minHeight={400}
  enableCellSelect={true}
  onGridRowsUpdated={handleRowUpdate}
/>

CheckboxEditor

Checkbox editor for boolean values with immediate commit on click.

/**
 * Checkbox editor for boolean cell values
 * Commits immediately when checkbox state changes
 */
const CheckboxEditor: React.ComponentType<EditorProps>;

Usage Example:

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

const columns = [
  { key: 'id', name: 'ID' },
  { key: 'name', name: 'Name' },
  { 
    key: 'active', 
    name: 'Active', 
    editor: <editors.CheckboxEditor />,
    editable: true 
  },
  { 
    key: 'verified', 
    name: 'Verified', 
    editor: <editors.CheckboxEditor />,
    editable: true 
  }
];

EditorBase

Base class providing common editor functionality for creating custom editors.

/**
 * Base class for custom cell editors
 * Provides common editor lifecycle and keyboard handling
 */
class EditorBase extends React.Component<EditorProps> {
  /** Get the current input value */
  getValue(): any;
  /** Get the input node for focus management */
  getInputNode(): HTMLElement;
  /** Check if the current value is valid */
  isSelectAllWhenEditingEnabled(): boolean;
  /** Handle keyboard events (Enter, Escape, Tab) */
  onKeyDown(event: KeyboardEvent): void;
}

Custom Editor Creation

Creating custom editors by extending EditorBase or implementing the EditorProps interface.

/**
 * Interface for custom editor components
 * Must implement these methods for proper grid integration
 */
interface CustomEditor extends React.Component<EditorProps> {
  /** Return the current editor value */
  getValue(): any;
  /** Return the DOM node to focus */
  getInputNode(): HTMLElement;
  /** Handle special key combinations */
  onKeyDown?(event: KeyboardEvent): void;
}

Custom Editor Example:

import React from 'react';
import { editors } from 'react-data-grid';

// Custom dropdown editor
class DropdownEditor extends editors.EditorBase {
  constructor(props) {
    super(props);
    this.state = { value: props.value };
  }
  
  getValue() {
    return this.state.value;
  }
  
  getInputNode() {
    return this.select;
  }
  
  render() {
    const options = this.props.column.options || [];
    
    return (
      <select
        ref={node => this.select = node}
        value={this.state.value}
        onChange={e => this.setState({ value: e.target.value })}
        onBlur={() => this.props.onCommit(this.state.value)}
        autoFocus
      >
        {options.map(option => (
          <option key={option.value} value={option.value}>
            {option.label}
          </option>
        ))}
      </select>
    );
  }
}

// Usage in column definition
const columns = [
  { key: 'id', name: 'ID' },
  { key: 'name', name: 'Name' },
  { 
    key: 'status', 
    name: 'Status',
    editor: <DropdownEditor />,
    editable: true,
    options: [
      { value: 'active', label: 'Active' },
      { value: 'inactive', label: 'Inactive' },
      { value: 'pending', label: 'Pending' }
    ]
  }
];

Editor Configuration

Column-level configuration for enabling and customizing cell editing.

interface EditableColumn extends Column {
  /** Enable editing for this column */
  editable: boolean;
  /** Custom editor component (optional, defaults to SimpleTextEditor) */
  editor?: React.ComponentType<EditorProps>;
  /** Additional options passed to custom editors */
  [key: string]: any;
}

Grid Editing Events

Events related to cell editing lifecycle and data updates.

interface EditingEvents {
  /** Called when cell editing results in data updates */
  onGridRowsUpdated?: (event: GridRowsUpdatedEvent) => void;
  /** Called before a cell becomes editable */
  onCheckCellIsEditable?: (event: CheckCellEditableEvent) => boolean;
  /** Called just before editing begins */
  onBeforeEdit?: (event: BeforeEditEvent) => void;
}

interface GridRowsUpdatedEvent {
  /** Starting row index for the update */
  fromRow: number;
  /** Ending row index for the update */
  toRow: number;
  /** Object containing the updated values */
  updated: { [columnKey: string]: any };
  /** Type of update action that occurred */
  action: 'CELL_UPDATE' | 'COLUMN_FILL' | 'COPY_PASTE' | 'CELL_DRAG';
}

interface CheckCellEditableEvent {
  /** Row data object */
  row: any;
  /** Column being edited */
  column: Column;
  /** Row index */
  rowIdx: number;
}

interface BeforeEditEvent {
  /** Row index being edited */
  rowIdx: number;
  /** Column being edited */
  column: Column;
  /** Row data object */
  row: any;
}

Advanced Editing Example:

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

const EditableGrid = () => {
  const [rows, setRows] = useState(initialData);
  
  const handleGridRowsUpdated = ({ fromRow, toRow, updated, action }) => {
    console.log('Update action:', action);
    
    const newRows = rows.slice();
    for (let i = fromRow; i <= toRow; i++) {
      newRows[i] = { ...newRows[i], ...updated };
    }
    setRows(newRows);
  };
  
  const checkCellEditable = ({ row, column, rowIdx }) => {
    // Only allow editing if row is not locked
    return !row.locked;
  };
  
  const beforeEdit = ({ rowIdx, column, row }) => {
    console.log(`Starting to edit ${column.key} in row ${rowIdx}`);
  };
  
  const columns = [
    { key: 'id', name: 'ID' },
    { 
      key: 'name', 
      name: 'Name', 
      editable: true,
      editor: <editors.SimpleTextEditor />
    },
    { 
      key: 'active', 
      name: 'Active', 
      editable: true,
      editor: <editors.CheckboxEditor />
    },
    { 
      key: 'category', 
      name: 'Category', 
      editable: true,
      editor: <CustomDropdownEditor />
    }
  ];
  
  return (
    <ReactDataGrid
      columns={columns}
      rowGetter={i => rows[i]}
      rowsCount={rows.length}
      minHeight={500}
      enableCellSelect={true}
      onGridRowsUpdated={handleGridRowsUpdated}
      onCheckCellIsEditable={checkCellEditable}
      onBeforeEdit={beforeEdit}
    />
  );
};

Keyboard Navigation

Built-in keyboard shortcuts for editing and navigation.

  • Enter: Start editing selected cell or commit current edit
  • Escape: Cancel current edit and revert to original value
  • Tab: Commit edit and move to next editable cell
  • Shift+Tab: Commit edit and move to previous editable cell
  • Arrow Keys: Navigate between cells (when not editing)

Editor Portal

Editors are rendered in DOM portals to avoid z-index and overflow issues.

interface EditorPortalConfig {
  /** DOM element where editor portals should be mounted */
  editorPortalTarget?: Element;
}

Usage Example:

// Custom portal target
const customPortalTarget = document.getElementById('editor-container');

<ReactDataGrid
  columns={columns}
  rowGetter={i => rows[i]}
  rowsCount={rows.length}
  minHeight={400}
  editorPortalTarget={customPortalTarget}
/>

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