Back to components
Components

Dropdown menu

Displays a list of selectable actions or links, commonly used for navigation or contextual actions. Uses a trigger element to display the menu.

Component

Props

Props Default Type
items — DropdownMenuItem[]
hasShadowtrueboolean
hasBordertrueboolean
triggerTrigger.CLICKTrigger
disabledfalseboolean
prefetchOnPrefetchOn.VISIBILITYPrefetchOnStrategy
positionbottom-rightDropdownPosition
positionXOffset0number
positionYOffset8number
positionClass'absolute right-0 mt-2 top-full'string
isRelativetrueboolean
shouldTeleporttrueboolean
nestedMenuGap8number
zIndex'50'string
isStickyfalseboolean

Slots

Name Description
items

Slot to insert the '<DropdownMenuItem />' components

activator

Slot to insert in activator item (eg. ActionButton)

 <template>
    <DropdownMenu
        class="min-w-[200px]"
    >
        <template #items>
            <DropdownMenuItem
                v-for="(item, index) in items"
                :key="index"
                v-bind="item"
            />
        </template>
        <template #activator>
            <ActionButton
                text="Open dropdown"
                styleType="neutral-filled"
            />
        </template>
    </DropdownMenu>
</template>

<script setup lang="ts">
const items = ref<DropdownMenuItem[]>([
    {
        text: "Item 1",
    },
    {
        text: "Item 2",
    },
    {
        text: "Item 3",
    },
    {
        text: "Item 4",
        icon: "mdi:folder-outline",
        children: [
            {
                sectionTitle: true,
                text: "Nested section",
                icon: "mdi:shape-outline",
            },
            {
                text: "Subitem 4.1",
            },
            {
                text: "Subitem 4.2",
                children: [
                    { text: "Third level item 4.2.1" },
                    { text: "Third level item 4.2.2" },
                ],
            },
        ],
    },
])
</script>
 

Components

Name Description
<DropdownMenu>

The main container that wraps all DropdownMenuItem components

<DropdownMenuItem>

Represents the single menu item.

<DropdownMenuActions>

Acts as a container for all DropdownMenuActions components. It is not included by default within the DropdownMenu component and must be manually injected when customizing the dropdown's structure.

<DropdownSectionItem>

Non-interactive section header used inside dropdown menus and dropdown selects.

Usage

items

Sets the items that will be displayed in the dropdown menu. It is an alternative to using the slot <template #items>.

It can be used while not using the <template #items> slot.

 <template>
    <DropdownMenu
        :items="exampleItems"
        class="min-w-[200px]"
    >
        <template #activator>
            <ActionButton
                text="Open dropdown"
                styleType="neutral-filled"
            />
        </template>
    </DropdownMenu>
</template>

<script setup lang="ts">
const exampleItems = ref<DropdownMenuItem[]>([
    {
        text: "Item 1",
    },
    {
        text: "Item 2",
    },
    {
        text: "Item 3",
    },
    {
        text: "Item 4",
        icon: "mdi:folder-outline",
        children: [
            {
                sectionTitle: true,
                text: "Nested section",
                icon: "mdi:shape-outline",
            },
            {
                text: "Subitem 4.1",
            },
            {
                text: "Subitem 4.2",
                children: [
                    { text: "Third level item 4.2.1" },
                    { text: "Third level item 4.2.2" },
                ],
            },
        ],
    },
])
</script>
 

TypeScript interface

 interface DropdownMenuItem {
    actionType?: DropdownActionType
    sectionTitle?: boolean
    text?: string
    icon?: any
    size?: DropdownItemSize
    type?: DropdownItemType
    checked?: boolean
    steps?: StepSwitchOption[]
    stepValue?: string | number
    userDisplayName?: string
    userProfileImg?: string
    imgUrl?: string
    alt?: string
    helpText?: string
    to?: string
    isExternal?: boolean
    hasSeparator?: boolean
    disabled?: boolean
    callback?: (checked?: boolean) => void
    stepCallback?: (value: string | number) => void
    children?: DropdownMenuItem[]
}
 

Nested Items: Supports contextual nested dropdown menus up to 3 levels. Nested items are only available when using the :items prop with the fallback rendering mode. Items with children will automatically render as ACTION items (not links) with a right chevron indicator.

hasShadow

Activates a dropdown shadow on the menu.

 <template>
    <DropdownMenu
        hasShadow
    >
        ....
    </DropdownMenu>
</template>
 
  • Type: boolean
  • Default: true

hasBorder

Activates a border on the menu.

 <template>
    <DropdownMenu
        hasBorder
    >
        ....
    </DropdownMenu>
</template>
 
  • Type: boolean
  • Default: true

trigger

Controls how the dropdown is opened from the activator.

 <template>
    <DropdownMenu
        :trigger="Trigger.HOVER"
    >
        ....
    </DropdownMenu>
