Dropdown Menu

Displays a menu to the user—such as a set of actions or functions—triggered by a button.

Loading...
 import { Component } from '@angular/core';
 
import {
    DropdownSide,
    RdxDropdownMenuContentDirective,
    RdxDropdownMenuItemCheckboxDirective,
    RdxDropdownMenuItemDirective,
    RdxDropdownMenuItemIndicatorDirective,
    RdxDropdownMenuItemRadioDirective,
    RdxDropdownMenuItemRadioGroupDirective,
    RdxDropdownMenuSeparatorDirective,
    RdxDropdownMenuTriggerDirective
} from '@radix-ng/primitives/dropdown-menu';
import { Check, Dot, LucideAngularModule, Menu } from 'lucide-angular';
 
@Component({
    selector: 'dropdown-menu-demo',
    standalone: true,
    styleUrl: 'dropdown-menu-demo.css',
    imports: [
        RdxDropdownMenuTriggerDirective,
        RdxDropdownMenuItemDirective,
        RdxDropdownMenuItemCheckboxDirective,
        RdxDropdownMenuItemIndicatorDirective,
        RdxDropdownMenuSeparatorDirective,
        RdxDropdownMenuContentDirective,
        LucideAngularModule,
        RdxDropdownMenuItemRadioGroupDirective,
        RdxDropdownMenuItemRadioDirective
    ],
    template: `
        <button
            class="IconButton"
            [rdxDropdownMenuTrigger]="menu"
            sideOffset="4"
            alignOffset="-5"
            aria-label="Customise options"
        >
            <lucide-angular [img]="MenuIcon" size="16" style="display: flex;" />
        </button>
 
        <ng-template #menu>
            <div class="DropdownMenuContent" rdxDropdownMenuContent>
                <button class="DropdownMenuItem" rdxDropdownMenuItem>
                    New Tab
                    <div class="RightSlot">⌘ T</div>
                </button>
                <button class="DropdownMenuItem" rdxDropdownMenuItem>
                    New Window
                    <div class="RightSlot">⌘ N</div>
                </button>
                <button class="DropdownMenuItem" rdxDropdownMenuItem disabled>
                    New Private Window
                    <div class="RightSlot">⇧+⌘+N</div>
                </button>
                <button
                    class="DropdownMenuItem DropdownMenuSubTrigger"
                    [rdxDropdownMenuTrigger]="share"
                    [side]="DropdownSide.Right"
                    rdxDropdownMenuItem
                >
                    More Tools
                    <div class="RightSlot">></div>
                </button>
                <div class="DropdownMenuSeparator" rdxDropdownMenuSeparator></div>
                <button class="DropdownMenuItem" [(checked)]="itemChecked1" rdxDropdownMenuItemCheckbox>
                    <div class="DropdownMenuItemIndicator" rdxDropdownMenuItemIndicator>
                        <lucide-icon [img]="CheckIcon" size="13" />
                    </div>
                    Show Bookmarks
                    <div class="RightSlot">⌘+B</div>
                </button>
                <button class="DropdownMenuItem" [(checked)]="itemChecked2" rdxDropdownMenuItemCheckbox>
                    <div class="DropdownMenuItemIndicator" rdxDropdownMenuItemIndicator>
                        <lucide-icon [img]="CheckIcon" size="13" />
                    </div>
                    Show Full URLs
                </button>
                <div class="DropdownMenuSeparator" rdxDropdownMenuSeparator></div>
                <div class="DropdownMenuLabel" rdxDropdownMenuLabel>People</div>
                <div [(value)]="selectedValue" (valueChange)="onValueChange($event)" rdxDropdownMenuItemRadioGroup>
                    <div class="DropdownMenuRadioItem" [value]="'1'" rdxDropdownMenuItemRadio>
                        <div class="DropdownMenuItemIndicator" rdxDropdownMenuItemIndicator>
                            <lucide-icon [img]="DotIcon" size="13" strokeWidth="6" />
                        </div>
                        Pedro Duarte
                    </div>
                    <div class="DropdownMenuRadioItem" [value]="'2'" rdxDropdownMenuItemRadio>
                        <div class="DropdownMenuItemIndicator" rdxDropdownMenuItemIndicator>
                            <lucide-icon [img]="DotIcon" size="13" strokeWidth="6" />
                        </div>
                        Colm Tuite
                    </div>
                </div>
            </div>
        </ng-template>
 
        <ng-template #share>
            <div class="DropdownMenuSubContent" rdxDropdownMenuContent>
                <button class="DropdownMenuItem" rdxDropdownMenuItem>
                    Save Page As...
                    <div class="RightSlot">⌘+S</div>
                </button>
                <button class="DropdownMenuItem" rdxDropdownMenuItem>Create Shortcut...</button>
                <button class="DropdownMenuItem" rdxDropdownMenuItem>Name Windows...</button>
                <div class="DropdownMenuSeparator" rdxDropdownMenuSeparator></div>
                <button class="DropdownMenuItem" rdxDropdownMenuItem>Developer Tools</button>
            </div>
        </ng-template>
    `
})
export class DropdownMenuDemo {
    protected readonly MenuIcon = Menu;
    protected readonly CheckIcon = Check;
    protected readonly DotIcon = Dot;
 
