Posted in Navigation
13922
1:30 am, December 2, 2021

WCAG Responsive Accessible Menu Dropdown Library

What is WCAG Responsive Accessible Menu?

Here we have a javascript library with css and html that produces a responsive and mobile compatible dropdown navigation system. When the screen size goes into a mobile width the menu switches to handle bars and then stilll works as a dropdown menuing system.

Also it has toggle arrows showing which menu item is the active one. 

Preview


a preview of WCAG Responsive Accessible Menu 

What can i use this for?

This is a stand alone script that does not rely on any other libraries, and can be used as your main site menu system. 

A JavaScript library to help you generate WCAG accessible menus in the DOM.

The supported menu types are:

Browser Support


Chrome

Firefox

Safari

Edge

Chromium

Webkit
last 2 versions last 2 versions last 2 versions last 2 versions last 2 versions last 2 versions

Found something that doesn't work the way it should in one of the listed browsers above? Open an issue!

Installation

NPM

NPM is recommended for large-scale development, since it works well with bundlers like Webpack or Rollup.

# latest stable
npm install accessible-menu

CDN

For learning/prototyping purposes you can use the latest version with:

<script src="https://cdn.jsdelivr.net/npm/accessible-menu/dist/accessible-menu.js"></script>

For production environments, it is recommend to use a specific version to avoid unforseen breaking changes:

<script src="https://cdn.jsdelivr.net/npm/accessible-menu@3.0.4/dist/accessible-menu.min.js"></script>

Usage

To use accessible-menu, you first need to make sure your menu matches the following structure:

<ul id="example-menu">
  <li><a href="/about">About</a></li>
  <li class="dropdown">
    <a href="#">Projects ▼</a>
    <ul>
      <li><a href="/projects/awesome">Awesome project</a></li>
      <li><a href="/projects/not-so-awesome">Not-so-awesome project</a></li>
    </ul>
  </li>
  <li><a href="/contact">Contact me</a></li>
</ul>

Include accessible-menu through import or bundled library in your project:

import AccessibleMenu from "accessible-menu";

or

<script src="https://cdn.jsdelivr.net/npm/accessible-menu@3.0.4/dist/accessible-menu.min.js"></script>

Once you have accessible-menu loaded, declare a new menu object.

menuElement is required for all menus, while submenuItemSelector is only required if you have submenus/dropdowns.

const menu = new AccessibleMenu.DisclosureMenu({
  menuElement: document.querySelector("#example-menu"),
  submenuItemSelector: "li.dropdown",
});

Only need one type of menu class?

Bundled versions of each menu are provided in the dist and individual exports are provided in the index.

There are also compiled ES Module versions if you don't want to use an iife!

DisclosureMenu usage

import { DisclosureMenu } from "accessible-menu";

or

<script src="https://cdn.jsdelivr.net/npm/accessible-menu@3.0.4/dist/disclosure-menu.min.js"></script>

then

const menu = new DisclosureMenu({
  menuElement: document.querySelector("#example-menu"),
  submenuItemSelector: "li.dropdown",
});

Menubar usage

import { Menubar } from "accessible-menu";

or

<script src="https://cdn.jsdelivr.net/npm/accessible-menu@3.0.4/dist/menubar.min.js"></script>

then

const menu = new Menubar({
  menuElement: document.querySelector("#example-menu"),
  submenuItemSelector: "li.dropdown",
});

Treeview usage

import { Treeview } from "accessible-menu";

or

<script src="https://cdn.jsdelivr.net/npm/accessible-menu@3.0.4/dist/treeview.min.js"></script>

then

const menu = new Treeview({
  menuElement: document.querySelector("#example-menu"),
  submenuItemSelector: "li.dropdown",
});

Documentation

Examples

Looking for a working example of accessible-menu? Check out these jsfiddles:

Bootstrap support

Looking to use this with Bootstrap? Because Bootstrap adds classes to the menu's containing element to show/hide the menu, you'll need custom open/close functions for your menu. Check out the accessible-menu-bootstrap-4 project where all that is done for you!

Original Source

Thanks to the author NickDJM on github. 

WCAG Responsive Accessible Menu Dropdown Library Demo

View Demo Full Screen View Demo New Tab

WCAG Responsive Accessible Menu Dropdown Library Code

HTML

<header>
    <nav>
      <button id="toggle-0" aria-label="Toggle main menu">☰</button>
      <ul id="menu-0">
        <li id="item-1-0-0"><a id="link-1-0-0" href="#">First item</a></li>
        <li id="item-2-0-0" class="dropdown">
          <a id="link-2-0-0" href="#">Second item</a>
          <ul id="menu-2">
            <li id="item-2-1-0"><a id="link-2-1-0" href="#">First item</a></li>
            <li id="item-2-2-0" class="dropdown">
              <a id="link-2-2-0" href="#">Second item</a>
              <ul id="menu-2-2">
                <li id="item-2-2-1"><a id="link-2-2-1" href="#">First item</a></li>
                <li id="item-2-2-2"><a id="link-2-2-2" href="#">Second item</a></li>
                <li id="item-2-2-3"><a id="link-2-2-3" href="#">Third item</a></li>
              </ul>
            </li>
            <li id="item-2-3-0" class="dropdown">
              <a id="link-2-3-0" href="#">Third item</a>
              <ul id="menu-2-3">
                <li id="item-2-3-1"><a id="link-2-3-1" href="#">First item</a></li>
                <li id="item-2-3-2"><a id="link-2-3-2" href="#">Second item</a></li>
                <li id="item-2-3-3"><a id="link-2-3-3" href="#">Third item</a></li>
              </ul>
            </li>
          </ul>
        </li>
        <li id="item-3-0-0" class="dropdown">
          <a id="link-3-0-0" href="#">Third item</a>
          <ul id="menu-3">
            <li id="item-3-1-0"><a id="link-3-1-0" href="#">First item</a></li>
            <li id="item-3-2-0"><a id="link-3-2-0" href="#">Second item</a></li>
            <li id="item-3-3-0"><a id="link-3-3-0" href="#">Third item</a></li>
          </ul>
        </li>
        <li id="item-4-0-0"><a id="link-4-0-0" href="#">Fourth item</a></li>
        <li id="item-5-0-0" class="dropdown">
          <a id="link-5-0-0" href="#">Fifth item</a>
          <ul id="menu-5">
            <li id="item-5-1-0"><a id="link-5-1-0" href="#">First item</a></li>
            <li id="item-5-2-0"><a id="link-5-2-0" href="#">Second item</a></li>
            <li id="item-5-3-0"><a id="link-5-3-0" href="#">Third item</a></li>
          </ul>
        </li>
      </ul>
    </nav>
  </header>

