Skip to content

Dropdown Menu ​

A neo-brutalist style dropdown menu built on reka-ui's DropdownMenu primitive, supporting menu items, checkboxes, radio groups, submenus, and keyboard shortcuts.

Demo ​

Preview

Installation ​

pnpm dlx brutx-vue@latest add dropdown-menu

Usage ​

Basic Usage ​

vue
<script setup>
import {
    DropdownMenu,
    DropdownMenuTrigger,
    DropdownMenuContent,
    DropdownMenuItem,
    DropdownMenuSeparator,
    DropdownMenuLabel,
    DropdownMenuShortcut,
} from 'brutx-ui-vue'
import { Button } from 'brutx-ui-vue'
</script>

<template>
    <DropdownMenu>
        <DropdownMenuTrigger as-child>
            <Button variant="outline">Open Menu</Button>
        </DropdownMenuTrigger>
        <DropdownMenuContent>
            <DropdownMenuLabel>My Account</DropdownMenuLabel>
            <DropdownMenuSeparator />
            <DropdownMenuItem>
                Profile
                <DropdownMenuShortcut>⇧⌘P</DropdownMenuShortcut>
            </DropdownMenuItem>
            <DropdownMenuItem>
                Settings
                <DropdownMenuShortcut>⌘S</DropdownMenuShortcut>
            </DropdownMenuItem>
            <DropdownMenuSeparator />
            <DropdownMenuItem>Log out</DropdownMenuItem>
        </DropdownMenuContent>
    </DropdownMenu>
</template>

Checkbox Items ​

Use v-model to bind checkbox state, supporting both boolean and 'indeterminate' values.

vue
<script setup>
import { ref } from 'vue'
import {
    DropdownMenu,
    DropdownMenuTrigger,
    DropdownMenuContent,
    DropdownMenuCheckboxItem,
} from 'brutx-ui-vue'
import { Button } from 'brutx-ui-vue'

const showStatusBar = ref(true)
const showActivityBar = ref(false)
</script>

<template>
    <DropdownMenu>
        <DropdownMenuTrigger as-child>
            <Button variant="outline">View</Button>
        </DropdownMenuTrigger>
        <DropdownMenuContent>
            <DropdownMenuCheckboxItem v-model="showStatusBar">
                Status Bar
            </DropdownMenuCheckboxItem>
            <DropdownMenuCheckboxItem v-model="showActivityBar">
                Activity Bar
            </DropdownMenuCheckboxItem>
        </DropdownMenuContent>
    </DropdownMenu>
</template>

Radio Items ​

vue
<script setup>
import { ref } from 'vue'
import {
    DropdownMenu,
    DropdownMenuTrigger,
    DropdownMenuContent,
    DropdownMenuRadioItem,
    DropdownMenuRadioGroup,
} from 'brutx-ui-vue'
import { Button } from 'brutx-ui-vue'

const position = ref('bottom')
</script>

<template>
    <DropdownMenu>
        <DropdownMenuTrigger as-child>
            <Button variant="outline">Position</Button>
        </DropdownMenuTrigger>
        <DropdownMenuContent>
            <DropdownMenuRadioGroup v-model="position">
                <DropdownMenuRadioItem value="top">Top</DropdownMenuRadioItem>
                <DropdownMenuRadioItem value="bottom">Bottom</DropdownMenuRadioItem>
                <DropdownMenuRadioItem value="left">Left</DropdownMenuRadioItem>
                <DropdownMenuRadioItem value="right">Right</DropdownMenuRadioItem>
            </DropdownMenuRadioGroup>
        </DropdownMenuContent>
    </DropdownMenu>
</template>
vue
<script setup>
import {
    DropdownMenu,
    DropdownMenuTrigger,
    DropdownMenuContent,
    DropdownMenuItem,
    DropdownMenuSub,
    DropdownMenuSubTrigger,
    DropdownMenuSubContent,
} from 'brutx-ui-vue'
import { Button } from 'brutx-ui-vue'
</script>

<template>
    <DropdownMenu>
        <DropdownMenuTrigger as-child>
            <Button variant="outline">Open Menu</Button>
        </DropdownMenuTrigger>
        <DropdownMenuContent>
            <DropdownMenuItem>New Tab</DropdownMenuItem>
            <DropdownMenuSub>
                <DropdownMenuSubTrigger>More Tools</DropdownMenuSubTrigger>
                <DropdownMenuSubContent>
                    <DropdownMenuItem>Save Page</DropdownMenuItem>
                    <DropdownMenuItem>Developer Tools</DropdownMenuItem>
                </DropdownMenuSubContent>
            </DropdownMenuSub>
        </DropdownMenuContent>
    </DropdownMenu>
