PUI
Actions Dropdown

Dropdown

Menu dropdowns with items, shortcuts, separators, and destructive actions.

The Dropdown component provides a trigger button with a floating menu of actions. Built on top of PUI's Popover, it supports keyboard navigation, shortcuts display, separators, and destructive action variants.

Import

use PUI
# or
import PUI.Dropdown

Basic Usage

The simplest dropdown uses the item slot:

<.menu_button>
Actions
<:item>Edit</:item>
<:item>Duplicate</:item>
<:item>Delete</:item>
</.menu_button>

With Shortcuts

Display keyboard shortcuts alongside menu items:

<.menu_button>
File
<:item shortcut="⌘N">New File</:item>
<:item shortcut="⌘O">Open</:item>
<:item shortcut="⌘S">Save</:item>
</.menu_button>

Destructive Items

Mark dangerous actions with the destructive variant:

<.menu_button>
Manage
<:item>Settings</:item>
<:item>Export</:item>
<:item variant="destructive" phx-click="delete">Delete</:item>
</.menu_button>

Button Variants

The trigger button supports all button variants:

<.menu_button variant="outline">Options</.menu_button>
<.menu_button variant="ghost">More</.menu_button>
<.menu_button variant="destructive">Danger</.menu_button>

With Navigation

Items can navigate using Phoenix's navigate, patch, or href:

<.menu_button>
Go To
<:item navigate={~p"/dashboard"}>Dashboard</:item>
<:item navigate={~p"/settings"}>Settings</:item>
<:item href="https://docs.example.com">Documentation</:item>
</.menu_button>

Custom Content

Use menu_content, menu_item, and menu_separator for full control:

<.menu_button>
Options
<:items>
<.menu_item>
<.icon name="hero-pencil" class="size-4 mr-2" /> Edit
</.menu_item>
<.menu_item>
<.icon name="hero-document-duplicate" class="size-4 mr-2" /> Duplicate
</.menu_item>
<.menu_separator />
<.menu_item variant="destructive">
<.icon name="hero-trash" class="size-4 mr-2" /> Delete
</.menu_item>
</:items>
</.menu_button>

API Reference

Name Type Default Description
variant string "secondary" Trigger button variant: "default", "secondary", "outline", "ghost", or "destructive"
class string "" Additional CSS classes for trigger
content_class string "" Additional CSS classes for dropdown content
Name Required Description
inner_block Trigger button text
item Quick menu items (supports variant, shortcut, href, navigate, patch, phx-click)
items Full custom content using menu_item components
Name Type Default Description
variant string "default" "default" or "destructive"
shortcut string nil Keyboard shortcut display text
class string "" Additional CSS classes

Headless

menu_button/1 always renders a styled PUI.Button trigger. When the application owns the trigger markup, compose PUI.Dropdown.Primitive instead. The parts keep the popover hook, role="menu" semantics, and keyboard navigation, and add no visual classes — so include both the hidden and visible display classes on the content, for example aria-hidden:hidden block:

<PUI.Dropdown.Primitive.root id="actions" placement="bottom-start" class="w-fit">
<PUI.Dropdown.Primitive.trigger id="actions-trigger" controls="actions-menu" class="my-trigger">
Options
</PUI.Dropdown.Primitive.trigger>
<PUI.Dropdown.Primitive.content id="actions-menu" class="aria-hidden:hidden block my-menu">
<PUI.Dropdown.Primitive.item phx-click="edit" class="my-item w-full text-left aria-selected:bg-accent aria-selected:text-accent-foreground">Edit</PUI.Dropdown.Primitive.item>
<PUI.Dropdown.Primitive.separator class="my-separator" />
<PUI.Dropdown.Primitive.item phx-click="delete" class="my-item w-full text-left aria-selected:bg-accent aria-selected:text-accent-foreground">Delete</PUI.Dropdown.Primitive.item>
</PUI.Dropdown.Primitive.content>
</PUI.Dropdown.Primitive.root>

Primitive items add no sizing or focus styles. Add w-full and text-left to button items that should fill the menu, and style aria-selected with the same surface used for hover.

PUI.Dropdown.menu_content/1, menu_item/1, menu_shortcut/1, and menu_separator/1 stay available when only the trigger needs custom markup.