Skip to content

Commit 5877f1b

Browse files
committed
Fix alignment of InputGroups with error messages
1 parent 132bcdf commit 5877f1b

5 files changed

Lines changed: 47 additions & 0 deletions

File tree

.changeset/many-sheep-yell.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@openproject/primer-view-components': patch
3+
---
4+
5+
Align Primer::OpenProject::InputGroup with error messages

app/components/primer/open_project/input_group.html.erb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@
44
<%= trailing_action %>
55
<% end %>
66

7+
<% if @text_input_validation_message %>
8+
<div class="FormControl-inlineValidation mt-1" id="<%= @text_input_validation_message_id %>">
9+
<span class="FormControl-inlineValidation--visual">
10+
<%= render(Primer::Beta::Octicon.new(icon: :"alert-fill", size: :xsmall, aria: { hidden: true })) %>
11+
</span>
12+
<span><%= @text_input_validation_message %></span>
13+
</div>
14+
<% end %>
15+
716
<% if caption %>
817
<%= caption %>
918
<% end %>

app/components/primer/open_project/input_group.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,19 @@ class InputGroup < Primer::Component
4949
renders_one :text_input, lambda { |readonly: true, **system_arguments|
5050
deny_single_argument(:input_width, "Set the `input_width` on the `InputGroup`", **system_arguments)
5151
deny_single_argument(:caption, "Set the `caption` on the `InputGroup`", **system_arguments)
52+
53+
# Extract validation_message so it can be rendered outside the flex row.
54+
# This prevents the trailing action from misaligning when validation is present.
55+
@text_input_validation_message = system_arguments.delete(:validation_message)
56+
if @text_input_validation_message
57+
@text_input_validation_message_id = self.class.generate_id(base_name: "input-group-validation")
58+
system_arguments[:invalid] = true
59+
system_arguments[:aria] = merge_aria(
60+
system_arguments,
61+
{ aria: { describedby: @text_input_validation_message_id } }
62+
)
63+
end
64+
5265
system_arguments[:input_width] = @system_arguments[:input_width]
5366

5467
system_arguments[:classes] = class_names(

previews/primer/open_project/input_group_preview.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,15 @@ def with_caption
7171
menu.with_caption { "Some caption" }
7272
end
7373
end
74+
75+
# @label With error message
76+
# @snapshot
77+
def with_error_message
78+
render(Primer::OpenProject::InputGroup.new) do |menu|
79+
menu.with_text_input(name: "a name", label: "My input group", validation_message: "Custom validation message", value: "Copyable value")
80+
menu.with_trailing_action_clipboard_copy_button(id: "button", value: "Copyable value", aria: { label: "Copy some text" })
81+
end
82+
end
7483
end
7584
end
7685
end

test/components/primer/open_project/input_group_test.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,17 @@ def test_renders_caption
5353
assert_selector(".FormControl-caption")
5454
end
5555

56+
def test_renders_validation_message_outside_flex_row
57+
render_inline(Primer::OpenProject::InputGroup.new) do |menu|
58+
menu.with_text_input(name: "a name", label: "My input group", value: "Copyable value", validation_message: "Custom validation message")
59+
menu.with_trailing_action_clipboard_copy_button(id: "button", value: "Copyable value", aria: { label: "Copy some text" })
60+
end
61+
62+
validation_id = page.find(".InputGroup > .FormControl-inlineValidation", text: "Custom validation message")[:id]
63+
assert_selector(%(.FormControl-input[aria-describedby~="#{validation_id}"]))
64+
assert_selector(".FormControl-input[aria-invalid]")
65+
end
66+
5667
def test_does_not_render_caption_from_system_argument
5768
render_inline(Primer::OpenProject::InputGroup.new(caption: "Some caption")) do |menu|
5869
menu.with_text_input(name: "a name", label: "My input group", value: "Copyable value")

0 commit comments

Comments
 (0)