Skip to content

Commit 8b8d542

Browse files
authored
Fix label for attribute when not scoped to model (#3696)
1 parent 38ba08e commit 8b8d542

3 files changed

Lines changed: 34 additions & 1 deletion

File tree

.changeset/chatty-pants-hang.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@primer/view-components': patch
3+
---
4+
5+
Fix incorrect label `for` attribute value when `scope_id_to_model: false`

app/lib/primer/forms/dsl/input.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ def initialize(builder:, form:, **system_arguments)
6161
@input_arguments = system_arguments
6262
@input_arguments.delete(:id) unless @input_arguments[:id].present?
6363
@label_arguments = @input_arguments.delete(:label_arguments) || {}
64-
@label_arguments[:for] = id if id.present?
6564

6665
@label_arguments[:class] = class_names(
6766
@label_arguments[:class],
@@ -105,6 +104,11 @@ def initialize(builder:, form:, **system_arguments)
105104
end
106105
# rubocop:enable Style/IfUnlessModifier
107106

107+
# Only set `for` when the id is known. Otherwise leave it unset so
108+
# Rails generates the scoped id for both label and input; passing
109+
# `for: nil` would suppress that and drop the association.
110+
@label_arguments[:for] = @input_arguments[:id] if @input_arguments[:id].present?
111+
108112
# Whether or not to wrap the component in a FormControl, which renders a
109113
# label above and validation message beneath the input.
110114
@form_control = @input_arguments.delete(:form_control) { true }

test/lib/primer/forms/input_test.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ def test_removes_model_scope_from_name_and_id
104104
end
105105

106106
assert_selector "input#ultimate_answer[name=ultimate_answer]"
107+
assert_selector "label[for=ultimate_answer]"
107108
end
108109

109110
def test_uses_given_id
@@ -116,5 +117,28 @@ def test_uses_given_id
116117
end
117118

118119
assert_selector "input#foobar[name=ultimate_answer]"
120+
assert_selector "label[for=foobar]"
121+
end
122+
123+
class ModelScopeForm < ApplicationForm
124+
form do |model_scope_form|
125+
model_scope_form.text_field(
126+
name: :ultimate_answer,
127+
label: "Ultimate answer"
128+
)
129+
end
130+
end
131+
132+
def test_label_for_matches_scoped_id_by_default
133+
model = DeepThought.new(42)
134+
135+
render_in_view_context do
136+
primer_form_with(model: model, url: "/foo") do |f|
137+
render(ModelScopeForm.new(f))
138+
end
139+
end
140+
141+
assert_selector "input#deep_thought_ultimate_answer[name='deep_thought[ultimate_answer]']"
142+
assert_selector "label[for=deep_thought_ultimate_answer]"
119143
end
120144
end

0 commit comments

Comments
 (0)