Dropdown Menu
Displays a list of actions or links that appear below a trigger button.
Installation
bin/rails g shadcnrb:component dropdown_menu
Usage
Compose m.trigger and m.content inside sui.dropdown_menu do |m|. The open/close behaviour is handled by the bundled Stimulus controller (shadcnrb--dropdown-menu--component) which is auto-installed with the gem.
<%= sui.dropdown_menu do |m| %> <%= m.trigger "Open menu" %> <%= m.content do %> <%= m.label "My Account" %> <%= m.separator %> <%= m.item "Profile", icon: :user %> <%= m.item "Settings", icon: :settings %> <%= m.separator %> <%= m.item "Sign out", icon: :x %> <% end %> <% end %>
With links
Pass href: to m.item to render an <a> tag instead of a button.
<%= sui.dropdown_menu do |m| %> <%= m.trigger "Navigate", variant: :default %> <%= m.content do %> <%= m.item "Dashboard", href: "#" %> <%= m.item "Billing", href: "#" %> <%= m.separator %> <%= m.item "Log out", href: "#" %> <% end %> <% end %>
Nested sub-menu
m.sub do |sub| spawns a nested menu: sub.trigger
looks like a regular item with a right-chevron, and sub.content
floats to the right. Opens on hover, closes after a short delay when the
pointer leaves both. Clicking a leaf item cascades-closes every ancestor.
<%= sui.dropdown_menu do |m| %> <%= m.trigger "File", variant: :outline %> <%= m.content do %> <%= m.item "New file", "#" %> <%= m.item "Open…", "#" %> <%= m.sub do |sub| %> <%= sub.trigger "Share" %> <%= sub.content do %> <%= m.item "Email link", "#" %> <%= m.item "Copy link", "#" %> <%= m.sub do |deeper| %> <%= deeper.trigger "More…" %> <%= deeper.content do %> <%= m.item "Slack", "#" %> <%= m.item "Discord", "#" %> <% end %> <% end %> <% end %> <% end %> <%= m.separator %> <%= m.item "Save", "#" %> <%= m.item "Save as…", "#" %> <% end %> <% end %>
Composition — scoped helpers inside
Pass a block with a scope arg (m.item do |i|) and
use i.link_to / i.button_to inside.
The item's scope tells link_to /
button_to they're in a non-top-level context, so they
default to variant: :bare automatically — no stacked
button visuals over the row styling. CSS on
m.item
([&>a]:flex-1 [&>form]:flex-1) makes the inner element
fill the row so clicks land anywhere.
<%= sui.dropdown_menu do |m| %> <%= m.trigger "Account", variant: :default %> <%= m.content do %> <%= m.item do |i| %> <%= i.link_to "Profile", "#", icon: :user %> <% end %> <%= m.item do |i| %> <%= i.link_to "Settings", "#", icon: :settings %> <% end %> <%= m.separator %> <%= m.item do |i| %> <%= i.button_to "Sign out", "#", method: :delete, icon: :x %> <% end %> <% end %> <% end %>
API
| Method | Args | Default | Description |
|---|---|---|---|
sui.dropdown_menu | — | — | Root container. Mounts the shadcnrb--dropdown-menu--component Stimulus controller and yields an m proxy. |
m.trigger(name) | variant:, size: | :outline, :default | Button that toggles the menu. Accepts all sui.button options. |
m.content | — | — | Floating panel that appears below the trigger. Hidden by default; shown when state is open. |
m.label(name) | — | — | Non-interactive section heading inside the content panel. |
m.separator | — | — | Horizontal divider line between groups of items. |
m.item(name) | href:, &block | nil | Interactive row. Shortcut renders <button> (or <a> when href: is given). Block form renders a <div role="menuitem"> wrapper — put link_to / button_to inside. Closes menu on click. |