-
Notifications
You must be signed in to change notification settings - Fork 21
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
New link helpers #419
New link helpers #419
Changes from all commits
65c7947
e925f0a
3a4ec34
ceba1d0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,157 @@ | ||||||||||||||||||||||||||
require "html_attributes_utils" | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
module GovukRailsCompatibileLinkHelper | ||||||||||||||||||||||||||
using HTMLAttributesUtils | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
def govuk_link_classes(*styles, default_class: "#{brand}-link") | ||||||||||||||||||||||||||
if (invalid_styles = (styles - link_styles.keys)) && invalid_styles.any? | ||||||||||||||||||||||||||
fail(ArgumentError, "invalid styles #{invalid_styles.to_sentence}. Valid styles are #{link_styles.keys.to_sentence}") | ||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
[default_class] + link_styles.values_at(*styles).compact | ||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
def govuk_button_classes(*styles, default_class: "#{brand}-button") | ||||||||||||||||||||||||||
if (invalid_styles = (styles - button_styles.keys)) && invalid_styles.any? | ||||||||||||||||||||||||||
fail(ArgumentError, "invalid styles #{invalid_styles.to_sentence}. Valid styles are #{button_styles.keys.to_sentence}") | ||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
[default_class] + button_styles.values_at(*styles).compact | ||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
def govuk_link_to(name = nil, options = nil, extra_options = {}, &block) | ||||||||||||||||||||||||||
extra_options = options if block_given? | ||||||||||||||||||||||||||
html_options = build_html_options(extra_options) | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
if block_given? | ||||||||||||||||||||||||||
link_to(name, html_options, &block) | ||||||||||||||||||||||||||
else | ||||||||||||||||||||||||||
link_to(name, options, html_options) | ||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||
Comment on lines
+23
to
+30
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you can avoid the
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Going to leave these as they're in the legacy implementation which will soon be dropped. |
||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
def govuk_mail_to(email_address, name = nil, extra_options = {}, &block) | ||||||||||||||||||||||||||
extra_options = name if block_given? | ||||||||||||||||||||||||||
html_options = build_html_options(extra_options) | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
if block_given? | ||||||||||||||||||||||||||
mail_to(email_address, html_options, &block) | ||||||||||||||||||||||||||
else | ||||||||||||||||||||||||||
mail_to(email_address, name, html_options) | ||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
def govuk_button_to(name = nil, options = nil, extra_options = {}, &block) | ||||||||||||||||||||||||||
extra_options = options if block_given? | ||||||||||||||||||||||||||
html_options = { | ||||||||||||||||||||||||||
data: { module: "govuk-button" } | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
if extra_options && extra_options[:prevent_double_click] | ||||||||||||||||||||||||||
html_options[:data]["prevent-double-click"] = "true" | ||||||||||||||||||||||||||
extra_options = extra_options.except(:prevent_double_click) | ||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
html_options.merge! build_html_options(extra_options, style: :button) | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
if block_given? | ||||||||||||||||||||||||||
button_to(options, html_options, &block) | ||||||||||||||||||||||||||
else | ||||||||||||||||||||||||||
button_to(name, options, html_options) | ||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
def govuk_button_link_to(name = nil, options = nil, extra_options = {}, &block) | ||||||||||||||||||||||||||
extra_options = options if block_given? | ||||||||||||||||||||||||||
html_options = { | ||||||||||||||||||||||||||
data: { module: "#{brand}-button" }, | ||||||||||||||||||||||||||
draggable: 'false', | ||||||||||||||||||||||||||
role: 'button', | ||||||||||||||||||||||||||
}.merge build_html_options(extra_options, style: :button) | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
if block_given? | ||||||||||||||||||||||||||
link_to(name, html_options, &block) | ||||||||||||||||||||||||||
else | ||||||||||||||||||||||||||
link_to(name, options, html_options) | ||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
def govuk_breadcrumb_link_to(name = nil, options = nil, extra_options = {}, &block) | ||||||||||||||||||||||||||
extra_options = options if block_given? | ||||||||||||||||||||||||||
html_options = build_html_options(extra_options, style: :breadcrumb) | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
if block_given? | ||||||||||||||||||||||||||
link_to(name, html_options, &block) | ||||||||||||||||||||||||||
else | ||||||||||||||||||||||||||
link_to(name, options, html_options) | ||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
private | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
def brand | ||||||||||||||||||||||||||
Govuk::Components.brand | ||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
def link_styles | ||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||
inverse: "#{brand}-link--inverse", | ||||||||||||||||||||||||||
muted: "#{brand}-link--muted", | ||||||||||||||||||||||||||
no_underline: "#{brand}-link--no-underline", | ||||||||||||||||||||||||||
no_visited_state: "#{brand}-link--no-visited-state", | ||||||||||||||||||||||||||
text_colour: "#{brand}-link--text-colour", | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
def button_styles | ||||||||||||||||||||||||||
{ | ||||||||||||||||||||||||||
disabled: "#{brand}-button--disabled", | ||||||||||||||||||||||||||
secondary: "#{brand}-button--secondary", | ||||||||||||||||||||||||||
warning: "#{brand}-button--warning", | ||||||||||||||||||||||||||
inverse: "#{brand}-button--inverse", | ||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
def build_html_options(provided_options, style: :link) | ||||||||||||||||||||||||||
element_styles = { link: link_styles, button: button_styles }.fetch(style, {}) | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
# we need to take a couple of extra steps here because we don't want the style | ||||||||||||||||||||||||||
# params (inverse, muted, etc) to end up as extra attributes on the link. | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
remaining_options = remove_styles_from_provided_options(element_styles, provided_options) | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
style_classes = build_style_classes(style, extract_styles_from_provided_options(element_styles, provided_options)) | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
combine_attributes(remaining_options, class_name: style_classes) | ||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
def build_style_classes(style, provided_options) | ||||||||||||||||||||||||||
keys = *provided_options&.keys | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
case style | ||||||||||||||||||||||||||
when :link then govuk_link_classes(*keys) | ||||||||||||||||||||||||||
when :button then govuk_button_classes(*keys) | ||||||||||||||||||||||||||
when :breadcrumb then "#{brand}-breadcrumbs__link" | ||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
def combine_attributes(attributes, class_name:) | ||||||||||||||||||||||||||
attributes ||= {} | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
attributes.with_indifferent_access.tap do |attrs| | ||||||||||||||||||||||||||
attrs[:class] = Array.wrap(attrs[:class]).prepend(class_name).flatten.join(" ") | ||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
def extract_styles_from_provided_options(styles, provided_options) | ||||||||||||||||||||||||||
return {} if provided_options.blank? | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
provided_options.slice(*styles.keys) | ||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
def remove_styles_from_provided_options(styles, provided_options) | ||||||||||||||||||||||||||
return {} if provided_options.blank? | ||||||||||||||||||||||||||
|
||||||||||||||||||||||||||
provided_options&.except(*styles.keys) | ||||||||||||||||||||||||||
end | ||||||||||||||||||||||||||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should these be private methods? Can't think of why you'd use them outside of a link or button helper.
If not, maybe move them below the other methods, and add a brief comment to explain what they do? It threw me a bit seeing these alongside the more obvious helper methods below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So these are exposed to make it easier for devs to use Rails' other link helpers, like
link_to_if
andlink_to_unless
,link_to_unless_current
, etc.