Drop Down Button
<oge-drop-down-button> pairs an oge-button trigger with an anchored menu panel from @oge-ui/overlay — flip-aware positioning, outside-click and Escape closing, focus restore and the full WAI-ARIA menu-button keyboard pattern (arrows, Home/End, type-ahead). Items can load lazily from a promise; split mode adds an independent action button.
Items & menu basics
Pass an items array of menu entries — plain actions, separators, checkable state (checked) and destructive styling (severity: 'danger'). The panel positions itself with flip-aware math, repositions on scroll, closes on outside click or Escape, and restores focus to the trigger. itemClick delivers the chosen item, then the panel closes.
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { OgeDropDownButton } from '@oge-ui/buttons';
import type { OgeMenuItem } from '@oge-ui/overlay';
@Component({
selector: 'demo-root',
imports: [OgeDropDownButton],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<oge-drop-down-button
text="Export"
severity="accent"
[items]="exportItems"
(itemClick)="exportAs($event.item.value)"
/>
`,
})
export class Demo {
protected readonly exportItems: OgeMenuItem[] = [
{ text: 'Excel (.xlsx)', value: 'xlsx' },
{ text: 'CSV', value: 'csv' },
{ separator: true, text: '' },
{ text: 'PDF', value: 'pdf' },
];
protected exportAs(format: unknown): void {
console.log('export as', format);
}
}Split button & remembered action
splitButton separates the control into an action button and a chevron toggle — the main button emits clicked (with full action/clickGuard support) without opening the menu. Add rememberLastAction and the last chosen item becomes the main button's label and action for the session; selectionChanged reports each swap with the previous item.
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { OgeDropDownButton } from '@oge-ui/buttons';
import type { OgeMenuItem } from '@oge-ui/overlay';
@Component({
selector: 'demo-root',
imports: [OgeDropDownButton],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<oge-drop-down-button
text="Run"
[splitButton]="true"
[rememberLastAction]="true"
[items]="runTargets"
(clicked)="runCurrent()"
(itemClick)="run($event.item.value)"
/>
`,
})
export class Demo {
protected readonly runTargets: OgeMenuItem[] = [
{ text: 'Run tests', value: 'test' },
{ text: 'Run build', value: 'build' },
{ text: 'Run lint', value: 'lint' },
];
protected runCurrent(): void {
console.log('run the remembered target');
}
protected run(target: unknown): void {
console.log('run', target);
}
}Async items
Instead of an array, items accepts a function returning a promise. It is invoked on the first open — the panel shows a localized loading row, then the items; failures show an error row and the next open retries. Results are cached until the function reference changes, and stale responses from superseded requests are discarded.
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { OgeDropDownButton } from '@oge-ui/buttons';
import type { OgeMenuItem } from '@oge-ui/overlay';
@Component({
selector: 'demo-root',
imports: [OgeDropDownButton],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<oge-drop-down-button text="Branches" [items]="loadBranches" />
`,
})
export class Demo {
// invoked on first open, cached until the reference changes
protected readonly loadBranches = (): Promise<OgeMenuItem[]> =>
fetch('/api/branches').then((response) => response.json());
}Custom panel content
For panels that are not menus — filter forms, pickers, mini toolbars — project a template with *ogeDropDownContent. It replaces the item list entirely and receives a close function as the implicit template variable, so any element inside can dismiss the panel and hand focus back to the trigger.
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { OgeButton, OgeDropDownButton, OgeDropDownContent } from '@oge-ui/buttons';
@Component({
selector: 'demo-root',
imports: [OgeButton, OgeDropDownButton, OgeDropDownContent],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<oge-drop-down-button text="Filters" [dropdownWidth]="260">
<div *ogeDropDownContent="let close" class="p-3">
…any content…
<oge-button text="Apply" size="sm" (clicked)="apply(); close()" />
</div>
</oge-drop-down-button>
`,
})
export class Demo {
protected apply(): void {
console.log('apply the filters');
}
}Notes
- Non-split mode: the trigger click only toggles the panel; bind
(itemClick).(clicked)fires solely from the split main button. - The panel flips above the trigger near the viewport bottom and repositions on scroll/resize — never detaches like a frozen popup.
- Keyboard: ↓/↑ opens focusing first/last item, type-ahead jumps by label, Esc closes and restores focus.
holdToConfirm/autoRepeatare not available on drop-down buttons.