Data Table

A client-side Alpine data table with sorting, search, selection, pagination, and custom cells.

A list of your team members and their roles.
Status Actions
No results found.

– of rows

/
Component Code
@php
$team = [
['id' => 1, 'name' => 'Olivia Martin', 'email' => 'olivia@example.com', 'role' => 'Owner', 'status' => 'Active'],
['id' => 2, 'name' => 'Jackson Lee', 'email' => 'jackson@example.com', 'role' => 'Developer', 'status' => 'Active'],
['id' => 3, 'name' => 'Isabella Nguyen', 'email' => 'isabella@example.com', 'role' => 'Designer', 'status' => 'Invited'],
['id' => 4, 'name' => 'William Kim', 'email' => 'william@example.com', 'role' => 'Support', 'status' => 'Active'],
];
 
$columns = [
['key' => 'name', 'label' => 'Name', 'sortable' => true],
['key' => 'email', 'label' => 'Email', 'sortable' => true],
['key' => 'role', 'label' => 'Role', 'sortable' => true],
['key' => 'status', 'label' => 'Status'],
];
@endphp
 
<april:data-table :data="$team" :columns="$columns" searchable selectable paginated :per-page="3">
<slot:caption>A list of your team members and their roles.</slot:caption>
<slot:cell-status>
<span class="rounded-full bg-emerald-500/15 px-2 py-1 text-xs font-medium text-emerald-700 dark:text-emerald-300" x-text="row.status"></span>
</slot:cell-status>
<slot:actions>
<april:button size="sm" variant="ghost" x-text="`Edit ${row.name}`"></april:button>
</slot:actions>
</april:data-table>

Pass row data and column definitions to enable the interactive table. It supports sorting, full-table search, row selection, pagination, an empty state, and query-change / selection-change events for a future server or Livewire integration.

@php
$columns = [
['key' => 'name', 'label' => 'Name', 'sortable' => true],
['key' => 'email', 'label' => 'Email', 'sortable' => true],
['key' => 'status', 'label' => 'Status'],
];
@endphp
 
<april:data-table :data="$users" :columns="$columns" searchable selectable paginated>
<slot:cell-status>
<april:badge variant="secondary" x-text="row.status" />
</slot:cell-status>
 
<slot:actions>
<april:button size="sm" variant="ghost" x-text="`Edit ${row.name}`" />
</slot:actions>
</april:data-table>

Columns accept key, label, sortable, searchable, and align ( left, center, or right). Use a cell-{key} slot to render a custom cell; the Alpine row object is available in that slot. The original header/body slot composition remains available when you do not pass columns.

Controlled data

Pass pagination with mode: controlled when another system owns the query. April displays the supplied page and emits query-change; it does not assume Livewire, an API client, or a backend transport. Send a data-table:sync browser event with { id, data, pagination } to replace the visible page without remounting the component.

Livewire adapter

The optional Livewire adapter ships inside yungifez/april-ui; install it alongside Livewire with composer require yungifez/april-ui livewire/livewire. It adds the familiar builder() and columns() class pattern, owns the Eloquent query, pagination, URL state, and bridges to this controlled mode while the base April component remains usable without Livewire.

final class UsersTable extends DataTableComponent
{
protected function builder(): Builder
{
return User::query();
}
 
protected function columns(): array
{
return [
Column::make('Name', 'name')->searchable()->sortable(),
Column::make('Email', 'email')->searchable()->sortable(),
];
}
}

Render the adapter with <livewire:users-table />.

Publishing Views

Use the following commands to publish these views:

php artisan april:publish data-table
php artisan april:publish data-table-row
php artisan april:publish data-table-head
php artisan april:publish data-table-cell
April UI keeps package views in `vendor/` by default. The command uses Laravel's vendor publishing system and copies overrides to `resources/views/vendor/april/components`. To publish all components, run:
php artisan april:publish --all
Review local overrides after an upgrade with `php artisan april:update --diff`.