New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

@florianreihl/react-datatable

Package Overview
Dependencies
Maintainers
1
Versions
2
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install
Package was removed
Sorry, it seems this package was removed from the registry

@florianreihl/react-datatable

A powerful, flexible React component for to display tabular json data with built-in sorting, pagination, filtering, and metadata support.

unpublished
latest
Source
npmnpm
Version
1.0.1
Version published
Maintainers
1
Created
Source

📊 React DataTable by Florian Reihl

A powerful, flexible React component for displaying tabular data with built-in sorting, pagination, filtering, and rich metadata support.

npm version Downloads License: MIT

✨ Features

  • 🔢 Pagination: Built-in pagination with customizable rows per page
  • 🔄 Multi-column Sorting: Sort by multiple columns with priority indicators
  • 👁️ Column Management: Show/hide columns dynamically
  • 🏷️ Label Toggle: Switch between column names and descriptive labels
  • 📊 Metadata Tooltips: Rich hover tooltips showing column metadata
  • 🎨 Custom Rendering: Flexible cell and empty state rendering
  • 📱 Responsive Design: Works on desktop and mobile
  • 🔍 Row Numbers: Optional row numbering with custom icons
  • Performance: Handles large datasets efficiently
  • 🎯 Event Handling: Click handlers for rows and cells
  • 💪 TypeScript: Full TypeScript support
  • 🎨 Tailwind CSS: Styled with Tailwind for easy customization

📦 Installation

npm install @florianreihl/react-datatable
yarn add @florianreihl/react-datatable

🚀 Quick Start

import React from 'react';
import { DataTable } from '@florianreihl/react-datatable';

const columns = [
  {
    name: 'id',
    label: 'ID',
    dataType: 'integer',
    keySequence: 1
  },
  {
    name: 'name',
    label: 'Full Name',
    dataType: 'text'
  },
  {
    name: 'email',
    label: 'Email Address',
    dataType: 'text'
  },
  {
    name: 'age',
    label: 'Age',
    dataType: 'integer'
  }
];

const data = [
  [1, 'John Doe', 'john@example.com', 28],
  [2, 'Jane Smith', 'jane@example.com', 32],
  [3, 'Bob Johnson', 'bob@example.com', 45],
  [4, 'Alice Brown', 'alice@example.com', 29],
  [5, 'Charlie Wilson', 'charlie@example.com', 38]
];

function App() {
  return (
    <div className="p-6">
      <h1 className="text-2xl font-bold mb-4">My Data Table</h1>
      <DataTable
        data={data}
        columns={columns}
        height="400px"
        showRowNumbers={true}
        showTooltips={true}
      />
    </div>
  );
}

export default App;

📋 Advanced Usage

With Pagination and Sorting

import React, { useState } from 'react';
import { DataTable, getPaginationInfo } from '@florianreihl/react-datatable';

function AdvancedTable() {
  const [currentPage, setCurrentPage] = useState(1);
  const [rowsPerPage, setRowsPerPage] = useState(10);
  const [sortColumns, setSortColumns] = useState([]);

  const handleSort = (columnName) => {
    setSortColumns(prevSort => {
      const existingIndex = prevSort.findIndex(sort => sort.column === columnName);
      
      if (existingIndex === -1) {
        // Add new sort
        return [...prevSort, { column: columnName, direction: 'asc' }];
      } else {
        // Toggle existing sort
        const existing = prevSort[existingIndex];
        if (existing.direction === 'asc') {
          return prevSort.map((sort, index) =>
            index === existingIndex ? { ...sort, direction: 'desc' } : sort
          );
        } else {
          // Remove sort
          return prevSort.filter((_, index) => index !== existingIndex);
        }
      }
    });
  };

  const paginationInfo = getPaginationInfo(currentPage, rowsPerPage, data.length);

  return (
    <div>
      <DataTable
        data={data}
        columns={columns}
        currentPage={currentPage}
        rowsPerPage={rowsPerPage}
        sortColumns={sortColumns}
        onSort={handleSort}
        height="500px"
      />
      
      {/* Pagination Controls */}
      <div className="flex justify-between items-center mt-4">
        <div className="text-sm text-gray-600">
          Showing {paginationInfo.startIndex + 1} to {paginationInfo.endIndex} of {data.length} rows
        </div>
        <div className="flex space-x-2">
          <button 
            onClick={() => setCurrentPage(prev => Math.max(1, prev - 1))}
            disabled={!paginationInfo.hasPrevPage}
            className="px-3 py-1 border rounded disabled:opacity-50"
          >
            Previous
          </button>
          <span className="px-3 py-1">
            Page {currentPage} of {paginationInfo.totalPages}
          </span>
          <button 
            onClick={() => setCurrentPage(prev => prev + 1)}
            disabled={!paginationInfo.hasNextPage}
            className="px-3 py-1 border rounded disabled:opacity-50"
          >
            Next
          </button>
        </div>
      </div>
    </div>
  );
}

With Custom Cell Rendering

const customCellRenderer = (value, column, row, rowIndex) => {
  if (column.name === 'email') {
    return (
      <a href={`mailto:${value}`} className="text-blue-600 hover:underline">
        {value}
      </a>
    );
  }
  
  if (column.name === 'age') {
    const age = parseInt(value);
    if (age >= 40) {
      return <span className="font-bold text-red-600">{value}</span>;
    }
    if (age >= 30) {
      return <span className="font-medium text-orange-600">{value}</span>;
    }
    return <span className="text-green-600">{value}</span>;
  }
  
  return value;
};

