Koala logo Design
No matches for “
↑↓ navigate open Esc close
Components List filters

List filters

A search + filters + sort row that keeps the filters inline until they'd no longer fit, then collapses them behind a single funnel button that opens an anchored popover. Width-driven (a ResizeObserver), not a fixed breakpoint — so it collapses exactly when the row runs out of room, whatever the filter count.

<koala-list-filters>
<form x-data="koalaListFilters()">
    <div data-filter-bar class="flex items-center gap-3">
        <div data-filter-search class="flex-1 min-w-0">
            <input type="search" placeholder="Search…" class="block w-full rounded-md border border-outline bg-surface px-3 py-2 text-sm" />
        </div>
        <koala-list-filters filter-count="2">
            <koala-multi-dropdown label="Status" trigger-icon="CircleDot" count="2" class="w-full md:w-auto">
                <label class="flex items-center px-3 py-2 hover:bg-surface-dim cursor-pointer text-sm text-on-surface">
                    <input type="checkbox" checked x-on:change="$el.form.requestSubmit()" class="w-4 h-4 mr-2 rounded border-outline text-primary" /> Active
                </label>
                <label class="flex items-center px-3 py-2 hover:bg-surface-dim cursor-pointer text-sm text-on-surface">
                    <input type="checkbox" checked x-on:change="$el.form.requestSubmit()" class="w-4 h-4 mr-2 rounded border-outline text-primary" /> Closed
                </label>
            </koala-multi-dropdown>
            <koala-multi-dropdown label="Partner" trigger-icon="Partner" class="w-full md:w-auto">
                <label class="flex items-center px-3 py-2 hover:bg-surface-dim cursor-pointer text-sm text-on-surface">
                    <input type="checkbox" x-on:change="$el.form.requestSubmit()" class="w-4 h-4 mr-2 rounded border-outline text-primary" /> Acme Estates
                </label>
                <label class="flex items-center px-3 py-2 hover:bg-surface-dim cursor-pointer text-sm text-on-surface">
                    <input type="checkbox" x-on:change="$el.form.requestSubmit()" class="w-4 h-4 mr-2 rounded border-outline text-primary" /> Box & Co
                </label>
            </koala-multi-dropdown>
        </koala-list-filters>
        <div data-filter-sort class="shrink-0 ml-auto">
            <button type="button" class="koala-filter-trigger inline-flex px-4 py-2">
                <koala-icon name="ArrowUpDown" size="Small" class="mr-2 koala-filter-trigger-icon" />
                Newest first
            </button>
        </div>
    </div>
</form>

One row: search (grows), filters, sort. While the dropdowns fit they sit inline; the moment they'd overflow they collapse into the funnel button, which opens the same dropdowns in an anchored popover.

3 states
Fits — inline
Filters render in the row beside search + sort.
Doesn't fit — collapsed
Filters fold into a funnel button (count badge); clicking opens the popover.
Collapsed — open
The funnel opens the same dropdowns in an anchored popover (a centred modal on narrow screens).

The collapse is width-driven, so it can't be pinned in a static tile — these mock the three layouts. Resize the browser with the Canonical row above to watch the real component switch between them.

2 attributes
Attribute Values Notes
filter-count int Active-filter count, shown as a badge on the collapsed funnel icon.
trigger-id string Id of the collapsed trigger (default filter-button) so a page can name it in an Alpine-AJAX x-target.
breakpoint Medium, Large Deprecated — ignored. Collapse is width-driven now; kept only so old call sites still bind.

The parent <form> must declare x-data="koalaListFilters()" and lay out a single row tagged data-filter-bar containing data-filter-search and (optionally) data-filter-sort. The component measures these to decide when to collapse.

Do Put search, <koala-list-filters> and sort in one data-filter-bar row. Each checkbox auto-submits via $el.form.requestSubmit().
Don't Don't let the filters wrap onto a second line. If they don't fit, they should collapse to the funnel icon — that's what the component does for you.