Skip to content

Components

Mobile Filter Sheets — Stage the Changes, Show the Count, Then Apply

Draft State + "Show 43 Results" — the Two Decisions That Make Filters Feel Trustworthy
Written by Aiden Wood Founder and Lead Design Engineer
🧃 🎚️ 🛒

Desktop filters live in a sidebar and apply instantly — fine, the results are right there reacting. Squeeze the same instant-apply behaviour into a mobile sheet and you get chaos: every checkbox tap re-queries, the list reflows invisibly behind the sheet, and the user commits blind.

The mobile pattern is different and it has two rules. Velocity X's standard-mobile-filter-sheet encodes both.

The Money Pattern

Rule one: the sheet edits a draft, not the live filter state. Rule two: the apply button carries the result count, so committing is never blind:

const [applied, setApplied] = useState<Filters>(initial);
const [draft, setDraft] = useState<Filters>(applied);

// Cheap count-only query as the draft changes (debounced)
const { count } = usePreviewCount(draft);

<button onClick={() => { setApplied(draft); close(); }}>
  Show {count} results
</button>
<button onClick={() => setDraft(EMPTY)}>Clear all</button>

"Show 43 results" is doing enormous work in four words: it previews the consequence, it catches the zero-results dead end before the user commits ("Show 0 results" begs to be loosened), and it turns apply from a gamble into a confirmation. The count query is count-only — cheap enough to run on a debounce while the full query waits for the commit.

The Catch

Dismissal semantics are where drafts get tricky: swiping the sheet away after ticking three boxes — did they mean cancel or apply? Convention says dismiss = cancel, which is why the apply button has to be sticky at the sheet's bottom edge, always visible, never scrolled out of reach below forty filter groups.

And applied filters must survive the sheet: chips above the product grid showing each active filter with an ✕. Without them, "why am I only seeing 12 products" has no visible answer, and the only escape is a page reload.

The Verdict

Mobile filters are a transaction: draft, preview the consequence, commit or abandon. Instant-apply belongs to the desktop sidebar; counts-on-the-button belongs everywhere. The sheet, chips and draft logic ship together in Velocity X's E-Commerce category — source you own, snap points included via the bottom sheet underneath.

Let us make some quick suggestions?

Please provide your full name.
Please provide your phone number.
Please provide a valid phone number.
Please provide your email address.
Please provide a valid email address.
Please provide your brand name or website.
Please provide your brand name or website.