Popover
Rich content in a panel that opens from a button.
import { … } from '@inlaylab/ivorie/popover'import { ChangeDetectionStrategy, Component } from '@angular/core';
import { IvButton } from '@inlaylab/ivorie/button';
import { IV_INPUT_IMPORTS } from '@inlaylab/ivorie/input';
import { IV_POPOVER_IMPORTS } from '@inlaylab/ivorie/popover';
@Component({
selector: 'demo-popover',
imports: [IV_POPOVER_IMPORTS, IV_INPUT_IMPORTS, IvButton],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<iv-popover>
<button ivButton ivPopoverTrigger variant="outline">Open popover</button>
<iv-popover-content class="w-80">
<iv-popover-header>
<iv-popover-title>Dimensions</iv-popover-title>
<iv-popover-description>Set the dimensions for the layer.</iv-popover-description>
</iv-popover-header>
<div class="grid grid-cols-3 items-center gap-3">
<label ivLabel for="pop-width">Width</label>
<input ivInput id="pop-width" value="100%" class="col-span-2 h-8" />
<label ivLabel for="pop-height">Height</label>
<input ivInput id="pop-height" value="25px" class="col-span-2 h-8" />
</div>
</iv-popover-content>
</iv-popover>
`,
})
export default class PopoverDemo {}
Installation
npx ivorie add popoverimport { … } from '@inlaylab/ivorie/popover'Usage
import { IV_POPOVER_IMPORTS } from '@inlaylab/ivorie/popover';<iv-popover>
<button ivButton ivPopoverTrigger>Open</button>
<iv-popover-content>
<iv-popover-title>Title</iv-popover-title>
Content
</iv-popover-content>
</iv-popover>Examples
Align
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { IvButton } from '@inlaylab/ivorie/button';
import { IV_POPOVER_IMPORTS } from '@inlaylab/ivorie/popover';
@Component({
selector: 'demo-popover-align',
imports: [IV_POPOVER_IMPORTS, IvButton],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<div class="flex flex-wrap justify-center gap-3">
@for (a of aligns; track a) {
<iv-popover>
<button ivButton ivPopoverTrigger variant="outline" size="sm">{{ a }}</button>
<iv-popover-content [align]="a" class="w-40">
<iv-popover-title>Aligned {{ a }}</iv-popover-title>
</iv-popover-content>
</iv-popover>
}
</div>
`,
})
export default class PopoverAlignDemo {
protected readonly aligns = ['start', 'center', 'end'] as const;
}
API
Every part also accepts class.
iv-popover
| Name | Type | Default | Description |
|---|---|---|---|
open |
boolean (two-way) |
false |
Open state. |
iv-popover-content
| Name | Type | Default | Description |
|---|---|---|---|
side |
'top' | 'right' | 'bottom' | 'left' |
'bottom' |
Side of the trigger. Flips when there is no room. |
align |
'start' | 'center' | 'end' |
'center' |
Alignment along that side. |
sideOffset |
number |
4 |
Gap to the trigger, in px. |
alignOffset |
number |
0 |
Shift along the side, in px. |
Other parts
[ivPopoverTrigger]: toggles the popover.[ivPopoverAnchor]: positions the content against this element instead of the trigger.iv-popover-header,iv-popover-title,iv-popover-description.
Accessibility
- The content is
role="dialog", labelled byiv-popover-title. - Opening moves focus into the content. Tab stays inside. Escape or a click outside closes it and returns focus to the trigger.