Skip to content

Commit

Permalink
Merge pull request #410 from DFE-Digital/set-accordion-section-ids-us…
Browse files Browse the repository at this point in the history
…ing-accordion-id

Use the accordion id to prefix its section ids
  • Loading branch information
peteryates authored Apr 3, 2023
2 parents d869329 + b2e1928 commit 23ffdad
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 15 deletions.
6 changes: 4 additions & 2 deletions app/components/govuk_component/accordion_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,24 @@ class GovukComponent::AccordionComponent < GovukComponent::Base
html_attributes: html_attributes,
summary_text: summary_text,
heading_text: heading_text,
accordion_id: accordion_id,
&block
)
end

attr_reader :id, :heading_level
attr_reader :accordion_id, :heading_level

def initialize(heading_level: 2, classes: [], html_attributes: {})
@heading_level = heading_tag(heading_level)
@accordion_id = html_attributes[:id]

super(classes: classes, html_attributes: html_attributes)
end

private

def default_attributes
{ class: %w(govuk-accordion), data: { module: 'govuk-accordion' } }
{ class: %w(govuk-accordion), data: { module: 'govuk-accordion' } }.compact
end

def heading_tag(level)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,29 @@
class GovukComponent::AccordionComponent::SectionComponent < GovukComponent::Base
attr_reader :heading_text, :summary_text, :expanded, :heading_level
attr_reader :heading_text, :summary_text, :expanded, :heading_level, :accordion_id

renders_one :heading_html
renders_one :summary_html

alias_method :expanded?, :expanded

def initialize(heading_text:, summary_text:, expanded:, heading_level:, classes: [], html_attributes: {})
def initialize(heading_text:, summary_text:, expanded:, heading_level:, accordion_id: nil, classes: [], html_attributes: {})
@heading_text = heading_text
@summary_text = summary_text
@expanded = expanded
@heading_level = heading_level
@accordion_id = accordion_id

super(classes: classes, html_attributes: html_attributes)
end

def id(suffix: nil)
prefix = @accordion_id

# generate a random number if we don't have heading_text to avoid attempting
# to parameterize a potentially-huge chunk of HTML
@prefix ||= heading_text&.parameterize || SecureRandom.hex(4)
@unique_identifier ||= heading_text&.parameterize || SecureRandom.hex(4)

[@prefix, suffix].compact.join('-')
[prefix, @unique_identifier, suffix].compact.join('-')
end

def heading_content
Expand Down
28 changes: 19 additions & 9 deletions spec/components/govuk_component/accordion_component_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,31 +43,41 @@
describe 'for each section' do
specify 'the heading text and content is present' do
sections.each do |heading_text, content|
expect(rendered_content).to have_tag('div', with: { class: 'govuk-accordion__section', id: %(#{heading_text.parameterize}-section) }) do
expect(rendered_content).to have_tag('div', with: { class: 'govuk-accordion__section', id: %(#{id}-#{heading_text.parameterize}-section) }) do
with_tag('h2', class: 'govuk-accordion__section-heading') do
with_tag('span', text: heading_text, with: { id: heading_text.parameterize, class: 'govuk-accordion__section-button' })
with_tag('span', text: heading_text, with: { id: %(#{id}-#{heading_text.parameterize}), class: 'govuk-accordion__section-button' })
end

with_tag('div', with: { id: %(#{heading_text.parameterize}-content), class: 'govuk-accordion__section-content' }, text: content)
with_tag('div', with: { id: %(#{id}-#{heading_text.parameterize}-content), class: 'govuk-accordion__section-content' }, text: content)
end
end
end

specify 'each section ID matches the content aria-labelledby' do
sections.each_key do |heading_text|
id = heading_text.parameterize
expected_id = %(#{id}-#{heading_text.parameterize})

expect(rendered_content).to have_tag('span', with: { id: id, class: 'govuk-accordion__section-button' })
expect(rendered_content).to have_tag('div', with: { 'aria-labelledby' => id })
expect(rendered_content).to have_tag('span', with: { id: expected_id, class: 'govuk-accordion__section-button' })
expect(rendered_content).to have_tag('div', with: { 'aria-labelledby' => expected_id })
end
end

specify 'each section ID matches the button aria-controls' do
sections.each_key do |heading_text|
id = heading_text.parameterize
expected_id = %(#{id}-#{heading_text.parameterize}-content)

expect(rendered_content).to have_tag('div', with: { id: %(#{id}-content) })
expect(rendered_content).to have_tag('span', with: { 'aria-controls' => %(#{id}-content) })
expect(rendered_content).to have_tag('div', with: { id: expected_id })
expect(rendered_content).to have_tag('span', with: { 'aria-controls' => expected_id })
end
end
end

describe 'building unique section ids' do
context 'when the accordion has an ID' do
let(:kwargs) { { html_attributes: { id: id } } }

specify 'the accordion id is prefixes the section id' do
expect(html.css('.govuk-accordion__section').map { |e| e[:id] }).to all(start_with(id))
end
end
end
Expand Down

0 comments on commit 23ffdad

Please sign in to comment.