<nav id="example-nav--sub--dark" class="cwf-nav cwf-nav--sub cwf-nav--dark" aria-label="Sub">
    <div class="cwf-nav__container">
        <div class="cwf-nav__controller">
            <ul class="cwf-nav__list cwf-nav__list--level-2 cwf-scroll--y">
                <li class="cwf-nav__item cwf-nav__item--has-dropdown ">
                    <a href="/components/global/" class="cwf-nav__link">
                        Global
                    </a>
                    <button class="cwf-nav__toggle">
                        <i class="cwf-nav__icon" aria-hidden="true"></i>
                    </button>
                    <ul class="cwf-nav__list cwf-nav__list--level-3 ">
                        <li class="cwf-nav__item  ">
                            <a href="/components/global/breadcrumb/" class="cwf-nav__link">
                                Breadcrumb
                            </a>
                        </li>
                        <li class="cwf-nav__item  ">
                            <a href="/components/global/button/" class="cwf-nav__link">
                                Button
                            </a>
                        </li>
                        <li class="cwf-nav__item  ">
                            <a href="/components/global/footer/" class="cwf-nav__link">
                                Footer
                            </a>
                        </li>
                        <li class="cwf-nav__item  ">
                            <a href="/components/global/form/" class="cwf-nav__link">
                                Form
                            </a>
                        </li>
                        <li class="cwf-nav__item  ">
                            <a href="/components/global/general-content/" class="cwf-nav__link">
                                General content
                            </a>
                        </li>
                        <li class="cwf-nav__item  ">
                            <a href="/components/global/grid/" class="cwf-nav__link">
                                Grid
                            </a>
                        </li>
                        <li class="cwf-nav__item  ">
                            <a href="/components/global/header/" class="cwf-nav__link">
                                Header
                            </a>
                        </li>
                        <li class="cwf-nav__item cwf-nav__item--has-dropdown ">
                            <a href="/components/global/navigation/" class="cwf-nav__link">
                                Navigation
                            </a>
                        </li>
                        <li class="cwf-nav__item  ">
                            <a href="/components/global/skip-links/" class="cwf-nav__link">
                                Skip links
                            </a>
                        </li>
                    </ul>

                </li>
                <li class="cwf-nav__item cwf-nav__item--has-dropdown ">
                    <a href="/components/content/" class="cwf-nav__link">
                        Content
                    </a>
                    <button class="cwf-nav__toggle">
                        <i class="cwf-nav__icon" aria-hidden="true"></i>
                    </button>
                    <ul class="cwf-nav__list cwf-nav__list--level-3 ">
                        <li class="cwf-nav__item  ">
                            <a href="/components/content/accordion/" class="cwf-nav__link">
                                Accordion
                            </a>
                        </li>
                        <li class="cwf-nav__item  ">
                            <a href="/components/content/card/" class="cwf-nav__link">
                                Card
                            </a>
                        </li>
                        <li class="cwf-nav__item  ">
                            <a href="/components/content/hero/" class="cwf-nav__link">
                                Hero
                            </a>
                        </li>
                        <li class="cwf-nav__item  ">
                            <a href="/components/content/modal/" class="cwf-nav__link">
                                Modal
                            </a>
                        </li>
                        <li class="cwf-nav__item  ">
                            <a href="/components/content/notification/" class="cwf-nav__link">
                                Notification
                            </a>
                        </li>
                        <li class="cwf-nav__item  ">
                            <a href="/components/content/tabs/" class="cwf-nav__link">
                                Tabs
                            </a>
                        </li>
                    </ul>

                </li>
            </ul>
        </div>
    </div>
</nav>
{% macro generate(title, routes, level, limit, class) %}
    {% if routes|length %}
        {% set listClasses = [
            'cwf-nav__list',
            'cwf-nav__list--level-' ~ level,
            class
        ] %}
        <ul class="{{ listClasses|join(' ') }}">
            {% for route in routes %}
                {% set hasDropdown = route.children
                    ? 'cwf-nav__item--has-dropdown'
                    : ''
                %}
                {% set isCurrent = route.name == title
                    ? 'cwf-nav__item--is-current'
                    : ''
                %}
                {% set classes = ['cwf-nav__item', hasDropdown, isCurrent] %}
                <li class="{{ classes|join(' ') }}">
                    {% set href = route.href %}
                    <a href="{{ href }}"
                        class="cwf-nav__link"
                        {{ isCurrent ? ' aria-current="page"' }}>
                        {{ route.name.short ?? route.name.full ?? route.name }}
                    </a>
                    {% if
                        route.children is defined
                            and (route.children|length)
                            and level <= limit %}
                        <button class="cwf-nav__toggle">
                            <i class="cwf-nav__icon" aria-hidden="true"></i>
                        </button>
                        {{
                            _self.generate(
                                title,
                                route.children,
                                level + 1,
                                limit
                            )
                        }}
                    {% endif %}
                </li>
            {% endfor %}
        </ul>
    {% endif %}
{% endmacro %}

{% macro main(title, routes) %}
    {% set filteredRoutes = [] %}
    {% for route in routes %}
        {% if route.level == 1 %}
            {% set filteredRoutes = filteredRoutes|merge([route]) %}
        {% endif %}
    {% endfor %}
    {{- _self.generate(title, filteredRoutes, 1, 2) -}}
{% endmacro %}

{% macro sub(title, routes, siblings) %}
    {% set filteredRoutes = [] %}
    {% set parentLink = '' %}
    {% set break = false %}
    {% for route in routes if not break %}
        {% if route.name.full == title or route.name == title %}
            {% set break = true %}
            {% set parent = false %}
            {% set hasParent = route.parents is defined
                and (route.parents|length)
            %}
            {% if hasParent %}
                {% set parent = route.parents|last %}
            {% endif %}
            {% set hasChildren = route.children is defined
                and (route.children|length)
            %}
            {% set hasSiblings = parent
                and parent.children is defined
                and (parent.children|length)
                and (parent.children|length) > 1
            %}
            {% if hasChildren %}
                {% set filteredRoutes = route.children %}
            {% elseif hasSiblings and siblings %}
                {% set filteredRoutes = parent.children %}
            {% endif %}
        {% endif %}
    {% endfor %}
    {{- _self.generate(title, filteredRoutes, 2, 2, 'cwf-scroll--y') -}}
{% endmacro %}

{% import _self as nav %}

{% set list %}
    {% if type == 'main' %}
        {{ nav.main(title, routes) }}
    {% endif %} {% if type == 'sub' %}
        {{ nav.sub(title, routes, siblings) }}
    {% endif %}
{% endset %}

