The simplest dropdown uses trigger_text to auto-generate a button trigger.
<c-ui.dropdown trigger_text="Account">
<c-ui.dropdown.item>Profile</c-ui.dropdown.item>
<c-ui.dropdown.item>Settings</c-ui.dropdown.item>
<c-ui.dropdown.item>Logout</c-ui.dropdown.item>
</c-ui.dropdown>
{% cotton ui.dropdown trigger_text="Account" %}
{% cotton ui.dropdown.item %}Profile{% endcotton %}
{% cotton ui.dropdown.item %}Settings{% endcotton %}
{% cotton ui.dropdown.item %}Logout{% endcotton %}
{% endcotton %}
Control dropdown placement with position, align, and offset props.
By default, dropdowns auto-adjust to stay within the viewport (disable with :auto_position="False").
<c-ui.dropdown position="bottom" align="start" offset="8" trigger_text="Bottom Start">
<c-ui.dropdown.item>Option 1</c-ui.dropdown.item>
<c-ui.dropdown.item>Option 2</c-ui.dropdown.item>
<c-ui.dropdown.item>Option 3</c-ui.dropdown.item>
</c-ui.dropdown>
<c-ui.dropdown position="bottom" align="end" offset="8" trigger_text="Bottom End">
<c-ui.dropdown.item>Option 1</c-ui.dropdown.item>
<c-ui.dropdown.item>Option 2</c-ui.dropdown.item>
<c-ui.dropdown.item>Option 3</c-ui.dropdown.item>
</c-ui.dropdown>
<c-ui.dropdown position="top" align="start" offset="8" trigger_text="Top Start">
<c-ui.dropdown.item>Option 1</c-ui.dropdown.item>
<c-ui.dropdown.item>Option 2</c-ui.dropdown.item>
<c-ui.dropdown.item>Option 3</c-ui.dropdown.item>
</c-ui.dropdown>
<c-ui.dropdown position="top" align="end" offset="8" trigger_text="Top End">
<c-ui.dropdown.item>Option 1</c-ui.dropdown.item>
<c-ui.dropdown.item>Option 2</c-ui.dropdown.item>
<c-ui.dropdown.item>Option 3</c-ui.dropdown.item>
</c-ui.dropdown>
{% cotton ui.dropdown position="bottom" align="start" offset="8" trigger_text="Bottom Start" %}
{% cotton ui.dropdown.item %}Option 1{% endcotton %}
{% cotton ui.dropdown.item %}Option 2{% endcotton %}
{% cotton ui.dropdown.item %}Option 3{% endcotton %}
{% endcotton %}
{% cotton ui.dropdown position="bottom" align="end" offset="8" trigger_text="Bottom End" %}
{% cotton ui.dropdown.item %}Option 1{% endcotton %}
{% cotton ui.dropdown.item %}Option 2{% endcotton %}
{% cotton ui.dropdown.item %}Option 3{% endcotton %}
{% endcotton %}
{% cotton ui.dropdown position="top" align="start" offset="8" trigger_text="Top Start" %}
{% cotton ui.dropdown.item %}Option 1{% endcotton %}
{% cotton ui.dropdown.item %}Option 2{% endcotton %}
{% cotton ui.dropdown.item %}Option 3{% endcotton %}
{% endcotton %}
{% cotton ui.dropdown position="top" align="end" offset="8" trigger_text="Top End" %}
{% cotton ui.dropdown.item %}Option 1{% endcotton %}
{% cotton ui.dropdown.item %}Option 2{% endcotton %}
{% cotton ui.dropdown.item %}Option 3{% endcotton %}
{% endcotton %}
With :auto_position (on by default) the menu watches the viewport and flips or realigns to stay
visible. Drag the handle to shrink the preview into a mini viewport and watch the open menu reposition.
Enhance items with icons, keyboard shortcuts, and danger variants.
<c-ui.dropdown trigger_text="Actions">
<c-ui.dropdown.item kbd="⌘E">
<c-slot name="icon">
<svg>...</svg>
</c-slot>
Edit
</c-ui.dropdown.item>
<c-ui.dropdown.item kbd="⌘D">
<c-slot name="icon">
<svg>...</svg>
</c-slot>
Duplicate
</c-ui.dropdown.item>
<c-ui.dropdown.separator />
<c-ui.dropdown.item variant="danger" kbd="⌘⌫">
<c-slot name="icon">
<svg>...</svg>
</c-slot>
Delete
</c-ui.dropdown.item>
</c-ui.dropdown>
{% cotton ui.dropdown trigger_text="Actions" %}
{% cotton ui.dropdown.item kbd="⌘E" %}
{% cotton:slot icon %}
<svg>...</svg>
{% endcotton:slot %}
Edit
{% endcotton %}
{% cotton ui.dropdown.item kbd="⌘D" %}
{% cotton:slot icon %}
<svg>...</svg>
{% endcotton:slot %}
Duplicate
{% endcotton %}
{% cotton ui.dropdown.separator /%}
{% cotton ui.dropdown.item variant="danger" kbd="⌘⌫" %}
{% cotton:slot icon %}
<svg>...</svg>
{% endcotton:slot %}
Delete
{% endcotton %}
{% endcotton %}
Use the trigger slot for complete control over the trigger element. Common uses include icon-only buttons, avatar menus, or custom styled triggers.
<!-- Icon-only menu button -->
<c-ui.dropdown position="bottom" align="end">
<c-slot name="trigger">
<button type="button" class="p-2 rounded-md hover:bg-zinc-100" aria-label="More options">
<svg class="w-5 h-5"><!-- three dots icon --></svg>
</button>
</c-slot>
<c-ui.dropdown.item>Edit</c-ui.dropdown.item>
<c-ui.dropdown.item>Duplicate</c-ui.dropdown.item>
<c-ui.dropdown.separator />
<c-ui.dropdown.item variant="danger">Delete</c-ui.dropdown.item>
</c-ui.dropdown>
<!-- User avatar menu -->
<c-ui.dropdown position="bottom" align="end">
<c-slot name="trigger">
<button class="flex items-center gap-2 rounded-full hover:bg-zinc-100">
<div class="w-8 h-8 rounded-full bg-accent text-white">JD</div>
<svg><!-- chevron --></svg>
</button>
</c-slot>
<c-ui.dropdown.item>My Profile</c-ui.dropdown.item>
<c-ui.dropdown.item>Account Settings</c-ui.dropdown.item>
<c-ui.dropdown.separator />
<c-ui.dropdown.item>Sign Out</c-ui.dropdown.item>
</c-ui.dropdown>
<!-- Icon-only menu button -->
{% cotton ui.dropdown position="bottom" align="end" %}
{% cotton:slot trigger %}
<button type="button" class="p-2 rounded-md hover:bg-zinc-100" aria-label="More options">
<svg class="w-5 h-5"><!-- three dots icon --></svg>
</button>
{% endcotton:slot %}
{% cotton ui.dropdown.item %}Edit{% endcotton %}
{% cotton ui.dropdown.item %}Duplicate{% endcotton %}
{% cotton ui.dropdown.separator /%}
{% cotton ui.dropdown.item variant="danger" %}Delete{% endcotton %}
{% endcotton %}
<!-- User avatar menu -->
{% cotton ui.dropdown position="bottom" align="end" %}
{% cotton:slot trigger %}
<button class="flex items-center gap-2 rounded-full hover:bg-zinc-100">
<div class="w-8 h-8 rounded-full bg-accent text-white">JD</div>
<svg><!-- chevron --></svg>
</button>
{% endcotton:slot %}
{% cotton ui.dropdown.item %}My Profile{% endcotton %}
{% cotton ui.dropdown.item %}Account Settings{% endcotton %}
{% cotton ui.dropdown.separator /%}
{% cotton ui.dropdown.item %}Sign Out{% endcotton %}
{% endcotton %}
Use separators to group menu items. Items can be disabled or rendered as links.
<c-ui.dropdown trigger_text="Menu">
<c-ui.dropdown.item href="/profile">View Profile</c-ui.dropdown.item>
<c-ui.dropdown.item>Edit Profile</c-ui.dropdown.item>
<c-ui.dropdown.separator />
<c-ui.dropdown.item>Settings</c-ui.dropdown.item>
<c-ui.dropdown.item disabled>Upgrade Plan</c-ui.dropdown.item>
<c-ui.dropdown.separator />
<c-ui.dropdown.item variant="danger">Sign Out</c-ui.dropdown.item>
</c-ui.dropdown>
{% cotton ui.dropdown trigger_text="Menu" %}
{% cotton ui.dropdown.item href="/profile" %}View Profile{% endcotton %}
{% cotton ui.dropdown.item %}Edit Profile{% endcotton %}
{% cotton ui.dropdown.separator /%}
{% cotton ui.dropdown.item %}Settings{% endcotton %}
{% cotton ui.dropdown.item disabled %}Upgrade Plan{% endcotton %}
{% cotton ui.dropdown.separator /%}
{% cotton ui.dropdown.item variant="danger" %}Sign Out{% endcotton %}
{% endcotton %}
Organize menu items into labeled groups using <c-ui.dropdown.group>.
<c-ui.dropdown trigger_text="File">
<c-ui.dropdown.group label="Edit">
<c-ui.dropdown.item kbd="⌘Z">
<c-slot name="icon">
<svg><!-- Undo icon --></svg>
</c-slot>
Undo
</c-ui.dropdown.item>
<c-ui.dropdown.item kbd="⌘⇧Z">
<c-slot name="icon">
<svg><!-- Redo icon --></svg>
</c-slot>
Redo
</c-ui.dropdown.item>
</c-ui.dropdown.group>
<c-ui.dropdown.separator />
<c-ui.dropdown.group label="File">
<c-ui.dropdown.item kbd="⌘S">
<c-slot name="icon">
<svg><!-- Save icon --></svg>
</c-slot>
Save
</c-ui.dropdown.item>
<c-ui.dropdown.item kbd="⌘O">
<c-slot name="icon">
<svg><!-- Open icon --></svg>
</c-slot>
Open
</c-ui.dropdown.item>
</c-ui.dropdown.group>
<c-ui.dropdown.separator />
<c-ui.dropdown.item variant="danger" kbd="⌘Q">
<c-slot name="icon">
<svg><!-- Quit icon --></svg>
</c-slot>
Quit
</c-ui.dropdown.item>
</c-ui.dropdown>
{% cotton ui.dropdown trigger_text="File" %}
{% cotton ui.dropdown.group label="Edit" %}
{% cotton ui.dropdown.item kbd="⌘Z" %}
{% cotton:slot icon %}
<svg><!-- Undo icon --></svg>
{% endcotton:slot %}
Undo
{% endcotton %}
{% cotton ui.dropdown.item kbd="⌘⇧Z" %}
{% cotton:slot icon %}
<svg><!-- Redo icon --></svg>
{% endcotton:slot %}
Redo
{% endcotton %}
{% endcotton %}
{% cotton ui.dropdown.separator /%}
{% cotton ui.dropdown.group label="File" %}
{% cotton ui.dropdown.item kbd="⌘S" %}
{% cotton:slot icon %}
<svg><!-- Save icon --></svg>
{% endcotton:slot %}
Save
{% endcotton %}
{% cotton ui.dropdown.item kbd="⌘O" %}
{% cotton:slot icon %}
<svg><!-- Open icon --></svg>
{% endcotton:slot %}
Open
{% endcotton %}
{% endcotton %}
{% cotton ui.dropdown.separator /%}
{% cotton ui.dropdown.item variant="danger" kbd="⌘Q" %}
{% cotton:slot icon %}
<svg><!-- Quit icon --></svg>
{% endcotton:slot %}
Quit
{% endcotton %}
{% endcotton %}
| Name | Description | Type | Options | Default |
|---|---|---|---|---|
position |
Dropdown position relative to trigger. | str | top, bottom, left, right | bottom |
align |
Dropdown alignment relative to position. | str | start, center, end | start |
offset |
Distance in pixels from the trigger. | str | Any number | 4 |
trigger_text |
Auto-generates a trigger button with this text. Use this OR the trigger slot, not both. | str | Any text | |
min_width |
Minimum width of dropdown content. | str | Any CSS width value | 12rem |
auto_position |
Automatically adjusts position and alignment to keep dropdown in viewport. Detects screen boundaries and intelligently repositions to prevent overflow. Set to False to disable. | bool | True (default), False | True |
| Name | Description | Type | Options | Default |
|---|---|---|---|---|
trigger |
Custom trigger element. If not provided, trigger_text is required. | — | — | Optional |
slot (default) |
Dropdown menu content. Place items directly or wrap in <c-ui.dropdown.group> for organization. | — | — | Required |
| Name | Description | Type | Options | Default |
|---|---|---|---|---|
icon |
Icon displayed before item text. | slot | Any SVG or icon component | |
kbd |
Keyboard shortcut displayed on the right (e.g., ⌘K). | str | Any text | |
variant |
Visual variant for the item. | str | danger, (empty for default) | |
disabled |
Disables the item. | bool | True, False | False |
href |
If provided, renders as a link (<a>) instead of button. | str | Any URL |
<c-ui.dropdown.separator /> - Horizontal divider for grouping menu items. No props required.
| Name | Description | Type | Options | Default |
|---|---|---|---|---|
label |
Group heading displayed above items in uppercase gray text. | str | Any text | |
slot (default) |
Group content. Place <c-ui.dropdown.item> components here. | — | Dropdown items | Required |