</template>

Sub-components ​

ComponentDescription
DropdownMenuRoot component, re-export of reka-ui DropdownMenuRoot
DropdownMenuTriggerButton to open the menu, re-export of reka-ui
DropdownMenuContentDropdown content panel
DropdownMenuItemStandard menu item
DropdownMenuCheckboxItemCheckbox menu item
DropdownMenuRadioItemRadio menu item
DropdownMenuRadioGroupRadio item group, re-export of reka-ui
DropdownMenuLabelSection label
DropdownMenuSeparatorVisual separator
DropdownMenuShortcutKeyboard shortcut hint
DropdownMenuSubSubmenu container, re-export of reka-ui
DropdownMenuSubTriggerSubmenu trigger
DropdownMenuSubContentSubmenu content
DropdownMenuGroupMenu item group, re-export of reka-ui

API Reference ​

DropdownMenuContent

DropdownMenuContent — Props
NameTypeDefaultDescription
sideOffset
number | undefined
6
Sets the pixel offset between the content panel and its trigger.
Details

Declared type

number | undefined

Default value details

Declaration
floatingContentSideOffsets.dropdownMenu

Source: packages/ui/src/components/dropdown-menu/DropdownMenuContent.vue

Resolved value
6

Source

DropdownMenuContent.vue:14

packages/ui/src/components/dropdown-menu/DropdownMenuContent.vue

align
"center" | "start" | "end" | undefined
undefined
Sets the horizontal alignment of the content panel relative to its trigger.
Details

Declared type

"center" | "start" | "end" | undefined

Literal values

  • "center"
  • "end"
  • "start"

Default value details

Resolved value
undefined

Source

DropdownMenuContent.vue:16

packages/ui/src/components/dropdown-menu/DropdownMenuContent.vue

to
string | HTMLElement | undefined
undefined
Sets the selector or element used as the teleport target for the popup; it defaults to body.
Details

Declared type

string | HTMLElement | undefined

Default value details

Resolved value
undefined

Source

DropdownMenuContent.vue:18

packages/ui/src/components/dropdown-menu/DropdownMenuContent.vue

class
string | undefined
undefined
CSS classes added to the dropdown menu content panel.
Details

Declared type

string | undefined

Default value details

Resolved value
undefined

Source

DropdownMenuContent.vue:19

packages/ui/src/components/dropdown-menu/DropdownMenuContent.vue

DropdownMenuContent — Slots
NameSignature or typeDescription
#default
{}
Menu content such as items, labels, separators, or submenus.
Details

Declared type

{}

Source

DropdownMenuContent.vue

packages/ui/src/components/dropdown-menu/DropdownMenuContent.vue

DropdownMenuCheckboxItem

DropdownMenuCheckboxItem — Props
NameTypeDefaultDescription
modelValue
boolean | "indeterminate" | undefined
undefined
The controlled checked state of the checkbox item, including indeterminate; synchronize it with update:modelValue.
Details

Declared type

boolean | "indeterminate" | undefined

Literal values

  • "indeterminate"
  • false
  • true

Default value details

Resolved value
undefined

Source

DropdownMenuCheckboxItem.vue:13

packages/ui/src/components/dropdown-menu/DropdownMenuCheckboxItem.vue

defaultChecked
boolean | "indeterminate" | undefined
false
The initial checked state used when modelValue is not provided.
Details

Declared type

boolean | "indeterminate" | undefined

Literal values

  • "indeterminate"
  • false
  • true

Default value details

Resolved value
false

Source

DropdownMenuCheckboxItem.vue:15

packages/ui/src/components/dropdown-menu/DropdownMenuCheckboxItem.vue

class
string | undefined
undefined
CSS classes added to the checkbox menu item root.
Details

Declared type

string | undefined

Default value details

Resolved value
undefined

Source

DropdownMenuCheckboxItem.vue:16

packages/ui/src/components/dropdown-menu/DropdownMenuCheckboxItem.vue

iconSize
IconSize | undefined
"md"
Sets the size of the checked-state indicator icon.
Details

Declared type

IconSize | undefined

Literal values

  • "2xl"
  • "lg"
  • "md"
  • "sm"
  • "xl"
  • "xs"

Referenced types

IconSize
Type definition — IconSize
export type IconSize = NonNullable<VariantProps<typeof iconSizeVariants>['size']>

Default value details

Resolved value
"md"

Source

DropdownMenuCheckboxItem.vue:17

