Skip to content

Dropdown ​

The Dropdown component consists of a trigger and a floating dropdown menu panel. Clicking or hovering over the trigger reveals the menu panel, which typically contains a set of action options. Common use‑cases include button dropdowns, navigation menus, table header dropdowns, "more‑actions" menus and multi‑level sub‑menus. Built on top of Tooltip.

Basic Usage ​

There are two ways to use Dropdown: Use options prop to render Dropdown menu items, or use slot#menu to customize menu with <re-dropdown-menu> and <re-dropdown-item>.

vue
<template>
  <re-dropdown :options="options" @select="select">
    <re-button>
      Dropdown Options List
      <arrow-downward class="ml-5px" />
    </re-button>
  </re-dropdown>
  <re-dropdown @select="select">
    <re-button>
      Dropdown Items List
      <arrow-downward class="ml-5px" />
    </re-button>
    <template #menu>
      <re-dropdown-menu>
        <re-dropdown-item value="item1" label="item-1"></re-dropdown-item>
        <re-dropdown-item value="item2">Item 2</re-dropdown-item>
        <re-dropdown-item value="item3">Item 3</re-dropdown-item>
      </re-dropdown-menu>
    </template>
  </re-dropdown>
</template>
<script lang="ts" setup>
import {
  ReDropdown,
  ReDropdownMenu,
  ReDropdownItem,
  ReButton,
  ReMessage,
  ArrowDownward
} from 'rappel-ui'

const options = [
  { label: 'option1', value: 'option1' },
  { label: 'option2', value: 'option2' },
  { label: 'option3', value: 'option3' }
]

const select = (value: string) => {
  ReMessage.success(`You selected ${value}`)
}
</script>

Placement ​

vue
<template>
  <div class="max-w-600px mx-auto">
    <div class="flex justify-center">
      <re-dropdown placement="top-start" :options @select="select">
        <re-button>top-start</re-button>
      </re-dropdown>
      <re-dropdown placement="top" :options @select="select">
        <re-button>top</re-button>
      </re-dropdown>
      <re-dropdown placement="top-end" :options @select="select">
        <re-button>top-end</re-button>
      </re-dropdown>
    </div>
    <div class="flex justify-between">
      <div class="flex flex-col items-start">
        <re-dropdown placement="left-start" :options @select="select">
          <re-button>left-start</re-button>
        </re-dropdown>
        <re-dropdown placement="left" :options @select="select">
          <re-button class="mt-1em ml-0!">left</re-button>
        </re-dropdown>
        <re-dropdown placement="left-end" :options @select="select">
          <re-button class="mt-1em ml-0!">left-end</re-button>
        </re-dropdown>
      </div>
      <div class="flex flex-col items-end">
        <re-dropdown placement="right-start" :options @select="select">
          <re-button>right-start</re-button>
        </re-dropdown>
        <re-dropdown placement="right" :options @select="select">
          <re-button class="mt-1em ml-0!">right</re-button>
        </re-dropdown>
        <re-dropdown placement="right-end" :options @select="select">
          <re-button class="mt-1em ml-0!">right-end</re-button>
        </re-dropdown>
      </div>
    </div>
    <div class="flex justify-center">
      <re-dropdown placement="bottom-start" :options @select="select">
        <re-button>bottom-start</re-button>
      </re-dropdown>
      <re-dropdown placement="bottom" :options @select="select">
        <re-button>bottom</re-button>
      </re-dropdown>
      <re-dropdown placement="bottom-end" :options @select="select">
        <re-button>bottom-end</re-button>
      </re-dropdown>
    </div>
  </div>
</template>
<script lang="ts" setup>
import { ReDropdown, ReButton, ReMessage } from 'rappel-ui'

const options = [
  { label: 'option1', value: 'option1' },
  { label: 'option2', value: 'option2' },
  { label: 'option3', value: 'option3' }
]

const select = (value: string) => {
  ReMessage.success(`You selected ${value}`)
}
</script>

Trigger ​

Use hover 、 click 、 focus and contextmenu to display Dropdown menu by trigger attribute.