</template>
 
  • Type: Trigger
  • Default: Trigger.CLICK

Options

Value Description
CLICK

Opens and closes the dropdown on activator click.

HOVER

Opens the dropdown on hover and closes when pointer leaves activator/dropdown.

disabled

Disables the dropdown activator behavior. When true, click and hover triggers will not open the menu.

 <template>
    <DropdownMenu
        :disabled="true"
    >
        ....
    </DropdownMenu>
</template>
 
  • Type: boolean
  • Default: false

prefetchOn

Controls when dropdown item route targets should be prefetched. It uses either the PrefetchOnStrategy type or the PrefetchOn enum.

 <template>
    <DropdownMenu
        :items="exampleItems"
        :prefetchOn="PrefetchOn.INTERACTION"
    />
</template>
 
  • Type: PrefetchOnStrategy
  • Default: PrefetchOn.VISIBILITY

Options

Value Description
VISIBILITY

Prefetches routes based on visibility strategy.

INTERACTION

Prefetches routes when users hover or focus a dropdown item with a route target.

You can also pass an object strategy:

 {
    visibility: true,
    interaction: true,
}
 

position

Sets the position of the dropdown menu relative to its activator. Uses the DropdownPosition enum.

 <template>
    <DropdownMenu
        :position="DropdownPosition.BOTTOM_RIGHT"
    >
        ....
    </DropdownMenu>
</template>
 
  • Type: DropdownPosition
  • Default: DropdownPosition.BOTTOM_RIGHT

Options

Value Description
TOP_LEFT

Aligns the menu above and to the left of the activator.

TOP_RIGHT

Aligns the menu above and to the right of the activator.

BOTTOM_LEFT

Places the menu below and left-aligned with the activator.

BOTTOM_RIGHT

Places the menu below and right-aligned with the activator.

LEFT_TOP

Displays the menu to the left of the activator, aligned to its top edge.

LEFT_BOTTOM

Displays the menu to the left of the activator, aligned to its bottom edge.

RIGHT_TOP

Displays the menu to the right of the activator, aligned to its top edge.

RIGHT_BOTTOM

Displays the menu to the right of the activator, aligned to its bottom edge.

positionXOffset

Sets the horizontal offset of the dropdown menu relative to its activator. Positive values move the menu to the right, while negative values move it to the left.

 <template>
    <DropdownMenu
        positionXOffset="10"
    >
        ....
    </DropdownMenu>
</template>
 
  • Type: number | string
  • Default: 0

positionYOffset

Sets the vertical offset of the dropdown menu relative to its activator. Positive values move the menu down, while negative values move it up.

 <template>
    <DropdownMenu
        positionYOffset="10"
    >
        ....
    </DropdownMenu>
</template>
 
  • Type: number | string
  • Default: 8

positionClass

Applies Tailwind classes to control the dropdown menu's placement relative to its activator. Useful for fine-tuning alignment, spacing, or offset beyond default positioning.

 <template>
    <DropdownMenu
        positionClass="absolute right-0 mt-2 top-full"
    >
        ....
    </DropdownMenu>
</template>
 
  • Type: string

isRelative

Sets the dropdown menu wrapper as the relative element. In case relative is false, the dropdown menu will be positioned absolutely or will try to find the next parent relative element.

 <template>
    <DropdownMenu
        isRelative
    >
        ....
    </DropdownMenu>
</template>
 
  • Type: boolean
  • Default: true

shouldTeleport

Determines whether the dropdown menu should be teleported to the end of the document body. This is useful for avoiding overflow issues within containers that have restricted dimensions or overflow settings.

 <template>
    <DropdownMenu
        shouldTeleport="false"
    >
        ....
    </DropdownMenu>
</template>
 
  • Type: boolean
  • Default: true

nestedMenuGap

Sets the horizontal gap (in pixels) between a parent dropdown panel and its nested child panel.

 <template>
    <DropdownMenu
        :items="exampleItems"
        :nestedMenuGap="8"
    />
</template>
 
  • Type: number
  • Default: 8

zIndex

Sets the CSS z-index property for the dropdown menu, controlling its stacking order relative to other elements on the page.

 <template>
    <DropdownMenu
        zIndex="50"
    >
        ....
    </DropdownMenu>
</template>
 
  • Type: string
  • Default: '50'

isSticky

When true, the teleported dropdown panel uses position: fixed instead of position: absolute, anchoring it to the viewport rather than the document. Use this when the activator lives inside a sticky container (e.g. a sticky header) so the panel stays correctly positioned as the user scrolls.

 <template>
    <DropdownMenu
        isSticky
    >
        ....
    </DropdownMenu>
</template>
 
  • Type: boolean
  • Default: false

<DropdownMenuItem> represents an individual item within the dropdown menu. It supports multiple visual and functional types, such as text, icons, user profiles, and images, making it flexible for various use cases like navigation, actions, or exporting data.

