- Overview
- Installation
- Required Methods
- Provided Properties
- Provided Methods
- Blade Integration
- Examples
- Live Demo
- Accessibility
Pro Component — This trait requires an Aura UI Pro license.
Overview
The WithAuraBulkActions trait adds multi-row selection and bulk operations to Livewire data table components. It provides individual row checkboxes, a "select all" toggle (including across pages), and a dropdown of configurable bulk actions. Designed to work alongside WithAuraDataTable and the <x-aura::data-table> Blade component.
Installation
Add the trait to your Livewire component:
use BlueStarSystem\AuraUIPro\Traits\WithAuraBulkActions;
use Livewire\Component;
class UserTable extends Component
{
use WithAuraBulkActions;
// ...
}
Required Methods
bulkActions(): array
Define the available bulk actions. Each action is an associative array with a key, label, and optional confirmation settings.
public function bulkActions(): array
{
return [
[
'key' => 'delete',
'label' => 'Delete Selected',
'confirm' => true, // Show confirmation dialog before executing
'confirmMessage' => 'Are you sure you want to delete the selected records?',
'variant' => 'danger', // Confirmation dialog variant
],
[
'key' => 'export',
'label' => 'Export to CSV',
'confirm' => false,
],
[
'key' => 'activate',
'label' => 'Activate',
'confirm' => false,
],
[
'key' => 'deactivate',
'label' => 'Deactivate',
'confirm' => true,
'confirmMessage' => 'Deactivate selected users?',
'variant' => 'warning',
],
];
}
You must also implement a handler method for each action key:
public function bulkDelete(): void
{
User::whereIn('id', $this->selected)->delete();
$this->clearSelection();
$this->dispatch('toast', type: 'success', message: count($this->selected) . ' users deleted.');
}
public function bulkExport(): void
{
// Generate and download CSV
return $this->exportCsv(User::whereIn('id', $this->selected)->get());
}
public function bulkActivate(): void
{
User::whereIn('id', $this->selected)->update(['is_active' => true]);
$this->clearSelection();
$this->dispatch('toast', type: 'success', message: 'Users activated.');
}
The trait calls the method named bulk + PascalCase of the action key (e.g., delete calls bulkDelete, export calls bulkExport).
Provided Properties
| Property | Type | Default | Description |
|---|---|---|---|
selected |
array |
[] |
Array of selected row IDs. |
selectAll |
bool |
false |
Whether all rows on the current page are selected. |
selectAllPages |
bool |
false |
Whether all rows across all pages are selected. |
Provided Methods
| Method | Description |
|---|---|
toggleSelectAll() |
Toggle selection of all rows on the current page. |
selectAllRecords() |
Select all records across all pages. |
clearSelection() |
Deselect all rows and reset selection state. |
toggleRow(mixed $id) |
Toggle selection of a single row by ID. |
getSelectedCount(): int |
Returns the count of selected rows. |
executeBulkAction(string $key) |
Trigger a bulk action by its key. Handles confirmation if configured. |
Blade Integration
The trait works with <x-aura::data-table> which renders the selection UI automatically. Here is the full Blade pattern:
<!-- resources/views/livewire/user-table.blade.php -->
<div>
{{-- Bulk action bar (appears when rows are selected) --}}
@if(count($selected) > 0)
<div class="mb-4 flex items-center gap-4 rounded-lg bg-indigo-50 px-4 py-3">
<span class="text-sm font-medium text-indigo-700">
{{ $this->getSelectedCount() }} selected
</span>
<div class="flex gap-2">
@foreach($this->bulkActions() as $action)
<x-aura::button
size="sm"
:variant="($action['variant'] ?? 'default') === 'danger' ? 'danger' : 'ghost'"
wire:click="executeBulkAction('{{ $action['key'] }}')"
>
{{ $action['label'] }}
</x-aura::button>
@endforeach
</div>
<button wire:click="clearSelection" class="ml-auto text-sm text-gray-500 hover:text-gray-700">
Clear selection
</button>
</div>
@endif
<x-aura::data-table :columns="$this->columns()" :rows="$this->getRows()">
<x-slot:header>
<th class="w-10 px-4 py-3">
<input
type="checkbox"
wire:model.live="selectAll"
class="rounded border-gray-300"
/>
</th>
</x-slot:header>
@foreach($this->getRows() as $user)
<tr wire:key="user-{{ $user->id }}">
<td class="px-4 py-3">
<input
type="checkbox"
value="{{ $user->id }}"
wire:model.live="selected"
class="rounded border-gray-300"
/>
</td>
<td class="px-4 py-3">{{ $user->name }}</td>
<td class="px-4 py-3">{{ $user->email }}</td>
<td class="px-4 py-3">{{ $user->role }}</td>
</tr>
@endforeach
</x-aura::data-table>
{{-- Select all pages notice --}}
@if($selectAll && !$selectAllPages)
<div class="mt-2 text-center text-sm text-gray-500">
All {{ count($this->getRows()) }} records on this page are selected.
<button wire:click="selectAllRecords" class="font-medium text-indigo-600 hover:underline">
Select all {{ $this->getRows()->total() }} records
</button>
</div>
@endif
</div>
Examples
User Management with Bulk Actions
<?php
namespace App\Livewire;
use App\Models\User;
use BlueStarSystem\AuraUIPro\Traits\WithAuraBulkActions;
use BlueStarSystem\AuraUIPro\Traits\WithAuraDataTable;
use Livewire\Component;
class UserTable extends Component
{
use WithAuraDataTable;
use WithAuraBulkActions;
public function columns(): array
{
return [
['key' => 'name', 'label' => 'Name', 'sortable' => true, 'searchable' => true],
['key' => 'email', 'label' => 'Email', 'sortable' => true, 'searchable' => true],
['key' => 'role', 'label' => 'Role', 'sortable' => true],
];
}
public function query(): \Illuminate\Database\Eloquent\Builder
{
return User::query();
}
public function bulkActions(): array
{
return [
[
'key' => 'delete',
'label' => 'Delete',
'confirm' => true,
'confirmMessage' => 'Permanently delete the selected users?',
'variant' => 'danger',
],
[
'key' => 'export',
'label' => 'Export CSV',
'confirm' => false,
],
];
}
public function bulkDelete(): void
{
$count = count($this->selected);
User::whereIn('id', $this->selected)->delete();
$this->clearSelection();
$this->dispatch('toast', type: 'success', message: "{$count} users deleted.");
}
public function bulkExport(): void
{
$users = User::whereIn('id', $this->selected)->get();
// ... generate CSV and return download response
$this->clearSelection();
$this->dispatch('toast', type: 'info', message: 'Export started.');
}
public function render()
{
return view('livewire.user-table');
}
}
Order Management with Status Updates
class OrderTable extends Component
{
use WithAuraDataTable;
use WithAuraBulkActions;
public function bulkActions(): array
{
return [
['key' => 'mark-shipped', 'label' => 'Mark as Shipped', 'confirm' => true,
'confirmMessage' => 'Mark selected orders as shipped?', 'variant' => 'info'],
['key' => 'mark-delivered', 'label' => 'Mark as Delivered', 'confirm' => false],
['key' => 'cancel', 'label' => 'Cancel Orders', 'confirm' => true,
'confirmMessage' => 'Cancel the selected orders? This cannot be undone.', 'variant' => 'danger'],
];
}
public function bulkMarkShipped(): void
{
Order::whereIn('id', $this->selected)
->where('status', 'processing')
->update(['status' => 'shipped', 'shipped_at' => now()]);
$this->clearSelection();
$this->dispatch('toast', type: 'success', message: 'Orders marked as shipped.');
}
public function bulkMarkDelivered(): void
{
Order::whereIn('id', $this->selected)
->where('status', 'shipped')
->update(['status' => 'delivered', 'delivered_at' => now()]);
$this->clearSelection();
$this->dispatch('toast', type: 'success', message: 'Orders marked as delivered.');
}
public function bulkCancel(): void
{
$count = Order::whereIn('id', $this->selected)
->whereNotIn('status', ['shipped', 'delivered'])
->update(['status' => 'cancelled']);
$this->clearSelection();
$this->dispatch('toast', type: 'success', message: "{$count} orders cancelled.");
}
}
Combining All Three Traits
class InvoiceTable extends Component
{
use WithAuraDataTable;
use WithAuraFilters;
use WithAuraBulkActions;
// All three traits work together seamlessly.
// Filters narrow down the results.
// Data table handles sorting, search, pagination.
// Bulk actions operate on selected rows.
}
Live Demo
| 27" Monitor Stand | Electronics | $45.00 | Active | |
| Bamboo Cutting Board | Home | $22.00 | Active | |
| Bath Towel Set | Home | $34.99 | Active | |
| Bluetooth Speaker | Electronics | $42.99 | Active | |
| Canvas Sneakers | Clothing | $44.50 | Active | |
| Cargo Pants | Clothing | $54.99 | Active | |
| Ceramic Vase | Home | $32.99 | Active | |
| Clean Code | Books | $39.99 | Active | |
| Cotton T-Shirt | Clothing | $24.99 | Draft | |
| Cycling Gloves | Sports | $22.50 | Active |
Accessibility
- The "select all" checkbox in the header has
aria-label="Select all rows on this page". - Individual row checkboxes have
aria-label="Select row [identifier]". - The bulk action bar uses
role="toolbar"witharia-label="Bulk actions". - Action buttons within the bar have descriptive labels.
- The "select all pages" link is focusable and announced by screen readers.
- The selected count is announced via
aria-live="polite"when the selection changes. - Confirmation dialogs triggered by bulk actions follow the same accessibility patterns as
<x-aura::confirmation-dialog>. - The "Clear selection" button has
aria-label="Clear all selected rows".