Weave 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

Nova Pill Filter Laravel Package

shllghst/nova-pill-filter

View on GitHub
Deep Wiki
Context7

Getting Started

This is a micro-package: a single Nova Filter subclass plus a Vue component that renders the filter's options as toggleable pill buttons instead of Nova's default dropdown. Treat it as a 100-line snippet you happen to install via Composer, not as infrastructure.

Minimal steps:

  1. Confirm compatibility before anything else. Last release was 2023-06-09, zero stars, zero dependents. That release predates Nova 5 and sits in the Nova 3 (Vue 2) / Nova 4 (Vue 3) transition window. Check composer.json for the laravel/nova constraint and check the Vue file for Vue.extend/beforeCreate (Vue 2) vs defineComponent/setup (Vue 3). If your Nova major doesn't match, stop here and copy the component instead of installing it.
  2. Install and read the source. composer require shllghst/nova-pill-filter — but note the Composer name (shllghst/nova-pill-filter) differs from the repo owner (mathieufrh), so verify the name field in the package's composer.json and that the vendor/package actually resolves on Packagist. Then read three files: the filter class under src/, the Vue component under resources/js/, and the service provider (if any) for asset registration.
  3. The first use case: a status filter on an index screen. php artisan nova:filter StatusFilter in your app, extend the package's filter class instead of Laravel\Nova\Filters\Filter, return your statuses from options(), and point component() at the package's pill component. You should see pills instead of a dropdown on that resource's index.

The value proposition is real but narrow: pills make a 3–6 option filter one click instead of two, and they show current state at a glance. That's the whole assessment. If your filter has more than ~8 options, pills are worse than a dropdown, and you've gained nothing.

Implementation Patterns

Extend, don't configure. The package almost certainly has no config file. The intended pattern is inheritance:

namespace App\Nova\Filters;

use Shllghst\NovaPillFilter\PillFilter; // verify namespace in src/

class StatusFilter extends PillFilter
{
    public function name() { return 'Status'; }

    public function options(Request $request)
    {
        return [
            'Active'   => 'active',
            'Paused'   => 'paused',
            'Archived' => 'archived',
        ];
    }

    public function apply(Request $request, $query, $value)
    {
        return $query->where('status', $value);
    }
}

The options() shape matters — most Nova pill implementations use the same label => value map as core Nova filters, so the Vue side can v-for over filter.options. Confirm this against the component; some forks pass an array of {label, value} objects via ->withMeta().

Multi-select via array values. The natural fit for pills is multi-select, which core Nova filters don't do well. Pattern: have the component emit an array, then in apply():

public function apply(Request $request, $query, $value)
{
    $values = is_array($value) ? $value : [$value];
    return $query->whereIn('status', $values);
}

The package may or may not support this out of the box. If the Vue component only emits a single scalar, you're either patching the component or dropping multi-select. Check props and $emit in the .vue file first — that's a five-minute read that determines your whole design.

"All" as a pill. A pill that clears the filter is the most-used pill on any real screen. If the component sets value = '' and your apply() returns $query unchanged on empty, Nova's own filter-clearing logic should handle it — but verify, because a pill that can't be un-toggled is the single most common complaint about this UI pattern.

Persistence and defaults. Nova filters persist in the session/URL per key(). If you copy the package's filter into several resources, override key() with a stable string per resource, or the same selection leaks between them. Use ->default() for the "Active" default on a status filter — but only if the component correctly renders the default as a selected pill on first load; otherwise the pill state and the actual query disagree, which is a confusing bug.

Asset pipeline. Nova packages that ship Vue components don't compile them — your app's webpack.mix.js / vite.config.js has to include nova-components or the package's resources/js. If the package ships a prebuilt dist/js/filter.js and registers it via Nova::script(), that's easier but likely broken on your Nova version. If it ships raw .vue only, you'll add an import in your app's resources/js/filters.js and run npm run dev/npm run build. Budget for this step; it's where most installs actually fail.

Gotchas and Tips

  • Zero stars, zero dependents, single 2023 release. No security review, no test suite, no issue triage. Read the Vue component line by line before shipping it into an admin panel. It's ~50 lines; the audit cost is trivial and the alternative is trusting an anonymous filter.
  • Vue version mismatch is the failure mode. Nova 3 = Vue 2, Nova 4+ = Vue 3. A component written against Vue 2 will fail silently or throw Cannot read properties of undefined in a Nova 4 app, and the error surfaces in the browser console, not in Laravel logs. Check the console first when pills don't render.
  • Composer name vs repo owner mismatch. shllghst/nova-pill-filter on Packagist, mathieufrh/nova-pill-filter on GitHub. Add a VCS repository entry or verify the Packagist entry is the same code. Typosquatting risk is non-trivial for abandoned-looking Nova packages.
  • Filter key collisions. Nova stores filter state keyed by the filter's key(), which defaults to the class name. Two resources sharing the same filter class share state. Override key() per resource, e.g. return 'users-status';.
  • URL/query-param debugging. Nova filters land in the ?filter[StatusFilter]=active query string. When a pill click "does nothing," inspect the URL first: no param means the component isn't wired to Nova's Filter mixin (it must emit input and read from the filter prop); a param that's present but ignored means apply() isn't matching the value type (e.g. '0' string vs 0 int, or boolean serialized as "true").
  • Empty vs null. apply() receives '' (empty string) when the filter is cleared, not null. A whereIn('status', $values) with [''] returns nothing rather than everything — guard for it.
  • Dark mode and styling. If the component uses hardcoded #fff/#000, pills will look wrong in Nova's dark theme. Tailwind classes (bg-primary-500, text-gray-500) inherit Nova's theme; hardcoded hex doesn't.
  • Extension point you'll actually want: don't fork the package, copy the .vue into resources/js/components/PillFilter.vue, register it, and delete the dependency. You get full control of multi-select, "All," counts, and styling, and you stop carrying an unmaintained Composer package for 50 lines of code. This is the recommended path for anything beyond a throwaway internal tool.
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.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin