Filter Bar
What is currently filtering a list, and a way to undo it.
Installation
npx shadcn@latest add https://qure-ui.qure.ai/r/filter-bar.jsonUsage
import { FilterBar, FilterChip } from '@/components/ui/filter-bar'<FilterBar onClear={() => setFilters([])}>
{filters.map((f) => (
<FilterChip key={f.key}>{f.label}</FilterChip>
))}
</FilterBar>This is one of the components with no shadcn equivalent. It comes from
worklist-filter-bar.tsx in qtrack-lc, where it sits under the search field in the patient panel.
Nothing about it is a worklist, so it ships on its own.
Why bother
A filtered list and an empty one look identical. Three chips explaining why there are four results is the difference between "no patients match this" and "no patients, something is broken" — and the second reading is the one people act on, usually by reloading and asking someone.
It matters more the longer a filter survives. A saved filter applied three days ago is invisible by Wednesday; the bar is what stops that becoming a support ticket.
Overflow
Past max chips, the rest collapse into "+N more", which opens a
Popover listing all of them. max defaults to 3, which is what the
app uses.
The chips in the bar truncate to keep the row one line; the ones in the popover wrap, because
reading the ones that did not fit is the entire point of opening it. Every chip also carries its
own full text as a title.
Nothing applied
FilterBar renders null when it has no chips. That is deliberate, and it means you can leave it
mounted rather than guarding it at the call site.
A bar reading "Filtered by" over an empty row is a claim that something is being hidden, which sends people looking for a filter that is not there.
Clearing
onClear is optional; omit it and the button is not rendered. Include it wherever you can — a
filter someone cannot see how to remove is one they will remove by reloading the page, losing
whatever else they had set up.
Clearing everything at once is the common case and the only one here. Removing chips one at a time means each chip is a button, and then the bar is a control rather than a summary; if that is what you want, put a Badge row together yourself.
API Reference
FilterBar
| Prop | Type | Default | Description |
|---|---|---|---|
label | ReactNode | "Filtered by" | The lead-in, shown in the bar and above the overflow list. |
onClear | () => void | — | Omit and no clear button is rendered. |
clearLabel | ReactNode | "Clear" | Text for that button. |
max | number | 3 | Chips shown before the rest move into "+N more". |
FilterChip
Renders a <span>. title defaults to the chip's own text when that text is a string, so a
truncated chip still says what it is on hover.