Paul Robert Lloyd
3 years ago
committed by
GitHub
20 changed files with 206 additions and 160 deletions
@ -0,0 +1,17 @@ |
|||||||
|
<nav class="app-primary-navigation" aria-label="primary"> |
||||||
|
<div class="govuk-width-container"> |
||||||
|
<ul class="app-primary-navigation__list"> |
||||||
|
<% items.each do |item| %> |
||||||
|
<% if item.fetch(:current, false) || current_page?(item.fetch(:url)) || current_page?("#{item.fetch(:url)}/details") %> |
||||||
|
<li class="app-primary-navigation__item app-primary-navigation__item--current"> |
||||||
|
<%= govuk_link_to item[:name], item[:url], class: "app-primary-navigation__link", aria: { current: "page" } %> |
||||||
|
</li> |
||||||
|
<% else %> |
||||||
|
<li class="app-primary-navigation__item"> |
||||||
|
<%= govuk_link_to item[:name], item[:url], class: "app-primary-navigation__link" %> |
||||||
|
</li> |
||||||
|
<% end %> |
||||||
|
<% end %> |
||||||
|
</ul> |
||||||
|
</div> |
||||||
|
</nav> |
@ -0,0 +1,8 @@ |
|||||||
|
class PrimaryNavigationComponent < ViewComponent::Base |
||||||
|
attr_reader :items |
||||||
|
|
||||||
|
def initialize(items:) |
||||||
|
@items = items |
||||||
|
super |
||||||
|
end |
||||||
|
end |
@ -1,15 +0,0 @@ |
|||||||
<nav class="app-tab-navigation" aria-label="sub menu"> |
|
||||||
<ul class="app-tab-navigation__list"> |
|
||||||
<% items.each do |item| %> |
|
||||||
<% if item.fetch(:current, false) || current_page?(strip_query(item.fetch(:url))) %> |
|
||||||
<li class="app-tab-navigation__item app-tab-navigation__item--current"> |
|
||||||
<%= govuk_link_to item[:name], item[:url], class: "app-tab-navigation__link", aria: { current: "page" } %> |
|
||||||
</li> |
|
||||||
<% else %> |
|
||||||
<li class="app-tab-navigation__item"> |
|
||||||
<%= govuk_link_to item[:name], item[:url], class: "app-tab-navigation__link" %> |
|
||||||
</li> |
|
||||||
<% end %> |
|
||||||
<% end %> |
|
||||||
</ul> |
|
||||||
</nav> |
|
@ -1,14 +0,0 @@ |
|||||||
class TabNavigationComponent < ViewComponent::Base |
|
||||||
attr_reader :items |
|
||||||
|
|
||||||
def initialize(items:) |
|
||||||
@items = items |
|
||||||
super |
|
||||||
end |
|
||||||
|
|
||||||
def strip_query(url) |
|
||||||
url = Addressable::URI.parse(url) |
|
||||||
url.query_values = nil |
|
||||||
url.to_s |
|
||||||
end |
|
||||||
end |
|
@ -0,0 +1,23 @@ |
|||||||
|
.app-header { |
||||||
|
border-bottom: govuk-spacing(2) solid $govuk-brand-colour; |
||||||
|
|
||||||
|
.govuk-header__logo { |
||||||
|
@include govuk-media-query($from: desktop) { |
||||||
|
width: 60%; |
||||||
|
} |
||||||
|
|
||||||
|
@include govuk-media-query($from: 860px) { |
||||||
|
width: 75%; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.govuk-header__content { |
||||||
|
@include govuk-media-query($from: desktop) { |
||||||
|
width: 40%; |
||||||
|
} |
||||||
|
|
||||||
|
@include govuk-media-query($from: 860px) { |
||||||
|
width: 25%; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,69 @@ |
|||||||
|
.app-primary-navigation { |
||||||
|
@include govuk-font(19, $weight: bold); |
||||||
|
background-color: govuk-colour("light-grey"); |
||||||
|
border-bottom: 1px solid $govuk-border-colour; |
||||||
|
} |
||||||
|
|
||||||
|
.govuk-phase-banner + .app-primary-navigation { |
||||||
|
margin-top: -1px; |
||||||
|
} |
||||||
|
|
||||||
|
.app-primary-navigation__list { |
||||||
|
@include govuk-clearfix; |
||||||
|
left: govuk-spacing(-3); |
||||||
|
list-style: none; |
||||||
|
margin: 0; |
||||||
|
padding: 0; |
||||||
|
position: relative; |
||||||
|
right: govuk-spacing(-3); |
||||||
|
width: calc(100% + #{govuk-spacing(6)}); |
||||||
|
} |
||||||
|
|
||||||
|
.app-primary-navigation__item { |
||||||
|
box-sizing: border-box; |
||||||
|
display: block; |
||||||
|
float: left; |
||||||
|
line-height: 50px; |
||||||
|
height: 50px; |
||||||
|
padding: 0 govuk-spacing(3); |
||||||
|
position: relative; |
||||||
|
} |
||||||
|
|
||||||
|
.app-primary-navigation__item--current { |
||||||
|
border-bottom: $govuk-border-width-narrow solid $govuk-link-colour; |
||||||
|
|
||||||
|
&:hover { |
||||||
|
border-bottom-color: $govuk-link-hover-colour; |
||||||
|
} |
||||||
|
|
||||||
|
&:active { |
||||||
|
border-bottom-color: $govuk-link-active-colour; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.app-primary-navigation__item--align-right { |
||||||
|
@include govuk-media-query($from: tablet) { |
||||||
|
float: right; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.app-primary-navigation__link { |
||||||
|
@include govuk-link-common; |
||||||
|
@include govuk-link-style-no-visited-state; |
||||||
|
@include govuk-link-style-no-underline; |
||||||
|
@include govuk-typography-weight-bold; |
||||||
|
|
||||||
|
// Extend the touch area of the link to the list |
||||||
|
&:after { |
||||||
|
bottom: 0; |
||||||
|
content: ""; |
||||||
|
left: 0; |
||||||
|
position: absolute; |
||||||
|
right: 0; |
||||||
|
top: 0; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
.app-primary-navigation__item--current .app-primary-navigation__link:hover { |
||||||
|
text-decoration: none; |
||||||
|
} |
@ -1,76 +0,0 @@ |
|||||||
.app-tab-navigation { |
|
||||||
@include govuk-font(19, $weight: bold); |
|
||||||
@include govuk-responsive-margin(6, "bottom"); |
|
||||||
} |
|
||||||
|
|
||||||
.app-tab-navigation__list { |
|
||||||
@include govuk-clearfix; |
|
||||||
left: govuk-spacing(-3); |
|
||||||
list-style: none; |
|
||||||
margin: 0; |
|
||||||
padding: 0; |
|
||||||
position: relative; |
|
||||||
right: govuk-spacing(-3); |
|
||||||
width: calc(100% + #{govuk-spacing(6)}); |
|
||||||
|
|
||||||
@include govuk-media-query($from: tablet) { |
|
||||||
box-shadow: inset 0 -1px 0 $govuk-border-colour; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
.app-tab-navigation__item { |
|
||||||
box-sizing: border-box; |
|
||||||
display: block; |
|
||||||
line-height: 40px; |
|
||||||
height: 40px; |
|
||||||
padding: 0 govuk-spacing(3); |
|
||||||
|
|
||||||
@include govuk-media-query($from: tablet) { |
|
||||||
box-shadow: none; |
|
||||||
display: block; |
|
||||||
float: left; |
|
||||||
line-height: 50px; |
|
||||||
height: 50px; |
|
||||||
padding: 0 govuk-spacing(3); |
|
||||||
position: relative; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
.app-tab-navigation__item--current { |
|
||||||
@include govuk-media-query($until: tablet) { |
|
||||||
border-left: 4px solid $govuk-link-colour; |
|
||||||
padding-left: 11px; |
|
||||||
} |
|
||||||
|
|
||||||
@include govuk-media-query($from: tablet) { |
|
||||||
border-bottom: 4px solid $govuk-link-colour; |
|
||||||
padding-left: govuk-spacing(3); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
.app-tab-navigation__link { |
|
||||||
@include govuk-link-common; |
|
||||||
@include govuk-link-style-no-visited-state; |
|
||||||
@include govuk-link-style-no-underline; |
|
||||||
@include govuk-typography-weight-bold; |
|
||||||
|
|
||||||
&:not(:focus):hover { |
|
||||||
color: $govuk-link-colour; |
|
||||||
} |
|
||||||
|
|
||||||
// Extend the touch area of the link to the list |
|
||||||
&:after { |
|
||||||
bottom: 0; |
|
||||||
content: ""; |
|
||||||
left: 0; |
|
||||||
position: absolute; |
|
||||||
right: 0; |
|
||||||
top: 0; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
.app-tab-navigation__item--current .app-tab-navigation__link { |
|
||||||
&:hover { |
|
||||||
text-decoration: none; |
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,27 @@ |
|||||||
|
require "rails_helper" |
||||||
|
|
||||||
|
RSpec.describe PrimaryNavigationComponent, type: :component do |
||||||
|
let(:items) do |
||||||
|
[{ name: "Organisations", url: "#", current: true }, |
||||||
|
{ name: "Users", url: "#" }, |
||||||
|
{ name: "Logs ", url: "#" }] |
||||||
|
end |
||||||
|
|
||||||
|
context "when the item is 'current' in nav tabs" do |
||||||
|
it "then that tab appears as selected" do |
||||||
|
result = render_inline(described_class.new(items:)) |
||||||
|
|
||||||
|
expect(result.css('.app-primary-navigation__link[aria-current="page"]').text).to include("Organisations") |
||||||
|
end |
||||||
|
end |
||||||
|
|
||||||
|
context "when rendering tabs" do |
||||||
|
it "all of the nav tabs specified in the items hash are passed to it" do |
||||||
|
result = render_inline(described_class.new(items:)) |
||||||
|
|
||||||
|
expect(result.text).to include("Organisations") |
||||||
|
expect(result.text).to include("Users") |
||||||
|
expect(result.text).to include("Logs") |
||||||
|
end |
||||||
|
end |
||||||
|
end |
@ -1,27 +0,0 @@ |
|||||||
require "rails_helper" |
|
||||||
|
|
||||||
RSpec.describe TabNavigationComponent, type: :component do |
|
||||||
let(:items) do |
|
||||||
[{ name: "Application", url: "#", current: true }, |
|
||||||
{ name: "Notes", url: "#" }, |
|
||||||
{ name: "Timeline", url: "#" }] |
|
||||||
end |
|
||||||
|
|
||||||
context "when the item is 'current' in nav tabs" do |
|
||||||
it "then that tab appears as selected" do |
|
||||||
result = render_inline(described_class.new(items:)) |
|
||||||
|
|
||||||
expect(result.css('.app-tab-navigation__link[aria-current="page"]').text).to include("Application") |
|
||||||
end |
|
||||||
end |
|
||||||
|
|
||||||
context "when rendering tabs" do |
|
||||||
it "all of the nav tabs specified in the items hash are passed to it" do |
|
||||||
result = render_inline(described_class.new(items:)) |
|
||||||
|
|
||||||
expect(result.text).to include("Application") |
|
||||||
expect(result.text).to include("Notes") |
|
||||||
expect(result.text).to include("Timeline") |
|
||||||
end |
|
||||||
end |
|
||||||
end |
|
Loading…
Reference in new issue