Show active filter count in the UI and enhance filter button styling and accessibility

This commit is contained in:
MartinBraquet
2026-07-31 13:47:37 +02:00
parent 5953a71310
commit c792cb9e7b
3 changed files with 40 additions and 1 deletions

View File

@@ -56,6 +56,20 @@ import {PsychedelicsFilter, PsychedelicsFilterText} from './psychedelics-filter'
import {RelationshipFilter, RelationshipFilterText} from './relationship-filter'
import {SmokerFilter, SmokerFilterText} from './smoker-filter'
// Same count the open panel shows in its summary, so the collapsed hint and the panel can never
// disagree about how narrowed the search is.
export function getActiveFilterCount(
filters: Partial<FilterFields>,
locationFilterProps: LocationFilterProps,
raisedInLocationFilterProps: LocationFilterProps,
) {
return countActiveFilters(
removeNullOrUndefinedProps({...filters, orderBy: undefined}),
locationFilterProps,
raisedInLocationFilterProps,
)
}
function countActiveFilters(
filters: Partial<FilterFields>,
locationFilterProps: LocationFilterProps,

View File

@@ -38,6 +38,7 @@ export const Search = forwardRef<
bookmarkedSearches: BookmarkedSearchesType[]
refreshBookmarkedSearches: () => void
profileCount: number | undefined
activeFilterCount?: number
openFilters?: () => void
openFiltersModal?: boolean
highlightFilters?: boolean
@@ -59,6 +60,7 @@ export const Search = forwardRef<
starredUsers,
refreshStars,
profileCount,
activeFilterCount = 0,
openFilters,
openFiltersModal: parentOpenFiltersModal,
setOpenFiltersModal: parentSetOpenFiltersModal,
@@ -173,14 +175,30 @@ export const Search = forwardRef<
size="sm"
className={clsx(
'!h-10 !rounded-full border border-canvas-200',
// With the panel closed there was nothing on screen saying the grid is a filtered
// view, so an active count tints the button and rides along as a badge.
activeFilterCount > 0 && '!border-primary-200 !bg-primary-50 !text-primary-700',
highlightFilters &&
'border-primary-500 ring-2 ring-primary-300 bg-primary-50 text-primary-700',
)}
onClick={handleOpenFilters}
data-testid="open-filters-button"
aria-label={
activeFilterCount > 0
? `${t('search.filters', 'Filters')} (${activeFilterCount})`
: t('search.filters', 'Filters')
}
>
<IoFilterSharp className="h-4 w-4 sm:mr-1.5" />
<span className="hidden sm:inline">{t('search.filters', 'Filters')}</span>
{activeFilterCount > 0 && (
<span
className="ml-1.5 flex h-[18px] min-w-[18px] items-center justify-center rounded-full bg-primary-100 px-1 text-[11px] font-medium text-primary-700"
data-testid="active-filter-count"
>
{activeFilterCount}
</span>
)}
</Button>
<Select
ref={sortSelectRef}

View File

@@ -10,7 +10,7 @@ import {useRouter} from 'next/router'
import {ReactNode, useCallback, useEffect, useRef, useState} from 'react'
import toast from 'react-hot-toast'
import {Button} from 'web/components/buttons/button'
import {FiltersElement} from 'web/components/filters/filters'
import {FiltersElement, getActiveFilterCount} from 'web/components/filters/filters'
import {Search} from 'web/components/filters/search'
import {useFilters} from 'web/components/filters/use-filters'
import {Col} from 'web/components/layout/col'
@@ -267,6 +267,12 @@ export function ProfilesHome() {
const showDockedFilters = isDesktop && openFiltersModal
const activeFilterCount = getActiveFilterCount(
filters,
locationFilterProps,
raisedInLocationFilterProps,
)
return (
<div className={clsx(showDockedFilters && 'lg:grid lg:grid-cols-12 lg:gap-4')}>
<Col className={clsx(showDockedFilters && 'lg:col-span-9')}>
@@ -362,6 +368,7 @@ export function ProfilesHome() {
bookmarkedSearches={bookmarkedSearches}
refreshBookmarkedSearches={refreshBookmarkedSearches}
profileCount={profileCount}
activeFilterCount={activeFilterCount}
filtersElement={filtersElement}
/>
{displayProfiles === undefined || compatibleProfiles === undefined ? (