Skip to content

A renderless Vue component that will auto detect if menu items don't fit and moves them to a separate dropdown. Also known as the Priority+ pattern.

Notifications You must be signed in to change notification settings

gijsroge/vue-responsive-menu

Repository files navigation

Vue responsive menu logo

A responsive menu build for Vue.js

A renderless Vue component that will auto detect if menu items don't fit and moves them to a separate dropdown. Also known as the Priority+ pattern.

End-to-end tests

Vue responsive menu demo

👉 Demo 👈


Install

yarn add vue-responsive-menu

Register as a Vue component

import VueResponsiveMenu from "vue-responsive-menu";

export default {
  components: {
    VueResponsiveMenu
  }
};

Pass your menu in the :nav prop

Responsive menu will expose 2 new arrays in the default prop, 1 normal menu & 1 with the excess items

<template>
  <!-- Renderless component that exposes 2 arrays based on the array you pass in the nav prop. -->
  <VueResponsiveMenu
    #default="{ menuItems, moreMenuItems}"
    :nav="mainMenu.items"
  >
    <ul>
      <!-- Default menu -->
      <li v-for="item in menuItems" :key="item.id">
        <a :href="item.href">
          {{ item.name }}
        </a>
      </li>

      <!-- More menu with the items that didn't fit -->
      <li v-if="moreMenuItems.length">
        <button type="button">
          {{ menuItems.length === 0 ? '☰' : 'more ↓' }}
        </button>
        <ul>
          <li v-for="item in moreMenuItems" :key="item.id">
            <a :href="item.href">
              {{ item.name }}
            </a>
          </li>
        </ul>
      </li>
    </ul>
  </VueResponsiveMenu>
</template>

<script>
  import VueResponsiveMenu from 'vue-responsive-menu'
  export default {
    components: {
      VueResponsiveMenu
    }
    data() {
      return {
        navigation: [
          { label: 'This', id: 1, link: '#1' },
          { label: 'is an', id: 2, link: '#2' },
          { label: 'example', id: 3, link: '#3' },
          { label: 'navigation', id: 4, link: '#4' },
          { label: 'with many', id: 5, link: '#5' },
          { label: 'many', id: 6, link: '#5' },
          { label: 'many', id: 7, link: '#5' },
          { label: 'many', id: 8, link: '#5' },
          { label: 'items', id: 9, link: '#6' }
        ]
      }
    }
  }
</script>

Props

Prop Type Default Description
:nav array<object> []
:maxCharacters number or boolean false
label string 'label' Key to read the menu item label. Only needed if you enable maxCharacters.
offset number 0 Adds x amount of pixels to the total width of menu items. This causes menu items to be moved more quickly to the more dropdown

Events

Name Payload Description
@menu-resized number current width of menu
@item-to-dropdown object Item from nav prop
@item-to-menu object Item from nav prop
@moreMenuItems array Current array of more menu items
@menuItems array Current array of menu items

Example with options

<!-- This will render max 35 characters counted from the name key in the nav array. In this case the first 5 menu items -->
<VueResponsiveMenu
  #default="{ menuItems, moreMenuItems}"
  :maxCharacters="35"
  label="name"
  :nav="mainMenu.items"
>
  <!-- ... -->
</VueResponsiveMenu>

Todo

  • Make a public example site
  • Create GIF in documentation
  • Add documentation
  • Write tests
  • Setup CI
  • Add contribution guidelines

About

A renderless Vue component that will auto detect if menu items don't fit and moves them to a separate dropdown. Also known as the Priority+ pattern.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published