<div id="menu-98686-21774" class="overlay overlay--slim overlay--with-footer menu" aria-label="Menü" aria-labelledby="" data-destroy-after-close="false" data-redirect-after-close="false" data-tracking-category="hamburger_menu">
    <div class="overlay__backdrop"></div>

    <div class="overlay__overlay u-inverted" role="document">
        <div class="overlay__bar">

            <button class="overlay__close" type="button" title="Schließen">
                <svg class="icon icon--cross" viewBox="0 0 200 200" aria-hidden="true">
                    <use xlink:href="/assets/icons/icons.3bafb6df0d.svg#cross"></use>
                </svg> </button>
        </div>

        <div class="overlay__content">
            <ul class="menu__sections">

                <li class="menu__section" data-open="false">

                    <a class="menu__link" href="https://jobs.e-fellows.net/" data-layer-push="{&quot;event&quot;:&quot;nav_menu_interaction&quot;,&quot;eventCategory&quot;:&quot;hamburger_menu&quot;,&quot;eventSubcategory&quot;:&quot;clickthrough&quot;,&quot;eventSubcategory2&quot;:&quot;n_a&quot;,&quot;eventSubcategory3&quot;:&quot;level_0&quot;,&quot;eventLocation&quot;:&quot;text_link&quot;,&quot;eventInnerLocation&quot;:1,&quot;eventLabel&quot;:&quot;Jobbörse&quot;,&quot;eventTargetUrl&quot;:&quot;https:\/\/jobs.e-fellows.net\/&quot;}">
                        <span class="menu__link-text u-underline">Jobbörse</span>

                        <span class="menu__link-icon">
                            <svg class="icon icon--external-link" viewBox="0 0 200 200" aria-hidden="true">
                                <use xlink:href="/assets/icons/icons.3bafb6df0d.svg#external-link"></use>
                            </svg> </span>
                    </a>

                </li>

                <li class="menu__section" data-open="false">

                    <a class="menu__link" href="#" data-layer-push="{&quot;event&quot;:&quot;nav_menu_interaction&quot;,&quot;eventCategory&quot;:&quot;hamburger_menu&quot;,&quot;eventSubcategory&quot;:&quot;clickthrough&quot;,&quot;eventSubcategory2&quot;:&quot;n_a&quot;,&quot;eventSubcategory3&quot;:&quot;level_0&quot;,&quot;eventLocation&quot;:&quot;text_link&quot;,&quot;eventInnerLocation&quot;:2,&quot;eventLabel&quot;:&quot;Für Studierende und Berufstätige&quot;,&quot;eventTargetUrl&quot;:&quot;#&quot;}">
                        <span class="menu__link-text u-underline">Für Studierende und Berufstätige</span>

                        <span class="menu__link-icon">
                            <svg class="icon icon--arrow-right" viewBox="0 0 200 200" aria-hidden="true">
                                <use xlink:href="/assets/icons/icons.3bafb6df0d.svg#arrow-right"></use>
                            </svg> </span>
                    </a>

                </li>

                <li class="menu__section" data-open="true">

                    <div class="menu__link">
                        <span class="menu__link-text u-underline">Für Schüler</span>

                        <span class="menu__link-icon">
                            <svg class="icon icon--caret-down" viewBox="0 0 200 200" aria-hidden="true">
                                <use xlink:href="/assets/icons/icons.3bafb6df0d.svg#caret-down"></use>
                            </svg> </span>
                    </div>

                    <div class="menu__navigation">

                        <ul class="menu__items">

                            <li class="menu__item">

                                <a class="menu__link" href="#" data-layer-push="{&quot;event&quot;:&quot;nav_menu_interaction&quot;,&quot;eventCategory&quot;:&quot;hamburger_menu&quot;,&quot;eventSubcategory&quot;:&quot;clickthrough&quot;,&quot;eventSubcategory2&quot;:&quot;n_a&quot;,&quot;eventSubcategory3&quot;:&quot;level_0&quot;,&quot;eventLocation&quot;:&quot;text_link&quot;,&quot;eventInnerLocation&quot;:1,&quot;eventLabel&quot;:&quot;Für Schüler:Studien-Infotag Startschuss Abi&quot;,&quot;eventTargetUrl&quot;:&quot;#&quot;}">
                                    <span class="menu__link-text u-underline">Studien-Infotag Startschuss Abi</span>

                                    <span class="menu__link-icon">
                                        <svg class="icon icon--arrow-right" viewBox="0 0 200 200" aria-hidden="true">
                                            <use xlink:href="/assets/icons/icons.3bafb6df0d.svg#arrow-right"></use>
                                        </svg> </span>
                                </a>

                            </li>

                            <li class="menu__item">

                                <a class="menu__link" href="#" data-layer-push="{&quot;event&quot;:&quot;nav_menu_interaction&quot;,&quot;eventCategory&quot;:&quot;hamburger_menu&quot;,&quot;eventSubcategory&quot;:&quot;clickthrough&quot;,&quot;eventSubcategory2&quot;:&quot;n_a&quot;,&quot;eventSubcategory3&quot;:&quot;level_0&quot;,&quot;eventLocation&quot;:&quot;text_link&quot;,&quot;eventInnerLocation&quot;:2,&quot;eventLabel&quot;:&quot;Für Schüler:FSJ, Work and Travel, Au-pair \u0026 Co.&quot;,&quot;eventTargetUrl&quot;:&quot;#&quot;}">
                                    <span class="menu__link-text u-underline">FSJ, Work and Travel, Au-pair &amp; Co.</span>

                                    <span class="menu__link-icon">
                                        <svg class="icon icon--arrow-right" viewBox="0 0 200 200" aria-hidden="true">
                                            <use xlink:href="/assets/icons/icons.3bafb6df0d.svg#arrow-right"></use>
                                        </svg> </span>
                                </a>

                            </li>

                            <li class="menu__item">

                                <a class="menu__link" href="#" data-layer-push="{&quot;event&quot;:&quot;nav_menu_interaction&quot;,&quot;eventCategory&quot;:&quot;hamburger_menu&quot;,&quot;eventSubcategory&quot;:&quot;clickthrough&quot;,&quot;eventSubcategory2&quot;:&quot;n_a&quot;,&quot;eventSubcategory3&quot;:&quot;level_0&quot;,&quot;eventLocation&quot;:&quot;text_link&quot;,&quot;eventInnerLocation&quot;:3,&quot;eventLabel&quot;:&quot;Für Schüler:Schüler-Stipendium&quot;,&quot;eventTargetUrl&quot;:&quot;#&quot;}">
                                    <span class="menu__link-text u-underline">Schüler-Stipendium</span>

                                    <span class="menu__link-icon">
                                        <svg class="icon icon--arrow-right" viewBox="0 0 200 200" aria-hidden="true">
                                            <use xlink:href="/assets/icons/icons.3bafb6df0d.svg#arrow-right"></use>
                                        </svg> </span>
                                </a>

                            </li>
                        </ul>

                    </div>
                </li>

                <li class="menu__section" data-open="false">

                    <a class="menu__link" href="#" data-layer-push="{&quot;event&quot;:&quot;nav_menu_interaction&quot;,&quot;eventCategory&quot;:&quot;hamburger_menu&quot;,&quot;eventSubcategory&quot;:&quot;clickthrough&quot;,&quot;eventSubcategory2&quot;:&quot;n_a&quot;,&quot;eventSubcategory3&quot;:&quot;level_0&quot;,&quot;eventLocation&quot;:&quot;text_link&quot;,&quot;eventInnerLocation&quot;:4,&quot;eventLabel&quot;:&quot;Für Unternehmen und Hochschulen&quot;,&quot;eventTargetUrl&quot;:&quot;#&quot;}">
                        <span class="menu__link-text u-underline">Für Unternehmen und Hochschulen</span>

                        <span class="menu__link-icon">
                            <svg class="icon icon--arrow-right" viewBox="0 0 200 200" aria-hidden="true">
                                <use xlink:href="/assets/icons/icons.3bafb6df0d.svg#arrow-right"></use>
                            </svg> </span>
                    </a>

                </li>
            </ul>

        </div>

        <div class="overlay__footer">
            <div class="menu__footer">
                <div class="menu__footer-lang-switchter">
                    <a class="lang-switcher u-overlay-link" title="Switch to English" rel="alternate" hreflang="en" href="#" data-navigation-link="{&quot;level&quot;:0,&quot;label&quot;:&quot;Switch to English&quot;}">
                        <img class="lang-switcher__flag" src="/assets/images/en-flag.583699d9c6.svg" width="50" height="30" role="presentation" loading="lazy" alt="">
                    </a>
                </div>
            </div>

        </div>
    </div>
