- Overview
- Installation
- Required Methods
- Filter Types
- Provided Properties
- Provided Methods
- Blade Integration
- Examples
- Live Demo
- Accessibility
Pro Component — This trait requires an Aura UI Pro license.
Overview
The WithAuraFilters trait adds a comprehensive filtering system to any Livewire component. It manages filter state, provides active filter badge display, and integrates with the <x-aura::data-table> component. Supports multiple filter types including select dropdowns, date ranges, booleans, and text search. Filters are applied to your Eloquent query automatically.
Installation
Add the trait to your Livewire component:
use BlueStarSystem\AuraUIPro\Traits\WithAuraFilters;
use Livewire\Component;
class ProductCatalog extends Component
{
use WithAuraFilters;
// ...
}
Required Methods
filters(): array
Define the available filters. Each filter is an associative array describing its type, label, and options.
public function filters(): array
{
return [
[
'key' => 'status',
'label' => 'Status',
'type' => 'select',
'options' => [
'' => 'All Statuses',
'active' => 'Active',
'inactive' => 'Inactive',
'pending' => 'Pending',
],
],
[
'key' => 'created_at',
'label' => 'Created Date',
'type' => 'date-range',
],
[
'key' => 'featured',
'label' => 'Featured Only',
'type' => 'boolean',
],
[
'key' => 'search',
'label' => 'Search',
'type' => 'search',
'placeholder' => 'Search by name...',
],
];
}
Filter Types
Select
Renders a dropdown with predefined options.
[
'key' => 'category',
'label' => 'Category',
'type' => 'select',
'options' => [
'' => 'All Categories',
'electronics' => 'Electronics',
'clothing' => 'Clothing',
'books' => 'Books',
],
]
Date Range
Renders two date inputs (from and to) for filtering a date column.
[
'key' => 'created_at',
'label' => 'Date Range',
'type' => 'date-range',
]
The trait stores date range values as $filterValues['created_at_from'] and $filterValues['created_at_to'].
Boolean
Renders a toggle/checkbox for true/false filtering.
[
'key' => 'is_active',
'label' => 'Active Only',
'type' => 'boolean',
]
Search
Renders a text input for partial-match filtering on a specific field.
[
'key' => 'name_search',
'label' => 'Name',
'type' => 'search',
'placeholder' => 'Search by name...',
'column' => 'name', // Database column to search against
]
Provided Properties
| Property | Type | Default | Description |
|---|---|---|---|
filterValues |
array |
[] |
Current filter values keyed by filter key. |
showFilters |
bool |
false |
Whether the filter sidebar/panel is visible. |
Provided Methods
| Method | Description |
|---|---|
toggleFilters() |
Show or hide the filter panel. |
applyFilter(string $key, mixed $value) |
Set a filter value programmatically. |
resetFilter(string $key) |
Reset a single filter to its default value. |
resetAllFilters() |
Reset all filters to their default values. |
getActiveFilters(): array |
Returns array of currently active filters with their labels and values. |
applyFiltersToQuery(Builder $query): Builder |
Apply all active filters to an Eloquent query. |
Blade Integration
The filter UI is rendered via dedicated Blade directives within your component view:
<!-- resources/views/livewire/product-catalog.blade.php -->
<div>
<div class="mb-4 flex items-center justify-between">
<h1 class="text-xl font-bold">Products</h1>
<x-aura::button variant="ghost" wire:click="toggleFilters" size="sm">
<x-aura::icon name="funnel" class="h-4 w-4 mr-1" />
Filters
@if(count($this->getActiveFilters()) > 0)
<x-aura::badge size="sm" variant="primary" class="ml-1">
{{ count($this->getActiveFilters()) }}
</x-aura::badge>
@endif
</x-aura::button>
</div>
{{-- Active filter badges --}}
@if(count($this->getActiveFilters()) > 0)
<div class="mb-4 flex flex-wrap gap-2">
@foreach($this->getActiveFilters() as $filter)
<x-aura::badge variant="info" size="sm">
{{ $filter['label'] }}: {{ $filter['displayValue'] }}
<button wire:click="resetFilter('{{ $filter['key'] }}')" class="ml-1">
<x-aura::icon name="x-mark" class="h-3 w-3" />
</button>
</x-aura::badge>
@endforeach
<button wire:click="resetAllFilters" class="text-sm text-gray-500 hover:text-gray-700">
Clear all
</button>
</div>
@endif
{{-- Filter sidebar --}}
@if($showFilters)
<div class="mb-6 rounded-lg border bg-white p-4 shadow-sm">
<div class="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4">
@foreach($this->filters() as $filter)
@if($filter['type'] === 'select')
<x-aura::select
:label="$filter['label']"
:options="$filter['options']"
wire:model.live="filterValues.{{ $filter['key'] }}"
/>
@elseif($filter['type'] === 'boolean')
<x-aura::toggle
:label="$filter['label']"
wire:model.live="filterValues.{{ $filter['key'] }}"
/>
@elseif($filter['type'] === 'search')
<x-aura::input
:label="$filter['label']"
:placeholder="$filter['placeholder'] ?? 'Search...'"
wire:model.live.debounce.300ms="filterValues.{{ $filter['key'] }}"
/>
@elseif($filter['type'] === 'date-range')
<div class="col-span-2 grid grid-cols-2 gap-2">
<x-aura::date-picker
label="{{ $filter['label'] }} From"
wire:model.live="filterValues.{{ $filter['key'] }}_from"
/>
<x-aura::date-picker
label="{{ $filter['label'] }} To"
wire:model.live="filterValues.{{ $filter['key'] }}_to"
/>
</div>
@endif
@endforeach
</div>
</div>
@endif
{{-- Table content --}}
<x-aura::data-table :columns="$this->columns()" :rows="$this->getRows()">
{{-- Row rendering --}}
</x-aura::data-table>
</div>
Examples
Product Catalog Filters
<?php
namespace App\Livewire;
use App\Models\Product;
use BlueStarSystem\AuraUIPro\Traits\WithAuraDataTable;
use BlueStarSystem\AuraUIPro\Traits\WithAuraFilters;
use Livewire\Component;
class ProductCatalog extends Component
{
use WithAuraDataTable;
use WithAuraFilters;
public function columns(): array
{
return [
['key' => 'name', 'label' => 'Product', 'sortable' => true, 'searchable' => true],
['key' => 'category', 'label' => 'Category', 'sortable' => true],
['key' => 'price', 'label' => 'Price', 'sortable' => true, 'format' => 'currency'],
['key' => 'stock', 'label' => 'Stock', 'sortable' => true],
['key' => 'status', 'label' => 'Status', 'sortable' => true],
];
}
public function filters(): array
{
return [
[
'key' => 'category',
'label' => 'Category',
'type' => 'select',
'options' => [
'' => 'All Categories',
...Category::pluck('name', 'slug')->toArray(),
],
],
[
'key' => 'status',
'label' => 'Status',
'type' => 'select',
'options' => [
'' => 'All',
'active' => 'Active',
'draft' => 'Draft',
'archived' => 'Archived',
],
],
[
'key' => 'in_stock',
'label' => 'In Stock Only',
'type' => 'boolean',
],
[
'key' => 'created_at',
'label' => 'Created',
'type' => 'date-range',
],
];
}
public function query(): \Illuminate\Database\Eloquent\Builder
{
$query = Product::query();
// Apply all filters at once
return $this->applyFiltersToQuery($query);
}
public function render()
{
return view('livewire.product-catalog');
}
}
Custom Filter Application
If you need custom logic for specific filters, override how they are applied:
public function query(): \Illuminate\Database\Eloquent\Builder
{
$query = Product::query()->with('category');
// Apply standard filters
$query = $this->applyFiltersToQuery($query);
// Custom filter logic
if (!empty($this->filterValues['price_min'])) {
$query->where('price', '>=', $this->filterValues['price_min']);
}
if (!empty($this->filterValues['price_max'])) {
$query->where('price', '<=', $this->filterValues['price_max']);
}
return $query;
}
Combining with WithAuraDataTable
The traits are designed to work together. When combined, the filter values automatically integrate with the data table's query pipeline:
class OrderManager extends Component
{
use WithAuraDataTable;
use WithAuraFilters;
public function columns(): array
{
return [
['key' => 'number', 'label' => 'Order #', 'sortable' => true],
['key' => 'customer', 'label' => 'Customer', 'sortable' => true],
['key' => 'total', 'label' => 'Total', 'sortable' => true],
['key' => 'status', 'label' => 'Status', 'sortable' => true],
];
}
public function filters(): array
{
return [
['key' => 'status', 'label' => 'Status', 'type' => 'select', 'options' => [
'' => 'All', 'pending' => 'Pending', 'processing' => 'Processing',
'shipped' => 'Shipped', 'delivered' => 'Delivered',
]],
['key' => 'created_at', 'label' => 'Order Date', 'type' => 'date-range'],
];
}
public function query(): \Illuminate\Database\Eloquent\Builder
{
return $this->applyFiltersToQuery(Order::query()->with('customer'));
}
}
Live Demo
| 27" Monitor Stand | Electronics | $45.00 | 73 | Active |
| Bamboo Cutting Board | Home | $22.00 | 168 | Active |
| Bath Towel Set | Home | $34.99 | 110 | Active |
| Bluetooth Speaker | Electronics | $42.99 | 165 | Active |
| Canvas Sneakers | Clothing | $44.50 | 156 | Active |
| Cargo Pants | Clothing | $54.99 | 88 | Active |
| Ceramic Vase | Home | $32.99 | 67 | Active |
| Clean Code | Books | $39.99 | 340 | Active |
| Cotton T-Shirt | Clothing | $24.99 | 500 | Draft |
| Cycling Gloves | Sports | $22.50 | 155 | Active |
Accessibility
- The filter toggle button includes an
aria-expandedattribute reflecting the panel visibility. - Filter inputs use standard Aura UI form components which provide proper label associations.
- Active filter badges include remove buttons with
aria-label="Remove [filter name] filter". - The "Clear all" button has
aria-label="Clear all active filters". - Filter changes trigger an
aria-live="polite"announcement of the updated result count. - The filter panel is focusable and can be closed with Escape when implemented as a slide-over.
- Date range inputs are properly labeled as "From" and "To" for screen readers.