PHPackages                             devaction-labs/livewire-filterable - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. devaction-labs/livewire-filterable

ActiveLibrary[Database &amp; ORM](/categories/database)

devaction-labs/livewire-filterable
==================================

A Laravel Livewire package for elegant, reactive model filtering with zero boilerplate

v1.0.0.0(5mo ago)0656MITPHPPHP ^8.5.0CI passing

Since Jan 27Pushed 5mo agoCompare

[ Source](https://github.com/devaction-labs/FilterSearchLive)[ Packagist](https://packagist.org/packages/devaction-labs/livewire-filterable)[ RSS](/packages/devaction-labs-livewire-filterable/feed)WikiDiscussions master Synced today

READMEChangelog (1)Dependencies (13)Versions (2)Used By (0)

 [![Livewire Filterable](./docs/Livewire.png)](./docs/Livewire.png)

 [![GitHub Workflow Status](https://github.com/devaction-labs/livewire-filterable/actions/workflows/tests.yml/badge.svg)](https://github.com/devaction-labs/livewire-filterable/actions) [![Total Downloads](https://camo.githubusercontent.com/7a773138da480112e0ae32ed33eb815c704267116fe00430194fd846a92ad25e/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f646576616374696f6e2d6c6162732f6c697665776972652d66696c74657261626c65)](https://packagist.org/packages/devaction-labs/livewire-filterable) [![Latest Version](https://camo.githubusercontent.com/62a4f0f5c09ebf7d44bd0b0022f4fbcd07980829b6d0eca16d2197bd901f0b4d/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f646576616374696f6e2d6c6162732f6c697665776972652d66696c74657261626c65)](https://packagist.org/packages/devaction-labs/livewire-filterable) [![License](https://camo.githubusercontent.com/dd58d9d67989923537c0d717d572a3357c3bdbac9e355668adb28bac2bad92a4/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f646576616374696f6e2d6c6162732f6c697665776972652d66696c74657261626c65)](https://packagist.org/packages/devaction-labs/livewire-filterable)

---

A Laravel Livewire package for **elegant, reactive model filtering with zero boilerplate**. No more manual `when()` clauses!

✨ Features
----------

[](#-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 &amp; 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
--------------

[](#-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
-------------

[](#-quick-start)

### 1. Add traits to your Model

[](#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

[](#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

[](#3-create-the-blade-view)

```

    {{-- Filters automatically bind to public properties --}}

        Tipo
        CPF
        CNPJ

    {{-- Results --}}

        @foreach($customers as $customer)

                {{ $customer->name }}
                {{ $customer->email }}

        @endforeach

    {{ $customers->links() }}

```

**That's it! 🎉** No `when()` clauses, filters are applied automatically!

📚 Documentation
---------------

[](#-documentation)

- **[📘 How It Works](docs/HOW_IT_WORKS.md)** - Understand how automatic property binding works
- **[🚀 Laravel 12 &amp; PHP 8.5 Features](docs/LARAVEL12_PHP85_FEATURES.md)** - Modern features used in the package
- **[🔮 PHP 8.5 Full Features Example](docs/PHP85_FULL_FEATURES_EXAMPLE.md)** - Future implementation with all PHP 8.5 features
- **[💡 Practical Examples](EXAMPLES.md)** - Real-world usage examples

🔄 Paginação
-----------

[](#-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 --}}

    10 por página
    25 por página
    50 por página
    100 por página

```

**[Ver mais sobre paginação →](docs/HOW_IT_WORKS.md#-pagina%C3%A7%C3%A3o-customizada)**

📖 Available Filters
-------------------

[](#-available-filters)

### Basic Comparison 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 setFullTextLanguage('portuguese')
    ->setFullTextPrefixMatch(true)
```

### Array Filters

[](#array-filters)

```
Filter::in('category_id')            // WHERE category_id IN (?)
Filter::notIn('status')              // WHERE status NOT IN (?)
```

### Null Filters

[](#null-filters)

```
Filter::isNull('deleted_at')         // WHERE deleted_at IS NULL
Filter::isNotNull('verified_at')     // WHERE verified_at IS NOT NULL
```

### Relationship Filters

[](#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

[](#json-field-filters)

```
Filter::json('attributes', 'color', '=', 'color')
    ->setDatabaseDriver('pgsql')

Filter::json('metadata', 'specs.weight', '>', 'min_weight')
    ->setDatabaseDriver('mysql')
```

🎯 Custom Property Names
-----------------------

[](#-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
---------------

[](#-date-handling)

```
public string $created_date = '';

Filter::exact('created_at', 'created_date')
    ->castDate()
    ->endOfDay()  // Sets time to 23:59:59
```

🔗 URL Persistence
-----------------

[](#-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
-------------

[](#️-debouncing)

Add debouncing to specific inputs in Blade:

```

```

Or programmatically:

```
Filter::like('name')->debounce(500)  // 500ms
```

🧹 Clear Filters
---------------

[](#-clear-filters)

```
public function clearFilters(): void
{
    $this->reset(['name', 'email', 'tax_id']);
}
```

In Blade:

```
Limpar Filtros
```

🎨 Complete Example
------------------

[](#-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
-----------------------------

[](#️-database-specific-features)

### PostgreSQL Full-Text Search with GIN Index

[](#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)

[](#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
---------

[](#-testing)

```
composer test
```

Run specific test suites:

```
composer test:unit
composer test:types
composer test:lint
```

📝 License
---------

[](#-license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

🤝 Contributing
--------------

[](#-contributing)

Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details.

🙏 Credits
---------

[](#-credits)

- [DevAction Labs](https://github.com/devaction-labs)
- [Alex Nogueira](https://github.com/alexnogueirasilva)

---

**Livewire Filterable** - Elegant filtering for Laravel Livewire 🚀

###  Health Score

38

—

LowBetter than 83% of packages

Maintenance72

Regular maintenance activity

Popularity13

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity52

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

157d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/b118fca24c478a6378ac5ec98bc4124c345fa6e398367665d121ca6f7bfe8a84?d=identicon)[alexnogueirasilva](/maintainers/alexnogueirasilva)

---

Top Contributors

[![alexnogueirasilva](https://avatars.githubusercontent.com/u/29835529?v=4)](https://github.com/alexnogueirasilva "alexnogueirasilva (14 commits)")

---

Tags

searchlaravelpaginationeloquentfilterlivewirequery builderphp85reactivefilterable

###  Code Quality

TestsPest

Static AnalysisPHPStan, Rector

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/devaction-labs-livewire-filterable/health.svg)

```
[![Health](https://phpackages.com/badges/devaction-labs-livewire-filterable/health.svg)](https://phpackages.com/packages/devaction-labs-livewire-filterable)
```

###  Alternatives

[mongodb/laravel-mongodb

A MongoDB based Eloquent model and Query builder for Laravel

7.1k8.4M96](/packages/mongodb-laravel-mongodb)[tucker-eric/eloquentfilter

An Eloquent way to filter Eloquent Models

1.8k5.1M34](/packages/tucker-eric-eloquentfilter)[psalm/plugin-laravel

Psalm plugin for Laravel

3355.3M345](/packages/psalm-plugin-laravel)[yajra/laravel-oci8

Oracle DB driver for Laravel via OCI8

8793.2M25](/packages/yajra-laravel-oci8)[glushkovds/phpclickhouse-laravel

Adapter of the most popular library https://github.com/smi2/phpClickHouse to Laravel

2051.5M2](/packages/glushkovds-phpclickhouse-laravel)[mohammad-fouladgar/eloquent-builder

526198.2k](/packages/mohammad-fouladgar-eloquent-builder)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
