Surface Petrol/Diesel as quick pills in the results filter bar
Add Petrol (e10) and Diesel (b7_standard) pills to the left of the Filters pill, same row and style, each re-searching on tap via the existing fuelType watcher. The popover's fuel section becomes "More fuels" listing only the four long-tail fuels (E5, Prem Diesel, B10, HVO), derived from the shared FUEL_TYPES source. Fuel only counts toward the Filters badge when a long-tail fuel is active; "Clear all" snaps a long-tail fuel back to Petrol but leaves a pill choice alone. Results-bar only, no API change. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1,12 +1,28 @@
|
|||||||
<template>
|
<template>
|
||||||
<div ref="popoverRoot">
|
<div ref="popoverRoot">
|
||||||
<div class="flex flex-wrap items-center justify-end gap-2 md:gap-2.5 py-2 border-b border-zinc-200">
|
<div class="flex flex-wrap items-center gap-2 md:gap-2.5 py-2 border-b border-zinc-200">
|
||||||
|
<div class="flex items-center gap-2 md:gap-2.5" role="radiogroup" aria-label="Fuel">
|
||||||
|
<button
|
||||||
|
v-for="fuel in PRIMARY_FUELS"
|
||||||
|
:key="fuel.value"
|
||||||
|
:aria-checked="fuelType === fuel.value"
|
||||||
|
:class="{ 'is-active': fuelType === fuel.value }"
|
||||||
|
class="pill !rounded-xl"
|
||||||
|
role="radio"
|
||||||
|
type="button"
|
||||||
|
@click="fuelType = fuel.value"
|
||||||
|
>
|
||||||
|
<iconify-icon v-if="fuel.icon" :icon="fuel.icon" class="text-sm opacity-70"></iconify-icon>
|
||||||
|
<span class="text-sm font-medium">{{ fuel.label }}</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
:aria-expanded="open"
|
:aria-expanded="open"
|
||||||
:class="{ 'is-active': activeCount > 0 || open }"
|
:class="{ 'is-active': activeCount > 0 || open }"
|
||||||
aria-controls="post-search-filters-panel"
|
aria-controls="post-search-filters-panel"
|
||||||
aria-haspopup="dialog"
|
aria-haspopup="dialog"
|
||||||
class="pill !rounded-xl"
|
class="pill !rounded-xl ml-auto"
|
||||||
type="button"
|
type="button"
|
||||||
@click="open = !open"
|
@click="open = !open"
|
||||||
>
|
>
|
||||||
@@ -35,11 +51,11 @@
|
|||||||
aria-label="Filters"
|
aria-label="Filters"
|
||||||
class="mt-3 rounded-2xl border border-zinc-200 bg-white shadow-sm p-4 space-y-4 max-h-[70vh] overflow-y-auto"
|
class="mt-3 rounded-2xl border border-zinc-200 bg-white shadow-sm p-4 space-y-4 max-h-[70vh] overflow-y-auto"
|
||||||
>
|
>
|
||||||
<div>
|
<div v-if="SECONDARY_FUELS.length">
|
||||||
<span class="block text-[10px] font-mono uppercase tracking-widest text-zinc-500 mb-2">Fuel</span>
|
<span class="block text-[10px] font-mono uppercase tracking-widest text-zinc-500 mb-2">More fuels</span>
|
||||||
<div class="grid grid-cols-2 sm:grid-cols-3 gap-2" role="radiogroup" aria-label="Fuel type">
|
<div class="grid grid-cols-2 sm:grid-cols-3 gap-2" role="radiogroup" aria-label="More fuel types">
|
||||||
<button
|
<button
|
||||||
v-for="fuel in FUEL_TYPES"
|
v-for="fuel in SECONDARY_FUELS"
|
||||||
:key="fuel.value"
|
:key="fuel.value"
|
||||||
:aria-checked="fuelType === fuel.value"
|
:aria-checked="fuelType === fuel.value"
|
||||||
:class="{ 'is-active': fuelType === fuel.value }"
|
:class="{ 'is-active': fuelType === fuel.value }"
|
||||||
@@ -152,6 +168,17 @@ const DEFAULTS = Object.freeze({
|
|||||||
sort: 'reliable',
|
sort: 'reliable',
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// The two everyday fuels are surfaced as quick pills outside the popover;
|
||||||
|
// everything else in the shared FUEL_TYPES source stays under "More fuels".
|
||||||
|
const PRIMARY_FUEL_VALUES = Object.freeze(['e10', 'b7_standard'])
|
||||||
|
|
||||||
|
const PRIMARY_FUELS = Object.freeze([
|
||||||
|
{ value: 'e10', label: 'Petrol', icon: 'lucide:fuel' },
|
||||||
|
{ value: 'b7_standard', label: 'Diesel', icon: null },
|
||||||
|
])
|
||||||
|
|
||||||
|
const SECONDARY_FUELS = FUEL_TYPES.filter((fuel) => !PRIMARY_FUEL_VALUES.includes(fuel.value))
|
||||||
|
|
||||||
const sortOptions = [
|
const sortOptions = [
|
||||||
{ label: 'Reliable', value: 'reliable', icon: 'lucide:shield-check' },
|
{ label: 'Reliable', value: 'reliable', icon: 'lucide:shield-check' },
|
||||||
{ label: 'Price', value: 'price', icon: 'lucide:pound-sterling' },
|
{ label: 'Price', value: 'price', icon: 'lucide:pound-sterling' },
|
||||||
@@ -195,8 +222,12 @@ watch([fuelType, radius, sort], () => {
|
|||||||
if (postcode.value.trim() || coords.value) emitSearch()
|
if (postcode.value.trim() || coords.value) emitSearch()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Petrol/Diesel are shown as pills, so only a long-tail fuel counts as a
|
||||||
|
// "hidden" filter on the Filters badge.
|
||||||
|
const isSecondaryFuel = computed(() => !PRIMARY_FUEL_VALUES.includes(fuelType.value))
|
||||||
|
|
||||||
const hasActive = computed(() => (
|
const hasActive = computed(() => (
|
||||||
fuelType.value !== DEFAULTS.fuelType
|
isSecondaryFuel.value
|
||||||
|| radius.value !== DEFAULTS.radius
|
|| radius.value !== DEFAULTS.radius
|
||||||
|| sort.value !== DEFAULTS.sort
|
|| sort.value !== DEFAULTS.sort
|
||||||
|| Boolean(props.brandFilter)
|
|| Boolean(props.brandFilter)
|
||||||
@@ -204,7 +235,7 @@ const hasActive = computed(() => (
|
|||||||
|
|
||||||
const activeCount = computed(() => {
|
const activeCount = computed(() => {
|
||||||
let count = 0
|
let count = 0
|
||||||
if (fuelType.value !== DEFAULTS.fuelType) count++
|
if (isSecondaryFuel.value) count++
|
||||||
if (radius.value !== DEFAULTS.radius) count++
|
if (radius.value !== DEFAULTS.radius) count++
|
||||||
if (sort.value !== DEFAULTS.sort) count++
|
if (sort.value !== DEFAULTS.sort) count++
|
||||||
if (props.brandFilter) count++
|
if (props.brandFilter) count++
|
||||||
@@ -212,7 +243,8 @@ const activeCount = computed(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
function resetFilters() {
|
function resetFilters() {
|
||||||
fuelType.value = DEFAULTS.fuelType
|
// Leave a Petrol/Diesel pill choice alone; only snap a long-tail fuel back.
|
||||||
|
if (isSecondaryFuel.value) fuelType.value = DEFAULTS.fuelType
|
||||||
radius.value = DEFAULTS.radius
|
radius.value = DEFAULTS.radius
|
||||||
sort.value = DEFAULTS.sort
|
sort.value = DEFAULTS.sort
|
||||||
if (props.brandFilter) emit('update:brandFilter', '')
|
if (props.brandFilter) emit('update:brandFilter', '')
|
||||||
|
|||||||
Reference in New Issue
Block a user