vue
<template>
  <re-dropdown :options="options" trigger="hover" @select="select">
    <re-button>
      Hover me
      <arrow-downward class="ml-5px" />
    </re-button>
  </re-dropdown>
  <re-dropdown :options="options" trigger="click" @select="select">
    <re-button>
      Click me
      <arrow-downward class="ml-5px" />
    </re-button>
  </re-dropdown>
  <re-dropdown :options="options" trigger="focus" @select="select">
    <re-button>
      Focus me
      <arrow-downward class="ml-5px" />
    </re-button>
  </re-dropdown>
  <re-dropdown :options="options" trigger="contextmenu" @select="select">
    <re-button>
      Contextmenu
      <arrow-downward class="ml-5px" />
    </re-button>
  </re-dropdown>
</template>
<script lang="ts" setup>
import { ReDropdown, ReButton, ReMessage, ArrowDownward } from 'rappel-ui'

const options = [
  { label: 'option1', value: 'option1' },
  { label: 'option2', value: 'option2' },
  { label: 'option3', value: 'option3' }
]

const select = (value: string) => {
  ReMessage.success(`You selected ${value}`)
}
</script>

Tree ​

When you need a tree dropdown menu, options should be a tree-shaped array. You can also build a tree menu manually using <re-dropdown-menu>、<re-dropdown-submenu> and <re-dropdown-item> components.

vue
<template>
  <re-dropdown :options="options" @select="select">
    <re-button>
      Dropdown Options List
      <arrow-downward class="ml-5px" />
    </re-button>
  </re-dropdown>
  <re-dropdown @select="select">
    <re-button>
      Dropdown Items List
      <arrow-downward class="ml-5px" />
    </re-button>
    <template #menu>
      <re-dropdown-menu>
        <re-dropdown-item value="Item 1" label="Item 1"></re-dropdown-item>
        <re-dropdown-item value="Item 2">Item 2</re-dropdown-item>
        <re-dropdown-submenu>
          <template #label>Item 3</template>
          <re-dropdown-item value="Item 3-1">Item 3-1</re-dropdown-item>
          <re-dropdown-item value="Item 3-2">Item 3-2</re-dropdown-item>
          <re-dropdown-submenu>
            <template #label>Item 3-3</template>
            <re-dropdown-item value="Item 3-3-1">Item 3-3-1</re-dropdown-item>
            <re-dropdown-item value="Item 3-3-2">Item 3-3-2</re-dropdown-item>
          </re-dropdown-submenu>
        </re-dropdown-submenu>
      </re-dropdown-menu>
    </template>
  </re-dropdown>
</template>
<script lang="ts" setup>
import {
  ReDropdown,
  ReDropdownMenu,
  ReDropdownSubmenu,
  ReDropdownItem,
  ReButton,
  ReMessage,
  ArrowDownward
} from 'rappel-ui'

const options = [
  {
    label: 'option1',
    value: 'option1',
    children: [
      {
        label: 'option1-1',
        value: 'option1-1'
      },
      {
        label: 'option1-2',
        value: 'option1-2',
        children: [{ label: 'option1-2-1', value: 'option1-2-1' }]
      }
    ]
  },
  { label: 'option2', value: 'option2' },
  { label: 'option3', value: 'option3' }
]

const select = (value: string) => {
  ReMessage.success(`You selected ${value}`)
}
</script>

Disabled ​

The disabled attribute specifies whether the dropdown menu is disabled, disabled the Dropdown or the Dropdown menu items.

