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>

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>

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>

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{label: 'label', value: 'value', disabled: 'disabled', children: 'children' }
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
NameDescription
defaultCustomize default reference
contentCustomize default content
NameDescriptionType
updateManually updates the Dropdown positionFunction
showManually show the DropdownFunction
hideManually hide the DropdownFunction
triggerRefThe trigger refernce elementHTMLElement
floatingRefThe Dropdown layer elementHTMLElement
arrowRefThe Dropdown arrow elementHTMLElement

基于 MIT 许可证发布。