megclaypool of Rootid
5/5/2020 - 1:38 AM

Menu dropdown toggle system refinement

{% include "@molecules/28-menu/_menu.twig" with {
  menu: {
    items: items,
    attributes: attributes,
    mods: ['dropdown', 'off-canvas'],
    toggle: 0
  }
} only %}
{#
/**
 * @file
 * Theme override to display a menu.
 *
 * Available variables:
 * - menu_name: The machine name of the menu.
 * - items: A nested list of menu items. Each menu item contains:
 *   - attributes: HTML attributes for the menu item.
 *   - below: The menu item child items.
 *   - title: The menu link title.
 *   - url: The menu link url, instance of \Drupal\Core\Url
 *   - localized_options: Menu link localized options.
 *   - is_expanded: TRUE if the link has visible children within the current
 *     menu tree.
 *   - is_collapsed: TRUE if the link has children within the current menu tree
 *     that are not currently visible.
 *   - in_active_trail: TRUE if the link is in the active trail.
 */
#}
{% import _self as menus %}

{#
  We call a macro which calls itself to render the full tree.
  @see http://twig.sensiolabs.org/doc/tags/macro.html
#}

{{ menus.menu_links(menu.items, menu.attributes, 0, menu.mods, menu.toggle) }}

{% macro menu_links(items, attributes, menu_level, mods, toggle) %}
  {% import _self as menus %}
  {% if items %}

    {% if menu_level == 0 %}
      {% set base = 'menu' %}
    {% else %}
      {% set base = 'sub-menu' %}
    {% endif %}

    {% embed "@atoms/20-list/_list.twig" with {
      list: {
        type: 'ul',
        base: base,
        items: items,
        mods: mods,
        menu_level: menu_level,
        attributes: attributes,
        toggle: toggle
      }
    } only %}
      {% block list_content %}
        {% for item in list.items %}
          {% include "@molecules/28-menu/_menu-item.twig" with {
            menu_item: {
              mods: [ item.below ? "has-dropdown", loop.first ? 'first',
              loop.last ? 'last', ],
              parent: list.base,
              attributes: list.attributes,
              item: item,
              menu_level: list.menu_level,
              is_expanded: item.is_expanded ? item.is_expanded : NULL,
              is_collapsed: item.is_collapsed ? item.is_collapsed : NULL,
              is_active_trail: item.is_active_trail ? item.is_active_trail : NULL,
              toggle: list.toggle
            }
          } only %}
        {% endfor %}
      {% endblock %}
    {% endembed %}
  {% endif %}
{% endmacro %}
{% import "@molecules/28-menu/_menu.twig" as menus %}

{% set mods = [] %}
{% set mods = menu_item.item.is_expanded ? mods|merge(['expanded']) : mods %}
{% set mods = menu_item.item.is_collapsed ? mods|merge(['collapsed']) : mods %}
{% set mods = menu_item.item.in_active_trail ? mods|merge(['active-trail']) : mods %}

<li {{ bem('menu-item', mods, menu_item.parent) }}>
  {{ link(menu_item.item.title, menu_item.item.url) }}
  {% if menu_item.item.below %}
    {% if menu_item.toggle == true or menu_item.toggle >= menu_item.menu_level %}
      <button class="dropdown-toggle level-{{menu_item.menu_level|number_format + 1}}">
        <span class="toggle-text visually-hidden">Show submenu</span>
        <i class="icon icon-down-dir" aria-hidden="true"></i>
      </button>
    {% endif %}

    {% set menu_level = menu_item.menu_level|number_format + 1 %}
    {{ menus.menu_links(menu_item.item.below, menu_item.attributes, menu_level, [], menu_item.toggle) }}
  {% endif %}
</li>
// this deploys the accordion functionality on the sub menu items in the offcanvas nav
// it only hides submenus proceeded with a toggle
jQuery(".menu--dropdown .dropdown-toggle+.sub-menu").hide();

jQuery(".menu--dropdown .dropdown-toggle").click(function() {
  jQuery(this).toggleClass("rotate-arrow");

  if (jQuery(this)
    .siblings(".sub-menu")
    .attr("aria-expanded") === "false" ) {
      jQuery(this)
        .siblings(".sub-menu")
        .attr("aria-expanded", "true");
    } else {
      jQuery(this)
        .siblings(".sub-menu")
        .attr("aria-expanded", "false");
    }

  jQuery(this)
    .siblings(".sub-menu")
    .toggle();

  if (jQuery(this).hasClass("rotate-arrow")) {
    jQuery(".toggle-text").text("Hide submenu");
  } else {
    jQuery(".toggle-text").text("Show submenu");
  }
});