- Accordion
- Alert
- Alert Dialog
- Aspect Ratio
- Autocomplete
- Avatar
- Badge
- Breadcrumb
- Button
- Button Group
- Calendar
- Card
- Carousel
- Checkbox
- Collapsible
- Combobox
- Command
- Context Menu
- Data Table
- Date Picker
- Dialog
- Dropdown Menu
- Empty
- Field
- Form Field
- Hover Card
- Icon
- Input Group
- Input OTP
- Input
- Item
- Kbd
- Label
- Menubar
- Navigation Menu
- Pagination
- Popover
- Progress
- Radio Group
- Resizable
- Scroll Area
- Select
- Separator
- Sheet
- Sidebar
- Skeleton
- Slider
- Sonner (Toast)
- Spinner
- Switch
- Table
- Tabs
- Textarea
- Toggle
- Toggle Group
- Tooltip
Dropdown
Displays a menu to the user — such as a set of actions or functions — triggered by a button.
import { Component } from '@angular/core';
import { provideIcons } from '@ng-icons/core';
import {
lucideCircleHelp,
lucideCirclePlus,
lucideCircleUser,
lucideCode,
lucideCog,
lucideGithub,
lucideKeyboard,
lucideLayers,
lucideLogOut,
lucideMail,
lucideMessageSquare,
lucidePlus,
lucideSmile,
lucideUser,
} from '@ng-icons/lucide';
import { HlmButtonImports } from '@spartan-ng/helm/button';
import { HlmDropdownMenuImports } from '@spartan-ng/helm/dropdown-menu';
@Component({
selector: 'spartan-dropdown-preview',
imports: [HlmDropdownMenuImports, HlmButtonImports],
providers: [
provideIcons({
lucideUser,
lucideLayers,
lucideCog,
lucideKeyboard,
lucideCircleUser,
lucideSmile,
lucidePlus,
lucideGithub,
lucideCircleHelp,
lucideCode,
lucideLogOut,
lucideMail,
lucideMessageSquare,
lucideCirclePlus,
}),
],
template: `
<button hlmBtn variant="outline" [hlmDropdownMenuTrigger]="menu">Open</button>
<ng-template #menu>
<hlm-dropdown-menu class="w-56">
<hlm-dropdown-menu-label>My Account</hlm-dropdown-menu-label>
<hlm-dropdown-menu-group>
<button hlmDropdownMenuItem>
<span>Profile</span>
<hlm-dropdown-menu-shortcut>⇧⌘P</hlm-dropdown-menu-shortcut>
</button>
<button hlmDropdownMenuItem>
<span>Billing</span>
<hlm-dropdown-menu-shortcut>⌘B</hlm-dropdown-menu-shortcut>
</button>
<button hlmDropdownMenuItem>
<span>Settings</span>
<hlm-dropdown-menu-shortcut>⌘S</hlm-dropdown-menu-shortcut>
</button>
<button hlmDropdownMenuItem>
<span>Keyboard shortcuts</span>
<hlm-dropdown-menu-shortcut>⌘K</hlm-dropdown-menu-shortcut>
</button>
</hlm-dropdown-menu-group>
<hlm-dropdown-menu-separator />
<hlm-dropdown-menu-group>
<button hlmDropdownMenuItem>
<span>Team</span>
<hlm-dropdown-menu-shortcut>⌘B</hlm-dropdown-menu-shortcut>
</button>
<button hlmDropdownMenuItem side="right" align="start" [hlmDropdownMenuTrigger]="invite">
<span>Invite Users</span>
<hlm-dropdown-menu-item-sub-indicator />
</button>
<button hlmDropdownMenuItem>
<span>New Team</span>
<hlm-dropdown-menu-shortcut>⌘+T</hlm-dropdown-menu-shortcut>
</button>
</hlm-dropdown-menu-group>
<hlm-dropdown-menu-separator />
<hlm-dropdown-menu-group>
<button hlmDropdownMenuItem>
<span>GitHub</span>
</button>
<button hlmDropdownMenuItem>
<span>Support</span>
</button>
<button hlmDropdownMenuItem disabled>
<span>API</span>
</button>
</hlm-dropdown-menu-group>
<hlm-dropdown-menu-separator />
<button hlmDropdownMenuItem>
Log out
<hlm-dropdown-menu-shortcut>⇧⌘Q</hlm-dropdown-menu-shortcut>
</button>
</hlm-dropdown-menu>
</ng-template>
<ng-template #invite>
<hlm-dropdown-menu-sub>
<button hlmDropdownMenuItem>Email</button>
<button hlmDropdownMenuItem>Message</button>
<hlm-dropdown-menu-separator />
<button hlmDropdownMenuItem>More...</button>
</hlm-dropdown-menu-sub>
</ng-template>
`,
})
export class DropdownPreview {}About
Dropdown Menu is built with the help of Menu from Material CDK .
Installation
ng g @spartan-ng/cli:ui dropdown-menu
npx nx g @spartan-ng/cli:ui dropdown-menu
Usage
import { HlmDropdownMenuImports } from '@spartan-ng/helm/dropdown-menu';<button [hlmDropdownMenuTrigger]="menu">Open</button>
<ng-template #menu>
<hlm-dropdown-menu>
<hlm-dropdown-menu-label>My Account</hlm-dropdown-menu-label>
<hlm-dropdown-menu-separator />
<hlm-dropdown-menu-group>
<button hlmDropdownMenuItem>
Profile
<hlm-dropdown-menu-shortcut>⇧⌘P</hlm-dropdown-menu-shortcut>
</button>
<hlm-dropdown-menu-separator />
<button hlmDropdownMenuItem [hlmDropdownMenuTrigger]="invite">
Invite Users
<hlm-dropdown-menu-item-sub-indicator />
</button>
</hlm-dropdown-menu-group>
</hlm-dropdown-menu>
</ng-template>Examples
Checkboxes
import { ChangeDetectionStrategy, Component, signal } from '@angular/core';
import { HlmButtonImports } from '@spartan-ng/helm/button';
import { HlmDropdownMenuImports } from '@spartan-ng/helm/dropdown-menu';
@Component({
selector: 'spartan-dropdown-menu-checkboxes',
imports: [HlmDropdownMenuImports, HlmButtonImports],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<button hlmBtn variant="outline" [hlmDropdownMenuTrigger]="menu">Open</button>
<ng-template #menu>
<hlm-dropdown-menu class="w-56">
<hlm-dropdown-menu-group>
<hlm-dropdown-menu-label>Appearance</hlm-dropdown-menu-label>
<hlm-dropdown-menu-separator />
<button hlmDropdownMenuCheckbox [checked]="statusBar()" (triggered)="statusBar.set(!statusBar())">
<hlm-dropdown-menu-checkbox-indicator />
<span>Status Bar</span>
</button>
<button
hlmDropdownMenuCheckbox
disabled
[checked]="activityBar()"
(triggered)="activityBar.set(!activityBar())"
>
<hlm-dropdown-menu-checkbox-indicator />
<span>Activity Bar</span>
</button>
<button hlmDropdownMenuCheckbox [checked]="panel()" (triggered)="panel.set(!panel())">
<hlm-dropdown-menu-checkbox-indicator />
<span>Panel</span>
</button>
</hlm-dropdown-menu-group>
</hlm-dropdown-menu>
</ng-template>
`,
})
export class DropdownMenuCheckboxes {
public readonly statusBar = signal(true);
public readonly activityBar = signal(false);
public readonly panel = signal(false);
}Radio Group
import { ChangeDetectionStrategy, Component, signal } from '@angular/core';
import { MenuSide } from '@spartan-ng/brain/core';
import { HlmButtonImports } from '@spartan-ng/helm/button';
import { HlmDropdownMenuImports } from '@spartan-ng/helm/dropdown-menu';
@Component({
selector: 'spartan-dropdown-menu-radio-group',
imports: [HlmDropdownMenuImports, HlmButtonImports],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<button hlmBtn variant="outline" [hlmDropdownMenuTrigger]="menu">Open</button>
<ng-template #menu>
<hlm-dropdown-menu class="w-56">
<hlm-dropdown-menu-group>
<hlm-dropdown-menu-label>Panel Position</hlm-dropdown-menu-label>
<hlm-dropdown-menu-separator />
@let p = position();
<button hlmDropdownMenuRadio [checked]="p === 'top'" (triggered)="position.set('top')">
<hlm-dropdown-menu-radio-indicator />
<span>Top</span>
</button>
<button hlmDropdownMenuRadio [checked]="p === 'bottom'" (triggered)="position.set('bottom')">
<hlm-dropdown-menu-radio-indicator />
<span>Bottom</span>
</button>
<button hlmDropdownMenuRadio [checked]="p === 'right'" (triggered)="position.set('right')">
<hlm-dropdown-menu-radio-indicator />
<span>Right</span>
</button>
</hlm-dropdown-menu-group>
</hlm-dropdown-menu>
</ng-template>
`,
})
export class DropdownMenuRadioGroup {
public readonly position = signal<MenuSide>('bottom');
}Stateful
import { Component, signal } from '@angular/core';
import { provideIcons } from '@ng-icons/core';
import { lucideUndo2 } from '@ng-icons/lucide';
import { HlmButtonImports } from '@spartan-ng/helm/button';
import { HlmDropdownMenuImports } from '@spartan-ng/helm/dropdown-menu';
import { HlmIconImports } from '@spartan-ng/helm/icon';
@Component({
selector: 'spartan-dropdown-with-state',
imports: [HlmDropdownMenuImports, HlmButtonImports, HlmIconImports],
providers: [provideIcons({ lucideUndo2 })],
template: `
<div class="flex w-full items-center justify-center pt-[20%]">
<button hlmBtn variant="outline" align="center" [hlmDropdownMenuTrigger]="menu">Open</button>
</div>
<ng-template #menu>
<hlm-dropdown-menu class="w-56">
<hlm-dropdown-menu-group>
<hlm-dropdown-menu-label>Appearance</hlm-dropdown-menu-label>
<button hlmDropdownMenuCheckbox [checked]="statusBar()" (triggered)="statusBar.set(!statusBar())">
<hlm-dropdown-menu-checkbox-indicator />
<span>Status Bar</span>
</button>
<button
hlmDropdownMenuCheckbox
disabled
[checked]="activityBar()"
(triggered)="activityBar.set(!activityBar())"
>
<hlm-dropdown-menu-checkbox-indicator />
<span>Activity Bar</span>
</button>
<button hlmDropdownMenuCheckbox [checked]="panel()" (triggered)="panel.set(!panel())">
<hlm-dropdown-menu-checkbox-indicator />
<span>Panel</span>
</button>
</hlm-dropdown-menu-group>
<hlm-dropdown-menu-separator />
<hlm-dropdown-menu-label>Panel Position</hlm-dropdown-menu-label>
<hlm-dropdown-menu-group>
@for (size of panelPositions; track size) {
<button hlmDropdownMenuRadio [checked]="size === selectedPosition" (triggered)="selectedPosition = size">
<hlm-dropdown-menu-radio-indicator />
<span>{{ size }}</span>
</button>
}
</hlm-dropdown-menu-group>
<hlm-dropdown-menu-separator />
<button hlmDropdownMenuItem (triggered)="reset()">
<ng-icon hlm name="lucideUndo2" hlmMenuIcon />
Reset
</button>
</hlm-dropdown-menu>
</ng-template>
`,
})
export class DropdownWithStatePreview {
public readonly statusBar = signal(true);
public readonly activityBar = signal(false);
public readonly panel = signal(false);
public panelPositions = ['Top', 'Bottom', 'Right', 'Left'] as const;
public selectedPosition: (typeof this.panelPositions)[number] | undefined = 'Bottom';
reset() {
this.statusBar.set(false);
this.panel.set(false);
this.activityBar.set(false);
this.selectedPosition = 'Bottom';
}
}Passing context to menu
import { Component, signal } from '@angular/core';
import { provideIcons } from '@ng-icons/core';
import { lucideUndo2 } from '@ng-icons/lucide';
import { HlmButtonImports } from '@spartan-ng/helm/button';
import { HlmDropdownMenuImports } from '@spartan-ng/helm/dropdown-menu';
import { HlmIconImports } from '@spartan-ng/helm/icon';
@Component({
selector: 'spartan-dropdown-with-context',
imports: [HlmDropdownMenuImports, HlmButtonImports, HlmIconImports],
providers: [provideIcons({ lucideUndo2 })],
template: `
<div class="flex w-full items-center justify-center pt-[20%]">
<button
hlmBtn
variant="outline"
align="center"
[hlmDropdownMenuTrigger]="menu"
[hlmDropdownMenuTriggerData]="{ $implicit: { data: 'Context Window Full' } }"
>
Open
</button>
</div>
<ng-template #menu let-ctx>
<hlm-dropdown-menu class="w-56">
<hlm-dropdown-menu-group>
<hlm-dropdown-menu-label>Context</hlm-dropdown-menu-label>
<button hlmDropdownMenuItem inset>{{ ctx.data }}</button>
</hlm-dropdown-menu-group>
<hlm-dropdown-menu-group>
<hlm-dropdown-menu-label>Appearance</hlm-dropdown-menu-label>
<button hlmDropdownMenuCheckbox [checked]="statusBar()" (triggered)="statusBar.set(!statusBar())">
<hlm-dropdown-menu-checkbox-indicator />
<span>Status Bar</span>
</button>
<button
hlmDropdownMenuCheckbox
disabled
[checked]="activityBar()"
(triggered)="activityBar.set(!activityBar())"
>
<hlm-dropdown-menu-checkbox-indicator />
<span>Activity Bar</span>
</button>
<button hlmDropdownMenuCheckbox [checked]="panel()" (triggered)="panel.set(!panel())">
<hlm-dropdown-menu-checkbox-indicator />
<span>Panel</span>
</button>
</hlm-dropdown-menu-group>
<hlm-dropdown-menu-separator />
<hlm-dropdown-menu-label>Panel Position</hlm-dropdown-menu-label>
<hlm-dropdown-menu-group>
@for (size of panelPositions; track size) {
<button hlmDropdownMenuRadio [checked]="size === selectedPosition" (triggered)="selectedPosition = size">
<hlm-dropdown-menu-radio-indicator />
<span>{{ size }}</span>
</button>
}
</hlm-dropdown-menu-group>
<hlm-dropdown-menu-separator />
<button hlmDropdownMenuItem (triggered)="reset()">
<ng-icon hlm name="lucideUndo2" hlmMenuIcon />
Reset
</button>
</hlm-dropdown-menu>
</ng-template>
`,
})
export class DropdownWithContextPreview {
public readonly statusBar = signal(true);
public readonly activityBar = signal(false);
public readonly panel = signal(false);
public panelPositions = ['Top', 'Bottom', 'Right', 'Left'] as const;
public selectedPosition: (typeof this.panelPositions)[number] | undefined = 'Bottom';
reset() {
this.statusBar.set(false);
this.panel.set(false);
this.activityBar.set(false);
this.selectedPosition = 'Bottom';
}
}Helm API
HlmDropdownMenuCheckboxIndicator
Selector: hlm-dropdown-menu-checkbox-indicator
Inputs
| Prop | Type | Default | Description |
|---|---|---|---|
| class | ClassValue | - | - |
HlmDropdownMenuCheckbox
Selector: [hlmDropdownMenuCheckbox]
Inputs
| Prop | Type | Default | Description |
|---|---|---|---|
| class | ClassValue | - | - |
| checked | boolean | this._cdkMenuItem.checked | - |
| disabled | boolean | this._cdkMenuItem.disabled | - |
HlmDropdownMenuGroup
Selector: [hlmDropdownMenuGroup],hlm-dropdown-menu-group
Inputs
| Prop | Type | Default | Description |
|---|---|---|---|
| class | ClassValue | - | - |
HlmDropdownMenuItemSubIndicator
Selector: hlm-dropdown-menu-item-sub-indicator
Inputs
| Prop | Type | Default | Description |
|---|---|---|---|
| class | ClassValue | - | - |
HlmDropdownMenuItem
Selector: button[hlmDropdownMenuItem]
Inputs
| Prop | Type | Default | Description |
|---|---|---|---|
| class | ClassValue | - | - |
| disabled | boolean | false | - |
| variant | 'default' | 'destructive' | default | - |
| inset | boolean | false | - |
HlmDropdownMenuLabel
Selector: [hlmDropdownMenuLabel],hlm-dropdown-menu-label
Inputs
| Prop | Type | Default | Description |
|---|---|---|---|
| class | ClassValue | - | - |
| inset | boolean | false | - |
HlmDropdownMenuRadioIndicator
Selector: hlm-dropdown-menu-radio-indicator
Inputs
| Prop | Type | Default | Description |
|---|---|---|---|
| class | ClassValue | - | - |
HlmDropdownMenuRadio
Selector: [hlmDropdownMenuRadio]
Inputs
| Prop | Type | Default | Description |
|---|---|---|---|
| class | ClassValue | - | - |
| checked | boolean | this._cdkMenuItem.checked | - |
| disabled | boolean | this._cdkMenuItem.disabled | - |
HlmDropdownMenuSeparator
Selector: [hlmDropdownMenuSeparator],hlm-dropdown-menu-separator
Inputs
| Prop | Type | Default | Description |
|---|---|---|---|
| class | ClassValue | - | - |
HlmDropdownMenuShortcut
Selector: [hlmDropdownMenuShortcut],hlm-dropdown-menu-shortcut
Inputs
| Prop | Type | Default | Description |
|---|---|---|---|
| class | ClassValue | - | - |
HlmDropdownMenuSub
Selector: [hlmDropdownMenuSub],hlm-dropdown-menu-sub
Inputs
| Prop | Type | Default | Description |
|---|---|---|---|
| class | ClassValue | - | - |
HlmDropdownMenuTrigger
Selector: [hlmDropdownMenuTrigger]
Inputs
| Prop | Type | Default | Description |
|---|---|---|---|
| align | MenuAlign | this._config.align | - |
| side | MenuSide | this._config.side | - |
HlmDropdownMenu
Selector: [hlmDropdownMenu],hlm-dropdown-menu
Inputs
| Prop | Type | Default | Description |
|---|---|---|---|
| class | ClassValue | - | - |
| sideOffset | number | 1 | - |
On This Page