Inline Tables
Render the table directly
For a table-only component, keep the inherited render() method:
class Users extends PenguTable
{
public function query(): Builder
{
return User::query();
}
public function columns(): array
{
return [
Column::make('Name', 'name')->sortable()->searchable(),
];
}
}
<livewire:users />
Render a table inside your own view
If the component has its own page layout or additional content, override
render() and include the table with x-pengutable:
use Illuminate\Contracts\View\View;
public function render(): View
{
return $this->view()
->layout('layouts.app')
->title('Users');
}
<div class="space-y-4">
<x-page-header title="Users" />
<x-card>
<x-pengutable :configuration="$this" />
</x-card>
</div>
The configuration value is the current PenguTable instance. It is passed
to the Blade component, not stored as a separate public Livewire property.
This is important because table definitions commonly contain closures and
objects that should not be serialized as Livewire state.
Livewire 4 MFC example
The same pattern works in a Livewire 4 multi-file component. The PHP file
extends PenguTable and the Blade file renders the table:
// resources/views/livewire/users.php
use App\Models\User;
use Illuminate\Database\Eloquent\Builder;
use RealZone22\PenguTables\Livewire\PenguTable;
use RealZone22\PenguTables\Table\Column;
new class extends PenguTable {
public function query(): Builder
{
return User::query();
}
public function columns(): array
{
return [
Column::make('Name', 'name')->sortable()->searchable(),
];
}
};
{{-- resources/views/livewire/users.blade.php --}}
<div>
<h1>Users</h1>
<x-pengutable :configuration="$this" />
</div>
Component state
The inherited component keeps the following main state:
searchperPagesortFieldsortDirectionactiveFiltersselectedselectAll
Do not duplicate these properties in the child component. Use the provided methods and configuration hooks instead.