@econnect/webcomponents-library
Documentation
Styleguide
Documentation
Styleguide
  • Getting Started

    • Installation
    • Patch Notes
    • Styleguide
  • Styling

    • e-connect colors
  • UI Components

    • Form

      • Search Field
      • Form Field
      • Forms
    • Filter

      • Filter
      • Search Filter
    • Grid

      • Grid
      • Grid Row
    • Inputs

      • File Input
      • Input Checkbox
      • Input Dropdown
      • Input Date
      • Input Date Time
      • Input Date Time Local
      • Input File
      • Input Label
      • Input Multi Select
      • Input Number
      • Input Radio
      • Input Range
      • Input Select
      • Input Switch
      • Input Slider
      • Input Text
      • Input TextArea
      • Input Time
      • Input Time Range
    • Controls

      • Booleans
      • Button
      • Checkboxes
      • Date Displays
      • Dropdown Lists
      • Text Displays
    • Headers

      • e-header
    • Cards

      • e-card
    • Images

      • Icon
      • Images
      • Flag Image
      • Hamburger
    • Iframe
    • Pager
    • Settings
    • Document Validation
    • Navigation

      • Navigation
      • Navigation Menu
      • Navigation Footer
      • Navigation Button
      • Navigation Button Item
      • Navigation Search Item

Navigation Menu v1.0

The <e-navigation-menu> component is a component that can be used for .

Usage

An e-navigation-menu has attributes that must be provided,

<e-navigation-menu
  :menu=""
  :socials=""
  :isMobile=""
  @toggleEmitNavMenu=""
/>

Attributes

menu | Type: Array | required
socials | Type: Boolean | Default: false
isMobile | Type: Boolean | Default: false
@toggleEmitNavMenu | Type: Function | required

Examples

Below a few interactive examples of e-navigation-menu can be found.

Default
const menu = {
  menuItems: [
    {
      displayText: 'Highlighted Item',
      icon: ['star'],
      type: 'highlight',
      url: 'https://econnect.eu/',
      key: '1'
    },
    {
      displayText: 'Standard Item',
      icon: ['heart'],
      url: 'https://econnect.eu/',
      key: '2'
    },
    {
      displayText: 'Dropdown Item',
      icon: ['energy'],
      key: '3',
      menuItems: [
        {
          displayText: 'First item',
          url: 'https://econnect.eu/',
          key: '3.1'
        },
        {
          displayText: 'Second item',
          url: 'https://econnect.eu/',
          key: '3.2'
        }
      ]
    }
  ]
}
<e-navigation-menu
  :menu="menu"
  @toggleEmitNavMenu=""
/>
:socials='true'
const menu = {
  menuItems: [
    {
      displayText: 'Highlighted Item',
      icon: ['star'],
      type: 'highlight',
      url: 'https://econnect.eu/',
      key: '1'
    },
    {
      displayText: 'Standard Item',
      icon: ['heart'],
      url: 'https://econnect.eu/',
      key: '2'
    },
    {
      displayText: 'Dropdown Item',
      icon: ['energy'],
      key: '3',
      menuItems: [
        { 
          displayText: 'First item', 
          url: 'https://econnect.eu/', 
          key: '3.1' 
        }, 
        { 
          displayText: 'Second item', 
          url: 'https://econnect.eu/', 
          key: '3.2'
        }
      ]
    }
  ]
}
<e-navigation-menu
  :menu="menu"
  :socials="true"
  @toggleEmitNavMenu=""
/>

Source Code

e-navigation-menu.vue
<script setup lang="ts">
import { computed, ref } from 'vue';
import { RouteLocation } from 'vue-router';
import { first } from 'lodash-es';

import { EMenuData } from 'types/menu/EMenuData';
import { EMenuItem } from 'types/menu/EMenuItem';
import type { ESocials } from 'types/menu/ESocials';

import ENavigationButton from '../e-navigation-button/e-navigation-button.vue';
import ENavigationFooter from '../e-navigation-footer/e-navigation-footer.vue';
import ENavigationSearchItem from '../e-navigation-search-item/e-navigation-search-item.vue';

export type Props = {
  menu: EMenuData;
  route: RouteLocation;
  socials?: ESocials;
  isMobile?: boolean;
};

const props = withDefaults(defineProps<Props>(), {
  socials: () => {
    return [];
  },
  isMobile: false
});

const emit = defineEmits<{
  (e: 'toggle:nav-menu'): void;
}>();

const navigationMenuClasses = computed(() => {
  return {
    mobile: props.isMobile
  };
});

const openedMenuItemId = ref('');

function toggleSubMenu(menuItem: EMenuItem) {
  if (openedMenuItemId.value === menuItem?.key) {
    openedMenuItemId.value = '';
  } else {
    openedMenuItemId.value = menuItem?.key;
  }
}

const menuItems = computed(() => {
  return props.menu?.menuItems;
});
</script>

<template>
  <nav
    class="e-navigation-menu"
    :class="navigationMenuClasses"
  >
    <div
      class="content"
      role="none"
    >
      <template
        v-for="menuItem in menuItems"
        :key="menuItem?.key"
      >
        <e-navigation-search-item
          v-if="first(menuItem?.icon) === 'search.svg' && $slots.search"
          :menu="menuItem"
        >
          <template #search>
            <slot name="search" />
          </template>
        </e-navigation-search-item>
        <e-navigation-button
          v-else
          :menu-item="menuItem"
          :route="route"
          :is-opened="openedMenuItemId === menuItem?.key"
          :is-mobile="isMobile"
          :active="menuItem?.active"
          @toggle="toggleSubMenu(menuItem)"
          @toggle:nav-menu="emit('toggle:nav-menu')"
        />
      </template>
    </div>

    <e-navigation-footer
      v-if="socials"
      :socials="socials"
    />
  </nav>
</template>

<style scoped lang="scss">
.e-navigation-menu {
  max-width: 300px;
  display: flex;
  flex-direction: column;
  gap: 20px;
  margin: 0 auto;
  height: 100%;
  overflow-x: hidden;

  .content {
    display: flex;
    flex-direction: column;
    gap: 20px;
    overflow-x: hidden;
    min-height: min-content;
  }

  &.mobile {
    min-height: min-content;
    overflow-y: auto;
    max-width: 100%;
    align-items: center;
    justify-content: space-between;
    flex: 0 1 auto;
    height: auto;

    .content {
      justify-content: center;
      max-width: 300px;
    }
  }

  &:not(.mobile) {
    .content {
      flex: 0 1 auto;
    }
  }

  div:last-child:not(.content) {
    margin-top: auto;
  }
}
</style>
Last Updated:: 10/10/24, 2:56 PM
Contributors: Antony Elfferich, Roeland Krijgsman, Marcel Lommers
Prev
Navigation
Next
Navigation Footer