inertia-table maintained by alik-laravel
alik-laravel/inertia-table
Server-driven filterable, sortable, paginated data tables for Inertia.js v3 + Vue 3, with bundled shadcn-vue UI primitives. Private package.
Features
- Fluent PHP API with autocompletion (
Table,Column,Filter,Actionclasses) - Built-in text / date / badge / boolean / image / action column types
- Text / dropdown / boolean / date filters with a rich clause system (contains, between, is_set, etc.)
- Sticky headers, sticky pagination, stickable columns, column resize + visibility
- Multi-table per-page support with scope isolation
- Artisan scaffolding:
make:table,make:column,make:filter - Orchestra Workbench demo app with live Inertia+Vue stack
Requirements
- PHP 8.4+
- Laravel 13.x
- Inertia.js v3 (
inertiajs/inertia-laravel^3.0) - Vue 3.5+
- Tailwind CSS v4
- Spatie Laravel Query Builder 7+ (
spatie/laravel-query-builder^7.2) - Pinia (client-side)
Installation
See docs/installation.md for the full guide.
Quick:
composer require alik-laravel/inertia-table
php artisan vendor:publish --tag=inertia-table-components
php artisan vendor:publish --tag=inertia-table-styles
Quick Start
// app/Tables/UsersTable.php
use Alik\InertiaTable\Table;
use Alik\InertiaTable\Columns\{TextColumn, DateColumn, BadgeColumn};
use Alik\InertiaTable\Filters\{TextFilter, DropdownFilter};
use Alik\InertiaTable\Enums\Variant;
use App\Models\User;
use Override;
final class UsersTable extends Table
{
protected string $resource = User::class;
#[Override]
public function columns(): array
{
return [
TextColumn::make('name')->sortable()->searchable(),
BadgeColumn::make('status')->variant([
'active' => Variant::Green,
'pending' => Variant::Yellow,
'suspended' => Variant::Red,
]),
DateColumn::make('created_at')->format('Y, M d'),
];
}
#[Override]
public function filters(): array
{
return [
TextFilter::make('name'),
DropdownFilter::make('status')->options([
'active' => 'Active',
'pending' => 'Pending',
'suspended' => 'Suspended',
]),
];
}
}
// Controller
return Inertia::render('Users/Index', [
'users' => UsersTable::make()->withQuery(User::query()),
]);
<!-- Users/Index.vue -->
<script setup lang="ts">
import { Table, type Paginated } from '@/vendor/inertia-table/table';
defineProps<{ users: Paginated<any> }>();
</script>
<template>
<Table name="users" :resource="users" />
</template>
The
nameprop on<Table>and the key inInertia::render([...])must be the same string. The package auto-binds the table's PHP-side name to that key, so->as(...)is only needed when you want a name that differs from the Inertia prop key. See docs/installation.md.
Documentation
- Installation — composer, Vite config, publishing assets
- Columns — all column types with every option
- Filters — all filter types +
Clauseenum reference - Actions —
Action,Icon,Imageconfiguration - Customization — overriding published Vue components, stubs, theme tokens
- Testing — writing tests for tables and filters
Workbench
The package ships an Orchestra Workbench demo app. From the package directory:
composer install
npm install
npm run build # build Vite assets into workbench/public/build
composer run build # migrate, seed, publish workbench assets
ln -sfn ../../../../../workbench/public/build vendor/orchestra/testbench-core/laravel/public/build
ln -sfn ../../../../../workbench/public/hot vendor/orchestra/testbench-core/laravel/public/hot
composer run serve # http://localhost:8000
npm run dev # hot reload Vite in another terminal
Why the symlinks?
Vite writes to workbench/public/, but Laravel's Vite facade resolves the
manifest (and the hot file) via public_path(), which under Testbench points
to vendor/orchestra/testbench-core/laravel/public/. Without the two symlinks
above you get Illuminate\Foundation\ViteManifestNotFoundException on every
request.
The vendor/ directory is rewritten by composer install / composer update,
so re-run both ln -s commands (or the php -r snippets above) after every
dependency install — or add them to a local script you run on fresh clones.
License
Proprietary. See LICENSE.md.