vue
<template>
  <re-dropdown :options="options" @select="select">
    <re-button>
      Disabled Dropdown Option
      <arrow-downward class="ml-5px" />
    </re-button>
  </re-dropdown>
  <re-dropdown @select="select">
    <re-button>
      Disabled Dropdown Item
      <arrow-downward class="ml-5px" />
    </re-button>
    <template #menu>
      <re-dropdown-menu>
        <re-dropdown-item value="item1">Item 1</re-dropdown-item>
        <re-dropdown-item value="item2" disabled>Item 2</re-dropdown-item>
        <re-dropdown-item value="item3">Item 3</re-dropdown-item>
      </re-dropdown-menu>
    </template>
  </re-dropdown>
  <re-dropdown :options="treeOptions" @select="select">
    <re-button>
      Disabled Submenu Option
      <arrow-downward class="ml-5px" />
    </re-button>
  </re-dropdown>
  <re-dropdown @select="select">
    <re-button>
      Disabled Submenu Item
      <arrow-downward class="ml-5px" />
    </re-button>
    <template #menu>
      <re-dropdown-menu>
        <re-dropdown-item value="Item 1">Item 1</re-dropdown-item>
        <re-dropdown-item value="Item 2">Item 2</re-dropdown-item>
        <re-dropdown-submenu disabled>
          <template #label>Item 3</template>
          <re-dropdown-item value="Item 3-1">Item 3-1</re-dropdown-item>
          <re-dropdown-item value="Item 3-2">Item 3-2</re-dropdown-item>
        </re-dropdown-submenu>
      </re-dropdown-menu>
    </template>
  </re-dropdown>
  <re-dropdown disabled :options="options" @select="select">
    <re-button disabled>
      Disabled Dropdown
      <arrow-downward class="ml-5px" />
    </re-button>
  </re-dropdown>
</template>
<script lang="ts" setup>
import {
  ReDropdown,
  ReDropdownMenu,
  ReDropdownItem,
  ReDropdownSubmenu,
  ReButton,
  ReMessage,
  ArrowDownward
} from 'rappel-ui'

const options = [
  { label: 'option1', value: 'option1' },
  { label: 'option2', value: 'option2', disabled: true },
  { label: 'option3', value: 'option3' }
]

const treeOptions = [
  { label: 'option1', value: 'option1' },
  {
    label: 'option2',
    value: 'option2',
    disabled: true,
    children: [{ label: 'option2-1', value: 'option2-1' }]
  },
  { label: 'option3', value: 'option3' }
]

const select = (value: string) => {
  ReMessage.success(`You selected ${value}`)
}
</script>

Icon ​

Use icon prop to add an icon to the menu item. It accepts an icon name or a VNode component.

vue
<template>
  <re-dropdown :options="options" @select="select">
    <re-button>
      Dropdown Options List
      <arrow-downward class="ml-5px" />
    </re-button>
  </re-dropdown>
  <re-dropdown @select="select">
    <re-button>
      Dropdown Items List
      <arrow-downward class="ml-5px" />
    </re-button>
    <template #menu>
      <re-dropdown-menu>
        <re-dropdown-item value="item1" label="item-1" :icon="Star"></re-dropdown-item>
        <re-dropdown-item value="item2" icon="more-dot-circle-outline-horizontal">
          Item 2
        </re-dropdown-item>
        <re-dropdown-item value="item3">
          <Delete size="16" color="var(--re-color-danger-base)" class="mr-5px" />
          <span>Item 3</span>
        </re-dropdown-item>
      </re-dropdown-menu>
    </template>
  </re-dropdown>
</template>
<script lang="ts" setup>
import { ReDropdown, ReDropdownMenu, ReDropdownItem, ReButton, ReMessage } from 'rappel-ui'
import { ArrowDownward, Star, Delete } from '@rappel-ui/svg-icons'

const options = [
  {
    label: 'option1',
    value: 'option1',
    icon: 'copy',
    children: [
      { label: 'option1-1', value: 'option1-1', icon: 'check-circle' },
      { label: 'option1-2', value: 'option1-2', icon: 'delete' }
    ]
  },
  { label: 'option2', value: 'option2', icon: 'exclam' },
  { label: 'option3', value: 'option3', icon: 'more-line' }
]

