zvizvi/filament-column-filters
Excel-style column header filters for Filament tables: add search, date range, select, and numeric range popups to any column, backed by real Filament filters with sync support and RTL.
Architecture fit
The package is a thin presentation layer over Filament's existing table-filter subsystem rather than a parallel filtering engine. That is the right architectural bet: every header filter is backed by a "real" Filament filter, so it inherits query scoping, filter indicators, and reset behaviour, and it participates in the same state container as the standard filters dropdown. The syncWith() mechanism is the most strategically important feature — it means header filters are not a competing source of truth but a second view onto an existing filter, which keeps saved views, bookmarks, and programmatic filter state coherent.
For a Filament-based admin panel this is close to zero-architecture-change adoption: no new persistence layer, no schema, no service contracts. It is a per-table plugin registration plus per-column configuration.
Integration feasibility
High in the narrow case, unknown in the general case. The install path is a single composer require, plugin registration on each table/panel, and declarative per-column wiring (search, date, select, range). There is no data migration and no backfill. The blocking unknowns are version compatibility and whether the header injection relies on public Filament extension points or on internal view/component hooks.
Technical risk
LIKE %term% unless documented otherwise — fine for admin-sized datasets, a latent performance problem for large tables. "Range" with two number inputs implies numeric typing that needs verification against string/decimal columns.Key questions
composer.json constraint that will conflict with our pinned version?filament-tables::...)? The answer determines fork cost.$tableFilters Livewire property such that saved views and getTableFiltersForm-based code keep working?Stack fit
Best fit is a Laravel application already on Filament for internal/admin tooling, with the table layer as the primary data-interaction surface. It is a poor fit for public-facing or customer-portal tables where the Excel metaphor and header-icon affordance are unfamiliar, and for any table where filters must be embedded in shareable URLs.
Migration path
Purely additive and reversible. No database work, no API changes. Because filters are opt-in per column, rollout can be incremental and feature-flagged at the table level — register the plugin, wire one or two columns, ship, observe. Rollback is removing the plugin registration; the underlying Filament filters remain intact, which is a genuinely low-cost escape hatch.
Compatibility
Validate three things before committing: (a) composer require resolves cleanly against the pinned filament/filament and PHP versions; (b) the package's frontend assets are pre-built and published (no Node build step in our pipeline, and no Tailwind purge conflicts with our custom panel theme); (c) dark mode and our panel's RTL locale render correctly. If we maintain a custom Filament theme, check that header markup changes do not break our CSS overrides.
Sequencing
syncWith() against an existing filter. Confirm state synchronisation both directions and that saved/view state still resolves.syncWith() wherever a canonical filter already exists so we do not fork filter semantics across two UIs.repositories VCS entry pinned to a commit) so an upstream abandonment does not block a Filament upgrade.Maintenance
The realistic maintenance model is "we own a fork we did not write." Budget a small recurring cost: one engineer tracking Filament releases, re-running the smoke test on each upgrade, and patching view hooks when Filament's table header internals move. The codebase is small enough (a handful of filter classes and one popup component) that forking is viable — that is the main argument in favour of adoption despite the low maturity score. Pin to an exact version, never a floating constraint.
Support
No commercial support, no SLA, single maintainer, 21 stars. Issue response is best-effort and should not be on any critical path. Internally, assign an explicit owner for the fork; without one this becomes orphaned code that everyone is afraid to upgrade.
Scaling
Filtering is query-level, so correctness scales; performance does not scale automatically. Specific pressure points: leading-wildcard LIKE search on large tables (unindexed full scan per keystroke if the popup is live/deferred-filtering), select option queries for high-cardinality relations, and the size of the Livewire filter-state payload if many columns are wired simultaneously. Each wired column adds an entry to $tableFilters, which is serialised into the Livewire snapshot on every request — wire columns deliberately, not exhaustively. Also confirm whether search triggers a network round-trip per keystroke or on submit; per-keystroke is a real load multiplier in a multi-tenant panel.
Failure modes
syncWith() drift — a filter's schema (e.g. becomes a range instead of a scalar) changes upstream and the header popup silently writes the wrong shape, producing filters that appear active but return wrong rows. Silent wrong-result bugs are the worst category here; add assertions or an integration test per synced filter.range — numeric inputs against string/decimal/currency columns returning unexpected rows at boundaries.Ramp-up
Developer ramp-up is low: any Filament-competent engineer reads the README and is productive within an hour. The real ramp-up cost is user-side — the header-icon interaction is a different mental model from the filters dropdown, and discoverability of a small icon is a known usability issue. Plan a short internal guide, and lean on syncWith() so users who ignore the header icon still get consistent behaviour from the dropdown. Treat the pilot's usability read as a go/no-go input, not a formality.
How can I help you explore Laravel packages today?