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 { BrnMenuTrigger } from '@spartan-ng/brain/menu';
import { HlmButton } from '@spartan-ng/helm/button';
import {
HlmMenu,
HlmMenuGroup,
HlmMenuItem,
HlmMenuItemSubIndicator,
HlmMenuLabel,
HlmMenuSeparator,
HlmMenuShortcut,
HlmSubMenu,
} from '@spartan-ng/helm/menu';
@Component({
selector: 'spartan-dropdown-preview',
imports: [
BrnMenuTrigger,
HlmMenu,
HlmSubMenu,
HlmMenuItem,
HlmMenuItemSubIndicator,
HlmMenuLabel,
HlmMenuShortcut,
HlmMenuSeparator,
HlmMenuGroup,
HlmButton,
],
providers: [
provideIcons({
lucideUser,
lucideLayers,
lucideCog,
lucideKeyboard,
lucideCircleUser,
lucideSmile,
lucidePlus,
lucideGithub,
lucideCircleHelp,
lucideCode,
lucideLogOut,
lucideMail,
lucideMessageSquare,
lucideCirclePlus,
}),
],
template: `
<div class="flex w-full items-center justify-center pt-[20%]">
<button hlmBtn variant="outline" align="end" [brnMenuTriggerFor]="menu">Open</button>
</div>
<ng-template #menu>
<hlm-menu class="w-56">
<hlm-menu-label>My Account</hlm-menu-label>
<hlm-menu-group>
<button hlmMenuItem>
<span>Profile</span>
<hlm-menu-shortcut>⇧⌘P</hlm-menu-shortcut>
</button>
<button hlmMenuItem>
<span>Billing</span>
<hlm-menu-shortcut>⌘B</hlm-menu-shortcut>
</button>
<button hlmMenuItem>
<span>Settings</span>
<hlm-menu-shortcut>⌘S</hlm-menu-shortcut>
</button>
<button hlmMenuItem>
<span>Keyboard shortcuts</span>
<hlm-menu-shortcut>⌘K</hlm-menu-shortcut>
</button>
</hlm-menu-group>
<hlm-menu-separator />
<hlm-menu-group>
<button hlmMenuItem>
<span>Team</span>
<hlm-menu-shortcut>⌘B</hlm-menu-shortcut>
</button>
<button hlmMenuItem [brnMenuTriggerFor]="invite">
<span>Invite Users</span>
<hlm-menu-item-sub-indicator />
</button>
<button hlmMenuItem>
<span>New Team</span>
<hlm-menu-shortcut>⌘+T</hlm-menu-shortcut>
</button>
</hlm-menu-group>
<hlm-menu-separator />
<hlm-menu-group>
<button hlmMenuItem>
<span>GitHub</span>
</button>
<button hlmMenuItem>
<span>Support</span>
</button>
<button hlmMenuItem disabled>
<span>API</span>
</button>
</hlm-menu-group>
<hlm-menu-separator />
<button hlmMenuItem>
Log out
<hlm-menu-shortcut>⇧⌘Q</hlm-menu-shortcut>
</button>
</hlm-menu>
</ng-template>
<ng-template #invite>
<hlm-sub-menu>
<button hlmMenuItem>Email</button>
<button hlmMenuItem>Message</button>
<hlm-menu-separator />
<button hlmMenuItem>More...</button>
</hlm-sub-menu>
</ng-template>
`,
})
export class DropdownPreview {}
Installation
npx nx g @spartan-ng/cli:ui menu
ng g @spartan-ng/cli:ui menu
Usage
import { BrnMenuTriggerDirective } from '@spartan-ng/brain/menu';
import {
HlmMenu
HlmMenuGroup
HlmMenuItem
HlmMenuItemIcon
HlmMenuItemSubIndicator
HlmMenuLabel
HlmMenuSeparator
HlmMenuShortcut
HlmSubMenu
} from '@spartan-ng/helm/menu';
<button [brnMenuTriggerFor]="menu">Open</button>
<ng-template #menu>
<hlm-menu>
<hlm-menu-label>My Account</hlm-menu-label>
<hlm-menu-separator />
<hlm-menu-group>
<button hlmMenuItem>
Profile
<hlm-menu-shortcut>⇧⌘P</hlm-menu-shortcut>
</button>
<hlm-menu-separator />
<button hlmMenuItem [brnMenuTriggerFor]="invite">
Invite Users
<hlm-menu-item-sub-indicator />
</button>
</hlm-menu-group>
</hlm-menu>
</ng-template>
Brain API
BrnContextMenuTrigger
Selector: [brnCtxMenuTriggerFor]
Inputs
Prop | Type | Default | Description |
---|---|---|---|
brnCtxMenuTriggerFor | TemplateRef<unknown> | null | null | - |
brnCtxMenuTriggerData | unknown | undefined | - |
align | BrnMenuAlign | undefined | - |
BrnMenuBar
Selector: [brnMenuBar]
BrnMenuGroup
Selector: [brnMenuGroup]
BrnMenuItemCheckbox
Selector: [brnMenuItemCheckbox]
Inputs
Prop | Type | Default | Description |
---|---|---|---|
checked | unknown | this._cdkMenuItem.checked | - |
disabled | unknown | this._cdkMenuItem.disabled | - |
BrnMenuItemRadio
Selector: [brnMenuItemRadio]
Inputs
Prop | Type | Default | Description |
---|---|---|---|
checked | unknown | this._cdkMenuItem.checked | - |
disabled | unknown | this._cdkMenuItem.disabled | - |
BrnMenuItem
Selector: [brnMenuItem]
Inputs
Prop | Type | Default | Description |
---|---|---|---|
disabled | unknown | this._cdkMenuItem.disabled | - |
BrnMenuTrigger
Selector: [brnMenuTriggerFor]
Inputs
Prop | Type | Default | Description |
---|---|---|---|
align | BrnMenuAlign | undefined | - |
BrnMenu
Selector: [brnMenu],[brnSubMenu]
Helm API
HlmMenuBarItem
Selector: [hlmMenuBarItem]
Inputs
Prop | Type | Default | Description |
---|---|---|---|
class | ClassValue | - | - |
HlmMenuBar
Selector: hlm-menu-bar
Inputs
Prop | Type | Default | Description |
---|---|---|---|
class | ClassValue | - | - |
HlmMenuGroup
Selector: hlm-menu-group
HlmMenuItemCheck
Selector: hlm-menu-item-check
Inputs
Prop | Type | Default | Description |
---|---|---|---|
class | ClassValue | - | - |
HlmMenuItemCheckbox
Selector: [hlmMenuItemCheckbox]
Inputs
Prop | Type | Default | Description |
---|---|---|---|
class | ClassValue | - | - |
HlmMenuItemIcon
Selector: [hlmMenuIcon]
Inputs
Prop | Type | Default | Description |
---|---|---|---|
class | ClassValue | - | - |
HlmMenuItemRadioIndicator
Selector: hlm-menu-item-radio
Inputs
Prop | Type | Default | Description |
---|---|---|---|
class | ClassValue | - | - |
HlmMenuItemRadio
Selector: [hlmMenuItemRadio]
Inputs
Prop | Type | Default | Description |
---|---|---|---|
class | ClassValue | - | - |
HlmMenuItemSubIndicator
Selector: hlm-menu-item-sub-indicator
Inputs
Prop | Type | Default | Description |
---|---|---|---|
class | ClassValue | - | - |
HlmMenuItem
Selector: [hlmMenuItem]
Inputs
Prop | Type | Default | Description |
---|---|---|---|
variant | 'default' | 'destructive' | default | - |
inset | boolean | false | - |
class | ClassValue | - | - |
HlmMenuLabel
Selector: hlm-menu-label
Inputs
Prop | Type | Default | Description |
---|---|---|---|
inset | boolean | false | - |
class | ClassValue | - | - |
HlmMenuSeparator
Selector: hlm-menu-separator
Inputs
Prop | Type | Default | Description |
---|---|---|---|
class | ClassValue | - | - |
HlmMenuShortcut
Selector: hlm-menu-shortcut
Inputs
Prop | Type | Default | Description |
---|---|---|---|
class | ClassValue | - | - |
HlmMenu
Selector: hlm-menu
Inputs
Prop | Type | Default | Description |
---|---|---|---|
class | ClassValue | - | - |
variant | MenuVariants['variant'] | default | - |
HlmSubMenu
Selector: hlm-sub-menu
Inputs
Prop | Type | Default | Description |
---|---|---|---|
class | ClassValue | - | - |
Examples
Stateful
import { Component } from '@angular/core';
import { NgIcon, provideIcons } from '@ng-icons/core';
import { lucideUndo2 } from '@ng-icons/lucide';
import { BrnMenuTrigger } from '@spartan-ng/brain/menu';
import { HlmButton } from '@spartan-ng/helm/button';
import { HlmIcon } from '@spartan-ng/helm/icon';
import {
HlmMenu,
HlmMenuGroup,
HlmMenuItem,
HlmMenuItemCheck,
HlmMenuItemCheckbox,
HlmMenuItemIcon,
HlmMenuItemRadio,
HlmMenuItemRadioIndicator,
HlmMenuLabel,
HlmMenuSeparator,
} from '@spartan-ng/helm/menu';
@Component({
selector: 'spartan-dropdown-with-state',
imports: [
BrnMenuTrigger,
HlmMenu,
HlmMenuItem,
HlmMenuLabel,
HlmMenuSeparator,
HlmMenuItemIcon,
HlmMenuItemCheck,
HlmMenuItemRadio,
HlmMenuGroup,
HlmMenuItemRadio,
HlmMenuItemCheckbox,
HlmButton,
NgIcon,
HlmIcon,
HlmMenuItemRadioIndicator,
],
providers: [provideIcons({ lucideUndo2 })],
template: `
<div class="flex w-full items-center justify-center pt-[20%]">
<button hlmBtn variant="outline" align="center" [brnMenuTriggerFor]="menu">Open</button>
</div>
<ng-template #menu>
<hlm-menu class="w-56">
<hlm-menu-group>
<hlm-menu-label>Appearance</hlm-menu-label>
<button hlmMenuItemCheckbox [checked]="isPanel" (triggered)="isPanel = !isPanel">
<hlm-menu-item-check />
<span>Panel</span>
</button>
<button hlmMenuItemCheckbox disabled [checked]="isActivityBar" (triggered)="isActivityBar = !isActivityBar">
<hlm-menu-item-check />
<span>Activity Bar</span>
</button>
<button hlmMenuItemCheckbox [checked]="isStatusBar" (triggered)="isStatusBar = !isStatusBar">
<hlm-menu-item-check />
<span>Status Bar</span>
</button>
</hlm-menu-group>
<hlm-menu-separator />
<hlm-menu-label>Panel Position</hlm-menu-label>
<hlm-menu-group>
@for (size of panelPositions; track size) {
<button hlmMenuItemRadio [checked]="size === selectedPosition" (triggered)="selectedPosition = size">
<hlm-menu-item-radio />
<span>{{ size }}</span>
</button>
}
</hlm-menu-group>
<hlm-menu-separator />
<button hlmMenuItem (triggered)="reset()">
<ng-icon hlm name="lucideUndo2" hlmMenuIcon />
Reset
</button>
</hlm-menu>
</ng-template>
`,
})
export class DropdownWithStatePreview {
public isStatusBar = false;
public isPanel = false;
public isActivityBar = false;
public panelPositions = ['Top', 'Bottom', 'Right', 'Left'] as const;
public selectedPosition: (typeof this.panelPositions)[number] | undefined = 'Bottom';
reset() {
this.isStatusBar = false;
this.isPanel = false;
this.isActivityBar = false;
this.selectedPosition = 'Bottom';
}
}
Passing context to menu
import { Component } from '@angular/core';
import { NgIcon, provideIcons } from '@ng-icons/core';
import { lucideUndo2 } from '@ng-icons/lucide';
import { BrnMenuTrigger } from '@spartan-ng/brain/menu';
import { HlmButton } from '@spartan-ng/helm/button';
import { HlmIcon } from '@spartan-ng/helm/icon';
import {
HlmMenu,
HlmMenuGroup,
HlmMenuItem,
HlmMenuItemCheck,
HlmMenuItemCheckbox,
HlmMenuItemIcon,
HlmMenuItemRadio,
HlmMenuItemRadioIndicator,
HlmMenuLabel,
HlmMenuSeparator,
} from '@spartan-ng/helm/menu';
@Component({
selector: 'spartan-dropdown-with-context',
imports: [
BrnMenuTrigger,
HlmMenu,
HlmMenuItem,
HlmMenuLabel,
HlmMenuSeparator,
HlmMenuItemIcon,
HlmMenuItemCheck,
HlmMenuItemRadio,
HlmMenuGroup,
HlmMenuItemRadio,
HlmMenuItemRadioIndicator,
HlmMenuItemCheckbox,
HlmButton,
NgIcon,
HlmIcon,
],
providers: [provideIcons({ lucideUndo2 })],
template: `
<div class="flex w-full items-center justify-center pt-[20%]">
<button
hlmBtn
variant="outline"
align="center"
[brnMenuTriggerFor]="menu"
[brnMenuTriggerData]="{ $implicit: { data: 'SomeContext' } }"
>
Open
</button>
</div>
<ng-template #menu let-ctx>
<hlm-menu class="w-56">
<hlm-menu-group>
<hlm-menu-label>Context</hlm-menu-label>
<button hlmMenuItem inset>{{ ctx.data }}</button>
</hlm-menu-group>
<hlm-menu-group>
<hlm-menu-label>Appearance</hlm-menu-label>
<button hlmMenuItemCheckbox [checked]="isPanel" (triggered)="isPanel = !isPanel">
<hlm-menu-item-check />
<span>Panel</span>
</button>
<button hlmMenuItemCheckbox disabled [checked]="isActivityBar" (triggered)="isActivityBar = !isActivityBar">
<hlm-menu-item-check />
<span>Activity Bar</span>
</button>
<button hlmMenuItemCheckbox [checked]="isStatusBar" (triggered)="isStatusBar = !isStatusBar">
<hlm-menu-item-check />
<span>Status Bar</span>
</button>
</hlm-menu-group>
<hlm-menu-separator />
<hlm-menu-label>Panel Position</hlm-menu-label>
<hlm-menu-group>
@for (size of panelPositions; track size) {
<button hlmMenuItemRadio [checked]="size === selectedPosition" (triggered)="selectedPosition = size">
<hlm-menu-item-radio />
<span>{{ size }}</span>
</button>
}
</hlm-menu-group>
<hlm-menu-separator />
<button hlmMenuItem (triggered)="reset()">
<ng-icon hlm name="lucideUndo2" hlmMenuIcon />
Reset
</button>
</hlm-menu>
</ng-template>
`,
})
export class DropdownWithContextPreview {
public isStatusBar = false;
public isPanel = false;
public isActivityBar = false;
public panelPositions = ['Top', 'Bottom', 'Right', 'Left'] as const;
public selectedPosition: (typeof this.panelPositions)[number] | undefined = 'Bottom';
reset() {
this.isStatusBar = false;
this.isPanel = false;
this.isActivityBar = false;
this.selectedPosition = 'Bottom';
}
}