Skip to content

Dropdown

The Dropdown component is highly versatile and can be used in various ways, such as for displaying lists as contextual overlays, as a quick menu, or as a selectable list of content options.

Unlike native select elements, the dropdown input allows you to customize both its appearance and behavior. The component implements both the W3C ARIA APG Combobox Pattern as well as the W3C ARIA APG Menu Button Pattern, depending on whether the options are selectable.

Examples

Base (Menu)

By default the dropdown will be a simple unselectable menu using the ARIA: menu role . A menu generally represents a list of actions or functions that the user can invoke.

When a user clicks an option in a menu that has been opened, the menu usually closes. This can be changed with the keepOpen property. When a menu opens, keyboard focus can be placed on the first menu item using the keepFirst property.

Triggers

The trigger can be defined by placing any element in the trigger template slot. To open the dropdown, the component can detect several different interaction variants, such as openOnHover or openOnContextmenu to only open on right click instead of left click. By default, only openOnClick is set.

The action that close the component can also be customised using the closeOnOutside and closeOnScroll properties.

Adding the teleport prop will move the dropdown menu to the referenced DOM location instead.

Options

Instead of using the <o-dropdown-item> component directly inside the default template slot, an options prop can be defined, which can be used to specify the options programmatically. It accepts several different value formats:

  • An array of primitives ['A', 'B', 'C']
  • An object literal with key-value pairs { a: 'A', b: 'B', c: 'C' }
  • An array of objects where each object represent an item
  • An array of grouped items where each group object has its own options property

TypeScript

The options property type is defined by the DropdownOptions type.

Array of primitives

The simplest way to provide options is an array of primitives like strings or numbers, where the primitive will be used for both the string casted label representation and the value of the option.

Key-Value pair object

You may also provide the options prop where the keys are values and the values of each property are the labels.

Array of objects

The most flexible way to define options is to provide an array of objects. The object has the same properties as the <o-dropdown-item> component.

Grouped options

You can also use the array of objects syntax to create grouped options, wrapping each group of options in an object with a label and an options property. The object has the same properties as the <o-dropdown-item> component.

Selectable (Combobox)

The component can be configured to have the options as a selectable list by adding the selectable property. This applies the ARIA: combobox role to the root element and changes the menu to an ARIA: listbox role . The combobox role identifies an element as either an input or a button that controls another element, that can dynamically pop up to help the user set a value.

By default only one option can be selected and the selected option will be refereced by the modelValue property. Adding the multiple property will change the modelValue to an array of selected options.

Scrollable

When having to many options, consider adding the scrollable property, which allows the options container to remain at a fixed height. The max-height property can be used to define the max container height.

The content can be opened in an modal mode either for mobile or desktop only, or for both, by adding the mobile-modal and desktop-modal properties.

Position

The direction in which the dropdown menu opens can be changed by the position property. By default, the direction is automatically calculated from the distance to the edges of the window. Adding the teleport prop additionally will move the dropdown menu to the referenced DOM location instead.

Dropdowns are very versatile, can used as a quick menu or even like a select for discoverable content.

html
<o-dropdown></o-dropdown>

Props

