The Dropdown component shows a list of links or actions in a menu that opens from a trigger. Use it for account menus, settings, and any place where a row of buttons would take too much room.
About
The menu opens on click or on hover, depending on triggerEvent. Alignment, animation style and animation speed are all props. Each item can be a link, a button, a header or a divider.
Example
To use the Dropdown component in your project, you first need to import it along with the DropdownItem component. Here's how you can set up the Dropdown in your Svelte component.
Here's a simple example of how to implement the Dropdown component. It includes a label and multiple DropdownItem components, which represent the individual links or actions within the dropdown.
In this example, the Dropdown is triggered by a label ("Dropdown"), and it contains three items, each with a URL and text.
Dropdown Sizing
The width of the Dropdown component can be customized using the width prop. You can choose from predefined sizes or set a custom width to suit your design needs. Here's a breakdown of the available options:
- auto: The Dropdown will automatically adjust its size based on its content.
- sm: A small size for compact dropdowns.
- md: The default medium size for a standard dropdown.
- lg: A large size for more prominent dropdowns.
- full: The dropdown will take up the full width of its container.
- Any width class: Pass a Tailwind width class, such as
width="w-[300px]", to size the dropdown yourself.
<!-- Automatically adjusts the size based on content -->
<Dropdown width="auto"> ... </Dropdown>
<!-- Small dropdown -->
<Dropdown width="sm"> ... </Dropdown>
<!-- Default medium size dropdown -->
<Dropdown width="md"> ... </Dropdown>
<!-- Large dropdown -->
<Dropdown width="lg"> ... </Dropdown>
<!-- Full-width dropdown -->
<Dropdown width="full"> ... </Dropdown>
<!-- Custom width - pass any TailwindCSS width class -->
<Dropdown width="w-[300px]"> ... </Dropdown>
In these examples, the width prop allows you to quickly adjust the appearance of the dropdown to fit different design needs. The default is "md".
Alignment
The align prop in the Dropdown component controls the alignment of the dropdown menu relative to its trigger. You can choose between two options:
- start: Aligns the dropdown to the start (left) of the trigger element.
- end: Aligns the dropdown to the end (right) of the trigger element. This is the default alignment.
Dropdown Trigger Event
The triggerEvent prop defines how the dropdown is triggered. By default, the dropdown opens when clicked, but you can change this behavior to trigger on hover by setting it to "hover".
Custom Dropdown Trigger
The label prop allows you to set a custom label for the dropdown trigger. You can either use a plain text string or define a custom trigger element using the snippet block.
- label as props: Directly set the trigger label as a prop.
- label as snippet: Define a custom trigger with any HTML or component structure.
The trigger is named by its own content, so a trigger with visible text needs nothing else. If your trigger is only an icon or an image, give the dropdown an ariaLabel, for example ariaLabel="Account menu", so screen reader users know what it opens.
<!-- Dropdown label by prop -->
<Dropdown label="Dropdown text label"> ... </Dropdown>
<!-- Custom dropdown label by Snippet -->
<Dropdown>
{#snippet label()}
<span class="...">Dropdown snippet label</span>
{/snippet}
</Dropdown>Animation
Based on your design requirements, you can customize the animation type and the speed of the Dropdown using the animation and animationSpeed props.
Animation Type
The animation prop controls how the menu appears when it opens. The default is slide-up.
- slide-left: The dropdown slides in from the left.
- slide-up: The default animation, sliding in from the bottom.
- slide-right: Slides in from the right.
- slide-down: Slides in from the top.
- fade: A smooth fade-in animation.
- zoom-in: The dropdown zooms in from a smaller size.
- zoom-out: The dropdown zooms out from a larger size.
<Dropdown animation="slide-left"> ... </Dropdown>
<Dropdown animation="slide-up"> ... </Dropdown> <!-- Default -->
<Dropdown animation="slide-right"> ... </Dropdown>
<Dropdown animation="slide-down"> ... </Dropdown>
<Dropdown animation="fade"> ... </Dropdown>
<Dropdown animation="zoom-in"> ... </Dropdown>
<Dropdown animation="zoom-out"> ... </Dropdown>Animation Speed
The animationSpeed prop controls the speed of the dropdown animation, allowing for smooth transitions at different paces. It accepts the following values none, slower, slow, normal, fast and faster
<Dropdown animationSpeed="slower"> ... </Dropdown>
<Dropdown animationSpeed="slow"> ... </Dropdown>
<Dropdown animationSpeed="medium"> ... </Dropdown>
<Dropdown animationSpeed="fast"> ... </Dropdown>
<Dropdown animationSpeed="faster"> ... </Dropdown>
<Dropdown animationSpeed="none"> ... </Dropdown>Arrow Icon
The trigger shows a chevron that rotates when the dropdown opens. Set arrowIcon=false to hide it, or pass a snippet to replace it with your own icon. The snippet is rendered in place of the chevron, so any rotation or transition is up to you.
<!-- Default chevron -->
<Dropdown label="With arrow"> ... </Dropdown>
<!-- No icon -->
<Dropdown label="No arrow" arrowIcon={false}> ... </Dropdown>
<!-- Your own icon -->
<Dropdown label="Custom arrow">
{#snippet arrowIcon()}
<span class="ms-1">+</span>
{/snippet}
...
</Dropdown>
Dropdown Backdrop
The backdrop prop determines whether a backdrop is shown behind the dropdown. When set to true, a backdrop is displayed; by default, it is set to false, meaning no backdrop is shown.
Close on Outside Click
An open dropdown closes by itself when you click anywhere outside it, when you choose an item, and when you press Escape. There is no prop to turn this off. Clicking a header, a divider or empty space inside the menu keeps it open.
In hover mode the dropdown also closes shortly after the pointer leaves it, so a small move off the menu does not close it instantly.
Dropdown Item
Item Types
The DropdownItem component supports four native types for consistent UI: link, button, header, and divider. The type of each item is controlled by the type prop, which defaults to link. The type prop can be set to 'link' | 'divider' | 'header' | 'button'.
- link: The default type, renders a standard hyperlink.
- button: Renders a clickable button within the dropdown.
- header: Creates a non-clickable header to separate sections.
- divider: Adds a visual divider to separate items.
You can also add custom items, but these four types are provided natively for a consistent UI experience.
A link item needs an href; without one it renders as a button. The item content is what you write inside the component, or you can pass it as the text prop, which renders as plain text. For markup, write the content inside the component.
<Dropdown label="Dropdown">
<!-- Header item -->
<DropdownItem type="header">Section Header</DropdownItem>
<!-- Link item (default) -->
<DropdownItem href="/">Link 1</DropdownItem>
<DropdownItem href="/">Link 2</DropdownItem>
<!-- Divider item -->
<DropdownItem type="divider" />
<!-- Button item -->
<DropdownItem type="button">Button 1</DropdownItem>
</Dropdown>This setup ensures your dropdown maintains a uniform appearance and functionality across different types of items.
Before and After Items
The DropdownItem component provides two snippet blocks, startItem and endItem, for adding custom content before or after the dropdown text.
- startItem: Displays content before the dropdown text, ideal for icons, images, or similar elements.
- endItem: shows content after the item text, such as a badge, a shortcut hint or a second icon.
<Dropdown label="Dropdown" width="md">
<DropdownItem href="/">
{#snippet startItem()}
<Svg>
<path d="M8 16a2 2 0 0 ... 13 6c0 .88.32 4.2 1.22 6"/>
</Svg>
{/snippet}
Notification
</DropdownItem>
<DropdownItem href="/">
Notification
{#snippet endItem()}
<Badge>New</Badge>
{/snippet}
</DropdownItem>
<DropdownItem href="/">
{#snippet startItem()}
<Svg>
<path d="M8 16a2 2 0 0 ... 13 6c0 .88.32 4.2 1.22 6"/>
</Svg>
{/snippet}
Notification
{#snippet endItem()}
<Badge>New</Badge>
{/snippet}
</DropdownItem>
</Dropdown>The two snippets let you put content on either side of the item text without changing its layout.
Custom Item
The DropdownItem component also supports fully custom content, allowing you to create items beyond the predefined types. By using custom markup within DropdownItem, you can design complex or unique dropdown items to fit your specific needs.
<Dropdown label="Custom Dropdown" width="md">
<DropdownItem href="/" class="hover:bg-brand-500 ... flex-wrap">
<div class="w-full text-start">
<p class="font-bold">Svelte 5 Component</p>
Kickstart your ... ecosystem.
</div>
</DropdownItem>
</Dropdown>This way you write the item markup yourself, so the content and the styling are entirely yours.
Active State
The active prop in the DropdownItem component is used to indicate whether the item is currently active. This prop accepts a boolean value and defaults to false. When set to true, the item will appear highlighted to show it is active.
<Dropdown label="Dropdown">
<DropdownItem href="/">Link</DropdownItem>
<DropdownItem href="/" active={true}>Active Link</DropdownItem>
<DropdownItem href="/">Link</DropdownItem>
</Dropdown>Using the active prop helps visually distinguish the selected or currently active item within the dropdown.
Customization
The Dropdown component provides several props to customize the appearance of the dropdown items and container. These props allow you to apply custom classes for different elements, giving you full control over the styling.
- containerClasses: Custom classes for the outer dropdown container.
- dropdownClasses: Customizes the dropdown content area.
- itemClasses: Sets custom classes for regular dropdown items.
- activeItemClasses: Applies custom classes to the active dropdown item.
- dividerClasses: Customizes the appearance of divider items.
- headerClasses: Adds custom styling to header items within the dropdown.
- buttonClasses: Styles the trigger itself, for example
buttonClasses="w-full"to make it fill its container.
<Dropdown
label="Customized Dropdown"
containerClasses="border-4 rounded-xl"
dropdownClasses="shadow-lg bg-green-50"
itemClasses="text-green-500 hover:bg-green-100"
activeItemClasses="text-white bg-green-500"
dividerClasses="border-b-2 border-green-200"
headerClasses="text-green-600 text-xs"
>
<DropdownItem href="/">Link 1</DropdownItem>
<DropdownItem type="header">Section Header</DropdownItem>
<DropdownItem type="divider" />
<DropdownItem href="/" active={true}>Link 2</DropdownItem>
</Dropdown>These props cover the trigger, the menu and the items, so each part can be styled on its own.
Accessibility
The Dropdown component follows WAI-ARIA best practices.
- The trigger button uses
aria-haspopup="menu",aria-expanded, andaria-controlsto describe the dropdown behavior. Its name comes from the trigger content; setariaLabelwhen the trigger has no visible text. - The dropdown list uses
role="menu"with each item using appropriate roles:menuitemon the link or button of each item- a heading element for group labels
separatorfor dividers
- On the trigger,
ArrowDownopens the menu,ArrowUpandEscapeclose it, andEnterorSpacetoggles it. Keys pressed on an item are left to that item, soEnterfollows a link, andEscapestill closes the menu and moves focus back to the trigger.