packages/ui/src/components/dropdown-menu/DropdownMenuCheckboxItem.vue

DropdownMenuCheckboxItem — Events
NameSignature or typeDescription
@update:modelValue
[value: boolean | "indeterminate"]
Emits the new checkbox state when it changes: true, false, or indeterminate.
Details

Declared type

[value: boolean | "indeterminate"]

Literal values

  • "indeterminate"
  • false
  • true

Source

DropdownMenuCheckboxItem.vue

packages/ui/src/components/dropdown-menu/DropdownMenuCheckboxItem.vue

DropdownMenuCheckboxItem — Slots
NameSignature or typeDescription
#default
{}
The checkbox menu item’s label and other content.
Details

Declared type

{}

Source

DropdownMenuCheckboxItem.vue

packages/ui/src/components/dropdown-menu/DropdownMenuCheckboxItem.vue

DropdownMenuItem

DropdownMenuItem — Props
NameTypeDefaultDescription
inset
boolean | undefined
false
Adds indentation to align the item with icon-bearing items or submenu triggers.
Details

Declared type

boolean | undefined

Literal values

  • false
  • true

Default value details

Resolved value
false

Source

DropdownMenuItem.vue:8

packages/ui/src/components/dropdown-menu/DropdownMenuItem.vue

disabled
boolean | undefined
false
Prevents the user from selecting this menu item.
Details

Declared type

boolean | undefined

Literal values

  • false
  • true

Default value details

Resolved value
false

Source

DropdownMenuItem.vue:10

packages/ui/src/components/dropdown-menu/DropdownMenuItem.vue

textValue
string | undefined
undefined
Sets the text used for keyboard typeahead, especially when the item’s text cannot be inferred from its content.
Details

Declared type

string | undefined

Default value details

Resolved value
undefined

Source

DropdownMenuItem.vue:11

packages/ui/src/components/dropdown-menu/DropdownMenuItem.vue

closeOnSelect
boolean | undefined
undefined
Controls whether selecting this item closes the menu.
Details

Declared type

boolean | undefined

Literal values

  • false
  • true

Default value details

Resolved value
undefined

Source

DropdownMenuItem.vue:13

packages/ui/src/components/dropdown-menu/DropdownMenuItem.vue

class
string | undefined
undefined
CSS classes added to the menu item root.
Details

Declared type

string | undefined

Default value details

Resolved value
undefined

Source

DropdownMenuItem.vue:14

packages/ui/src/components/dropdown-menu/DropdownMenuItem.vue

DropdownMenuItem — Slots
NameSignature or typeDescription
#default
{}
The menu item label and any optional icon or shortcut hint.
Details

Declared type

{}

Source

DropdownMenuItem.vue

packages/ui/src/components/dropdown-menu/DropdownMenuItem.vue

DropdownMenuLabel

DropdownMenuLabel — Props
NameTypeDefaultDescription
inset
boolean | undefined
—
Adds indentation to align the menu label with menu item content.
Details

Declared type

boolean | undefined

Literal values

  • false
  • true

Default value details

Not declared
—

Source

DropdownMenuLabel.vue:7

packages/ui/src/components/dropdown-menu/DropdownMenuLabel.vue

class
string | undefined
—
CSS classes added to the menu label element.
Details

Declared type

string | undefined

Default value details

Not declared
—

Source

DropdownMenuLabel.vue:8

packages/ui/src/components/dropdown-menu/DropdownMenuLabel.vue

DropdownMenuLabel — Slots
NameSignature or typeDescription
#default
{}
The heading for a menu group or menu content.
Details

Declared type

{}

Source

DropdownMenuLabel.vue

packages/ui/src/components/dropdown-menu/DropdownMenuLabel.vue

DropdownMenuRadioItem

DropdownMenuRadioItem — Props
NameTypeDefaultDescription
value
Required
string
—
The string value represented by this radio item in its RadioGroup.
Details

Declared type

string

Default value details

Not declared
—

Source

DropdownMenuRadioItem.vue:12

packages/ui/src/components/dropdown-menu/DropdownMenuRadioItem.vue

class
string | undefined
—
CSS classes added to the radio menu item root.
Details

Declared type

string | undefined

Default value details

Not declared
—

Source

DropdownMenuRadioItem.vue:13

packages/ui/src/components/dropdown-menu/DropdownMenuRadioItem.vue

DropdownMenuRadioItem — Slots
NameSignature or typeDescription
#default
{}
The radio menu item’s label and optional content.
Details

Declared type

{}

Source

DropdownMenuRadioItem.vue

