Filter Notice

Says how many items active filters hide and which filter hides what, so people don't think data is missing or bulk-act on a partial set.

StopsThought data was missing behind a filter

Installation

pnpm dlx shadcn@latest add https://bollard-ui.vercel.app/r/filter-notice.json

The files land in your project. They're yours to edit.

Usage

filter-notice-usage.tsx
import { FilterNotice, hiddenByEach } from "@/components/ui/filter-notice"

<FilterNotice
  total={invoices.length}
  shown={visible.length}
  filters={filters.map((filter) => ({ id: filter.id, label: filter.label, hides: hides[filter.id] }))}
  hiddenSelected={hiddenSelected}
  formatCount={(count) => `${count} ${count === 1 ? "invoice" : "invoices"}`}
  onRemoveFilter={(id) => setActive((list) => list.filter((item) => item !== id))}
  onClearAll={() => setActive([])}
/>

What it catches

  • Items hidden by active filters, counted
  • Which filter hides the most, per chip
  • Selected items that are currently hidden

Props

FilterNotice props
PropTypeDefault
total* (required)

Items before any filter or search.

number—
shown* (required)

Items visible now.

number—
filters* (required)

Active filters and search terms, one chip each.

ActiveFilter[]—
onRemoveFilter* (required)

Remove one filter.

(id: string) => void—
onClearAll* (required)

Remove every filter and the search.

() => void—
hiddenSelected

Selected items that the filters now hide, so a bulk action wouldn't visibly include them.

number0
formatCount

"23 items". Override to name your rows or translate.

(count: number) => stringdefaultCount
message

Templates: `{hidden}`, `{shown}`, `{total}` (formatted counts) and `{filters}` ("2 filters") are filled in.

string"{hidden} hidden by {filters} · showing {shown} of {total}"
emptyText

Shown when filters hide every item.

string"Nothing matches. {hidden} hidden by {filters}."
hiddenSelectedText

`{count}` is the number of hidden selected items.

string"{count} selected {verb} hidden by these filters and not …
clearAllLabel

Text for the clear-all button.

string"Clear all"
removeLabel

Accessible label prefix for remove buttons.

string"Remove filter"

* required. Also accepts the native props of <div> (className, aria-*, data-*…), passed through to it.

Accessibility

  • A role="region" labelled "Active filters"
  • Counts and warnings are aria-live="polite"
  • Filter chips are a labelled list; remove buttons name the filter

Only what the source does. Test with your own screen reader and content before shipping.

Limitations

  • Counts come from your props; it doesn't compute them
  • Per-filter counts are what each filter hides on its own, so they can add up to more than the total hidden

What it stops

Thought data was missing behind a filter

Also known as

filters · filter chips · data table · bulk action · search results · clear filters · hidden rows · admin table

Dependencies

Pairs well with