feat: Add WCAG-compliant handling for boolean custom fields

This commit is contained in:
carla 2025-12-23 17:02:07 +01:00
parent e3ff3e610c
commit 4e101ea36e
2 changed files with 24 additions and 4 deletions

View file

@ -333,7 +333,8 @@ defmodule MvWeb.CoreComponents do
attr :error_class, :string, default: nil, doc: "the input error class to use over defaults"
attr :rest, :global,
include: ~w(accept autocomplete capture cols disabled form list max maxlength min minlength
include:
~w(accept autocomplete aria-required capture cols disabled form list max maxlength min minlength
multiple pattern placeholder readonly required rows size step)
def input(%{field: %Phoenix.HTML.FormField{} = field} = assigns) do
@ -353,6 +354,24 @@ defmodule MvWeb.CoreComponents do
Phoenix.HTML.Form.normalize_value("checkbox", assigns[:value])
end)
# For checkboxes, we don't use HTML required attribute (means "must be checked")
# Instead, we use aria-required for screen readers (WCAG 2.1, Success Criterion 3.3.2)
# Extract required from rest and remove it, but keep aria-required if provided
rest = assigns.rest || %{}
is_required = Map.get(rest, :required, false)
aria_required = Map.get(rest, :aria_required, if(is_required, do: "true", else: nil))
# Remove required from rest (we don't want HTML required on checkbox)
rest_without_required = Map.delete(rest, :required)
# Ensure aria-required is set if field is required
rest_final =
if aria_required,
do: Map.put(rest_without_required, :aria_required, aria_required),
else: rest_without_required
assigns = assign(assigns, :rest, rest_final)
assigns = assign(assigns, :is_required, is_required)
~H"""
<fieldset class="mb-2 fieldset">
<label>
@ -367,9 +386,9 @@ defmodule MvWeb.CoreComponents do
class={@class || "checkbox checkbox-sm"}
{@rest}
/>{@label}<span
:if={@rest[:required]}
:if={@is_required}
class="text-red-700 tooltip tooltip-right"
data-tip={gettext("This field cannot be empty")}
data-tip={gettext("This field is required")}
>*</span>
</span>
</label>