Skip to content

Commit

Permalink
Expose aria attributes when initialising
Browse files Browse the repository at this point in the history
Expose the hidden / collapsed state of the navigation on page load, rather than only after the menu button to be interacted with for the first time.

Find the menu button and menu when the module is initialised and store them in the instance so we can easily sync them without having to pass references to the button and menu between functions.

Add tests to check the aria state of the menu and menu button when the page is first loaded.
  • Loading branch information
36degrees committed Sep 4, 2020
1 parent 760ad18 commit 18771ce
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 29 deletions.
65 changes: 36 additions & 29 deletions src/govuk/components/header/header.js
Original file line number Diff line number Diff line change
@@ -1,46 +1,53 @@
import '../../vendor/polyfills/Function/prototype/bind'
import '../../vendor/polyfills/Event' // addEventListener and event.target normalization
import '../../vendor/polyfills/Event'
import '../../vendor/polyfills/Element/prototype/classList'
import '../../vendor/polyfills/Function/prototype/bind'

function Header ($module) {
this.$module = $module
this.$menuButton = $module && $module.querySelector('.govuk-js-header-toggle')
this.$menu = this.$menuButton && $module.querySelector(
'#' + this.$menuButton.getAttribute('aria-controls')
)
}

/**
* Initialise header
*
* Check for the presence of the header, menu and menu button – if any are
* missing then there's nothing to do so return early.
*/
Header.prototype.init = function () {
// Check for module
var $module = this.$module
if (!$module) {
return
}

// Check for button
var $toggleButton = $module.querySelector('.govuk-js-header-toggle')
if (!$toggleButton) {
if (!this.$module || !this.$menuButton || !this.$menu) {
return
}

// Handle $toggleButton click events
$toggleButton.addEventListener('click', this.handleClick.bind(this))
this.syncState(this.$menu.classList.contains('govuk-header__navigation--open'))
this.$menuButton.addEventListener('click', this.handleMenuButtonClick.bind(this))
}

/**
* An event handler for click event on $toggleButton
* @param {object} event event
*/
Header.prototype.handleClick = function (event) {
var $module = this.$module
var $toggleButton = event.target || event.srcElement
var $target = $module.querySelector('#' + $toggleButton.getAttribute('aria-controls'))

// If a button with aria-controls, handle click
if ($toggleButton && $target) {
var isVisible = $target.classList.toggle('govuk-header__navigation--open')

$toggleButton.classList.toggle('govuk-header__menu-button--open', isVisible)
* Sync menu state
*
* Sync the menu button class and the accessible state of the menu and the menu
* button with the visible state of the menu
*
* @param {boolean} isVisible Whether the menu is currently visible
*/
Header.prototype.syncState = function (isVisible) {
this.$menuButton.classList.toggle('govuk-header__menu-button--open', isVisible)
this.$menuButton.setAttribute('aria-expanded', isVisible)
this.$menu.setAttribute('aria-hidden', !isVisible)
}

$toggleButton.setAttribute('aria-expanded', isVisible)
$target.setAttribute('aria-hidden', !isVisible)
}
/**
* Handle menu button click
*
* When the menu button is clicked, change the visibility of the menu and then
* sync the accessibility state and menu button state
*/
Header.prototype.handleMenuButtonClick = function () {
var isVisible = this.$menu.classList.toggle('govuk-header__navigation--open')
this.syncState(isVisible)
}

export default Header
25 changes: 25 additions & 0 deletions src/govuk/components/header/header.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,31 @@ describe('/components/header', () => {
})

describe('when JavaScript is available', () => {
describe('when no navigation is present', () => {
it('exits gracefully with no errors', async () => {
// Errors logged to the console will cause this test to fail
await page.goto(baseUrl + '/components/header/preview', { waitUntil: 'load' })
})
})

describe('on page load', () => {
beforeAll(async () => {
await page.goto(baseUrl + '/components/header/with-navigation/preview', { waitUntil: 'load' })
})

it('exposes the hidden state of the menu using aria-hidden', async () => {
const ariaHidden = await page.$eval('.govuk-header__navigation', el => el.getAttribute('aria-hidden'))

expect(ariaHidden).toBe('true')
})

it('exposes the collapsed state of the menu button using aria-expanded', async () => {
const ariaExpanded = await page.$eval('.govuk-header__menu-button', el => el.getAttribute('aria-expanded'))

expect(ariaExpanded).toBe('false')
})
})

describe('when menu button is pressed', () => {
it('should indicate the open state of the toggle button', async () => {
await page.goto(baseUrl + '/components/header/with-navigation/preview', { waitUntil: 'load' })
Expand Down

0 comments on commit 18771ce

Please sign in to comment.