diff --git a/.changeset/chatty-pants-hang.md b/.changeset/chatty-pants-hang.md new file mode 100644 index 0000000000..68c4b2e8ab --- /dev/null +++ b/.changeset/chatty-pants-hang.md @@ -0,0 +1,5 @@ +--- +'@primer/view-components': patch +--- + +Fix incorrect label `for` attribute value when `scope_id_false: false` diff --git a/app/lib/primer/forms/dsl/input.rb b/app/lib/primer/forms/dsl/input.rb index 14203a8364..6392febe8f 100644 --- a/app/lib/primer/forms/dsl/input.rb +++ b/app/lib/primer/forms/dsl/input.rb @@ -58,7 +58,6 @@ def initialize(builder:, form:, **system_arguments) @input_arguments = system_arguments @input_arguments.delete(:id) unless @input_arguments[:id].present? @label_arguments = @input_arguments.delete(:label_arguments) || {} - @label_arguments[:for] = id if id.present? @label_arguments[:class] = class_names( @label_arguments[:class], @@ -102,6 +101,8 @@ def initialize(builder:, form:, **system_arguments) end # rubocop:enable Style/IfUnlessModifier + @label_arguments[:for] = @input_arguments[:id] + # Whether or not to wrap the component in a FormControl, which renders a # label above and validation message beneath the input. @form_control = @input_arguments.delete(:form_control) { true } diff --git a/test/lib/primer/forms/input_test.rb b/test/lib/primer/forms/input_test.rb index 830c0b3134..d786ab1e2d 100644 --- a/test/lib/primer/forms/input_test.rb +++ b/test/lib/primer/forms/input_test.rb @@ -104,6 +104,34 @@ def test_removes_model_scope_from_name_and_id end assert_selector "input#ultimate_answer[name=ultimate_answer]" + assert_selector "label[for=ultimate_answer]" + end + + def test_removes_model_scope_from_name_and_id_using_namespace + model = DeepThought.new(42) + + render_in_view_context do + primer_form_with(model: model, url: "/foo", namespace: "baz") do |f| + render(NoModelScopeForm.new(f)) + end + end + + assert_selector "input#baz_ultimate_answer[name=ultimate_answer]" + end + + def test_label_removes_model_scope_from_name_and_id_using_namespace + # See upstream issue: https://github.com/rails/rails/pull/51237 + skip "Broken in Rails versions prior to 8.0.3" unless Rails::VERSION::STRING >= "8.0.3" + + model = DeepThought.new(42) + + render_in_view_context do + primer_form_with(model: model, url: "/foo", namespace: "baz") do |f| + render(NoModelScopeForm.new(f)) + end + end + + assert_selector "label[for=baz_ultimate_answer]" end def test_uses_given_id @@ -116,5 +144,33 @@ def test_uses_given_id end assert_selector "input#foobar[name=ultimate_answer]" + assert_selector "label[for=foobar]" + end + + def test_uses_given_id_and_namespace + model = DeepThought.new(42) + + render_in_view_context do + primer_form_with(model: model, url: "/foo", namespace: "baz") do |f| + render(NoModelScopeForm.new(f, id: "foobar")) + end + end + + assert_selector "input#baz_foobar[name=ultimate_answer]" + end + + def test_label_uses_given_id_and_namespace + # See upstream issue: https://github.com/rails/rails/pull/51237 + skip "Broken in Rails versions prior to 8.0.3" unless Rails::VERSION::STRING >= "8.0.3" + + model = DeepThought.new(42) + + render_in_view_context do + primer_form_with(model: model, url: "/foo", namespace: "baz") do |f| + render(NoModelScopeForm.new(f, id: "foobar")) + end + end + + assert_selector "label[for=baz_foobar]" end end