From 4618f3491b45286f26eb7559684bdebb2905d2cd Mon Sep 17 00:00:00 2001 From: kolaente Date: Sun, 12 Apr 2026 14:18:57 +0200 Subject: [PATCH] feat(a11y): associate form errors with input fields Adds aria-invalid, aria-describedby, and role='alert' to error messages in FormField and Password components so screen readers announce validation errors. Fixes WCAG 3.3.1 (Error Identification). --- frontend/src/components/input/FormField.vue | 17 +++++++++++++++-- frontend/src/components/input/Password.vue | 7 ++++++- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/input/FormField.vue b/frontend/src/components/input/FormField.vue index ee23a61ce..389e8bde6 100644 --- a/frontend/src/components/input/FormField.vue +++ b/frontend/src/components/input/FormField.vue @@ -35,6 +35,7 @@ const slots = useSlots() const generatedId = useId() const inputId = computed(() => props.id ?? generatedId) +const errorId = computed(() => props.error ? `${inputId.value}-error` : undefined) const hasAddon = computed(() => !!slots.addon) const fieldClasses = computed(() => [ @@ -82,13 +83,18 @@ defineExpose({ class="two-col" > {{ label }} - + @@ -109,13 +115,18 @@ defineExpose({ {{ label }}
- + @@ -129,7 +140,9 @@ defineExpose({ diff --git a/frontend/src/components/input/Password.vue b/frontend/src/components/input/Password.vue index e0c1977cc..6e77a3d2e 100644 --- a/frontend/src/components/input/Password.vue +++ b/frontend/src/components/input/Password.vue @@ -9,6 +9,8 @@ :type="passwordFieldType" :autocomplete="autocomplete" :tabindex="tabindex" + :aria-invalid="isValid !== true ? true : undefined" + :aria-describedby="errorId" @keyup.enter="e => $emit('submit', e)" @focusout="() => {validate(); validateAfterFirst = true}" @keyup="() => {validateAfterFirst ? validate() : null}" @@ -25,14 +27,16 @@