diff --git a/app/components/dsfr/button_component.rb b/app/components/dsfr/button_component.rb index fd020e52a..64e1e6d85 100644 --- a/app/components/dsfr/button_component.rb +++ b/app/components/dsfr/button_component.rb @@ -1,12 +1,59 @@ class Dsfr::ButtonComponent < ApplicationComponent private - def initialize(label:, form: nil, url: nil, class_names: []) - @form = form - @label = label - @url = url - @class_names = Array(class_names) + attr_reader :label, :url, :form, :html_options + + # Mimic link_to signature link_to, except when form keyword is given for a submit, or when rendering a collection of buttons. + # + # `fr-btn` class is always added. + # + # Examples of usage: + # + # A link as a button, with any html option: + # Dsfr::ButtonComponent.new("My link", "http://example.com", class: "fr-btn--secondary", title: "Link title") + # + # With external: true option which appends target="_blank", rel="noopener noreferrer" to html options: + # Dsfr::ButtonComponent.new("My link", "http://example.com", class: "fr-btn--lg fr-btn--mb-1w", external: true) + # + # A submit button for a given form, (accept also any html option): + # Dsfr::ButtonComponent.new("My submit", form: $form-builder-instance) + # + # A collection of button rendered: + # Dsfr::ButtonComponent.with_collection([ + # { label: "My link 1", url: "http://example.com" }, + # { label: "My link 2", url: "http://example2.com", class: "fr-btn--secondary" } + # ]) + # + def initialize(label = nil, url = nil, form: nil, external: nil, button: nil, **html_options) + if button.present? + assign_attributes(**button) + else + assign_attributes(label:, form:, url:, html_options:, external:) + end end - attr_reader :form, :url, :label, :class_names + def assign_attributes(label: nil, url: nil, form: nil, html_options: {}, external: false) + @label = label + @url = url + @form = form + @external = external + + @html_options = build_all_html_options(html_options) + end + + def build_all_html_options(input_html_options) + class_names = Array(input_html_options.delete(:class)).push("fr-btn") + + external_attributes.merge(class: class_names.join(" "), **input_html_options) + end + + def external_attributes + return {} unless external? + + { target: "_blank", rel: "noopener noreferrer" } + end + + def external? + @external + end end diff --git a/app/components/dsfr/button_component/button_component.html.haml b/app/components/dsfr/button_component/button_component.html.haml index b4d48b632..38b5f6bfc 100644 --- a/app/components/dsfr/button_component/button_component.html.haml +++ b/app/components/dsfr/button_component/button_component.html.haml @@ -1,5 +1,5 @@ - if form - = form.submit label, class: "fr-btn #{class_names.join(" ")}" + = form.submit label, html_options - elsif url - = link_to label, url, class: "fr-btn #{class_names.join(" ")}" + = link_to label, url, html_options diff --git a/app/views/administrateurs/services/_form.html.haml b/app/views/administrateurs/services/_form.html.haml index c11e2a2ce..efa06dc43 100644 --- a/app/views/administrateurs/services/_form.html.haml +++ b/app/views/administrateurs/services/_form.html.haml @@ -72,6 +72,6 @@ = hidden_field_tag :procedure_id, procedure_id .send-wrapper.justify-content--space-between.send-wrapper--with-border-top.my-0.py-3 - = render Dsfr::ButtonComponent.new(label: "Annuler et revenir à la page de suivi", url: admin_procedure_path(id: @procedure.id), class_names: ['fr-btn--secondary']) - = render Dsfr::ButtonComponent.new(form: f, label: "Enregistrer", class_names: ['']) + = render Dsfr::ButtonComponent.new("Annuler et revenir à la page de suivi", admin_procedure_path(id: @procedure.id), class: "fr-btn--secondary") + = render Dsfr::ButtonComponent.new("Enregistrer", form: f) diff --git a/app/views/administrateurs/services/index.html.haml b/app/views/administrateurs/services/index.html.haml index 87104eedb..b31071186 100644 --- a/app/views/administrateurs/services/index.html.haml +++ b/app/views/administrateurs/services/index.html.haml @@ -13,7 +13,7 @@ %th{ scope: "col" } Nom %th.change{ scope: "col" } - = render Dsfr::ButtonComponent.new(label: "Nouveau service", url: new_admin_service_path(procedure_id: @procedure.id), class_names: ['fr-btn--secondary']) + = render Dsfr::ButtonComponent.new("Nouveau service", new_admin_service_path(procedure_id: @procedure.id), class: "fr-btn--secondary") %tbody - @services.each do |service|