Skip to content

Commit

Permalink
Add new main menu block
Browse files Browse the repository at this point in the history
This will replace the main navigation block. Have created a new block to make the diff/changes easier to process.
  • Loading branch information
AshGDS committed Nov 15, 2024
1 parent 5127521 commit 3317176
Show file tree
Hide file tree
Showing 7 changed files with 305 additions and 2 deletions.
26 changes: 26 additions & 0 deletions app/assets/javascripts/modules/app-b-main-menu.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
window.GOVUK = window.GOVUK || {}
window.GOVUK.Modules = window.GOVUK.Modules || {};

(function (Modules) {
'use strict'

function AppBMainMenu (module) {
this.module = module
this.module.button = this.module.querySelector('button')
this.module.navContainer = this.module.querySelector('#app-b-main-menu__nav-container')
this.module.button.classList.remove('app-b-main-menu__button--no-js')
}

AppBMainMenu.prototype.init = function () {
this.module.button.addEventListener('click', this.toggleMenu.bind(this))
}

AppBMainMenu.prototype.toggleMenu = function (e) {
var ariaExpanded = this.module.button.getAttribute('aria-expanded') === 'true'
this.module.navContainer.classList.toggle('app-b-main-menu__nav-container--js-hidden')
this.module.button.setAttribute('aria-expanded', `${!ariaExpanded}`)
this.module.classList.toggle('app-b-main-menu--collapsed')
}

Modules.AppBMainMenu = AppBMainMenu
})(window.GOVUK.Modules)
131 changes: 131 additions & 0 deletions app/assets/stylesheets/views/_landing_page/main-menu.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
@import "govuk_publishing_components/individual_component_support";

.app-b-main-menu {
border-bottom: 1px solid $govuk-border-colour;
@include govuk-font(19);
}

.app-b-main-menu--collapsed {
border-bottom: 0;
}

.app-b-main-menu__button-container {
background-color: govuk-colour("light-grey");
border-bottom: 1px solid govuk-colour("mid-grey");
}

.app-b-main-menu__button {
height: 70px;
color: govuk-colour("blue");
@include govuk-font(19);
background: none;
border-top: 0;
border-bottom: 0;
// Invisible border that matches the background colour is used here to keep the element width/focus styles consistent.
border-left: 1px solid govuk-colour("light-grey");
border-right: 1px solid govuk-colour("light-grey");
padding-left: govuk-spacing(2);
padding-right: govuk-spacing(2);
cursor: pointer;
position: relative;
}

// Shared styles for the expanded and collapsed arrow icon. Based off of the super navigation menu button.
.app-b-main-menu__button::before {
border-bottom: 2px solid govuk-colour("blue");
border-right: 2px solid govuk-colour("blue");
content: "";
display: inline-block;
height: 8px;
margin: 0 10px 0 2px;
vertical-align: middle;
width: 8px;
}

.app-b-main-menu__button:focus {
border-color: $govuk-focus-colour;
box-shadow: 0 0, 0 4px govuk-colour("black");
z-index: 999; // Prevents focus style black bottom border being obscured

&.app-b-main-menu__button::before {
border-color: govuk-colour("black");
}
}

.app-b-main-menu__button[aria-expanded="false"]::before {
// Collapsed arrow icon
-webkit-transform: translateY(-35%) rotate(45deg) scale(1);
-ms-transform: translateY(-35%) rotate(45deg) scale(1);
transform: translateY(-35%) rotate(45deg) scale(1);
}

.app-b-main-menu__button[aria-expanded="true"] {
border-color: govuk-colour("mid-grey");
background-color: govuk-colour("white");

// Expanded arrow icon
&.app-b-main-menu__button::before {
-webkit-transform: translateY(1px) rotate(225deg) scale(1);
-ms-transform: translateY(1px) rotate(225deg) scale(1);
transform: translateY(1px) rotate(225deg) scale(1);
}
}

.app-b-main-menu__button[aria-expanded="true"]:focus {
background-color: $govuk-focus-colour;
border-color: $govuk-focus-colour;
}