<DataTable
  data={data}
  columns={columns}
  cellRenderer={customCellRenderer}
  onRowClick={(row, index) => console.log('Row clicked:', row)}
  onCellClick={(value, column, row, index) => console.log('Cell clicked:', value)}
/>

With Column Visibility Control

function TableWithColumnControl() {
  const [visibleColumns, setVisibleColumns] = useState(['id', 'name', 'email']);
  const [isLabelToggled, setIsLabelToggled] = useState(false);

  return (
    <div>
      {/* Column Controls */}
      <div className="mb-4 p-4 bg-gray-100 rounded">
        <h3 className="font-medium mb-2">Column Visibility:</h3>
        <div className="flex flex-wrap gap-2 mb-3">
          {columns.map(column => (
            <label key={column.name} className="flex items-center">
              <input
                type="checkbox"
                checked={visibleColumns.includes(column.name)}
                onChange={(e) => {
                  if (e.target.checked) {
                    setVisibleColumns(prev => [...prev, column.name]);
                  } else {
                    setVisibleColumns(prev => prev.filter(name => name !== column.name));
                  }
                }}
                className="mr-1"
              />
              {column.name}
            </label>
          ))}
        </div>
        
        <label className="flex items-center">
          <input
            type="checkbox"
            checked={isLabelToggled}
            onChange={(e) => setIsLabelToggled(e.target.checked)}
            className="mr-2"
          />
          Show column labels instead of names
        </label>
      </div>

      <DataTable
        data={data}
        columns={columns}
        visibleColumns={visibleColumns}
        isLabelToggled={isLabelToggled}
        height="400px"
      />
    </div>
  );
}

🔧 API Reference

Props

PropTypeDefaultDescription
dataany[][][]Array of rows, where each row is an array of values
columnsColumn[][]Array of column definitions
currentPagenumber1Current page number
rowsPerPagenumber25Number of rows per page
visibleColumnsstring[] | nullnullArray of column names to show (null = show all)
showRowNumbersbooleantrueShow row numbers column
isLabelToggledbooleanfalseShow labels instead of column names
showTooltipsbooleantrueShow metadata tooltips on hover
heightstring"400px"Table height
classNamestring""Additional CSS classes
headerIconstring | ReactNodenullIcon for row numbers header
sortColumnsSortColumn[][]Current sort configuration
onSortfunctionnullCalled when column header is clicked
onRowClickfunctionnullCalled when row is clicked
onCellClickfunctionnullCalled when cell is clicked
processedDataany[][]nullPre-filtered/sorted data (overrides data)
cellRendererfunctionnullCustom cell renderer
emptyStateRendererfunctionnullCustom empty state component
loadingbooleanfalseShow loading state
loadingRendererfunctionnullCustom loading component

Column Definition

interface Column {
  name: string;              // Unique column identifier
  label?: string;            // Human-readable label
  dataType: string;          // Data type (text, integer, float, etc.)
  itemOID?: string;          // Item OID for metadata
  keySequence?: number;      // Key sequence for primary keys
  length?: number;           // Maximum length
  codelist?: string;         // Codelist reference
  format?: string;           // Display format
  significantDigits?: number; // Significant digits for numbers
}

Sort Column

interface SortColumn {
  column: string;           // Column name to sort by
  direction: 'asc' | 'desc'; // Sort direction
}

🛠️ Utility Functions

getPaginationInfo(currentPage, rowsPerPage, totalRows)

Returns detailed pagination information:

interface PaginationInfo {
  totalPages: number;
  startIndex: number;
  endIndex: number;
  isFirstPage: boolean;
  isLastPage: boolean;
  hasNextPage: boolean;
  hasPrevPage: boolean;
}

calculateTotalPages(totalRows, rowsPerPage)

Returns the total number of pages for pagination.

🎨 Styling

This component uses Tailwind CSS classes. Make sure Tailwind CSS is available in your project. If you're not using Tailwind, you can override the styles with your own CSS.

Key CSS classes used:

  • bg-white, border-gray-300 - Basic styling
  • hover:bg-gray-50 - Row hover effects
  • text-purple-600 - Sort and key indicators
  • sticky, top-0 - Fixed header

🔄 Examples

Check out the examples directory for more detailed usage examples including:

  • Basic table setup
  • Advanced filtering
  • Custom styling
  • Integration with forms
  • Real-world data scenarios

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  • Fork the repository
  • Create your feature branch (git checkout -b feature/AmazingFeature)
  • Commit your changes (git commit -m 'Add some AmazingFeature')
  • Push to the branch (git push origin feature/AmazingFeature)
  • Open a Pull Request

📝 License

This project is licensed under the MIT License - see the LICENSE file for details.

👨‍💻 Author

Florian Reihl

🙏 Acknowledgments

  • Built with React and TypeScript
  • Styled with Tailwind CSS
  • Bundled with Rollup

📊 Browser Support

  • Chrome 60+
  • Firefox 60+
  • Safari 12+
  • Edge 79+

Made with ❤️ by Florian Reihl

Keywords

react

FAQs

Package last updated on 24 Jun 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts