app/helpers/govuk_link_helper.rb
require "html_attributes_utils"
module GovukLinkHelper
using HTMLAttributesUtils
def govuk_link_to(a, b = nil, new_tab: false, inverse: false, muted: false, no_underline: false, no_visited_state: false, text_colour: false, visually_hidden_prefix: nil, visually_hidden_suffix: nil, **kwargs, &block)
(block_given?) ? (name, href = nil, a) : (name, href = a, b)
link_args = extract_link_args(new_tab:, inverse:, muted:, no_underline:, no_visited_state:, text_colour:, **kwargs)
link_text = build_text(name, new_tab:, visually_hidden_prefix:, visually_hidden_suffix:)
if block_given?
link_to(href, **link_args, &block)
else
link_to(link_text, href, **link_args)
end
end
def govuk_mail_to(a, b = nil, inverse: false, muted: false, no_underline: false, no_visited_state: false, text_colour: false, visually_hidden_prefix: nil, visually_hidden_suffix: nil, **kwargs, &block)
(block_given?) ? (email_address, name = a, nil) : (email_address, name = a, b)
link_args = extract_link_args(inverse:, muted:, no_underline:, no_visited_state:, text_colour:, **kwargs)
link_text = build_text(name, visually_hidden_prefix:, visually_hidden_suffix:)
mail_to(email_address, link_text, **link_args, &block)
end
def govuk_button_to(a, b = nil, disabled: false, inverse: false, secondary: false, warning: false, visually_hidden_prefix: nil, visually_hidden_suffix: nil, **kwargs, &block)
(block_given?) ? (name, href = nil, a) : (name, href = a, b)
button_args = extract_button_args(new_tab: false, disabled:, inverse:, secondary:, warning:, **kwargs)
button_text = build_text(name, visually_hidden_prefix:, visually_hidden_suffix:)
if block_given?
button_to(href, **button_args, &block)
else
button_to(button_text, href, **button_args)
end
end
def govuk_button_link_to(a, b = nil, new_tab: false, disabled: false, inverse: false, secondary: false, warning: false, visually_hidden_prefix: nil, visually_hidden_suffix: nil, **kwargs, &block)
(block_given?) ? (name, href = nil, a) : (name, href = a, b)
button_args = extract_button_link_args(new_tab:, disabled:, inverse:, secondary:, warning:, **kwargs)
button_text = build_text(name, new_tab:, visually_hidden_prefix:, visually_hidden_suffix:)
if block_given?
link_to(href, **button_args, &block)
else
link_to(button_text, href, **button_args)
end
end
def govuk_breadcrumb_link_to(name, href = nil, **kwargs, &block)
link_args = { class: "#{brand}-breadcrumbs__link" }.deep_merge_html_attributes(kwargs)
link_to(name, href, **link_args, &block)
end
def govuk_footer_link_to(name, href = nil, **kwargs, &block)
link_args = { class: "#{brand}-footer__link" }.deep_merge_html_attributes(kwargs)
link_to(name, href, **link_args, &block)
end
def govuk_link_classes(inverse: false, muted: false, no_underline: false, no_visited_state: false, text_colour: false)
if [text_colour, inverse, muted].count(true) > 1
fail("links can be only be one of text_colour, inverse or muted")
end
class_names(
"#{brand}-link",
"#{brand}-link--inverse" => inverse,
"#{brand}-link--muted" => muted,
"#{brand}-link--no-underline" => no_underline,
"#{brand}-link--no-visited-state" => no_visited_state,
"#{brand}-link--text-colour" => text_colour,
)
end
def govuk_button_classes(inverse: false, secondary: false, warning: false)
if [inverse, secondary, warning].count(true) > 1
fail("buttons can only be one of inverse, secondary or warning")
end
class_names(
"#{brand}-button",
"#{brand}-button--inverse" => inverse,
"#{brand}-button--secondary" => secondary,
"#{brand}-button--warning" => warning,
)
end
private
def new_tab_args(new_tab)
new_tab != false ? { target: "_blank", rel: "noreferrer noopener" } : {}
end
def button_attributes(disabled)
disabled ? { disabled: true, aria: { disabled: true } } : {}
end
def extract_link_args(new_tab: false, inverse: false, muted: false, no_underline: false, no_visited_state: false, text_colour: false, **kwargs)
Rails.logger.warn(actions_warning_message(kwargs.fetch(:action))) if kwargs.key?(:action)
Rails.logger.warn(controller_warning_message(kwargs.fetch(:controller))) if kwargs.key?(:controller)
link_classes = extract_link_classes(inverse:, muted:, no_underline:, no_visited_state:, text_colour:)
{ **link_classes, **new_tab_args(new_tab) }.deep_merge_html_attributes(kwargs)
end
def extract_button_link_args(new_tab: false, disabled: false, inverse: false, secondary: false, warning: false, **kwargs)
Rails.logger.warn(actions_warning_message(kwargs.fetch(:action))) if kwargs.key?(:action)
Rails.logger.warn(controller_warning_message(kwargs.fetch(:controller))) if kwargs.key?(:controller)
button_classes = extract_button_classes(inverse:, secondary:, warning:)
data_attributes = build_data_attributes("#{brand}-button")
{ **button_classes, **data_attributes, **button_attributes(disabled), **new_tab_args(new_tab) }.deep_merge_html_attributes(kwargs)
end
def extract_button_args(disabled: false, inverse: false, secondary: false, warning: false, prevent_double_click: nil, **kwargs)
button_classes = extract_button_classes(inverse:, secondary:, warning:)
data_attributes = build_data_attributes("#{brand}-button", prevent_double_click:)
{ **button_classes, **data_attributes, **button_attributes(disabled) }.deep_merge_html_attributes(kwargs)
end
def extract_link_classes(inverse: false, muted: false, no_underline: false, no_visited_state: false, text_colour: false)
{
class: govuk_link_classes(
inverse:,
muted:,
no_underline:,
no_visited_state:,
text_colour:,
)
}
end
def extract_button_classes(inverse: false, secondary: false, warning: false)
{
class: govuk_button_classes(
inverse:,
secondary:,
warning:
)
}
end
def brand
Govuk::Components.brand
end
def build_text(text, visually_hidden_prefix:, visually_hidden_suffix:, new_tab: false)
return nil if text.nil?
prefix = (visually_hidden_prefix.present?) ? visually_hidden_prefix + " " : nil
suffix = (visually_hidden_suffix.present?) ? " " + visually_hidden_suffix : nil
parts = [govuk_visually_hidden(prefix), text, govuk_visually_hidden(suffix), new_tab_text(new_tab)]
safe_join(parts.compact)
end
def new_tab_text(new_tab)
return if new_tab.blank?
text = if new_tab == true
Govuk::Components.config.default_link_new_tab_text
else
new_tab
end
return if text.blank?
text.starts_with?(" ") ? text : " " + text
end
def actions_warning_message(value)
"action: '#{value}' parameter detected Support for old style controller/action links has been removed. See https://github.com/x-govuk/govuk-components/releases/tag/v5.0.0"
end
def controller_warning_message(value)
"controller: '#{value}' parameter detected. Support for old style controller/action links has been removed. See https://github.com/x-govuk/govuk-components/releases/tag/v5.0.0"
end
def build_data_attributes(data_module, prevent_double_click: nil)
{
data: {
module: data_module,
"prevent-double-click": prevent_double_click
}.compact
}
end
end
ActiveSupport.on_load(:action_view) { include GovukLinkHelper }