Dropdown Position
Default
With the default CSS, Vs Vue3 Select uses absolute positioning to render the dropdown menu. The root .v-select
container (the components $el
) is used as the relative
parent for the dropdown. The dropdown will be displayed below the $el
regardless of the available space.
This works for most cases, but you might run into issues placing into a modal or near the bottom of the viewport. If you need more fine grain control, you can use calculated positioning.
Calculated
If you want more control over how the dropdown is rendered, or if you're running into z-index issues, you may use the appendToBody
boolean prop. When enabled, Vs Vue3 Select will append the dropdown to the document, outside of the .v-select
container, and position it with Javascript.
When appendToBody
is true, the positioning will be handled by the calculatePosition
prop. This function is responsible for setting top/left absolute positioning values for the dropdown. The default implementation places the dropdown in the same position that it would normally appear.
Popper.js Integration
Popper.js is an awesome, 3kb utility for calculating positions of just about any DOM element relative to another.
By using the appendToBody
and calculatePosition
props, we're able to integrate directly with popper to calculate positioning for us.
Check out the Popper Docs to see the full modifiers
API being used below.
<script>
import countries from '../data/countries'
import {createPopper} from '@popperjs/core'
export default {
data: () => ({ countries, placement: 'top' }),
methods: {
withPopper(dropdownList, component, { width }) {
/**
* We need to explicitly define the dropdown width since
* it is usually inherited from the parent with CSS.
*/
dropdownList.style.width = width
/**
* Here we position the dropdownList relative to the $refs.toggle Element.
*
* The 'offset' modifier aligns the dropdown so that the $refs.toggle and
* the dropdownList overlap by 1 pixel.
*
* The 'toggleClass' modifier adds a 'drop-up' class to the Vue Select
* wrapper so that we can set some styles for when the dropdown is placed
* above.
*/
const popper = createPopper(component.$refs.toggle, dropdownList, {
placement: this.placement,
modifiers: [
{
name: 'offset',
options: {
offset: [0, -1],
},
},
{
name: 'toggleClass',
enabled: true,
phase: 'write',
fn({ state }) {
component.$el.classList.toggle(
'drop-up',
state.placement === 'top'
)
},
},
],
})
/**
* To prevent memory leaks Popper needs to be destroyed.
* If you return function, it will be called just before dropdown is removed from DOM.
*/
return () => popper.destroy()
},
},
}
</script>