diff --git a/lib/mv_web/live/components/add_filter_builder_component.ex b/lib/mv_web/live/components/add_filter_builder_component.ex index ccafd01e..fc1ee34b 100644 --- a/lib/mv_web/live/components/add_filter_builder_component.ex +++ b/lib/mv_web/live/components/add_filter_builder_component.ex @@ -1190,13 +1190,20 @@ defmodule MvWeb.Components.AddFilterBuilderComponent do slot :inner_block, required: true # Shared two-state join toggle used by the boolean and is/is-not controls - # (Task 5): a `join-item` button label wrapping a hidden radio, with a visible + # (Task 5): a `join-item` button label wrapping a native radio, with a visible # selected state (`btn-primary` when the radio is checked) and an optional # leading icon. Consistent look across every two-state selector. + # + # The radio is `sr-only` (visually hidden) rather than `hidden`/`display:none` + # so it stays keyboard-focusable and in the tab order: Tab reaches the group, + # native same-`name` radio semantics move the selection with the arrow keys + # (WCAG 2.1.1). `has-[:focus-visible]:*` surfaces a visible ring on the styled + # label while its input has keyboard focus (WCAG 2.4.7); `z-10` lifts the + # focused item so the ring is not clipped by adjacent join-items. defp toggle_option(assigns) do ~H""" -