/**
* Toggles visibility between two elements on the page.
*
* @example
* <button class="toggle-switch">
* <span class="toggle-off">Initial State</span>
* <span class="toggle-on">Toggled State</span>
* </button>
*
* @module Toggle
*/
const Toggle = {
toggleSelector: '.toggle-switch',
toggleOnSelector: '.toggle-on',
toggleFlag: 'is-toggled',
outsideClickListener: false,
/**
* Binds click events to any `toggle-switch` blocks on the page.
* @method init
*/
init( $toggles ) {
if ( ! $toggles ) {
/* eslint-disable no-param-reassign */
$toggles = document.querySelectorAll( this.toggleSelector );
/* eslint-enable no-param-reassign */
}
[].forEach.call( $toggles, ( $toggle ) => {
$toggle.addEventListener( 'click', () => {
if ( $toggle.classList.contains( this.toggleFlag ) ) {
$toggle.classList.remove( this.toggleFlag );
} else {
$toggle.classList.add( this.toggleFlag );
const $toggleOn = $toggle.querySelector( this.toggleOnSelector );
if ( $toggleOn && 'SELECT' === $toggleOn.nodeName ) {
$toggleOn.focus();
$toggleOn.addEventListener( 'blur', () => {
$toggle.classList.remove( this.toggleFlag );
});
}
// allow toggle element to collapse when user clicks outside of the element
this.outsideClickListener = false;
if ( $toggle.dataset.toggleOutsideClick ) {
this.outsideClickListener = this.handleOutsideClick.bind( this, $toggle );
document.addEventListener( 'click', this.outsideClickListener );
}
}
});
});
},
/**
* Handle clicks outside of a $toggle element
*
* @method handleOutsideClick
* @param $toggle - toggle element clicked
* @param evt - document click event
*/
handleOutsideClick( $toggle, evt ) {
if ( evt.target
&& ( ( evt.target === $toggle )
|| ( evt.target.parentNode && evt.target.parentNode === $toggle ) ) ) {
return;
}
$toggle.classList.remove( this.toggleFlag );
document.removeEventListener( 'click', this.outsideClickListener );
},
};
export default Toggle;