Tooltip & Context Menu
Two directives turn the overlay engine into everyday UI: ogeTooltip attaches an accessible, viewport-aware tooltip to any element, and [ogeContextMenu] opens a fully keyboard-navigable menu at the pointer on right-click. Both render into the document body, so overflow or transformed ancestors never clip them.
Tooltip basics
Bind a string to ogeTooltip on any element. The bubble shows after a short hover dwell — or instantly on keyboard focus — and hides on leave, blur or Escape. While visible the trigger's aria-describedby points at the bubble, so screen readers announce it; an empty string disables the tooltip entirely.
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { OgeButton } from '@oge-ui/buttons';
import { OgeTooltip } from '@oge-ui/overlay';
@Component({
selector: 'demo-root',
imports: [OgeButton, OgeTooltip],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<!-- any element becomes a tooltip trigger -->
<oge-button text="Save" ogeTooltip="Saves your changes" />
<button type="button" ogeTooltip="Plain elements work too">Hover me</button>
<!-- shows on hover after a dwell, immediately on keyboard focus;
hides on leave, blur or Escape; wired to aria-describedby -->
`,
})
export class Demo {}Tooltip placement & delays
tooltipPlacement prefers a side (top, bottom, left, right — centered on the anchor) and flips automatically when the viewport runs out of room. Delays fall back to the global overlay config (provideOgeOverlayConfig) and can be tuned per trigger; tooltipDisabled suppresses the tooltip without removing the directive.
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { OgeButton } from '@oge-ui/buttons';
import { OgeTooltip, provideOgeOverlayConfig } from '@oge-ui/overlay';
import type { ApplicationConfig } from '@angular/core';
@Component({
selector: 'demo-root',
imports: [OgeButton, OgeTooltip],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<oge-button text="Below" ogeTooltip="Prefers the bottom edge"
tooltipPlacement="bottom" />
<oge-button text="Slow" ogeTooltip="Waits 800ms before showing"
[tooltipShowDelay]="800" />
<oge-button text="Muted" ogeTooltip="Never appears"
[tooltipDisabled]="true" />
`,
})
export class Demo {}
// application-wide defaults
export const appConfig: ApplicationConfig = {
providers: [
provideOgeOverlayConfig({ tooltipShowDelayMs: 300, tooltipHideDelayMs: 150 }),
],
};Context menu
Bind an OgeMenuItem array to [ogeContextMenu] and right-click opens it at the pointer, replacing the browser menu. Shift+F10 (or the menu key) opens it anchored to the element for keyboard users. The menu takes focus with full arrow-key, Home/End and type-ahead support; Escape and outside clicks close it and focus returns to the target.
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { OgeContextMenu } from '@oge-ui/overlay';
import type { OgeMenuItem } from '@oge-ui/overlay';
@Component({
selector: 'demo-root',
imports: [OgeContextMenu],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<div [ogeContextMenu]="rowMenu" tabindex="0">
Right-click me (or press Shift+F10)
</div>
`,
})
export class Demo {
// the canonical OgeMenuItem model: separators, checked state,
// danger severity, per-item actions
protected readonly rowMenu: OgeMenuItem[] = [
{ text: 'Open', value: 'open' },
{ text: 'Duplicate', value: 'duplicate' },
{ separator: true, text: '' },
{ text: 'Delete', value: 'delete', severity: 'danger' },
];
}Context menu events
contextMenuItemClick delivers the activated item with its index and the originating DOM event — the same payload as OgeMenuList. contextMenuOpened and contextMenuClosed track visibility, and items support the full menu model: checkable entries, separators, disabled state, hints and destructive severity.
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { OgeContextMenu } from '@oge-ui/overlay';
import type { OgeMenuItem } from '@oge-ui/overlay';
@Component({
selector: 'demo-root',
imports: [OgeContextMenu],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<div
[ogeContextMenu]="menu"
contextMenuAriaLabel="File actions"
(contextMenuItemClick)="run($event.item.value)"
(contextMenuOpened)="log('opened')"
(contextMenuClosed)="log('closed')"
></div>
`,
})
export class Demo {
protected readonly menu: OgeMenuItem[] = [
{ text: 'Open', value: 'open' },
{ text: 'Delete', value: 'delete', severity: 'danger' },
];
// $event: { item, index, event } — the same payload as OgeMenuList
protected run(command: unknown): void {
console.log('run', command);
}
protected log(phase: string): void {
console.log(phase);
}
}Notes
- Tooltips are transient: they never join the Escape stack, so an open tooltip cannot swallow the Escape meant for a drop-down or dialog underneath.
- The tooltip bubble is
pointer-events: none— it never blocks clicks on content beneath it. - Give context-menu targets
tabindex="0"(when they are not natively focusable) so keyboard users can reach Shift+F10 and focus can be restored after closing. - Both directives read
provideOgeOverlayConfig()for offsets, viewport padding and tooltip delays.