CSS

* {
  box-sizing: border-box; margin: 0; padding: 0; 
  font-family:"Roboto", sans-serif;
}
  *:focus {
    outline: 2px dotted #000;
    outline-offset: -2px;
    box-shadow: 0 0 2px 0 inset #fff; }
    *:focus:not(:focus-visible) {
      outline: none;
      box-shadow: none; }
.lead { font-size: 24px; font-weight: 300; }
body {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  font-family: 'Inter'; }

main {
  padding: 1rem 6rem; }

nav {
  background-color: #293345;
  color: #3bc993; }
  nav > button {
    min-width: 44px;
    min-height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-left: auto;
    border: 0;
    background-color: #293345;
    color: #3bc993;
    font-size: 2.5rem; }
  nav ul {
    display: none;
    margin: 0;
    padding: 0;
    background-color: #293345;
    color: #3bc993;
    list-style: none; }
    nav ul.show {
      display: grid;
      grid-auto-flow: row;
      grid-auto-rows: max-content; }
  nav a {
    min-width: 44px;
    min-height: 44px;
    display: flex;
    align-items: center;
    padding: 0.75rem 1.5rem;
    transition: background-color 150ms ease-in-out;
    color: #3bc993;
    text-decoration: none; }
    nav a:hover {
      background-color: #3bc993;
      color: #293345; }
  nav li {
    padding: 0.25rem; }
  nav li.dropdown {
    position: relative; }
    nav li.dropdown > a::after {
      content: "▼";
      display: block;
      margin-left: 0.5rem;
      transition: transform 250ms linear;
      font-size: 0.5em; }
    nav li.dropdown > a[aria-expanded="true"]::after {
      transform: rotate(-180deg); }
    nav li.dropdown ul a {
      padding-left: 2.25rem; }
    nav li.dropdown ul li.dropdown ul a {
      padding-left: 3.375rem; }

@media screen and (min-width: 1080px) {
  nav button {
    display: none; }
  nav > ul,
  nav > ul.show {
    display: grid;
    grid-auto-columns: max-content;
    grid-auto-flow: column; }
  nav .dropdown ul.show {
    position: absolute; }
  nav .dropdown ul ul {
    top: 0;
    left: 100%; } }

Javascript

var DisclosureMenu=function(){"use strict";function e(t){return(e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(t)}function t(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function n(e,t){for(var n=0;n<t.length;n++){var o=t[n];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}function o(e,t,o){return t&&n(e.prototype,t),o&&n(e,o),e}function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),t&&i(e,t)}function l(e){return(l=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)})(e)}function i(e,t){return(i=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e})(e,t)}function u(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}function c(e,t){return!t||"object"!=typeof t&&"function"!=typeof t?u(e):t}function a(e){var t=function(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}();return function(){var n,o=l(e);if(t){var s=l(this).constructor;n=Reflect.construct(o,arguments,s)}else n=o.apply(this,arguments);return c(this,n)}}function m(e,t,n){return(m="undefined"!=typeof Reflect&&Reflect.get?Reflect.get:function(e,t,n){var o=function(e,t){for(;!Object.prototype.hasOwnProperty.call(e,t)&&null!==(e=l(e)););return e}(e,t);if(o){var s=Object.getOwnPropertyDescriptor(o,t);return s.get?s.get.call(n):s.value}})(e,t,n||e)}function h(e){return function(e){if(Array.isArray(e))return f(e)}(e)||function(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}(e)||function(e,t){if(!e)return;if("string"==typeof e)return f(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);"Object"===n&&e.constructor&&(n=e.constructor.name);if("Map"===n||"Set"===n)return Array.from(e);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return f(e,t)}(e)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function f(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,o=new Array(t);n<t;n++)o[n]=e[n];return o}function d(t,n){try{if("object"!==e(n)){var o=e(n);throw new TypeError("AccessibleMenu: Elements given to isValidInstance() must be inside of an object. ".concat(o," given."))}for(var s in n)if(!(n[s]instanceof t)){var r=e(n[s]);throw new TypeError("AccessibleMenu: ".concat(s," must be an instance of ").concat(t.name,". ").concat(r," given."))}return!0}catch(e){return console.error(e),!1}}function p(t,n){try{if("object"!==e(n)){var o=e(n);throw new TypeError("AccessibleMenu: Values given to isValidType() must be inside of an object. ".concat(o," given."))}for(var s in n){var r=e(n[s]);if(r!==t)throw new TypeError("AccessibleMenu: ".concat(s," must be a ").concat(t,". ").concat(r," given."))}return!0}catch(e){return console.error(e),!1}}function v(t){try{if("object"!==e(t)){var n=e(t);throw new TypeError("AccessibleMenu: Values given to isCSSSelector() must be inside of an object. ".concat(n," given."))}for(var o in t)try{if(null===t[o])throw new Error;document.querySelector(t[o])}catch(e){throw new TypeError("AccessibleMenu: ".concat(o,' must be a valid CSS selector. "').concat(t[o],'" given.'))}return!0}catch(e){return console.error(e),!1}}function y(t){try{if("object"!==e(t)||Array.isArray(t)){var n=e(t);throw new TypeError("AccessibleMenu: Values given to isValidClassList() must be inside of an object. ".concat(n," given."))}var o=function(n){var o=e(t[n]);if("string"!==o){if(!Array.isArray(t[n]))throw new TypeError("AccessibleMenu: ".concat(n," must be a string or an array of strings. ").concat(o," given."));t[n].forEach((function(e){if("string"!=typeof e)throw new TypeError("AccessibleMenu: ".concat(n," must be a string or an array of strings. An array containing non-strings given."))}))}else{var s={};s[n]=t[n],v(s)}};for(var s in t)o(s);return!0}catch(e){return console.error(e),!1}}function g(t){try{if("object"!==e(t)){var n=e(t);throw new TypeError("AccessibleMenu: Values given to isValidHoverType() must be inside of an object. ".concat(n," given."))}var o=["off","on","dynamic"];for(var s in t)if(!o.includes(t[s]))throw new TypeError("AccessibleMenu: ".concat(s," must be one of the following values: ").concat(o.join(", "),'. "').concat(t[s],'" given.'));return!0}catch(e){return console.error(e),!1}}function b(e,t){return!(!p("string",{event:e})||!d(HTMLElement,{element:t}))&&void 0!==t["on".concat(e)]}var _=function(){function e(n){var o=n.menuToggleElement,r=n.parentElement,l=n.controlledMenu,i=n.parentMenu,u=void 0===i?null:i;t(this,e),s(this,"_dom",{toggle:null,parent:null}),s(this,"_elements",{controlledMenu:null,parentMenu:null}),s(this,"_open",!1),s(this,"_expandEvent",new CustomEvent("accessibleMenuExpand",{bubbles:!0,detail:{toggle:this}})),s(this,"_collapseEvent",new CustomEvent("accessibleMenuCollapse",{bubbles:!0,detail:{toggle:this}})),this._dom.toggle=o,this._dom.parent=r,this._elements.controlledMenu=l,this._elements.parentMenu=u}return o(e,[{key:"initialize",value:function(){if(this.dom.toggle.setAttribute("aria-haspopup","true"),this.dom.toggle.setAttribute("aria-expanded","false"),function(e,t){if(p("string",{tagName:e})&&d(HTMLElement,t)){var n=e.toLowerCase(),o=!0;for(var s in t)t[s].tagName.toLowerCase()!==n&&(o=!1);return o}return!1}("button",{toggle:this.dom.toggle})||this.dom.toggle.setAttribute("role","button"),""===this.dom.toggle.id||""===this.elements.controlledMenu.dom.menu.id){var e=Math.random().toString(36).replace(/[^a-z]+/g,"").substr(0,10),t=this.dom.toggle.innerText.replace(/[^a-zA-Z0-9\s]/g,""),n=e;!t.replace(/\s/g,"").length&&this.dom.toggle.getAttribute("aria-label")&&(t=this.dom.toggle.getAttribute("aria-label").replace(/[^a-zA-Z0-9\s]/g,"")),t.replace(/\s/g,"").length>0&&((t=t.toLowerCase().replace(/\s+/g,"-")).startsWith("-")&&(t=t.substring(1)),t.endsWith("-")&&(t=t.slice(0,-1)),n="".concat(t,"-").concat(n)),this.dom.toggle.id=this.dom.toggle.id||"".concat(n,"-menu-button"),this.elements.controlledMenu.dom.menu.id=this.elements.controlledMenu.dom.menu.id||"".concat(n,"-menu")}this.elements.controlledMenu.dom.menu.setAttribute("aria-labelledby",this.dom.toggle.id),this.dom.toggle.setAttribute("aria-controls",this.elements.controlledMenu.dom.menu.id),this._collapse(!1)}},{key:"dom",get:function(){return this._dom}},{key:"elements",get:function(){return this._elements}},{key:"isOpen",get:function(){return this._open},set:function(e){p("boolean",{value:e}),this._open=e}},{key:"_expand",value:function(){var e,t,n=!(arguments.length>0&&void 0!==arguments[0])||arguments[0],o=this.elements.controlledMenu,s=o.closeClass,r=o.openClass;(this.dom.toggle.setAttribute("aria-expanded","true"),""!==r)&&("string"==typeof r?this.elements.controlledMenu.dom.menu.classList.add(r):(e=this.elements.controlledMenu.dom.menu.classList).add.apply(e,h(r)));""!==s&&("string"==typeof s?this.elements.controlledMenu.dom.menu.classList.remove(s):(t=this.elements.controlledMenu.dom.menu.classList).remove.apply(t,h(s)));n&&this.dom.toggle.dispatchEvent(this._expandEvent)}},{key:"_collapse",value:function(){var e,t,n=!(arguments.length>0&&void 0!==arguments[0])||arguments[0],o=this.elements.controlledMenu,s=o.closeClass,r=o.openClass;(this.dom.toggle.setAttribute("aria-expanded","false"),""!==s)&&("string"==typeof s?this.elements.controlledMenu.dom.menu.classList.add(s):(e=this.elements.controlledMenu.dom.menu.classList).add.apply(e,h(s)));""!==r&&("string"==typeof r?this.elements.controlledMenu.dom.menu.classList.remove(r):(t=this.elements.controlledMenu.dom.menu.classList).remove.apply(t,h(r)));n&&this.dom.toggle.dispatchEvent(this._collapseEvent)}},{key:"open",value:function(){this.elements.controlledMenu.focusState="self",this._expand(),this.isOpen=!0}},{key:"preview",value:function(){this.elements.parentMenu&&(this.elements.parentMenu.focusState="self"),this._expand(),this.isOpen=!0}},{key:"close",value:function(){this.isOpen&&(this.elements.controlledMenu.currentChild=0,this.elements.controlledMenu.blur(),this.elements.parentMenu&&(this.elements.parentMenu.focusState="self"),this._collapse(),this.isOpen=!1)}},{key:"toggle",value:function(){this.isOpen?this.close():this.open()}},{key:"closeSiblings",value:function(){var e=this;this.elements.parentMenu&&this.elements.parentMenu.elements.submenuToggles.forEach((function(t){t!==e&&t.close()}))}},{key:"closeChildren",value:function(){this.elements.controlledMenu.elements.submenuToggles.forEach((function(e){return e.close()}))}}]),e}(),M=function(){function e(n){var o=n.menuItemElement,r=n.menuLinkElement,l=n.parentMenu,i=n.isSubmenuItem,u=void 0!==i&&i,c=n.childMenu,a=void 0===c?null:c,m=n.toggle,h=void 0===m?null:m;t(this,e),s(this,"_dom",{item:null,link:null}),s(this,"_elements",{parentMenu:null,childMenu:null,toggle:null}),s(this,"_submenu",!1),this._dom.item=o,this._dom.link=r,this._elements.parentMenu=l,this._elements.childMenu=a,this._elements.toggle=h,this._submenu=u}return o(e,[{key:"initialize",value:function(){}},{key:"dom",get:function(){return this._dom}},{key:"elements",get:function(){return this._elements}},{key:"isSubmenuItem",get:function(){return this._submenu}},{key:"focus",value:function(){this.elements.parentMenu.shouldFocus&&this.dom.link.focus()}},{key:"blur",value:function(){this.elements.parentMenu.shouldFocus&&this.dom.link.blur()}}]),e}();function E(e){try{var t=e.key||e.keyCode,n={Enter:"Enter"===t||13===t,Space:" "===t||"Spacebar"===t||32===t,Escape:"Escape"===t||"Esc"===t||27===t,ArrowUp:"ArrowUp"===t||"Up"===t||38===t,ArrowRight:"ArrowRight"===t||"Right"===t||39===t,ArrowDown:"ArrowDown"===t||"Down"===t||40===t,ArrowLeft:"ArrowLeft"===t||"Left"===t||37===t,Home:"Home"===t||36===t,End:"End"===t||35===t,Character:isNaN(t)&&!!t.match(/^[a-zA-Z]{1}$/),Tab:"Tab"===t||9===t,Asterisk:"*"===t||56===t};return Object.keys(n).find((function(e){return!0===n[e]}))||""}catch(e){return""}}function C(e){e.preventDefault(),e.stopPropagation()}var T=function(){function n(e){var o=e.menuElement,r=e.menuItemSelector,l=void 0===r?"li":r,i=e.menuLinkSelector,u=void 0===i?"a":i,c=e.submenuItemSelector,a=void 0===c?"":c,m=e.submenuToggleSelector,h=void 0===m?"a":m,f=e.submenuSelector,d=void 0===f?"ul":f,p=e.controllerElement,v=void 0===p?null:p,y=e.containerElement,g=void 0===y?null:y,b=e.openClass,E=void 0===b?"show":b,C=e.closeClass,T=void 0===C?"hide":C,k=e.isTopLevel,w=void 0===k||k,S=e.parentMenu,I=void 0===S?null:S,L=e.hoverType,A=void 0===L?"off":L,O=e.hoverDelay,D=void 0===O?250:O;t(this,n),s(this,"_MenuType",n),s(this,"_MenuItemType",M),s(this,"_MenuToggleType",_),s(this,"_dom",{menu:null,menuItems:[],submenuItems:[],submenuToggles:[],submenus:[],controller:null,container:null}),s(this,"_selectors",{menuItems:"",menuLinks:"",submenuItems:"",submenuToggles:"",submenus:""}),s(this,"_elements",{menuItems:[],submenuToggles:[],controller:null,parentMenu:null,rootMenu:null}),s(this,"_openClass","show"),s(this,"_closeClass","hide"),s(this,"_root",!0),s(this,"_currentChild",0),s(this,"_focusState","none"),s(this,"_currentEvent","none"),s(this,"_hoverType","off"),s(this,"_hoverDelay",250),this._dom.menu=o,this._dom.controller=v,this._dom.container=g,this._selectors.menuItems=l,this._selectors.menuLinks=u,this._selectors.submenuItems=a,this._selectors.submenuToggles=h,this._selectors.submenus=d,this._elements.menuItems=[],this._elements.submenuToggles=[],this._elements.controller=null,this._elements.parentMenu=I,this._elements.rootMenu=w?this:null,this._openClass=E||"",this._closeClass=T||"",this._root=w,this._hoverType=A,this._hoverDelay=D}return o(n,[{key:"initialize",value:function(){if(!this._validate())throw new Error("AccesibleMenu: cannot initialize menu. See other error messages for more information.");if(null===this.elements.rootMenu&&this._findRootMenu(this),this._setDOMElements(),this.isTopLevel&&this.dom.controller&&this.dom.container){var e=new this._MenuToggleType({menuToggleElement:this.dom.controller,parentElement:this.dom.container,controlledMenu:this});this._elements.controller=e}this._createChildElements()}},{key:"dom",get:function(){return this._dom}},{key:"selectors",get:function(){return this._selectors}},{key:"elements",get:function(){return this._elements}},{key:"isTopLevel",get:function(){return this._root}},{key:"openClass",get:function(){return this.isTopLevel?this._openClass:this.elements.rootMenu.openClass},set:function(e){y({openClass:e}),this._openClass!==e&&(this._openClass=e)}},{key:"closeClass",get:function(){return this.isTopLevel?this._closeClass:this.elements.rootMenu.closeClass},set:function(e){y({closeClass:e}),this._closeClass!==e&&(this._closeClass=e)}},{key:"currentChild",get:function(){return this._currentChild},set:function(e){function t(e){if(["mouse","character"].includes(e.currentEvent)&&e.elements.parentMenu)for(var t=0,n=!1;!n&&t<e.elements.parentMenu.elements.menuItems.length;){var o=e.elements.parentMenu.elements.menuItems[t];o.isSubmenuItem&&o.elements.toggle.elements.controlledMenu===e&&(n=!0,e.elements.parentMenu.currentEvent=e.currentEvent,e.elements.parentMenu.currentChild=t),t++}}p("number",{value:e}),e<-1?(this._currentChild=-1,t(this)):e>=this.elements.menuItems.length?(this._currentChild=this.elements.menuItems.length-1,t(this)):this.focusChild!==e&&(this._currentChild=e,t(this))}},{key:"focusState",get:function(){return this._focusState},set:function(t){!function(t){try{if("object"!==e(t)){var n=e(t);throw new TypeError("AccessibleMenu: Values given to isValidState() must be inside of an object. ".concat(n," given."))}var o=["none","self","child"];for(var s in t)if(!o.includes(t[s]))throw new TypeError("AccessibleMenu: ".concat(s," must be one of the following values: ").concat(o.join(", "),'. "').concat(t[s],'" given.'))}catch(e){return console.error(e),!1}}({value:t}),this._focusState!==t&&(this._focusState=t),this.elements.submenuToggles.length>0&&("self"===t||"none"===t)&&this.elements.submenuToggles.forEach((function(e){e.elements.controlledMenu.focusState="none"})),!this.elements.parentMenu||"self"!==t&&"child"!==t||(this.elements.parentMenu.focusState="child")}},{key:"currentEvent",get:function(){return this._currentEvent},set:function(t){!function(t){try{if("object"!==e(t)){var n=e(t);throw new TypeError("AccessibleMenu: Values given to isValidEvent() must be inside of an object. ".concat(n," given."))}var o=["none","mouse","keyboard","character"];for(var s in t)if(!o.includes(t[s]))throw new TypeError("AccessibleMenu: ".concat(s," must be one of the following values: ").concat(o.join(", "),'. "').concat(t[s],'" given.'))}catch(e){return console.error(e),!1}}({value:t}),this._currentEvent!==t&&(this._currentEvent=t,this.elements.submenuToggles.length>0&&this.elements.submenuToggles.forEach((function(e){e.elements.controlledMenu.currentEvent=t})))}},{key:"currentMenuItem",get:function(){return this.elements.menuItems[this.currentChild]}},{key:"hoverType",get:function(){return this._root?this._hoverType:this.elements.rootMenu.hoverType},set:function(e){g({value:e}),this._hoverType!==e&&(this._hoverType=e)}},{key:"hoverDelay",get:function(){return this._root?this._hoverDelay:this.elements.rootMenu.hoverDelay},set:function(e){p("number",{value:e}),this._hoverDelay!==e&&(this._hoverDelay=e)}},{key:"shouldFocus",get:function(){var e=!1;return"keyboard"!==this.currentEvent&&"character"!==this.currentEvent||(e=!0),"mouse"===this.currentEvent&&"dynamic"===this.hoverType&&(e=!0),e}},{key:"_validate",value:function(){var e=!0;return null!==this._dom.container||null!==this._dom.controller?d(HTMLElement,{menuElement:this._dom.menu,controllerElement:this._dom.controller,containerElement:this._dom.container})||(e=!1):d(HTMLElement,{menuElement:this._dom.menu})||(e=!1),""!==this._selectors.submenuItems?v({menuItemSelector:this._selectors.menuItems,menuLinkSelector:this._selectors.menuLinks,submenuItemSelector:this._selectors.submenuItems,submenuToggleSelector:this._selectors.submenuToggles,submenuSelector:this._selectors.submenus})||(e=!1):v({menuItemSelector:this._selectors.menuItems,menuLinkSelector:this._selectors.menuLinks})||(e=!1),""===this._openClass||y({openClass:this._openClass})||(e=!1),""===this._closeClass||y({closeClass:this._closeClass})||(e=!1),p("boolean",{isTopLevel:this._root})||(e=!1),null===this._elements.parentMenu||d(n,{parentMenu:this._elements.parentMenu})||(e=!1),g({hoverType:this._hoverType})||(e=!1),p("number",{hoverDelay:this._hoverDelay})||(e=!1),e}},{key:"_setDOMElementType",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.dom.menu,n=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];if("string"!=typeof this.selectors[e])throw new Error('AccessibleMenu: "'.concat(e,'" is not a valid element type within the menu.'));if(!Array.isArray(this.dom[e]))throw new Error('AccessibleMenu: The "'.concat(e,'" element cannot be set through _setDOMElementType.'));t!==this.dom.menu&&d(HTMLElement,{base:t});var o=Array.from(t.querySelectorAll(this.selectors[e])),s=o.filter((function(e){return e.parentElement===t}));this._dom[e]=n?s:[].concat(h(this._dom[e]),h(s))}},{key:"_resetDOMElementType",value:function(e){if(void 0===this.dom[e])throw new Error('AccessibleMenu: "'.concat(e,'" is not a valid element type within the menu.'));if(!Array.isArray(this.dom[e]))throw new Error('AccessibleMenu: The "'.concat(e,'" element cannot be reset through _resetDOMElementType.'));this._dom[e]=[]}},{key:"_setDOMElements",value:function(){var e=this;this._setDOMElementType("menuItems"),""!==this.selectors.submenuItems&&(this._setDOMElementType("submenuItems"),this._resetDOMElementType("submenuToggles"),this._resetDOMElementType("submenus"),this.dom.submenuItems.forEach((function(t){e._setDOMElementType("submenuToggles",t,!1),e._setDOMElementType("submenus",t,!1)})))}},{key:"_findRootMenu",value:function(e){if(e.isTopLevel)this._elements.rootMenu=e;else{if(null===e.elements.parentMenu)throw new Error("Cannot find root menu.");this._findRootMenu(e.elements.parentMenu)}}},{key:"_createChildElements",value:function(){var e=this;this.dom.menuItems.forEach((function(t){var n;if(e.dom.submenuItems.includes(t)){var o=t.querySelector(e.selectors.submenuToggles),s=t.querySelector(e.selectors.submenus),r=new e._MenuType({menuElement:s,menuItemSelector:e.selectors.menuItems,menuLinkSelector:e.selectors.menuLinks,submenuItemSelector:e.selectors.submenuItems,submenuToggleSelector:e.selectors.submenuToggles,submenuSelector:e.selectors.submenus,openClass:e.openClass,closeClass:e.closeClass,isTopLevel:!1,parentMenu:e,hoverType:e.hoverType,hoverDelay:e.hoverDelay}),l=new e._MenuToggleType({menuToggleElement:o,parentElement:t,controlledMenu:r,parentMenu:e});e._elements.submenuToggles.push(l),n=new e._MenuItemType({menuItemElement:t,menuLinkElement:o,parentMenu:e,isSubmenuItem:!0,childMenu:r,toggle:l})}else{var i=t.querySelector(e.selectors.menuLinks);n=new e._MenuItemType({menuItemElement:t,menuLinkElement:i,parentMenu:e})}e._elements.menuItems.push(n)}))}},{key:"_handleFocus",value:function(){var e=this;this.elements.menuItems.forEach((function(t,n){t.dom.link.addEventListener("focus",(function(){e.focusState="self",e.currentChild=n}))}))}},{key:"_handleClick",value:function(){var e=this,t=b("touchstart",this.dom.menu)?"touchstart":"mousedown",n=b("touchend",this.dom.menu)?"touchend":"mouseup";function o(e,t,n){C(n),t.toggle(),t.isOpen&&(e.focusState="self",t.elements.controlledMenu.focusState="none")}this.elements.menuItems.forEach((function(s,r){s.dom.link.addEventListener(t,(function(){e.currentEvent="mouse",e.elements.rootMenu.blurChildren(),e.focusChild(r)})),s.isSubmenuItem&&(s.elements.toggle.dom.toggle["on".concat(n)]=function(t){e.currentEvent="mouse",o(e,s.elements.toggle,t)})})),this.isTopLevel&&this.elements.controller&&(this.elements.controller.dom.toggle["on".concat(n)]=function(t){e.currentEvent="mouse",o(e,e.elements.controller,t)})}},{key:"_handleHover",value:function(){var e=this;this.elements.menuItems.forEach((function(t,n){t.dom.link.addEventListener("mouseenter",(function(){if("on"===e.hoverType)e.currentEvent="mouse",e.currentChild=n,t.isSubmenuItem&&t.elements.toggle.preview();else if("dynamic"===e.hoverType){var o=e.elements.submenuToggles.some((function(e){return e.isOpen}));e.currentChild=n,e.isTopLevel&&"none"===e.focusState||(e.currentEvent="mouse",e.focusCurrentChild()),!t.isSubmenuItem||e.isTopLevel&&!o||(e.currentEvent="mouse",t.elements.toggle.preview())}})),t.isSubmenuItem&&t.dom.item.addEventListener("mouseleave",(function(){"on"===e.hoverType?e.hoverDelay>0?setTimeout((function(){e.currentEvent="mouse",t.elements.toggle.close()}),e.hoverDelay):(e.currentEvent="mouse",t.elements.toggle.close()):"dynamic"===e.hoverType&&(e.isTopLevel||(e.hoverDelay>0?setTimeout((function(){e.currentEvent="mouse",t.elements.toggle.close(),e.focusCurrentChild()}),e.hoverDelay):(e.currentEvent="mouse",t.elements.toggle.close(),e.focusCurrentChild())))}))}))}},{key:"_handleKeydown",value:function(){var e=this;this.isTopLevel&&this.elements.controller&&this.elements.controller.dom.toggle.addEventListener("keydown",(function(t){e.currentEvent="keyboard";var n=E(t);"Space"!==n&&"Enter"!==n||C(t)}))}},{key:"_handleKeyup",value:function(){var e=this;this.isTopLevel&&this.elements.controller&&this.elements.controller.dom.toggle.addEventListener("keyup",(function(t){e.currentEvent="keyboard";var n=E(t);"Space"!==n&&"Enter"!==n||(C(t),e.elements.controller.open(),e.focusFirstChild())}))}},{key:"focus",value:function(){this.focusState="self",this.shouldFocus&&this.dom.menu.focus()}},{key:"blur",value:function(){this.focusState="none",this.shouldFocus&&this.dom.menu.blur()}},{key:"focusCurrentChild",value:function(){this.focusState="self",-1!==this.currentChild&&this.currentMenuItem.focus()}},{key:"focusChild",value:function(e){this.blurCurrentChild(),this.currentChild=e,this.focusCurrentChild()}},{key:"focusFirstChild",value:function(){this.focusChild(0)}},{key:"focusLastChild",value:function(){this.focusChild(this.elements.menuItems.length-1)}},{key:"focusNextChild",value:function(){this.currentChild<this.elements.menuItems.length-1?this.focusChild(this.currentChild+1):this.focusCurrentChild()}},{key:"focusPreviousChild",value:function(){this.currentChild>0?this.focusChild(this.currentChild-1):this.focusCurrentChild()}},{key:"blurCurrentChild",value:function(){this.focusState="none",-1!==this.currentChild&&this.currentMenuItem.blur()}},{key:"focusController",value:function(){this.dom.controller&&(this.shouldFocus&&this.dom.controller.focus(),this.focusState="none")}},{key:"focusContainer",value:function(){this.dom.container&&(this.shouldFocus&&this.dom.container.focus(),this.focusState="none")}},{key:"closeChildren",value:function(){this.elements.submenuToggles.forEach((function(e){return e.close()}))}},{key:"blurChildren",value:function(){this.elements.menuItems.forEach((function(e){e.blur(),e.isSubmenuItem&&e.elements.childMenu.blurChildren()}))}}]),n}(),k=function(e){r(o,e);var n=a(o);function o(e){var s,r=e.menuItemElement,l=e.menuLinkElement,i=e.parentMenu,u=e.isSubmenuItem,c=void 0!==u&&u,a=e.childMenu,m=void 0===a?null:a,h=e.toggle,f=void 0===h?null:h,d=e.initialize,p=void 0===d||d;return t(this,o),s=n.call(this,{menuItemElement:r,menuLinkElement:l,parentMenu:i,isSubmenuItem:c,childMenu:m,toggle:f}),p&&s.initialize(),s}return o}(M),w=function(e){r(s,e);var n=a(s);function s(e){var o,r=e.menuToggleElement,l=e.parentElement,i=e.controlledMenu,u=e.parentMenu,c=void 0===u?null:u,a=e.initialize,m=void 0===a||a;return t(this,s),o=n.call(this,{menuToggleElement:r,parentElement:l,controlledMenu:i,parentMenu:c}),m&&o.initialize(),o}return o(s,[{key:"open",value:function(){this.closeSiblings(),m(l(s.prototype),"open",this).call(this)}},{key:"preview",value:function(){this.closeSiblings(),m(l(s.prototype),"preview",this).call(this)}},{key:"close",value:function(){this.isOpen&&this.closeChildren(),m(l(s.prototype),"close",this).call(this)}}]),s}(_);return function(e){r(i,e);var n=a(i);function i(e){var o,r=e.menuElement,l=e.menuItemSelector,c=void 0===l?"li":l,a=e.menuLinkSelector,m=void 0===a?"a":a,h=e.submenuItemSelector,f=void 0===h?"":h,d=e.submenuToggleSelector,p=void 0===d?"a":d,v=e.submenuSelector,y=void 0===v?"ul":v,g=e.controllerElement,b=void 0===g?null:g,_=e.containerElement,M=void 0===_?null:_,E=e.openClass,C=void 0===E?"show":E,T=e.closeClass,S=void 0===T?"hide":T,I=e.isTopLevel,L=void 0===I||I,A=e.parentMenu,O=void 0===A?null:A,D=e.hoverType,j=void 0===D?"off":D,R=e.hoverDelay,z=void 0===R?250:R,K=e.optionalKeySupport,x=void 0!==K&&K,F=e.initialize,H=void 0===F||F;return t(this,i),s(u(o=n.call(this,{menuElement:r,menuItemSelector:c,menuLinkSelector:m,submenuItemSelector:f,submenuToggleSelector:p,submenuSelector:y,controllerElement:b,containerElement:M,openClass:C,closeClass:S,isTopLevel:L,parentMenu:O,hoverType:j,hoverDelay:z})),"_MenuType",i),s(u(o),"_MenuItemType",k),s(u(o),"_MenuToggleType",w),s(u(o),"_currentChild",-1),s(u(o),"_optionalSupport",!1),o._optionalSupport=x,H&&o.initialize(),o}return o(i,[{key:"initialize",value:function(){try{m(l(i.prototype),"initialize",this).call(this),this._handleFocus(),this._handleClick(),this._handleHover(),this._handleKeydown(),this._handleKeyup()}catch(e){console.error(e)}}},{key:"optionalKeySupport",get:function(){return this.isTopLevel?this._optionalSupport:this.elements.rootMenu.optionalKeySupport},set:function(e){p("boolean",{optionalKeySupport:e}),this._optionalSupport=e}},{key:"_validate",value:function(){var e=m(l(i.prototype),"_validate",this).call(this);return p("boolean",{optionalKeySupport:this._optionalSupport})||(e=!1),e}},{key:"_handleClick",value:function(){var e=this;m(l(i.prototype),"_handleClick",this).call(this);var t=b("touchend",this.dom.menu)?"touchend":"mouseup";document.addEventListener(t,(function(t){"none"!==e.focusState&&(e.currentEvent="mouse",e.dom.menu.contains(t.target)||!e.dom.menu===t.target||(e.closeChildren(),e.blur(),e.elements.controller&&e.elements.controller.close()))}))}},{key:"_handleKeydown",value:function(){var e=this;m(l(i.prototype),"_handleKeydown",this).call(this),this.dom.menu.addEventListener("keydown",(function(t){e.currentEvent="keyboard";var n=E(t);if("self"===e.focusState){if(e.optionalKeySupport){["ArrowUp","ArrowRight","ArrowDown","ArrowLeft","Home","End"].includes(n)&&C(t)}else(e.currentMenuItem.isSubmenuItem&&["Space","Enter"].includes(n)||e.elements.controller&&["Escape"].includes(n)||e.elements.parentMenu&&["Escape"].includes(n))&&C(t)}}))}},{key:"_handleKeyup",value:function(){var e=this;m(l(i.prototype),"_handleKeyup",this).call(this),this.dom.menu.addEventListener("keyup",(function(t){e.currentEvent="keyboard";var n=E(t);if("self"===e.focusState)if("Space"===n||"Enter"===n)e.currentMenuItem.isSubmenuItem?(C(t),e.currentMenuItem.elements.toggle.preview()):e.currentMenuItem.dom.link.click();else if("Escape"===n){e.elements.submenuToggles.some((function(e){return e.isOpen}))?(C(t),e.closeChildren()):e.elements.parentMenu?(C(t),e.elements.parentMenu.currentEvent=e.currentEvent,e.elements.parentMenu.closeChildren(),e.elements.parentMenu.focusCurrentChild()):e.isTopLevel&&e.elements.controller&&e.elements.controller.isOpen&&(e.elements.controller.close(),e.focusController())}else e.optionalKeySupport&&("ArrowDown"===n||"ArrowRight"===n?(C(t),e.currentMenuItem.isSubmenuItem&&e.currentMenuItem.elements.toggle.isOpen?(e.currentMenuItem.elements.childMenu.currentEvent="keyboard",e.currentMenuItem.elements.childMenu.focusFirstChild()):e.focusNextChild()):"ArrowUp"===n||"ArrowLeft"===n?(C(t),e.focusPreviousChild()):"Home"===n?(C(t),e.focusFirstChild()):"End"===n&&(C(t),e.focusLastChild()))}))}}]),i}(T)}();
//# sourceMappingURL=disclosure-menu.min.js.map

    document.addEventListener("DOMContentLoaded", () => {
  const containerElement = document.querySelector("nav");
  const controllerElement = containerElement.querySelector("button");
  const menuElement = containerElement.querySelector("ul");

  const menu = new DisclosureMenu({
    menuElement,
    submenuItemSelector: ".dropdown",
    containerElement,
    controllerElement,
    optionalKeySupport: true,
  });
});

