npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@elselab-io/react-laravel-datatable

v1.0.1

Published

A TypeScript/JavaScript library for Laravel pagination with Tailwind CSS support

Readme

npm version License: MIT TypeScript

A powerful, TypeScript-ready data table library for Laravel pagination with React support and beautiful Tailwind CSS styling.

✨ Key Features

  • 🚀 Framework Agnostic - Works with vanilla JavaScript, React, Vue, or any framework
  • 📊 Laravel Integration - Seamless integration with Laravel's resource pagination API
  • 🎨 Tailwind CSS Styling - Beautiful, responsive design with Tailwind CSS
  • 🔍 Search & Sort - Built-in search and sorting functionality with server-side support
  • 📱 Mobile Responsive - Mobile-friendly pagination and table design
  • 🔧 TypeScript Support - Full type definitions and IntelliSense support
  • ⚡ Performance Optimized - Lightweight with minimal dependencies
  • 🧹 Easy Integration - Simple API for common use cases

🚀 Quick Start

Installation

npm install @elselab-io/react-laravel-datatable

Basic Usage

import { ReactDataTable, Column } from '@elselab-io/react-laravel-datatable';

// Define your data interface
interface User {
  id: number;
  name: string;
  email: string;
  created_at: string;
}

// Define columns
const columns: Column<User>[] = [
  { key: 'id', label: 'ID', sortable: true },
  { key: 'name', label: 'Name', sortable: true },
  { key: 'email', label: 'Email', sortable: true },
  { 
    key: 'created_at', 
    label: 'Created', 
    render: (value) => new Date(value).toLocaleDateString() 
  }
];

function UsersTable() {
  return (
    <ReactDataTable<User>
      apiUrl="/api/users"
      columns={columns}
      searchable={true}
      onRowClick={(user) => console.log('Selected user:', user)}
    />
  );
}

That's it! Your Laravel-powered data table is ready with search, sorting, and pagination.

📖 API Reference

ReactDataTable<T>

The main React component for rendering data tables with Laravel pagination.

<ReactDataTable<T>
  apiUrl="/api/users"                    // Laravel API endpoint
  columns={columns}                      // Column definitions
  searchable={true}                      // Enable search functionality
  perPage={10}                          // Items per page
  onRowClick={(item) => {}}             // Row click handler
  onDataLoad={(data) => {}}             // Data load callback
  className="custom-table"              // Custom CSS classes
  loadingComponent={<CustomLoader />}   // Custom loading component
/>

DataTable (Vanilla JavaScript)

For non-React applications, use the vanilla JavaScript DataTable class.

import { DataTable } from '@elselab-io/react-laravel-datatable';

const dataTable = new DataTable('#table-container', columns, {
  apiUrl: '/api/users',
  perPage: 10,
  searchable: true,
  sortable: true
});

useLaravelDataTable Hook

React hook for custom data table implementations.

import { useLaravelDataTable } from '@elselab-io/react-laravel-datatable';

const {
  data,
  loading,
  error,
  search,
  sort,
  goToPage,
  refresh
} = useLaravelDataTable<User>({
  apiUrl: '/api/users',
  perPage: 10
});

Column Definition

interface Column<T> {
  key: keyof T;                         // Data property key
  label: string;                        // Column header text
  sortable?: boolean;                   // Enable sorting
  render?: (value: any, row: T) => any; // Custom render function
  className?: string;                   // Custom CSS classes
}

🎨 Examples

Advanced Column Rendering

const columns: Column<User>[] = [
  { key: 'id', label: 'ID', sortable: true },
  { key: 'name', label: 'Name', sortable: true },
  { 
    key: 'status', 
    label: 'Status',
    render: (value) => (
      <span className={`px-2 py-1 rounded ${
        value === 'active' ? 'bg-green-100 text-green-800' : 'bg-red-100 text-red-800'
      }`}>
        {value}
      </span>
    )
  },
  {
    key: 'actions',
    label: 'Actions',
    sortable: false,
    render: (_, user) => (
      <div className="space-x-2">
        <button 
          onClick={() => editUser(user.id)}
          className="text-blue-600 hover:text-blue-800"
        >
          Edit
        </button>
        <button 
          onClick={() => deleteUser(user.id)}
          className="text-red-600 hover:text-red-800"
        >
          Delete
        </button>
      </div>
    )
  }
];

Custom Loading and Error States

function CustomDataTable() {
  const LoadingSpinner = () => (
    <div className="flex justify-center items-center py-8">
      <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600"></div>
    </div>
  );

  return (
    <ReactDataTable<User>
      apiUrl="/api/users"
      columns={columns}
      loadingComponent={<LoadingSpinner />}
      onDataLoad={(data) => {
        console.log(`Loaded ${data.data.length} users`);
      }}
    />
  );
}

Vanilla JavaScript Implementation

import { DataTable } from '@elselab-io/react-laravel-datatable';

// Define columns
const columns = [
  { key: 'id', label: 'ID', sortable: true },
  { key: 'name', label: 'Name', sortable: true },
  { key: 'email', label: 'Email', sortable: true },
  { 
    key: 'created_at', 
    label: 'Created', 
    render: (value) => new Date(value).toLocaleDateString() 
  }
];

// Initialize DataTable
const dataTable = new DataTable('#users-table', columns, {
  apiUrl: '/api/users',
  perPage: 15,
  searchable: true,
  sortable: true,
  className: 'custom-table-class'
});

// API methods
dataTable.refresh();                    // Reload data
dataTable.search('john');              // Search for 'john'
dataTable.sort('name', 'desc');        // Sort by name descending
dataTable.goToPage(2);                 // Navigate to page 2

