DEV Community

KarmaBlackshaw
KarmaBlackshaw

Posted on

Creating a dropdown menu using Vue3 and PopperJS

Been struggling for a while of creating a dropdown menu which auto adjusts when the element goes beyond the document's bounds.

Libraries used:

<script setup> import { createPopper } from '@popperjs/core' const popperInstance = ref(null) const popcorn = ref(null) const tooltip = ref(null) onMounted(() => { useEventListener(popcorn.value, 'click', show) onClickOutside(popcorn.value, hide) popperInstance.value = createPopper(popcorn.value, tooltip.value, { placement: 'right-start', modifiers: [ { name: 'offset', options: { offset: [0, 8] } } ] }) }) function show () { tooltip.value.setAttribute('data-show', '') popperInstance.value.update() } function hide () { tooltip.value.removeAttribute('data-show') } </script> <template> <div> <div ref="tooltip" class=" tooltip bg-neutral-900 rounded p-2 text-white text-xs w-[100px] " > <div class="arrow" data-popper-arrow ></div> <ul> <li v-for="i in 5" :key="i" class=" px-2 py-2 bg-neutral-900 hover:bg-neutral-800 rounded " > Hey </li> </ul> </div> <button ref="popcorn" class=" popcorn bg-blue-500 text-white px-3 py-2 rounded " > Add </button> </div> </template> <style lang="scss" scoped> .tooltip { display: none; } .tooltip[data-show] { display: block; } .arrow, .arrow::before { position: absolute; width: 8px; height: 8px; background: inherit; } .arrow { visibility: hidden; } .arrow::before { visibility: visible; content: ''; transform: rotate(45deg); } .tooltip[data-popper-placement^='top'] > .arrow { bottom: -4px; } .tooltip[data-popper-placement^='bottom'] > .arrow { top: -4px; } .tooltip[data-popper-placement^='left'] > .arrow { right: -4px; } .tooltip[data-popper-placement^='right'] > .arrow { left: -4px; } </style> 
Enter fullscreen mode Exit fullscreen mode

Top comments (0)