@piyushnagar/react-editable-table
v1.0.13
Published
A comprehensive, feature-rich React table component with inline editing, sorting, filtering, column resizing, and more
Maintainers
Readme
React Editable Table
A comprehensive, feature-rich React table component with inline editing, sorting, filtering, column resizing, drag-and-drop row reordering, and much more.
Features
- ✅ Inline Editing - Edit cells directly with support for multiple data types
- ✅ Column Types - Text, Number, Integer, Date, Select, Multi-Select, Boolean, File Upload
- ✅ File Upload - Upload and manage multiple files including images and videos with preview
- ✅ Sorting & Filtering - Advanced column-based filtering with search
- ✅ Column Resizing - Drag to resize columns with minimum width constraints
- ✅ Row Management - Add, delete, and reorder rows with drag-and-drop
- ✅ Keyboard Navigation - Full keyboard support with arrow keys, Tab, Enter
- ✅ Copy/Paste - Excel-like copy/paste functionality with clipboard support
- ✅ Context Menus - Right-click menus for cells and rows
- ✅ Pagination - Built-in pagination with configurable page sizes
- ✅ CSV Export - Export table data to CSV format
- ✅ TypeScript - Full TypeScript support with comprehensive type definitions
- ✅ Responsive - Mobile-friendly design with horizontal scrolling
- ✅ Customizable - Extensive configuration options and styling
Installation
npm install @your-org/react-editable-tableQuick Start
import React, { useState } from 'react';
import { EditableTable, TableColumn, TableRow } from '@your-org/react-editable-table';
import '@your-org/react-editable-table/styles';
const columns: TableColumn[] = [
{
id: 'name',
title: 'Name',
type: 'text',
width: 200,
sortable: true,
editable: true,
required: true,
},
{
id: 'email',
title: 'Email',
type: 'text',
width: 250,
sortable: true,
editable: true,
},
{
id: 'age',
title: 'Age',
type: 'integer',
width: 100,
sortable: true,
editable: true,
},
{
id: 'department',
title: 'Department',
type: 'select',
options: ['Engineering', 'Marketing', 'Sales', 'HR'],
width: 150,
sortable: true,
editable: true,
},
{
id: 'active',
title: 'Active',
type: 'boolean',
width: 100,
sortable: true,
editable: true,
},
];
const initialData: TableRow[] = [
{
id: '1',
name: 'John Doe',
email: '[email protected]',
age: 30,
department: 'Engineering',
active: true,
},
// ... more data
];
function App() {
const [data, setData] = useState<TableRow[]>(initialData);
const [tableColumns, setTableColumns] = useState<TableColumn[]>(columns);
return (
<EditableTable
columns={tableColumns}
data={data}
sortable={true}
filterable={true}
addRows={true}
deleteRows={true}
pagination={{ enabled: true, pageSize: 10 }}
onDataChange={setData}
onColumnChange={setTableColumns}
/>
);
}Column Types
Text
{
id: 'name',
title: 'Name',
type: 'text',
width: 200,
editable: true,
required: true,
}Number & Integer
{
id: 'salary',
title: 'Salary',
type: 'number', // Supports decimals
width: 120,
editable: true,
}
{
id: 'age',
title: 'Age',
type: 'integer', // Whole numbers only
width: 80,
editable: true,
}Date
{
id: 'startDate',
title: 'Start Date',
type: 'date',
width: 140,
editable: true,
}Select (Dropdown)
{
id: 'department',
title: 'Department',
type: 'select',
options: ['Engineering', 'Marketing', 'Sales', 'HR'],
width: 150,
editable: true,
}Multi-Select
{
id: 'skills',
title: 'Skills',
type: 'multiselect',
options: ['JavaScript', 'Python', 'React', 'Node.js'],
width: 200,
editable: true,
multiple: true,
}Boolean
{
id: 'active',
title: 'Active',
type: 'boolean',
width: 100,
editable: true,
}File Upload
{
id: 'media',
title: 'Media Files',
type: 'file',
width: 250,
editable: true,
acceptedFileTypes: ['.jpg', '.png', '.mp4', '.mov', '.webm'], // Images and videos
maxFileSize: 100 * 1024 * 1024, // 100MB total limit (not per file)
maxFiles: 3,
}
// File data structure
interface FileData {
id: string;
name: string;
size: number;
type: string;
url?: string; // For display/download
file?: File; // Actual File object for upload
lastModified?: number;
}Video File Support
The file upload component now supports video files with:
- Video Preview: Inline video player with controls during editing
- Video Formats: MP4, AVI, MOV, WMV, WebM, MKV, and more
- Visual Indicators: Different colored badges for videos (red), images (green), and documents (purple)
- Size Management: Configurable file size limits (recommended 10MB+ for videos)
// Example: Video-specific configuration
{
id: 'videos',
title: 'Training Videos',
type: 'file',
width: 300,
editable: true,
acceptedFileTypes: ['.mp4', '.webm', '.mov'], // Video only
maxFileSize: 100 * 1024 * 1024, // 100MB total limit
maxFiles: 2,
}
// Access video files in callbacks
const handleCellUpdate = (rowId, columnId, oldValue, newValue) => {
if (column.type === 'file' && Array.isArray(newValue)) {
newValue.forEach(fileData => {
if (fileData.file) {
// Check if it's a video file
if (fileData.type.startsWith('video/')) {
console.log('Video file uploaded:', fileData.name);
uploadVideoToServer(fileData.file);
} else {
uploadFileToServer(fileData.file);
}
}
});
}
};Configuration Options
Table Configuration
interface TableConfig {
columns: TableColumn[];
data: TableRow[];
sortable?: boolean; // Enable sorting (default: true)
filterable?: boolean; // Enable filtering (default: true)
addRows?: boolean; // Allow adding rows (default: true)
deleteRows?: boolean; // Allow deleting rows (default: true)
addColumns?: boolean; // Allow adding columns (default: false)
deleteColumns?: boolean; // Allow deleting columns (default: false)
pagination?: {
enabled: boolean;
pageSize?: number; // Items per page (default: 10)
};
onDataChange?: (data: TableRow[]) => void;
onColumnChange?: (columns: TableColumn[]) => void;
// Row-wise callback methods
onRowAdd?: (newRow: TableRow, insertIndex?: number) => void;
onRowUpdate?: (updatedRow: TableRow, rowIndex: number, changes: Partial<TableRow>) => void;
onRowDelete?: (deletedRow: TableRow, rowIndex: number) => void;
onRowsDelete?: (deletedRows: TableRow[], rowIndices: number[]) => void;
onRowMove?: (movedRow: TableRow, fromIndex: number, toIndex: number) => void;
onRowSelect?: (selectedRows: TableRow[], selectedIndices: number[]) => void;
onRowCopy?: (copiedRows: TableRow[], rowIndices: number[]) => void;
onRowCut?: (cutRows: TableRow[], rowIndices: number[]) => void;
onRowPaste?: (pastedRows: TableRow[], targetIndex: number) => void;
// Cell-wise callback methods
onCellUpdate?: (rowId: string, columnId: string, oldValue: any, newValue: any, rowIndex: number, columnIndex: number) => void;
onCellSelect?: (rowId: string, columnId: string, value: any, position: CellPosition) => void;
onCellEdit?: (rowId: string, columnId: string, value: any, position: CellPosition) => void;
// Validation callbacks
onValidationError?: (errors: ValidationError[]) => void;
validateRow?: (row: TableRow, rowIndex: number) => ValidationError[];
validateCell?: (value: any, column: TableColumn, row: TableRow) => string | null;
}Column Configuration
interface TableColumn {
id: string; // Unique identifier
title: string; // Display name
type: 'text' | 'number' | 'integer' | 'date' | 'select' | 'multiselect' | 'boolean';
width?: number; // Column width in pixels
required?: boolean; // Required field validation
options?: string[]; // Options for select/multiselect
sortable?: boolean; // Enable sorting for this column
editable?: boolean; // Enable editing for this column
multiple?: boolean; // For multiselect type
acceptedFileTypes?: string[]; // For file type - e.g., ['.pdf', '.jpg']
maxFileSize?: number; // For file type - in bytes
maxFiles?: number; // For file type - maximum number of files
}Keyboard Shortcuts
- Arrow Keys - Navigate between cells
- Tab / Shift+Tab - Navigate to next/previous cell
- Enter - Start editing selected cell
- Escape - Cancel editing
- Delete / Backspace - Clear cell content
- Ctrl+C - Copy selected cells
- Ctrl+V - Paste clipboard content
- Ctrl+X - Cut selected cells
Advanced Usage
Custom Data Validation
import { validateRowData } from '@your-org/react-editable-table';
const errors = validateRowData(rowData, columns);
if (errors.length > 0) {
console.log('Validation errors:', errors);
}Sample Data Generation
import { createSampleData } from '@your-org/react-editable-table';
const sampleData = createSampleData(columns, 100); // Generate 100 sample rowsUsing Hooks Directly
import { useClipboard, useColumnFilters } from '@your-org/react-editable-table';
// Use individual hooks for custom implementations
const { copyToClipboard, pasteFromClipboard } = useClipboard({
data,
columns,
selectedCell,
selectionRange,
onDataChange,
});Styling
The component uses Tailwind CSS classes. Import the styles:
import '@your-org/react-editable-table/styles';Or if you're using Tailwind CSS in your project, the component will inherit your theme.
Browser Support
- Chrome (latest)
- Firefox (latest)
- Safari (latest)
- Edge (latest)
Contributing
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Changelog
v1.0.0
- Initial release
- Full feature set with inline editing, sorting, filtering
- Column resizing and drag-and-drop row reordering
- Configurable pagination with customizable page size
- TypeScript support
- Comprehensive documentation
- Enhanced callback system for granular control
- Built-in validation support
