Dropdowns
Dropdown menus that just work. They're built on top of Floating UI and Alpine.js. While they often seem simple on the surface, you might be surprised how complex they are under the hood. Things like focus states, keyboard navigation, accessibility, and positioning are all (usually) handled for you.
Using Dropdowns
To use a dropdown, use the <ui:dropdown> tag with an <x-slot:trigger> to define the triggering element (usually a button).
Here's what an example dropdown might look like:
Basic Dropdown Menu
1<ui:dropdown>2 <x-slot:trigger>3 <ui:button>Click Me, If You Dare...</ui:button>4 </x-slot:trigger>5 <ui:dropdown-item>Grizzly Bears</ui:dropdown-item>6 <ui:dropdown-item>Polar Bears</ui:dropdown-item>7 <ui:dropdown-item>Panda Bears</ui:dropdown-item>8 <ui:dropdown-item>Teddy Bears</ui:dropdown-item>9</ui:dropdown>1<ui:dropdown>2 <x-slot:trigger>3 <ui:button>Click Me, If You Dare...</ui:button>4 </x-slot:trigger>5 <ui:dropdown-item>Grizzly Bears</ui:dropdown-item>6 <ui:dropdown-item>Polar Bears</ui:dropdown-item>7 <ui:dropdown-item>Panda Bears</ui:dropdown-item>8 <ui:dropdown-item>Teddy Bears</ui:dropdown-item>9</ui:dropdown>
Properties
| Property | Type | Default | Description |
|---|---|---|---|
offset |
integer |
4 |
The pixel-value gap between the menu and the trigger element. See the Alpine docs on offset for more. |
position |
string |
bottom |
The dropdown's location relative to the trigger element. See the Alpine docs on positioning for possible values. |
Offset
The the gap between the dropdown and the triggering element as a pixel value. This value is passed directly to Alpine's Anchor plugin, which is built on top of Floating UI. Most of the time you'll want the default value, but if you need more or less space you can use this property to achieve it.
1<ui:dropdown offset="10">2 ...3</ui:dropdown>1<ui:dropdown offset="10">2 ...3</ui:dropdown>
Position
The dropdown's location relative to the trigger element. This value is passed directly to Alpine's Anchor plugin too. The default value is bottom, but you can also use top, top-start, top-end, left, left-start, left-end, bottom-start, bottom-end, right, right-start, and right-end.
1<ui:dropdown position="top">2 I open above the trigger element.3</ui:dropdown>1<ui:dropdown position="top">2 I open above the trigger element.3</ui:dropdown>
Slots
Trigger
Use <x-slot:trigger> to define the trigger element.
The Trigger Slot
1<x-slot:trigger>2 <button>...</button>3</x-slot:trigger>1<x-slot:trigger>2 <button>...</button>3</x-slot:trigger>
Dropdown Items
Use the <ui:dropdown-item> component to define menu items. The default slot is the item's main label.
Note that content gets wrapped in a <span> tag to allow for automatic spacing within menu items.
Dropdown Item
1<ui:dropdown-item>2 Make it grrreat!3</ui:dropdown-item>1<ui:dropdown-item>2 Make it grrreat!3</ui:dropdown-item>
Properties
Dropdown items have a few properties:
| Property | Type | Default | Description |
|---|---|---|---|
dismiss |
boolean |
true |
Close the outer dropdown menu when the item is clicked (or focused and enter is pressed) |
focusOnHover |
boolean |
true |
Focus the item when hovered over. Use kebab-case like :focus-on-hover="false" |
spacing |
string |
space-x-2 |
A Tailwind CSS Spacing Utility class, like space-x-2. |
icon |
string |
null |
Include an Icon before the dropdown item's main content. |
iconAfter |
string |
null |
Include an Icon after the dropdown item's main content. |
iconVariant |
string |
micro |
The icon variant to use. micro (default), mini, solid, or outline |
Icons
The icon property is used to include an icon before the dropdown item's main content.
1<ui:dropdown-item icon="arrow-down">...</ui:dropdown-item>1<ui:dropdown-item icon="arrow-down">...</ui:dropdown-item>
Menu Items - Icons
1<ui:dropdown>2 <x-slot:trigger>3 <ui:button>Dropdown Items with Icons</ui:button>4 </x-slot:trigger>5 <ui:dropdown-item icon="arrow-down">Icons</ui:dropdown-item>6 <ui:dropdown-item icon="arrows-pointing-in">Provided by</ui:dropdown-item>7 <ui:dropdown-item icon="bell-alert">Heroicons</ui:dropdown-item>8</ui:dropdown>1<ui:dropdown>2 <x-slot:trigger>3 <ui:button>Dropdown Items with Icons</ui:button>4 </x-slot:trigger>5 <ui:dropdown-item icon="arrow-down">Icons</ui:dropdown-item>6 <ui:dropdown-item icon="arrows-pointing-in">Provided by</ui:dropdown-item>7 <ui:dropdown-item icon="bell-alert">Heroicons</ui:dropdown-item>8</ui:dropdown>
Icon Position
The icon-after property is used to include an icon after the dropdown item's main content.
1<ui:dropdown-item icon-after="arrow-down">...</ui:dropdown-item>1<ui:dropdown-item icon-after="arrow-down">...</ui:dropdown-item>
Menu Items - Icons After
1<ui:dropdown>2 <x-slot:trigger>3 <ui:button>Dropdown Items with Icons After</ui:button>4 </x-slot:trigger>5 <ui:dropdown-item icon-after="arrow-down">Icons</ui:dropdown-item>6 <ui:dropdown-item icon-after="arrows-pointing-in">Provided by</ui:dropdown-item>7 <ui:dropdown-item icon-after="bell-alert">Heroicons</ui:dropdown-item>8</ui:dropdown>1<ui:dropdown>2 <x-slot:trigger>3 <ui:button>Dropdown Items with Icons After</ui:button>4 </x-slot:trigger>5 <ui:dropdown-item icon-after="arrow-down">Icons</ui:dropdown-item>6 <ui:dropdown-item icon-after="arrows-pointing-in">Provided by</ui:dropdown-item>7 <ui:dropdown-item icon-after="bell-alert">Heroicons</ui:dropdown-item>8</ui:dropdown>
Slots
The <ui:dropdown-item> has two named slots: before and after. Use the before slot to add
content before the menu item's main content -- or the after slot to add content after it. These
slots are most commonly used for icons or to denote further actions (such as a hover menu).
1<ui:dropdown-item>2 <x-slot:before>...</x-slot:before>3 ...4 <x-slot:after>...</x-slot:after>5</ui:dropdown-item>1<ui:dropdown-item>2 <x-slot:before>...</x-slot:before>3 ...4 <x-slot:after>...</x-slot:after>5</ui:dropdown-item>
Menu Items - Before / After Slots
1<ui:dropdown>2 <x-slot:trigger>3 <ui:button>Example Before / After Slots</ui:button>4 </x-slot:trigger>5 <ui:dropdown-item>6 <x-slot:before>7 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5">8 <path stroke-linecap="round" stroke-linejoin="round" d="M2.25 18.75a60.07 60.07 0 0115.797 2.101c.727.198 1.453-.342 1.453-1.096V18.75M3.75 4.5v.75A.75.75 0 013 6h-.75m0 0v-.375c0-.621.504-1.125 1.125-1.125H20.25M2.25 6v9m18-10.5v.75c0 .414.336.75.75.75h.75m-1.5-1.5h.375c.621 0 1.125.504 1.125 1.125v9.75c0 .621-.504 1.125-1.125 1.125h-.375m1.5-1.5H21a.75.75 0 00-.75.75v.75m0 0H3.75m0 0h-.375a1.125 1.125 0 01-1.125-1.125V15m1.5 1.5v-.75A.75.75 0 003 15h-.75M15 10.5a3 3 0 11-6 0 3 3 0 016 0zm3 0h.008v.008H18V10.5zm-12 0h.008v.008H6V10.5z" />9 </svg>10 </x-slot:before>11 Menu Item with Before / After icons12 <x-slot:after>13 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="w-5 h-5">14 <path fill-rule="evenodd" d="M15.28 9.47a.75.75 0 0 1 0 1.06l-4.25 4.25a.75.75 0 1 1-1.06-1.06L13.69 10 9.97 6.28a.75.75 0 0 1 1.06-1.06l4.25 4.25ZM6.03 5.22l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.75.75 0 0 1-1.06-1.06L8.69 10 4.97 6.28a.75.75 0 0 1 1.06-1.06Z" clip-rule="evenodd" />15 </svg>16 </x-slot:after>17 </ui:dropdown-item>18</ui:dropdown>1<ui:dropdown>2 <x-slot:trigger>3 <ui:button>Example Before / After Slots</ui:button>4 </x-slot:trigger>5 <ui:dropdown-item>6 <x-slot:before>7 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5">8 <path stroke-linecap="round" stroke-linejoin="round" d="M2.25 18.75a60.07 60.07 0 0115.797 2.101c.727.198 1.453-.342 1.453-1.096V18.75M3.75 4.5v.75A.75.75 0 013 6h-.75m0 0v-.375c0-.621.504-1.125 1.125-1.125H20.25M2.25 6v9m18-10.5v.75c0 .414.336.75.75.75h.75m-1.5-1.5h.375c.621 0 1.125.504 1.125 1.125v9.75c0 .621-.504 1.125-1.125 1.125h-.375m1.5-1.5H21a.75.75 0 00-.75.75v.75m0 0H3.75m0 0h-.375a1.125 1.125 0 01-1.125-1.125V15m1.5 1.5v-.75A.75.75 0 003 15h-.75M15 10.5a3 3 0 11-6 0 3 3 0 016 0zm3 0h.008v.008H18V10.5zm-12 0h.008v.008H6V10.5z" />9 </svg>10 </x-slot:before>11 Menu Item with Before / After icons12 <x-slot:after>13 <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="w-5 h-5">14 <path fill-rule="evenodd" d="M15.28 9.47a.75.75 0 0 1 0 1.06l-4.25 4.25a.75.75 0 1 1-1.06-1.06L13.69 10 9.97 6.28a.75.75 0 0 1 1.06-1.06l4.25 4.25ZM6.03 5.22l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.75.75 0 0 1-1.06-1.06L8.69 10 4.97 6.28a.75.75 0 0 1 1.06-1.06Z" clip-rule="evenodd" />15 </svg>16 </x-slot:after>17 </ui:dropdown-item>18</ui:dropdown>
Slot Attribute Forwarding
The before and after slots are also wrapped in a <span> tag, and the slot attributes are forwarded to it
by default. This means you can use the class attribute to style the content within each slot.
1<ui:dropdown-item>2 <x-slot:before class="text-red-500">...</x-slot:before>3 ...4 <x-slot:after class="text-blue-500">...</x-slot:after>5</ui:dropdown-item>1<ui:dropdown-item>2 <x-slot:before class="text-red-500">...</x-slot:before>3 ...4 <x-slot:after class="text-blue-500">...</x-slot:after>5</ui:dropdown-item>
Menu Items - Before / After Slots with Classes
1<ui:dropdown>2 <x-slot:trigger>3 <ui:button>Example Before / After Slots with Classes</ui:button>4 </x-slot:trigger>5 <ui:dropdown-item>6 <x-slot:before class="text-red-500">7 RED8 </x-slot:before>9 Menu Item with Before / After icons10 <x-slot:after class="text-blue-500">11 BLUE12 </x-slot:after>13 </ui:dropdown-item>14</ui:dropdown>1<ui:dropdown>2 <x-slot:trigger>3 <ui:button>Example Before / After Slots with Classes</ui:button>4 </x-slot:trigger>5 <ui:dropdown-item>6 <x-slot:before class="text-red-500">7 RED8 </x-slot:before>9 Menu Item with Before / After icons10 <x-slot:after class="text-blue-500">11 BLUE12 </x-slot:after>13 </ui:dropdown-item>14</ui:dropdown>