Phara UI v2.x

Table

A flexible table component for displaying structured data with support for sorting and pagination.

Basic

A simple table with columns, rows, and cells. Use variant="strong" on a cell to bold the primary column.

Name Email Role Status
Alice Johnson alice@example.com Admin Active
Bob Martinez bob@example.com Editor Active
Carol White carol@example.com Viewer Inactive
David Lee david@example.com Editor Active
Blade
<x-ui::table>
    <x-ui::table-columns>
        <x-ui::table-column>Name</x-ui::table-column>
        <x-ui::table-column>Email</x-ui::table-column>
        <x-ui::table-column>Role</x-ui::table-column>
        <x-ui::table-column align="end">Status</x-ui::table-column>
    </x-ui::table-columns>

    <x-ui::table-rows>
        @foreach($users as $user)
            <x-ui::table-row>
                <x-ui::table-cell variant="strong">{{ $user->name }}</x-ui::table-cell>
                <x-ui::table-cell>{{ $user->email }}</x-ui::table-cell>
                <x-ui::table-cell>{{ $user->role }}</x-ui::table-cell>
                <x-ui::table-cell align="end">{{ $user->status }}</x-ui::table-cell>
            </x-ui::table-row>
        @endforeach
    </x-ui::table-rows>
</x-ui::table>
Sortable

Add sortable, :sorted, and :direction to a column to show sort indicators. Wire up a Livewire sort() action to handle ordering.

Name Email Role Status
Alice Johnson alice@example.com Admin Active
Bob Martinez bob@example.com Editor Active
Carol White carol@example.com Viewer Inactive
David Lee david@example.com Editor Active
PHP
// Livewire component
public string $sortBy = 'name';
public string $sortDirection = 'asc';

public function sort(string $column): void
{
    if ($this->sortBy === $column) {
        $this->sortDirection = $this->sortDirection === 'asc' ? 'desc' : 'asc';
    } else {
        $this->sortBy = $column;
        $this->sortDirection = 'asc';
    }
}

// Template
<x-ui::table>
    <x-ui::table-columns>
        <x-ui::table-column
            sortable
            :sorted="$sortBy === 'name'"
            :direction="$sortDirection"
            wire:click="sort('name')"
            href="#"
        >
            Name
        </x-ui::table-column>
    </x-ui::table-columns>
    ...
</x-ui::table>
Selection

Add selectable to x-ui::table and x-ui::table-columns, then pass :value to each x-ui::table-row. A "select all" header checkbox and per-row checkboxes are rendered automatically.

Name Email Role Status
Alice Johnson alice@example.com Admin Active
Bob Martinez bob@example.com Editor Active
Carol White carol@example.com Viewer Inactive
David Lee david@example.com Editor Active
Eva Brown eva@example.com Viewer Pending
Frank Garcia frank@example.com Admin Active
Grace Kim grace@example.com Editor Inactive
Blade
{{-- Blade template --}}
<x-ui::table selectable>
    <x-ui::table-columns selectable>
        <x-ui::table-column>Name</x-ui::table-column>
        <x-ui::table-column>Email</x-ui::table-column>
        <x-ui::table-column align="end">Status</x-ui::table-column>
    </x-ui::table-columns>

    <x-ui::table-rows>
        @@foreach($users as $user)
            <x-ui::table-row :value="$user->id">
                <x-ui::table-cell variant="strong">{{ $user->name }}</x-ui::table-cell>
                <x-ui::table-cell>{{ $user->email }}</x-ui::table-cell>
                <x-ui::table-cell align="end">{{ $user->status }}</x-ui::table-cell>
            </x-ui::table-row>
        @@endforeach
    </x-ui::table-rows>
</x-ui::table>

{{-- To sync selected IDs with Livewire, pass an @change listener: --}}
<x-ui::table selectable @change.capture="$wire.selected = selected">
    ...
</x-ui::table>

The selected array lives in Alpine state on the table wrapper. Use @change.capture="$wire.selected = selected" on the table element to sync it with a Livewire public array $selected = [] property.

Clicking a selected row's checkbox deselects it. The "select all" checkbox shows an indeterminate state when only some rows are checked. Clicking it selects all; clicking again clears all.

Pagination

Pass a LengthAwarePaginator to :paginate and the table automatically renders the custom x-ui::pagination component below — with page controls and a "Showing X–Y of Z" summary.

Name Email Role Status
Alice Johnson alice@example.com Admin Active
Bob Martinez bob@example.com Editor Active
Carol White carol@example.com Viewer Inactive
PHP
// Livewire component
use Illuminate\Pagination\LengthAwarePaginator;
use Livewire\WithPagination;

use WithPagination;

public int $perPage = 10;

#[Computed]
public function users(): LengthAwarePaginator
{
    $all   = User::query()->get();
    $page  = $this->getPage();
    $items = $all->slice(($page - 1) * $this->perPage, $this->perPage)->values();

    return new LengthAwarePaginator($items, $all->count(), $this->perPage, $page, [
        'path' => request()->url(),
    ]);
}

// Template — the table renders <x-ui::pagination> automatically
<x-ui::table :paginate="$this->users">
    ...
    <x-ui::table-rows>
        @foreach($this->users->items() as $user)
            <x-ui::table-row>...</x-ui::table-row>
        @endforeach
    </x-ui::table-rows>
</x-ui::table>
Pagination Size

Use pagination-size to match the pagination controls to the density of your table. Default is md.

Small

Name Role Status
Alice Johnson Admin Active
Bob Martinez Editor Active
Carol White Viewer Inactive

Large

Name Role Status
Alice Johnson Admin Active
Bob Martinez Editor Active
Carol White Viewer Inactive
Blade
{{-- Small pagination controls --}}
<x-ui::table :paginate="$this->users" pagination-size="sm">
    ...
</x-ui::table>

{{-- Medium (default) --}}
<x-ui::table :paginate="$this->users" pagination-size="md">
    ...
</x-ui::table>

{{-- Large --}}
<x-ui::table :paginate="$this->users" pagination-size="lg">
    ...
</x-ui::table>
Pagination Info

Set :show-info="false" to hide the "Showing X–Y of Z results" summary and render only the page controls, centered below the table.

Name Role Status
Alice Johnson Admin Active
Bob Martinez Editor Active
Carol White Viewer Inactive
Blade
{{-- Hide "Showing X–Y of Z results" --}}
<x-ui::table :paginate="$this->users" :show-info="false">
    ...
</x-ui::table>