feat(a11y): add aria-pressed and group semantics to filter pills
- Wrap each .filters__pills in role=group with aria-labelledby pointing to the label - Add type=button to all pill buttons - Toggle aria-pressed alongside .is-active class on click - All inactive pills start with aria-pressed=false
This commit is contained in:
@@ -9,26 +9,26 @@ const { municipios, temas, fuentes } = Astro.props;
|
||||
|
||||
<div class="filters" id="filters">
|
||||
<div class="filters__group">
|
||||
<span class="filters__label">Municipi</span>
|
||||
<div class="filters__pills" data-filter-type="municipio">
|
||||
<button class="pill is-active" data-value="">Tots</button>
|
||||
{municipios.map((m) => <button class="pill" data-value={m}>{m}</button>)}
|
||||
<span class="filters__label" id="filter-label-municipi">Municipi</span>
|
||||
<div class="filters__pills" role="group" aria-labelledby="filter-label-municipi" data-filter-type="municipio">
|
||||
<button type="button" class="pill is-active" aria-pressed="true" data-value="">Tots</button>
|
||||
{municipios.map((m) => <button type="button" class="pill" aria-pressed="false" data-value={m}>{m}</button>)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="filters__group">
|
||||
<span class="filters__label">Tema</span>
|
||||
<div class="filters__pills" data-filter-type="tema">
|
||||
<button class="pill is-active" data-value="">Tots</button>
|
||||
{temas.map((t) => <button class="pill" data-value={t}>{t}</button>)}
|
||||
<span class="filters__label" id="filter-label-temes">Tema</span>
|
||||
<div class="filters__pills" role="group" aria-labelledby="filter-label-temes" data-filter-type="tema">
|
||||
<button type="button" class="pill is-active" aria-pressed="true" data-value="">Tots</button>
|
||||
{temas.map((t) => <button type="button" class="pill" aria-pressed="false" data-value={t}>{t}</button>)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="filters__group">
|
||||
<span class="filters__label">Font</span>
|
||||
<div class="filters__pills" data-filter-type="fuente">
|
||||
<button class="pill is-active" data-value="">Totes</button>
|
||||
{fuentes.map((f) => <button class="pill" data-value={f}>{f}</button>)}
|
||||
<span class="filters__label" id="filter-label-fonts">Font</span>
|
||||
<div class="filters__pills" role="group" aria-labelledby="filter-label-fonts" data-filter-type="fuente">
|
||||
<button type="button" class="pill is-active" aria-pressed="true" data-value="">Totes</button>
|
||||
{fuentes.map((f) => <button type="button" class="pill" aria-pressed="false" data-value={f}>{f}</button>)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -120,10 +120,12 @@ const { municipios, temas, fuentes } = Astro.props;
|
||||
const type = group?.dataset.filterType as keyof FilterState | undefined;
|
||||
if (!type) return;
|
||||
|
||||
for (const sibling of group!.querySelectorAll('.pill')) {
|
||||
for (const sibling of group!.querySelectorAll<HTMLButtonElement>('.pill')) {
|
||||
sibling.classList.remove('is-active');
|
||||
sibling.setAttribute('aria-pressed', 'false');
|
||||
}
|
||||
btn.classList.add('is-active');
|
||||
btn.setAttribute('aria-pressed', 'true');
|
||||
state[type] = btn.dataset.value ?? '';
|
||||
apply();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user