1.0.1 โ€ข Published 5 months ago

@elselab-io/react-laravel-datatable v1.0.1

Weekly downloads
-
License
MIT
Repository
github
Last release
5 months ago

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": "john@example.com",
      "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

Website โ€ข GitHub โ€ข Contact

1.0.1

5 months ago

1.0.0

5 months ago