Using the Hook for Custom Implementation

import { useLaravelDataTable } from '@elselab-io/react-laravel-datatable';

function CustomUsersTable() {
  const {
    data,
    loading,
    error,
    search,
    sort,
    goToPage,
    currentPage,
    totalPages
  } = useLaravelDataTable<User>({
    apiUrl: '/api/users',
    perPage: 10
  });

  if (loading) return <div>Loading...</div>;
  if (error) return <div>Error: {error}</div>;

  return (
    <div>
      <input 
        type="text" 
        placeholder="Search users..."
        onChange={(e) => search(e.target.value)}
        className="mb-4 p-2 border rounded"
      />
      
      <table className="w-full border-collapse">
        <thead>
          <tr>
            <th onClick={() => sort('name')}>Name</th>
            <th onClick={() => sort('email')}>Email</th>
          </tr>
        </thead>
        <tbody>
          {data?.data.map(user => (
            <tr key={user.id}>
              <td>{user.name}</td>
              <td>{user.email}</td>
            </tr>
          ))}
        </tbody>
      </table>
      
      <div className="mt-4">
        <button 
          onClick={() => goToPage(currentPage - 1)}
          disabled={currentPage === 1}
        >
          Previous
        </button>
        <span className="mx-4">
          Page {currentPage} of {totalPages}
        </span>
        <button 
          onClick={() => goToPage(currentPage + 1)}
          disabled={currentPage === totalPages}
        >
          Next
        </button>
      </div>
    </div>
  );
}

⚡ Laravel Backend Setup

Controller Implementation

<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\User;
use Illuminate\Http\Request;

class UserController extends Controller
{
    public function index(Request $request)
    {
        $query = User::query();

        // Handle search
        if ($request->has('search') && $request->search) {
            $search = $request->search;
            $query->where(function ($q) use ($search) {
                $q->where('name', 'like', "%{$search}%")
                  ->orWhere('email', 'like', "%{$search}%");
            });
        }

        // Handle sorting
        if ($request->has('sort_by') && $request->sort_by) {
            $direction = $request->sort_direction ?? 'asc';
            $query->orderBy($request->sort_by, $direction);
        }

        // Paginate results
        $perPage = $request->per_page ?? 10;
        $users = $query->paginate($perPage);

        return response()->json($users);
    }
}

Expected API Response Format

{
  "current_page": 1,
  "data": [
    {
      "id": 1,
      "name": "John Doe",
      "email": "[email protected]",
      "created_at": "2023-01-01T00:00:00.000000Z"
    }
  ],
  "first_page_url": "http://example.com/api/users?page=1",
  "from": 1,
  "last_page": 5,
  "last_page_url": "http://example.com/api/users?page=5",
  "links": [...],
  "next_page_url": "http://example.com/api/users?page=2",
  "path": "http://example.com/api/users",
  "per_page": 10,
  "prev_page_url": null,
  "to": 10,
  "total": 50
}

Route Definition

// routes/api.php
Route::get('/users', [UserController::class, 'index']);

🔧 Advanced Usage

Custom API Parameters

// Add custom parameters to all API requests
const { data, loading } = useLaravelDataTable<User>({
  apiUrl: '/api/users',
  customParams: {
    department: 'engineering',
    status: 'active'
  }
});

Dynamic Column Configuration

const [columns, setColumns] = useState<Column<User>[]>([
  { key: 'id', label: 'ID', sortable: true },
  { key: 'name', label: 'Name', sortable: true }
]);

// Add columns dynamically
const addEmailColumn = () => {
  setColumns(prev => [...prev, { 
    key: 'email', 
    label: 'Email', 
    sortable: true 
  }]);
};

Custom Styling with Tailwind

<ReactDataTable<User>
  apiUrl="/api/users"
  columns={columns}
  className="shadow-lg rounded-lg overflow-hidden"
  tableClassName="min-w-full divide-y divide-gray-200"
  headerClassName="bg-gray-50"
  bodyClassName="bg-white divide-y divide-gray-200"
  paginationClassName="bg-white px-4 py-3 border-t border-gray-200"
/>

🌐 Framework Support

React

import { ReactDataTable } from '@elselab-io/react-laravel-datatable';
// Full React component with hooks support

Vue.js

import { DataTable } from '@elselab-io/react-laravel-datatable';
// Use the vanilla DataTable class in Vue components

Angular

import { DataTable } from '@elselab-io/react-laravel-datatable';
// Integrate with Angular components using the DataTable class

Vanilla JavaScript

import { DataTable } from '@elselab-io/react-laravel-datatable';
// Works with any JavaScript application

📦 Module Systems

react-laravel-datatable supports all module systems:

ES Modules

import { ReactDataTable, DataTable, useLaravelDataTable } from '@elselab-io/react-laravel-datatable';

CommonJS

const { ReactDataTable, DataTable, useLaravelDataTable } = require('@elselab-io/react-laravel-datatable');

TypeScript

import { 
  ReactDataTable, 
  DataTable, 
  useLaravelDataTable,
  Column,
  LaravelPaginationResponse 
} from '@elselab-io/react-laravel-datatable';

🧪 Testing

Run the test suite:

npm test

Build the project:

npm run build

Run examples:

cd examples/react-app
npm install
npm start

📄 License

MIT License - see LICENSE file for details.

🤝 Contributing

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

📊 Bundle Size

  • Minified: ~25KB
  • Gzipped: ~8KB
  • Dependencies: React (peer dependency)
  • TypeScript definitions included

Made with ❤️ by Else Lab

WebsiteGitHubContact