diff --git a/.changeset/hip-flies-pretend.md b/.changeset/hip-flies-pretend.md new file mode 100644 index 0000000000..1ab0ad0753 --- /dev/null +++ b/.changeset/hip-flies-pretend.md @@ -0,0 +1,5 @@ +--- +"@primer/view-components": patch +--- + +Give inputs unique ids so that SR doesn't skip Label announcement diff --git a/app/lib/primer/forms/dsl/multi_input.rb b/app/lib/primer/forms/dsl/multi_input.rb index 0ec1d4562f..880cb988db 100644 --- a/app/lib/primer/forms/dsl/multi_input.rb +++ b/app/lib/primer/forms/dsl/multi_input.rb @@ -39,7 +39,9 @@ def decorate_options(name:, **options) new_options[:data] ||= {} new_options[:data][:name] = name new_options[:data][:targets] = "primer-multi-input.fields" - new_options[:id] = nil if options[:hidden] + new_options[:id] = "#{@name}_#{name}" + new_options[:aria] ||= {} + new_options[:aria][:labelledby] = "label-#{base_id}" new_options[:disabled] = true if options[:hidden] # disable to avoid submitting to server new_options end diff --git a/app/lib/primer/forms/form_control.html.erb b/app/lib/primer/forms/form_control.html.erb index e714631301..b45d88c902 100644 --- a/app/lib/primer/forms/form_control.html.erb +++ b/app/lib/primer/forms/form_control.html.erb @@ -1,7 +1,8 @@ <% if @input.form_control? %> <%= content_tag(@tag, **@form_group_arguments) do %> <% if @input.label %> - <%= builder.label(@input.name, **@input.label_arguments) do %> + <% label_id = @input.label_arguments[:id] || "label-#{@input.base_id}" %> + <%= builder.label(@input.name, **@input.label_arguments.merge(id: label_id)) do %> <%= @input.label %> <% if @input.required? %> diff --git a/lib/primer/accessibility.rb b/lib/primer/accessibility.rb index 033c9a8fd3..2aaa616128 100644 --- a/lib/primer/accessibility.rb +++ b/lib/primer/accessibility.rb @@ -32,6 +32,10 @@ module Accessibility per_component: { Primer::Alpha::ToggleSwitch => { all_scenarios: %i[button-name] + }, + + Primer::Alpha::MultiInput => { + visually_hide_label: %i[label-title-only] } } } @@ -46,6 +50,8 @@ def ignore_preview?(preview_class) end def axe_rules_to_skip(component: nil, scenario_name: nil, flatten: false) + scenario_key = scenario_name.is_a?(String) ? scenario_name.to_sym : scenario_name + to_skip = { wont_fix: Set.new(AXE_RULES_TO_SKIP.dig(:wont_fix, :global) || []), will_fix: Set.new(AXE_RULES_TO_SKIP.dig(:will_fix, :global) || []) @@ -55,9 +61,9 @@ def axe_rules_to_skip(component: nil, scenario_name: nil, flatten: false) to_skip[:wont_fix].merge(AXE_RULES_TO_SKIP.dig(:wont_fix, :per_component, component, :all_scenarios) || []) to_skip[:will_fix].merge(AXE_RULES_TO_SKIP.dig(:will_fix, :per_component, component, :all_scenarios) || []) - if scenario_name - to_skip[:wont_fix].merge(AXE_RULES_TO_SKIP.dig(:wont_fix, :per_component, component, scenario_name) || []) - to_skip[:will_fix].merge(AXE_RULES_TO_SKIP.dig(:will_fix, :per_component, component, scenario_name) || []) + if scenario_key + to_skip[:wont_fix].merge(AXE_RULES_TO_SKIP.dig(:wont_fix, :per_component, component, scenario_key) || []) + to_skip[:will_fix].merge(AXE_RULES_TO_SKIP.dig(:will_fix, :per_component, component, scenario_key) || []) end end diff --git a/static/info_arch.json b/static/info_arch.json index 93e6d5f3fc..0eb571cce3 100644 --- a/static/info_arch.json +++ b/static/info_arch.json @@ -5312,7 +5312,8 @@ "snapshot": "true", "skip_rules": { "wont_fix": [ - "region" + "region", + "label-title-only" ], "will_fix": [ "color-contrast" diff --git a/static/previews.json b/static/previews.json index 5a4b7c9522..1f21802777 100644 --- a/static/previews.json +++ b/static/previews.json @@ -4883,7 +4883,8 @@ "snapshot": "true", "skip_rules": { "wont_fix": [ - "region" + "region", + "label-title-only" ], "will_fix": [ "color-contrast"