Filter Bar | LlamaPress Pattern Catalog
LlamaPress
Find & Navigate
Pattern

Filter Bar

A row of controls above a collection that narrows it by attribute, with every active filter visible as a removable chip and the whole state carried in the URL.

Find & Navigate Scan & Understand

Someone wants "all overdue invoices owned by Dana" — they know the attributes, not the name. Search cannot help, because there is no term to type. Without filters they scan the whole list, and without visible active filters they eventually forget what they are looking at.

Live demo — try it Open full screen
Use when
  • People describe what they want by attributes rather than by name.
  • The collection is too large to scan and too varied for one default view.
  • The same few narrowings are used repeatedly by the same people.
Avoid when
  • There are fewer than about fifteen records. Sorting is enough.
  • Only one attribute ever matters — then it is a set of tabs, which is cheaper and more visible.
  • Every user needs a different combination every time; consider saved views instead.

Anatomy

┌─────────────────────────────────────────────────────────────┐
│ Status ▾   Owner ▾   Date ▾            42 of 318 invoices   │
│ ● Overdue ✕   ● Owner: Dana ✕                  Clear all    │
└─────────────────────────────────────────────────────────────┘
   ↑ active filters, visible and individually removable

The controls are the easy half. The three that matter:

  1. Chips for what is on. The single most common failure is a filter applied from a dropdown that then shows no trace of itself. People read a partial list as if it were the whole one and draw wrong conclusions.
  2. State in the URL. It makes the view shareable, reloadable and — the part people feel every day — restorable when they come back from a record.
  3. A count. "42 of 318" is orientation: it says both how much you have and how much you excluded.

Why it works

It serves a different question from search. Search answers where is this specific thing; filters answer which of these things match a description. A product that offers only one of the two leaves half its users scanning.

Chips are what make it safe. A filtered list looks exactly like an unfiltered one, so the interface has to say which it is — otherwise the person who inherited someone else's saved link reports a data problem that is really a filter.

Putting the state in the URL is the quiet upgrade. It turns a transient UI state into something a person can send in a message, which is how most real collaboration on a list actually happens.

Getting it wrong

  • Invisible active filters. The list is wrong and nothing on screen says so.
  • A filter per column. Filters are a shared cost: everyone reads them, few use each one. Add the ones people ask for, not the ones the schema permits.
  • Filter state only in memory. Reload, or come back from a record, and the work is gone — see back link.
  • A bare empty state. "No results" with active filters and no way to clear them is a dead end.
  • A hidden default. A list quietly scoped to this month, with nothing saying so, produces confident wrong answers.

Exemplars

Linear's filter bar builds up as chips, each one editable in place, and the whole set is one click from being saved as a view. It shows the natural progression: filters that keep getting rebuilt want a name.

Stripe's payments filters are notable for restraint — a handful of attributes on a record type with dozens of fields — and for putting everything in the URL, so support conversations happen by pasting a filtered link.

The extractable rule: a filter bar's job is to make the current scope undeniable. Narrowing the list is the easy part; saying so, permanently and visibly, is what keeps people from misreading it.

Instead of this, consider

Same problem, different trade-off. Pick on the condition, not on taste.

Global Search
When: People know the name or the identifier of the thing they want.
Saved Views
When: The same combinations are rebuilt daily and deserve a name.

Ask Leo for this

Paste this into your Leo chat. It describes the behaviour, not the code, so Leo can fit it to your data.

Prompt
Put a filter bar above this collection.

- Offer filters for the attributes people actually narrow by. Do not add one
  per column; every filter is a control everyone reads and most never use.
- Show every active filter as a removable chip, with its value, next to the
  controls. A filter that is on but not visible is how people end up
  misreading a list.
- Include a single "Clear all" that appears only when something is active.
- Put the whole filter state in the URL so a view can be reloaded, bookmarked
  and pasted to a colleague, and so returning from a record restores it.
- Show the result count, and update it as filters change.
- When a combination matches nothing, say which filters are active and offer
  to clear them. Never show a bare empty list.
- Keep sensible defaults visible rather than hidden: if the list defaults to
  the current month, show that as a chip like any other filter.

Related

Cookbook recipe
Filterable Index with Slide-Out Detail Drawer
The implementation, filter bar and drawer together.
Pattern
Dense Operational Table
What sits below the bar, and why fewer columns beats more filters.