</div>
{% set id = id ??? html_id('menu') %}
{% set eventCategory = eventCategory ?? 'hamburger_menu' %}

{% embed '@overlay' with {
  id: id,
  open: open ?? false,
  closeUrl: closeUrl ?? false,
  label: 'Menu' | t('site'),
  slim: true,
  destroyAfterClose: false,
  componentAttrs: {
    class: 'menu',
    'data-tracking-category': eventCategory,
  },
} %}
  {% macro menu_link(link) %}
    {% set tag = link.hasSubmenu ? 'button' : (link.href|default ? 'a' : 'div') %}

    <{{ tag }} {{ html_attributes({
      class: 'menu__link',
      href: tag == 'a' ? link.href,
      target: tag == 'a' ? link.target ?? null,
      type: tag == 'button' ? 'button',
      'aria-haspopup': link.hasSubmenu ? 'true',
      'aria-expanded': link.hasSubmenu ? 'false',
      'aria-controls': link.hasSubmenu ? link.submenuId,
      'data-layer-push': tag != 'div' ? {
        event: 'nav_menu_interaction',
        eventCategory: link.eventCategory,
        eventSubcategory: link.eventSubcategory ??? (link.hasSubmenu ? 'level_down' : 'clickthrough'),
        eventSubcategory2: 'n_a',
        eventSubcategory3: "level_#{link.level}",
        eventLocation: 'text_link',
        eventInnerLocation: "#{link.index}",
        eventLabel: link.eventLabel,
        eventTargetUrl: not link.hasSubmenu ? link.href : null,
      },
    }) }}>
      <span class="menu__link-text u-underline">
        {{- link.text -}}
      </span>

      {% if link.icon|default %}
        <span class="menu__link-icon">
          {% include '@icon' with { icon: link.icon } only %}
        </span>
      {% elseif link.hasSubmenu %}
        <span class="menu__link-icon">
          {% include '@icon' with { icon: 'caret-right' } only %}
        </span>
      {% elseif link.href|default %}
        <span class="menu__link-icon">
          {% include '@icon' with { icon: link_icon(link=link.href, showInternal=true) } only %}
        </span>
      {% endif %}
    </{{ tag }}>
  {% endmacro %}

  {% macro navigation_content(navigation) %}
    {% if navigation.prevLevel|default %}
      <div class="menu__back-container">
        <button {{ html_attributes({
          class: 'menu__back',
          type: 'button',
          'aria-controls': navigation.id,
          title: 'Back to: {level}' | t('site', { level: navigation.prevLevel.text }),
          'data-layer-push': {
            event: 'nav_menu_interaction',
            eventCategory: navigation.eventCategory,
            eventSubcategory: 'level_up',
            eventSubcategory2: 'n_a',
            eventSubcategory3: "level_#{navigation.level}",
            eventLocation: 'text_link',
            eventInnerLocation: null,
            eventLabel: navigation.eventLabel,
            eventTargetUrl: null,
          },
        }) }}>
          <span class="menu__back-icon">
            {% include '@icon' with { icon: 'arrow-left' } only %}
          </span>

          <span class="menu__back-text u-underline" aria-hidden="true">
            {{- navigation.currentLevel.text -}}
          </span>
        </button>
      </div>
    {% endif %}

    <ul class="menu__items">
      {% set items = navigation.currentLevel.items %}

      {% if navigation.currentLevel.link|default %}
        {% set items = items | merge([
          navigation.currentLevel | merge({
            items: null,
            text: 'More Information' | t('site'),
          }),
        ]) %}
      {% endif %}

      {% for item in items %}
        {% set hasSubmenu = item.items | default([]) | length > 0 %}
        {% set submenuId = "submenu-#{loop.index}" | namespaceInputId(navigation.id) %}
        {% set link = item.link ?? false %}
        {% set isDivider = not link and not hasSubmenu %}

        <li class="menu__item{{ isDivider ? ' menu__item--divider' }}">
          {% if isDivider %}
            <div class="menu__divider">
              {{- item.text -}}
            </div>
          {% else %}
            {{ _self.menu_link({
              hasSubmenu: hasSubmenu,
              submenuId: submenuId,
              href: link,
              text: item.text,
              target: item.target ?? null,
              eventCategory: navigation.eventCategory,
              level: navigation.level,
              index: loop.index,
              eventLabel: navigation.eventLabel|default ? "#{navigation.eventLabel}:#{item.text}" : item.text,
            }) }}

            {% if hasSubmenu %}
              <div id="{{ submenuId }}" class="menu__submenu" hidden>
                {{ _self.navigation_content({
                  id: submenuId,
                  currentLevel: item,
                  eventCategory: navigation.eventCategory,
                  prevLevel: navigation.currentLevel,
                  level: navigation.level + 1,
                  eventLabel: "#{navigation.eventLabel}:#{item.text}",
                }) }}
              </div>
            {% endif %}
          {% endif %}
        </li>
      {% endfor %}
    </ul>
  {% endmacro %}

  {% block content %}
    {% if items|default %}
      <ul class="menu__sections">
        {% for item in items %}
          {% set hasSubmenu = item.items | default([]) | length > 0 %}
          {% set id = "item-#{loop.index}" | namespaceInputId(id) %}
          {% set submenuId = "submenu-#{loop.index}" | namespaceInputId(id) %}

          <li class="menu__section" data-open="{{ hasSubmenu ? 'true' : 'false' }}">
            {{ _self.menu_link({
              hasSubmenu: false,
              submenuId: null,
              href: not hasSubmenu ? item.link,
              text: item.text,
              target: not hasSubmenu ? item.target ?? null,
              eventCategory: eventCategory,
              eventLabel: item.text,
              level: 0,
              index: loop.index,
              icon: hasSubmenu ? 'caret-down' : null,
            }) }}

            {% if hasSubmenu %}
              <div class="menu__navigation">
                {{ _self.navigation_content({
                  id: id,
                  currentLevel: item,
                  eventCategory: eventCategory,
                  prevLevel: false,
                  level: 0,
                  eventLabel: item.text,
                }) }}
              </div>
            {% endif %}
          </li>
        {% endfor %}
      </ul>
    {% endif %}
  {% endblock %}

  {% block footer %}
    <div class="menu__footer">
      {% if langSwitcher|default %}
        <div class="menu__footer-lang-switchter">
          {% include '@lang-switcher' with langSwitcher | merge({
            attrs: {
              'class': 'u-overlay-link',
              'data-navigation-link': { level: 0, label: langSwitcher.title },
            },
          }) only %}
        </div>
      {% endif %}
    </div>
  {% endblock %}
{% endembed %}
{
  "open": true,
  "langSwitcher": {
    "link": "#",
    "title": "Switch to English",
    "language": "EN"
  },
  "items": [
    {
      "text": "Jobbörse",
      "link": "https://jobs.e-fellows.net/"
    },
    {
      "text": "Für Studierende und Berufstätige",
      "link": "#"
    },
    {
      "text": "Für Schüler",
      "items": [
        {
          "text": "Studien-Infotag Startschuss Abi",
          "link": "#"
        },
        {
          "text": "FSJ, Work and Travel, Au-pair & Co.",
          "link": "#"
        },
        {
          "text": "Schüler-Stipendium",
          "link": "#"
        }
      ]
    },
    {
      "text": "Für Unternehmen und Hochschulen",
      "link": "#"
    }
  ]
}
  • Content:
    .menu {
      --overlay-footer-height: 6.2rem;
    }
    
    .menu__sections {
      margin-inline: calc(var(--overlay-content-padding-inline) * -1);
    }
    
    .menu__section {
      --menu-link-padding-inline: var(--overlay-content-padding-inline);
      --menu-link-padding-block: 2rem;
      --menu-link-font-weight: var(--font-weight-semibold);
      --focus-outline-width: 3px;
      --focus-outline-offset: -4px;
    
      display: block;
    
      &:is([data-open='true']) {
        background-color: var(--color-midnight-offset);
      }
    
      &:is([data-open='true']) + &::before,
      & + &:is([data-open='true'])::before {
        opacity: 0;
      }
    
      & + &::before {
        background-color: var(--color-midnight-line);
        block-size: 1px;
        content: '';
        display: block;
        inline-size: calc(100% - var(--overlay-content-padding-inline) * 2);
        margin-block-start: -1px;
        margin-inline: var(--overlay-content-padding-inline);
        position: absolute;
        transition-property: opacity;
        z-index: 1;
      }
    }
    
    .menu__navigation {
      font-size: 1.8rem;
      line-height: var(--line-height-body);
      padding-block-end: 2rem;
      padding-inline-end: var(--overlay-content-padding-inline);
      padding-inline-start: calc(var(--overlay-content-padding-inline) * 1.5);
    }
    
    .menu__back {
      display: flex;
      font-weight: var(--font-weight-semibold);
      gap: 1rem;
      inline-size: 100%;
      margin-block-end: 2rem;
      padding-block: 0.5rem;
      user-select: text;
    }
    
    .menu__back-icon {
      color: var(--color-orange);
      flex-shrink: 0;
      font-size: 1.6rem;
      line-height: 0;
      padding-block: calc((1.8rem * var(--line-height-body) - 1em) / 2);
    }
    
    .menu__items {
      --menu-link-padding-inline: 0;
      --menu-link-padding-block: 0.5rem;
      --menu-link-font-weight: var(--font-weight-regular);
      --focus-outline-width: 3px;
      --focus-outline-offset: 3px;
    
      display: grid;
      row-gap: 1rem;
    }
    
    .menu__divider {
      border-block-start-color: var(--color-midnight-line);
      border-block-start-style: solid;
      border-block-start-width: 1px;
      font-size: 1.4rem;
      font-weight: var(--font-weight-semibold);
      margin-block-start: 1rem;
      padding-block-end: 0.5rem;
      padding-block-start: 2.4rem;
    }
    
    .menu__item {
      display: block;
    }
    
    .menu__link {
      align-items: flex-start;
      display: flex;
      font-weight: var(--menu-link-font-weight, var(--font-weight-regular));
      gap: 1rem;
      inline-size: 100%;
      justify-content: space-between;
      line-height: var(--line-height-body);
      padding-block: var(--menu-link-padding-block, 0);
      padding-inline: var(--menu-link-padding-inline, 0);
      user-select: text;
    }
    
    .menu__link-icon {
      color: var(--color-orange);
      flex-shrink: 0;
      font-size: 1.4rem;
      line-height: 0;
      padding-block: calc((1.8rem * var(--line-height-body) - 1em) / 2);
    }
    
    .menu__submenu {
      animation: slide-from-right var(--duration-default);
      background-color: var(--color-midnight-offset);
      inline-size: 100%;
      inset-block-end: var(--overlay-footer-height);
      inset-block-start: var(--overlay-bar-height);
      inset-inline-end: 0;
      inset-inline-start: auto;
      margin-block-start: 0;
      max-inline-size: var(--overlay-max-width);
      overflow-x: hidden;
      overflow-y: auto;
      overscroll-behavior: contain;
      padding-block: 2rem;
      padding-inline: var(--overlay-content-padding-inline);
      position: fixed;
      z-index: 3;
    }
    
    .menu__footer {
      align-items: stretch;
      block-size: 100%;
      display: flex;
      flex-grow: 1;
      margin-inline: calc(var(--overlay-content-padding-inline) * -1);
    }
    
    .menu__footer-lang-switchter {
      align-items: center;
      display: flex;
      flex-shrink: 0;
      padding-inline: var(--overlay-content-padding-inline);
      position: relative;
    }
    
  • URL: /components/raw/menu/menu.scss
  • Filesystem Path: src/components/3-organisms/menu/menu.scss
  • Size: 3.6 KB
  • Content:
    import { on } from 'delegated-events';
    import { disableBodyScroll, enableBodyScroll } from 'body-scroll-lock';
    import { createFocusTrap, FocusTrap } from 'focus-trap';
    import moveFocus from '../../../javascripts/utils/moveFocus';
    import abort from '../../../javascripts/utils/abort';
    
    const trapStack: FocusTrap[] = [];
    
    on('click', 'button.menu__link[aria-controls]', (event) => {
      const { currentTarget: $button } = event;
      let focusTrap: FocusTrap;
    
      event.preventDefault();
    
      const targetId = $button.getAttribute('aria-controls') ?? abort();
      const $target = document.getElementById(targetId) ?? abort();
      const $items = $target.querySelector<HTMLElement>('.menu__items') ?? abort();
      const $overlayBar =
        $button
          .closest<HTMLElement>('.overlay')
          ?.querySelector<HTMLElement>('.overlay__bar') ?? abort();
    
      $target.hidden = false;
      $target.scroll({ top: 0, behavior: 'instant' });
    
      $button.setAttribute('aria-expanded', 'true');
    
      const $back = $target.querySelector<HTMLButtonElement>('.menu__back');
      const $backParent = $back?.parentElement ?? abort();
    
      const onBack = (backEvent: MouseEvent) => {
        backEvent.preventDefault();
        focusTrap.deactivate();
      };
    
      focusTrap = createFocusTrap([$items, $backParent, $overlayBar], {
        clickOutsideDeactivates: false,
        allowOutsideClick: true,
        trapStack,
        initialFocus: false,
        returnFocusOnDeactivate: false,
        escapeDeactivates: false,
        onUnpause() {
          $target.scroll({ top: 0, behavior: 'instant' });
        },
        onPostActivate() {
          moveFocus($items);
          disableBodyScroll($target);
    
          $back?.addEventListener('click', onBack);
        },
        onDeactivate() {
          $button.setAttribute('aria-expanded', 'false');
          $back?.removeEventListener('click', onBack);
    
          const animation = $target.animate(
            [{ transform: 'translateX(0)' }, { transform: 'translateX(100%)' }],
            { duration: 150 },
          );
    
          animation.onfinish = () => {
            $target.hidden = true;
          };
    
          enableBodyScroll($target);
        },
        onPostDeactivate() {
          moveFocus($button);
        },
      });
    
      focusTrap.activate();
    });
    
    on('overlay:show', '.menu', (event) => {
      const { currentTarget: $overlay } = event;
      const trackingCategory = $overlay.dataset.trackingCategory ?? 'menu';
    
      window.dataLayer = window.dataLayer || [];
      window.dataLayer.push({
        event: 'nav_menu_interaction',
        eventCategory: trackingCategory,
        eventSubcategory: 'open',
        eventLabel: `${trackingCategory}_open`,
      });
    });
    
    on('overlay:hide', '.menu', () => {
      trapStack.forEach((focusTrap) => {
        focusTrap.deactivate({
          onPostDeactivate() {
            // Replace re-focus between overlay will do that.
          },
        });
      });
    });
    
  • URL: /components/raw/menu/menu.ts
  • Filesystem Path: src/components/3-organisms/menu/menu.ts
  • Size: 2.8 KB

No notes defined.