Props

Props Default Type
actionTypeLINKDropdownActionType
textMenu item textstring
iconmdi:helpstring
sizeMDDropdownItemSize
typeTEXTDropdownItemType
checkedfalseboolean
steps[]StepSwitchOption[]
stepValue — string | number
userDisplayNameTest userstring
userProfileImg — string
imgUrl — string
altMenu item imagestring
helpText — string
to/string
isExternalfalseboolean
hasSeparatorfalseboolean
hasNestedLevelsfalseboolean
disabledfalseboolean
prefetchOnPrefetchOn.VISIBILITYPrefetchOnStrategy

actionType

Sets the action type for the menu item. Uses the DropdownActionType enum.

 <template>
    <DropdownMenuItem
        actionType="action"
    >
        ....
    </DropdownMenuItem>
</template>
 
  • Type: DropdownActionType
  • Default: 'LINK'

text

Sets the text content of the menu item.

 <template>
    <DropdownMenuItem
        text="Menu item text"
    >
        ....
    </DropdownMenuItem>
</template>
 
  • Type: string
  • Default: 'Menu item text'

icon

Sets the icon to be displayed in the menu item.

 <template>
    <DropdownMenuItem
        icon="mdi:help"
    >
        ....
    </DropdownMenuItem>
</template>
 
  • Type: string
  • Default: 'mdi:help'

size

Sets the size of the menu item. Uses the DropdownItemSize enum.

 <template>
    <DropdownMenuItem
        size="DropdownItemSize.LG"
    >
        ....
    </DropdownMenuItem>
</template>
 
  • Type: DropdownItemSize
  • Default: 'MD'

type

Sets the type of the menu item. Uses the DropdownItemType enum.

 <template>
    <DropdownMenuItem
        type="DropdownItemType.TEXT"
    >
        ....
    </DropdownMenuItem>
</template>
 
  • Type: DropdownItemType
  • Default: 'TEXT'

Options

Value Description
TEXT

Displays plain text.

DANGER_TEXT

Displays text styled to indicate a destructive action.

ICON

Displays an icon alongside the text.

DANGER_ICON

Displays an icon styled to indicate a destructive action, alongside the text.

USER

Displays a user avatar and display name instead of plain text.

IMAGE

Displays an image alongside the text.

CHECKBOX

Displays a non-interactive Checkbox reflecting the checked prop, aligned to the end of the item.

SWITCH

Displays a non-interactive Switch reflecting the checked prop, aligned to the end of the item.

CHECK

Displays a check icon reflecting the checked prop, aligned to the end of the item, when checked is true.

STEP_SWITCH

Displays an interactive StepSwitch built from the steps prop and reflecting the stepValue prop, aligned to the end of the item.

ICON_CHECKBOX

Displays a leading icon together with a non-interactive Checkbox reflecting the checked prop, aligned to the end of the item.

ICON_SWITCH

Displays a leading icon together with a non-interactive Switch reflecting the checked prop, aligned to the end of the item.

ICON_CHECK

Displays a leading icon together with a check icon reflecting the checked prop, aligned to the end of the item, when checked is true.

ICON_STEP_SWITCH

Displays a leading icon together with an interactive StepSwitch built from the steps prop and reflecting the stepValue prop, aligned to the end of the item.

checked

Sets the checked state of the control rendered when type is DropdownItemType.CHECKBOX, DropdownItemType.SWITCH, DropdownItemType.CHECK, DropdownItemType.ICON_CHECKBOX, DropdownItemType.ICON_SWITCH, or DropdownItemType.ICON_CHECK. Has no effect for other types.

Clicking anywhere on the menu item toggles the state automatically: it emits click and update:checked with the new boolean value, and, unlike other item types, does not close the dropdown, so multiple options can be toggled in the same session. Use v-model:checked for two-way binding, or handle update:checked manually.

 <template>
    <DropdownMenuItem
        type="DropdownItemType.CHECKBOX"
        text="Show hidden files"
        v-model:checked="showHiddenFiles"
    />
</template>
<script setup lang="ts">
const showHiddenFiles = ref(false)
</script>
 

When using the items prop instead, the toggled value is passed as the first argument to the item's callback:

 <template>
    <DropdownMenu :items="items" />
</template>
<script setup lang="ts">
const showHiddenFiles = ref(false)

const items = computed<DropdownMenuItem[]>(() => [
    {
        text: 'Show hidden files',
        type: DropdownItemType.CHECKBOX,
        checked: showHiddenFiles.value,
        callback: (checked) => { showHiddenFiles.value = checked ?? false },
    },
])
</script>
 
  • Type: boolean
  • Default: false

steps

