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

Livewire Table Kit Laravel Package

unlab/livewire-table-kit

View on GitHub
Deep Wiki
Context7

unlab/livewire-table-kit

Reusable Livewire table component kit with:

  • search
  • filters
  • sorting
  • pagination
  • row actions
  • bulk delete
  • CSV / XLSX / PDF export

Documentation

Install

composer require unlab/livewire-table-kit

Setup

1. Tailwind Configuration

Add the package path to your Tailwind configuration to ensure styles are compiled.

For Tailwind v4 (app.css):

@source "../../vendor/unlab/livewire-table-kit/resources/views/**/*.blade.php";

For Tailwind v3 (tailwind.config.js):

content: [
    './vendor/unlab/livewire-table-kit/resources/views/**/*.blade.php',
],

Then run: npm run build

2. Publish views (Optional)

php artisan vendor:publish --tag=livewire-table-kit-views

3. Publish config and MCP assets (Optional)

php artisan vendor:publish --tag=livewire-table-kit-config
php artisan vendor:publish --tag=livewire-table-kit-mcp
php artisan vendor:publish --tag=livewire-table-kit-stubs
php artisan vendor:publish --tag=livewire-table-kit-lang

Install AI skills (Optional)

If you want to use the package MCP server or project-local AI skills:

# Install local MCP server config
php artisan livewire-table-kit:install-mcp

# Install skill files for Codex and project-local workflows
php artisan livewire-table-kit:install-skill

Generate a table component

Use the package generator command to scaffold a table component from an Eloquent model:

php artisan make:livewire-table App\\Models\\User UsersTable

The generator uses schema heuristics to automatically determine:

  • Searchable and sortable fields
  • Badge columns for statuses and booleans
  • Sensible labels

Advanced Usage

Full Example

<?php

declare(strict_types=1);

namespace App\Livewire\Tables;

use App\Models\User;
use Illuminate\Database\Eloquent\Builder;
use Unlab\LivewireTableKit\Livewire\Components\Tables\BaseTable;
use Unlab\LivewireTableKit\Livewire\Components\Tables\Columns\Column;
use Unlab\LivewireTableKit\Livewire\Components\Tables\Columns\BadgeColumn;
use Unlab\LivewireTableKit\Livewire\Components\Tables\Columns\ActionColumn;
use Unlab\LivewireTableKit\Livewire\Components\Tables\Columns\Actions\TableAction;
use Unlab\LivewireTableKit\Livewire\Components\Tables\Filters\Filter;

class UsersTable extends BaseTable
{
    public function query(): Builder
    {
        return User::query();
    }

    public function columns(): array
    {
        return [
            Column::make('ID')->field('id')->sortable(),
            
            Column::make('Name')
                ->field('name')
                ->searchable()
                ->sortable(),

            Column::make('Email')
                ->field('email')
                ->searchable()
                ->sortable(),

            BadgeColumn::make('Status')
                ->field('status')
                ->colorMap([
                    'active' => 'success',
                    'pending' => 'warning',
                    'inactive' => 'danger',
                ]),

            ActionColumn::make()->actions([
                TableAction::wire('Edit', fn ($row) => "edit('{$row->id}')", icon: 'pencil'),
                TableAction::link('View', fn ($row) => route('users.show', $row), icon: 'eye'),
            ]),
        ];
    }

    public function filters(): array
    {
        return [
            Filter::select('role', 'Role', [
                'admin' => 'Administrator',
                'user' => 'User',
            ]),

            Filter::radio('status', 'Status', [
                'active' => 'Active',
                'inactive' => 'Inactive',
            ])->placeholder('All statuses')
                ->display('dropdown'),

            Filter::checkbox('department', 'Departments', [
                'engineering' => 'Engineering',
                'product' => 'Product',
                'support' => 'Support',
            ]),
            
            Filter::date('created_at', 'Created After'),
            
            // Custom query filter
            Filter::text('search_bio', 'Search Bio')
                ->query(fn ($query, $value) => $query->where('bio', 'like', "%{$value}%")),
        ];
    }