packages/ui/src/components/dropdown-menu/DropdownMenuRadioItem.vue

DropdownMenuSeparator

DropdownMenuSeparator — Props
NameTypeDefaultDescription
class
string | undefined
—
CSS classes added to the menu separator element.
Details

Declared type

string | undefined

Default value details

Not declared
—

Source

DropdownMenuSeparator.vue:7

packages/ui/src/components/dropdown-menu/DropdownMenuSeparator.vue

DropdownMenuShortcut

DropdownMenuShortcut — Props
NameTypeDefaultDescription
class
string | undefined
—
CSS classes added to the keyboard shortcut hint element.
Details

Declared type

string | undefined

Default value details

Not declared
—

Source

DropdownMenuShortcut.vue:6

packages/ui/src/components/dropdown-menu/DropdownMenuShortcut.vue

DropdownMenuShortcut — Slots
NameSignature or typeDescription
#default
{}
The keyboard shortcut text or symbols to display.
Details

Declared type

{}

Source

DropdownMenuShortcut.vue

packages/ui/src/components/dropdown-menu/DropdownMenuShortcut.vue

DropdownMenuSubContent

DropdownMenuSubContent — Props
NameTypeDefaultDescription
sideOffset
number | undefined
6
Sets the pixel offset between the submenu panel and its trigger.
Details

Declared type

number | undefined

Default value details

Declaration
floatingContentSideOffsets.dropdownMenu

Source: packages/ui/src/components/dropdown-menu/DropdownMenuSubContent.vue

Resolved value
6

Source

DropdownMenuSubContent.vue:10

packages/ui/src/components/dropdown-menu/DropdownMenuSubContent.vue

class
string | undefined
undefined
CSS classes added to the submenu content panel.
Details

Declared type

string | undefined

Default value details

Resolved value
undefined

Source

DropdownMenuSubContent.vue:11

packages/ui/src/components/dropdown-menu/DropdownMenuSubContent.vue

DropdownMenuSubContent — Slots
NameSignature or typeDescription
#default
{}
Menu items and grouped content inside the submenu.
Details

Declared type

{}

Source

DropdownMenuSubContent.vue

packages/ui/src/components/dropdown-menu/DropdownMenuSubContent.vue

DropdownMenuSubTrigger

DropdownMenuSubTrigger — Props
NameTypeDefaultDescription
inset
boolean | undefined
false
Adds indentation to align the submenu trigger with sibling menu items.
Details

Declared type

boolean | undefined

Literal values

  • false
  • true

Default value details

Resolved value
false

Source

DropdownMenuSubTrigger.vue:10

packages/ui/src/components/dropdown-menu/DropdownMenuSubTrigger.vue

disabled
boolean | undefined
false
Prevents this submenu from opening.
Details

Declared type

boolean | undefined

Literal values

  • false
  • true

Default value details

Resolved value
false

Source

DropdownMenuSubTrigger.vue:11

packages/ui/src/components/dropdown-menu/DropdownMenuSubTrigger.vue

class
string | undefined
undefined
CSS classes added to the submenu trigger root.
Details

Declared type

string | undefined

Default value details

Resolved value
undefined

Source

DropdownMenuSubTrigger.vue:12

packages/ui/src/components/dropdown-menu/DropdownMenuSubTrigger.vue

iconSize
IconSize | undefined
"md"
Sets the size of the icon indicating the submenu direction.
Details

Declared type

IconSize | undefined

Literal values

  • "2xl"
  • "lg"
  • "md"
  • "sm"
  • "xl"
  • "xs"

Referenced types

IconSize
Type definition — IconSize
export type IconSize = NonNullable<VariantProps<typeof iconSizeVariants>['size']>

Default value details

Resolved value
"md"

Source

DropdownMenuSubTrigger.vue:13

packages/ui/src/components/dropdown-menu/DropdownMenuSubTrigger.vue

DropdownMenuSubTrigger — Slots
NameSignature or typeDescription
#default
{}
The label content displayed by the submenu trigger.
Details

Declared type

{}

Source

DropdownMenuSubTrigger.vue

packages/ui/src/components/dropdown-menu/DropdownMenuSubTrigger.vue

Accessibility ​

  • Keyboard: Supports Space / Enter to open the menu, Escape to close the menu, arrow keys to navigate menu items
  • ARIA Attributes: Automatically manages aria-expanded, aria-haspopup, role="menu" and other accessibility attributes
  • Focus Management: Focus is trapped within the menu when open; focus returns to the trigger when closed
  • Submenu Navigation: Supports expanding and navigating submenus via arrow keys

Brute force builds.