Filtering
How to choose the filters of a list, where they go, and how they apply, count, clear and stay visible.
Filters narrow a list to the records someone needs now: the critical alerts of one tenant, the credentials leaked this week. This page says which filters a list gets, where they go and how they behave. Build them with Filter panel; choose the columns of the list with Tables.
Choose the filters
- Filter on what people decide by. The deciding attribute of the table (severity, status, priority) and the context columns people narrow by (owner, source, type). A field nobody narrows by is not a filter, even if the API accepts it.
- One control per kind of value. Several values of a small set: a checkbox list. One value, or yes and no: a radio list. A long or open set (users, entities, tags): a search with chips. Values people type that no list holds (country codes, domains): free-text chips. A score or an amount: a floor, a ceiling or both; a threshold people pick from a few values (confidence 50, 75, 90): a radio list of presets, never a slider of a hundred steps. An on/off condition (known exploited, internet-facing): a switch. Identifiers: the search box of the list, not a filter.
- Time windows start with presets. “Today”, “Last 7 days”, “Last 30 days”, then custom dates. A preset stays relative in the URL, so a shared link still means the last seven days tomorrow; resolve it with today in the profile’s time zone, never the browser’s. Put a date filter in the panel only where the screen has no date window of its own.
- Status tabs and search are not filters. A tab splits the list into the views people switch between (open, resolved); the search finds a record. Neither has a section in the panel, and Clear never touches them.
- Column visibility is not a filter. It belongs to the Columns menu of the table.
zx/filter-place Four or more facets go in a panel
- One to three facets: dropdowns in the toolbar, each a checkbox list in a Popover.
- Four or more, or any range or date: a Filter panel on the inline start of the results, 240 px wide. It starts closed below a 1280 px window; people open it, and the app remembers their choice.
- Inside a detail sheet or a dialog, the panel never collapses (
collapsible="none").
Counts
zx/filter-counts A count says what a choice would return
- Show the number of results next to each value when the API can count them. People use the count to decide whether a filter is worth applying.
- Counts are disjunctive: a facet’s counts take every other filter into account, never its own selection, so ticking a second value shows what it adds.
- Counts are exact (“1,204”), through the app’s number formatter. Compact numbers are for Stat Tile and chart axes only.
- A count that ignores the filters (a global total) says so in the section description, or is left out.
- Keep the given order for ranked or small sets (severity, priority, status); sort by count for open sets (tags, sources). Hide values with no results only in open sets, and never a selected one.
Apply and remember
- Filters apply at once. No Apply button on desktop. Text and numbers commit on Enter or when the field loses focus, never per keystroke or per step of a slider.
- Queries wait for the user. Debounce the request and cancel the one it replaces: arrow keys select radios as they move, and each move is a change.
- Filters live in the URL. Readable params (
?severity=critical&severity=high), written withfiltersToSearchParams, so a link reproduces the list. A filter change replaces the history entry instead of adding one per click. - Defaults are filters too. A list that opens narrowed (recent only, pending) counts the default in the panel and shows it as a chip, and Clear becomes Reset.
- Narrow layouts use a sheet. Below 60rem the panel opens over the results from the same trigger. Filters still apply at once; the sheet’s “Show 1,204 results” button takes people back to the list, and the chips summarize the filters while it is closed.
Keep every filter in sight
zx/filter-visible A filter in force is always visible
- With the panel open, the panel is the summary: each folded section shows how many values it holds.
- With the panel closed, chips under the toolbar list the active filters, one per field (“Severity: Critical, High”), each removable, with Clear filters at the end. The trigger shows the number of active filters.
- A filter without a section (from a shared link, a saved view, an advanced editor) always has a chip. A list narrowed by a filter nobody can see is a bug.
- One source of truth: when a list also has a query bar, the panel and the query show the same state.
No results
zx/filter-zero Zero results name their cause
When the filters, the search or the tab leave nothing, the empty state says which one, and its action clears that one: “No alerts match these filters” with Clear filters, “No alerts match ‘vpn-gw’” with Clear search. See Empty states.
Review checklist
- Every filter is something people decide by; tabs, search and columns are not filters.
- Four or more facets, or a range or a date, use the panel; fewer use toolbar dropdowns.
- Counts are disjunctive and exact; global counts say so.
- Filters apply at once, debounced, and live in readable URL params.
- Every active filter is visible: in the panel, or as a chip, defaults included.
- Zero results name the cause and clear it.