    public function supportsExport(): bool => true;
    public function supportsBulkDelete(): bool => true;

    public function actionBulkDelete(array $payload): void
    {
        User::whereIn('id', $payload)->delete();
    }
}

Column Helpers

  • Column::make('Label'): Create a column.
  • ->field('db_column'): Maps to a database column.
  • ->value(fn ($row) => ...): Define a custom value resolver.
  • ->searchable(?string $field = null): Enable search.
  • ->searchableRaw(string $expression): Search using a raw SQL expression (e.g., CONCAT(first_name, ' ', last_name)).
  • ->sortable(?string $field = null): Enable sorting.
  • ->view('custom.cell-view'): Render cells using a custom Blade view.
  • ->align('center'): Set text alignment (left, center, right).
  • ->headerAlign('center'): Set header alignment.
  • ->html(): Treat the value as raw HTML.
  • ->exportable(false): Exclude from exports.

Badge Columns

BadgeColumn uses Flux UI's badge styles.

BadgeColumn::make('Status')
    ->field('status')
    ->colorMap([
        'active' => 'success',   // emerald
        'pending' => 'warning',  // amber
        'inactive' => 'danger',  // rose
        'default' => 'default',  // zinc
    ]);

Available colors: primary, success, warning, danger, default.

Filter Types

  • Filter::select(key, label, options)
  • Filter::radio(key, label, options)
  • Filter::checkbox(key, label, options)
  • Filter::text(key, label, placeholder)
  • Filter::date(key, label)
  • Filter::number(key, label, placeholder)

For select and radio filters, placeholder() is used as the label for the reset or "all" option. Checkbox filters are multi-select, render inside a dropdown in the default toolbar UI, and apply a whereIn-style match by default. Option-based filters can also control their toolbar presentation with ->display('inline') or ->display('dropdown').

At the table level, you can collapse the entire filter set into a single dropdown trigger:

protected function filterToolbarMode(): string
{
    return 'dropdown';
}

Events

The component listens for and dispatches several events:

  • refreshTable: (Inbound) Refreshes the table data and resets pagination.
  • openBulkDeleteConfirm: (Outbound) Triggered when bulk delete is clicked.
  • bulkDeleteConfirmed: (Inbound) Triggered when the user confirms deletion.
  • notify: (Outbound) Standard notification event with type and message.

Customization

BaseTable Hooks

Override these methods in your table class to customize behavior:

Method Description Default
defaultSortField() Initial sort column null
defaultSortDirection() Initial sort direction 'asc'
perPageOptions() Options for the per-page selector [10, 25, 50, 100, 'all']
emptyState() Configure the empty state display Array with title/message
exportType() Export processing mode: sync or queued (queue alias accepted) 'sync'
exportFilename(ext) Name of the exported file Derived from class name

Queued Exports

For large exports, queue the export job instead of generating the file during the Livewire request:

protected function exportType(): string
{
    return 'queued';
}

Queued exports store the generated file on the configured disk and dispatch an exportQueued event with format, disk, and path. The table UI shows a Flux-styled loading toast while the export is processing, then a permanent ready toast with a Download action after the file exists. If the job fails, the table shows a permanent failed toast with the cached error message. Ready and failed toasts stay visible until the user closes them.

PDF Customization

protected function exportPdfTitle(): string => 'User Report';
protected function exportPdfOrientation(): string => 'landscape'; // portrait or landscape
protected function exportPdfPaperSize(): string => 'a4';
protected function exportPdfMargins(): array => ['top' => '10mm', ...];
protected function exportPdfFontSize(): string => '9px';

Requirements

  • PHP 8.4+
  • Laravel 13+
  • Livewire 4+
  • Flux UI 2+ (The UI depends on Flux components)
  • Maatwebsite Excel (For XLSX exports)
  • Barryvdh DomPDF (For PDF exports)

License

The MIT License (MIT). Please see LICENSE for more information.

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.
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
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