Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add heading options to radio component #635

Merged
merged 1 commit into from
Nov 22, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
useful summary for people upgrading their application, not a replication
of the commit log.

## Unreleased

- Add heading options to radio component (PR #635)

## 12.12.1

* Corrects name for checkboxes documentation (PR #638)
Expand Down
146 changes: 82 additions & 64 deletions app/views/govuk_publishing_components/components/_radio.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -3,91 +3,109 @@
items ||= []

label ||= nil
heading ||= nil
is_page_heading ||= false
hint ||= nil
error_message ||= nil
error_items ||= nil

has_error = error_message || error_items&.any?
hint_id = "hint-#{SecureRandom.hex(4)}"
hint_id = "hint-#{SecureRandom.hex(4)}" if hint
error_id = "error-#{SecureRandom.hex(4)}"

form_group_css_classes = %w(govuk-form-group)
form_group_css_classes << "govuk-form-group--error" if has_error

aria = "#{hint_id} #{"#{error_id}" if has_error}".strip if hint or has_error

# check if any item is set as being conditional
has_conditional = items.any? { |item| item.is_a?(Hash) && item[:conditional] }
%>
<%= content_tag :div, class: form_group_css_classes do %>
<%= tag.fieldset class: "govuk-fieldset", "aria-describedby": aria do %>

<% if hint %>
<%= render "govuk_publishing_components/components/hint", {
id: hint_id,
text: hint
} %>
<% end %>
<% if heading.present? %>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bit pedantic but can the indenting match what it was? It seems to have gained two spaces which is making this diff confusing because blocks without changes are showing up as different.

Copy link
Contributor Author

@andysellick andysellick Nov 22, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, appreciate that it's confusing. I had to add a fieldset element to wrap the radios so I think the indenting is correct, unless I've missed something? I think you can set the PR to ignore whitespace changes when reviewing changes if that helps.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, yep, it's the fieldset that's doing it. Sorry, missed that. Ignore this comment.

<% if is_page_heading %>
<%= tag.legend class: "govuk-fieldset__legend govuk-fieldset__legend--xl gem-c-title gem-c-title--margin-bottom-5" do %>
<%= tag.h1 heading, class: "gem-c-title__text" %>
<% end %>
<% else %>
<%= tag.legend heading, class: "govuk-fieldset__legend govuk-fieldset__legend--m" %>
<% end %>
<% end %>

<% if error_message %>
<%= render "govuk_publishing_components/components/error_message", {
id: error_id,
text: error_message
} %>
<% elsif error_items %>
<%= render "govuk_publishing_components/components/error_message", {
id: error_id,
text: raw(error_items.map { |item| item[:text] }.join("<br/>"))
} %>
<% end %>
<% if hint %>
<%= render "govuk_publishing_components/components/hint", {
id: hint_id,
text: hint
} %>
<% end %>

<%= content_tag :div, class: "govuk-radios",
data: {
module: ('radios' if has_conditional)
} do %>
<% items.each_with_index do |item, index| %>
<% if item === :or %>
<div class="gem-c-radios__divider govuk-radios__divider">
<%= t('components.radio.or') %>
</div>
<% else %>
<%
item_next = items[index + 1] unless index === items.size - 1
label_id = item[:id] ? item[:id] : "#{id_prefix}-#{index}"
label_hint_id = "label-hint-#{SecureRandom.hex(4)}" if item[:hint_text].present?
conditional_id = "conditional-#{SecureRandom.hex(4)}" if item[:conditional].present?
<% if error_message %>
<%= render "govuk_publishing_components/components/error_message", {
id: error_id,
text: error_message
} %>
<% elsif error_items %>
<%= render "govuk_publishing_components/components/error_message", {
id: error_id,
text: raw(error_items.map { |item| item[:text] }.join("<br/>"))
} %>
<% end %>

<%= content_tag :div, class: "govuk-radios",
data: {
module: ('radios' if has_conditional)
} do %>
<% items.each_with_index do |item, index| %>
<% if item === :or %>
<div class="gem-c-radios__divider govuk-radios__divider">
<%= t('components.radio.or') %>
</div>
<% else %>
<%
item_next = items[index + 1] unless index === items.size - 1
label_id = item[:id] ? item[:id] : "#{id_prefix}-#{index}"
label_hint_id = "label-hint-#{SecureRandom.hex(4)}" if item[:hint_text].present?
conditional_id = "conditional-#{SecureRandom.hex(4)}" if item[:conditional].present?

data_attrs = { "aria-controls": conditional_id }
data_attrs["tracking-url"] = item[:url] if item.key?(:url)
%>
<%= tag.div class: %w( gem-c-radio govuk-radios__item ) do %>
<%= check_box_tag name,
item[:value],
item[:checked],
{
class: "govuk-radios__input",
id: label_id,
type: "radio",
aria: {
describedby: label_hint_id
},
data: data_attrs,
}
data_attrs = { "aria-controls": conditional_id }
data_attrs["tracking-url"] = item[:url] if item.key?(:url)
%>
<%= render "govuk_publishing_components/components/label", {
hint_id: label_hint_id,
html_for: label_id,
classes: "govuk-radios__label",
hint_text_classes: "govuk-radios__hint",
hint_text: item[:hint_text],
text: item[:text],
bold: item[:bold]
} %>
<% end %>
<%= tag.div class: %w( gem-c-radio govuk-radios__item ) do %>
<%= check_box_tag name,
item[:value],
item[:checked],
{
class: "govuk-radios__input",
id: label_id,
type: "radio",
aria: {
describedby: label_hint_id
},
data: data_attrs,
}
%>
<%= render "govuk_publishing_components/components/label", {
hint_id: label_hint_id,
html_for: label_id,
classes: "govuk-radios__label",
hint_text_classes: "govuk-radios__hint",
hint_text: item[:hint_text],
text: item[:text],
bold: item[:bold]
} %>
<% end %>

<% if item[:conditional] %>
<div class="govuk-radios__conditional" id="<%= conditional_id %>">
<%= item[:conditional] %>
</div>
<% end %>
<% if item[:conditional] %>
<div class="govuk-radios__conditional" id="<%= conditional_id %>">
<%= item[:conditional] %>
</div>
<% end %>

<% end %>
<% end %>
<% end %>

<% end %>
<% end %>
66 changes: 61 additions & 5 deletions app/views/govuk_publishing_components/components/docs/radio.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,61 @@ examples:
text: "Use GOV.UK Verify"
hint_text: "You'll have an account if you've already proved your identity with a certified company, such as the Post Office."
bold: true
with_hint_text:
with_hint_on_form_group:
data:
name: "radio-group-error"
id_prefix: "hint"
hint: "You’ll need to prove your identity using one of the following methods"
items:
- value: "government-gateway"
text: "Use Government Gateway"
- value: "govuk-verify"
text: "Use GOV.UK Verify"
with_heading:
description: This adds a legend element containing the text supplied.
data:
name: "radio-group-heading"
heading: "Are you hungry?"
items:
- value: "yes"
text: "Yes"
- value: "no"
text: "No"
with_heading_and_hint:
data:
name: "radio-group-heading"
heading: "What is your favourite colour?"
hint: "If your favourite is not below, pick the colour closest to it."
items:
- value: "red"
text: "Red"
- value: "green"
text: "Green"
- value: "blue"
text: "Blue"
with_page_heading:
description: This adds a H1 element containing the text supplied.
data:
name: "radio-group-heading"
heading: "Is it raining?"
is_page_heading: true
items:
- value: "yes"
text: "Yes"
- value: "no"
text: "No"
with_page_heading_and_hint:
data:
name: "radio-group-heading"
heading: "Is it snowing?"
is_page_heading: true
hint: "Sleet or hail doesn’t count."
items:
- value: "yes"
text: "Yes"
- value: "no"
text: "No"
with_hint_text_on_radios:
data:
name: "radio-group-hint-text"
items:
Expand Down Expand Up @@ -120,21 +174,23 @@ examples:
hint_text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus sapien justo, lobortis elementum tortor in, luctus interdum turpis. Nam sit amet nulla nec arcu condimentum dapibus quis varius metus. Suspendisse cursus tristique diam et vestibulum. Proin nec lacinia tortor. Morbi at nisi id lorem aliquam ullamcorper. Pellentesque laoreet sit amet leo sodales ultricies. Suspendisse maximus efficitur odio in tristique."
text: "Quisque tincidunt venenatis bibendum. Morbi volutpat magna euismod ipsum consequat cursus. Etiam bibendum interdum ultricies."
bold: true
with_hint_on_form_group:
with_error_on_form_group:
data:
name: "radio-group-error"
id_prefix: "hint"
hint: "You’ll need to prove your identity using one of the following methods"
id_prefix: "error"
error_message: "Please select one option"
items:
- value: "government-gateway"
text: "Use Government Gateway"
- value: "govuk-verify"
text: "Use GOV.UK Verify"
with_error_on_form_group:
with_error_and_hint_on_form_group:
description: ""
data:
name: "radio-group-error"
id_prefix: "error"
error_message: "Please select one option"
hint: "Choose the option that suits"
items:
- value: "government-gateway"
text: "Use Government Gateway"
Expand Down
64 changes: 64 additions & 0 deletions spec/components/radio_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ def component_name

assert_select ".govuk-radios__input[name=radio-group-one-item]"
assert_select ".govuk-radios__item:first-child .govuk-radios__label", text: "Use Government Gateway"
assert_select "legend", false
assert_select "legend h1", false
end

it "renders radio-group with multiple items" do
Expand All @@ -51,6 +53,34 @@ def component_name
assert_select ".govuk-radios__item:last-child .govuk-radios__label", text: "Use GOV.UK Verify"
end

it "renders radio-group with a legend" do
render_component(
name: "favourite-smartie",
heading: "What is your favourite smartie?",
items: [
{ label: "Red", value: "red" },
{ label: "Blue", value: "blue" }
]
)
assert_select ".govuk-radios"
assert_select "legend", "What is your favourite smartie?"
assert_select "legend h1", false
end

it "renders radio-group with the legend as the page heading" do
render_component(
name: "favourite-skittle",
heading: "What is your favourite skittle?",
is_page_heading: true,
items: [
{ label: "Red", value: "red" },
{ label: "Blue", value: "blue" }
]
)
assert_select ".govuk-radios"
assert_select "legend h1", "What is your favourite skittle?"
end

it "renders radio-group with bold labels" do
render_component(
name: "radio-group-bold-labels",
Expand Down Expand Up @@ -199,6 +229,10 @@ def component_name
)

assert_select ".govuk-hint", text: "You’ll need to prove your identity using one of the following methods"

dom = Nokogiri::HTML(rendered)
hint_id = dom.xpath('//span')[0].attr('id')
assert_select ".govuk-fieldset[aria-describedby='#{hint_id}']"
end

it "renders radio-group with error message" do
Expand All @@ -218,6 +252,36 @@ def component_name
)

assert_select ".govuk-error-message", text: "Please select one option"

dom = Nokogiri::HTML(rendered)
error_id = dom.xpath('//span')[0].attr('id')
assert_select ".govuk-fieldset[aria-describedby='#{error_id}']"
end

it "renders radio-group with error message and hint text" do
render_component(
name: "radio-group-conditional",
hint: "You’ll need to prove your identity using one of the following methods",
error_message: "Please select one option",
items: [
{
value: "government-gateway",
text: "Use Government Gateway"
},
{
value: "govuk-verify",
text: "Use GOV.UK Verify"
}
]
)

assert_select ".govuk-error-message", text: "Please select one option"

dom = Nokogiri::HTML(rendered)
hint_id = dom.xpath('//span')[0].attr('id')
error_id = dom.xpath('//span')[1].attr('id')
ids = hint_id + " " + error_id
assert_select ".govuk-fieldset[aria-describedby='#{ids}']"
end

it "renders radio-group with error items" do
Expand Down