Repository: woylie/doggo (elixir)

Issue:
aria-invalid and aria-errormessage
Update `input` component to set `aria-invalid` and `aria-errormessage` attributes. Maybe use a live region for validation errors as well.

- https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-invalid
- https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes/aria-errormessage
- https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Live_Regions

Pull request:
aria invalid errormessage
- update doc tags
- set aria-invalid and aria-errormessage attributes in input component

resolves #190 

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 215cb5d..8d38820 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -13,6 +13,8 @@
 
 ### Changed
 
+- Set `aria-invalid` and `aria-errormessage` attributes in `Doggo.input/1`
+  component.
 - Depend on `phoenix_storybook ~> 0.6.0`.
 
 ## [0.4.0] - 2023-12-31
diff --git a/lib/doggo.ex b/lib/doggo.ex
index 1de31f6..f50dbe7 100644
--- a/lib/doggo.ex
+++ b/lib/doggo.ex
@@ -2438,7 +2438,9 @@ defmodule Doggo do
           id={@id}
           value={@checked_value}
           checked={@checked}
-          aria-describedby={input_aria_describedby(@id, @errors, @description)}
+          aria-describedby={input_aria_describedby(@id, @description)}
+          aria-errormessage={input_aria_errormessage(@id, @errors)}
+          aria-invalid={@errors != [] && "true"}
           {@validations}
           {@rest}
         />
@@ -2527,7 +2529,9 @@ defmodule Doggo do
           id={@id}
           value={@checked_value}
           checked={@checked}
-          aria-describedby={input_aria_describedby(@id, @errors, @description)}
+          aria-describedby={input_aria_describedby(@id, @description)}
+          aria-errormessage={input_aria_errormessage(@id, @errors)}
+          aria-invalid={@errors != [] && "true"}
           {@validations}
           {@rest}
         />
@@ -2567,7 +2571,9 @@ defmodule Doggo do
           name={@name}
           id={@id}
           multiple={@multiple}
-          aria-describedby={input_aria_describedby(@id, @errors, @description)}
+          aria-describedby={input_aria_describedby(@id, @description)}
+          aria-errormessage={input_aria_errormessage(@id, @errors)}
+          aria-invalid={@errors != [] && "true"}
           {@validations}
           {@rest}
         >
@@ -2596,7 +2602,9 @@ defmodule Doggo do
       <textarea
         name={@name}
         id={@id}
-        aria-describedby={input_aria_describedby(@id, @errors, @description)}
+        aria-describedby={input_aria_describedby(@id, @description)}
+        aria-errormessage={input_aria_errormessage(@id, @errors)}
+        aria-invalid={@errors != [] && "true"}
         {@validations}
         {@rest}
       ><%= Phoenix.HTML.Form.normalize_value("textarea", @value) %></textarea>
@@ -2641,7 +2649,9 @@ defmodule Doggo do
           list={@options && "#{@id}_datalist"}
           type={@type}
           value={normalize_value(@type, @value)}
-          aria-describedby={input_aria_describedby(@id, @errors, @description)}
+          aria-describedby={input_aria_describedby(@id, @description)}
+          aria-errormessage={input_aria_errormessage(@id, @errors)}
+          aria-invalid={@errors != [] && "true"}
           {@validations}
           {@rest}
         />
@@ -2690,12 +2700,11 @@ defmodule Doggo do
   defp normalize_value("date", _), do: ""
   defp normalize_value(type, value), do: Form.normalize_value(type, value)
 
-  defp input_aria_describedby(_, [], []), do: nil
-  defp input_aria_describedby(id, _, []), do: field_errors_id(id)
-  defp input_aria_describedby(id, [], _), do: field_description_id(id)
+  defp input_aria_describedby(_, []), do: nil
+  defp input_aria_describedby(id, _), do: field_description_id(id)
 
-  defp input_aria_describedby(id, _, _),
-    do: "#{field_errors_id(id)} #{field_description_id(id)}"
+  defp input_aria_errormessage(_, []), do: nil
+  defp input_aria_errormessage(id, _), do: field_errors_id(id)
 
   defp field_error_class([]), do: nil
   defp field_error_class(_), do: "has-errors"
@@ -2709,7 +2718,9 @@ defmodule Doggo do
         id={@id <> "_#{@option_value}"}
         value={@option_value}
         checked={checked?(@option_value, @value)}
-        aria-describedby={input_aria_describedby(@id, @errors, @description)}
+        aria-describedby={input_aria_describedby(@id, @description)}
+        aria-errormessage={input_aria_errormessage(@id, @errors)}
+        aria-invalid={@errors != [] && "true"}
       />
       <%= @label %>
     </.label>
@@ -2741,7 +2752,9 @@ defmodule Doggo do
         id={@id <> "_#{@option_value}"}
         value={@option_value}
         checked={checked?(@option_value, @value)}
-        aria-describedby={input_aria_describedby(@id, @errors, @description)}
+        aria-describedby={input_aria_describedby(@id, @description)}
+        aria-errormessage={input_aria_errormessage(@id, @errors)}
+        aria-invalid={@errors != [] && "true"}
       />
       <%= @label %>
     </.label>


Test patch:
diff --git a/test/doggo_test.exs b/test/doggo_test.exs
index 35d4911..b215e52 100644
--- a/test/doggo_test.exs
+++ b/test/doggo_test.exs
@@ -2765,6 +2765,8 @@ defmodule DoggoTest do
       assert attribute(input, "name") == "age"
       assert attribute(input, "type") == "text"
       assert attribute(input, "aria-describedby") == nil
+      assert attribute(input, "aria-invalid") == nil
+      assert attribute(input, "aria-errormessage") == nil
 
       assert attribute(html, "label", "for") == "age"
       assert text(html, "label") == "Age"
@@ -3068,7 +3070,8 @@ defmodule DoggoTest do
         </.form>
         """)
 
-      assert attribute(html, "input", "aria-describedby") == "species_errors"
+      assert attribute(html, "input", "aria-invalid") == "true"
+      assert attribute(html, "input", "aria-errormessage") == "species_errors"
       assert attribute(html, "ul", "id") == "species_errors"
       assert attribute(html, "ul", "class") == "field-errors"
       assert text(html, ".field-errors > li") == "wrong"
@@ -3086,8 +3089,11 @@ defmodule DoggoTest do
         </.form>
         """)
 
+      assert attribute(html, "input", "aria-invalid") == "true"
+      assert attribute(html, "input", "aria-errormessage") == "species_errors"
+
       assert attribute(html, "input", "aria-describedby") ==
-               "species_errors species_description"
+               "species_description"
 
       assert attribute(html, "ul", "id") == "species_errors"
       assert attribute(html, "ul", "class") == "field-errors"