From 4c0017cb91b4fd9735310720905c52f42764e506 Mon Sep 17 00:00:00 2001 From: Ovidiu U Date: Fri, 12 Jun 2026 11:28:26 +0100 Subject: [PATCH] Add design spec for inline Petrol/Diesel quick pills Surfaces the two everyday fuels as one-tap pills in the results filter bar, left of the Filters pill; the popover keeps the four long-tail fuels under a "More fuels" section. Results-bar only, no API change. Co-Authored-By: Claude Opus 4.8 --- .../2026-06-12-inline-fuel-pills-design.md | 112 ++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 docs/superpowers/specs/2026-06-12-inline-fuel-pills-design.md diff --git a/docs/superpowers/specs/2026-06-12-inline-fuel-pills-design.md b/docs/superpowers/specs/2026-06-12-inline-fuel-pills-design.md new file mode 100644 index 0000000..3afa61c --- /dev/null +++ b/docs/superpowers/specs/2026-06-12-inline-fuel-pills-design.md @@ -0,0 +1,112 @@ +# Inline Petrol/Diesel Quick Pills — Design + +Date: 2026-06-12 +Status: Approved (brainstorm) +Branch: `feature/inline-fuel-pills` + +## Problem + +After a station search, the only way to change fuel type is to open the +"Filters" popover, which buries the two everyday fuels — Petrol (`e10`) and +Diesel (`b7_standard`) — behind a button. Almost every user wants one of those +two. We want them surfaced as one-tap pills directly in the results filter bar, +while keeping the four long-tail fuels (Premium `e5`, Prem Diesel `b7_premium`, +`b10`, `hvo`) reachable. + +## Scope + +- **Single file:** `resources/js/components/PostSearchFilters.vue`. +- **No backend/API change** — server-side fuel filtering already exists via the + `fuel_type` query param on `/api/stations`. +- **`Home.vue` unchanged** — the pills reuse the existing `search` event + contract the popover already emits. +- **`HeroSearch.vue` unchanged** — placement is results-bar only (the hero keeps + forwarding whatever `fuelType` is in the URL). + +## Layout + +The top row of the filter bar changes from a single right-aligned "Filters" +button to: + +``` +[ ⛽ Petrol ] [ Diesel ] ……………… [ ≡ Filters ▾ ] +``` + +- Two fuel pills left-aligned; the Filters pill pushed right via `ml-auto`. +- All three reuse the existing `pill !rounded-xl` class + `is-active` state, so + they are visually identical (the user's explicit "same row, same style" + requirement). +- ⛽ (`lucide:fuel`) icon on Petrol only; Diesel is label-only (matches the + user's mock). +- The row stays `flex flex-wrap items-center` so it wraps gracefully on narrow + screens. + +## Fuel model + +- **Primary fuels (pills):** `e10` → "Petrol", `b7_standard` → "Diesel". +- **Long-tail fuels (popover "More fuels"):** every other entry in `FUEL_TYPES` + — `e5`, `b7_premium`, `b10`, `hvo`. Derived by filtering `FUEL_TYPES` to + exclude the two primary values, so the list stays driven by the shared + `window.FUEL_TYPES` source rather than a second hard-coded list. + +The two primary fuel values (`e10`, `b7_standard`) are defined once as a local +constant in the component, with the short pill labels ("Petrol" / "Diesel"). +The canonical enum labels ("Petrol (E10)", "Diesel (B7)") are intentionally not +used on the pills — the short forms are a UX shortening. + +## Behaviour + +- Tapping **Petrol** sets `fuelType = 'e10'`; tapping **Diesel** sets + `fuelType = 'b7_standard'`. Either triggers an immediate re-search via the + existing `watch([fuelType, radius, sort])` — no new emit wiring. +- The popover "Fuel" section is relabeled **"More fuels"** and renders only the + long-tail fuels. Selecting one re-searches and drops both pill highlights. + +## Highlighting — the selected fuel is always visible + +- `e10` active → **Petrol** pill `is-active`. +- `b7_standard` active → **Diesel** pill `is-active`. +- A long-tail fuel active → neither pill highlighted, **but** the selected fuel + is highlighted inside the "More fuels" grid, and the Filters pill shows its + active state + badge. Selection is never ambiguous in any state. + +## Filters badge / active count + +- Fuel contributes to the Filters badge (`activeCount`) **only when a long-tail + fuel is active** — the pills already display Petrol/Diesel selection, so those + need no badge. +- Radius, sort, and brand contribute to `activeCount` as before. +- `hasActive` (which controls the "Clear all" affordance) likewise treats fuel + as active only when a long-tail fuel is selected. + +## Clear all + +- Resets radius / sort / brand to their defaults. +- If a long-tail fuel is selected, snaps fuel back to Petrol (`e10`) so the badge + clears. +- A Petrol/Diesel pill choice is left alone (the default is Petrol anyway). + +## Accessibility + +- The two pills form a `role="radiogroup"` labelled "Fuel" with `aria-checked` + on each, consistent with the existing radio pattern already used in this + component for radius/sort/brand. +- The "More fuels" grid remains its own radiogroup. + +## Out of scope + +- No new filter criteria (supermarket-only, open-now, amenities, price ceiling). +- No hero fuel selector. +- No server-side brand filtering (brand stays a client-side filter in `Home.vue`). +- No change to the radius or sort options. + +## Testing + +- `npm run build` must succeed (no Vite/compile regressions). +- Behavioural verification of: Petrol/Diesel toggles re-search and highlight; + selecting a long-tail fuel via the popover shows the badge with neither pill + highlighted; "Clear all" resets radius/sort/brand and snaps a long-tail fuel + back to Petrol. +- The exact mechanism (Pest 4 browser test vs. a JS unit harness vs. manual) is + decided in the implementation plan after confirming what frontend test + infrastructure exists in the repo.