team-nifty-gmbh / tall-datatables
Server-side rendered datatables for Laravel and Livewire
Package info
github.com/Team-Nifty-GmbH/tall-datatables
pkg:composer/team-nifty-gmbh/tall-datatables
Requires
- php: ^8.4
- laravel/framework: ^12.0|^13.0
- livewire/livewire: ^4.0
- maatwebsite/excel: ^3.1
- spatie/laravel-model-info: ^1.0|^2.0
- tallstackui/tallstackui: ^3.0
Requires (Dev)
- laravel/pint: ^1.0
- laravel/scout: ^10.0
- nunomaduro/collision: ^8.5
- orchestra/testbench: ^10.0
- pestphp/pest: ^4.0
- pestphp/pest-plugin-browser: ^4.0
- pestphp/pest-plugin-faker: ^4.0
- pestphp/pest-plugin-laravel: ^4.0
- pestphp/pest-plugin-livewire: ^4.0
- dev-main
- v2.4.2
- v2.4.1
- v2.4.0
- v2.3.9
- v2.3.8
- v2.3.7
- v2.3.6
- v2.3.5
- v2.3.4
- v2.3.3
- v2.3.2
- v2.3.1
- v2.3.0
- v2.2.2
- v2.2.1
- v2.2.0
- v2.2.0-beta.1
- v2.1.0
- v2.0.0
- 1.x-dev
- v1.8.0
- v1.7.10
- v1.7.9
- v1.7.8
- v1.7.7
- v1.7.6
- v1.7.5
- v1.1.7
- v1.1.6
- v1.1.5
- v1.1.4
- v1.1.3
- v1.1.2
- v1.1.1
- v1.1.0
- v1.0.5
- v1.0.4
- v1.0.3
- v1.0.2
- v1.0.1
- v1.0.0
- v1.0.0-beta.26
- v1.0.0-beta.25
- v1.0.0-beta.24
- v1.0.0-beta.23
- v1.0.0-beta.22
- v1.0.0-beta.21
- v1.0.0-beta.20
- v1.0.0-beta.19
- v1.0.0-beta.18
- v1.0.0-beta.17
- v1.0.0-beta.16
- v1.0.0-beta.15
- v1.0.0-beta.14
- v1.0.0-beta.13
- v1.0.0-beta.12
- v1.0.0-beta.11
- v1.0.0-beta.10
- v1.0.0-beta.9
- v1.0.0-beta.8
- v1.0.0-beta.7
- v1.0.0-beta.6
- v1.0.0-beta.5
- v1.0.0-beta.4
- v1.0.0-beta.3
- v1.0.0-beta.2
- v1.0.0-beta.1
- v1.0.0-beta.0
- 0.x-dev
- v0.9.39
- v0.9.38
- v0.9.37
- v0.9.36
- v0.9.35
- v0.9.34
- v0.9.33
- v0.9.32
- v0.9.31
- v0.9.30
- v0.9.29
- v0.9.28
- v0.9.27
- v0.9.26
- v0.9.25
- v0.9.24
- v0.9.23
- v0.9.22
- v0.9.21
- v0.9.20
- v0.9.19
- v0.9.18
- v0.9.17
- v0.9.16
- v0.9.15
- v0.9.14
- v0.9.13
- v0.9.12
- v0.9.11
- v0.9.10
- v0.9.9
- v0.9.8
- v0.9.7
- v0.9.6
- v0.9.5
- v0.9.4
- v0.9.3
- v0.9.2
- v0.9.1
- v0.9.0
- v0.8.13
- v0.8.12
- v0.8.11
- v0.8.10
- v0.8.9
- v0.8.8
- v0.8.7
- v0.8.6
- v0.8.5
- v0.8.4
- v0.8.3
- v0.8.2
- v0.8.1
- v0.8.0
- v0.7.10
- v0.7.9
- v0.7.8
- v0.7.7
- v0.7.6
- v0.7.5
- v0.7.4
- v0.7.3
- v0.7.2
- v0.7.1
- v0.7.0
- v0.6.2
- v0.6.1
- v0.6.0
- v0.5.8
- v0.5.7
- v0.5.6
- v0.5.5
- v0.5.4
- v0.5.3
- v0.5.2
- v0.5.1
- v0.5.0
- v0.4.14
- v0.4.13
- v0.4.12
- v0.4.11
- v0.4.10
- v0.4.9
- v0.4.8
- v0.4.7
- v0.4.6
- v0.4.5
- v0.4.4
- v0.4.3
- v0.4.2
- v0.4.1
- v0.4.0
- v0.3.4
- v0.3.3
- v0.3.2
- v0.3.1
- v0.3.0
- v0.2.1
- v0.2.0
- v0.1.3
- v0.1.2
- v0.1.1
- v0.1.0
- dev-fix/append-array-keys
- dev-fix/restore-append-rendering
- dev-feature/resizable-columns
- dev-fix/string-formatter-strip-tags
- dev-feature/kanban-improvements
- dev-chore/gitignore-test-artifacts
- dev-fix/clear-session-filter-on-reset
- dev-fix/progress-bar-label-and-animation
- dev-fix-selected-row-action-clipping
- dev-feature/required-cols
- dev-fix/has-selected-dom-query
- dev-fix/bccomp-non-numeric-value
- dev-chore/update-readme-roadmap
- dev-feature/kanban-view
- dev-fix/skip-render-on-dynamic-mount
- dev-feature/relative-date-filters
- dev-feature/release-workflow
- dev-feature/positive-empty-state
- dev-chore/bump-vite-8
- dev-fix/alpine-init-race-condition
- dev-feature/tailwind-v4-compat
- dev-fix/changelog-workflow
- dev-fix/scope-data-loaded-event
- dev-fix/octane-compatibility
- dev-feature/add-laravel-13-support
- dev-feature/tallstackui-v3-tailwind-v4
- dev-fix/livewire-v4-data-flickering
- dev-fix/entangle-livewire-v4
- dev-fix/enum-filter-operators
- dev-fix/saved-filter-object-object
- dev-hotfix/fix-filter-method-calls
- dev-hotfix/fix-wherenull-method-call
- dev-feature/livewire-4-support
- dev-prevent-event-when-clicking-action
- dev-refactor
This package is auto-updated.
Last update: 2026-04-14 09:21:32 UTC
README
Performant, feature-rich datatables for the TALL stack. Built on Livewire 4 Islands architecture with Alpine.js driven rendering for minimal payloads.
Requirements
- PHP 8.4+
- Laravel 12+
- Livewire 4+
- TallStackUI 3+
- Alpine.js 3+
- Tailwind CSS 3+
Installation
composer require team-nifty-gmbh/tall-datatables:^2.0
Add the scripts and styles to your layout:
<datatable:styles /> <datatable:scripts />
Publish migrations and run them:
php artisan vendor:publish --tag="tall-datatables-migrations"
php artisan migrate
Quick Start
class UserDataTable extends DataTable { protected string $model = User::class; public array $enabledCols = ['name', 'email', 'created_at']; }
<livewire:data-tables.user-data-table />
Layouts
Three built-in layouts: table (default), grid, and kanban.
View-Mode Switcher
Let users switch between layouts at runtime:
protected function availableLayouts(): array { return ['table', 'grid', 'kanban']; }
When more than one layout is configured, a switcher appears in the toolbar. The active layout is persisted in saved filters.
Grid Layout
Cards in a responsive CSS grid. Image columns get hero treatment.
protected function availableLayouts(): array { return ['table', 'grid']; }
Kanban Layout
Cards grouped into lanes by a column value. Drag & drop between lanes.
protected function availableLayouts(): array { return ['table', 'kanban']; } // Which column determines the lanes protected function kanbanColumn(): string { return 'state'; } // Optional: explicit lane config (order, labels, colors) protected function kanbanLanes(): ?array { return [ 'open' => ['label' => 'Open', 'color' => 'emerald'], 'in_progress' => ['label' => 'In Progress', 'color' => 'amber'], 'done' => ['label' => 'Done', 'color' => 'indigo'], ]; } // Handle drag & drop public function kanbanMoveItem(int|string $id, string $targetLane): void { MyModel::findOrFail($id)->update(['state' => $targetLane]); } // Optional: custom card blade view protected function kanbanCardView(): ?string { return 'components.my-kanban-card'; }
If kanbanLanes() returns null, lanes are auto-generated from the column's enum/state values.
Filtering
Sidebar Filters
Enable filtering with the sidebar:
public bool $isFilterable = true;
Available operators: =, !=, >, >=, <, <=, like, not like, starts with, ends with, contains, does not contain, in, not in, is null, is not null, between.
The in and not in operators accept comma-separated values.
Date Presets
Date columns automatically show a preset dropdown: Today, Yesterday, This Week/Month/Quarter/Year, Last 7/30 Days, Last Week/Month/Quarter/Year. A "Custom" option opens inline fields for building custom relative date calculations.
Saved Filters
Users can save their current filter/column/sort configuration and reload it later. Supports shared filters across team members:
protected function canShareFilters(): bool { return true; }
Sorting
Click a column header to sort. Shift+Click for multi-sort on additional columns.
// Restrict sortable columns (default: all) public array $sortable = ['name', 'created_at'];
Selection
public bool $isSelectable = true;
Select individual rows or use "select all" (wildcard). The wildcard stays compact (['*']) regardless of record count. Use getSelectedValues() or getSelectedModels() in your actions to resolve the actual records.
Relation Columns
Display columns from related models using dot notation:
public array $enabledCols = [ 'name', 'email', 'department.name', 'department.manager.email', ];
Relation Count Columns
Show relation counts by adding _count suffix in the column configuration. Counts are filterable and sortable:
public array $enabledCols = ['name', 'orders_count', 'comments_count'];
Export
Export data in three formats: Excel (.xlsx), CSV, and JSON. Users select the format from a dropdown in the export tab.
// Disable export (enabled by default) public bool $isExportable = false;
CSV uses semicolon delimiter with UTF-8 BOM for Excel compatibility. JSON exports relations as nested objects.
Row Actions
Define actions using DataTableButton:
protected function getRowActions(): array { return [ DataTableButton::make('edit') ->label(__('Edit')) ->icon('pencil') ->wireClick('edit(record.id)'), ]; }
Row Drag & Drop
Enable manual row reordering:
protected function getRowDragDropConfig(): ?array { return [ 'column' => 'sort_order', ]; }
Custom Formatters
Register formatters for custom display logic:
use TeamNiftyGmbH\DataTable\Formatters\FormatterRegistry; app(FormatterRegistry::class)->register(MyCast::class, new MyFormatter());
Built-in formatters: boolean, date, datetime, money, percentage, image, link, badge, float, string, array.
Custom Column Transformation
Use augmentItemArray() to add computed columns before formatters are applied:
protected function augmentItemArray(array &$itemArray, Model $item): void { $itemArray['full_name'] = $item->first_name . ' ' . $item->last_name; }
Sidebar Tabs
Extend the sidebar with custom tabs:
public function getSidebarTabs(): array { $tabs = parent::getSidebarTabs(); $tabs[] = [ 'id' => 'my-tab', 'label' => __('My Tab'), 'view' => 'components.my-custom-tab', ]; return $tabs; }
Positive Empty State
Show a friendly message when a table is expected to be empty:
public bool $positiveEmptyState = true;
Default Columns
Allow users to save their column layout as the default:
protected function canSaveDefaultColumns(): bool { return true; }
Testing
vendor/bin/pest
Credits
License
MIT. See LICENSE.