← cd ../blog

Accesibilitate Angular pe mobil: Lecții din Fonoteca Pontes

Accesibilitate Angular pe mobil: Lecții din Fonoteca Pontes — imagine de copertă

Dezvoltarea unei aplicații web complexe, precum Fonoteca Pontes, pentru utilizatorii de screen reader este o călătorie fascinantă. Când am pornit la drum, foloseam Angular Material, o librărie excelentă, dar care, pe ecrane de 360px și utilizată prin VoiceOver sau TalkBack, a scos la iveală provocări neașteptate. Accesibilitatea (a11y) nu este doar un checkbox în Lighthouse, ci o experiență de utilizare continuă.

Auditul: Dincolo de scorurile Lighthouse

Am început cu axe-core și Lighthouse, dar am realizat rapid că scorul de 100 nu garantează o navigare fluidă. Testarea manuală cu TalkBack pe Android a fost „momentul adevărului”. Am găsit meniuri care „înghițeau” focusul și liste drag-and-drop care erau imposibil de parcurs. Problema principală? Interfața desktop-first nu era gândită pentru fluxul liniar al cititoarelor de ecran.

Gestionarea Focusului cu Angular CDK

Dialogurile modale sunt coșmarul oricărui utilizator de screen reader dacă focusul nu este capturat corect. Folosind cdkTrapFocus, am asigurat o experiență predictibilă în ferestrele de editare playlist:

<div cdkTrapFocus [cdkTrapFocusAutoCapture]="true" class="modal-container">
  <h2>Editează Playlist</h2>
  <!-- Conținutul formularului -->
</div>

Anunțuri dinamice: Aria-live pentru context

Când un utilizator salvează o melodie, acesta trebuie să primească feedback. Am creat o directivă simplă pentru a gestiona aria-live fără a întrerupe redarea audio:

@Directive({ selector: '[appAnnouncer]' })
export class AnnouncerDirective {
  constructor(private el: ElementRef, private renderer: Renderer2) {
    this.renderer.setAttribute(this.el.nativeElement, 'aria-live', 'polite');
    this.renderer.setAttribute(this.el.nativeElement, 'aria-atomic', 'true');
  }
}

Reordonarea listelor: Dincolo de Drag-and-Drop

Gesturile de drag-and-drop sunt adesea inaccesibile. În Fonoteca Pontes, am adăugat butoane explicite de “Mută sus” și “Mută jos”, gestionate prin FocusKeyManager pentru a menține focusul utilizatorului vizibil în timpul operațiunilor de reordonare.

// Exemplu logică mutare item
moveItem(index: number, direction: 'up' | 'down') {
  const newIndex = direction === 'up' ? index - 1 : index + 1;
  moveItemInArray(this.playlist, index, newIndex);
  this.announceChange(`Melodie mutată ${direction === 'up' ? 'sus' : 'jos'}`);
}

Reducerea zgomotului vizual

Am curățat ierarhia de heading-uri (<h1> la <h6>) pentru a permite utilizatorilor să sară rapid între secțiuni. Elementele decorative au primit aria-hidden="true", iar link-urile de “Sari la conținut” au devenit obligatorii pentru a evita parcurgerea repetitivă a meniului de navigare pe mobil.

Feedback-ul real: Iterația finală

După ce am implementat aceste schimbări, am invitat doi utilizatori de screen reader să testeze aplicația. Feedback-ul lor a fost neprețuit: „Acum pot naviga în 5 secunde, înainte îmi lua un minut”.

Pentru testarea automată a acestor fluxuri, recomand Testing Library:

it('afișează butonul de editare cu rolul corect', () => {
  render(PlaylistComponent);
  const btn = screen.getByRole('button', { name: /editează/i });
  expect(btn).toBeInTheDocument();
});

Accesibilitatea nu este o destinație, ci un proces de învățare continuă. Începeți prin a asculta aplicația voastră prin TalkBack sau VoiceOver – veți descoperi o perspectivă nouă care va îmbunătăți experiența tuturor utilizatorilor.