Navigation element

Demo styling
<nav id="page-navigation" class="page-navigation" aria-label="Company">
    <ul role="menubar" class="page-navigation__menu main-menu flex flex-column flex-row@xl items-center@xl list--reset">
        <li class="main-menu__item main-menu__item--has-submenu main-menu__link--has-large-submenu" role="none">
            <a href="#" class="main-menu__link main-menu__link--has-submenu main-menu__link--primary block" role="menuitem" aria-haspopup="true" aria-expanded="false">
                <span class="main-menu__link-label block">
                    Item 1

                    <svg class="icon" viewBox="0 0 24 24" style="width: 16px; height: 16px;">
                        <path fill="currentColor" d="M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z" />
                    </svg>
                </span>
            </a>
            <div class="main-menu__dropdown main-menu__dropdown--large flex flex-column flex-row@xl" aria-hidden="true">
                <div class="main-menu__dropdown-inner flex flex-column flex-row@xl">
                    <button class="menu-menu__link--back hidden@xl">
                        <svg class="icon" viewBox="0 0 24 24" style="width: 16px; height: 16px;">
                            <path fill="currentColor" d="M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z" />
                        </svg>
                        Terug naar Hoofdnavigatie
                    </button>
                    <div class="hidden@xl">
                        <a href="{item.link}" class="main-menu__link main-menu__link--parent" role="menuitem" data-uid="xx">
                            missing link and attribute View all...
                        </a>
                    </div>
                    <div class="main-menu__column ">
                        <a href="#" class="main-menu__column-title main-menu__link main-menu__link--has-submenu" role="menuitem" aria-haspopup="true" aria-expanded="false">
                            Uitgelicht
                            <svg class="icon" viewBox="0 0 24 24" style="width: 16px; height: 16px;">
                                <path fill="currentColor" d="M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z" />
                            </svg>
                        </a>
                        <div class="main-menu__dropdown main-menu__dropdown--sub flex flex-column flex-row@xl" aria-hidden="true">
                            <button class="menu-menu__link--back hidden@xl">
                                <svg class="icon" viewBox="0 0 24 24" style="width: 16px; height: 16px;">
                                    <path fill="currentColor" d="M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z" />
                                </svg>
                                Terug naar Uitgelicht
                            </button>
                            <ul class="list--reset main-menu__menu" role="menu" aria-label="Uitgelicht">
                                <li class="main-menu__dropdown-item main-menu__dropdown-item--current" role="none">
                                    <a href="#" class="main-menu__link main-menu__link--current" role="menuitem">
                                        Uitgelicht
                                    </a>
                                </li>
                                <li class="main-menu__dropdown-item" role="none">
                                    <a href="#" class="main-menu__link main-menu__link--sub" role="menuitem">
                                        Nieuwe producten
                                    </a>
                                </li>
                                <li class="main-menu__dropdown-item" role="none">
                                    <a href="#" class="main-menu__link main-menu__link--sub" role="menuitem">
                                        Collectie
                                    </a>
                                </li>
                                <li class="main-menu__dropdown-item" role="none">
                                    <a href="#" class="main-menu__link main-menu__link--sub" role="menuitem">
                                        Uitverkoop
                                    </a>
                                </li>
                                <li class="main-menu__dropdown-item" role="none">
                                    <a href="#" class="main-menu__link main-menu__link--sub" role="menuitem">
                                        Duurzame materialen
                                    </a>
                                </li>
                            </ul>
                        </div>
                    </div>
                    <div class="main-menu__column padding-left-md@xl padding-left-lg@xl">
                        <a href="#" class="main-menu__column-title main-menu__link main-menu__link--has-submenu" role="menuitem" aria-haspopup="true" aria-expanded="false">
                            Item 1 Sub 1
                            <svg class="icon" viewBox="0 0 24 24" style="width: 16px; height: 16px;">
                                <path fill="currentColor" d="M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z" />
                            </svg>
                        </a>
                        <div class="main-menu__dropdown main-menu__dropdown--sub flex flex-column flex-row@xl" aria-hidden="true">
                            <button class="menu-menu__link--back hidden@xl">
                                <svg class="icon" viewBox="0 0 24 24" style="width: 16px; height: 16px;">
                                    <path fill="currentColor" d="M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z" />
                                </svg>
                                Terug naar Item 1 Sub 1
                            </button>
                            <ul class="list--reset main-menu__menu" role="menu" aria-label="Item 1 Sub 1">
                                <li class="main-menu__dropdown-item main-menu__dropdown-item--current" role="none">
                                    <a href="#" class="main-menu__link main-menu__link--current" role="menuitem">
                                        Item 1 Sub 1
                                    </a>
                                </li>
                                <li class="main-menu__dropdown-item" role="none">
                                    <a href="#" class="main-menu__link main-menu__link--sub" role="menuitem">
                                        Subcategorie
                                    </a>
                                </li>
                                <li class="main-menu__dropdown-item" role="none">
                                    <a href="#" class="main-menu__link main-menu__link--sub" role="menuitem">
                                        Subcategorie
                                    </a>
                                </li>
                                <li class="main-menu__dropdown-item" role="none">
                                    <a href="#" class="main-menu__link main-menu__link--sub" role="menuitem">
                                        Subcategorie
                                    </a>
                                </li>
                                <li class="main-menu__dropdown-item" role="none">
                                    <a href="#" class="main-menu__link main-menu__link--sub" role="menuitem">
                                        Subcategorie
                                    </a>
                                </li>
                            </ul>
                        </div>
                    </div>
                    <div class="main-menu__column padding-left-md@xl padding-left-lg@xl">
                        <a href="#" class="main-menu__column-title main-menu__link main-menu__link--has-submenu" role="menuitem" aria-haspopup="true" aria-expanded="false">
                            Item 1 Sub 2
                            <svg class="icon" viewBox="0 0 24 24" style="width: 16px; height: 16px;">
                                <path fill="currentColor" d="M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z" />
                            </svg>
                        </a>
                        <div class="main-menu__dropdown main-menu__dropdown--sub flex flex-column flex-row@xl" aria-hidden="true">
                            <button class="menu-menu__link--back hidden@xl">
                                <svg class="icon" viewBox="0 0 24 24" style="width: 16px; height: 16px;">
                                    <path fill="currentColor" d="M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z" />
                                </svg>
                                Terug naar Item 1 Sub 2
                            </button>
                            <ul class="list--reset main-menu__menu" role="menu" aria-label="Item 1 Sub 2">
                                <li class="main-menu__dropdown-item main-menu__dropdown-item--current" role="none">
                                    <a href="#" class="main-menu__link main-menu__link--current" role="menuitem">
                                        Item 1 Sub 2
                                    </a>
                                </li>
                                <li class="main-menu__dropdown-item" role="none">
                                    <a href="#" class="main-menu__link main-menu__link--sub" role="menuitem">
                                        Subcategorie
                                    </a>
                                </li>
                                <li class="main-menu__dropdown-item" role="none">
                                    <a href="#" class="main-menu__link main-menu__link--sub" role="menuitem">
                                        Subcategorie
                                    </a>
                                </li>
                                <li class="main-menu__dropdown-item" role="none">
                                    <a href="#" class="main-menu__link main-menu__link--sub" role="menuitem">
                                        Subcategorie
                                    </a>
                                </li>
                                <li class="main-menu__dropdown-item" role="none">
                                    <a href="#" class="main-menu__link main-menu__link--sub" role="menuitem">
                                        Subcategorie
                                    </a>
                                </li>
                            </ul>
                        </div>
                    </div>
                </div>
            </div>
        </li>
        <li class="main-menu__item main-menu__item--has-submenu " role="none">
            <a href="#" class="main-menu__link main-menu__link--has-submenu main-menu__link--primary block" role="menuitem" aria-haspopup="true" aria-expanded="false">
                <span class="main-menu__link-label block">
                    Item 2

                    <svg class="icon" viewBox="0 0 24 24" style="width: 16px; height: 16px;">
                        <path fill="currentColor" d="M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z" />
                    </svg>
                </span>
            </a>
            <div class="main-menu__dropdown flex flex-column" aria-hidden="true">
                <div class="main-menu__dropdown-inner flex flex-column flex-row@xl">
                    <button class="menu-menu__link--back hidden@xl">
                        <svg class="icon" viewBox="0 0 24 24" style="width: 16px; height: 16px;">
                            <path fill="currentColor" d="M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z" />
                        </svg>
                        Terug naar Item 2
                    </button>
                    <div class="hidden@xl">
                        <a href="{item.link}" class="main-menu__link main-menu__link--parent" role="menuitem" data-uid="xx">
                            Missing link attribute View all...
                        </a>
                    </div>
                    <ul class="list--reset main-menu__menu" role="menu">
                        <li class="main-menu__dropdown-item" role="none">
                            <a href="#" class="main-menu__link main-menu__link--sub block padding-sm" role="menuitem">
                                Nieuwe producten
                            </a>
                        </li>
                        <li class="main-menu__dropdown-item" role="none">
                            <a href="#" class="main-menu__link main-menu__link--sub block padding-sm" role="menuitem">
                                Collectie
                            </a>
                        </li>
                        <li class="main-menu__dropdown-item" role="none">
                            <a href="#" class="main-menu__link main-menu__link--sub block padding-sm" role="menuitem">
                                Uitverkoop
                            </a>
                        </li>
                        <li class="main-menu__dropdown-item" role="none">
                            <a href="#" class="main-menu__link main-menu__link--sub block padding-sm" role="menuitem">
                                Duurzame materialen
                            </a>
                        </li>
                    </ul>
                </div>
            </div>
        </li>
        <li class="main-menu__item  " role="none">
            <a href="#" class="main-menu__link main-menu__link--has-submenu main-menu__link--primary block" role="menuitem">
                <span class="main-menu__link-label block">
                    Item 3

                </span>
            </a>
            <div class="main-menu__dropdown flex flex-column" aria-hidden="true">
                <div class="main-menu__dropdown-inner flex flex-column flex-row@xl">
                    <button class="menu-menu__link--back hidden@xl">
                        <svg class="icon" viewBox="0 0 24 24" style="width: 16px; height: 16px;">
                            <path fill="currentColor" d="M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z" />
                        </svg>
                        Terug naar Item 3
                    </button>
                    <div class="hidden@xl">
                        <a href="{item.link}" class="main-menu__link main-menu__link--parent" role="menuitem" data-uid="xx">
                            Missing link attribute View all...
                        </a>
                    </div>
                    <ul class="list--reset main-menu__menu" role="menu">
                    </ul>
                </div>
            </div>
        </li>
        <li class="main-menu__item  " role="none">
            <a href="#" class="main-menu__link main-menu__link--has-submenu main-menu__link--primary block" role="menuitem">
                <span class="main-menu__link-label block">
                    Item 4

                </span>
            </a>
            <div class="main-menu__dropdown flex flex-column" aria-hidden="true">
                <div class="main-menu__dropdown-inner flex flex-column flex-row@xl">
                    <button class="menu-menu__link--back hidden@xl">
                        <svg class="icon" viewBox="0 0 24 24" style="width: 16px; height: 16px;">
                            <path fill="currentColor" d="M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z" />
                        </svg>
                        Terug naar Item 4
                    </button>
                    <div class="hidden@xl">
                        <a href="{item.link}" class="main-menu__link main-menu__link--parent" role="menuitem" data-uid="xx">
                            Missing link attribute View all...
                        </a>
                    </div>
                    <ul class="list--reset main-menu__menu" role="menu">
                    </ul>
                </div>
            </div>
        </li>
    </ul>
