Filter bar
canonRow of filter chips with add, reset and save controls.
React implementation lives in the app (apps/web/src/components/FilterBar.tsx), not in @acrm/ui. Phone (owner 2026-09-28, acrm !4088): with onOpenChange the bar is the bottom sheet „Filtry" (search, conditions with ⋮ Odebrat, Přidat filtr, Vymazat vše, Hotovo); the Filtr toggle shows a neutral CountBadge, Řadit (SegmentScreen) a sort sheet; „Uložit pro všechny" moves to the bar's ⋮ (phoneOnly). „Vymazat filtry" = Button ghost tone muted. Desktop unchanged. 14 Oct 2026 (owner "24c approved", proto/lista-vypisu@a16fe17a7, acrm !5045): no word labels — Filtr = icon (+ dot), Seskupit/Řadit/Zobrazení = icon + chosen value, field name only in aria-label/tooltip; open row: chip = field icon + value, „+" and „×" icons; closed by default, „Jen moje" is a chip inside Filtr. Dev check 14 Oct on /tasks /pipeline /objednavky /setkani /lide, 1440 + 390: 0 label words, no overflow. Registry repaired 17 Oct 2026 (review F2): removed classes with no CSS definition and no TSX use on main: .fb-add, .fb-reset, .fb-save.
Used in 23 files · 21 areas · 48× — components/communication, components/datamart, pages/AccountingInvoicesPage, pages/AccountingReceivedInvoicesPage, pages/AsistentAuditPage, pages/DokumentyPage …
apps/web <FilterBar> <FilterToggleChip>.fb-clear .fb-conj .fb-menu .fb-sheet +3SourceStoryLegacy card filter-bar.htmlThe one way to filter a table listing. A row of chips under the Section top bar: every chip is a field that already has a value, + Filtr adds another field, and on the right sit Vymazat filtry and Uložit pro všechny (which turns the current filter into a segment). React: apps/web/src/components/FilterBar.tsx; CSS apps/web/src/ds/filter-bar.css (prefix .fb).
The model is Notion, taken literally: a chip without a value does not exist. Choosing a field and choosing its value is one act — the chip appears already filled in, and clearing the value removes the chip.
When to use
- Filtering a table listing (deals, companies, contacts, invoices, tasks) — the bar sits directly under the Section top bar of that listing.
- A listing whose filter must be readable without clicking: the bar states the whole query in one line, including the logic between chips.
- Turning a filter into a saved segment — that is what
Uložit pro všechnyis for.
When not to use
- A form. The bar filters what is already on screen; it does not collect input.
- One switch over a listing ("only mine", "include inactive") — that is a toggle chip in the Section top bar (
.tchip), not a bar of its own. - Building a segment definition with nested conditions — that is the segment builder (
SegmentBuilder,.acrm-fchip), a separate screen with its own grammar. - A search that should always be visible: use the bar's own inline search (
.fb-search), not a chip.
Anatomy
- Bar
.fb:stickyatleft: 0,z-index: 5, flex withgap: var(--sp-3), paddingvar(--sp-3) var(--fb-gutter, 20px), hairlineborder-bottom, background--bg-canvas. The 20px gutter holds the content line of the listing; a host with a different line overrides--fb-gutter. - Chip
.fb-chip: 30px tall,padding: 0 10px,gap: 7px,border-radius: var(--radius-md),1px solid var(--border-strong),--surface-100,500 12px,box-shadow: var(--shadow-xs)— metrics 1:1 with the Section top bar chip.tchip. - Spacer
.fb-sp(flex: 1) separates the field chips from the bar actions. - Add / reset
.fb-add,.fb-reset: ghost, 30px, no border,--fg-muted, hover--hover-surface. - Save
.fb-save: the only emphasised action in the bar —--accent-tintfill,--accent-inktext,600 12px var(--font-display), hover adds the accent border. - Conjunction
.fb-conj: pill with a dashed border,--sp-6tall, texta zároveň; the activenebo(.or) switches to a solid border and--ink-900— neutral, never accent (ACRM-50: the conjunction records logic, it is not an action). - Group
.fb-group: tinted--active-surfaceblock that shows how far anebogroup reaches. Vertical padding is cancelled by a negative margin, so the bar is 47px high with or without a group. - Inline search
.fb-search: 30px boxed field in the row of chips (min 220px),--surface-75, focus-within paints the border accent and the fill--surface-100.
Phone (below 720 px) — Filtry sheet (2026-09-28, acrm !4088)
With onOpenChange the bar is a bottom sheet „Filtry" on a phone (without it, it stays an inline bar — lists are switched over one by one):
- Trigger: the bar's Filtr icon button with a neutral
CountBadge(number of active conditions); next to it Řadit (SegmentScreen, phone only) with its count — a sheet of the sortable columns, a second tap flips the direction, a third clears it. - Sheet, top to bottom: the inline search field, the active conditions one per row (chip over the width + ⋮ „Odebrat filtr", red), „+ Přidat filtr", „Vymazat vše", and Hotovo (
<Button touch>). - „Uložit pro všechny" is not in the sheet — the page gives it to the bar's ⋮ as a
phoneOnlyaction. - „Vymazat filtry" / „Vymazat vše" is
<Button variant="ghost" tone="muted">(owner 2026-09-28):--fg-secondary,--fgon hover. - Desktop unchanged.
Best practices
- Keep the bar to one row of the query: field chips left, actions right, nothing else in between.
- Let the toggle chip in the Section top bar open and close the bar in both directions — closing it must not switch the filters off; the accent dot says they are still on.
- Show the conjunction between chips always, not on hover: the reader must be able to read the logic without clicking.
- Give the host its own
--fb-gutterwhen its content line differs from the 20px of a table listing.
- An empty chip ("Fáze: —") waiting for a value; pick the field in
+ Filtrand set the value in one go. - A count of results in the bar ("12 z 340") — the listing says that, not the filter.
- A second emphasised action next to
Uložit pro všechny; the rest are ghost actions. - A
.setdot on a field chip in the bar. The dot belongs to toggle chips (+ Filtr, modifiers) where the value is not written out; on a bar chip the value is right there, so the dot would be noise.
Content
- Chip = field name (
.k, muted) + value (.v, 600, clipped at 148px). No operator word in the chip; the operator lives in the menu. - Bar actions are verbs:
Filtr,Vymazat filtry,Uložit pro všechny. - Conjunction is lower case, two states only:
a zároveň/nebo. - Sentence case everywhere, no capitals, no trailing period.
Related
filter-chip— the chip and the menu it opens.section-top-bar— hosts the toggle chip that shows and hides this bar.record-list,table— the listings this bar filters.- Stories:
components--filter-bar--default,--variants,--states,--with-icon-kbd,--composition.
Source: docs/filter/filter-bar.usage.md · GitLab