Angular Aria: Componentes Headless Accesibles
Kevin Dávila
Hace poco estuve probando con Angular Aria y me quede impresionado con lo facil que ahora es construir componentes accesibles. Si alguna vez intentaste implementar un menu, un combobox o un arbol siguiendo las WAI-ARIA guidelines, sabes que es un dolor de cabeza absoluto.
La cantidad de atributos ARIA, navegacion por teclado, manejo de foco y soporte para lectores de pantalla es abrumadora.
Angular Aria resuelve esto de una vez por todas: son directivas headless que manejan toda la complejidad de accesibilidad por ti. Tu solo traes el HTML, el CSS y la logica de negocio.
Qué es Angular Aria exactamente?
Angular Aria es una coleccion de directivas headless que implementan los patrones WAI-ARIA comunes. Las directivas se encargan de:
Interacciones por teclado: navegacion con flechas, Enter, Escape, Space.
Atributos ARIA: aria-expanded, aria-selected, aria-pressed, etc.
Manejo de foco: movimiento logico entre elementos.
Soporte para lectores de pantalla: anuncios correctos de estado y contexto.
"Angular Aria is a collection of headless, accessible directives that implement common WAI-ARIA patterns. The directives handle keyboard interactions, ARIA attributes, focus management, and screen reader support" - Source: https://angular.dev/guide/aria/overview
Instalación
# terminal
npm install @angular/aria
Simple. Sin configuracion adicional.
Los 12 patrones disponibles
Angular Aria v22 incluye directivas para los patrones interactivos mas comunes:
Busqueda y seleccion
Componente | Descripcion |
|---|---|
Autocomplete | Input de texto con sugerencias filtradas |
Listbox | Lista de opciones single o multi-select |
Select | Dropdown de seleccion unica |
Multiselect | Dropdown de seleccion multiple |
Combobox | Input coordinado con un popup |
Navegacion y acciones
Componente | Descripcion |
|---|---|
Menu | Dropdown menus con submenus anidados |
Menubar | Barra de navegacion horizontal persistente |
Toolbar | Grupo de controles con navegacion logica |
Organizacion de contenido
Componente | Descripcion |
|---|---|
Accordion | Paneles de contenido colapsables |
Tabs | Interfaces con pestanas |
Tree | Listas jerarquicas con expand/collapse |
Grid | Datos bidimensionales con navegacion celda por celda |
Ejemplo real: Toolbar con formato de texto
Veamos como se construye un toolbar de formato de texto (como el de un editor de texto). Sin Angular Aria, esto requeriria cientos de lineas de codigo para manejar teclado, ARIA y foco. Con Angular Aria:
// text-editor-toolbar.component.ts
import { Component } from '@angular/core';
import {
Toolbar,
ToolbarWidget,
ToolbarWidgetGroup,
} from '@angular/aria/toolbar';
@Component({
selector: 'app-text-editor-toolbar',
imports: [Toolbar, ToolbarWidget, ToolbarWidgetGroup],
templateUrl: './text-editor-toolbar.component.html',
styleUrl: './text-editor-toolbar.component.css',
})
export class TextEditorToolbarComponent {}
<!-- text-editor-toolbar.component.html -->
<div [ngToolbar] aria-label="Text Formatting Tools">
<!-- Grupo Undo/Redo -->
<div class="group">
<button
[ngToolbarWidget]
value="undo"
type="button"
aria-label="undo"
class="material-symbols-outlined"
translate="no"
>
undo
</button>
<button
[ngToolbarWidget]
value="redo"
type="button"
aria-label="redo"
class="material-symbols-outlined"
translate="no"
>
redo
</button>
</div>
<div class="separator" role="separator"></div>
<!-- Grupo Bold/Italic/Underline -->
<div class="group">
<button
[ngToolbarWidget]
value="bold"
type="button"
aria-label="bold"
#bold="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="bold.selected()"
translate="no"
>
format_bold
</button>
<button
[ngToolbarWidget]
value="italic"
type="button"
aria-label="italic"
#italic="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="italic.selected()"
translate="no"
>
format_italic
</button>
<button
[ngToolbarWidget]
value="underlined"
type="button"
aria-label="underlined"
#underlined="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="underlined.selected()"
translate="no"
>
format_underlined
</button>
</div>
<div class="separator" role="separator"></div>
<!-- Grupo Alineacion (radio group) -->
<div [ngToolbarWidgetGroup] role="radiogroup" class="group" aria-label="Text alignment options">
<button
[ngToolbarWidget]
role="radio"
type="button"
value="align left"
aria-label="align left"
#leftAlign="ngToolbarWidget"
class="material-symbols-outlined"
[aria-checked]="leftAlign.selected()"
translate="no"
>
format_align_left
</button>
<button
[ngToolbarWidget]
role="radio"
type="button"
value="align center"
aria-label="align center"
#centerAlign="ngToolbarWidget"
class="material-symbols-outlined"
[aria-checked]="centerAlign.selected()"
translate="no"
>
format_align_center
</button>
<button
[ngToolbarWidget]
role="radio"
type="button"
value="align right"
aria-label="align right"
#rightAlign="ngToolbarWidget"
class="material-symbols-outlined"
[aria-checked]="rightAlign.selected()"
translate="no"
>
format_align_right
</button>
</div>
</div>
/* text-editor-toolbar.component.css */
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: center;
}
[ngToolbar] {
gap: 1.5rem;
display: flex;
padding: 0.5rem 1rem;
border-radius: 0.5rem;
background-color: #f5f5f5;
}
.group {
gap: 0.5rem;
display: flex;
}
.separator {
width: 1px;
align-self: center;
height: calc(100% - 1rem);
background-color: #e0e0e0;
}
[ngToolbarWidget] {
border: none;
cursor: pointer;
padding: 0.5rem;
border-radius: 4px;
font-size: 1.25rem;
background-color: transparent;
color: #333;
}
[ngToolbarWidget]:hover {
background-color: rgba(0, 0, 0, 0.08);
}
[ngToolbarWidget]:active {
background-color: rgba(0, 0, 0, 0.12);
}
[ngToolbarWidget]:focus {
outline-offset: -1px;
outline: 2px solid #1976d2;
}
[ngToolbarWidget][aria-pressed="true"],
[ngToolbarWidget][aria-checked="true"] {
color: #1976d2;
background-color: rgba(25, 118, 210, 0.1);
}
Que hace Angular Aria automaticamente por ti?
Navegacion por teclado: las flechas mueven el foco entre widgets, Enter/Space activa.
aria-pressed y aria-checked: se actualizan automaticamente basados en el estado del widget.
Radio groups: ToolbarWidgetGroup maneja la logica de radio buttons (solo uno seleccionado).
RTL support: la navegacion con flechas se invierte automaticamente en idiomas right-to-left.
Focus trapping: el foco se mantiene dentro del toolbar mientras lo usas.
Cuando usar Angular Aria
Angular Aria brilla cuando necesitas:
Construir un design system: tu equipo mantiene una libreria de componentes con estandares visuales especificos que necesitan implementaciones accesibles.
Librerias de componentes enterprise: creas componentes reutilizables para multiples aplicaciones dentro de una organizacion.
Requisitos de marca personalizados: la interfaz debe coincidir con especificaciones de diseno precisas que las librerias pre-estilizadas no pueden acomodar facilmente.
Cuando NO usar Angular Aria
Componentes pre-estilizados: si necesitas componentes que se vean completos sin CSS custom, usa Angular Material.
Formularios simples: los controles nativos de HTML como <button> y <input type="radio"> ya proporcionan accesibilidad para casos basicos.
Prototipado rapido: cuando validas conceptos rapido, las librerias pre-estilizadas reducen el tiempo de desarrollo inicial.
"Angular Aria works well when you need accessible interactive components that are WCAG compliant with custom styling" - Source: https://angular.dev/guide/aria/overview
Angular Aria vs Angular CDK vs Angular Material
Criterio | Angular Aria | Angular CDK | Angular Material |
|---|---|---|---|
Estilos incluidos | No | No | Si |
Accesibilidad completa | Si | Parcial | Si |
Customizacion visual | Total | Total | Limitada |
Patrones ARIA | 12 patrones | Behaviors genericos | Componentes completos |
Curva de aprendizaje | Baja | Media | Baja |
Mi recomendacion: si estas construyendo un design system custom, Angular Aria es el camino. Si necesitas algo rapido y bonito sin esfuerzo, Angular Material sigue siendo la opcion.
Accesibilidad: no es opcional
Segun la OMS, mas de 1000 millones de personas viven con alguna discapacidad. En muchos paises, la accesibilidad web no es solo buena practica, es ley (ADA en Estados Unidos, EAA en Europa).
Angular Aria hace que cumplir con WCAG sea mas facil que nunca. No necesitas ser un experto en accesibilidad: las directivas implementan los patrones correctos por ti.
Conclusión
Angular Aria representa un cambio fundamental en como construimos componentes interactivos accesibles. En lugar de confiar en que cada desarrollador implemente correctamente los patrones WAI-ARIA (spoiler: la mayoria no lo hace), Angular proporciona directivas probadas que hacen el trabajo pesado.
Si estas construyendo un sistema de componentes, dale una oportunidad a Angular Aria. Tus usuarios con discapacidades (y tu equipo de QA) te lo van a agradecer.
Para mas contenido sobre Angular y buenas practicas, visita Codea Bien.
Referencias adicionales:
SEO
Keywords: Angular Aria, componentes headless Angular, accesibilidad web Angular, WAI-ARIA Angular, design system Angular, componentes accesibles
Meta description: Aprende a construir componentes interactivos accesibles con Angular Aria. 12 patrones WAI-ARIA implementados como directivas headless. Toolbar, Menu, Combobox y mas.