Dropdowns
Menus on the floating-panel surface: group labels, separators, icons, keyboard hints and destructive items.
Account menu
Menus on the floating-panel surface. label renders the built-in trigger - deliberately neutral gray whatever your palette, only its focus ring rides primary. dropdown_menu_label and dropdown_menu_separator organise groups; items take arbitrary content - icons, .pc-kbd hints, a custom class for the destructive one - and render as a, live_patch, live_redirect or button via link_type.
Row actions and a custom trigger
No label renders the ghost ellipsis - the table-row actions trigger. For a branded trigger, :trigger_element is your own button (style it with trigger_class); this one goes solid and follows your colour dials. side and align place the panel: side is which side of the trigger it opens on ("bottom", "top", or "left"/"right" to open it beside the trigger instead), and align is which edges line up on the other axis. Below the trigger that reads horizontally, and the default "end" aligns the right edges so the panel grows leftward, which is what a menu in a right-hand corner wants; "start" aligns the left edges and grows it rightward, as the second trigger here does. Leave side out and the panel measures on every open, flipping upward when the viewport leaves no room below. placement and direction are the older spelling of the same two questions and still work.
<div class="flex items-start justify-center gap-16">
<.dropdown>
<.dropdown_menu_item link_type="button">
<.icon name="hero-pencil-square" class="w-4 h-4" /> Edit
<kbd class="pc-kbd ml-auto"><span>⌘</span>E</kbd>
</.dropdown_menu_item>
<.dropdown_menu_item link_type="button">
<.icon name="hero-document-duplicate" class="w-4 h-4" /> Duplicate
<kbd class="pc-kbd ml-auto"><span>⌘</span>D</kbd>
</.dropdown_menu_item>
<.dropdown_menu_item link_type="button">
<.icon name="hero-archive-box" class="w-4 h-4" /> Archive
</.dropdown_menu_item>
<.dropdown_menu_separator />
<.dropdown_menu_item link_type="button" class="text-danger-600 dark:text-danger-400">
<.icon name="hero-trash" class="w-4 h-4" /> Delete
<kbd class="pc-kbd ml-auto"><span>⌘</span>⌫</kbd>
</.dropdown_menu_item>
</.dropdown>
<.dropdown align="start" trigger_class="pc-button pc-button--primary pc-button--md">
<:trigger_element>
Move to project <.icon name="hero-chevron-down" class="w-4 h-4 ml-1" />
</:trigger_element>
<.dropdown_menu_label>Recent</.dropdown_menu_label>
<.dropdown_menu_item link_type="button">petal_components</.dropdown_menu_item>
<.dropdown_menu_item link_type="button">petal_pro</.dropdown_menu_item>
<.dropdown_menu_item link_type="button">marketing site</.dropdown_menu_item>
</.dropdown>
</div>
Properties
| Attribute | Type | Default | Description |
|---|---|---|---|
align
|
string |
nil
|
how the panel lines up along the other axis: leading edges flush ("start") or trailing edges flush ("end"). Above or below the trigger that is horizontal - "start" aligns the left edges so the panel grows rightward, "end" aligns the right edges so it grows leftward, which is what a menu in a right-hand corner wants. Beside the trigger it is vertical - "start" aligns the tops, "end" aligns the bottoms, which is what a user menu at the bottom of a sidebar wants. Left out it falls back to placement above and below (so "end" by default), and to "start" beside
one of: nil, "start", "end"
|
class
|
any |
nil
|
any extra CSS class for the parent container |
direction
|
string |
"auto"
|
the legacy spelling of side on the vertical axis, kept working: "up" is side="top", "down" is side="bottom", and "auto" is the measured default you get by naming neither - it flips upward when the viewport leaves no room below (needs the PetalDropdown hook). Prefer side in new code
one of: "auto", "up", "down"
|
label
|
string |
nil
|
labels your dropdown option |
menu_items_wrapper_class
|
any |
nil
|
any extra CSS class for menu item wrapper container |
on_close
|
{:struct, Phoenix.LiveView.JS} |
%Phoenix.LiveView.JS{ops: []}
|
additional JS commands to run when the dropdown closes (LiveView.JS only) |
options_container_id
|
string |
||
placement
|
string |
"left"
|
the legacy spelling of align, kept working: "left" is align="end" (the panel grows leftward, right edges aligned, the way a menu in the right-hand corner of a navbar wants) and "right" is align="start" (it grows rightward from the trigger's left edge). Prefer align in new code, and note that placement only has an opinion about a panel above or below - beside the trigger, side already answers the horizontal question
one of: "left", "right"
|
rest
|
global |
||
side
|
string |
nil
|
which side of the trigger the panel opens on. "bottom" is the ordinary menu and "top" opens it upward. "left" and "right" open it BESIDE the trigger, over whatever is next to it rather than over the thing it belongs to - the account panel a sidebar pushes out into the content area. Left out, the panel opens downward and measures on every open, flipping upward when the viewport leaves no room below (the PetalDropdown hook). Naming a side skips the hook: you have already answered the question it existed to ask
one of: nil, "bottom", "top", "left", "right"
|
trigger_class
|
string |
nil
|
additional classes for the trigger button |
:inner_block
slot
|
slot |
||
:trigger_element
slot
|
slot |
custom trigger content. Rendered INSIDE the dropdown's own <button>, so never nest interactive elements (<.button>, links) here - browsers split nested buttons and the toggle binding breaks. Style the built-in trigger via trigger_class instead, e.g. trigger_class="pc-button pc-button--primary pc-button--md" |
| Attribute | Type | Default | Description |
|---|---|---|---|
class
|
any |
nil
|
any additional CSS classes |
disabled
|
boolean |
false
|
|
label
|
string |
link label | |
link_type
|
string |
"button"
|
one of: "a", "live_patch", "live_redirect", "button"
|
rest
|
global |
||
to
|
string |
nil
|
link path |
:inner_block
slot
|
slot |
| Attribute | Type | Default | Description |
|---|---|---|---|
class
|
any |
nil
|
any additional CSS classes |
rest
|
global |
||
:inner_block
slot
|
slot |
| Attribute | Type | Default | Description |
|---|---|---|---|
class
|
any |
nil
|
any additional CSS classes |
rest
|
global |
||
:inner_block
slot
|
slot |
| Attribute | Type | Default | Description |
|---|---|---|---|
class
|
any |
nil
|
any additional CSS classes |
rest
|
global |