const select = (value: string) => {
  ReMessage.success(`You selected ${value}`)
}
</script>
NameDescriptionTypeDefault
optionsData-driven rendering for Dropdown menu, accepts an array of menu itemsArray<OptionsItem>: interface—
item-propsField Names Mapping for optionsinterface—
close-on-selectWhether to close the dropdown menu when clicking a menu itembooleantrue
placementDropdown positionenumbottom
triggerThe trigger event nameenumhover
disabledWhether Dropdown menu is disabledboolean—
visible / v-model:visibleWhether Dropdown is visibleboolean—
offsetOffset from the reference edge. See Floating UI OffsetOptions for detailsnumber | interface10
widthDropdown widthnumber | string—
heightDropdown heightnumber | string—
max-widthDropdown max widthnumber | string—
max-heightDropdown max heightnumber | string—
themeDropdown theme'dark' |'light'light
reverse-themewhether to reverse Dropdown theme colorbooleanfalse
append-toTarget element for appending DropdowncssSelector | HTMLElementbody
teleportedWhether to teleport Dropdown to the appendTo targetbooleantrue
persistentWhether to keep the floating open on hoverbooleantrue
click-to-toggleWhether to toggle the floating on click, only trigger='click' booleantrue
floating-classCustom class for the floatingstring | object | Array —
floating-styleCustom style for the floatingstring | object | Array—
show-delayDelay(ms) before Dropdown appears , but not effective when visible is present or is-virtual or is-externalnumber0
hide-delayDelay(ms) before Dropdown disappears , but not effective when visible is present or is-virtual or is-externalnumber200
show-arrowWhether to show arrow for Dropdownbooleantrue
arrow-sizeThe arrow sizenumber8
arrow-offsetPadding between the arrow and the Dropdown edgenumber4
arrow-optionsFloating UI ArrowOptions Parametersinterface—
transitionName of Vue3 Transition componentstringdropdown
css-transitionCss of Vue3 Transition componentbooleantrue
strategyThe type of CSS position property to use'absolute' | 'fixed'absolute
css-durationDuration of Vue3 Transition component for fade in/fade outnumber300
boundaryBoundary of Floating UI DetectOverflowOptions : interfaceunionclippingAncestors
alt-boundaryAltBoundary of Floating UI DetectOverflowOptionsbooleanfalse
root-boundaryRootBoundary of Floating UI DetectOverflowOptionsunionviewport
element-contextElementContext of Floating UI DetectOverflowOptions'reference' | 'floating'floating
flip-offsetOffset from boundary before flipping, Padding of Floating UI DetectOverflowOptionsunion8
flip-optionsFloating UI FlipOptions Parametersinterface—
inline-optionsFloating UI InlineOptions Parametersinterface—
is-externalWhether external reference is enabledboolean—
external-refExternal reference targetHTMLElement—
is-virtualWhether virtual reference is enabledboolean—
virtual-refVirtual reference object for Floating UI VirtualElementinterface—
NameDescriptionParameters
selectTriggered when a menu item is clickedFunction
before-enterVue3 <Transition> event hookFunction
enterVue3 <Transition> event hookFunction
after-enterVue3 <Transition> event hookFunction
before-leaveVue3 <Transition> event hookFunction
leaveVue3 <Transition> event hookFunction
after-leaveVue3 <Transition> event hookFunction
enter-cancelledVue3 <Transition> event hookFunction
leave-cancelledVue3 <Transition> event hookFunction

OptionsItem Object or Dropdown-item Props ​

NameDescriptionTypeRequired
labelText content of the menu itemstringfalse
valueUnique identifier for the menu itemanytrue
disabledWhether the menu item is disabledbooleanfalse
childrenSubmenu items arrayArray<OptionsItem>false
has-childrenWhether the menu item has submenus, controls submenu arrow icon visibilitybooleanfalse
iconPrefix icon of the menu itemstring | Componentfalse

ItemProps ​

AttributeDescriptionTypeDefault
labelSpecify which field in the data source maps to the option labelstringlabel
valueSpecify which field in the data source maps to the option valuestringvalue
disabledSpecify which field in the data source maps to the option disabled statestringdisabled
childrenSpecify which field in the data source maps to the option childrenstringchildren
NameDescriptionTypeDefault
itemObject for dropdown-item propsinterface{ value: '' }
NameDescription
menuCustomize dropdown-menu
NameDescription
defaultCustomize dropdown-menu items
NameDescription
labelCustomize dropdown-item label text
NameDescription
defaultCustomize dropdown-item label text
iconCustomize dropdown-item prefix icon
sub-iconCustomize dropdown-submenu arrow icon
submenuCustomize the current dropdown-item submenu
NameDescriptionType
tooltipRefThe Dropdown tooltip instance elementHTMLElement

MIT License