refactor(dsfr/button_component): more modular & signature more like link_to

This commit is contained in:
Colin Darie 2022-09-06 19:12:21 +02:00
parent c4a769d72d
commit 0e28a3870a
4 changed files with 58 additions and 11 deletions

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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|