You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(drinks): multi-select categories and grouped style filter (#506)
* feat(drinks): support multi-select category filtering
Category filtering was single-select (String?), so users could not
view beer + international-beer + low-no together even though those
three categories make up 76% of a typical festival. Switch
DrinkFilterController/Service and BeerProvider to a Set<String>-based
category filter (OR logic across categories, matching the existing
style-filter pattern) and convert CategoryFilterSheet from
single-select radios to multi-select checkboxes that stay open across
taps.
Toggling a category now prunes (rather than clears) the selected
styles, keeping only styles still present under the new category
scope, since an unconditional clear was too destructive once several
categories can be active at once.
Analytics keeps logCategoryFilter's existing String? signature; the
provider now passes a canonical sorted, comma-joined value (or null
when cleared) so the logged value is independent of selection order.
Fixes#319
* feat(drinks): group styles by category in the style filter sheet
With no category selected, the style list was one flat alphabetical
run mixing styles from unrelated categories (e.g. wine and perry
styles interleaved with beer styles). Add
DrinkFilterController.stylesByCategory, a grouped view of the same
style facet scope the facet-scoping rule already defines, and render
a category header above each group in StyleFilterSheet.
A lone group (the common case once a single category is selected)
renders flat with no header. Headers reuse the existing
"Allergen-free" label treatment and carry Semantics(header: true) for
screen-reader section navigation. A selected style outside the
current scope is still grouped, under its category in the full
source, preserving the facet-scoping invariant that an active filter
is never hidden.
Fixes#318
* fix(a11y): announce formatted category names in the filter bar
The category filter button renders formatted names ('International
Beer') but its semanticLabel joined the raw category ids, so a screen
reader announced 'international-beer'. Sighted and screen-reader users
now get the same names, sorted so the announcement is deterministic
(a Set has no defined order).
Adds semantic tests pinning the label in all three states.
* test(drinks): cover the empty-state Clear Filters button
The empty-state button is the only way out of a filter combination that
matches nothing without reopening the category sheet, and this branch
changed its callback from setCategory(null) to clearCategories() with no
test exercising it.
Asserts the button appears when a category selection yields no drinks,
clears the selection when tapped, and disappears afterwards.
* fix(a11y): correct filter sheet count grammar and clear-all label
Two screen-reader wording fixes surfaced in review:
Category and style filter rows announced '1 drinks'. They now use the
count == 1 ? 'drink' : 'drinks' idiom already used in festival_header
and my_festival_screen.
The empty-state button clears every selected category since this branch
made categories multi-select, but announced 'Clear category filter'
(singular) and hinted 'show all drinks' — a promise it cannot keep when
a search or style filter is also active.
* fix(drinks): left-align style filter category headers
The headers were the only children narrower than the sheet in a Column
that defaults to centre alignment, so they rendered centred instead of
sitting above their group. Every other Column in this file already sets
CrossAxisAlignment.start.
Found by driving a local release web build in a headless browser; the
widget tests passed because none of them asserted horizontal position.
The header test now pins it.
---------
Co-authored-by: Claude <noreply@anthropic.com>
0 commit comments