No Items Found.

Add Comment
Type in a Nick Name here
 
Related Search Terms
Search Code
Search Code by entering your search text above.
Welcome to CSSBundle.com

Hi there and welcome to CSSBundle. Here at CSS Bundle we aim to find the best css and javascript bundles and demos and add them here to make them easy to find all in one place.

If you would like to stay up to date with our latest updates you can subscribe to our mailing list where we will send you one email per week with the latest updates, no spam emails just the latest updates.

Random Quote


Latest Code
css animations Falling Stars CSS Animation html Video different sources on screen sizes video embed html responsive css animations Animated Triangles on Canvas JS HTML HTML Canvas Instant colour fill with HTML Canvas javascript Transform Text into Images using SnapText JS CSS Tools Fancy Border Radius CSS Generator Tool - spin animation keyframes CSS Tools CSS Drop Filter Shadow Creator CSS Slider A CSS and HTML Only Carousel Slider CSS Z-Index Z-Index Code Front - CSS to change z-index when element is active sections section with image to the right text to the left gradient Sections Two Clickable Logo Promo Box Section Foundation HTML CSS Sections Inline Contact Form Formatting HTML CSS Sections Overview full width section in Poppins font with light gray background using foundation Interactive Images Map Image with Easy Dots and Titles using only CSS HTML Sections Social Header Links easy Drop in Code with Font Awesome Icons Sections Responsive Friendly Subscribe to our Newsletter Section CSS Tips Create a button with CSS, HTML and Center it! CSS Text Formatting Truncate Text to an amount of lines using line-clamp CSS Positions Item Positioning in CSS CSS Tips Draw a Circle in CSS css animations Magical Text Effect Bootstrap 4.2 Kitchen Sink CSS Frameworks Make your site look like windows 7 CSS Backgrounds Fancy up your banner image hero sections using overlay gradients CSS Modal Floating Modal Message Fixed on the Bottom of the Screen CSS Modal Create a modal with only CSS css grid display items in a css grid CSS Text Effects Using the selection selector to change the default highlight color Text Truncate your Text with CSS CSS Cursors Change your cursor into an Emoji Cursor or Image Cursor CSS How to Center Everything or Anything with CSS CSS Animations Smooth Scrolling with just CSS CSS Animations Radial Glow under cursor on box hover over effect CSS Shadows Using a filter drop shadow for transparent images CSS Animations Pure CSS 3D Flipping Book with Animations CSS Create a checkerboard background pattern with CSS CSS Animations button animations hover and fill animation CSS Animations button on focus swing animation CSS Animations Animated Button Border when Active Quick CSS create a border with top triangle in css CSS Animations Single Element CSS Spinners CSS Animations CSS Shake - Shake up your elements CSS Framework NES-style(8bit-like) CSS Framework CSS Tips Why to use a CSS Reset? Web Developer Checklists Front-End Checklist Icons Font Awesome Icons CSS Animation Animate Stuff with Animate.css CSS Animations Check Wave Click a Checkbox and Watch the Animation Animation Cloudy spiral animation with CSS3 Notifications Toast Messages and Notifications Standalone Library no JQuery - notify.js