Table

Simple

# Nice Name City
1 Duncan Ebertchester
2 Iliana Brendantown
3 Clementina Port Lenorefort
4 Lyla West Harrison
5 Hailie Mertzchester
@php
$users = App\Models\User::with('city')->take(5)->get();
 
$headers = [
['key' => 'id', 'label' => '#'],
['key' => 'name', 'label' => 'Nice Name'],
['key' => 'city.name', 'label' => 'City'] # <---- nested attributes
];
@endphp
 
{{-- You can use any `$wire.METHOD` on `@row-click` --}}
<x-table :headers="$headers" :rows="$users" striped @row-click="alert($event.detail.name)" />

Click to navigate

The following {tokens} will be replaced by actual values on each row based on any key from $headers config object.

Some examples:

  • /users/{id}
  • /users/profile/{username}/?&admin=true
  • /users/{id}/?from={city.name}

@php
$users = App\Models\User::with('city')->take(2)->get();
 
$headers = [
['key' => 'id', 'label' => '#'],
['key' => 'username', 'label' => 'username'],
['key' => 'city.name', 'label' => 'City'],
];
@endphp
 
{{-- Notice `link` --}}
{{-- Check browser url on next page --}}
<x-table :headers="$headers" :rows="$users" link="/docs/installation/?from={username}" />

No headers

Duncan Ebertchester
Iliana Brendantown
@php
$users = App\Models\User::with('city')->take(2)->get();
 
$headers = [
['key' => 'name', 'label' => 'Name'],
['key' => 'city.name', 'label' => 'City'],
];
@endphp
 
{{-- Notice `no-headers` --}}
<x-table :headers="$headers" :rows="$users" no-headers />

Header slot

You can override any header by using @scope('header_XXX', $header) special blade directive, in which XXX is any key from $headers config object.


# Nice Name City
1 Duncan Ebertchester
2 Iliana Brendantown
@php
$users = App\Models\User::with('city')->take(2)->get();
 
$headers = [
['key' => 'id', 'label' => '#', 'class' => 'bg-red-100'], # <--- custom CSS
['key' => 'name', 'label' => 'Nice Name'],
['key' => 'city.name', 'label' => 'City'], # <---- nested attributes
];
@endphp
 
<x-table :headers="$headers" :rows="$users">
{{-- Overrides `name` header --}}
@scope('header_name', $header)
{{ $header['label'] }} <x-icon name="s-question-mark-circle" />
@endscope
 
{{-- Overrides `city.name` header --}}
@scope('header_city.name', $header)
<u>{{ $header['label'] }}</u>
@endscope
</x-table>

Row slot

You can override any row by using @scope('row_XXX', $row) special blade directive, in which XXX is any key from $headers config object.

It injects current $row from the loop's context and achieves the same behavior that you would expect from the Vue/React components.

Notice that you do not need to override all the attributes.


# Nice Name City Fake City
1
Duncan
Ebertchester Ebertchester
2
Iliana
Brendantown Brendantown
3
Clementina
Port Lenorefort Port Lenorefort
@php
$users = App\Models\User::with('city')->take(3)->get();
 
$headers = [
['key' => 'id', 'label' => '#'],
['key' => 'name', 'label' => 'Nice Name'],
['key' => 'city.name', 'label' => 'City'], # <-- nested attributes
['key' => 'fakeColumn', 'label' => 'Fake City'] # <-- this column does not exists
];
@endphp
 
<x-table :headers="$headers" :rows="$users">
 
{{-- Notice `$user` is the current row item on loop --}}
@scope('cell_id', $user)
<strong>{{ $user->id }}</strong>
@endscope
 
{{-- You can name the injected object as you wish --}}
@scope('cell_name', $stuff)
<x-badge :value="$stuff->name" class="badge-info" />
@endscope
 
{{-- Notice the `dot` notation for nested attribute cell's slot --}}
@scope('cell_city.name', $user)
<i>{{ $user->city->name }}</i>
@endscope
 
{{-- The `fakeColumn` does not exist to the actual object --}}
@scope('cell_fakeColumn', $user)
<u>{{ $user->city->name }}</u>
@endscope
 
{{-- Special `actions` slot --}}
@scope('actions', $user)
<x-button icon="o-trash" wire:click="delete({{ $user->id }})" spinner class="btn-sm" />
@endscope
 
</x-table>

Row selection

Use selectable attribute in conjunction with wire:model to manage selection state.

public array $selected = [1, 3];

# Nice Name
1 Duncan
2 Iliana
3 Clementina
@php
$users = App\Models\User::take(3)->get();
 
$headers = [
['key' => 'id', 'label' => '#', 'class' => 'w-1'],
['key' => 'name', 'label' => 'Nice Name'],
];
@endphp
 
{{-- Notice `selectable` and `wire:model` --}}
{{-- See `@row-selection` output on console --}}
{{-- You can use any `$wire.METHOD` on `@row-selection` --}}
<x-table
:headers="$headers"
:rows="$users"
wire:model="selected"
selectable
@row-selection="console.log($event.detail)" />
 
<x-button label="Save" icon="o-check" wire:click="save" spinner />

By default, it will look up for $row->id attribute. You can customize this with selectable-key attribute.

{{-- Uses `$row->mycode` as selection key --}}
<x-table ... selectable selectable-key="mycode" />

Row expansion

Use expandable attribute in conjunction with wire:model to manage expansion state.

public array $expanded = [2];

Nice Name
Duncan
Hello, Duncan!
Iliana
Hello, Iliana!
Clementina
Hello, Clementina!
@php
$users = App\Models\User::take(3)->get();
 
$headers = [
['key' => 'id', 'label' => '#', 'class' => 'hidden'],
['key' => 'name', 'label' => 'Nice Name'],
];
@endphp
 
{{-- Notice `expandable` and `wire:model` --}}
<x-table :headers="$headers" :rows="$users" wire:model="expanded" expandable>
 
{{-- Special `expansion` slot --}}
@scope('expansion', $user)
<div class="bg-base-200 p-8 font-bold">
Hello, {{ $user->name }}!
</div>
@endscope
 
</x-table>

By default, it will look up for $row->id attribute. You can customize this with expandable-key attribute.

{{-- Uses `$row->mycode` as expandable key --}}
<x-table ... expandable expandable-key="mycode" />