Skip to content
Merged
Original file line number Diff line number Diff line change
@@ -1,16 +1,4 @@
<%#
yields: Link text (required).
locals:
* url: URL of link.
* new_tab: Whether link should open in a new tab. Defaults to false. Use best judgment to reserve
new tabs to when absolutely necessary, such as when form data may otherwise be lost.
%>
<% content = yield.presence or raise 'no block content given'
new_tab = local_assigns.fetch(:new_tab, false)
tag_attrs = { href: url, class: ['usa-link', 'block-link'] }
tag_attrs[:target] = '_blank' if new_tab
tag_attrs[:class] << 'usa-link--external' if new_tab %>
<%= tag.a(**tag_attrs) do %>
<%= tag.a(**tag_options, href: url, class: css_class, target: target) do %>
<%= content %>
<% if new_tab %>
<span class="usa-sr-only"><%= t('links.new_window') %></span>
Expand Down
19 changes: 19 additions & 0 deletions app/components/block_link_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
class BlockLinkComponent < BaseComponent
attr_reader :url, :new_tab, :tag_options

def initialize(url:, new_tab: false, **tag_options)
@url = url
@new_tab = new_tab
@tag_options = tag_options
end

def css_class
classes = ['usa-link', 'block-link', *tag_options[:class]]
classes << 'usa-link--external' if new_tab
classes
end

def target
'_blank' if new_tab
end
end
2 changes: 1 addition & 1 deletion app/components/status_page_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class StatusPageComponent < BaseComponent
renders_many :action_buttons, ->(**button_options) do
ButtonComponent.new(**button_options, big: true, wide: true)
end
renders_one :troubleshooting_options
renders_one :troubleshooting_options, TroubleshootingOptionsComponent

attr_reader :status, :icon

Expand Down
8 changes: 8 additions & 0 deletions app/components/troubleshooting_options_component.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<%= tag.section(**tag_options, class: css_class) do %>
<%= header %>
<ul class="troubleshooting-options__options">
<% options.each do |option| %>
<li><%= option %></li>
<% end %>
</ul>
<% end %>
30 changes: 30 additions & 0 deletions app/components/troubleshooting_options_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
class TroubleshootingOptionsComponent < BaseComponent
renders_one :header, 'TroubleshootingOptionsHeadingComponent'
renders_many :options, BlockLinkComponent

attr_reader :tag_options

def initialize(**tag_options)
@tag_options = tag_options
end

def render?
options?
end

def css_class
['troubleshooting-options', *tag_options[:class]]
end

class TroubleshootingOptionsHeadingComponent < BaseComponent
attr_reader :heading_level

def initialize(heading_level: :h2)
@heading_level = heading_level
end

def call
content_tag(heading_level, content, class: 'troubleshooting-options__heading')
end
end
end
16 changes: 3 additions & 13 deletions app/views/shared/_troubleshooting_options.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,7 @@ locals:
* options: List of link options to display, as an array of hashes with `url`, `text`, `new_tab` values.
* class: Additional class names to add to wrapper element.
%>
<% if local_assigns[:options].presence %>
<% heading_tag = local_assigns[:heading_tag] || :h2 %>
<% classes = ['troubleshooting-options', *local_assigns[:class]] %>
<%= tag.section class: classes do %>
<%= content_tag(heading_tag, heading, class: 'troubleshooting-options__heading') %>
<ul class="troubleshooting-options__options">
<% options.each do |option| %>
<li>
<%= render('shared/block_link', **option.except(:text)) { option[:text] } %>
</li>
<% end %>
</ul>
<% end %>
<%= render TroubleshootingOptionsComponent.new(class: local_assigns[:class]) do |c| %>
<% c.header(heading_level: local_assigns[:heading_tag] || :h2).with_content(heading) %>
<% options.each { |option| c.option(**option.except(:text)).with_content(option[:text]) } %>
<% end %>
27 changes: 10 additions & 17 deletions app/views/two_factor_authentication/_locked.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,15 @@
) %>
</p>

