El problema
Varios componentes exponen el nombre accesible como una prop label opcional. Si
quien consume el componente no la pasa, el elemento queda sin nombre accesible
y no hay nada en la librería que lo advierta: no falla el build, no falla el lint y
no falla ningún test.
Los casos que encontramos hasta ahora:
ch-modal — un diálogo modal sin label se anuncia solo como «diálogo». Es
el caso más grave, porque un modal siempre necesita nombre y, como el encabezado
va en un slot en el light DOM, no se puede referenciar con aria-labelledby a
través del shadow boundary. No existe un valor por defecto razonable.
ch-button — un botón de solo icono sin label queda sin nombre.
ch-spinner — sin label queda decorativo (aria-hidden), lo que acá sí es
intencional y correcto.
O sea: el mismo patrón («label opcional») significa cosas distintas según el
componente. En ch-spinner la ausencia es una decisión válida; en ch-modal y en
un ch-button de solo icono es un bug de accesibilidad silencioso.
Por qué conviene resolverlo a nivel de librería
Hoy los 16 componentes declaran label?: string. No hay ninguna prop obligatoria
en la librería y tampoco hay precedente de console.warn en ningún componente. Por
eso preferimos no inventar un mecanismo nuevo en un solo componente: quedaría
inconsistente con los otros 15 y el próximo componente repetiría el problema.
La decisión que hay que tomar es transversal, no de ch-modal.
Opciones a discutir
- Prop obligatoria en el tipo — declarar
@Prop() label!: string en los
componentes donde la ausencia nunca es válida. Da error de compilación a quien
consume desde TypeScript/JSX, pero no protege a quien usa HTML directo.
- Advertencia en desarrollo — un
console.warn cuando falta el nombre. Avisa
en todos los casos, incluido HTML directo, pero es un patrón nuevo para la
librería y hay que definir dónde vive para no repetirlo en cada componente.
- Convención documentada solamente — dejarlo en
docs/components.md y en el
JSDoc de cada prop. Es lo que hay hoy; no evita el error.
- Una mezcla — tipo obligatorio donde se pueda, más una advertencia
compartida para el resto.
También hay que decidir qué hacer con el caso «el label y el encabezado del slot
pueden decir cosas distintas», que hoy nada mantiene sincronizado.
Estado
Lo dejamos como discussion porque la respuesta define una convención para toda la
librería y conviene acordarla antes de tocar 16 componentes. Salió de la revisión de
#20; ahí ch-modal quedó con
label opcional para no divergir del resto, y documentado en docs/components.md
como una prop que hay que pasar siempre.
El problema
Varios componentes exponen el nombre accesible como una prop
labelopcional. Siquien consume el componente no la pasa, el elemento queda sin nombre accesible
y no hay nada en la librería que lo advierta: no falla el build, no falla el lint y
no falla ningún test.
Los casos que encontramos hasta ahora:
ch-modal— un diálogo modal sinlabelse anuncia solo como «diálogo». Esel caso más grave, porque un modal siempre necesita nombre y, como el encabezado
va en un slot en el light DOM, no se puede referenciar con
aria-labelledbyatravés del shadow boundary. No existe un valor por defecto razonable.
ch-button— un botón de solo icono sinlabelqueda sin nombre.ch-spinner— sinlabelqueda decorativo (aria-hidden), lo que acá sí esintencional y correcto.
O sea: el mismo patrón («
labelopcional») significa cosas distintas según elcomponente. En
ch-spinnerla ausencia es una decisión válida; ench-modaly enun
ch-buttonde solo icono es un bug de accesibilidad silencioso.Por qué conviene resolverlo a nivel de librería
Hoy los 16 componentes declaran
label?: string. No hay ninguna prop obligatoriaen la librería y tampoco hay precedente de
console.warnen ningún componente. Poreso preferimos no inventar un mecanismo nuevo en un solo componente: quedaría
inconsistente con los otros 15 y el próximo componente repetiría el problema.
La decisión que hay que tomar es transversal, no de
ch-modal.Opciones a discutir
@Prop() label!: stringen loscomponentes donde la ausencia nunca es válida. Da error de compilación a quien
consume desde TypeScript/JSX, pero no protege a quien usa HTML directo.
console.warncuando falta el nombre. Avisaen todos los casos, incluido HTML directo, pero es un patrón nuevo para la
librería y hay que definir dónde vive para no repetirlo en cada componente.
docs/components.mdy en elJSDoc de cada prop. Es lo que hay hoy; no evita el error.
compartida para el resto.
También hay que decidir qué hacer con el caso «el
labely el encabezado del slotpueden decir cosas distintas», que hoy nada mantiene sincronizado.
Estado
Lo dejamos como
discussionporque la respuesta define una convención para toda lalibrería y conviene acordarla antes de tocar 16 componentes. Salió de la revisión de
#20; ahí
ch-modalquedó conlabelopcional para no divergir del resto, y documentado endocs/components.mdcomo una prop que hay que pasar siempre.