Prop nameDescriptionTypeValuesDefault
activeThe active state of the dropdown, use v-model:active to make it two-way bindingboolean-false
animationCustom animation (transition name)string-
From config:
dropdown: {
  animation: "fade"
}
ariaLabelAccessibility aria-label to be passed to the trigger element - usefull if selectablestring-
clipScrollSet true to remove the body scrollbar.
When false, a non-scrollable scrollbar will be kept to avoid moving the background,
but will set the body to a fixed position, which may break some layouts.
boolean-
From config:
dropdown: {
  clipScroll: false
}
closeOnOutsideClose Dropdown when clicked outsideboolean-
From config:
dropdown: {
  closeOnOutside: true
}
closeOnScrollClose Dropdown when page get scrolledboolean-
From config:
dropdown: {
  closeOnScroll: false
}
delayDropdown delay before it appears (number in ms)number-
desktopModalDropdown content (items) are shown into a modal on desktopboolean-
From config:
dropdown: {
  desktopModal: false
}
disabledInteraction is disabledboolean-false
expandedDropdown will be expanded (full-width)boolean-false
inline
deprecated - since 0.13.0, use the OListbox component instead
Menu content (items) are shown inline, trigger is removed
boolean-false
itemTagDropdown item tag nameDynamicComponent-
From config:
dropdown: {
  itemTag: "div"
}
keepFirstThe first option will always be pre-selected (easier to just hit enter or tab)boolean-
From config:
dropdown: {
  keepFirst: false
}
keepOpenKeep dropdown list open when item get selectedboolean-
From config:
dropdown: {
  keepOpen: false
}
labelTrigger label, unnecessary when trigger slot is usedstring-
labelledbyEnsures that each input has an accessible name.string-
maxHeightMax height of dropdown contentNumberish-
From config:
dropdown: {
  maxHeight: 200
}
menuIdHTML element Id of the dropdown menu elementstring-useId()
menuTagDropdown menu tag nameDynamicComponent-
From config:
dropdown: {
  menuTag: "div"
}
mobileBreakpointMobile breakpoint as max-width valuestring-
From config:
dropdown: {
  mobileBreakpoint: undefined
}
mobileModalDropdown content (items) are shown into a modal on mobileboolean-
From config:
dropdown: {
  mobileModal: true
}
v-modelThe selected option value, use v-model to make it two-way bindingValueType<unknown, IsMultiple>-
multipleAllows multiple selections - converts the modelValue into an arrayIsMultiple-
openOnClickShow when clicked on the triggerboolean-
From config:
tooltip: {
  openOnClick: true
}
openOnContextmenuShow when right clicked on the triggerboolean-
From config:
tooltip: {
  openOnContextmenu: false
}
openOnFocusShow when trigger get focusedboolean-
From config:
tooltip: {
  openOnFocus: false
}
openOnHoverShow when hover over the triggerboolean-
From config:
tooltip: {
  openOnHover: false
}
optionsDropdown options, unnecessary when default slot is usedDropdownOptions<unknown>-
overrideOverride existing theme classes completelyboolean-
positionPosition of the dropdown relative to the trigger"auto" | "bottom-left" | "bottom-right" | "bottom" | "left" | "right" | "top-left" | "top-right" | "top"auto, top, bottom, left, right, top-right, top-left, bottom-left, bottom-right
From config:
dropdown: {
  position: "bottom-left"
}
scrollableMenu content will be scrollableboolean-false
selectOnCloseSelect current focused item when closedboolean-
From config:
dropdown: {
  selectOnClose: false
}
selectOnFocusSelect current focused item when focusedboolean-
From config:
dropdown: {
  selectOnFocus: false
}
selectableEnables item selectionboolean-false
teleportAppend the component to another part of the DOM.
Set true to append the component to the body.
In addition, any CSS selector string or an actual DOM node can be used.
boolean | object | string-
From config:
dropdown: {
  teleport: false
}
triggerTagDropdown trigger tag nameDynamicComponent-
From config:
dropdown: {
  triggerTag: "div"
}

Events

Event namePropertiesDescription
update:model-valuevalue unknown | unknown[] - updated modelValue propmodelValue prop two-way binding
update:activevalue boolean - updated active propactive prop two-way binding
selectvalue unknown - selected valueon select event - fired before update:modelValue
changevalue unknown | unknown[] - selected value
openevent Event - native eventon active state changes to true
closeevent Event - native eventon active state changes to false
scroll-startthe list inside the dropdown reached the start
scroll-endthe list inside the dropdown reached it's end

Slots

NameDescriptionBindings
triggerOverride the trigger element, default is label propactive boolean - dropdown active state
value unknown | unknown[] - the selected value
toggle (event: Event): void - toggle dropdown active state
beforeDefine extra o-dropdown-item components here, even if you have some options defined by proptoggle (): void - toggle dropdown active state
defaultDefine the dropdown items heretoggle (): void - toggle dropdown active state
groupOverride the option groupgroup object - options group item
optionOverride the label, default is label propoption object - option item
emptyDefine the content to show if the list is emptytoggle (): void - toggle dropdown active state
afterDefine extra o-dropdown-item components here, even if you have some options defined by proptoggle (): void - toggle dropdown active state

An option item used by the dropdown component.

html
<o-dropdown-item></o-dropdown-item>

Props

Prop nameDescriptionTypeValuesDefault
clickableItem is clickable and emit an eventboolean-true
disabledItem is disabledboolean-false
hiddenDefine whether the item is visible or notboolean-false
labelItem label, unnecessary when default slot is usedstring-
overrideOverride existing theme classes completelyboolean-
tagDropdown item tag nameDynamicComponent-
valueItem value (it will be used as the v-model of the wrapper component) - default is an uuidstring|number|object-useId()

Events

Event namePropertiesDescription
clickvalue unknown - value prop data
event event - native event
onclick event

Slots

NameDescriptionBindings
defaultOverride the label, default is label prop

Class Inspector