<% c.troubleshooting_options do %>
<%= render(
'shared/troubleshooting_options',
heading: t('components.troubleshooting_options.default_heading'),
options: [
{
text: t('two_factor_authentication.read_about_two_factor_authentication'),
url: MarketingSite.help_url,
new_tab: true,
},
{
url: MarketingSite.contact_url,
text: t('idv.troubleshooting.options.contact_support', app_name: APP_NAME),
new_tab: true,
},
],
) %>
<% c.troubleshooting_options do |tc| %>
<% tc.header { t('components.troubleshooting_options.default_heading') } %>
<% tc.option(
url: MarketingSite.help_url,
new_tab: true,
).with_content(t('two_factor_authentication.read_about_two_factor_authentication')) %>
<% tc.option(
url: MarketingSite.contact_url,
new_tab: true,
).with_content(t('idv.troubleshooting.options.contact_support', app_name: APP_NAME)) %>
<% end %>
<% end %>
31 changes: 31 additions & 0 deletions spec/components/block_link_component_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
require 'rails_helper'

RSpec.describe BlockLinkComponent, type: :component do
it 'renders a link' do
rendered = render_inline BlockLinkComponent.new(url: '/').with_content('Link Text')

expect(rendered).to have_link('Link Text', href: '/')
expect(rendered).to have_css('.block-link.usa-link')
end

context 'with tag options' do
it 'renders a link' do
rendered = render_inline BlockLinkComponent.new(
url: '/',
class: 'my-custom-class',
data: { foo: 'bar' },
)

expect(rendered).to have_css('.block-link.usa-link.my-custom-class[data-foo="bar"]')
end
end

context 'with new tab' do
it 'renders as external' do
rendered = render_inline BlockLinkComponent.new(url: '/', new_tab: true)

expect(rendered).to have_css('.block-link.usa-link.usa-link--external[target=_blank]')
expect(rendered).to have_content(t('links.new_window'))
end
end
end
8 changes: 6 additions & 2 deletions spec/components/status_page_component_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,16 @@
)
end

it 'renders action buttons' do
it 'renders troubleshooting options' do
rendered = render_inline(StatusPageComponent.new) do |c|
c.troubleshooting_options { 'Troubleshooting' }
c.troubleshooting_options do |tc|
tc.header { 'Troubleshooting' }
tc.option(url: '/', new_tab: true) { 'Option' }
end
end

expect(rendered).to have_content('Troubleshooting')
expect(rendered).to have_link('Option', href: '/')
end

it 'raises error for unknown status' do
Expand Down
55 changes: 55 additions & 0 deletions spec/components/troubleshooting_options_component_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
require 'rails_helper'

RSpec.describe TroubleshootingOptionsComponent, type: :component do
it 'renders nothing if not given options' do
rendered = render_inline TroubleshootingOptionsComponent.new

expect(rendered.children).to be_empty
end

context 'with options' do
it 'renders troubleshooting options' do
rendered = render_inline(TroubleshootingOptionsComponent.new) do |c|
c.option(url: '/').with_content('Link Text')
end

expect(rendered).to have_css('.troubleshooting-options')
expect(rendered).to have_link('Link Text', href: '/')
end

context 'with tag options' do
it 'renders troubleshooting options' do
rendered = render_inline(
TroubleshootingOptionsComponent.new(
class: 'my-custom-class',
data: { foo: 'bar' },
),
) { |c| c.option(url: '/').with_content('Link Text') }

expect(rendered).to have_css('.troubleshooting-options.my-custom-class[data-foo="bar"]')
end
end

context 'with header' do
it 'renders header' do
rendered = render_inline(TroubleshootingOptionsComponent.new) do |c|
c.header { 'Heading' }
c.option(url: '/')
end

expect(rendered).to have_css('h2.troubleshooting-options__heading', text: 'Heading')
end

context 'with custom heading level' do
it 'renders header' do
rendered = render_inline(TroubleshootingOptionsComponent.new) do |c|
c.header(heading_level: :h3) { 'Heading' }
c.option(url: '/')
end

expect(rendered).to have_css('h3.troubleshooting-options__heading', text: 'Heading')
end
end
end
end
end
22 changes: 0 additions & 22 deletions spec/views/shared/_block_link.html.erb_spec.rb

This file was deleted.