Dropdown Menu
Displays a menu to the user — such as a set of actions or functions — triggered by a button.
<script lang="ts">
import * as DropdownMenu from "$lib/components/ui/dropdown-menu/index.js";
import { Button } from "$lib/components/ui/button/index.js";
</script>
<DropdownMenu.Root>
<DropdownMenu.Trigger>
{#snippet child({ props })}
<Button {...props} variant="outline">Open</Button>
{/snippet}
</DropdownMenu.Trigger>
<DropdownMenu.Content class="w-56" align="start">
<DropdownMenu.Label>My Account</DropdownMenu.Label>
<DropdownMenu.Group>
<DropdownMenu.Item>
Profile
<DropdownMenu.Shortcut>⇧⌘P</DropdownMenu.Shortcut>
</DropdownMenu.Item>
<DropdownMenu.Item>
Billing
<DropdownMenu.Shortcut>⌘B</DropdownMenu.Shortcut>
</DropdownMenu.Item>
<DropdownMenu.Item>
Settings
<DropdownMenu.Shortcut>⌘S</DropdownMenu.Shortcut>
</DropdownMenu.Item>
<DropdownMenu.Item>
Keyboard shortcuts
<DropdownMenu.Shortcut>⌘K</DropdownMenu.Shortcut>
</DropdownMenu.Item>
</DropdownMenu.Group>
<DropdownMenu.Separator />
<DropdownMenu.Group>
<DropdownMenu.Item>Team</DropdownMenu.Item>
<DropdownMenu.Sub>
<DropdownMenu.SubTrigger>Invite users</DropdownMenu.SubTrigger>
<DropdownMenu.SubContent>
<DropdownMenu.Item>Email</DropdownMenu.Item>
<DropdownMenu.Item>Message</DropdownMenu.Item>
<DropdownMenu.Separator />
<DropdownMenu.Item>More...</DropdownMenu.Item>
</DropdownMenu.SubContent>
</DropdownMenu.Sub>
<DropdownMenu.Item>
New Team
<DropdownMenu.Shortcut>⌘+T</DropdownMenu.Shortcut>
</DropdownMenu.Item>
</DropdownMenu.Group>
<DropdownMenu.Separator />
<DropdownMenu.Item>GitHub</DropdownMenu.Item>
<DropdownMenu.Item>Support</DropdownMenu.Item>
<DropdownMenu.Item disabled>API</DropdownMenu.Item>
<DropdownMenu.Separator />
<DropdownMenu.Item>
Log out
<DropdownMenu.Shortcut>⇧⌘Q</DropdownMenu.Shortcut>
</DropdownMenu.Item>
</DropdownMenu.Content>
</DropdownMenu.Root> Installation
pnpm dlx jsrepo@latest add dropdown-menunpx jsrepo@latest add dropdown-menuyarn dlx jsrepo@latest add dropdown-menubunx jsrepo@latest add dropdown-menuInstall bits-ui:
pnpm add bits-ui -Dnpm install bits-ui -Dyarn add bits-ui -Dbun add bits-ui -DCopy and paste the following code into your project.
<script lang="ts">
import { DropdownMenu as DropdownMenuPrimitive } from 'bits-ui';
import { cn } from '$lib/utils.js';
let {
ref = $bindable(null),
value = $bindable([]),
class: className,
...restProps
}: DropdownMenuPrimitive.CheckboxGroupProps = $props();
</script>
<DropdownMenuPrimitive.CheckboxGroup
bind:ref
bind:value
data-slot="dropdown-menu-checkbox-group"
class={cn('border-border/60 py-1 not-first:border-t', className)}
{...restProps}
/>
Usage
<script lang="ts">
import * as DropdownMenu from '$lib/components/ui/dropdown-menu/index.js';
</script> <DropdownMenu.Root>
<DropdownMenu.Trigger>Open</DropdownMenu.Trigger>
<DropdownMenu.Content>
<DropdownMenu.Group>
<DropdownMenu.Label>My Account</DropdownMenu.Label>
<DropdownMenu.Separator />
<DropdownMenu.Item>Profile</DropdownMenu.Item>
<DropdownMenu.Item>Billing</DropdownMenu.Item>
<DropdownMenu.Item>Team</DropdownMenu.Item>
<DropdownMenu.Item>Subscription</DropdownMenu.Item>
</DropdownMenu.Group>
</DropdownMenu.Content>
</DropdownMenu.Root> Examples
Checkboxes
<script lang="ts">
import * as DropdownMenu from "$lib/components/ui/dropdown-menu/index.js";
import { Button } from "$lib/components/ui/button/index.js";
let showStatusBar = $state(true);
let showActivityBar = $state(false);
let showPanel = $state(false);
</script>
<DropdownMenu.Root>
<DropdownMenu.Trigger>
{#snippet child({ props })}
<Button {...props} variant="outline">Open</Button>
{/snippet}
</DropdownMenu.Trigger>
<DropdownMenu.Content class="w-56">
<DropdownMenu.Group>
<DropdownMenu.Label>Appearance</DropdownMenu.Label>
<DropdownMenu.Separator />
<DropdownMenu.CheckboxItem bind:checked={showStatusBar}
>Status Bar</DropdownMenu.CheckboxItem
>
<DropdownMenu.CheckboxItem bind:checked={showActivityBar} disabled>
Activity Bar
</DropdownMenu.CheckboxItem>
<DropdownMenu.CheckboxItem bind:checked={showPanel}
>Panel</DropdownMenu.CheckboxItem
>
</DropdownMenu.Group>
</DropdownMenu.Content>
</DropdownMenu.Root> Radio Group
<script lang="ts">
import * as DropdownMenu from "$lib/components/ui/dropdown-menu/index.js";
import { Button } from "$lib/components/ui/button/index.js";
let position = $state("bottom");
</script>
<DropdownMenu.Root>
<DropdownMenu.Trigger>
{#snippet child({ props })}
<Button {...props} variant="outline">Open</Button>
{/snippet}
</DropdownMenu.Trigger>
<DropdownMenu.Content class="w-56">
<DropdownMenu.Group>
<DropdownMenu.Label>Panel Position</DropdownMenu.Label>
<DropdownMenu.Separator />
<DropdownMenu.RadioGroup bind:value={position}>
<DropdownMenu.RadioItem value="top">Top</DropdownMenu.RadioItem>
<DropdownMenu.RadioItem value="bottom">Bottom</DropdownMenu.RadioItem>
<DropdownMenu.RadioItem value="right">Right</DropdownMenu.RadioItem>
</DropdownMenu.RadioGroup>
</DropdownMenu.Group>
</DropdownMenu.Content>
</DropdownMenu.Root> Dialog
This example shows how to open a dialog from a dropdown menu.
<DropdownMenu.Root>
<DropdownMenu.Trigger class={buttonVariants({ variant: 'outline' })}>
Actions
</DropdownMenu.Trigger>
</DropdownMenu.Root> <script lang="ts">
import DotsThreeIcon from "phosphor-svelte/lib/DotsThreeIcon";
import { Button, buttonVariants } from "$lib/components/ui/button/index.js";
import * as Dialog from "$lib/components/ui/dialog/index.js";
import * as DropdownMenu from "$lib/components/ui/dropdown-menu/index.js";
import { Input } from "$lib/components/ui/input/index.js";
import { Label } from "$lib/components/ui/label/index.js";
import { Textarea } from "$lib/components/ui/textarea/index.js";
import * as Field from "$lib/components/ui/field/index.js";
let showNewDialog = $state(false);
let showShareDialog = $state(false);
</script>
<DropdownMenu.Root>
<DropdownMenu.Trigger
class={buttonVariants({ variant: "outline", size: "icon-sm" })}
>
<DotsThreeIcon />
</DropdownMenu.Trigger>
<DropdownMenu.Content class="w-40" align="end">
<DropdownMenu.Label>File Actions</DropdownMenu.Label>
<DropdownMenu.Group>
<DropdownMenu.Item onSelect={() => (showNewDialog = true)}
>New File...</DropdownMenu.Item
>
<DropdownMenu.Item onSelect={() => (showShareDialog = true)}
>Share...</DropdownMenu.Item
>
<DropdownMenu.Item disabled>Download</DropdownMenu.Item>
</DropdownMenu.Group>
</DropdownMenu.Content>
</DropdownMenu.Root>
<Dialog.Root bind:open={showNewDialog}>
<Dialog.Content class="sm:max-w-[425px]">
<Dialog.Header>
<Dialog.Title>Create New File</Dialog.Title>
<Dialog.Description>
Provide a name for your new file. Click create when you're done.
</Dialog.Description>
</Dialog.Header>
<Field.Group class="pb-3">
<Field.Field>
<Field.Label for="filename">File Name</Field.Label>
<Input id="filename" name="filename" placeholder="document.txt" />
</Field.Field>
</Field.Group>
<Dialog.Footer>
<Dialog.Close class={buttonVariants({ variant: "outline" })}
>Cancel</Dialog.Close
>
<Button type="submit">Create</Button>
</Dialog.Footer>
</Dialog.Content>
</Dialog.Root>
<Dialog.Root bind:open={showShareDialog}>
<Dialog.Content class="sm:max-w-[425px]">
<Dialog.Header>
<Dialog.Title>Share File</Dialog.Title>
<Dialog.Description
>Anyone with the link will be able to view this file.</Dialog.Description
>
</Dialog.Header>
<Field.Group class="py-3">
<Field.Field>
<Label for="email">Email Address</Label>
<Input
id="email"
name="email"
type="email"
placeholder="[email protected]"
/>
</Field.Field>
<Field.Field>
<Field.Label for="message">Message (Optional)</Field.Label>
<Textarea
id="message"
name="message"
placeholder="Check out this file"
/>
</Field.Field>
</Field.Group>
<Dialog.Footer>
<Dialog.Close class={buttonVariants({ variant: "outline" })}
>Cancel</Dialog.Close
>
<Button type="submit">Send Invite</Button>
</Dialog.Footer>
</Dialog.Content>
</Dialog.Root>