devaction-labs/livewire-filterable
Composer 安装命令:
composer require devaction-labs/livewire-filterable
包简介
A Laravel Livewire package for elegant, reactive model filtering with zero boilerplate
关键字:
README 文档
README
A Laravel Livewire package for elegant, reactive model filtering with zero boilerplate. No more manual when() clauses!
✨ Features
- 🎯 Zero Boilerplate - No manual
when()clauses needed - ⚡ Reactive - Filters update automatically with Livewire
- 🔥 Elegant API - Same simple syntax:
Filter::like('name') - 🚀 PHP 8.5+ - Uses cutting-edge PHP features
#[\NoDiscard]attribute on all fluent methods (30+ methods)- Pipe operator
|>for data transformation pipelines - Laravel 12's
#[Scope]attribute for cleaner scopes
- 📦 Laravel 11 & 12 - Full support
- 🎨 Livewire 4 - Built for the latest version
- 🔍 Full-Text Search - PostgreSQL native support with GIN indexes
- 🔗 Relationships - Filter with
whereAny,whereAll,whereNone - 📅 Smart Dates - Carbon integration with
startOfDay/endOfDay - 🗄️ JSON Fields - Database-agnostic JSON filtering
- 🎭 Type-Safe - Full PHP 8.5 type coverage
📦 Installation
composer require devaction-labs/livewire-filterable
Requirements:
- PHP 8.5+
- Laravel 11 or 12
- Livewire 4
Note: PHP 8.5 is currently available on Linux. macOS and Windows support will be available when PHP 8.5 stable builds are released for those platforms.
🚀 Quick Start
1. Add traits to your Model
namespace App\Models; use DevactionLabs\LivewireFilterable\Traits\Filterable; use DevactionLabs\LivewireFilterable\Concerns\HasCustomPagination; use Illuminate\Database\Eloquent\Model; class Customer extends Model { use Filterable; use HasCustomPagination; }
2. Create a Livewire Component
namespace App\Livewire; use App\Models\Customer; use DevactionLabs\LivewireFilterable\Concerns\LivewireFilterable; use DevactionLabs\LivewireFilterable\Filter; use Livewire\Component; class CustomerList extends Component { use LivewireFilterable; // Public properties = automatic filters! public string $name = ''; public string $legal_name = ''; public string $email = ''; public string $tax_id = ''; public string $tax_id_type = ''; public int $tenant_id = 0; public function render() { $customers = Customer::query() ->with('tenant') ->filterable([ // Same elegant API! Filter::ilike('name'), Filter::ilike('legal_name'), Filter::ilike('email'), Filter::ilike('tax_id'), Filter::exact('tax_id_type'), Filter::exact('tenant_id'), ]) ->orderBy('name') ->customPaginate(); return view('livewire.customer-list', compact('customers')); } }
3. Create the Blade View
<div> {{-- Filters automatically bind to public properties --}} <input wire:model.live="name" type="text" placeholder="Nome"> <input wire:model.live="legal_name" type="text" placeholder="Razão Social"> <input wire:model.live="email" type="text" placeholder="Email"> <input wire:model.live="tax_id" type="text" placeholder="CPF/CNPJ"> <select wire:model.live="tax_id_type"> <option value="">Tipo</option> <option value="cpf">CPF</option> <option value="cnpj">CNPJ</option> </select> {{-- Results --}} <div class="grid gap-4"> @foreach($customers as $customer) <div class="border p-4 rounded"> <h3>{{ $customer->name }}</h3> <p>{{ $customer->email }}</p> </div> @endforeach </div> {{ $customers->links() }} </div>
That's it! 🎉 No when() clauses, filters are applied automatically!
📚 Documentation
- 📘 How It Works - Understand how automatic property binding works
- 🚀 Laravel 12 & PHP 8.5 Features - Modern features used in the package
- 🔮 PHP 8.5 Full Features Example - Future implementation with all PHP 8.5 features
- 💡 Practical Examples - Real-world usage examples
🔄 Paginação
O pacote suporta 3 tipos de paginação:
// 1. Padrão (com total count) ->customPaginate('paginate', 15) // 2. Simples (sem total - mais rápido) ->customPaginate('simple', 20) // 3. Cursor (mais performático - ideal para datasets grandes) ->customPaginate('cursor', 25)
Controle dinâmico via Livewire:
class CustomerList extends Component { use LivewireFilterable; public string $name = ''; public int $perPage = 15; // ✅ Dinâmico! public function render() { $customers = Customer::query() ->filterable([Filter::ilike('name')]) ->customPaginate('cursor', $this->perPage); // ✅ Usa a propriedade } }
{{-- Usuário pode escolher --}} <select wire:model.live="perPage"> <option value="10">10 por página</option> <option value="25">25 por página</option> <option value="50">50 por página</option> <option value="100">100 por página</option> </select>
📖 Available Filters
Basic Comparison Filters
Filter::exact('status') // WHERE status = ? Filter::notEquals('status') // WHERE status != ? Filter::gt('amount') // WHERE amount > ? Filter::gte('amount') // WHERE amount >= ? Filter::lt('amount') // WHERE amount < ? Filter::lte('amount') // WHERE amount <= ? Filter::between('created_at') // WHERE created_at BETWEEN ? AND ?
Text Search Filters
Filter::like('name') // WHERE name LIKE %?% Filter::ilike('email') // Case-insensitive (database-specific) Filter::notLike('description') // WHERE description NOT LIKE %?% Filter::startsWith('sku') // WHERE sku LIKE ?% Filter::endsWith('domain') // WHERE domain LIKE %?
Full-Text Search
// PostgreSQL native with GIN index support Filter::fullText(['title', 'content'], 'search') ->setFullTextLanguage('portuguese') ->setFullTextPrefixMatch(true)
Array Filters
Filter::in('category_id') // WHERE category_id IN (?) Filter::notIn('status') // WHERE status NOT IN (?)
Null Filters
Filter::isNull('deleted_at') // WHERE deleted_at IS NULL Filter::isNotNull('verified_at') // WHERE verified_at IS NOT NULL
Relationship Filters
// Simple relationship Filter::relationship('category', 'slug', '=', 'category') ->with() // OR logic (whereAny) Filter::relationship('tags', 'name') ->whereAny([ ['name', '=', 'featured'], ['name', '=', 'sale'], ]) ->with() // AND logic (whereAll) Filter::relationship('permissions', 'name') ->whereAll([ ['name', '=', 'edit-posts'], ['is_active', '=', true], ]) ->with() // NOT logic (whereNone) Filter::relationship('tags', 'is_banned') ->whereNone([ ['is_banned', '=', true], ]) ->with()
JSON Field Filters
Filter::json('attributes', 'color', '=', 'color') ->setDatabaseDriver('pgsql') Filter::json('metadata', 'specs.weight', '>', 'min_weight') ->setDatabaseDriver('mysql')
🎯 Custom Property Names
If your Livewire property name differs from the database column:
public string $searchName = ''; public string $customerEmail = ''; // Second parameter = Livewire property name Filter::ilike('name', 'searchName') Filter::ilike('email', 'customerEmail')
📅 Date Handling
public string $created_date = ''; Filter::exact('created_at', 'created_date') ->castDate() ->endOfDay() // Sets time to 23:59:59
🔗 URL Persistence
Use Livewire's #[Url] attribute to persist filters in the URL:
use Livewire\Attributes\Url; class CustomerList extends Component { use LivewireFilterable; #[Url] public string $name = ''; #[Url] public string $email = ''; #[Url(as: 'type')] public string $tax_id_type = ''; }
Now filters appear in URL: ?name=john&email=test@&type=cpf
⏱️ Debouncing
Add debouncing to specific inputs in Blade:
<input wire:model.live.debounce.500ms="name" type="text">
Or programmatically:
Filter::like('name')->debounce(500) // 500ms
🧹 Clear Filters
public function clearFilters(): void { $this->reset(['name', 'email', 'tax_id']); }
In Blade:
<button wire:click="clearFilters">Limpar Filtros</button>
🎨 Complete Example
class ProductList extends Component { use LivewireFilterable; #[Url] public string $search = ''; #[Url] public array $price_range = []; #[Url] public ?string $category = null; #[Url] public array $tags = []; #[Url] public string $created_date = ''; public function render() { $products = Product::query() ->filterable([ // Full-text search Filter::fullText(['name', 'description'], 'search') ->setFullTextLanguage('portuguese'), // Price range Filter::between('price', 'price_range'), // Category relationship Filter::relationship('category', 'slug', '=', 'category') ->with(), // Tags with OR logic Filter::relationship('tags', 'name', 'IN', 'tags') ->with(), // Date filter Filter::exact('created_at', 'created_date') ->castDate() ->endOfDay(), ]) ->orderBy('created_at', 'desc') ->customPaginate('paginate', 20); return view('livewire.product-list', compact('products')); } public function clearFilters(): void { $this->reset(['search', 'price_range', 'category', 'tags', 'created_date']); } }
🗄️ Database-Specific Features
PostgreSQL Full-Text Search with GIN Index
// Migration Schema::table('products', function (Blueprint $table) { $table->tsvector('search_vector')->nullable(); }); DB::statement('CREATE INDEX products_search_idx ON products USING GIN(search_vector)'); // Update trigger DB::statement(" CREATE TRIGGER products_search_update BEFORE INSERT OR UPDATE ON products FOR EACH ROW EXECUTE FUNCTION tsvector_update_trigger(search_vector, 'pg_catalog.portuguese', name, description); "); // Filter Filter::fullText('search_vector', 'q') ->useTsVector() ->setDatabaseDriver('pgsql')
Performance: 5ms vs 500ms on 1M rows (100x faster!)
Case-Insensitive Search (ILIKE)
Automatically adapts to your database:
- PostgreSQL: Native
ILIKE - MySQL:
LOWER()function - SQLite: Standard
LIKE(case-insensitive by default)
Filter::ilike('email') // Works on all databases!
🧪 Testing
composer test
Run specific test suites:
composer test:unit composer test:types composer test:lint
📝 License
The MIT License (MIT). Please see License File for more information.
🤝 Contributing
Please see CONTRIBUTING.md for details.
🙏 Credits
Livewire Filterable - Elegant filtering for Laravel Livewire 🚀
devaction-labs/livewire-filterable 适用场景与选型建议
devaction-labs/livewire-filterable 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 656 次下载、GitHub Stars 达 0, 最近一次更新时间为 2026 年 01 月 27 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「search」 「pagination」 「filter」 「filterable」 「laravel」 「eloquent」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 devaction-labs/livewire-filterable 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 devaction-labs/livewire-filterable 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 devaction-labs/livewire-filterable 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
A Laravel package to retrieve data from Google Search Console
Nova searchable filter for belongsTo relationships.
Indexed Search Autocomplete - Extends the TYPO3 Core Extension Indexed_Search searchform with an autocomplete feature.
Abstraction Layer to index and search entities
Symfony DataGridBundle
Data provider for yii2
统计信息
- 总下载量: 656
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 44
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-01-27
