Dropdown
<wa-dropdown>
Dropdowns display a list of options triggered by a button or other element. They support keyboard navigation, submenus, and checkable items for building menus and context actions.
Dropdowns consist of a trigger and a panel. By default, activating the trigger will expose the panel and interacting outside of the panel will close it.
Dropdowns are designed to work well with dropdown items to provide a list of options the user can select from. However, dropdowns can also be used in lower-level applications. The API gives you complete control over showing, hiding, and positioning the panel.
<wa-dropdown> <wa-button appearance="filled" slot="trigger" with-caret>Dropdown</wa-button> <wa-dropdown-item> <wa-icon slot="icon" name="scissors"></wa-icon> Cut </wa-dropdown-item> <wa-dropdown-item> <wa-icon slot="icon" name="copy"></wa-icon> Copy </wa-dropdown-item> <wa-dropdown-item> <wa-icon slot="icon" name="paste"></wa-icon> Paste </wa-dropdown-item> <wa-divider></wa-divider> <wa-dropdown-item> Show images <wa-dropdown-item slot="submenu" value="show-all-images">Show All Images</wa-dropdown-item> <wa-dropdown-item slot="submenu" value="show-thumbnails">Show Thumbnails</wa-dropdown-item> </wa-dropdown-item> <wa-divider></wa-divider> <wa-dropdown-item type="checkbox" checked>Emoji Shortcuts</wa-dropdown-item> <wa-dropdown-item type="checkbox" checked>Word Wrap</wa-dropdown-item> <wa-divider></wa-divider> <wa-dropdown-item variant="danger"> <wa-icon slot="icon" name="trash"></wa-icon> Delete </wa-dropdown-item> </wa-dropdown>
Examples
Getting the Selected Item
When an item is selected, the wa-select event will be emitted by the dropdown. You can inspect event.detail.item to get a reference to the selected item. If you've provided a value for each dropdown item, it will be available in event.detail.item.value.
<div class="dropdown-selection"> <wa-dropdown> <wa-button appearance="filled" slot="trigger" with-caret>View</wa-button> <wa-dropdown-item value="full-screen">Enter full screen</wa-dropdown-item> <wa-dropdown-item value="actual">Actual size</wa-dropdown-item> <wa-dropdown-item value="zoom-in">Zoom in</wa-dropdown-item> <wa-dropdown-item value="zoom-out">Zoom out</wa-dropdown-item> </wa-dropdown> </div> <script> const container = document.querySelector('.dropdown-selection'); const dropdown = container.querySelector('wa-dropdown'); dropdown.addEventListener('wa-select', event => { console.log(event.detail.item.value); }); </script>
To keep the dropdown open after selection, call event.preventDefault() in the wa-select event's callback.
Showing Icons
Use the icon slot to add icons to dropdown items. This works best with icon elements.
<wa-dropdown> <wa-button appearance="filled" slot="trigger" with-caret>Edit</wa-button> <wa-dropdown-item value="cut"> <wa-icon slot="icon" name="scissors"></wa-icon> Cut </wa-dropdown-item> <wa-dropdown-item value="copy"> <wa-icon slot="icon" name="copy"></wa-icon> Copy </wa-dropdown-item> <wa-dropdown-item value="paste"> <wa-icon slot="icon" name="paste"></wa-icon> Paste </wa-dropdown-item> <wa-dropdown-item value="delete" variant="danger"> <wa-icon slot="icon" name="trash"></wa-icon> Delete </wa-dropdown-item> </wa-dropdown>
Showing Labels & Dividers
Use any heading, e.g. <h1>–<h6> to add labels and the <wa-divider> element for separators.
Type
<wa-dropdown> <wa-button appearance="filled" slot="trigger" with-caret>Device</wa-button> <h3>Type</h3> <wa-dropdown-item value="phone">Phone</wa-dropdown-item> <wa-dropdown-item value="tablet">Tablet</wa-dropdown-item> <wa-dropdown-item value="desktop">Desktop</wa-dropdown-item> <wa-divider></wa-divider> <wa-dropdown-item value="more">More options…</wa-dropdown-item> </wa-dropdown>
Showing Details
Use the details slot to display details, such as keyboard shortcuts, inside dropdown items.
<wa-dropdown> <wa-button appearance="filled" slot="trigger" with-caret>Message</wa-button> <wa-dropdown-item value="reply"> Reply <span slot="details">⌘R</span> </wa-dropdown-item> <wa-dropdown-item value="forward"> Forward <span slot="details">⌘F</span> </wa-dropdown-item> <wa-dropdown-item value="move"> Move <span slot="details">⌘M</span> </wa-dropdown-item> <wa-divider></wa-divider> <wa-dropdown-item value="archive"> Archive <span slot="details">⌘A</span> </wa-dropdown-item> <wa-dropdown-item value="delete" variant="danger"> Delete <span slot="details">Del</span> </wa-dropdown-item> </wa-dropdown>
Checkable Items
You can turn a dropdown item into a checkable option by setting type="checkbox". Add the checked attribute to make it checked initially. When clicked, the item's checked state will toggle and the dropdown will close. You can cancel the wa-select event if you want to keep it open instead.
<div class="dropdown-checkboxes"> <wa-dropdown> <wa-button appearance="filled" slot="trigger" with-caret>View</wa-button> <wa-dropdown-item type="checkbox" value="canvas" checked>Show canvas</wa-dropdown-item> <wa-dropdown-item type="checkbox" value="grid" checked>Show grid</wa-dropdown-item> <wa-dropdown-item type="checkbox" value="source">Show source</wa-dropdown-item> <wa-divider></wa-divider> <wa-dropdown-item value="preferences">Preferences…</wa-dropdown-item> </wa-dropdown> </div> <script> const container = document.querySelector('.dropdown-checkboxes'); const dropdown = container.querySelector('wa-dropdown'); dropdown.addEventListener('wa-select', event => { if (event.detail.item.type === 'checkbox') { // Checkbox console.log(event.detail.item.value, event.detail.item.checked ? 'checked' : 'unchecked'); } else { // Not a checkbox console.log(event.detail.item.value); } }); </script>
When a checkable option exists anywhere in the dropdown, all items will receive additional padding so they align properly.
Destructive Items
Add variant="danger" to any dropdown item to highlight that it's a dangerous action.
Danger zone
<wa-dropdown> <wa-button appearance="filled" slot="trigger" with-caret>Project</wa-button> <wa-dropdown-item value="share"> <wa-icon slot="icon" name="share"></wa-icon> Share </wa-dropdown-item> <wa-dropdown-item value="preferences"> <wa-icon slot="icon" name="gear"></wa-icon> Preferences </wa-dropdown-item> <wa-divider></wa-divider> <h3>Danger zone</h3> <wa-dropdown-item value="archive"> <wa-icon slot="icon" name="archive"></wa-icon> Archive </wa-dropdown-item> <wa-dropdown-item value="delete" variant="danger"> <wa-icon slot="icon" name="trash"></wa-icon> Delete </wa-dropdown-item> </wa-dropdown>
Placement
The preferred placement of the dropdown can be set with the placement attribute. Note that the actual position may vary to ensure the panel remains in the viewport.
<wa-dropdown placement="right-start"> <wa-button appearance="filled" slot="trigger"> File formats <wa-icon slot="end" name="chevron-right"></wa-icon> </wa-button> <wa-dropdown-item value="pdf">PDF Document</wa-dropdown-item> <wa-dropdown-item value="docx">Word Document</wa-dropdown-item> <wa-dropdown-item value="xlsx">Excel Spreadsheet</wa-dropdown-item> <wa-dropdown-item value="pptx">PowerPoint Presentation</wa-dropdown-item> <wa-dropdown-item value="txt">Plain Text</wa-dropdown-item> <wa-dropdown-item value="json">JSON File</wa-dropdown-item> </wa-dropdown>
Distance
The distance from the panel to the trigger can be customized using the distance attribute. This value is specified in pixels.
<wa-dropdown distance="30"> <wa-button appearance="filled" slot="trigger" with-caret>Edit</wa-button> <wa-dropdown-item>Cut</wa-dropdown-item> <wa-dropdown-item>Copy</wa-dropdown-item> <wa-dropdown-item>Paste</wa-dropdown-item> <wa-divider></wa-divider> <wa-dropdown-item>Find</wa-dropdown-item> <wa-dropdown-item>Replace</wa-dropdown-item> </wa-dropdown>
Offset
The offset of the panel along the trigger can be customized using the skidding attribute. This value is specified in pixels.
<wa-dropdown skidding="30"> <wa-button appearance="filled" slot="trigger" with-caret>Edit</wa-button> <wa-dropdown-item>Cut</wa-dropdown-item> <wa-dropdown-item>Copy</wa-dropdown-item> <wa-dropdown-item>Paste</wa-dropdown-item> <wa-divider></wa-divider> <wa-dropdown-item>Find</wa-dropdown-item> <wa-dropdown-item>Replace</wa-dropdown-item> </wa-dropdown>
Submenus
To create submenus, nest dropdown items inside of a dropdown item and assign slot="submenu" to each one. You can also add dividers as needed.
<div class="dropdown-submenus"> <wa-dropdown> <wa-button appearance="filled" slot="trigger" with-caret>Export</wa-button> <wa-dropdown-item> Documents <wa-dropdown-item slot="submenu" value="pdf">PDF</wa-dropdown-item> <wa-dropdown-item slot="submenu" value="docx">Word Document</wa-dropdown-item> </wa-dropdown-item> <wa-dropdown-item> Spreadsheets <wa-dropdown-item slot="submenu"> Excel Formats <wa-dropdown-item slot="submenu" value="xlsx">Excel (.xlsx)</wa-dropdown-item> <wa-dropdown-item slot="submenu" value="xls">Excel 97-2003 (.xls)</wa-dropdown-item> <wa-dropdown-item slot="submenu" value="csv">CSV (.csv)</wa-dropdown-item> </wa-dropdown-item> <wa-dropdown-item slot="submenu"> Other Formats <wa-dropdown-item slot="submenu" value="ods">OpenDocument (.ods)</wa-dropdown-item> <wa-dropdown-item slot="submenu" value="tsv">Tab-separated (.tsv)</wa-dropdown-item> <wa-dropdown-item slot="submenu" value="json">JSON (.json)</wa-dropdown-item> </wa-dropdown-item> <wa-dropdown-item slot="submenu" value="numbers">Apple Numbers</wa-dropdown-item> </wa-dropdown-item> <wa-divider></wa-divider> <wa-dropdown-item> Options <wa-dropdown-item slot="submenu" type="checkbox" value="compress">Compress files</wa-dropdown-item> <wa-dropdown-item slot="submenu" type="checkbox" checked value="metadata">Include metadata</wa-dropdown-item> <wa-dropdown-item slot="submenu" type="checkbox" value="password">Password protect</wa-dropdown-item> </wa-dropdown-item> </wa-dropdown> </div> <script> const container = document.querySelector('.dropdown-submenus'); const dropdown = container.querySelector('wa-dropdown'); dropdown.addEventListener('wa-select', event => { console.log(event.detail.item.value); }); </script>
Dropdown items that have a submenu will not dispatch the wa-select event. However, items inside the submenu will, unless they also have a submenu.
As a UX best practice, avoid using more than one level of submenu when possible.
Disabling Items
Add the disabled attribute to any dropdown item to disable it.
<wa-dropdown> <wa-button appearance="filled" slot="trigger" with-caret>Payment method</wa-button> <wa-dropdown-item value="cash">Cash</wa-dropdown-item> <wa-dropdown-item value="check" disabled>Personal check</wa-dropdown-item> <wa-dropdown-item value="credit">Credit card</wa-dropdown-item> <wa-dropdown-item value="gift-card">Gift card</wa-dropdown-item> </wa-dropdown>
Importing
If you're using the autoloader or a hosted project, components load on demand — no manual import needed. To cherry-pick a component manually, use one of the following snippets.
Import this component directly from the CDN:
import 'https://ka-f.webawesome.com/[email protected]/components/dropdown/dropdown.js';
After installing Web Awesome via npm, import this component:
import '@awesome.me/webawesome/dist/components/dropdown/dropdown.js';
If you're self-hosting Web Awesome, import this component from your server:
import './webawesome/dist/components/dropdown/dropdown.js';
To import this component for React 18 or below, use the following code:
import WaDropdown from '@awesome.me/webawesome/dist/react/dropdown/index.js';
Slots
Learn more about using slots.
| Name | Description |
|---|---|
| (default) | The dropdown's items, typically <wa-dropdown-item> elements. |
trigger
|
The element that triggers the dropdown, such as a <wa-button> or <button>. |
Attributes & Properties
Learn more about attributes and properties.
| Name | Description | Reflects | |
|---|---|---|---|
css |
One or more CSSResultGroup to include in the component's shadow root. Host styles are automatically prepended.
Type
CSSResultGroup | undefinedDefault
[sizeStyles, styles] |
||
distancedistance |
The distance of the dropdown menu from its trigger.
Type
numberDefault
0 |
||
openopen |
Opens or closes the dropdown.
Type
booleanDefault
false |
|
|
placementplacement |
The placement of the dropdown menu in reference to the trigger. The menu will shift to a more optimal location if
the preferred placement doesn't have enough room.
Type
'top'
| 'top-start'
| 'top-end'
| 'bottom'
| 'bottom-start'
| 'bottom-end'
| 'right'
| 'right-start'
| 'right-end'
| 'left'
| 'left-start'
| 'left-end'Default
'bottom-start' |
|
|
sizesize |
The dropdown's size.
Type
'xs' | 's' | 'm' | 'l' | 'xl' | 'small' | 'medium' | 'large'Default
'm' |
|
|
skiddingskidding |
The offset of the dropdown menu along its trigger.
Type
numberDefault
0 |
Events
Learn more about events.
| Name | Description |
|---|---|
wa-after-hide |
Emitted after the dropdown has been hidden. |
wa-after-show |
Emitted after the dropdown has been shown. |
wa-hide |
Emitted when the dropdown is about to hide. |
wa-select |
Emitted when an item in the dropdown is selected. |
wa-show |
Emitted when the dropdown is about to show. |
CSS custom properties
Learn more about CSS custom properties.
| Name | Description |
|---|---|
--hide-duration |
The duration of the hide animation.
|
--show-duration |
The duration of the show animation.
|
CSS parts
Learn more about CSS parts.
| Name | Description | CSS selector |
|---|---|---|
base |
The component's host element. |
::part(base)
|
menu |
The dropdown menu container. |
::part(menu)
|
Dependencies
This component automatically imports the following elements. Sub-dependencies, if any exist, will also be included in this list.