Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Filament Header Filters Laravel Package

leek/filament-header-filters

Add inline filters to Filament table column headers. Attach any BaseFilter (selects, date pickers, min/max ranges, custom schemas) as a richer alternative to individual searchable fields. Works with Filament v4/v5, PHP 8.2+.

View on GitHub
Deep Wiki
Context7

Filament Header Filters

Inline header filters for Filament tables. Attach any BaseFilter to a column header — select dropdowns, date pickers, min/max ranges, custom multi-field schemas — as a richer alternative to searchable(isIndividual: true).

Screenshot

Header filters in action

Requirements

  • PHP 8.2+
  • Filament v4.x or v5.x

Installation

composer require leek/filament-header-filters

Add the HasHeaderFilters trait to any Livewire component that uses InteractsWithTable (resource list pages, custom Livewire table components):

use Filament\Resources\Pages\ListRecords;
use Leek\FilamentHeaderFilters\Concerns\HasHeaderFilters;

class ListOrders extends ListRecords
{
    use HasHeaderFilters;
}

Styles

Add the package stylesheet to the panel theme configured with ->viteTheme(...). Place it after Filament's theme import so it can adjust the table and header filter styles:

@import '../../../../vendor/filament/filament/resources/css/theme.css';
@import '../../../../vendor/leek/filament-header-filters/resources/css/filament-header-filters.css';

Then rebuild your app assets:

npm run build

If you are using Vite locally, restart or keep running:

npm run dev

Usage

Call ->headerFilter() on any column and pass a filter instance.

Dropdown filter

Use SelectFilter for exact-match column filtering. The default placeholder is "All".

use App\Enums\OrderStatus;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Filters\SelectFilter;

TextColumn::make('status')
    ->badge()
    ->headerFilter(
        SelectFilter::make('status')
            ->options(OrderStatus::class)
            ->native(false)
    )

Min/max range filter

Use a custom Filter with two TextInput fields and ->columns(2) for a side-by-side numeric range:

use Filament\Forms\Components\TextInput;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Filters\Filter;
use Illuminate\Database\Eloquent\Builder;

TextColumn::make('total_price')
    ->headerFilter(
        Filter::make('total_price_range')
            ->columns(2)
            ->schema([
                TextInput::make('min')->numeric()->placeholder('Min'),
                TextInput::make('max')->numeric()->placeholder('Max'),
            ])
            ->query(fn (Builder $query, array $data): Builder => $query
                ->when($data['min'] ?? null, fn (Builder $q, $v): Builder => $q->where('total_price', '>=', $v))
                ->when($data['max'] ?? null, fn (Builder $q, $v): Builder => $q->where('total_price', '<=', $v))
            )
    )

Date range filter

Use DatePicker fields for a two-date range:

use Filament\Forms\Components\DatePicker;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Filters\Filter;
use Illuminate\Database\Eloquent\Builder;

TextColumn::make('created_at')
    ->label('Order date')
    ->date()
    ->headerFilter(
        Filter::make('order_date_range')
            ->columns(2)
            ->schema([
                DatePicker::make('from')->placeholder('From')->native(false),
                DatePicker::make('until')->placeholder('Until')->native(false),
            ])
            ->query(fn (Builder $query, array $data): Builder => $query
                ->when($data['from'] ?? null, fn (Builder $q, $v): Builder => $q->whereDate('created_at', '>=', $v))
                ->when($data['until'] ?? null, fn (Builder $q, $v): Builder => $q->whereDate('created_at', '<=', $v))
            )
    )

Behavior

  • Header filters share state with panel filters ($tableFilters). Filter indicators, reset, and session persistence all work.
  • Header filters are always live — they apply immediately on change, regardless of deferFilters().
  • Field labels inside header filters are auto-hidden; the column header acts as the label.
  • Hidden columns' header filters are not applied to the query.

Tips

Hide the filters button when only using header filters

If a table has only header filters and no panel filters, hide the filters dropdown so the button doesn't render empty:

use Filament\Tables\Enums\FiltersLayout;

public function table(Table $table): Table
{
    return $table
        ->filtersLayout(FiltersLayout::Hidden)
        ->columns([
            TextColumn::make('status')->headerFilter(/* ... */),
            // ...
        ]);
}

Filacheck false positive

Filacheck's missing-table-filters rule doesn't recognize ->headerFilter() and will flag tables that only use header filters. Publish the config and disable the rule:

php artisan vendor:publish --tag=filacheck-config
// config/filacheck.php
'missing-table-filters' => [
    'enabled' => false,
],

How it works

The package ships:

  • Column::macro('headerFilter', ...), getHeaderFilter(), hasHeaderFilter()
  • BaseFilter::macro('columnName', ...), getColumnName(), isHeaderFilter()
  • Table::macro('getHeaderFilters', ...), hasHeaderFilters()
  • A HasHeaderFilters Livewire trait that wires filters into the table, seeds header filter state, and exposes getTableHeaderFiltersForm()
  • A view override (filament-tables::index) that renders the header filter row under the column search row
  • A small CSS file raising the z-index and lifting overflow clipping so dropdown / date picker popups escape the table container

The view override is a patched copy of Filament's table view. If you upgrade Filament and something breaks, please open an issue.

Testing

composer test

License

MIT. See LICENSE.md.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
daikazu/eloquent-salesforce-objects
unseen-codes/chat
romalytar/yammi-jobs-monitoring-laravel
kisame76/filament-db-table-state
nqxcode/laravel-lucene-search
dpfx/laravel-livewire-wizards
workos/workos-php-laravel
sofa/laravel-global-scope
nawasara/auth-primitives
adhocrat-io/arkhe-main
make-dev/orca-harpoon
itsemon245/lamet
baks-dev/dashboard
amoifr/pickle-panther-bundle
make-dev/orca
dmstr/symfony-system-resources-bundle
dmstr/symfony-job-queue-bundle
dmstr/openapi-json-schema-bundle
dmstr/keycloak-security-bundle
dmstr/doctrine-audit-log-bundle