    protected readonly DropdownSide = DropdownSide;
 
    itemChecked1 = true;
    itemChecked2 = false;
 
    selectedValue = '1';
 
    onValueChange(value: string) {
        this.selectedValue = value;
    }
}
  
 /* reset */
button {
    all: unset;
}
 
.DropdownMenuContent,
.DropdownMenuSubContent {
    flex-direction: column;
    display: inline-flex;
    min-width: 220px;
    background-color: white;
    border-radius: 6px;
    padding: 5px;
    box-shadow:
        0px 10px 38px -10px rgba(22, 23, 24, 0.35),
        0px 10px 20px -15px rgba(22, 23, 24, 0.2);
    will-change: transform, opacity;
}
 
.DropdownMenuItem,
.DropdownMenuCheckboxItem,
.DropdownMenuRadioItem,
.DropdownMenuSubTrigger {
    font-size: 13px;
    line-height: 1;
    color: var(--violet-11);
    border-radius: 3px;
    display: flex;
    align-items: center;
    height: 25px;
    position: relative;
    padding: 0 5px 0 25px;
    user-select: none;
    outline: none;
}
 
.DropdownMenuItem[data-disabled],
.DropdownMenuCheckboxItem[data-disabled],
.DropdownMenuRadioItem[data-disabled] {
    color: var(--mauve-8);
    pointer-events: none;
}
 
.DropdownMenuItem[data-highlighted],
.DropdownMenuCheckboxItem[data-highlighted],
.DropdownMenuRadioItem[data-highlighted] {
    background-color: var(--violet-9);
    color: var(--violet-1);
}
 
.DropdownMenuSeparator {
    height: 1px;
    background-color: var(--violet-6);
    margin: 5px;
}
 
.DropdownMenuLabel {
    padding-left: 25px;
    font-size: 12px;
    line-height: 25px;
    color: var(--mauve-11);
}
 
.IconButton {
    font-family: inherit;
    border-radius: 100%;
    height: 35px;
    width: 35px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    color: var(--violet-11);
    background-color: white;
    box-shadow: 0 2px 10px var(--black-a7);
}
 
.DropdownMenuSubTrigger[data-state='open'] {
    background-color: var(--violet-4);
    color: var(--violet-11);
}
 
.DropdownMenuItemIndicator {
    position: absolute;
    left: 6px;
    width: 25px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
 
.IconButton:hover {
    background-color: var(--violet-3);
}
 
.IconButton:focus {
    box-shadow: 0 0 0 2px black;
}
 
.RightSlot {
    margin-left: auto;
    padding-left: 20px;
    color: var(--mauve-9);
    display: flex;
    flex-direction: row;
    flex: 1;
    justify-content: flex-end;
}
 
[data-highlighted] > .RightSlot {
    color: white;
}
 
[data-disabled] .RightSlot {
    color: var(--mauve-8);
} 

Anatomy

Import all parts and piece them together.

API Reference

Trigger

The button that toggles the dropdown menu. By default, the DropdownMenu.Content will position itself against the trigger.

Prop Default Type
side
DropdownSide

The preferred side of the trigger to render against when open. Will be reversed when collisions occur and `avoidCollisions` is enabled.

align
DropdownAlign

The preferred alignment against the trigger. May change when collisions occur.

sideOffset
number

The distance in pixels from the trigger.

alignOffset
number

An offset in pixels from the "start" or "end" alignment options.

Data Attribute Value
[data-state]
"open" | "closed"
[data-disabled]
Present when disabled

Content

The component that pops out when the dropdown menu is open.

Prop Default Type