{% if list|trim|length %}
    <nav id="{{ id ?? 'cwf-nav--' ~ type }}"
        class="cwf-nav cwf-nav--{{ type }} cwf-nav--{{ theme }}"
        aria-label="{{ type|capitalize }}">
        {% if type == 'main' %}
            <button id="{{
                id is defined
                    ? id ~ '__hamburger'
                    : 'cwf-nav__hamburger'
                }}"
                aria-label="Open or close the menu with this button"
                class="cwf-nav__hamburger">
                <span class="cwf-nav__hamburger-text cwf-nav__hamburger-text--close">
                    Close
                </span>
                <i class="cwf-nav__icon" aria-hidden="true"></i>
                <span class="cwf-nav__hamburger-text cwf-nav__hamburger-text--menu">
                    Menu
                </span>
            </button>
        {% endif %}
        <div class="cwf-nav__container">
            <div class="cwf-nav__controller">
                {{ list|trim }}
            </div>
        </div>
    </nav>
{% endif %}
{
  "id": "example-nav--sub--dark",
  "type": "sub",
  "theme": "dark",
  "siblings": true,
  "routes": [
    {
      "level": 1,
      "name": "Blog",
      "href": "https://blogs.vcu.edu/compass/"
    },
    {
      "level": 1,
      "name": "Components",
      "href": "/components/",
      "children": [
        {
          "name": {
            "full": "Global components",
            "short": "Global"
          },
          "href": "/components/global/",
          "children": [
            {
              "name": "Breadcrumb",
              "href": "/components/global/breadcrumb/"
            },
            {
              "name": "Button",
              "href": "/components/global/button/"
            },
            {
              "name": "Footer",
              "href": "/components/global/footer/"
            },
            {
              "name": "Form",
              "href": "/components/global/form/"
            },
            {
              "name": "General content",
              "href": "/components/global/general-content/"
            },
            {
              "name": "Grid",
              "href": "/components/global/grid/"
            },
            {
              "name": "Header",
              "href": "/components/global/header/"
            },
            {
              "name": "Navigation",
              "href": "/components/global/navigation/",
              "children": [
                {
                  "name": "Main navigation",
                  "href": "/components/global/navigation/main/"
                },
                {
                  "name": "Sub navigation",
                  "href": "/components/global/navigation/sub/"
                }
              ]
            },
            {
              "name": "Skip links",
              "href": "/components/global/skip-links/"
            }
          ]
        },
        {
          "name": {
            "full": "Content components",
            "short": "Content"
          },
          "href": "/components/content/",
          "children": [
            {
              "name": "Accordion",
              "href": "/components/content/accordion/"
            },
            {
              "name": "Card",
              "href": "/components/content/card/"
            },
            {
              "name": "Hero",
              "href": "/components/content/hero/"
            },
            {
              "name": "Modal",
              "href": "/components/content/modal/"
            },
            {
              "name": "Notification",
              "href": "/components/content/notification/"
            },
            {
              "name": "Tabs",
              "href": "/components/content/tabs/"
            }
          ]
        }
      ]
    },
    {
      "level": 2,
      "name": {
        "full": "Global components",
        "short": "Global"
      },
      "href": "/components/global/",
      "parents": [
        {
          "name": "Components",
          "href": "/components/",
          "children": [
            {
              "name": {
                "full": "Global components",
                "short": "Global"
              },
              "href": "/components/global/",
              "children": [
                {
                  "name": "Breadcrumb",
                  "href": "/components/global/breadcrumb/"
                },
                {
                  "name": "Button",
                  "href": "/components/global/button/"
                },
                {
                  "name": "Footer",
                  "href": "/components/global/footer/"
                },
                {
                  "name": "Form",
                  "href": "/components/global/form/"
                },
                {
                  "name": "General content",
                  "href": "/components/global/general-content/"
                },
                {
                  "name": "Grid",
                  "href": "/components/global/grid/"
                },
                {
                  "name": "Header",
                  "href": "/components/global/header/"
                },
                {
                  "name": "Navigation",
                  "href": "/components/global/navigation/",
                  "children": [
                    {
                      "name": "Main navigation",
                      "href": "/components/global/navigation/main/"
                    },
                    {
                      "name": "Sub navigation",
                      "href": "/components/global/navigation/sub/"
                    }
                  ]
                },
                {
                  "name": "Skip links",
                  "href": "/components/global/skip-links/"
                }
              ]
            },
            {
              "name": {
                "full": "Content components",
                "short": "Content"
              },
              "href": "/components/content/",
              "children": [
                {
                  "name": "Accordion",
                  "href": "/components/content/accordion/"
                },
                {
                  "name": "Card",
                  "href": "/components/content/card/"
                },
                {
                  "name": "Hero",
                  "href": "/components/content/hero/"
                },
                {
                  "name": "Modal",
                  "href": "/components/content/modal/"
                },
                {
                  "name": "Notification",
                  "href": "/components/content/notification/"
                },
                {
                  "name": "Tabs",
                  "href": "/components/content/tabs/"
                }
              ]
            }
          ]
        }
      ],
      "children": [
        {
          "name": "Breadcrumb",
          "href": "/components/global/breadcrumb/"
        },
        {
          "name": "Button",
          "href": "/components/global/button/"
        },
        {
          "name": "Footer",
          "href": "/components/global/footer/"
        },
        {
          "name": "Form",
          "href": "/components/global/form/"
        },
        {
          "name": "General content",
          "href": "/components/global/general-content/"
        },
        {
          "name": "Grid",
          "href": "/components/global/grid/"
        },
        {
          "name": "Header",
          "href": "/components/global/header/"
        },
        {
          "name": "Navigation",
          "href": "/components/global/navigation/",
          "children": [
            {
              "name": "Main navigation",
              "href": "/components/global/navigation/main/"
            },
            {
              "name": "Sub navigation",
              "href": "/components/global/navigation/sub/"
            }
          ]
        },
        {
          "name": "Skip links",
          "href": "/components/global/skip-links/"
        }
      ]
    },
    {
      "level": 3,
      "name": "Breadcrumb",
      "href": "/components/global/breadcrumb/",
      "parents": [
        {
          "name": "Components",
          "href": "/components/",
          "children": [
            {
              "name": {
                "full": "Global components",
                "short": "Global"
              },
              "href": "/components/global/",
              "children": [
                {
                  "name": "Breadcrumb",
                  "href": "/components/global/breadcrumb/"
                },
                {
                  "name": "Button",
                  "href": "/components/global/button/"
                },
                {
                  "name": "Footer",
                  "href": "/components/global/footer/"
                },
                {
                  "name": "Form",
                  "href": "/components/global/form/"
                },
                {
                  "name": "General content",
                  "href": "/components/global/general-content/"
                },
                {
                  "name": "Grid",
                  "href": "/components/global/grid/"
                },
                {
                  "name": "Header",
                  "href": "/components/global/header/"
                },
                {
                  "name": "Navigation",
                  "href": "/components/global/navigation/",
                  "children": [
                    {
                      "name": "Main navigation",
                      "href": "/components/global/navigation/main/"
                    },
                    {
                      "name": "Sub navigation",
                      "href": "/components/global/navigation/sub/"
                    }
                  ]
                },
                {
                  "name": "Skip links",
                  "href": "/components/global/skip-links/"
                }
              ]
            },
            {
              "name": {
                "full": "Content components",
                "short": "Content"
              },
              "href": "/components/content/",
              "children": [
                {
                  "name": "Accordion",
                  "href": "/components/content/accordion/"
                },
                {
                  "name": "Card",
                  "href": "/components/content/card/"
                },
                {
                  "name": "Hero",
                  "href": "/components/content/hero/"
                },
                {
                  "name": "Modal",
                  "href": "/components/content/modal/"
                },
                {
                  "name": "Notification",
                  "href": "/components/content/notification/"
                },
                {
                  "name": "Tabs",
                  "href": "/components/content/tabs/"
                }
              ]
            }
          ]
        },
        {
          "name": {
            "full": "Global components",
            "short": "Global"
          },
          "href": "/components/global/",
          "children": [
            {
              "name": "Breadcrumb",
              "href": "/components/global/breadcrumb/"
            },
            {
              "name": "Button",
              "href": "/components/global/button/"
            },
            {
              "name": "Footer",
              "href": "/components/global/footer/"
            },
            {
              "name": "Form",
              "href": "/components/global/form/"
            },
            {
              "name": "General content",
              "href": "/components/global/general-content/"
            },
            {
              "name": "Grid",
              "href": "/components/global/grid/"
            },
            {
              "name": "Header",
              "href": "/components/global/header/"
            },
            {
              "name": "Navigation",
              "href": "/components/global/navigation/",
              "children": [
                {
                  "name": "Main navigation",
                  "href": "/components/global/navigation/main/"
                },
                {
                  "name": "Sub navigation",
                  "href": "/components/global/navigation/sub/"
                }
              ]
            },
            {
              "name": "Skip links",
              "href": "/components/global/skip-links/"
            }
          ]
        }
      ]
    },
    {
      "level": 3,
      "name": "Button",
      "href": "/components/global/button/",
      "parents": [
        {
          "name": "Components",
          "href": "/components/",
          "children": [
            {
              "name": {
                "full": "Global components",
                "short": "Global"
              },
              "href": "/components/global/",
              "children": [
                {
                  "name": "Breadcrumb",
                  "href": "/components/global/breadcrumb/"
                },
                {
                  "name": "Button",
                  "href": "/components/global/button/"
                },
                {
                  "name": "Footer",
                  "href": "/components/global/footer/"
                },
                {
                  "name": "Form",
                  "href": "/components/global/form/"
                },
                {
                  "name": "General content",
                  "href": "/components/global/general-content/"
                },
                {
                  "name": "Grid",
                  "href": "/components/global/grid/"
                },
                {
                  "name": "Header",
                  "href": "/components/global/header/"
                },
                {
                  "name": "Navigation",
                  "href": "/components/global/navigation/",
                  "children": [
                    {
                      "name": "Main navigation",
                      "href": "/components/global/navigation/main/"
                    },
                    {
                      "name": "Sub navigation",
                      "href": "/components/global/navigation/sub/"
                    }
                  ]
                },
                {
                  "name": "Skip links",
                  "href": "/components/global/skip-links/"
                }
              ]
            },
            {
              "name": {
                "full": "Content components",
                "short": "Content"
              },
              "href": "/components/content/",
              "children": [
                {
                  "name": "Accordion",
                  "href": "/components/content/accordion/"
                },
                {
                  "name": "Card",
                  "href": "/components/content/card/"
                },
                {
                  "name": "Hero",
                  "href": "/components/content/hero/"
                },
                {
                  "name": "Modal",
                  "href": "/components/content/modal/"
                },
                {
                  "name": "Notification",
                  "href": "/components/content/notification/"
                },
                {
                  "name": "Tabs",
                  "href": "/components/content/tabs/"
                }
              ]
            }
          ]
        },
        {
          "name": {
            "full": "Global components",
            "short": "Global"
          },
          "href": "/components/global/",
          "children": [
            {
              "name": "Breadcrumb",
              "href": "/components/global/breadcrumb/"
            },
            {
              "name": "Button",
              "href": "/components/global/button/"
            },
            {
              "name": "Footer",
              "href": "/components/global/footer/"
            },
            {
              "name": "Form",
              "href": "/components/global/form/"
            },
            {
              "name": "General content",
              "href": "/components/global/general-content/"
            },
            {
              "name": "Grid",
              "href": "/components/global/grid/"
            },
            {
              "name": "Header",
              "href": "/components/global/header/"
            },
            {
              "name": "Navigation",
              "href": "/components/global/navigation/",
              "children": [
                {
                  "name": "Main navigation",
                  "href": "/components/global/navigation/main/"
                },
                {
                  "name": "Sub navigation",
                  "href": "/components/global/navigation/sub/"
                }
              ]
            },
            {
              "name": "Skip links",
              "href": "/components/global/skip-links/"
            }
          ]
        }
      ]
    },
    {
      "level": 3,
      "name": "Footer",
      "href": "/components/global/footer/",
      "parents": [
        {
          "name": "Components",
          "href": "/components/",
          "children": [
            {
              "name": {
                "full": "Global components",
                "short": "Global"
              },
              "href": "/components/global/",
              "children": [
                {
                  "name": "Breadcrumb",
                  "href": "/components/global/breadcrumb/"
                },
                {
                  "name": "Button",
                  "href": "/components/global/button/"
                },
                {
                  "name": "Footer",
                  "href": "/components/global/footer/"
                },
                {
                  "name": "Form",
                  "href": "/components/global/form/"
                },
                {
                  "name": "General content",
                  "href": "/components/global/general-content/"
                },
                {
                  "name": "Grid",
                  "href": "/components/global/grid/"
                },
                {
                  "name": "Header",
                  "href": "/components/global/header/"
                },
                {
                  "name": "Navigation",
                  "href": "/components/global/navigation/",
                  "children": [
                    {
                      "name": "Main navigation",
                      "href": "/components/global/navigation/main/"
                    },
                    {
                      "name": "Sub navigation",
                      "href": "/components/global/navigation/sub/"
                    }
                  ]
                },
                {
                  "name": "Skip links",
                  "href": "/components/global/skip-links/"
                }
              ]
            },
            {
              "name": {
                "full": "Content components",
                "short": "Content"
              },
              "href": "/components/content/",
              "children": [
                {
                  "name": "Accordion",
                  "href": "/components/content/accordion/"
                },
                {
                  "name": "Card",
                  "href": "/components/content/card/"
                },
                {
                  "name": "Hero",
                  "href": "/components/content/hero/"
                },
                {
                  "name": "Modal",
                  "href": "/components/content/modal/"
                },
                {
                  "name": "Notification",
                  "href": "/components/content/notification/"
                },
                {
                  "name": "Tabs",
                  "href": "/components/content/tabs/"
                }
              ]
            }
          ]
        },
        {
          "name": {
            "full": "Global components",
            "short": "Global"
          },
          "href": "/components/global/",
          "children": [
            {
              "name": "Breadcrumb",
              "href": "/components/global/breadcrumb/"
            },
            {
              "name": "Button",
              "href": "/components/global/button/"
            },
            {
              "name": "Footer",
              "href": "/components/global/footer/"
            },
            {
              "name": "Form",
              "href": "/components/global/form/"
            },
            {
              "name": "General content",
              "href": "/components/global/general-content/"
            },
            {
              "name": "Grid",
              "href": "/components/global/grid/"
            },
            {
              "name": "Header",
              "href": "/components/global/header/"
            },
            {
              "name": "Navigation",
              "href": "/components/global/navigation/",
              "children": [
                {
                  "name": "Main navigation",
                  "href": "/components/global/navigation/main/"
                },
                {
                  "name": "Sub navigation",
                  "href": "/components/global/navigation/sub/"
                }
              ]
            },
            {
              "name": "Skip links",
              "href": "/components/global/skip-links/"
            }
          ]
        }
      ]
    },
    {
      "level": 3,
      "name": "Form",
      "href": "/components/global/form/",
      "parents": [
        {
          "name": "Components",
          "href": "/components/",
          "children": [
            {
              "name": {
                "full": "Global components",
                "short": "Global"
              },
              "href": "/components/global/",
              "children": [
                {
                  "name": "Breadcrumb",
                  "href": "/components/global/breadcrumb/"
                },
                {
                  "name": "Button",
                  "href": "/components/global/button/"
                },
                {
                  "name": "Footer",
                  "href": "/components/global/footer/"
                },
                {
                  "name": "Form",
                  "href": "/components/global/form/"
                },
                {
                  "name": "General content",
                  "href": "/components/global/general-content/"
                },
                {
                  "name": "Grid",
                  "href": "/components/global/grid/"
                },
                {
                  "name": "Header",
                  "href": "/components/global/header/"
                },
                {
                  "name": "Navigation",
                  "href": "/components/global/navigation/",
                  "children": [
                    {
                      "name": "Main navigation",
                      "href": "/components/global/navigation/main/"
                    },
                    {
                      "name": "Sub navigation",
                      "href": "/components/global/navigation/sub/"
                    }
                  ]
                },
                {
                  "name": "Skip links",
                  "href": "/components/global/skip-links/"
                }
              ]
            },
            {
              "name": {
                "full": "Content components",
                "short": "Content"
              },
              "href": "/components/content/",
              "children": [
                {
                  "name": "Accordion",
                  "href": "/components/content/accordion/"
                },
                {
                  "name": "Card",
                  "href": "/components/content/card/"
                },
                {
                  "name": "Hero",
                  "href": "/components/content/hero/"
                },
                {
                  "name": "Modal",
                  "href": "/components/content/modal/"
                },
                {
                  "name": "Notification",
                  "href": "/components/content/notification/"
                },
                {
                  "name": "Tabs",
                  "href": "/components/content/tabs/"
                }
              ]
            }
          ]
        },
        {
          "name": {
            "full": "Global components",
            "short": "Global"
          },
          "href": "/components/global/",
          "children": [
            {
              "name": "Breadcrumb",
              "href": "/components/global/breadcrumb/"
            },
            {
              "name": "Button",
              "href": "/components/global/button/"
            },
            {
              "name": "Footer",
              "href": "/components/global/footer/"
            },
            {
              "name": "Form",
              "href": "/components/global/form/"
            },
            {
              "name": "General content",
              "href": "/components/global/general-content/"
            },
            {
              "name": "Grid",
              "href": "/components/global/grid/"
            },
            {
              "name": "Header",
              "href": "/components/global/header/"
            },
            {
              "name": "Navigation",
              "href": "/components/global/navigation/",
              "children": [
                {
                  "name": "Main navigation",
                  "href": "/components/global/navigation/main/"
                },
                {
                  "name": "Sub navigation",
                  "href": "/components/global/navigation/sub/"
                }
              ]
            },
            {
              "name": "Skip links",
              "href": "/components/global/skip-links/"
            }
          ]
        }
      ]
    },
    {
      "level": 3,
      "name": "General content",
      "href": "/components/global/general-content/",
      "parents": [
        {
          "name": "Components",
          "href": "/components/",
          "children": [
            {
              "name": {
                "full": "Global components",
                "short": "Global"
              },
              "href": "/components/global/",
              "children": [
                {
                  "name": "Breadcrumb",
                  "href": "/components/global/breadcrumb/"
                },
                {
                  "name": "Button",
                  "href": "/components/global/button/"
                },
                {
                  "name": "Footer",
                  "href": "/components/global/footer/"
                },
                {
                  "name": "Form",
                  "href": "/components/global/form/"
                },
                {
                  "name": "General content",
                  "href": "/components/global/general-content/"
                },
                {
                  "name": "Grid",
                  "href": "/components/global/grid/"
                },
                {
                  "name": "Header",
                  "href": "/components/global/header/"
                },
                {
                  "name": "Navigation",
                  "href": "/components/global/navigation/",
                  "children": [
                    {
                      "name": "Main navigation",
                      "href": "/components/global/navigation/main/"
                    },
                    {
                      "name": "Sub navigation",
                      "href": "/components/global/navigation/sub/"
                    }
                  ]
                },
                {
                  "name": "Skip links",
                  "href": "/components/global/skip-links/"
                }
              ]
            },
            {
              "name": {
                "full": "Content components",
                "short": "Content"
              },
              "href": "/components/content/",
              "children": [
                {
                  "name": "Accordion",
                  "href": "/components/content/accordion/"
                },
                {
                  "name": "Card",
                  "href": "/components/content/card/"
                },
                {
                  "name": "Hero",
                  "href": "/components/content/hero/"
                },
                {
                  "name": "Modal",
                  "href": "/components/content/modal/"
                },
                {
                  "name": "Notification",
                  "href": "/components/content/notification/"
                },
                {
                  "name": "Tabs",
                  "href": "/components/content/tabs/"
                }
              ]
            }
          ]
        },
        {
          "name": {
            "full": "Global components",
            "short": "Global"
          },
          "href": "/components/global/",
          "children": [
            {
              "name": "Breadcrumb",
              "href": "/components/global/breadcrumb/"
            },
            {
              "name": "Button",
              "href": "/components/global/button/"
            },
            {
              "name": "Footer",
              "href": "/components/global/footer/"
            },
            {
              "name": "Form",
              "href": "/components/global/form/"
            },
            {
              "name": "General content",
              "href": "/components/global/general-content/"
            },
            {
              "name": "Grid",
              "href": "/components/global/grid/"
            },
            {
              "name": "Header",
              "href": "/components/global/header/"
            },
            {
              "name": "Navigation",
              "href": "/components/global/navigation/",
              "children": [
                {
                  "name": "Main navigation",
                  "href": "/components/global/navigation/main/"
                },
                {
                  "name": "Sub navigation",
                  "href": "/components/global/navigation/sub/"
                }
              ]
            },
            {
              "name": "Skip links",
              "href": "/components/global/skip-links/"
            }
          ]
        }
      ]
    },
    {
      "level": 3,
      "name": "Grid",
      "href": "/components/global/grid/",
      "parents": [
        {
          "name": "Components",
          "href": "/components/",
          "children": [
            {
              "name": {
                "full": "Global components",
                "short": "Global"
              },
              "href": "/components/global/",
              "children": [
                {
                  "name": "Breadcrumb",
                  "href": "/components/global/breadcrumb/"
                },
                {
                  "name": "Button",
                  "href": "/components/global/button/"
                },
                {
                  "name": "Footer",
                  "href": "/components/global/footer/"
                },
                {
                  "name": "Form",
                  "href": "/components/global/form/"
                },
                {
                  "name": "General content",
                  "href": "/components/global/general-content/"
                },
                {
                  "name": "Grid",
                  "href": "/components/global/grid/"
                },
                {
                  "name": "Header",
                  "href": "/components/global/header/"
                },
                {
                  "name": "Navigation",
                  "href": "/components/global/navigation/",
                  "children": [
                    {
                      "name": "Main navigation",
                      "href": "/components/global/navigation/main/"
                    },
                    {
                      "name": "Sub navigation",
                      "href": "/components/global/navigation/sub/"
                    }
                  ]
                },
                {
                  "name": "Skip links",
                  "href": "/components/global/skip-links/"
                }
              ]
            },
            {
              "name": {
                "full": "Content components",
                "short": "Content"
              },
              "href": "/components/content/",
              "children": [
                {
                  "name": "Accordion",
                  "href": "/components/content/accordion/"
                },
                {
                  "name": "Card",
                  "href": "/components/content/card/"
                },
                {
                  "name": "Hero",
                  "href": "/components/content/hero/"
                },
                {
                  "name": "Modal",
                  "href": "/components/content/modal/"
                },
                {
                  "name": "Notification",
                  "href": "/components/content/notification/"
                },
                {
                  "name": "Tabs",
                  "href": "/components/content/tabs/"
                }
              ]
            }
          ]
        },
        {
          "name": {
            "full": "Global components",
            "short": "Global"
          },
          "href": "/components/global/",
          "children": [
            {
              "name": "Breadcrumb",
              "href": "/components/global/breadcrumb/"
            },
            {
              "name": "Button",
              "href": "/components/global/button/"
            },
            {
              "name": "Footer",
              "href": "/components/global/footer/"
            },
            {
              "name": "Form",
              "href": "/components/global/form/"
            },
            {
              "name": "General content",
              "href": "/components/global/general-content/"
            },
            {
              "name": "Grid",
              "href": "/components/global/grid/"
            },
            {
              "name": "Header",
              "href": "/components/global/header/"
            },
            {
              "name": "Navigation",
              "href": "/components/global/navigation/",
              "children": [
                {
                  "name": "Main navigation",
                  "href": "/components/global/navigation/main/"
                },
                {
                  "name": "Sub navigation",
                  "href": "/components/global/navigation/sub/"
                }
              ]
            },
            {
              "name": "Skip links",
              "href": "/components/global/skip-links/"
            }
          ]
        }
      ]
    },
    {
      "level": 3,
      "name": "Header",
      "href": "/components/global/header/",
      "parents": [
        {
          "name": "Components",
          "href": "/components/",
          "children": [
            {
              "name": {
                "full": "Global components",
                "short": "Global"
              },
              "href": "/components/global/",
              "children": [
                {
                  "name": "Breadcrumb",
                  "href": "/components/global/breadcrumb/"
                },
                {
                  "name": "Button",
                  "href": "/components/global/button/"
                },
                {
                  "name": "Footer",
                  "href": "/components/global/footer/"
                },
                {
                  "name": "Form",
                  "href": "/components/global/form/"
                },
                {
                  "name": "General content",
                  "href": "/components/global/general-content/"
                },
                {
                  "name": "Grid",
                  "href": "/components/global/grid/"
                },
                {
                  "name": "Header",
                  "href": "/components/global/header/"
                },
                {
                  "name": "Navigation",
                  "href": "/components/global/navigation/",
                  "children": [
                    {
                      "name": "Main navigation",
                      "href": "/components/global/navigation/main/"
                    },
                    {
                      "name": "Sub navigation",
                      "href": "/components/global/navigation/sub/"
                    }
                  ]
                },
                {
                  "name": "Skip links",
                  "href": "/components/global/skip-links/"
                }
              ]
            },
            {
              "name": {
                "full": "Content components",
                "short": "Content"
              },
              "href": "/components/content/",
              "children": [
                {
                  "name": "Accordion",
                  "href": "/components/content/accordion/"
                },
                {
                  "name": "Card",
                  "href": "/components/content/card/"
                },
                {
                  "name": "Hero",
                  "href": "/components/content/hero/"
                },
                {
                  "name": "Modal",
                  "href": "/components/content/modal/"
                },
                {
                  "name": "Notification",
                  "href": "/components/content/notification/"
                },
                {
                  "name": "Tabs",
                  "href": "/components/content/tabs/"
                }
              ]
            }
          ]
        },
        {
          "name": {
            "full": "Global components",
            "short": "Global"
          },
          "href": "/components/global/",
          "children": [
            {
              "name": "Breadcrumb",
              "href": "/components/global/breadcrumb/"
            },
            {
              "name": "Button",
              "href": "/components/global/button/"
            },
            {
              "name": "Footer",
              "href": "/components/global/footer/"
            },
            {
              "name": "Form",
              "href": "/components/global/form/"
            },
            {
              "name": "General content",
              "href": "/components/global/general-content/"
            },
            {
              "name": "Grid",
              "href": "/components/global/grid/"
            },
            {
              "name": "Header",
              "href": "/components/global/header/"
            },
            {
              "name": "Navigation",
              "href": "/components/global/navigation/",
              "children": [
                {
                  "name": "Main navigation",
                  "href": "/components/global/navigation/main/"
                },
                {
                  "name": "Sub navigation",
                  "href": "/components/global/navigation/sub/"
                }
              ]
            },
            {
              "name": "Skip links",
              "href": "/components/global/skip-links/"
            }
          ]
        }
      ]
    },
    {
      "level": 3,
      "name": "Navigation",
      "href": "/components/global/navigation/",
      "parents": [
        {
          "name": "Components",
          "href": "/components/",
          "children": [
            {
              "name": {
                "full": "Global components",
                "short": "Global"
              },
              "href": "/components/global/",
              "children": [
                {
                  "name": "Breadcrumb",
                  "href": "/components/global/breadcrumb/"
                },
                {
                  "name": "Button",
                  "href": "/components/global/button/"
                },
                {
                  "name": "Footer",
                  "href": "/components/global/footer/"
                },
                {
                  "name": "Form",
                  "href": "/components/global/form/"
                },
                {
                  "name": "General content",
                  "href": "/components/global/general-content/"
                },
                {
                  "name": "Grid",
                  "href": "/components/global/grid/"
                },
                {
                  "name": "Header",
                  "href": "/components/global/header/"
                },
                {
                  "name": "Navigation",
                  "href": "/components/global/navigation/",
                  "children": [
                    {
                      "name": "Main navigation",
                      "href": "/components/global/navigation/main/"
                    },
                    {
                      "name": "Sub navigation",
                      "href": "/components/global/navigation/sub/"
                    }
                  ]
                },
                {
                  "name": "Skip links",
                  "href": "/components/global/skip-links/"
                }
              ]
            },
            {
              "name": {
                "full": "Content components",
                "short": "Content"
              },
              "href": "/components/content/",
              "children": [
                {
                  "name": "Accordion",
                  "href": "/components/content/accordion/"
                },
                {
                  "name": "Card",
                  "href": "/components/content/card/"
                },
                {
                  "name": "Hero",
                  "href": "/components/content/hero/"
                },
                {
                  "name": "Modal",
                  "href": "/components/content/modal/"
                },
                {
                  "name": "Notification",
                  "href": "/components/content/notification/"
                },
                {
                  "name": "Tabs",
                  "href": "/components/content/tabs/"
                }
              ]
            }
          ]
        },
        {
          "name": {
            "full": "Global components",
            "short": "Global"
          },
          "href": "/components/global/",
          "children": [
            {
              "name": "Breadcrumb",
              "href": "/components/global/breadcrumb/"
            },
            {
              "name": "Button",
              "href": "/components/global/button/"
            },
            {
              "name": "Footer",
              "href": "/components/global/footer/"
            },
            {
              "name": "Form",
              "href": "/components/global/form/"
            },
            {
              "name": "General content",
              "href": "/components/global/general-content/"
            },
            {
              "name": "Grid",
              "href": "/components/global/grid/"
            },
            {
              "name": "Header",
              "href": "/components/global/header/"
            },
            {
              "name": "Navigation",
              "href": "/components/global/navigation/",
              "children": [
                {
                  "name": "Main navigation",
                  "href": "/components/global/navigation/main/"
                },
                {
                  "name": "Sub navigation",
                  "href": "/components/global/navigation/sub/"
                }
              ]
            },
            {
              "name": "Skip links",
              "href": "/components/global/skip-links/"
            }
          ]
        }
      ],
      "children": [
        {
          "name": "Main navigation",
          "href": "/components/global/navigation/main/"
        },
        {
          "name": "Sub navigation",
          "href": "/components/global/navigation/sub/"
        }
      ]
    },
    {
      "level": 4,
      "name": "Main navigation",
      "href": "/components/global/navigation/main/",
      "parents": [
        {
          "name": "Components",
          "href": "/components/",
          "children": [
            {
              "name": {
                "full": "Global components",
                "short": "Global"
              },
              "href": "/components/global/",
              "children": [
                {
                  "name": "Breadcrumb",
                  "href": "/components/global/breadcrumb/"
                },
                {
                  "name": "Button",
                  "href": "/components/global/button/"
                },
                {
                  "name": "Footer",
                  "href": "/components/global/footer/"
                },
                {
                  "name": "Form",
                  "href": "/components/global/form/"
                },
                {
                  "name": "General content",
                  "href": "/components/global/general-content/"
                },
                {
                  "name": "Grid",
                  "href": "/components/global/grid/"
                },
                {
                  "name": "Header",
                  "href": "/components/global/header/"
                },
                {
                  "name": "Navigation",
                  "href": "/components/global/navigation/",
                  "children": [
                    {
                      "name": "Main navigation",
                      "href": "/components/global/navigation/main/"
                    },
                    {
                      "name": "Sub navigation",
                      "href": "/components/global/navigation/sub/"
                    }
                  ]
                },
                {
                  "name": "Skip links",
                  "href": "/components/global/skip-links/"
                }
              ]
            },
            {
              "name": {
                "full": "Content components",
                "short": "Content"
              },
              "href": "/components/content/",
              "children": [
                {
                  "name": "Accordion",
                  "href": "/components/content/accordion/"
                },
                {
                  "name": "Card",
                  "href": "/components/content/card/"
                },
                {
                  "name": "Hero",
                  "href": "/components/content/hero/"
                },
                {
                  "name": "Modal",
                  "href": "/components/content/modal/"
                },
                {
                  "name": "Notification",
                  "href": "/components/content/notification/"
                },
                {
                  "name": "Tabs",
                  "href": "/components/content/tabs/"
                }
              ]
            }
          ]
        },
        {
          "name": {
            "full": "Global components",
            "short": "Global"
          },
          "href": "/components/global/",
          "children": [
            {
              "name": "Breadcrumb",
              "href": "/components/global/breadcrumb/"
            },
            {
              "name": "Button",
              "href": "/components/global/button/"
            },
            {
              "name": "Footer",
              "href": "/components/global/footer/"
            },
            {
              "name": "Form",
              "href": "/components/global/form/"
            },
            {
              "name": "General content",
              "href": "/components/global/general-content/"
            },
            {
              "name": "Grid",
              "href": "/components/global/grid/"
            },
            {
              "name": "Header",
              "href": "/components/global/header/"
            },
            {
              "name": "Navigation",
              "href": "/components/global/navigation/",
              "children": [
                {
                  "name": "Main navigation",
                  "href": "/components/global/navigation/main/"
                },
                {
                  "name": "Sub navigation",
                  "href": "/components/global/navigation/sub/"
                }
              ]
            },
            {
              "name": "Skip links",
              "href": "/components/global/skip-links/"
            }
          ]
        },
        {
          "name": "Navigation",
          "href": "/components/global/navigation/",
          "children": [
            {
              "name": "Main navigation",
              "href": "/components/global/navigation/main/"
            },
            {
              "name": "Sub navigation",
              "href": "/components/global/navigation/sub/"
            }
          ]
        }
      ]
    },
    {
      "level": 4,
      "name": "Sub navigation",
      "href": "/components/global/navigation/sub/",
      "parents": [
        {
          "name": "Components",
          "href": "/components/",
          "children": [
            {
              "name": {
                "full": "Global components",
                "short": "Global"
              },
              "href": "/components/global/",
              "children": [
                {
                  "name": "Breadcrumb",
                  "href": "/components/global/breadcrumb/"
                },
                {
                  "name": "Button",
                  "href": "/components/global/button/"
                },
                {
                  "name": "Footer",
                  "href": "/components/global/footer/"
                },
                {
                  "name": "Form",
                  "href": "/components/global/form/"
                },
                {
                  "name": "General content",
                  "href": "/components/global/general-content/"
                },
                {
                  "name": "Grid",
                  "href": "/components/global/grid/"
                },
                {
                  "name": "Header",
                  "href": "/components/global/header/"
                },
                {
                  "name": "Navigation",
                  "href": "/components/global/navigation/",
                  "children": [
                    {
                      "name": "Main navigation",
                      "href": "/components/global/navigation/main/"
                    },
                    {
                      "name": "Sub navigation",
                      "href": "/components/global/navigation/sub/"
                    }
                  ]
                },
                {
                  "name": "Skip links",
                  "href": "/components/global/skip-links/"
                }
              ]
            },
            {
              "name": {
                "full": "Content components",
                "short": "Content"
              },
              "href": "/components/content/",
              "children": [
                {
                  "name": "Accordion",
                  "href": "/components/content/accordion/"
                },
                {
                  "name": "Card",
                  "href": "/components/content/card/"
                },
                {
                  "name": "Hero",
                  "href": "/components/content/hero/"
                },
                {
                  "name": "Modal",
                  "href": "/components/content/modal/"
                },
                {
                  "name": "Notification",
                  "href": "/components/content/notification/"
                },
                {
                  "name": "Tabs",
                  "href": "/components/content/tabs/"
                }
              ]
            }
          ]
        },
        {
          "name": {
            "full": "Global components",
            "short": "Global"
          },
          "href": "/components/global/",
          "children": [
            {
              "name": "Breadcrumb",
              "href": "/components/global/breadcrumb/"
            },
            {
              "name": "Button",
              "href": "/components/global/button/"
            },
            {
              "name": "Footer",
              "href": "/components/global/footer/"
            },
            {
              "name": "Form",
              "href": "/components/global/form/"
            },
            {
              "name": "General content",
              "href": "/components/global/general-content/"
            },
            {
              "name": "Grid",
              "href": "/components/global/grid/"
            },
            {
              "name": "Header",
              "href": "/components/global/header/"
            },
            {
              "name": "Navigation",
              "href": "/components/global/navigation/",
              "children": [
                {
                  "name": "Main navigation",
                  "href": "/components/global/navigation/main/"
                },
                {
                  "name": "Sub navigation",
                  "href": "/components/global/navigation/sub/"
                }
              ]
            },
            {
              "name": "Skip links",
              "href": "/components/global/skip-links/"
            }
          ]
        },
        {
          "name": "Navigation",
          "href": "/components/global/navigation/",
          "children": [
            {
              "name": "Main navigation",
              "href": "/components/global/navigation/main/"
            },
            {
              "name": "Sub navigation",
              "href": "/components/global/navigation/sub/"
            }
          ]
        }
      ]
    },
    {
      "level": 3,
      "name": "Skip links",
      "href": "/components/global/skip-links/",
      "parents": [
        {
          "name": "Components",
          "href": "/components/",
          "children": [
            {
              "name": {
                "full": "Global components",
                "short": "Global"
              },
              "href": "/components/global/",
              "children": [
                {
                  "name": "Breadcrumb",
                  "href": "/components/global/breadcrumb/"
                },
                {
                  "name": "Button",
                  "href": "/components/global/button/"
                },
                {
                  "name": "Footer",
                  "href": "/components/global/footer/"
                },
                {
                  "name": "Form",
                  "href": "/components/global/form/"
                },
                {
                  "name": "General content",
                  "href": "/components/global/general-content/"
                },
                {
                  "name": "Grid",
                  "href": "/components/global/grid/"
                },
                {
                  "name": "Header",
                  "href": "/components/global/header/"
                },
                {
                  "name": "Navigation",
                  "href": "/components/global/navigation/",
                  "children": [
                    {
                      "name": "Main navigation",
                      "href": "/components/global/navigation/main/"
                    },
                    {
                      "name": "Sub navigation",
                      "href": "/components/global/navigation/sub/"
                    }
                  ]
                },
                {
                  "name": "Skip links",
                  "href": "/components/global/skip-links/"
                }
              ]
            },
            {
              "name": {
                "full": "Content components",
                "short": "Content"
              },
              "href": "/components/content/",
              "children": [
                {
                  "name": "Accordion",
                  "href": "/components/content/accordion/"
                },
                {
                  "name": "Card",
                  "href": "/components/content/card/"
                },
                {
                  "name": "Hero",
                  "href": "/components/content/hero/"
                },
                {
                  "name": "Modal",
                  "href": "/components/content/modal/"
                },
                {
                  "name": "Notification",
                  "href": "/components/content/notification/"
                },
                {
                  "name": "Tabs",
                  "href": "/components/content/tabs/"
                }
              ]
            }
          ]
        },
        {
          "name": {
            "full": "Global components",
            "short": "Global"
          },
          "href": "/components/global/",
          "children": [
            {
              "name": "Breadcrumb",
              "href": "/components/global/breadcrumb/"
            },
            {
              "name": "Button",
              "href": "/components/global/button/"
            },
            {
              "name": "Footer",
              "href": "/components/global/footer/"
            },
            {
              "name": "Form",
              "href": "/components/global/form/"
            },
            {
              "name": "General content",
              "href": "/components/global/general-content/"
            },
            {
              "name": "Grid",
              "href": "/components/global/grid/"
            },
            {
              "name": "Header",
              "href": "/components/global/header/"
            },
            {
              "name": "Navigation",
              "href": "/components/global/navigation/",
              "children": [
                {
                  "name": "Main navigation",
                  "href": "/components/global/navigation/main/"
                },
                {
                  "name": "Sub navigation",
                  "href": "/components/global/navigation/sub/"
                }
              ]
            },
            {
              "name": "Skip links",
              "href": "/components/global/skip-links/"
            }
          ]
        }
      ]
    },
    {
      "level": 2,
      "name": {
        "full": "Content components",
        "short": "Content"
      },
      "href": "/components/content/",
      "parents": [
        {
          "name": "Components",
          "href": "/components/",
          "children": [
            {
              "name": {
                "full": "Global components",
                "short": "Global"
              },
              "href": "/components/global/",
              "children": [
                {
                  "name": "Breadcrumb",
                  "href": "/components/global/breadcrumb/"
                },
                {
                  "name": "Button",
                  "href": "/components/global/button/"
                },
                {
                  "name": "Footer",
                  "href": "/components/global/footer/"
                },
                {
                  "name": "Form",
                  "href": "/components/global/form/"
                },
                {
                  "name": "General content",
                  "href": "/components/global/general-content/"
                },
                {
                  "name": "Grid",
                  "href": "/components/global/grid/"
                },
                {
                  "name": "Header",
                  "href": "/components/global/header/"
                },
                {
                  "name": "Navigation",
                  "href": "/components/global/navigation/",
                  "children": [
                    {
                      "name": "Main navigation",
                      "href": "/components/global/navigation/main/"
                    },
                    {
                      "name": "Sub navigation",
                      "href": "/components/global/navigation/sub/"
                    }
                  ]
                },
                {
                  "name": "Skip links",
                  "href": "/components/global/skip-links/"
                }
              ]
            },
            {
              "name": {
                "full": "Content components",
                "short": "Content"
              },
              "href": "/components/content/",
              "children": [
                {
                  "name": "Accordion",
                  "href": "/components/content/accordion/"
                },
                {
                  "name": "Card",
                  "href": "/components/content/card/"
                },
                {
                  "name": "Hero",
                  "href": "/components/content/hero/"
                },
                {
                  "name": "Modal",
                  "href": "/components/content/modal/"
                },
                {
                  "name": "Notification",
                  "href": "/components/content/notification/"
                },
                {
                  "name": "Tabs",
                  "href": "/components/content/tabs/"
                }
              ]
            }
          ]
        }
      ],
      "children": [
        {
          "name": "Accordion",
          "href": "/components/content/accordion/"
        },
        {
          "name": "Card",
          "href": "/components/content/card/"
        },
        {
          "name": "Hero",
          "href": "/components/content/hero/"
        },
        {
          "name": "Modal",
          "href": "/components/content/modal/"
        },
        {
          "name": "Notification",
          "href": "/components/content/notification/"
        },
        {
          "name": "Tabs",
          "href": "/components/content/tabs/"
        }
      ]
    },
    {
      "level": 3,
      "name": "Accordion",
      "href": "/components/content/accordion/",
      "parents": [
        {
          "name": "Components",
          "href": "/components/",
          "children": [
            {
              "name": {
                "full": "Global components",
                "short": "Global"
              },
              "href": "/components/global/",
              "children": [
                {
                  "name": "Breadcrumb",
                  "href": "/components/global/breadcrumb/"
                },
                {
                  "name": "Button",
                  "href": "/components/global/button/"
                },
                {
                  "name": "Footer",
                  "href": "/components/global/footer/"
                },
                {
                  "name": "Form",
                  "href": "/components/global/form/"
                },
                {
                  "name": "General content",
                  "href": "/components/global/general-content/"
                },
                {
                  "name": "Grid",
                  "href": "/components/global/grid/"
                },
                {
                  "name": "Header",
                  "href": "/components/global/header/"
                },
                {
                  "name": "Navigation",
                  "href": "/components/global/navigation/",
                  "children": [
                    {
                      "name": "Main navigation",
                      "href": "/components/global/navigation/main/"
                    },
                    {
                      "name": "Sub navigation",
                      "href": "/components/global/navigation/sub/"
                    }
                  ]
                },
                {
                  "name": "Skip links",
                  "href": "/components/global/skip-links/"
                }
              ]
            },
            {
              "name": {
                "full": "Content components",
                "short": "Content"
              },
              "href": "/components/content/",
              "children": [
                {
                  "name": "Accordion",
                  "href": "/components/content/accordion/"
                },
                {
                  "name": "Card",
                  "href": "/components/content/card/"
                },
                {
                  "name": "Hero",
                  "href": "/components/content/hero/"
                },
                {
                  "name": "Modal",
                  "href": "/components/content/modal/"
                },
                {
                  "name": "Notification",
                  "href": "/components/content/notification/"
                },
                {
                  "name": "Tabs",
                  "href": "/components/content/tabs/"
                }
              ]
            }
          ]
        },
        {
          "name": {
            "full": "Content components",
            "short": "Content"
          },
          "href": "/components/content/",
          "children": [
            {
              "name": "Accordion",
              "href": "/components/content/accordion/"
            },
            {
              "name": "Card",
              "href": "/components/content/card/"
            },
            {
              "name": "Hero",
              "href": "/components/content/hero/"
            },
            {
              "name": "Modal",
              "href": "/components/content/modal/"
            },
            {
              "name": "Notification",
              "href": "/components/content/notification/"
            },
            {
              "name": "Tabs",
              "href": "/components/content/tabs/"
            }
          ]
        }
      ]
    },
    {
      "level": 3,
      "name": "Card",
      "href": "/components/content/card/",
      "parents": [
        {
          "name": "Components",
          "href": "/components/",
          "children": [
            {
              "name": {
                "full": "Global components",
                "short": "Global"
              },
              "href": "/components/global/",
              "children": [
                {
                  "name": "Breadcrumb",
                  "href": "/components/global/breadcrumb/"
                },
                {
                  "name": "Button",
                  "href": "/components/global/button/"
                },
                {
                  "name": "Footer",
                  "href": "/components/global/footer/"
                },
                {
                  "name": "Form",
                  "href": "/components/global/form/"
                },
                {
                  "name": "General content",
                  "href": "/components/global/general-content/"
                },
                {
                  "name": "Grid",
                  "href": "/components/global/grid/"
                },
                {
                  "name": "Header",
                  "href": "/components/global/header/"
                },
                {
                  "name": "Navigation",
                  "href": "/components/global/navigation/",
                  "children": [
                    {
                      "name": "Main navigation",
                      "href": "/components/global/navigation/main/"
                    },
                    {
                      "name": "Sub navigation",
                      "href": "/components/global/navigation/sub/"
                    }
                  ]
                },
                {
                  "name": "Skip links",
                  "href": "/components/global/skip-links/"
                }
              ]
            },
            {
              "name": {
                "full": "Content components",
                "short": "Content"
              },
              "href": "/components/content/",
              "children": [
                {
                  "name": "Accordion",
                  "href": "/components/content/accordion/"
                },
                {
                  "name": "Card",
                  "href": "/components/content/card/"
                },
                {
                  "name": "Hero",
                  "href": "/components/content/hero/"
                },
                {
                  "name": "Modal",
                  "href": "/components/content/modal/"
                },
                {
                  "name": "Notification",
                  "href": "/components/content/notification/"
                },
                {
                  "name": "Tabs",
                  "href": "/components/content/tabs/"
                }
              ]
            }
          ]
        },
        {
          "name": {
            "full": "Content components",
            "short": "Content"
          },
          "href": "/components/content/",
          "children": [
            {
              "name": "Accordion",
              "href": "/components/content/accordion/"
            },
            {
              "name": "Card",
              "href": "/components/content/card/"
            },
            {
              "name": "Hero",
              "href": "/components/content/hero/"
            },
            {
              "name": "Modal",
              "href": "/components/content/modal/"
            },
            {
              "name": "Notification",
              "href": "/components/content/notification/"
            },
            {
              "name": "Tabs",
              "href": "/components/content/tabs/"
            }
          ]
        }
      ]
    },
    {
      "level": 3,
      "name": "Hero",
      "href": "/components/content/hero/",
      "parents": [
        {
          "name": "Components",
          "href": "/components/",
          "children": [
            {
              "name": {
                "full": "Global components",
                "short": "Global"
              },
              "href": "/components/global/",
              "children": [
                {
                  "name": "Breadcrumb",
                  "href": "/components/global/breadcrumb/"
                },
                {
                  "name": "Button",
                  "href": "/components/global/button/"
                },
                {
                  "name": "Footer",
                  "href": "/components/global/footer/"
                },
                {
                  "name": "Form",
                  "href": "/components/global/form/"
                },
                {
                  "name": "General content",
                  "href": "/components/global/general-content/"
                },
                {
                  "name": "Grid",
                  "href": "/components/global/grid/"
                },
                {
                  "name": "Header",
                  "href": "/components/global/header/"
                },
                {
                  "name": "Navigation",
                  "href": "/components/global/navigation/",
                  "children": [
                    {
                      "name": "Main navigation",
                      "href": "/components/global/navigation/main/"
                    },
                    {
                      "name": "Sub navigation",
                      "href": "/components/global/navigation/sub/"
                    }
                  ]
                },
                {
                  "name": "Skip links",
                  "href": "/components/global/skip-links/"
                }
              ]
            },
            {
              "name": {
                "full": "Content components",
                "short": "Content"
              },
              "href": "/components/content/",
              "children": [
                {
                  "name": "Accordion",
                  "href": "/components/content/accordion/"
                },
                {
                  "name": "Card",
                  "href": "/components/content/card/"
                },
                {
                  "name": "Hero",
                  "href": "/components/content/hero/"
                },
                {
                  "name": "Modal",
                  "href": "/components/content/modal/"
                },
                {
                  "name": "Notification",
                  "href": "/components/content/notification/"
                },
                {
                  "name": "Tabs",
                  "href": "/components/content/tabs/"
                }
              ]
            }
          ]
        },
        {
          "name": {
            "full": "Content components",
            "short": "Content"
          },
          "href": "/components/content/",
          "children": [
            {
              "name": "Accordion",
              "href": "/components/content/accordion/"
            },
            {
              "name": "Card",
              "href": "/components/content/card/"
            },
            {
              "name": "Hero",
              "href": "/components/content/hero/"
            },
            {
              "name": "Modal",
              "href": "/components/content/modal/"
            },
            {
              "name": "Notification",
              "href": "/components/content/notification/"
            },
            {
              "name": "Tabs",
              "href": "/components/content/tabs/"
            }
          ]
        }
      ]
    },
    {
      "level": 3,
      "name": "Modal",
      "href": "/components/content/modal/",
      "parents": [
        {
          "name": "Components",
          "href": "/components/",
          "children": [
            {
              "name": {
                "full": "Global components",
                "short": "Global"
              },
              "href": "/components/global/",
              "children": [
                {
                  "name": "Breadcrumb",
                  "href": "/components/global/breadcrumb/"
                },
                {
                  "name": "Button",
                  "href": "/components/global/button/"
                },
                {
                  "name": "Footer",
                  "href": "/components/global/footer/"
                },
                {
                  "name": "Form",
                  "href": "/components/global/form/"
                },
                {
                  "name": "General content",
                  "href": "/components/global/general-content/"
                },
                {
                  "name": "Grid",
                  "href": "/components/global/grid/"
                },
                {
                  "name": "Header",
                  "href": "/components/global/header/"
                },
                {
                  "name": "Navigation",
                  "href": "/components/global/navigation/",
                  "children": [
                    {
                      "name": "Main navigation",
                      "href": "/components/global/navigation/main/"
                    },
                    {
                      "name": "Sub navigation",
                      "href": "/components/global/navigation/sub/"
                    }
                  ]
                },
                {
                  "name": "Skip links",
                  "href": "/components/global/skip-links/"
                }
              ]
            },
            {
              "name": {
                "full": "Content components",
                "short": "Content"
              },
              "href": "/components/content/",
              "children": [
                {
                  "name": "Accordion",
                  "href": "/components/content/accordion/"
                },
                {
                  "name": "Card",
                  "href": "/components/content/card/"
                },
                {
                  "name": "Hero",
                  "href": "/components/content/hero/"
                },
                {
                  "name": "Modal",
                  "href": "/components/content/modal/"
                },
                {
                  "name": "Notification",
                  "href": "/components/content/notification/"
                },
                {
                  "name": "Tabs",
                  "href": "/components/content/tabs/"
                }
              ]
            }
          ]
        },
        {
          "name": {
            "full": "Content components",
            "short": "Content"
          },
          "href": "/components/content/",
          "children": [
            {
              "name": "Accordion",
              "href": "/components/content/accordion/"
            },
            {
              "name": "Card",
              "href": "/components/content/card/"
            },
            {
              "name": "Hero",
              "href": "/components/content/hero/"
            },
            {
              "name": "Modal",
              "href": "/components/content/modal/"
            },
            {
              "name": "Notification",
              "href": "/components/content/notification/"
            },
            {
              "name": "Tabs",
              "href": "/components/content/tabs/"
            }
          ]
        }
      ]
    },
    {
      "level": 3,
      "name": "Notification",
      "href": "/components/content/notification/",
      "parents": [
        {
          "name": "Components",
          "href": "/components/",
          "children": [
            {
              "name": {
                "full": "Global components",
                "short": "Global"
              },
              "href": "/components/global/",
              "children": [
                {
                  "name": "Breadcrumb",
                  "href": "/components/global/breadcrumb/"
                },
                {
                  "name": "Button",
                  "href": "/components/global/button/"
                },
                {
                  "name": "Footer",
                  "href": "/components/global/footer/"
                },
                {
                  "name": "Form",
                  "href": "/components/global/form/"
                },
                {
                  "name": "General content",
                  "href": "/components/global/general-content/"
                },
                {
                  "name": "Grid",
                  "href": "/components/global/grid/"
                },
                {
                  "name": "Header",
                  "href": "/components/global/header/"
                },
                {
                  "name": "Navigation",
                  "href": "/components/global/navigation/",
                  "children": [
                    {
                      "name": "Main navigation",
                      "href": "/components/global/navigation/main/"
                    },
                    {
                      "name": "Sub navigation",
                      "href": "/components/global/navigation/sub/"
                    }
                  ]
                },
                {
                  "name": "Skip links",
                  "href": "/components/global/skip-links/"
                }
              ]
            },
            {
              "name": {
                "full": "Content components",
                "short": "Content"
              },
              "href": "/components/content/",
              "children": [
                {
                  "name": "Accordion",
                  "href": "/components/content/accordion/"
                },
                {
                  "name": "Card",
                  "href": "/components/content/card/"
                },
                {
                  "name": "Hero",
                  "href": "/components/content/hero/"
                },
                {
                  "name": "Modal",
                  "href": "/components/content/modal/"
                },
                {
                  "name": "Notification",
                  "href": "/components/content/notification/"
                },
                {
                  "name": "Tabs",
                  "href": "/components/content/tabs/"
                }
              ]
            }
          ]
        },
        {
          "name": {
            "full": "Content components",
            "short": "Content"
          },
          "href": "/components/content/",
          "children": [
            {
              "name": "Accordion",
              "href": "/components/content/accordion/"
            },
            {
              "name": "Card",
              "href": "/components/content/card/"
            },
            {
              "name": "Hero",
              "href": "/components/content/hero/"
            },
            {
              "name": "Modal",
              "href": "/components/content/modal/"
            },
            {
              "name": "Notification",
              "href": "/components/content/notification/"
            },
            {
              "name": "Tabs",
              "href": "/components/content/tabs/"
            }
          ]
        }
      ]
    },
    {
      "level": 3,
      "name": "Tabs",
      "href": "/components/content/tabs/",
      "parents": [
        {
          "name": "Components",
          "href": "/components/",
          "children": [
            {
              "name": {
                "full": "Global components",
                "short": "Global"
              },
              "href": "/components/global/",
              "children": [
                {
                  "name": "Breadcrumb",
                  "href": "/components/global/breadcrumb/"
                },
                {
                  "name": "Button",
                  "href": "/components/global/button/"
                },
                {
                  "name": "Footer",
                  "href": "/components/global/footer/"
                },
                {
                  "name": "Form",
                  "href": "/components/global/form/"
                },
                {
                  "name": "General content",
                  "href": "/components/global/general-content/"
                },
                {
                  "name": "Grid",
                  "href": "/components/global/grid/"
                },
                {
                  "name": "Header",
                  "href": "/components/global/header/"
                },
                {
                  "name": "Navigation",
                  "href": "/components/global/navigation/",
                  "children": [
                    {
                      "name": "Main navigation",
                      "href": "/components/global/navigation/main/"
                    },
                    {
                      "name": "Sub navigation",
                      "href": "/components/global/navigation/sub/"
                    }
                  ]
                },
                {
                  "name": "Skip links",
                  "href": "/components/global/skip-links/"
                }
              ]
            },
            {
              "name": {
                "full": "Content components",
                "short": "Content"
              },
              "href": "/components/content/",
              "children": [
                {
                  "name": "Accordion",
                  "href": "/components/content/accordion/"
                },
                {
                  "name": "Card",
                  "href": "/components/content/card/"
                },
                {
                  "name": "Hero",
                  "href": "/components/content/hero/"
                },
                {
                  "name": "Modal",
                  "href": "/components/content/modal/"
                },
                {
                  "name": "Notification",
                  "href": "/components/content/notification/"
                },
                {
                  "name": "Tabs",
                  "href": "/components/content/tabs/"
                }
              ]
            }
          ]
        },
        {
          "name": {
            "full": "Content components",
            "short": "Content"
          },
          "href": "/components/content/",
          "children": [
            {
              "name": "Accordion",
              "href": "/components/content/accordion/"
            },
            {
              "name": "Card",
              "href": "/components/content/card/"
            },
            {
              "name": "Hero",
              "href": "/components/content/hero/"
            },
            {
              "name": "Modal",
              "href": "/components/content/modal/"
            },
            {
              "name": "Notification",
              "href": "/components/content/notification/"
            },
            {
              "name": "Tabs",
              "href": "/components/content/tabs/"
            }
          ]
        }
      ]
    },
    {
      "level": 1,
      "name": "Documentation",
      "href": "https://compass.vcu.edu/"
    }
  ],
  "title": "Components"
}
  • Content:
    // Navigation component styles
    
    @import "../../shared/animation";
    @import "../../shared/media";
    @import "../../shared/style";
    @import "../../shared/theme";
    
    .cwf-nav {
        line-height: 1;
        font-family: theme__font--sans-serif();
    
        @include media__breakpoint {
            background-color: var(--cwf-nav--background-color);
        }
    }
    
    // Nav dark colors
    $nav--dark__hamburger--mobile--foreground-color: style__color(white) !default;
    $nav--dark--background-color: darken(
        style__color(gray-dark),
        6.5%
    ) !default; // #222
    $nav--dark--background-color--level-2: style__color(gray-dark) !default;
    $nav--dark--background-color--level-3: style__color(gray) !default;
    $nav--dark--foreground-color: style__color(white) !default;
    $nav--dark--active--foreground-color: style__color(black) !default;
    $nav--dark--border-color: style__color(gray-light) !default;
    $nav--dark--accent-color: style__color(gold) !default;
    $nav--dark__controller--background-color: style__color(black) !default;
    
    // Nav light colors
    $nav--light__hamburger--mobile--foreground-color: style__color(black) !default;
    $nav--light--background-color: darken(
        style__color(white-dark),
        3%
    ) !default; // #f0f0f0
    $nav--light--background-color--level-2: style__color(white-dark) !default;
    $nav--light--background-color--level-3: style__color(white) !default;
    $nav--light--foreground-color: darken(
        style__color(gray-lightest),
        3%
    ) !default; // #6d6d6d
    $nav--light--active--foreground-color: theme__accent--foreground() !default;
    $nav--light--border-color: lighten(
        style__color(white-darkest),
        6.5%
    ) !default; // #ddd
    $nav--light--accent-color: theme__accent--background() !default;
    $nav--light__controller--background-color: style__color(white) !default;
    
    // Nav themes
    $nav__themes: (
        dark: (
            hamburger-mobile-foreground-color:
                $nav--dark__hamburger--mobile--foreground-color,
            background-color: $nav--dark--background-color,
            background-color-level-2: $nav--dark--background-color--level-2,
            background-color-level-3: $nav--dark--background-color--level-3,
            foreground-color: $nav--dark--foreground-color,
            active-foreground-color: $nav--dark--active--foreground-color,
            border-color: $nav--dark--border-color,
            accent-color: $nav--dark--accent-color,
            controller-background-color: $nav--dark__controller--background-color
        ),
        light: (
            hamburger-mobile-foreground-color:
                $nav--light__hamburger--mobile--foreground-color,
            background-color: $nav--light--background-color,
            background-color-level-2: $nav--light--background-color--level-2,
            background-color-level-3: $nav--light--background-color--level-3,
            foreground-color: $nav--light--foreground-color,
            active-foreground-color: $nav--light--active--foreground-color,
            border-color: $nav--light--border-color,
            accent-color: $nav--light--accent-color,
            controller-background-color: $nav--light__controller--background-color
        )
    );
    
    @mixin nav__theme($instructions) {
        .cwf-nav--#{map-get($instructions, theme)} {
            --cwf-nav__hamburger--mobile-foreground-color: #{map-get(
                    $instructions,
                    hamburger-mobile-foreground-color
                )};
            --cwf-nav--background-color: #{map-get($instructions, background-color)};
            --cwf-nav--background-color--level-2: #{map-get(
                    $instructions,
                    background-color-level-2
                )};
            --cwf-nav--background-color--level-3: #{map-get(
                    $instructions,
                    background-color-level-3
                )};
            --cwf-nav--foreground-color: #{map-get($instructions, foreground-color)};
            --cwf-nav--active--foreground-color: #{map-get(
                    $instructions,
                    active-foreground-color
                )};
            --cwf-nav--border-color: #{map-get($instructions, border-color)};
            --cwf-nav--accent-color: #{map-get($instructions, accent-color)};
            --cwf-nav__controller--background-color: #{map-get(
                    $instructions,
                    controller-background-color
                )};
        }
    }
    
    @mixin nav__theme--official($theme) {
        $colors: map-get($nav__themes, $theme);
    
        $instructions: map-merge(
            $colors,
            (
                theme: $theme
            )
        );
    
        @include nav__theme($instructions);
    }
    
    @each $theme, $colors in $nav__themes {
        @include nav__theme--official($theme);
    }
    
    $nav__container--background-color: rgba(style__color(black), 0.68) !default;
    $nav__container--reduced-transparency--background-color: style__color(
        black
    ) !default;
    
    .cwf-nav__container {
        display: none;
        position: absolute;
        left: 0;
        top: 0;
        width: 100%;
        height: 100%;
        background-color: var(--cwf-nav__container--background-color);
        @include style__z-index(modal);
    
        --cwf-nav__container--background-color: #{$nav__container--background-color};
    
        @include media__reduced(transparency) {
            --cwf-nav__container--background-color: #{$nav__container--reduced-transparency--background-color};
        }
    
        @include media__reduced(transparency, no-preference) {
            --cwf-nav__container--background-color: #{$nav__container--background-color};
        }
    
        @include media__breakpoint {
            display: block;
            position: static;
            background-color: unset;
            @include theme__contain;
        }
    }
    
    .cwf-nav__controller {
        height: 100%;
        background-color: var(--cwf-nav__controller--background-color);
    }
    
    .cwf-nav--main .cwf-nav__controller {
        width: 70%;
    
        @include media__breakpoint {
            width: 100%;
        }
    }
    
    .cwf--show-main-nav .cwf-nav__controller {
        padding-top: 64px;
    }
    
    .cwf-nav--main .cwf--show-main-nav .cwf-nav__controller {
        @include media__breakpoint {
            padding-top: 0;
        }
    }
    
    .cwf-nav__item {
        display: flex;
        flex-wrap: wrap;
        position: relative;
    }
    
    .cwf-nav__link {
        flex: 1;
        display: flex;
        align-items: center;
        font-weight: 500;
        overflow: hidden;
        padding: 1rem 1.75rem;
        position: relative;
        background-color: transparent;
        text-align: left;
        text-decoration: none;
        color: var(--cwf-nav--foreground-color);
    
        &:hover,
        &:focus {
            background-color: var(--cwf-nav--accent-color);
            color: var(--cwf-nav--active--foreground-color);
    
            .cwf-nav--main & {
                @include media__breakpoint {
                    & + .cwf-nav__toggle {
                        color: var(--cwf-nav--active--foreground-color);
                    }
                }
            }
        }
    }
    
    .cwf-nav__list {
        display: none;
        list-style-type: none;
        width: 100%;
        margin: 0;
        padding: 0;
        border: 1px solid var(--cwf-nav--border-color);
    
        & .cwf-nav__list {
            border: none;
            border-top: 1px solid var(--cwf-nav--border-color);
        }
    }
    
    $nav__list--scroll--background-fallback: transparent !default;
    $nav__list--scroll--background: rgba(style__color(black), 0.25) !default;
    
    @mixin nav__list--scroll-shadow($side) {
        background: var(--cwf-nav__list--scroll--background-fallback);
        background: radial-gradient(
            ellipse farthest-corner at $side center,
            var(--cwf-nav__list--scroll--background) 0%,
            transparent 75%
        );
    
        @include media__reduced(transparency) {
            background: var(--cwf-nav__list--scroll--background-fallback);
        }
    
        @include media__reduced(transparency, no-preference) {
            background: radial-gradient(
                ellipse farthest-corner at $side center,
                var(--cwf-nav__list--scroll--background) 0%,
                transparent 75%
            );
        }
    }
    
    .cwf-nav__list.cwf-scroll--y {
        position: relative;
        max-height: 551px;
        --cwf-nav__list--scroll--background-fallback: #{$nav__list--scroll--background-fallback};
        --cwf-nav__list--scroll--background: #{$nav__list--scroll--background};
        --cwf-nav__list--scroll-top: 0;
        --cwf-nav__list--scroll-bottom: 0;
    
        &:before {
            top: 0;
            margin-bottom: -0.5rem;
            @include nav__list--scroll-shadow(top);
            opacity: var(--cwf-nav__list--scroll-top);
        }
    
        &:before,
        &:after {
            content: "";
            position: sticky;
            display: block;
            width: 100%;
            height: 0.5rem;
            pointer-events: none;
            @include style__z-index(content, middle);
        }
    
        &:after {
            bottom: 0;
            margin-top: -0.5rem;
            @include nav__list--scroll-shadow(bottom);
            opacity: var(--cwf-nav__list--scroll-bottom);
        }
    }
    
    .cwf-nav--main .cwf-nav__list {
        @include style__z-index(menu, middle);
        border: none;
    }
    
    .cwf-nav__item--is-expanded > .cwf-nav__list,
    .cwf-nav__controller > .cwf-nav__list {
        display: block;
    }
    
    .cwf-nav__list--level-1 {
        background-color: var(--cwf-nav--background-color);
        margin: 0;
        width: 100%;
        @include style__z-index(page);
    }
    
    .cwf--show-main-nav .cwf-nav--main .cwf-nav__list--level-1 {
        height: 100%;
        overflow-y: auto;
    }
    
    $nav--main__list--level-1__link--border-color: transparent !default;
    $nav--main__list--level-1__link--active--border-color: rgba(
        style__color(black),
        0.15
    ) !default;
    
    .cwf-nav--main .cwf-nav__list--level-1 {
        @include media__breakpoint {
            display: flex;
            flex-direction: row;
    
            & > .cwf-nav__item > .cwf-nav__link {
                padding-top: calc(1rem - 1px);
                border-top: 1px solid
                    var(--cwf-nav--main__list--level-1__link--border-color);
                --cwf-nav--main__list--level-1__link--border-color: #{$nav--main__list--level-1__link--border-color};
                --cwf-nav--main__list--level-1__link--active--border-color: #{$nav--main__list--level-1__link--active--border-color};
    
                &:hover,
                &:focus {
                    border-color: var(
                        --cwf-nav--main__list--level-1__link--active--border-color
                    );
                }
            }
        }
    }
    
    .cwf-nav--sub .cwf-nav__list--level-2 {
        @include style__z-index(content);
    }
    
    // make room for the dropdown arrows on level 1
    .cwf-nav__list--level-1 > .cwf-nav__item--has-dropdown > .cwf-nav__link,
    .cwf-nav__list--level-2 > .cwf-nav__item--has-dropdown > .cwf-nav__link {
        padding-right: 3rem;
    }
    
    .cwf-nav--sub .cwf-nav__list--level-1 > .cwf-nav__item > .cwf-nav__link,
    .cwf-nav--sub .cwf-nav__list--level-1 > .cwf-nav__item > .cwf-nav__toggle {
        display: none;
    }
    
    .cwf-nav__item {
        border-bottom: 1px solid var(--cwf-nav--border-color);
    
        &:last-child {
            border-bottom: none;
        }
    }
    
    .cwf-nav--main .cwf-nav__list--level-1 > .cwf-nav__item {
        @include media__breakpoint {
            border-bottom: none;
            border-right: 1px solid var(--cwf-nav--border-color);
        }
    }
    
    .cwf-nav--sub .cwf-nav__list--level-1 > .cwf-nav__item {
        @include media__breakpoint {
            border-right: none;
        }
    }
    
    .cwf-nav--sub .cwf-nav__list--level-1 > .cwf-nav__item:first-of-type {
        @include media__breakpoint {
            border-top: none;
        }
    }
    
    .cwf-nav--main .cwf-nav__list--level-1 > .cwf-nav__item:last-of-type {
        @include media__breakpoint {
            border-right: none;
        }
    }
    
    .cwf-nav__list--level-3 > .cwf-nav__item > .cwf-nav__link {
        padding-left: 2.5rem;
    }
    
    .cwf-nav--main .cwf-nav__list--level-3 > .cwf-nav__item > .cwf-nav__link {
        @include media__breakpoint {
            padding-left: 1.75rem;
        }
    }
    
    .cwf-nav__list--level-2 {
        padding: 0;
        background-color: var(--cwf-nav--background-color--level-2);
    }
    
    .cwf-nav--main .cwf-nav__list--level-2 {
        @include media__breakpoint {
            top: 100%;
        }
    }
    
    .cwf-nav--main .cwf-nav__list--level-2,
    .cwf-nav--main .cwf-nav__list--level-3 {
        @include media__breakpoint {
            position: absolute;
            min-width: 14rem;
        }
    }
    
    .cwf-nav__list--level-3 {
        padding: 0;
        background-color: var(--cwf-nav--background-color--level-3);
    }
    
    .cwf-nav--main .cwf-nav__list--level-3 {
        @include media__breakpoint {
            left: 100%;
            top: 0;
        }
    }
    
    $nav__toggle--background-color: transparent !default;
    
    .cwf-nav__toggle {
        width: 3rem;
        min-height: 3rem;
        padding: 0;
        border: none;
        background-color: var(--cwf-nav__toggle--background-color);
        font-size: 1rem;
        color: var(--cwf-nav--foreground-color);
        --cwf-nav__toggle--background-color: #{$nav__toggle--background-color};
    
        @include style__cursor;
    
        &:hover,
        &:focus {
            background-color: var(--cwf-nav--accent-color);
        }
    
        @include media__touch {
            position: relative;
    
            &:before {
                content: "";
                position: absolute;
                left: 0;
                top: 10%;
                width: 1px;
                height: 80%;
                background-color: var(--cwf-nav--border-color);
            }
    
            &:focus:before {
                display: none;
            }
        }
    }
    
    .cwf-nav--dark .cwf-nav__toggle {
        &:hover,
        &:focus {
            color: var(--cwf-nav--background-color);
        }
    }
    
    .cwf-nav--light .cwf-nav__toggle {
        &:hover,
        &:focus {
            color: var(--cwf-nav--background-color--level-3);
        }
    }
    
    .cwf-nav--main .cwf-nav__toggle {
        @include media__breakpoint {
            position: absolute;
            height: 100%;
            top: 0;
            right: 0;
            padding: 0;
            pointer-events: none;
    
            @include media__touch {
                &:before {
                    display: none;
                }
            }
        }
    }
    
    $nav__icon: "\f078" !default; // Chevron down
    
    .cwf-nav__icon {
        display: inline-block;
        @include style__icon;
        @include animation__transition(transform);
    
        &:before {
            content: $nav__icon;
        }
    }
    
    .cwf-nav__icon--rotate {
        @include animation__flip;
    }
    
    $nav--main__list--level-2__toggle__icon: "\f054" !default; // Chevron right
    
    .cwf-nav--main .cwf-nav__list--level-2 .cwf-nav__toggle .cwf-nav__icon:before {
        @include media__breakpoint {
            content: $nav--main__list--level-2__toggle__icon;
        }
    }
    
    $nav__hamburger--background-color: transparent !default;
    $nav__hamburger--foreground-color: darken(
        style__color(gray-dark),
        0.75%
    ) !default; // #313131
    $nav__hamburger--active--background-color: rgba(
        style__color(black),
        0.05
    ) !default;
    $nav__hamburger--active--foreground-color: style__color(black) !default;
    
    .cwf-nav__hamburger {
        align-items: center;
        background-color: var(--cwf-nav__hamburger--background-color);
        border: none;
        color: var(--cwf-nav__hamburger--foreground-color);
        display: flex;
        flex-direction: column;
        font-size: 0.65rem;
        font-weight: 700;
        height: 64px;
        justify-content: space-evenly;
        left: 0;
        min-width: 48px;
        padding: 0.5rem 0;
        position: absolute;
        top: 0;
        @include style__z-index(modal, middle);
    
        --cwf-nav__hamburger--background-color: #{$nav__hamburger--background-color};
        --cwf-nav__hamburger--foreground-color: #{$nav__hamburger--foreground-color};
        --cwf-nav__hamburger--active--background-color: #{$nav__hamburger--active--background-color};
        --cwf-nav__hamburger--active--foreground-color: #{$nav__hamburger--active--foreground-color};
    
        &:hover,
        &:focus {
            background-color: var(--cwf-nav__hamburger--active--background-color);
            color: var(--cwf-nav__hamburger--active--foreground-color);
        }
    
        & .cwf-nav__icon {
            font-size: 1.25rem;
        }
    }
    
    .cwf-nav--main .cwf-nav__hamburger {
        @include media__breakpoint {
            display: none;
        }
    }
    
    .cwf--show-main-nav {
        overflow: hidden;
    }
    
    .cwf--show-main-nav .cwf-nav__hamburger {
        left: 70%;
        right: 0;
        flex-direction: row;
        width: 0;
        min-width: 128px;
        padding: 0;
        font-size: 1rem;
        color: var(--cwf-nav__hamburger--mobile-foreground-color);
        transform: translateX(-100%);
    
        & .cwf-nav__icon {
            font-size: 1.5rem;
        }
    }
    
    $nav__hamburger__icon--expand: "\f0c9" !default; // Bars
    $nav__hamburger__icon--collapse: "\f00d" !default; // Times
    
    .cwf-nav__hamburger .cwf-nav__icon:before {
        content: $nav__hamburger__icon--expand;
    }
    
    .cwf--show-main-nav .cwf-nav__hamburger .cwf-nav__icon:before {
        content: $nav__hamburger__icon--collapse;
    }
    
    .cwf-nav__hamburger-text--menu {
        display: block;
    
        .cwf--show-main-nav & {
            display: none;
        }
    }
    
    .cwf-nav__hamburger-text--close {
        display: none;
    
        .cwf--show-main-nav & {
            display: block;
        }
    }
    
    .cwf--show-main-nav .cwf-nav__hamburger-text--menu {
        display: none;
    }
    
    // Navigation utilities
    
    .cwf--show-main-nav .cwf-nav--main .cwf-nav__container {
        display: block;
    }
    
    .cwf-nav__item > .cwf-nav__link:before {
        content: "";
        display: none;
        position: absolute;
        left: 0;
        top: 0;
        width: 0.5rem;
        height: 100%;
        background-color: var(--cwf-nav--accent-color);
        @include animation__transition(width, height);
    }
    
    .cwf-nav__item.cwf-nav__item--is-current > .cwf-nav__link:before {
        display: block;
    }
    
    .cwf-nav--main
        .cwf-nav__list--level-1
        > .cwf-nav__item.cwf-nav__item--is-current
        > .cwf-nav__link:before {
        @include media__breakpoint {
            top: unset;
            bottom: 0;
            width: 100%;
            height: 0.25rem;
        }
    }
    
    .cwf-nav--main
        .cwf-nav__list--level-3
        > .cwf-nav__item.cwf-nav__item--is-current
        > .cwf-nav__link:before {
        @include media__breakpoint {
            left: unset;
            right: 0;
        }
    }
    
    .cwf-nav__item.cwf-nav__item--is-parent-of-current > .cwf-nav__link:before {
        opacity: 0.32;
    }
    
    .cwf-nav--main
        .cwf-nav__list--level-1
        .cwf-nav__item.cwf-nav__item--is-parent-of-current
        > .cwf-nav__link:before {
        @include media__breakpoint {
            opacity: 0.64;
        }
    }
    
  • URL: /components/raw/nav/_index.scss
  • Filesystem Path: components/nav/_index.scss
  • Size: 17.7 KB
  • Content:
    // The default component class
    import { Component } from '../../shared/component';
    
    // Provide functionality to all navs
    export class Nav extends Component {
        constructor({
            desktopBreakpoint = 1024,
            // Selectors
            container = 'cwf-nav__container',
            controller = 'cwf-nav__controller',
            hamburger = 'cwf-nav__hamburger',
            iconRotate = 'cwf-nav__icon--rotate',
            item = 'cwf-nav__item',
            itemHasDropdown = 'cwf-nav__item--has-dropdown',
            itemIsCurrent = 'cwf-nav__item--is-current',
            itemIsExpanded = 'cwf-nav__item--is-expanded',
            itemIsParentOfCurrent = 'cwf-nav__item--is-parent-of-current',
            link = 'cwf-nav__link',
            list = 'cwf-nav__list',
            listLevel = /cwf-nav__list--level-?(\d)/,
            nav = 'cwf-nav',
            scrollable = 'cwf-scroll--y',
            showMainNav = 'cwf--show-main-nav',
            subNav = 'cwf-nav--sub',
            toggle = 'cwf-nav__toggle',
            // Properties
            listScrollTop = '--cwf-nav__list--scroll-top',
            listScrollBottom = '--cwf-nav__list--scroll-bottom'
        } = {}) {
            super();
    
            // Initialize a run flag
            this.run = false;
    
            // Set the desktop breakpoint,...
            this.desktopBreakpoint = desktopBreakpoint;
            // ... selectors,...
            this.selectors = {
                container,
                controller,
                hamburger,
                iconRotate,
                item,
                itemHasDropdown,
                itemIsCurrent,
                itemIsExpanded,
                itemIsParentOfCurrent,
                link,
                list,
                listLevel,
                nav,
                scrollable,
                showMainNav,
                subNav,
                toggle
            };
            // ... and properties
            this.properties = {
                listScrollTop,
                listScrollBottom
            };
    
            // Initialize an empty array for all nav references
            this.references = [];
    
            // Bind this to all event methods that need the class context
            this.normalizeReferences = this.normalizeReferences.bind(this);
            this.keyboardNavigation = this.keyboardNavigation.bind(this);
            this.toggleDropdownMenu = this.toggleDropdownMenu.bind(this);
            this.toggleMainMenu = this.toggleMainMenu.bind(this);
        }
    
        // Normalize a nav reference
        normalizeReferences(nav) {
            // Initialize a reference object
            let reference = {};
    
            // Store whether this nav is a sub nav,...
            reference.isSubNav = nav.classList.contains(this.selectors.subNav);
            // ... its lists,...
            reference.lists = Array.from(
                nav.getElementsByClassName(this.selectors.list)
            );
            // ... items,...
            reference.items = Array.from(
                nav.getElementsByClassName(this.selectors.item)
            );
            // ... toggles,...
            reference.toggles = Array.from(
                nav.getElementsByClassName(this.selectors.toggle)
            );
            // ... and links
            reference.links = Array.from(
                nav.getElementsByClassName(this.selectors.link)
            );
    
            // If the nav is a sub nav, return the reference object as is
            if (reference.isSubNav) return reference;
    
            // Otherwise, also store its hamburger button,...
            reference.hamburger = nav.querySelector(`.${this.selectors.hamburger}`);
            // ... container,...
            reference.container = nav.querySelector(`.${this.selectors.container}`);
            // ... and controller
            reference.controller = nav.querySelector(
                `.${this.selectors.controller}`
            );
    
            // Finally, return the reference object
            return reference;
        }
    
        // Get all references to the navs and their lists/items
        getReferences() {
            // Attempt to grab all navs from the page...
            const navs = Array.from(
                document.querySelectorAll(`.${this.selectors.nav}`)
            );
            // ... and if none exist, do nothing else
            if (!navs) return;
    
            // Otherwise, normalize/store the references to these navs
            this.references = navs.map(this.normalizeReferences);
        }
    
        // Get an item's toggle
        getToggle(item) {
            return Array.from(item.children).find((child) =>
                child.matches(`.${this.selectors.toggle}`)
            );
        }
    
        // Figures out whether to bind or unbind from an event
        get listener() {
            return this.run ? 'addEventListener' : 'removeEventListener';
        }
    
        // Add the `--has-dropdown` item class to any drop-down items without it
        indicateHasDropdown(item) {
            // If the item already has the `--has-dropdown` item class, return the item
            if (item.classList.contains(this.selectors.itemHasDropdown))
                return item;
    
            // Attempt to grab the item's toggle...
            const toggle = this.getToggle(item);
            // ... and if none exist, return the item
            if (!toggle) return item;
    
            // Othwerwise, add the `--has-dropdown` item class to the item...
            item.classList.add(this.selectors.itemHasDropdown);
            // ... and return it
            return item;
        }
    
        // Attempt to find/indicate the current item of a nav
        findCurrentItem(items) {
            // Grab the full/relative path of the current page...
            const { href, pathname } = window.location,
                // ... and try to find an item with a link with an HREF that matches
                currentItem = items.find((item) => {
                    // Attempt to grab the item's link...
                    const link = item.querySelector(`.${this.selectors.link}`);
                    // ... and if it doesn't exist...
                    if (!link) return false;
                    // ... or its href doesn't match the full/relative path, return false
                    if (link.href !== href && link.href !== pathname) return false;
    
                    // Otherwise, return true
                    return true;
                });
    
            // If no item was found, return undefined
            if (!currentItem) return undefined;
    
            // Grab the current item's link
            const currentLink = currentItem.querySelector(
                `.${this.selectors.link}`
            );
    
            // Otherwise, add the `--is-current` class to it,...
            currentItem.classList.add(this.selectors.itemIsCurrent);
            // ... indicate via ARIA that this its link goes to the current page,...
            currentLink.setAttribute('aria-current', 'page');
            // ... and return it
            return currentItem;
        }
    
        // Find the parent items of the current item
        findParentsOfCurrent(item) {
            // Get the parent item of the current item...
            let parent = item.parentNode.parentNode;
            // ... and initialize a parents array
            let parents = [];
    
            // While there's a parent item that's an <li> and not a nav controller,...
            while (
                parent &&
                parent.tagName === 'LI' &&
                !parent.classList.contains(this.selectors.controller)
            ) {
                // ... push it to the parents array...
                parents.push(parent);
                // ... and recurse up to the next parent item
                parent = parent.parentNode.parentNode;
            }
    
            // Finally, return all parents
            return parents;
        }
    
        // Indicate the current item tree
        indicateCurrentItemTree(currentItem, isSubNav) {
            // Find all parent items of the current item...
            const parents = this.findParentsOfCurrent(currentItem);
            // ... and for each,...
            parents.forEach((parent) => {
                // ... add the current and parent-of-current classes to it
                parent.classList.add(
                    this.selectors.itemIsCurrent,
                    this.selectors.itemIsParentOfCurrent
                );
            });
    
            // If the current navigation is a main-nav and the viewport is not at desktop size, or it's a sub nav, do nothing else
            if (!isSubNav && !(window.innerWidth < this.desktopBreakpoint)) return;
    
            // Create an array of current items from the current item and its parents...
            const currentItems = [currentItem, ...parents];
    
            // ... and for each,...
            currentItems.forEach((item) => {
                // ... expand it
                item.classList.add(this.selectors.itemIsExpanded);
    
                // Next, attempt to find its toggle...
                const toggle = this.getToggle(item);
                // ... and if it doesn't exist...
                if (!toggle) return;
                // ... or it's not visible, do nothing else
                if (window.getComputedStyle(toggle).display !== 'block') return;
    
                // Otherwise, rotate its icon
                this.rotateToggleIcon(toggle, true);
            });
        }
    
        // Indicate the current items
        indicateCurrentItems({ items, isSubNav }) {
            // Either store or find the current item...
            const currentItem =
                items.find((item) => {
                    item.classList.contains(this.selectors.itemIsCurrent);
                }) || this.findCurrentItem(items);
    
            // ... and if one was stored, indicate its current tree
            if (currentItem) this.indicateCurrentItemTree(currentItem, isSubNav);
        }
    
        // Rotate the toogle icon based on the collapse state.
        rotateToggleIcon(toggle, expanded) {
            // If there's no toggle, do nothing else
            if (!toggle) return;
    
            // Attempt to grab the toggle's icon...
            const icon = toggle.getElementsByTagName('i')[0];
            // ... and if it doesn't exist, do nothing else
            if (!icon) return;
    
            // Finally, toggle the icon's rotation class (add it if expanded, and remove it if collapsed)
            icon.classList.toggle(this.selectors.iconRotate, expanded);
        }
    
        // Collapse/expand dropdown menus
        toggleDropdownMenu({ type, currentTarget }, expand) {
            // Check whether the current target is an item...
            const isItem = currentTarget.classList.contains(this.selectors.item),
                // ... and store the item accordingly,...
                item = isItem ? currentTarget : currentTarget.parentElement,
                // ... and grab the desktop breakpoint
                { desktopBreakpoint } = this;
            // ... and if the window isn't at desktop size when triggered by hovering, do nothing else
            if (
                ['mouseenter', 'mouseleave'].includes(type) &&
                !(window.innerWidth > desktopBreakpoint)
            )
                return;
    
            // Initialize a state and focus variable...
            let state, focus;
            switch (type) {
                case 'mouseenter':
                    // ... and for 'mouseeneter' events, set state to true and focus to false,...
                    state = true;
                    focus = false;
                    break;
                case 'mouseleave':
                    // ... for 'mouseleave' events, set both to false,...
                    state = false;
                    focus = false;
                    break;
                default:
                    // ... otherwise, set both to the optional expand variable
                    state = expand;
                    focus = expand;
            }
    
            // Check whether the item is expanded or not...
            const expanded = item.classList.contains(this.selectors.itemIsExpanded),
                // ... and whether to force it open/close or toggle it
                toggle = typeof state === 'boolean' ? state : !expanded;
    
            // Toggle the expand class...
            item.classList.toggle(this.selectors.itemIsExpanded, toggle);
            // ... and rotate the icon accordingly
            this.rotateToggleIcon(item, toggle);
    
            // If nothing is to be focused, do nothing else
            if (!focus) return;
    
            // Grab the list and its first link from the current target...
            const list = item.querySelector(`.${this.selectors.list}`),
                firstLink = list.querySelector(`.${this.selectors.link}`);
            // ... and focus it
            firstLink.focus();
        }
    
        // Focus the previous/next link (with options to collapse the to-be-focused link's parent item)
        focusLink(direction, links, from, collapse = false) {
            // Store the first/last links,...
            const firstLink = links[0],
                lastLink = links[links.length - 1];
    
            // If the direction is "first", focus the first link...
            if (direction === 'first') return firstLink.focus();
            // ... and if the direction is "last", focus the last link
            if (direction === 'last') return lastLink.focus();
    
            // Check whether the from element is an item...
            const isItem = from.classList.contains(this.selectors.item),
                // ... and get the current link accordingly,...
                current = isItem
                    ? from.querySelector(`.${this.selectors.link}`)
                    : from,
                // ... and get the index of the current link
                index = links.indexOf(current);
    
            // Initialize storage for a link to compare the current link to,...
            let compare,
                // ... a link to wrap to,,,
                wrap,
                // ... and the index of the sibling link to move to
                sibling;
    
            // Dependending on the direction provided...
            switch (direction) {
                case 'previous':
                    // Previous = if the current link is the first link, wrap to the last link, otherwise move to the previous sibling link
                    compare = firstLink;
                    wrap = lastLink;
                    sibling = index - 1;
                    break;
                case 'next':
                    // Next = if the current link is the last link, wrap to the first link, otherwise move to the next sibling link
                    compare = lastLink;
                    wrap = firstLink;
                    sibling = index + 1;
            }
            // ... change what link should be focused
            const focusable = current === compare ? wrap : links[sibling];
    
            // If collapse has been enabled,...
            if (collapse) {
                // ... get the parent item of the link to be focused...
                const item = focusable.parentElement;
                // ... and collapse it if open
                this.toggleDropdownMenu({ currentTarget: item }, false);
            }
    
            // Finally, focus the appropriate link
            return focusable.focus();
        }
    
        // Focus an item's element
        focusItemElement(element, item) {
            // Grab the item element...
            const target = item.querySelector(`.${this.selectors[element]}`);
            // ... and focus it
            target.focus();
        }
    
        // Provide advanced keyboard navigation
        keyboardNavigation(event) {
            // Pull the type and current target from the event
            const { type, currentTarget } = event;
    
            // Either add/remove a keydown event listener when the current target is focused/blurred respectively...
            switch (type) {
                case 'focus':
                    currentTarget.addEventListener(
                        'keydown',
                        this.keyboardNavigation
                    );
                    break;
                case 'blur':
                    currentTarget.removeEventListener(
                        'keydown',
                        this.keyboardNavigation
                    );
            }
            // ... and if the event is not a keydown, do nothing else
            if (type !== 'keydown') return;
    
            // Pull the key from the event...
            const { key } = event;
            // ... and if it's tab...
            if (key === 'Tab') return;
            // ... or it's not an arrow key/home/end/escape,...
            if (
                ![
                    'ArrowLeft',
                    'ArrowUp',
                    'ArrowRight',
                    'ArrowDown',
                    'Home',
                    'End',
                    'Escape'
                ].includes(key)
            )
                return;
            // ... or if there's an outstanding active composition, do nothing else
            if (event.isComposing) return;
    
            // Prevent the default behavior
            event.preventDefault();
    
            // Store whether the current target is a toggle or not
            const isToggle = currentTarget.classList.contains(
                this.selectors.toggle
            );
    
            // Get the links and sub nav check of the nav containing the current target
            const { links, isSubNav } = this.references.find((nav) => {
                // If the current target is not a toggle, find a nav with links containing it...
                if (!isToggle) return nav.links.includes(currentTarget);
                // ... otherwise, find a nav with toggles containing it
                return nav.toggles.includes(currentTarget);
            });
    
            // Store all visible, focusable links,...
            const visibleLinks = links.filter((link) => link.offsetParent !== null),
                // ... the current target's parent (item),...
                item = currentTarget.parentElement,
                // ... if the item has a dropdown,...
                hasDropdown = item.classList.contains(
                    this.selectors.itemHasDropdown
                ),
                // ... if the item is expanded,...
                isExpanded = item.classList.contains(this.selectors.itemIsExpanded),
                // ... the item's parent (list),...
                list = item.parentElement,
                // ... the list's level,..
                levelMatch = list.className.match(this.selectors.listLevel),
                level = levelMatch && levelMatch.length ? Number(levelMatch[1]) : 0,
                // ... if the list is not the first level within the nav,...
                isNotTopLevel = isSubNav ? level !== 2 : level !== 1,
                // ... and store focusable links within the same list
                sameListLinks = links.filter(
                    (link) => link.parentElement.parentElement === list
                );
    
            // Main navigation on desktop
            if (!isSubNav && !(window.innerWidth < this.desktopBreakpoint)) {
                // Level 1
                if (level === 1) {
                    // Toggles
                    if (isToggle) {
                        switch (key) {
                            case 'ArrowLeft':
                                // Level 1, arrow left = focus the current item's link
                                return this.focusItemElement('link', item);
                            case 'ArrowUp':
                                // Level 1, arrow up = collapse the dropdown
                                return this.toggleDropdownMenu(
                                    { currentTarget },
                                    false
                                );
                            case 'ArrowRight':
                                // Level 1, arrow right = focus the next same list link from the current item's link
                                return this.focusLink(
                                    'next',
                                    sameListLinks,
                                    item,
                                    true
                                );
                        }
                    }
    
                    switch (key) {
                        case 'ArrowLeft':
                            // Level 1, arrow left = focus previous link within the same list
                            return this.focusLink(
                                'previous',
                                sameListLinks,
                                currentTarget
                            );
                        case 'ArrowUp':
                            // Level 1, arrow up = nothing
                            return;
                        case 'ArrowRight':
                            // Level 1, arrow right = focus next link within the same list
                            return this.focusLink(
                                'next',
                                sameListLinks,
                                currentTarget
                            );
                    }
                    // Level 1, arrow down
                    if (key === 'ArrowDown') {
                        // Level 1, arrow down, has dropdown = expand dropdown and focus first link
                        if (hasDropdown)
                            return this.toggleDropdownMenu({ currentTarget }, true);
                        // Level 1, arrow down = nothing
                        return;
                    }
                }
    
                // Level 2
                if (level === 2) {
                    // Toggles
                    if (isToggle) {
                        switch (key) {
                            case 'ArrowLeft':
                                // Level 2, arrow left = focus the current item's link
                                return this.focusItemElement('link', item);
                            case 'ArrowUp':
                                // Level 2, arrow up = focus previous link within the same list from the current item's link
                                return this.focusLink(
                                    'previous',
                                    sameListLinks,
                                    item
                                );
                            case 'ArrowRight':
                                // Level 2, arrow right = open the dropdown
                                return this.toggleDropdownMenu(
                                    { currentTarget },
                                    true
                                );
                            case 'ArrowDown':
                                // Level 2, arrow down = focus next link within the same list from current item's link
                                return this.focusLink('next', sameListLinks, item);
                        }
                    }
    
                    // Level 2, arrow right, has dropdown = expand dropdown and focus first link
                    if (key === 'ArrowRight' && hasDropdown)
                        return this.toggleDropdownMenu({ currentTarget }, true);
    
                    // Level 2, arrow up, is first link of same list = focus previous visible link and collapse dropdown
                    if (key === 'ArrowUp' && currentTarget === sameListLinks[0])
                        return this.focusLink(
                            'previous',
                            visibleLinks,
                            currentTarget,
                            true
                        );
                }
    
                // Level 3, arrow left = focus previous visible link from first link of the same list and collapse dropdown
                if (level === 3 && key === 'ArrowLeft')
                    return this.focusLink(
                        'previous',
                        visibleLinks,
                        sameListLinks[0],
                        true
                    );
    
                // Defaults
                switch (key) {
                    case 'ArrowUp':
                        // Arrow up = focus previous link within the same list
                        return this.focusLink(
                            'previous',
                            sameListLinks,
                            currentTarget
                        );
                    case 'ArrowDown':
                        // Arrow down = focus next link within the same list
                        return this.focusLink('next', sameListLinks, currentTarget);
                    case 'Home':
                        // Home = focus first link within the same list
                        return this.focusLink('first', sameListLinks);
                    case 'End':
                        // End = focus last link within the same list
                        return this.focusLink('last', sameListLinks);
                }
            }
    
            // All toggles
            if (isToggle) {
                // Arrow up
                if (key === 'ArrowUp') {
                    // Arrow up, item is expanded = collapse the dropdown
                    if (isExpanded)
                        return this.toggleDropdownMenu({ currentTarget }, false);
                    // Arrow up = focus the previous visible link from the current item's link
                    return this.focusLink('previous', visibleLinks, item, true);
                }
    
                // Defaults
                switch (key) {
                    case 'ArrowLeft':
                        // Arrow left = focus the current item's link
                        return this.focusItemElement('link', item);
                    case 'ArrowDown':
                        // Arrow down = expand the dropdown
                        return this.toggleDropdownMenu({ currentTarget }, true);
                }
            }
    
            // All navigation
            switch (key) {
                case 'ArrowUp':
                    // Arrow up = focus previous visible link
                    return this.focusLink('previous', visibleLinks, currentTarget);
                case 'ArrowDown':
                    // Arrow down = focus next visible link
                    return this.focusLink('next', visibleLinks, currentTarget);
                case 'Home':
                    // Home = focus first visible link
                    return this.focusLink('first', visibleLinks);
                case 'End':
                    // End = focus last visible link
                    return this.focusLink('last', visibleLinks);
            }
    
            // Not top level list, escape = focus previous visible link from first link of same list and collapse
            if (isNotTopLevel && key === 'Escape')
                return this.focusLink(
                    'previous',
                    visibleLinks,
                    sameListLinks[0],
                    true
                );
    
            // Arrow right, has dropdown = focus the item's toggle
            if (key === 'ArrowRight' && hasDropdown)
                return this.focusItemElement('toggle', item);
        }
    
        // Bind to every nav's toggle's click event
        togglesOnClickFocusBlur({ toggles }) {
            // If it has none, do nothing else
            if (!toggles.length) return;
    
            // Otherwiser, for each toggle,...
            toggles.forEach((toggle) => {
                // ... toggle its sub menu when clicked, and provide advanced keyboard navigation when focused/blurred
                toggle[this.listener]('click', this.toggleDropdownMenu);
                toggle[this.listener]('focus', this.keyboardNavigation);
                toggle[this.listener]('blur', this.keyboardNavigation);
            });
        }
    
        // Bind to every link's focus/blur events
        linksOnFocusBlur({ links }) {
            // If no links exist, do nothing else
            if (!links.length) return;
    
            // Otherwise, for each link,...
            links.forEach((link) => {
                // ... provide advanced keyboard nevigation when focused (and remove it when blurred)
                link[this.listener]('focus', this.keyboardNavigation);
                link[this.listener]('blur', this.keyboardNavigation);
            });
        }
    
        // Bind to every main nav's item's mouse enter/leave event if they have dropdowns
        itemsWithDropdownsOnHover({ items }) {
            // If no items exist, do nothing else
            if (!items.length) return;
    
            // Otherwise, filter the items that have dropdowns...
            items
                .filter((item) =>
                    item.classList.contains(this.selectors.itemHasDropdown)
                )
                .forEach((item) => {
                    // ... and toggle its dropdown menu on mouse enter/leave
                    item[this.listener]('mouseenter', this.toggleDropdownMenu);
                    item[this.listener]('mouseleave', this.toggleDropdownMenu);
                });
        }
    
        // Start or stop core functionality
        allFunctionality() {
            // For each nav,...
            this.references.forEach((nav) => {
                // ... indicate the current items and their trees...
                this.indicateCurrentItems(nav);
                // ... bind to every nav's toggle's click event,...
                this.togglesOnClickFocusBlur(nav);
                // ... and bind to every link's focus/blur events
                this.linksOnFocusBlur(nav);
            });
        }
    
        // Collapse/expand the main menu
        toggleMainMenu({ currentTarget }) {
            // Change the default behavior whether the current target is a link or not
            const isLink = currentTarget.classList.contains(this.selectors.link),
                operation = isLink ? 'remove' : 'toggle',
                listener = isLink ? 'removeEventListener' : 'addEventListener';
    
            // Toggle the show main nav class on the document body
            document.body.classList[operation](this.selectors.showMainNav);
    
            // Finally, get the links from the nav of the current target...
            const { links } = this.references.find((nav) => {
                // If the current target is not a link, find a nav with a hamburger button or container that matches the current target...
                if (!isLink)
                    return (
                        nav.hamburger === currentTarget ||
                        nav.container === currentTarget
                    );
                // ... otherwise, find a nav with links that include the current target
                return nav.links.includes(currentTarget);
            });
            // ... and toggle the main menu when a link is clicked
            links.forEach((link) => {
                link[listener]('click', this.toggleMainMenu);
            });
        }
    
        // Stop event propagation
        stopPropagation(event) {
            event.stopPropagation();
        }
    
        // Bind to a main nav's hamburger button click event
        hamburgerOnClick({ hamburger }) {
            // If no hamburger button exists, do nothing else
            if (!hamburger) return;
    
            // Otherwise, toggle the main menu when its clicked
            hamburger[this.listener]('click', this.toggleMainMenu);
        }
    
        // Bind to the nav container's click event
        containerOnClick({ container, controller }) {
            // If no container or controller exist, do nothing else
            if (!container || !controller) return;
    
            // Otherwise, toggle the main menu when the overflow container is clicked...
            container[this.listener]('click', this.toggleMainMenu);
            // ... and stop event propagation if the nav controller is clicked
            controller[this.listener]('click', this.stopPropagation);
        }
    
        // Start or stop the main navigation functionality
        mainFunctionality() {
            // For each main nav...
            this.references
                .filter(({ isSubNav }) => !isSubNav)
                .forEach((nav) => {
                    // ... bind to its item's mouse enter/leave event if they have dropdowns,...
                    this.itemsWithDropdownsOnHover(nav);
                    // ... hamburger's click event,...
                    this.hamburgerOnClick(nav);
                    // ... and nav container's click event
                    this.containerOnClick(nav);
                });
        }
    
        // Adjusts the opacity of the visual scroll indicators of a nav list based on the scroll position
        indicateScrollDirection({ target }) {
            // Grab the relavent scroll information from the target,...
            const { scrollTop, scrollHeight, clientHeight } = target,
                // ... how far it's scrolled from the top,
                top = Math.round(scrollTop);
            // ... and the maximum distance of scrolling
            let max = scrollHeight - clientHeight;
    
            // Normalize the maximum distance to zero (if lower)
            if (max < 0) max = 0;
    
            // Figure out the percent scrolled from the top/bottom
            const percentFromTop = (top / max || 0).toFixed(2),
                percentFromBottom = ((max - top) / max || 0).toFixed(2);
    
            // Set the scroll top...
            target.style.setProperty(this.properties.listScrollTop, percentFromTop);
            // ... and scroll bottom CSS custom property of the list to correspond with opacity
            target.style.setProperty(
                this.properties.listScrollBottom,
                percentFromBottom
            );
        }
    
        scrollToCurrentItem(list) {
            const current = list.querySelector(`.${this.selectors.itemIsCurrent}`);
    
            if (!current) return;
    
            const { offsetTop } = current;
    
            list.scrollTop = offsetTop;
        }
    
        // Adds visual indicators that a nav list is scrollable
        indicateScrollable({ lists }) {
            // If no lists exists, do nothing else
            if (!lists.length) return;
    
            // For each list,...
            lists.forEach((list) => {
                // If the list isn't scrollable, return it as is
                if (!list.classList.contains(this.selectors.scrollable))
                    return list;
    
                // Otherwise, scroll to the current item...
                this.scrollToCurrentItem(list);
                // ... and indicate the scroll direction up front...
                this.indicateScrollDirection({ target: list });
                // ... and whenever the list is scrolled thereafter
                list[this.listener](
                    'scroll',
                    this.indicateScrollDirection.bind(this)
                );
            });
        }
    
        // Start or stop the sub navigation functionality
        subFunctionality() {
            // For each sub nav...
            this.references
                .filter(({ isSubNav }) => isSubNav)
                .forEach((nav) => {
                    this.indicateScrollable(nav);
                });
        }
    
        // Destroy the navigation functionality
        destroy() {
            // Set the run flag to false
            this.run = false;
    
            // If no container exists,...
            if (!this.references.length) {
                // ... simply delete the settings/references...
                delete this.settings;
                delete this.references;
                // ... and do nothing else
                return;
            }
    
            // Otherwse, remove core functionality of all navs...
            this.allFunctionality();
            // ... and special functionality of main...
            this.mainFunctionality();
            // ... and sub navs
            this.subFunctionality();
    
            // Finally, delete the settings/references
            delete this.settings;
            delete this.references;
        }
    
        // Initialize the navigation functionality
        initialize() {
            // Set the run flag to true
            this.run = true;
    
            // First, get all references to the navs and their lists/items
            this.getReferences();
    
            // Next, provide core functionality to all navs
            this.allFunctionality();
    
            // Finally, provide special functionality to main...
            this.mainFunctionality();
            // ... and sub navs
            this.subFunctionality();
        }
    }
    
    export default Nav;
    
  • URL: /components/raw/nav/index.js
  • Filesystem Path: components/nav/index.js
  • Size: 34.1 KB

No notes defined.