</nav>

<script src="/components/raw/navigation/navigation.js"></script>
<nav id="page-navigation" class="page-navigation" aria-label="{{siteName}}">
    <ul role="menubar" class="page-navigation__menu main-menu flex flex-column flex-row@xl items-center@xl list--reset">
        {{#each navigation.items}}
            <li class="main-menu__item {{#if children}}main-menu__item--has-submenu{{/if}} {{#if this.megamenu}}main-menu__link--has-large-submenu{{/if}}" role="none">
                <a href="{{link}}" class="main-menu__link main-menu__link--has-submenu main-menu__link--primary block" role="menuitem" {{#if children}}aria-haspopup="true" aria-expanded="false"{{/if}}>
                    <span class="main-menu__link-label block">
                        {{label}}

                        {{#if children}}
                            <svg class="icon" viewBox="0 0 24 24" style="width: 16px; height: 16px;">
                                <path fill="currentColor" d="M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z" />
                            </svg>
                        {{/if}}
                    </span>
                </a>
                {{#if megamenu}}
                    <div class="main-menu__dropdown main-menu__dropdown--large flex flex-column flex-row@xl" aria-hidden="true">
                        <div class="main-menu__dropdown-inner flex flex-column flex-row@xl">
                            <button class="menu-menu__link--back hidden@xl">
                                <svg class="icon" viewBox="0 0 24 24" style="width: 16px; height: 16px;">
                                    <path fill="currentColor" d="M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z" />
                                </svg>
                                Terug naar Hoofdnavigatie
                            </button>
                            <div class="hidden@xl">
                                <a href="{item.link}" class="main-menu__link main-menu__link--parent" role="menuitem" data-uid="xx">
                                    missing link and attribute View all...
                                </a>
                            </div>
                            {{#each children}}
                                <div class="main-menu__column {{#unless @first}}padding-left-md@xl padding-left-lg@xl{{/unless}}">
                                    <a href="{{link}}" class="main-menu__column-title main-menu__link {{#if items}}main-menu__link--has-submenu{{/if}}" role="menuitem" {{#if items}}aria-haspopup="true" aria-expanded="false"{{/if}}>
                                        {{title}}
                                        {{#if items}}
                                            <svg class="icon" viewBox="0 0 24 24" style="width: 16px; height: 16px;">
                                                <path fill="currentColor" d="M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z" />
                                            </svg>
                                        {{/if}}
                                    </a>
                                    {{#if items}}
                                        <div class="main-menu__dropdown main-menu__dropdown--sub flex flex-column flex-row@xl" aria-hidden="true">
                                            <button class="menu-menu__link--back hidden@xl">
                                                <svg class="icon" viewBox="0 0 24 24" style="width: 16px; height: 16px;">
                                                    <path fill="currentColor" d="M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z" />
                                                </svg>
                                                Terug naar {{title}}
                                            </button>
                                            <ul class="list--reset main-menu__menu" role="menu" aria-label="{{title}}">
                                                <li class="main-menu__dropdown-item main-menu__dropdown-item--current" role="none">
                                                    <a href="{{link}}" class="main-menu__link main-menu__link--current" role="menuitem">
                                                        {{title}}
                                                    </a>
                                                </li>
                                                {{#each items}}
                                                    <li class="main-menu__dropdown-item" role="none">
                                                        <a href="{{link}}" class="main-menu__link main-menu__link--sub" role="menuitem">
                                                            {{label}}
                                                        </a>
                                                    </li>
                                                {{/each}}
                                            </ul>
                                        </div>
                                    {{/if}}
                                </div>
                            {{/each}}
                        </div>
                    </div>
                {{else}}
                    <div class="main-menu__dropdown flex flex-column" aria-hidden="true">
                        <div class="main-menu__dropdown-inner flex flex-column flex-row@xl">
                            <button class="menu-menu__link--back hidden@xl">
                                <svg class="icon" viewBox="0 0 24 24" style="width: 16px; height: 16px;">
                                    <path fill="currentColor" d="M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z" />
                                </svg>
                                Terug naar {{label}}
                            </button>
                           <div class="hidden@xl">
                                <a href="{item.link}" class="main-menu__link main-menu__link--parent" role="menuitem" data-uid="xx">
                                    Missing link attribute View all...
                                </a>
                            </div>
                            <ul class="list--reset main-menu__menu" role="menu">
                                {{#each children.items}}
                                    <li class="main-menu__dropdown-item" role="none">
                                        <a href="{{link}}" class="main-menu__link main-menu__link--sub block padding-sm" role="menuitem">
                                            {{label}}
                                        </a>
                                    </li>
                                {{/each}}
                            </ul>
                        </div>
                    </div>
                {{/if}}
            </li>
        {{/ each}}
    </ul>
</nav>

<script src="{{static 'navigation.js'}}"></script>
{
  "siteName": "Company",
  "navigation": {
    "items": [
      {
        "label": "Item 1",
        "link": "#",
        "megamenu": true,
        "current": true,
        "children": {
          "1": {
            "title": "Uitgelicht",
            "link": "#",
            "items": [
              {
                "label": "Nieuwe producten",
                "link": "#"
              },
              {
                "label": "Collectie",
                "link": "#"
              },
              {
                "label": "Uitverkoop",
                "link": "#"
              },
              {
                "label": "Duurzame materialen",
                "link": "#"
              }
            ]
          },
          "2": {
            "title": "Item 1 Sub 1",
            "link": "#",
            "items": [
              {
                "label": "Subcategorie",
                "link": "#"
              },
              {
                "label": "Subcategorie",
                "link": "#"
              },
              {
                "label": "Subcategorie",
                "link": "#"
              },
              {
                "label": "Subcategorie",
                "link": "#"
              }
            ]
          },
          "3": {
            "title": "Item 1 Sub 2",
            "link": "#",
            "items": [
              {
                "label": "Subcategorie",
                "link": "#"
              },
              {
                "label": "Subcategorie",
                "link": "#"
              },
              {
                "label": "Subcategorie",
                "link": "#"
              },
              {
                "label": "Subcategorie",
                "link": "#"
              }
            ]
          }
        }
      },
      {
        "label": "Item 2",
        "link": "#",
        "current": false,
        "children": {
          "items": [
            {
              "label": "Nieuwe producten",
              "link": "#"
            },
            {
              "label": "Collectie",
              "link": "#"
            },
            {
              "label": "Uitverkoop",
              "link": "#"
            },
            {
              "label": "Duurzame materialen",
              "link": "#"
            }
          ]
        }
      },
      {
        "label": "Item 3",
        "link": "#",
        "current": false
      },
      {
        "label": "Item 4",
        "link": "#",
        "current": false
      }
    ]
  }
}
  • Content:
    (function () {
        "use strict";
    
        var PageNavigation,
            navigationActive = false,
            breakpoint = getComputedStyle(document.documentElement).getPropertyValue('--navigation-breakpoint') || "xl"
    
        PageNavigation = function (el) {
            this.element = el;
            this.pageNavigationActiveClass = "page-navigation--active";
    
            this.navToggle = document.querySelector(".js-nav-toggle");
            this.navToggleActiveClass = "nav-toggle--active";
    
            this.dropdownClass = ".main-menu__dropdown";
    
            this.menuClass = ".main-menu__menu";
    
            this.menuColumnClass = "main-menu__column";
            this.menuColumnTitleClass = "main-menu__column-title";
    
            this.menuLinkPrimaryClass = "main-menu__link--primary";
            this.menuLinkSubClass = "main-menu__link--sub";
    
            this.menuLinkColumnTitleClass = "main-menu__column-title";
    
            this.menuLinkCurrentClass = "main-menu__dropdown-item--current"
    
            this.menuLinksClass = "main-menu__link";
            this.menuLinksParentClass = "main-menu__link--parent";
            this.menuLinks = this.element.querySelectorAll("." + this.menuLinksClass);
    
            this.menuLinksWithDropdownClass = "main-menu__link--has-submenu"
            this.menuLinksWithLargeDropdownClass = "main-menu__item--has-large-submenu"
            this.menuLinksWithDropdown = this.element.querySelectorAll("." + this.menuLinksWithDropdownClass);
    
            this.backButtonClass = "menu-menu__link--back";
            this.backButtons = this.element.querySelectorAll("." + this.backButtonClass);
    
            this.bodyClass = "navigation-active";
    
            this.keys = {
                tab: 9,
                enter: 13,
                esc: 27,
                space: 32,
                left: 37,
                up: 38,
                right: 39,
                down: 40
            }
    
            this.init = this.init.bind(this);
            this.addEventListeners = this.addEventListeners.bind(this);
            this.responsiveEventListeners = this.responsiveEventListeners.bind(this);
            this.setResponsiveAttributes = this.setResponsiveAttributes.bind(this);
            this.toggleNavigation = this.toggleNavigation.bind(this);
            this.toggleAttribute = this.toggleAttribute.bind(this);
            this.openSubMenu = this.openSubMenu.bind(this);
            this.closeSubMenu = this.closeSubMenu.bind(this);
            this.toggleAllSubMenus = this.toggleAllSubMenus.bind(this);
            this.goPrev = this.goPrev.bind(this);
            this.goNext = this.goNext.bind(this);
            this.checkKey = this.checkKey.bind(this);
    
            this.init();
        }
    
        PageNavigation.prototype.init = function () {
            this.addEventListeners();
            this.responsiveEventListeners();
            this.setResponsiveAttributes();
    
            window.addEventListener("resize", FF.throttle(this.responsiveEventListeners, 10));
            window.addEventListener("resize", FF.throttle(this.setResponsiveAttributes, 10));
        }
    
        /*
        * Listen to clicks and keypress on nav toggle to display navigation when a user interacts with it
        * */
        PageNavigation.prototype.addEventListeners = function () {
            this.navToggle.addEventListener("click", this.toggleNavigation);
            this.navToggle.addEventListener("keydown", this.toggleNavigation);
    
            for (var i = 0; i < this.menuLinks.length; i += 1) {
                this.menuLinks[i].addEventListener("keydown", this.checkKey)
            }
    
            for (var i = 0; i < this.backButtons.length; i += 1) {
                this.backButtons[i].addEventListener("click", this.closeSubMenu);
                this.backButtons[i].addEventListener("keydown", this.checkKey);
            }
        }
    
        /*
        * Event listeners for menuLinks that need to change based on the breakpoint
        * */
        PageNavigation.prototype.responsiveEventListeners = function () {
            for (var i = 0; i < this.menuLinksWithDropdown.length; i +=1) {
                if (FF.mq.atLeast(breakpoint)) {
                    this.menuLinksWithDropdown[i].removeEventListener("click", this.openSubMenu);
                } else {
                    this.menuLinksWithDropdown[i].addEventListener("click", this.openSubMenu);
                }
            }
        }
    
        /*
        * Set aria-hidden attribute when screen gets below threshold.
        * */
        PageNavigation.prototype.setResponsiveAttributes = function () {
            if (!FF.mq.atLeast(breakpoint)) {
                this.element.setAttribute('aria-hidden', "true");
                this.element.setAttribute('aria-expanded', "false");
            } else {
                this.element.setAttribute('aria-hidden', "false");
                this.element.setAttribute('aria-expanded', "true");
            }
        }
    
        /*
        * Toggle navigation on small screens and set attributes to nav toggle
        * */
        PageNavigation.prototype.toggleNavigation = function (event) {
            var code = event.keyCode || event.which;
    
            if (code === 1 || code === this.keys.esc) {
                // Set navigationActive variable
                navigationActive = !navigationActive;
    
                // Set class and aria attributes on toggle
                this.navToggle.classList.toggle(this.navToggleActiveClass);
                this.toggleAttribute(this.navToggle, "aria-expanded");
    
                // Set aria attributes on navigation
                this.element.classList.toggle(this.pageNavigationActiveClass);
                this.toggleAttribute(this.element, "aria-hidden");
                this.toggleAttribute(this.element, "aria-expanded");
    
                // Move focus to  navigation
                this.element.focus();
    
                // Set class to body
                document.body.classList.add(this.bodyClass);
            }
    
            // Close all submenu's when navigation is closed and move focus to navToggle
            if (!navigationActive) {
                this.toggleAllSubMenus(this.element, false);
                this.navToggle.focus();
                document.body.classList.remove(this.bodyClass);
            }
        }
    
        PageNavigation.prototype.openSubMenu = function (event) {
            var target = event.target,
                dropdown = target.parentElement.querySelector(this.dropdownClass);
            event.preventDefault();
    
            if (dropdown) {
                // Set attribute expanded true on target
                this.toggleAttribute(target, "aria-expanded");
    
                // Open dropdown and move focus to first item in dropdown
                this.toggleAttribute(dropdown, "aria-hidden");
                dropdown.querySelector("." + this.menuLinksClass).focus();
    
                // If dropdown is a mega menu, toggle all aria attributes of submenu's
                if (FF.mq.atLeast(breakpoint)) {
                    if (event.target.parentElement.classList.contains(this.menuLinksWithLargeDropdownClass)) {
                        this.toggleAllSubMenus(event.target.nextElementSibling, true);
                    }
                }
            }
        }
    
        PageNavigation.prototype.closeSubMenu = function (event) {
            var target = event.target,
                dropdown = target.closest(this.dropdownClass),
                dropdownParent;
    
            if (dropdown) {
                dropdownParent = dropdown.parentElement.querySelector("." + this.menuLinksWithDropdownClass);
    
                // Close dropdown
                this.toggleAttribute(dropdown, "aria-hidden");
    
                // Set attribute expanded false on parent of dropdown and move focus to parent item
                this.toggleAttribute(dropdownParent, "aria-expanded");
                dropdownParent.focus();
    
                // If dropdown is a mega menu, toggle all aria attributes of submenu's
                if (FF.mq.atLeast(breakpoint)) {
                    if (event.target.parentElement.classList.contains(this.menuLinksWithLargeDropdownClass)) {
                        this.toggleAllSubMenus(event.target.nextElementSibling, false);
                    }
                }
            } else {
                this.toggleNavigation(event);
            }
        }
    
        /*
        * Reset all dropdowns inside the menu
        * */
        PageNavigation.prototype.toggleAllSubMenus = function (target, state) {
            var menuLinks = target.querySelectorAll("." + this.menuLinksWithDropdownClass),
                dropdowns = target.querySelectorAll(this.dropdownClass);
    
    
            for (var i = 0; i < menuLinks.length; i +=1) {
                menuLinks[i].setAttribute("aria-expanded", state);
            }
    
            for (var i = 0; i < dropdowns.length; i += 1) {
                dropdowns[i].setAttribute("aria-hidden", !state);
            }
        }
    
        PageNavigation.prototype.goNext = function (event) {
            event.preventDefault();
            var nextItem = event.target.parentElement.nextElementSibling;
    
            if (nextItem) {
                nextItem.querySelector("." + this.menuLinksClass).focus();
            } else {
                if (FF.mq.atLeast(breakpoint)) {
                    if (event.target.closest("." + this.menuColumnClass) && event.target.closest("." + this.menuColumnClass).nextElementSibling) {
                        event.target.closest("." + this.menuColumnClass).nextElementSibling.querySelector("." + this.menuLinksClass).focus();
                    }
                } else {
                    if (event.target.classList.contains(this.menuLinksParentClass)) {
                        event.target.nextElementSibling.querySelector("." + this.menuLinksClass).focus();
                    } else {
                        event.target.parentElement.querySelector("." + this.menuLinksClass).focus();
                    }
                }
            }
        }
    
        PageNavigation.prototype.goPrev = function (event) {
            event.preventDefault();
    
            var prevItem = event.target.parentElement.previousElementSibling;
    
            if (prevItem) {
                if (prevItem.classList.contains(this.backButtonClass)) {
                    prevItem.focus();
                } else if (prevItem.querySelector("." + this.menuLinksClass)) {
                    prevItem.querySelector("." + this.menuLinksClass).focus();
                }
    
                if (FF.mq.atLeast(breakpoint)) {
                    if (prevItem.classList.contains(this.menuLinkCurrentClass)) {
                        if (event.target.closest("." + this.menuColumnClass)) {
                            event.target.closest("." + this.menuColumnClass).querySelector("." + this.menuLinksClass).focus();
                        }
                    }
    
                    if (prevItem.classList.contains(this.menuColumnClass)) {
                        if (prevItem.querySelector(this.menuClass)) {
                            prevItem.querySelector(this.menuClass).lastElementChild.querySelector("." + this.menuLinksClass).focus()
                        } else {
                            prevItem.querySelector("." + this.menuLinksClass).focus();
                        }
                    }
                }
            } else {
                if (FF.mq.atLeast(breakpoint)) {
                    this.closeSubMenu(event);
                } else {
                    if (event.target.closest(this.menuClass) && event.target.closest(this.menuClass).previousElementSibling) {
                        if (event.target.closest(this.menuClass).previousElementSibling.classList.contains(this.backButtonClass)) {
                            event.target.closest(this.menuClass).previousElementSibling.focus();
                        } else {
                            event.target.closest(this.menuClass).previousElementSibling.querySelector("." + this.menuLinksClass).focus();
                        }
                    }
                }
            }
        }
    
        PageNavigation.prototype.checkKey = function (event) {
            var target = event.target,
                code = event.keyCode,
                preventDefault = false;
    
            switch (code) {
                case this.keys.tab:
                    if (!event.target.classList.contains('main-menu__link--last')) {
                        preventDefault = true;
    
                        if (event.shiftKey) {
                            this.goPrev(event);
                        } else {
                            this.goNext(event);
                        }
                    }
    
                    break;
                case this.keys.down:
                    preventDefault = true;
    
                    if (FF.mq.atLeast(breakpoint)) {
                        if (event.target.classList.contains(this.menuLinkPrimaryClass)) {
                            if (event.target.parentElement.classList.contains(this.menuLinksWithLargeDropdownClass)) {
                                this.toggleAllSubMenus(event.target.nextElementSibling, true);
                            }
                            this.openSubMenu(event);
                        } else if (event.target.classList.contains(this.menuColumnTitleClass)) {
                            if (event.target.nextElementSibling) {
                                event.target.nextElementSibling.querySelectorAll("." + this.menuLinksClass)[1].focus()
                            }
                        } else {
                            this.goNext(event);
                        }
                    } else {
                        this.goNext(event);
                    }
                    break;
                case this.keys.up:
                    preventDefault = true;
    
                    if (FF.mq.atLeast(breakpoint)) {
                        if (!event.target.classList.contains(this.menuLinkPrimaryClass)) {
                            this.goPrev(event);
                        }
                    } else {
                        this.goPrev(event);
                    }
                    break;
    
                case this.keys.left:
                    preventDefault = true;
                    if (FF.mq.atLeast(breakpoint)) {
                        if (!event.target.classList.contains(this.menuLinkSubClass)) {
                            this.goPrev(event);
                        }
                    }
                    break;
                case this.keys.right:
                    preventDefault = true;
                    if (FF.mq.atLeast(breakpoint)) {
                        if (!event.target.classList.contains(this.menuLinkSubClass)) {
                            this.goNext(event);
                        }
                    }
                    break;
                case this.keys.enter:
                case this.keys.space:
                    preventDefault = true;
                    if (target.classList.contains(this.menuLinksWithDropdownClass)) {
                        this.openSubMenu(event);
                    }
    
                    if (target.classList.contains(this.backButtonClass)) {
                        this.closeSubMenu(event);
                    }
                    break;
                case this.keys.esc:
                    if (FF.mq.atLeast(breakpoint)) {
                        if (!event.target.closest("." + this.menuColumnClass)) {
                            this.closeSubMenu(event);
                        } else if (event.target.classList.contains(this.menuLinkColumnTitleClass)) {
                            this.closeSubMenu(event);
                        } else {
                            event.target.closest("." + this.menuColumnClass).querySelector("." + this.menuLinksClass).focus();
                        }
                    } else {
                        this.closeSubMenu(event);
                    }
                    break;
            }
    
            if (preventDefault) {
                event.preventDefault();
            }
        }
    
        /*
        * Helper function to set attributes
        * */
        PageNavigation.prototype.toggleAttribute = function (element, attr) {
            var state = element.getAttribute(attr) === "true" || false
            element.setAttribute(attr, !state);
        }
    
        window.PageNavigation = PageNavigation;
    })();
    
    new PageNavigation(document.getElementById('page-navigation'));
  • URL: /components/raw/navigation/navigation.js
  • Filesystem Path: src/components/components/navigation/navigation.js
  • Size: 15.4 KB

No notes defined.