Sets the steps of the StepSwitch rendered when type is DropdownItemType.STEP_SWITCH or DropdownItemType.ICON_STEP_SWITCH. Has no effect for other types. See StepSwitch for the available options, such as the recommended maximum number of steps.

 <template>
    <DropdownMenuItem
        :type="DropdownItemType.STEP_SWITCH"
        text="Effort"
        :steps="steps"
        v-model:stepValue="effort"
    />
</template>
<script setup lang="ts">
const steps: StepSwitchOption[] = [
    { value: 'low', label: 'Low' },
    { value: 'medium', label: 'Medium' },
    { value: 'high', label: 'High' },
]
const effort = ref<string | number>('medium')
</script>
 

TypeScript interface

 interface StepSwitchOption {
    value: string | number
    label?: string
}
 
  • Type: StepSwitchOption[]
  • Default: []

stepValue

Sets the selected step, by its value, of the StepSwitch rendered when type is DropdownItemType.STEP_SWITCH or DropdownItemType.ICON_STEP_SWITCH. Has no effect for other types.

Changing the step through the StepSwitch emits update:stepValue with the value of the new step. Unlike other item types, clicking the rest of the item does nothing and the dropdown is not closed. Use v-model:stepValue for two-way binding, or handle update:stepValue manually.

When using the items prop instead, the selected value is passed to the item's stepCallback:

 <template>
    <DropdownMenu :items="items" />
</template>
<script setup lang="ts">
const effort = ref<string | number>('medium')

const items = computed<DropdownMenuItem[]>(() => [
    {
        text: 'Effort',
        type: DropdownItemType.STEP_SWITCH,
        steps: [
            { value: 'low', label: 'Low' },
            { value: 'medium', label: 'Medium' },
            { value: 'high', label: 'High' },
        ],
        stepValue: effort.value,
        stepCallback: (value) => { effort.value = value },
    },
])
</script>
 
  • Type: string | number

userDisplayName

Sets the userDisplayName of the user profile.

 <template>
    <DropdownMenuItem
        userDisplayName="Test user"
    >
        ....
    </DropdownMenuItem>
</template>
 
  • Type: string
  • Default: 'Test user'

userProfileImg

Sets the URL of the user profile image.

 <template>
    <DropdownMenuItem
        userProfileImg="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80"
    >
        ....
    </DropdownMenuItem>
</template>
 
  • Type: string

imgUrl

Sets the URL of the image.

 <template>
    <DropdownMenuItem
        imgUrl="https://www.wheeliebinstorage.co.uk/wp-content/uploads/2025/01/Small-Space-Garden-Ideas.jpg"
    >
        ....
    </DropdownMenuItem>
</template>
 
  • Type: string

alt

Sets the alternative text for the image.

 <template>
    <DropdownMenuItem
        alt="Menu item image"
    >
        ....
    </DropdownMenuItem>
</template>
 
  • Type: string
  • Default: 'Menu item image'

helpText

Sets the help text for the menu item.

 <template>
    <DropdownMenuItem
        helpText="Help text"
    >
        ....
    </DropdownMenuItem>
</template>
 
  • Type: string

to

Sets the target URL for the menu item.

 <template>
    <DropdownMenuItem
        to="/"
    >
        ....
    </DropdownMenuItem>
</template>
 
  • Type: string
  • Default: '/'

isExternal

Sets whether the menu item is external or not.

 <template>
    <DropdownMenuItem
        isExternal
    >
        ....
    </DropdownMenuItem>
</template>
 
  • Type: boolean
  • Default: false

hasSeparator

Adds a separator line below the menu item.

 <template>
    <DropdownMenuItem
        hasSeparator
    >
        ....
    </DropdownMenuItem>
</template>
 
  • Type: boolean
  • Default: false

hasNestedLevels

Shows a right chevron indicator for items that open nested levels. It is used by DropdownMenu fallback rendering for contextual menus.

 <template>
    <DropdownMenuItem
        text="Has nested levels"
        hasNestedLevels
    />
</template>
 
  • Type: boolean
  • Default: false

prefetchOn

Controls when the dropdown menu item route target should be prefetched. It uses either the PrefetchOnStrategy type or the PrefetchOn enum.

 <template>
    <DropdownMenuItem
        text="Profile"
        to="/profile"
        :prefetchOn="PrefetchOn.INTERACTION"
    />
</template>
 
  • Type: PrefetchOnStrategy
  • Default: PrefetchOn.VISIBILITY

Options

Value Description
VISIBILITY

Prefetches routes based on visibility strategy.

INTERACTION

Prefetches routes when users hover or focus the item.

You can also pass an object strategy:

 {
    visibility: true,
    interaction: true,
}
 

disabled

Disables the menu item interaction and applies disabled visual styles.

 <template>
    <DropdownMenuItem
        text="Disabled item"
        :disabled="true"
    />
</template>
 
  • Type: boolean
  • Default: false