Skip to content

Commit

Permalink
accordion: allow specifying the default header level
Browse files Browse the repository at this point in the history
Closes #171
  • Loading branch information
freesteph committed Jan 21, 2025
1 parent ac2bb37 commit c57b7c6
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 28 deletions.
9 changes: 8 additions & 1 deletion app/components/dsfr_component/accordion_component.rb
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
class DsfrComponent::AccordionComponent < DsfrComponent::Base
DEFAULT_HEADER_LEVEL = 3

attr_reader :starting_header_level

renders_many :sections, ->(title: nil, expanded: false, id: nil, classes: [], html_attributes: {}, &block) do
DsfrComponent::AccordionComponent::SectionComponent.new(
classes: classes,
expanded: expanded,
html_attributes: html_attributes,
title: title,
id: id,
starting_header_level: starting_header_level,
&block
)
end

def initialize(classes: [], html_attributes: {})
def initialize(classes: [], html_attributes: {}, starting_header_level: DEFAULT_HEADER_LEVEL)
@starting_header_level = starting_header_level

super(classes: classes, html_attributes: html_attributes)
end

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<%= tag.section(**html_attributes) do %>
<h3 class="fr-accordion__title">
<%= tag.send("h#{starting_header_level}", class: "fr-accordion__title") do %>
<button
class="fr-accordion__btn"
aria-expanded="<%= expanded? ? "true" : "false" %>"
aria-controls="<%= id %>"
class="fr-accordion__btn"
aria-expanded="<%= expanded? ? "true" : "false" %>"
aria-controls="<%= id %>"
>
<%= title %>
</button>
</h3>
<% end %>
<div
id="<%= id %>"
class="fr-collapse <%= "fr-collapse--expanded" if expanded? %>"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
class DsfrComponent::AccordionComponent::SectionComponent < DsfrComponent::Base
attr_reader :title, :expanded
attr_reader :title, :expanded, :starting_header_level

alias_method :expanded?, :expanded

# @param title [String] section title
# @param expanded [Boolean] toggles section folding
# @param id [String] the HTML id, optional if you want to reuse the anchor
def initialize(title:, expanded: false, id: nil, classes: [], html_attributes: {})
def initialize(
title:,
starting_header_level:,
expanded: false,
id: nil,
classes: [],
html_attributes: {}
)
@title = title
@expanded = expanded
@id = id
@starting_header_level = starting_header_level

super(classes: classes, html_attributes: html_attributes)
end
Expand Down
25 changes: 16 additions & 9 deletions guide/content/components/accordion.haml
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@
title: Accordéon
---

%p
Les accordéons permettent aux utilisateurs d'afficher et de masquer des sections de contenu
présentés dans une page.

= render('/partials/example.haml',
caption: "Accordéon section unique",
code: accordion_single) do
.fr-text-wrap
:markdown
Vous pouvez aussi utiliser le helper `dsfr_accordion` avec une unique section.
La section sera alors wrappée par une div `fr-accordions-group` invisible.
Les accordéons permettent aux utilisateurs d'afficher et de masquer des sections de contenu
présentés dans une page.

En conformité avec la documentation officielle en bas de page, ce composant :

* introduit des niveaux de titre : assurez-vous de **respecter la hiérarchie de la page** ;
* ne doit pas être utilisé pour du contenu que vos utilisateurs devraient lire ;
* ne doit pas être utilisé pour un contenu très court : utilisez des listes ou paragraphes.

= render('/partials/example.haml',
caption: "Accordéon avec trois sections",
Expand All @@ -21,4 +21,11 @@ title: Accordéon
L'attribut `id` est optionnel et permet de définir une ancre HTML réutilisable.
S'il n'est pas passé un `id` aléatoire sera généré.

= render('/partials/example.haml',
caption: "Accordéon avec niveau de titre personnalisé",
code: accordion_custom_header_level) do
:markdown
Si le niveau de titre par défaut (`H3`) ne vous convient pas, vous pouvez le surcharger en passant l'option `starting_header_level`.


= render('/partials/related-info.haml', links: dsfr_component_doc_link("Accordéons", "accordeon"))
11 changes: 7 additions & 4 deletions guide/lib/examples/accordion_helpers.rb
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
module Examples
module AccordionHelpers
def accordion_single
def accordion_normal
<<~ACCORDION
= dsfr_accordion_section(title: "Un") { tag.p("Premier contenu") }
= dsfr_accordion do |accordion|
- accordion.with_section(title: "Un") { tag.p("Premier contenu") }
- accordion.with_section(title: "Deux", id: "section-deux") { tag.p("Deuxième contenu") }
- accordion.with_section(title: "Trois", expanded: true) { tag.p("Troisième contenu déplié") }
ACCORDION
end

def accordion_normal
def accordion_custom_header_level
<<~ACCORDION
= dsfr_accordion do |accordion|
= dsfr_accordion(starting_header_level: 2) do |accordion|
- accordion.with_section(title: "Un") { tag.p("Premier contenu") }
- accordion.with_section(title: "Deux", id: "section-deux") { tag.p("Deuxième contenu") }
- accordion.with_section(title: "Trois", expanded: true) { tag.p("Troisième contenu déplié") }
Expand Down
10 changes: 10 additions & 0 deletions spec/components/dsfr_component/accordion_component_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,16 @@
end
end

context "when the default header level is overriden" do
it "renders matching sections" do
render_inline(DsfrComponent::AccordionComponent.new(starting_header_level: 2)) do |component|
component.with_section(title: "Un", id: "test-un") { "Premier contenu" }
end

expect(rendered_content).to have_tag('h2')
end
end

context "with an expanded section" do
subject! do
render_inline(DsfrComponent::AccordionComponent.new) do |component|
Expand Down
7 changes: 0 additions & 7 deletions spec/helpers/dsfr_components_helper_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,6 @@ def initialize(helper_method:, klass:, args:, kwargs:, css_matcher:, block: nil)
args: [],
kwargs: {},
css_matcher: %(.fr-accordions-group)
},
{
helper_method: :dsfr_accordion_section,
klass: DsfrComponent::AccordionComponent::SectionComponent,
args: [],
kwargs: { title: "Section Un" },
css_matcher: %(.fr-accordion)
}
]
.map { |h| HelperComponentMapping.new(**h) }
Expand Down

0 comments on commit c57b7c6

Please sign in to comment.