// Adds a white border at the bottom of the button when the button is expanded. Used to make the button look like a tab that's seamlessly connected to element below it.
.app-b-main-menu__button[aria-expanded="true"]::after {
content: "";
position: absolute;
border-bottom: 1px solid govuk-colour("white");
width: 100%;
left: 0;
bottom: -1px;
}

// Removes the white border on bottom of button when focus styles are active.
.app-b-main-menu__button[aria-expanded="true"]:focus::after {
border: 0;
}

.app-b-main-menu__button--no-js {
display: none;
}

.app-b-main-menu__button:hover::before {
border-color: govuk-colour("dark-blue");
}

.app-b-main-menu__nav-container {
margin-top: govuk-spacing(4);
}

.js-enabled {
.app-b-main-menu__nav-container--js-hidden {
display: none;
}
}

.app-b-main-menu__list {
padding-left: 0;
display: grid;
column-gap: govuk-spacing(7);
row-gap: govuk-spacing(4);

@include govuk-media-query($from: mobile) {
grid-template-columns: 1fr 1fr;
}
@include govuk-media-query($from: tablet) {
grid-template-columns: 1fr 1fr 1fr;
}
}

.app-b-main-menu__list-item {
list-style: none;
@include govuk-media-query($until: mobile) {
margin-top: govuk-spacing(3);
}
}
13 changes: 13 additions & 0 deletions app/models/landing_page/block/main_menu.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module LandingPage::Block
class MainMenu < Base
attr_reader :links

def initialize(block_hash, landing_page)
super
end

def full_width?
true
end
end
end
26 changes: 26 additions & 0 deletions app/views/landing_page/blocks/_main_menu.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<%
add_view_stylesheet("landing_page/main-menu")
%>
<div class="app-b-main-menu app-b-main-menu--collapsed" data-module="app-b-main-menu">
<div class="app-b-main-menu__button-container">
<div class="govuk-width-container">
<button type="button" class="app-b-main-menu__button app-b-main-menu__button--no-js govuk-link govuk-link--no-underline" aria-expanded="false" aria-controls="app-b-main-menu__nav-container" type="button">
<%= block.data["button_label"] %>
</button>
</div>
</div>
<div class="app-b-main-menu__nav-container app-b-main-menu__nav-container--js-hidden govuk-width-container" id="app-b-main-menu__nav-container">
<nav id="app-b-main-menu__nav" aria-label="Secondary">
<% block.data["groups"].each do |link_group| %>
<h2 class="govuk-heading-s"><%= link_group["heading"] %></h2>
<ul class="app-b-main-menu__list">
<% link_group["links"].each do |link| %>
<li class="app-b-main-menu__list-item">
<%= link_to link["text"], link["href"], class: "govuk-link govuk-link--no-underline govuk-link--no-visited-state" %>
</li>
<% end %>
</ul>
<% end %>
</nav>
</div>
</div>
1 change: 1 addition & 0 deletions config/initializers/dartsass.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"views/_landing_page/featured.scss" => "views/_landing_page/featured.css",
"views/_landing_page/grid.scss" => "views/_landing_page/grid.css",
"views/_landing_page/main-navigation.scss" => "views/_landing_page/main-navigation.css",
"views/_landing_page/main-menu.scss" => "views/_landing_page/main-menu.css",
"views/_landing_page/quote.scss" => "views/_landing_page/quote.css",
}.freeze

