-
Notifications
You must be signed in to change notification settings - Fork 237
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Service Navigation component, add new Mobile Navigation component #4368
base: main
Are you sure you want to change the base?
Conversation
✅ You can preview this change here:
To edit notification comments on pull requests, go to your Netlify site configuration. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Listed the comments we had during our call. Once the accordion is in place, there are these two other responsibilities that the current component handles and that we'll need to implement in the new one:
- Starting with the subnav open on the current page if not on the homepage
- Handling if CSS fails to load, but JavaScript loads by using
hidden
attributes- Responding to screen-size changes by setting
hidden
attributes as well
- Responding to screen-size changes by setting
src/javascripts/application.mjs
Outdated
const newButton = document.createElement('button') | ||
newButton.classList.add('app-navigation__list-toggle') | ||
newButton.setAttribute('subitems-toggle-closed', true) | ||
newButton.innerHTML = '▼' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion Use the textContent
from the link to create the button name and hide the link on mobile.
src/javascripts/application.mjs
Outdated
const serviceNavigationHeader = document.querySelector( | ||
'.govuk-service-navigation' | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion Create a MobileNavigation
component set up on a <div>
that wraps the service navigation.
{% macro subNavigationItems(params) %} | ||
{% if params.items %} | ||
<ul class="app-navigation__list js-app-navigation__list--hidden"> | ||
{% for item in params.items %} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue Accordions in the current navigation have a first item linking to the section, replacing the link that's getting hidden.
views/partials/_navigation.njk
Outdated
{% set subNavItemHtml = subNavigationItems({ items: item.items }) %} | ||
{% set navItem = { | ||
href: item.href, | ||
html: item.text + '<template>' + subNavItemHtml + '</template>', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion Setting a class on the <template>
will help access it from the JavaScript.
src/javascripts/application.mjs
Outdated
if ( | ||
serviceNavigationHeader.hasAttribute('data-govuk-service-navigation-init') | ||
) { | ||
const subNavTreeParents = serviceNavigationHeader.querySelectorAll('li') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion We can access the links and use insertAdjacentElement
to inject the sub navigation and button.
src/javascripts/application.mjs
Outdated
if (e.target.hasAttribute('subitems-toggle-closed')) { | ||
subNav.classList.remove('js-app-navigation__list--hidden') | ||
e.target.removeAttribute('subitems-toggle-closed') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion Instead of having our own attribute, we can use the aria-expanded
attribute which will be necessary for accessibility.
src/javascripts/application.mjs
Outdated
const subNav = subNavParent.querySelector('.app-navigation__list') | ||
|
||
if (e.target.hasAttribute('subitems-toggle-closed')) { | ||
subNav.classList.remove('js-app-navigation__list--hidden') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion We could use the next sibling selector to toggle the visibility of the subnav based on the state of aria-expanded
. https://www.htmhell.dev/adventcalendar/2024/16/
d6b7fb6
to
9007223
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice to see the feature gathered in its own component and generally going in the right direction. Thanks for updating 🙌🏻
I've dropped comments where I've noticed things with the current implementation (some of them which may become addressed by the replication of the feature that handles JS loading but CSS not loading).
src/javascripts/application.mjs
Outdated
// Initialise mobile navigation | ||
createAll(Navigation) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion Given we're using a new component we can drop this bit :)
// Initialise mobile navigation | |
createAll(Navigation) |
this.templates = this.$root.querySelectorAll( | ||
'.app-mobile-navigation__template' | ||
) | ||
this.links = this.$root.querySelectorAll('a') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue This has a risk to collect elements more broadly than we intend, if one day we add some content to the navigation through slots, for example. Would be good to limit this to links from the actual navigation using their class from the Service Navigation (unless we can set up our own .js-
prefixed class).
|
||
// 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 | ||
this.mql = window.matchMedia('(min-width: 40.0625em)') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion We can use the CSS custom properties set by GOV.UK Frontend to get the breakpoint value.
}, | ||
{ bubbles: true } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue bubbles
is not one of the options of addEventListener
}, | |
{ bubbles: true } | |
} |
* Mobile Navigation enhancement for Service Navigation component | ||
*/ | ||
class MobileNavigation extends Component { | ||
static moduleName = 'mobile-navigation' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue For consistency with the other components, let's make sure to prefix the module name with app-
static moduleName = 'mobile-navigation' | |
static moduleName = 'app-mobile-navigation' |
border-top: govuk-px-to-rem(2px) solid; | ||
border-right: govuk-px-to-rem(2px) solid; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Solid way to have the chevron visible for people using high contrast mode 🙌🏻
.app-mobile-navigation__toggle-button[aria-expanded="true"] ~ .app-navigation__list { | ||
@include govuk-media-query($until: tablet) { | ||
display: block; | ||
} | ||
|
||
display: none; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion Hiding the navigation list and toggle would gain at being regrouped in a single block of code and a single media query for easier maintainability rather than split in their own selector, in the lines of:
.app-mobile-navigation__toggle-button[aria-expanded="true"] ~ .app-navigation__list { | |
@include govuk-media-query($until: tablet) { | |
display: block; | |
} | |
display: none; | |
} | |
@include govuk-media-query($from: tablet) { | |
.app-mobile-navigation__toggle-button, | |
.app-navigation__list { | |
display: none; | |
} | |
} |
This would allow the file to describe first how the different parts look, then when they're visible or not. That media query may also not be necessary once the JavaScript handles using hidden
to ensure elements are not visible if CSS did not load.
.app-mobile-navigation__toggle-button[aria-expanded="true"]::after { | ||
transform: rotate(-45deg); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion This can likely be the default state of the button and save a selector.
.app-mobile-navigation__toggle-button[aria-expanded="false"] ~ .app-navigation__list { | ||
display: none; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We may be able to let that selector go when we re-implement the current navigation feature for using hidden
to hide elements when CSS fails to load.
.app-width-container, | ||
.govuk-service-navigation .govuk-width-container { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This may be an indication that we may want to update the CSS variable in this stylesheet and add a custom width container to the examples 🤔 This is something we can explore in a future PR, though 😊
9007223
to
d18d80c
Compare
What
Why