- Accordion
- Alert
- Alert Dialog
- Aspect Ratio
- Attachment
- Avatar
- Badge
- Banner
- Breadcrumb
- Bubble
- Button
- Button Group
- Calendar
- Card
- Carousel
- Chart
- Checkbox
- Command
- Collapsible
- Combobox
- Context Menu
- Data Table
- Date Picker
- Dialog
- Dropdown Menu
- Editor
- Input
- Input Group
- Label
- Loading Spinner
- Native Select
- Popover
- Select
- Separator
- Sheet
- Sidebar
- Skeleton
- Slider
- Steps
- Switch
- Tabs
- Textarea
- Tooltip
Data Table
A client-side Alpine data table with sorting, search, selection, pagination, and custom cells.
| Status | Actions | ||||
|---|---|---|---|---|---|
| No results found. |
– of rows
@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>
@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
php artisan april:publish data-table-row
php artisan april:publish data-table-row
php artisan april:publish data-table-head
php artisan april:publish data-table-head
php artisan april:publish data-table-cell
php artisan april:publish data-table-cell
php artisan april:publish --all
php artisan april:publish --all