Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Livewire Tables Laravel Package

alp-develop/laravel-livewire-tables

Reactive Livewire data tables for Laravel—search, sort, filter, paginate, export, and bulk actions with zero JavaScript. Supports Laravel 10–13, Livewire 3–4, PHP 8.1+, Tailwind or Bootstrap 4/5, plus dark mode and configurable themes.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation (unchanged):

    composer require alp-develop/laravel-livewire-tables
    php artisan vendor:publish --tag=livewire-tables-config
    

    Configure config/livewire-tables.php (required for theme, dark mode, and styling).

  2. First Use Case (updated for security):

    php artisan make:livewire Admin/UsersTable
    

    Add the table component to your view (ensure wire:ignore for non-table elements):

    <livewire:admin.users-table />
    
  3. Basic Table Definition (with security best practices):

    use AlpDevelop\LivewireTables\DataTableComponent;
    use AlpDevelop\LivewireTables\Column\TextColumn;
    use AlpDevelop\LivewireTables\Column\ViewColumn;
    
    public function table()
    {
        return DataTable::of(User::query())
            ->addColumn('Name', TextColumn::make('name'))
            ->addColumn('Email', TextColumn::make('email'))
            ->addColumn('Actions', ViewColumn::make('actions')
                ->view('livewire-tables::columns.actions', [
                    'url' => fn($row) => route('users.edit', $row)
                ]));
    }
    
  4. Render the Table (with eager loading):

    public function configure()
    {
        $this->setEagerLoad(['posts']); // Declare relations upfront
    }
    
    public function render()
    {
        return view('livewire.admin.users-table');
    }
    

Implementation Patterns

Core Workflow (updated for performance/security)

  1. Data Source Binding (with eager loading):

    DataTable::of(User::query()->where('active', true))
        ->setEagerLoad(['posts']); // Apply eager loading
    
  2. Column Definitions (with security):

    • Text/HTML: TextColumn::make('column_name')
    • Views: ViewColumn::make('column_name')->view('path.to.view')
    • Actions: Pre-built action columns (now XSS-safe):
      ViewColumn::make('actions')
          ->view('livewire-tables::columns.actions', ['url' => fn($row) => route('users.edit', $row)])
      
  3. Reactive Features (with validation):

    DataTable::of(User::query())
        ->search(['name', 'email']) // Search capped at 200 chars
        ->sort('name') // Field whitelisted
        ->paginate(10); // Validated against perPageOptions
    
  4. Bulk Actions (with TOCTOU protection):

    DataTable::of(User::query())
        ->addBulkAction('Delete', fn($rows) => User::whereIn('id', $rows)->delete());
    // IDs are now intersected with live query results
    
  5. Exporting (with sanitization):

    DataTable::of(User::query())
        ->addExport('CSV', fn() => User::all()->toArray());
    // Column labels are now escaped via escapeCsvValue()
    

Integration Tips (updated for security/performance)

  • Custom Views: Override default views (now XSS-safe):
    php artisan vendor:publish --tag=livewire-tables-views
    
  • Dark Mode: Enable via config (dark_mode: true) with sanitized CSS:
    'colors' => [
        'primary' => '#3b82f6', // Validated against CSS allowlist
    ],
    
  • Theming: Extend Tailwind/Bootstrap themes (now with SRI-pinned Flatpickr):
    @layer components {
        .livewire-tables-table {
            @apply bg-white dark:bg-gray-800;
        }
    }
    
  • API Integration: Use ->apiResponse() with validated perPage:
    ->apiResponse()->validatePerPage();
    

Gotchas and Tips

Pitfalls (updated for security/performance)

  1. Config Required (unchanged): Forgetting to publish the config breaks theming and styling.

  2. Query Scoping (updated for eager loading):

    // Good: Use setEagerLoad() in configure()
    public function configure() {
        $this->setEagerLoad(['posts']); // Applied in render()
    }
    
  3. Column Caching (now 3-tier): Column definitions are cached per request in cachedColumns, cachedVisibleColumns, and cachedSearchableColumns.

  4. Bulk Action IDs (now TOCTOU-protected): Bulk actions automatically intersect with live query results—no manual filtering needed.

  5. New Security Risks:

    • Sort Fields: Only [a-zA-Z0-9_.] allowed in sort fields.
    • Search Input: Capped at 200 characters to prevent LIKE wildcard abuse.
    • CSV Headers: Escaped via escapeCsvValue().
    • ActionColumn: XSS vectors (scripts, iframes, etc.) are stripped.

Debugging (updated for performance)

  • Logs: Enable debug: true in config to log queries and table events.
  • Wire Events: Use wire:ignore on non-table elements to avoid reactivity conflicts.
  • Performance:
    • resolveFilters() now caches filter resolution (previously called 5x per request).
    • FilterStep and SortStep build lookup maps in constructors (O(1) instead of O(n)).
    • Session writes are now dirty-tracked to avoid unnecessary writes.

Extension Points (updated for security)

  1. Custom Columns (now XSS-safe):

    class StatusColumn extends TextColumn {
        public function __construct() {
            parent::__construct('status');
            $this->format(fn($value) => ucfirst($value)); // Escaped via TextColumn
        }
    }
    
  2. Hooks (with Engine subclassing):

    // Extend Engine for custom pipeline logic
    class CustomEngine extends \AlpDevelop\LivewireTables\Engine {
        // Override applySteps()
    }
    
    public function getEngine() {
        return new CustomEngine($this);
    }
    
  3. Dark Mode (with CSS sanitization): Override dark mode styles via published assets (colors are now validated):

    @layer components {
        .dark .livewire-tables-table {
            @apply bg-gray-900;
        }
    }
    
  4. Localization (unchanged): Translate labels via config/livewire-tables.php:

    'labels' => [
        'search' => 'Filter',
    ],
    
  5. New: Eager Loading: Declare relations in configure():

    public function configure() {
        $this->setEagerLoad(['posts', 'roles']);
    }
    
  6. New: Engine Subclassing: Override getEngine() to customize pipeline orchestration:

    protected function getEngine() {
        return new CustomEngine($this);
    }
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope