List filter modals
Index pages (Quotes, Transactions, Partners) ship with a row of filter dropdowns that need to render inline
on desktop and as a full-screen modal on mobile. The
<koala-list-filters>
Portal tag helper wraps that row and handles the responsive collapse, the mobile backdrop, the close button,
and the sticky "Apply filters" footer for you. You only write the filter dropdowns themselves.
When to use
Use this on every list page that has 1+ filter dropdowns. The pattern enforces a consistent layout across Quotes / Transactions / Partners — the search box and a mobile filter trigger live to the left of the row, and the dropdowns flow into a modal below that breakpoint.
- The parent
<form>declaresx-data="{ filtersOpen: false, ... }". - The mobile trigger button (the funnel icon outside the tag helper) flips
filtersOpento open the modal. - Choose
breakpoint="Medium"(default, 768px) for 1–2 dropdowns, orbreakpoint="Large"(1024px) when 3+ dropdowns need more horizontal space. - The dropdowns inside should use the same breakpoint for their
w-auto/left-autoclasses to match.
Reference snippet
Inside the form (after the search box and the mobile filter trigger) wrap the dropdown sections in a
<koala-list-filters> tag.
<form method="get" x-data="{ searching: false, filtersOpen: false }"
x-target.push="filter-button quote-results">
<div class="flex flex-wrap items-center justify-between gap-3 p-4">
<!-- search input + mobile filter button (md:hidden) live OUTSIDE the tag helper -->
<koala-list-filters>
<!-- Status dropdown -->
<div class="relative w-full md:w-auto" x-data="{ open: false }">
<button id="status-dropdown-button" ... >Status</button>
<!-- panel with checkboxes that auto-submit on change -->
</div>
<!-- Partner dropdown (only when relevant) -->
@if (Model.Partners.Count > 0)
{
<div class="relative w-full md:w-auto" x-data="{ open: false }">
<button id="partner-dropdown-button" ... >Partner</button>
<!-- panel -->
</div>
}
</koala-list-filters>
</div>
</form>
Conventions
- Mobile trigger lives outside the tag helper. The funnel-icon button that flips
filtersOpensits next to the search input on mobile so users can tap to open the filter modal. The tag helper renders only the modal/desktop-row content. - Auto-submit on change. Each dropdown checkbox calls
$el.form.requestSubmit()on change so the list re-renders immediately. There is no draft / dirty state. - Apply button is mobile-only. The footer Apply Filters button is rendered for you and just dismisses the modal — every change has already been applied.
- Don't nest forms. The dropdowns share the parent
<form>; nesting a second form inside breaks auto-submit. - Mobile breakpoint must match the dropdowns inside. If the dropdowns use
md:w-auto, keep the defaultbreakpoint="Medium". If they uselg:w-auto, switch tobreakpoint="Large".
Where it's used
/conveyancing/quotes— search + status + partner filter/conveyancing/transactions— search + status + type + partner filter/partner/quotes— search + status + referrer filter/partner/transactions— search + status + type + referrer filter