-
Notifications
You must be signed in to change notification settings - Fork 237
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement accordion functionality for ServiceNav
- New partial for building HTML of sub-navigation items - Accordion functionality for Service Navigation component when page viewed on mobile viewport - Update configuration for building list of links for navigation and sub navigation items
- Loading branch information
1 parent
70fd03b
commit 2386b09
Showing
9 changed files
with
259 additions
and
31 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
import { Component } from 'govuk-frontend' | ||
|
||
/** | ||
* Mobile Navigation enhancement for Service Navigation component | ||
*/ | ||
class MobileNavigation extends Component { | ||
static moduleName = 'app-mobile-navigation' | ||
|
||
/** | ||
* @param {Element} $root - HTML element | ||
*/ | ||
constructor($root) { | ||
super($root) | ||
|
||
this.templates = this.$root.querySelectorAll( | ||
'.app-mobile-navigation__template' | ||
) | ||
this.links = this.$root.querySelectorAll('a') | ||
|
||
Array.from(this.templates).forEach((template) => { | ||
const templateClone = template.content.cloneNode(true) | ||
let link | ||
|
||
if (template.parentNode.tagName === 'A') { | ||
link = template.parentNode | ||
link.removeChild(template) | ||
} else { | ||
link = template.parentNode.parentNode | ||
template.parentNode.removeChild(template) | ||
} | ||
|
||
const button = document.createElement('button') | ||
button.classList.add('govuk-service-navigation__link') | ||
button.classList.add('app-mobile-navigation__toggle-button') | ||
button.setAttribute( | ||
'aria-expanded', | ||
String( | ||
link.parentNode.classList.contains( | ||
'govuk-service-navigation__item--active' | ||
) | ||
) | ||
) | ||
button.textContent = link.textContent | ||
|
||
link.insertAdjacentElement('afterend', templateClone.firstElementChild) | ||
link.insertAdjacentElement('afterend', button) | ||
}) | ||
|
||
const currentLink = Array.from( | ||
this.$root.querySelectorAll( | ||
`.app-navigation__subnav-item a[href="${window.location.pathname.slice(0, -1)}"]` | ||
) | ||
).pop() | ||
|
||
if (currentLink) { | ||
currentLink.classList.add('app-mobile-navigation__link--active') | ||
} | ||
|
||
// A global const for storing a matchMedia instance which we'll use to detect when a screen size change happens | ||
// Set the matchMedia to the govuk-frontend tablet breakpoint | ||
|
||
const breakPoint = getComputedStyle( | ||
document.documentElement | ||
).getPropertyValue('--govuk-frontend-breakpoint-tablet') | ||
|
||
this.mql = window.matchMedia(`(min-width: ${breakPoint})`) | ||
|
||
// MediaQueryList.addEventListener isn't supported by Safari < 14 so we need | ||
// to be able to fall back to the deprecated MediaQueryList.addListener | ||
if ('addEventListener' in this.mql) { | ||
this.mql.addEventListener('change', () => this.setHiddenStates()) | ||
} else { | ||
// @ts-expect-error Property 'addListener' does not exist | ||
this.mql.addListener(() => this.setHiddenStates()) | ||
} | ||
|
||
this.setHiddenStates() | ||
this.setEventListener() | ||
} | ||
|
||
/** | ||
* Set up event delegation for button clicks | ||
*/ | ||
setEventListener() { | ||
this.$root.addEventListener( | ||
'click', | ||
(e) => { | ||
if (e.target.tagName === 'BUTTON') { | ||
e.target.setAttribute( | ||
'aria-expanded', | ||
!(e.target.getAttribute('aria-expanded') === 'true') | ||
) | ||
} | ||
}, | ||
{ bubbles: true } | ||
) | ||
} | ||
|
||
/** | ||
* Hide links if viewport is below tablet | ||
*/ | ||
setHiddenStates() { | ||
if (!this.mql.matches) { | ||
this.links.forEach((a) => a.setAttribute('hidden', '')) | ||
} else { | ||
this.links.forEach((a) => a.removeAttribute('hidden')) | ||
} | ||
} | ||
} | ||
|
||
export default MobileNavigation |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
.app-mobile-navigation__theme { | ||
@include govuk-typography-common; | ||
position: relative; // this is to get around the artificial click area generated by the :after of the parent button | ||
margin: 0; | ||
padding: 0; | ||
color: govuk-colour("dark-grey"); | ||
// Font is defined as a hard 19px so | ||
// it does not re-size on mobile viewport | ||
font-size: 19px; | ||
font-size: govuk-px-to-rem(19px); | ||
font-weight: normal; | ||
} | ||
|
||
.app-mobile-navigation .govuk-service-navigation__item--active { | ||
@include govuk-media-query($until: tablet) { | ||
border-color: transparent; | ||
} | ||
} | ||
|
||
.app-mobile-navigation__link--active { | ||
@include govuk-media-query($until: tablet) { | ||
border-left: 5px solid rgb(26.1, 100.8, 165.6); | ||
} | ||
} | ||
|
||
.app-mobile-navigation__toggle-button { | ||
@include govuk-media-query($from: tablet) { | ||
display: none; | ||
} | ||
position: relative; | ||
padding: 0; | ||
border: 0; | ||
|
||
background: none; | ||
font-size: inherit; | ||
} | ||
|
||
.app-mobile-navigation__toggle-button::after { | ||
content: ""; | ||
box-sizing: border-box; | ||
display: block; | ||
position: absolute; | ||
right: govuk-px-to-rem(-14px); | ||
bottom: govuk-px-to-rem(10px); | ||
width: govuk-px-to-rem(6px); | ||
height: govuk-px-to-rem(6px); | ||
border-top: govuk-px-to-rem(2px) solid; | ||
border-right: govuk-px-to-rem(2px) solid; | ||
} | ||
|
||
.app-mobile-navigation__toggle-button[aria-expanded="false"]::after { | ||
transform: rotate(135deg); | ||
} | ||
|
||
.app-mobile-navigation__toggle-button[aria-expanded="false"] ~ .app-navigation__list { | ||
display: none; | ||
} | ||
|
||
.app-mobile-navigation__toggle-button[aria-expanded="true"]::after { | ||
transform: rotate(-45deg); | ||
} | ||
|
||
.app-mobile-navigation__toggle-button[aria-expanded="true"] ~ .app-navigation__list { | ||
@include govuk-media-query($until: tablet) { | ||
display: block; | ||
} | ||
|
||
display: none; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
{% macro mobileNavigation(params) %} | ||
{% if params.items %} | ||
<ul class="app-navigation__list"> | ||
{% for theme, items in params.items | groupby("theme") %} | ||
{% if theme != 'undefined' %} | ||
<li class="app-navigation__subnav-item"> | ||
<h3 class="app-mobile-navigation__theme" >{{ theme }}</h3> | ||
</li> | ||
{% endif %} | ||
{% for item in items %} | ||
<li class="app-navigation__subnav-item"> | ||
<a class="govuk-link govuk-link--no-visited-state govuk-link--no-underline" href="{{ item.href }}"> | ||
{{ item.text }} | ||
</a> | ||
</li> | ||
{% endfor %} | ||
{% endfor %} | ||
</ul> | ||
{% endif %} | ||
{% endmacro %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,34 @@ | ||
{% from "govuk/components/service-navigation/macro.njk" import govukServiceNavigation %} | ||
{% from "_mobile-navigation.njk" import mobileNavigation %} | ||
|
||
{% set navigationItems = [] %} | ||
|
||
{% for item in navigation %} | ||
{% set navigationItems = navigationItems.concat({ | ||
{% set subNavItems = [{ | ||
href: item.href, | ||
text: item.text, | ||
current: permalink and permalink.startsWith(item.url) | ||
}) %} | ||
text: item.text + " overview", | ||
active: permalink and permalink.startsWith(item.href.slice(1)), | ||
current: permalink === item.href | ||
}] %} | ||
|
||
{% if item.items %} | ||
{% set subNavItems = subNavItems.concat(item.items) %} | ||
{% endif %} | ||
|
||
{% set subNavItemHtml = mobileNavigation({ items: subNavItems, theme: item.theme }) %} | ||
|
||
{% set navItem = { | ||
href: item.href, | ||
html: item.text + '<template class="app-mobile-navigation__template">' + subNavItemHtml + '</template>', | ||
active: permalink and permalink.startsWith(item.href.slice(1)), | ||
current: permalink === item.href | ||
} %} | ||
|
||
{% set navigationItems = navigationItems.concat(navItem) %} | ||
{% endfor %} | ||
|
||
{{ govukServiceNavigation({ | ||
navigation: navigationItems | ||
}) }} | ||
<div class="app-mobile-navigation" data-module="app-mobile-navigation"> | ||
{{ govukServiceNavigation({ | ||
navigation: navigationItems | ||
}) }} | ||
</div> |