Expand Down
39 changes: 37 additions & 2 deletions lib/data/landing_page_content_items/homepage.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,43 @@ navigation_groups:
- text: Be thankful
href: "/landing-page/be-thankful"
blocks:
- type: main_navigation
navigation_group_id: Top Menu
- type: main_menu
button_label: "Landing page menu"
groups:
- heading: "First heading"
links:
- text: Landing page homepage very long text here to demonstrate wrapping
href: "/landing-page/homepage"
- text: Landing page homepage
href: "/landing-page/homepage"
- text: Landing page homepage
href: "/landing-page/homepage"
- heading: "Goals"
links:
- text: Goal 1
href: "/landing-page/goal-1"
- text: Goal 2 very long text here to demonstrate wrapping
href: "/landing-page/goal-2"
- text: Goal 3
href: "/landing-page/goal-3"
- text: Goal 4
href: "/landing-page/goal-4"
- text: Goal 5
href: "/landing-page/goal-5"
- text: Goal 6
href: "/landing-page/goal-6"
- heading: "Tasks"
links:
- text: Be kinder
href: "/landing-page/be-kinder"
- text: Exercise more
href: "/landing-page/exercise-more"
- text: Donate to charity and this has extra text to demonstrate more wrapping
href: "/landing-page/donate-to-charity"
- text: Learn something new
href: "/landing-page/learn-something-new"
- text: Be thankful
href: "/landing-page/be-thankful"
- type: hero
image:
alt: "Placeholder alt text"
Expand Down
71 changes: 71 additions & 0 deletions spec/javascripts/unit/modules/app-b-main-menu-spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
describe('Main Menu Block module', function () {
'use strict'

var el, module

beforeEach(function () {
var DOM =
`<div class="app-b-main-menu app-b-main-menu--collapsed" data-module="app-b-main-menu">
<div class="app-b-main-menu__button-container">
<div class="govuk-width-container">
<button type="button" class="app-b-main-menu__button app-b-main-menu__button--no-js govuk-link govuk-link--no-underline" aria-expanded="false" aria-controls="app-b-main-menu__nav-container">
Landing page menu
</button>
</div>
</div>
<div class="app-b-main-menu__nav-container app-b-main-menu__nav-container--js-hidden govuk-width-container" id="app-b-main-menu__nav-container">
<nav id="app-b-main-menu__nav" aria-label="Secondary">
<h2 class="govuk-heading-s">First heading</h2>
<ul class="app-b-main-menu__list">
<li class="app-b-main-menu__list-item">
<a class="govuk-link govuk-link--no-underline govuk-link--no-visited-state" href="/landing-page/homepage">Landing page homepage very long text here to demonstrate wrapping</a>
</li>
</ul>
<h2 class="govuk-heading-s">Goals</h2>
<ul class="app-b-main-menu__list">
<li class="app-b-main-menu__list-item">
<a class="govuk-link govuk-link--no-underline govuk-link--no-visited-state" href="/landing-page/goal-1">Goal 1</a>
</li>
</ul>
<h2 class="govuk-heading-s">Tasks</h2>
<ul class="app-b-main-menu__list">
<li class="app-b-main-menu__list-item">
<a class="govuk-link govuk-link--no-underline govuk-link--no-visited-state" href="/landing-page/be-kinder">Be kinder</a>
</li>
</ul>
</nav>
</div>
</div>
`
el = document.createElement('div')
el.innerHTML = DOM
document.body.appendChild(el)
module = new GOVUK.Modules.AppBMainMenu(el)
module.init()
})

afterEach(function () {
document.body.removeChild(el)
})

it('removes the no-js class from the button on initialisation', function () {
expect(document.querySelector('app-b-main-menu__button--no-js')).toBe(null)
})

it('toggles aria expanded on the button when it is clicked', function () {
var button = el.querySelector('button')
expect(button.getAttribute('aria-expanded')).toBe('false')
window.GOVUK.triggerEvent(button, 'click')
expect(button.getAttribute('aria-expanded')).toBe('true')
})

it('toggles the show/hide class when the button is clicked', function () {
var button = el.querySelector('button')
var toggledClass = '.app-b-main-menu__nav-container--js-hidden'
expect(document.querySelector(toggledClass)).not.toBe(null)
window.GOVUK.triggerEvent(button, 'click')
expect(document.querySelector(toggledClass)).toBe(null)
window.GOVUK.triggerEvent(button, 'click')
expect(document.querySelector(toggledClass)).not.toBe(null)
})
})

0 comments on commit 3317176

Please sign in to comment.