fix(mobile): announce which Show and rating chip is chosen

MChip only showed its state through colour. A pressable option renders
aria-pressed from active; the places filter's Show and rating floor chips use
it, and the tests now check the chosen chip by its pressed state.
This commit is contained in:
EvKoh
2026-10-03 15:51:34 +02:00
committed by Maurice
parent 3951e8cc9a
commit db3c9d660e
5 changed files with 21 additions and 5 deletions
+8 -1
View File
@@ -10,16 +10,23 @@ interface MChipProps {
* back what it can: the chips that start a search are the ones worth the height.
*/
size?: 'sm' | 'tap'
/**
* The chip is one choice of a picker: announce `active` as `aria-pressed`, so a
* screen reader hears which one is on, not just its colour. Off by default, for
* chips that only run an action.
*/
pressable?: boolean
className?: string
children: ReactNode
}
/** Small pill chip: --m-act when active, neutral --m-ic surface otherwise. */
export default function MChip({ active = false, onClick, size = 'sm', className = '', children }: MChipProps) {
export default function MChip({ active = false, onClick, size = 'sm', pressable = false, className = '', children }: MChipProps) {
return (
<button
type="button"
onClick={onClick}
aria-pressed={pressable ? active : undefined}
className={`inline-flex flex-none items-center gap-[6px] rounded-full font-semibold ${
size === 'tap' ? 'px-[13px] py-[10px] text-[0.8125rem]' : 'px-3 py-[7px] text-[0.75rem]'
} ${
@@ -94,7 +94,7 @@ export function MRatingFloorChips() {
return (
<div role="group" aria-label={t('places.filterByRating')} className="flex flex-wrap gap-[6px]">
{RATING_FLOORS.map(floor => (
<MChip key={String(floor)} size="tap" active={ratingFilter === floor} onClick={() => setRatingFilter(floor)}>
<MChip key={String(floor)} size="tap" pressable active={ratingFilter === floor} onClick={() => setRatingFilter(floor)}>
{floor === 'all' ? t('common.all') : (
<>
<Star size={12} strokeWidth={2.2} fill="currentColor" className="flex-none" />
@@ -61,7 +61,7 @@ export default function MPlacesFilterSheet({ open, onClose, places, categories }
<SectionTitle>{t('places.filterShow')}</SectionTitle>
<div role="group" aria-label={t('places.filterShow')} className="flex flex-wrap gap-[6px]">
{pools.map(pool => (
<MChip key={pool.id} size="tap" active={filter === pool.id} onClick={() => setFilter(pool.id)}>
<MChip key={pool.id} size="tap" pressable active={filter === pool.id} onClick={() => setFilter(pool.id)}>
{pool.label}
</MChip>
))}