Classes applied to the element:
Want to know how does the Class Inspector work?
Class propDescriptionPropsSuffixes
rootClass
Class of the root element.
mobileClass
Class of the root element when on mobile.
👉 Switch to mobile view to see it in action!
modalClass
Class of the root element when shown as modal.
mobileModal
desktopModal
teleportClass
Class of the root element when teleported.
teleport
disabledClass
Class of the root element when disabled.
disabled
inlineClass
Class of the root element when inlined.
inline
expandedClass
Class of the root element when expanded.
expanded
activeClass
Class of the root element when active or inline.
active
inline
hoverableClass
Class of the root element when trigger is hoverable.
openOnHover
positionClass
Class of the root element with postion.
positionauto
top
bottom
left
right
top-right
top-left
bottom-left
bottom-right
auto
top
bottom
left
right
top-right
top-left
bottom-left
bottom-right
triggerClass
Class of the trigger element.
overlayClass
Class of the overlay element when shown as modal.
mobileModal
desktopModal
menuClass
Class of the menu element.
menuActiveClass
Class of the menu element when active or inline.
inline
active
menuPositionClass
Class of the menu element with position.
positionauto
top
bottom
left
right
top-right
top-left
bottom-left
bottom-right
auto
top
bottom
left
right
top-right
top-left
bottom-left
bottom-right
itemClass
Class of the item element.
itemSelectedClass
Class of the item element when selected.
itemDisabledClass
Class of the item element when disabled.
disabled
itemClickableClass
Class of the item element when clickable.
clickable
itemFocusedClass
Class of the item element when focused.
scrollClipClass
Class of the body when is open and scroll is clipped.
clipScroll
scrollKeepClass
Class of the body when is open and scroll is keeped.
clipScroll

Sass Variables

Current theme ➜ Oruga

SASS VariableDefault
$dropdown-disabled-opacityh.useVar("control-disabled-opacity")
$dropdown-menu-zindexmap.get(vars.$zindex, "dropdown")
$dropdown-menu-spacer0px
$dropdown-menu-paddingh.useVar("control-spacer") 0
$dropdown-menu-box-shadow0 0.5em 1em -0.125em rgba(10, 10, 10, 0.1), 0 0 0 1px rgba(10, 10, 10, 0.02)
$dropdown-menu-background-colorh.useVar("control-brackground-color")
$dropdown-menu-border-colorh.useVar("control-border-color")
$dropdown-menu-border-stylesolid
$dropdown-menu-border-widthh.useVar("control-border-width")
$dropdown-menu-border-radiush.useVar("border-radius")
$dropdown-item-padding0.25rem 1rem
$dropdown-item-colorh.useVar("font-color")
$dropdown-item-font-sizeh.useVar("font-size")
$dropdown-item-font-weighth.useVar("font-weight")
$dropdown-item-line-heighth.useVar("line-height")
$dropdown-item-background-colortransparent
$dropdown-item-active-colorh.useVar("primary-invert")
$dropdown-item-active-background-colorh.useVar("primary")
$dropdown-item-hover-background-colorh.useVar("grey-lighter")
$dropdown-item-hover-colorh.useVar("font-color")
$dropdown-modal-zindexmap.get(vars.$zindex, "modal")
$dropdown-modal-max-heightmin(50vh, calc(100vh - 160px))
$dropdown-modal-max-widthmin(50vw, calc(100vw - 160px))
$dropdown-modal-min-widthmin(80vw, 400px)
$dropdown-overlay-background-colorh.useVar( "overlay-background-color")
$dropdown-overlay-zindexmap.get(vars.$zindex, "overlay")

See ➜ 📄 SCSS file

Current theme ➜ Bulma

SASS VariableDefault
$dropdown-content-max-height200px
$dropdown-disabled-opacity0.5
$dropdown-gap0px
$dropdown-z40
$dropdown-mobile-breakpointiv.$desktop
$dropdown-background-background-colorhsla( #{css.getVar("scheme-h")}, #{css.getVar("scheme-s")}, #{css.getVar("scheme-invert-l")}, 0.86)
$dropdown-modal-width75%
$dropdown-modal-min-width25%
$dropdown-modal-max-widthcalc(100vw - 40px)

See ➜ 📄 SCSS file

Current theme ➜ Bootstrap

SASS VariableDefault
$dropdown-modal-menu-zindex$zindex-modal
$dropdown-modal-backdrop-zindex$zindex-modal-backdrop
$dropdown-modal-width75%
$dropdown-modal-min-width25%
$dropdown-modal-max-widthcalc(100vw - 40px)

See ➜ 📄 SCSS file

Released under the MIT License.