Skip to content

Commit 42e49c5

Browse files
committed
fix(compare): improve facet selector accessibility
1 parent 7d69561 commit 42e49c5

File tree

2 files changed

+19
-9
lines changed

2 files changed

+19
-9
lines changed

app/components/Compare/FacetSelector.vue

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,20 @@ function isCategoryNoneSelected(category: string): boolean {
2828
<div class="space-y-3" role="group" :aria-label="$t('compare.facets.group_label')">
2929
<div v-for="category in categoryOrder" :key="category">
3030
<!-- Category header with all/none buttons -->
31-
<div class="flex items-center gap-2 mb-2">
31+
<div
32+
class="flex items-center gap-2 mb-2"
33+
role="radiogroup"
34+
:aria-label="getCategoryLabel(category)"
35+
>
3236
<span class="text-3xs text-fg-subtle uppercase tracking-wider">
3337
{{ getCategoryLabel(category) }}
3438
</span>
35-
<!-- TODO: These should be radios, since they are mutually exclusive, and currently this behavior is faked with buttons -->
3639
<ButtonBase
40+
role="radio"
3741
:aria-label="
3842
$t('compare.facets.select_category', { category: getCategoryLabel(category) })
3943
"
40-
:aria-pressed="isCategoryAllSelected(category)"
44+
:aria-checked="isCategoryAllSelected(category)"
4145
:disabled="isCategoryAllSelected(category)"
4246
@click="selectCategory(category)"
4347
size="small"
@@ -46,10 +50,11 @@ function isCategoryNoneSelected(category: string): boolean {
4650
</ButtonBase>
4751
<span class="text-2xs text-fg-muted/40">/</span>
4852
<ButtonBase
53+
role="radio"
4954
:aria-label="
5055
$t('compare.facets.deselect_category', { category: getCategoryLabel(category) })
5156
"
52-
:aria-pressed="isCategoryNoneSelected(category)"
57+
:aria-checked="isCategoryNoneSelected(category)"
5358
:disabled="isCategoryNoneSelected(category)"
5459
@click="deselectCategory(category)"
5560
size="small"
@@ -59,15 +64,20 @@ function isCategoryNoneSelected(category: string): boolean {
5964
</div>
6065

6166
<!-- Facet buttons -->
62-
<div class="flex items-center gap-1.5 flex-wrap" role="group">
63-
<!-- TODO: These should be checkboxes -->
67+
<div
68+
class="flex items-center gap-1.5 flex-wrap"
69+
role="group"
70+
:aria-label="getCategoryLabel(category)"
71+
>
6472
<ButtonBase
6573
v-for="facet in facetsByCategory[category]"
6674
:key="facet.id"
6775
size="small"
6876
:title="facet.comingSoon ? $t('compare.facets.coming_soon') : facet.description"
6977
:disabled="facet.comingSoon"
70-
:aria-pressed="isFacetSelected(facet.id)"
78+
role="checkbox"
79+
:aria-checked="isFacetSelected(facet.id)"
80+
:aria-disabled="facet.comingSoon"
7181
:aria-label="facet.label"
7282
class="gap-1 px-1.5 rounded transition-colors focus-visible:outline-accent/70"
7383
:class="

test/nuxt/components/compare/FacetSelector.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,8 @@ describe('FacetSelector', () => {
170170

171171
const component = await mountSuspended(FacetSelector)
172172

173-
const buttons = component.findAll('button[aria-pressed]')
174-
const selectedButton = buttons.find(b => b.attributes('aria-pressed') === 'true')
173+
const buttons = component.findAll('button[aria-checked]')
174+
const selectedButton = buttons.find(b => b.attributes('aria-checked') === 'true')
175175
expect(selectedButton).toBeDefined()
176176
})
177177

0 commit comments

Comments
 (0)