Popover
Popover displays contextual information or actions in a floating container that appears relative to a trigger element. Unlike dialogs, popovers are non-modal and allow users to continue interacting with the background content.
import {PopoverModule} from "@qualcomm-ui/angular/popover"Examples
Simple
Basic popover using the simple API with a label and child content. The anchor and trigger are supplied using directives, while the content is the default slot.
<div description="Description" label="Label" q-popover>
<div q-popover-anchor>
<button q-button q-popover-trigger variant="outline">Click Me</button>
</div>
</div>
Composite
Build with the composite API for granular control. This API requires you to provide each subcomponent, but gives you full control over the structure and layout.
<div q-popover-root>
<div q-popover-anchor>
<button q-button q-popover-trigger variant="outline">Click Me</button>
</div>
<ng-template qPortal>
<div q-popover-positioner>
<div q-popover-content>
<div q-popover-arrow></div>
<div q-popover-label>Label</div>
<div q-popover-description>Description</div>
</div>
</div>
</ng-template>
</div>
Emphasis
Use emphasis to control the visual style of the popover. Two emphasis options are available: neutral (default) and brand.
import {Component} from "@angular/core"
import {ButtonModule} from "@qualcomm-ui/angular/button"
import {PopoverModule} from "@qualcomm-ui/angular/popover"
import {PortalDirective} from "@qualcomm-ui/angular-core/portal"
import type {QdsPopoverEmphasis} from "@qualcomm-ui/qds-core/popover"
@Component({
imports: [PopoverModule, ButtonModule, PortalDirective],
selector: "popover-emphasis-demo",
template: `
<div class="flex gap-4">
@for (emp of emphasisOptions; track emp) {
<div q-popover-root [emphasis]="emp">
<div q-popover-anchor>
<button emphasis="primary" q-button q-popover-trigger>
{{ emp }}
</button>
</div>
<ng-template qPortal>
<div q-popover-positioner>
<div q-popover-content>
<div q-popover-arrow></div>
<div q-popover-label>Label</div>
<div q-popover-description>This is a {{ emp }} popover.</div>
</div>
</div>
</ng-template>
</div>
}
</div>
`,
})
export class PopoverEmphasisDemo {
readonly emphasisOptions: QdsPopoverEmphasis[] = ["neutral", "brand"]
}API
q-popover
The q-popover directive extends the q-popover-root directive with the following props:
| Prop | Type |
|---|---|
Optional description text for the popover. | string |
Set to true to disable portalling behavior for the popup content. | boolean |
Set to true to hide the arrow element. | boolean |
Optional label text for the popover. | string |
stringbooleanbooleanstringComposite API
q-popover-root
| Prop | Type | Default |
|---|---|---|
Whether to automatically set focus on the first focusable
content within the popover when opened. | boolean | true |
Whether to close the popover when the escape key is pressed. | boolean | true |
Whether to close the popover when the user clicks outside the popover. | boolean | true |
The initial open state of the popover when rendered.
Use when you don't need to control the open state of the popover. | boolean | |
The document's text/writing direction. | 'ltr' | 'rtl' | "ltr" |
The style variant of the popover. | | 'neutral' | 'neutral' |
A root node to correctly resolve the Document in custom environments. i.e.,
Iframes, Electron. | () => | |
The element to focus on when the popover is opened. | () => HTMLElement | |
Whether the popover should be modal. When set to true:- interaction with outside elements will be disabled - only popover content will be visible to screen readers - scrolling is blocked - focus is trapped within the popover | boolean | false |
The controlled open state of the popover | boolean | |
The persistent elements that: - should not have pointer-events disabled - should not trigger the dismiss event | Array< | |
The options used to position the popover content. | PositioningOptions | |
On close, restore focus to the element that triggered the open event. | boolean | true |
Function called when the escape key is pressed | KeyboardEvent | |
Function called when the focus is moved outside the component | CustomEvent<{ | |
Function called when an interaction happens outside the component | | CustomEvent<{event?: E}> | |
Fired when the popover opens or closes. | { | |
Function called when the pointer is pressed down outside the component | CustomEvent<{ | |
Function called when this layer is closed due to a parent layer being closed | CustomEvent<{ |
booleanbooleanbooleanboolean'ltr' | 'rtl'
| 'neutral'
| 'brand'
() =>
| Node
| ShadowRoot
| Document
() => HTMLElement
booleantrue:- interaction with outside elements will be disabled
- only popover content will be visible to screen readers
- scrolling is blocked
- focus is trapped within the popover
booleanArray<
() => Element
>
- should not have pointer-events disabled
- should not trigger the dismiss event
PositioningOptionsbooleanKeyboardEventCustomEvent<{
event?: E
}>
| CustomEvent<{event?: E}>
| CustomEvent<{event?: E}>
{
open: boolean
}
CustomEvent<{
event?: E
}>
CustomEvent<{
originalIndex: number
originalLayer: HTMLElement
targetIndex: number
targetLayer: HTMLElement
}>
This section describes the elements of the Popover's composite API.
q-popover-label
| Prop | Type |
|---|---|
id attribute. If
omitted, a unique identifier will be generated for accessibility.) | string |
stringData Structures
PopoverPositioningOptions
| Prop | Type | Default |
|---|---|---|
The minimum padding between the arrow and the floating element's corner. | number | 4 |
The overflow boundary of the reference element | () => | |
Whether the popover should fit the viewport. | boolean | |
Whether to flip the placement when the floating element overflows the boundary. | | boolean | true |
Function that returns the anchor rect | ( | |
The main axis offset or gap between the reference and floating element | number | 8 |
Whether the popover should be hidden when the reference element is detached | boolean | |
Options to activate auto-update listeners | | boolean | true |
The offset of the floating element | { | |
Function called when the placement is computed | ( | |
Function called when the floating element is positioned or not | (data: { | |
The virtual padding around the viewport edges to check for overflow | number | |
Whether the floating element can overlap the reference element | boolean | false |
The initial placement of the floating element | | 'bottom' | 'top' |
Whether to make the floating element same width as the reference element | boolean | |
The secondary axis offset or gap between the reference and floating elements | number | |
Whether the popover should slide when it overflows. | boolean | |
The strategy to use for positioning | | 'absolute' | 'absolute' |
A callback that will be called when the popover needs to calculate its
position. | (data: { |
number() =>
| 'clippingAncestors'
| Element
| Array<Element>
| {
height: number
width: number
x: number
y: number
}
boolean| boolean
| Array<
| 'bottom'
| 'bottom-end'
| 'bottom-start'
| 'left'
| 'left-end'
| 'left-start'
| 'right'
| 'right-end'
| 'right-start'
| 'top'
| 'top-end'
| 'top-start'
>
(
element:
| HTMLElement
| VirtualElement,
) => {
height?: number
width?: number
x?: number
y?: number
}
numberboolean| boolean
| {
ancestorResize?: boolean
ancestorScroll?: boolean
animationFrame?: boolean
elementResize?: boolean
layoutShift?: boolean
}
{
crossAxis?: number
mainAxis?: number
}
(
data: ComputePositionReturn,
) => void
(data: {
placed: boolean
}) => void
numberboolean| 'bottom'
| 'bottom-end'
| 'bottom-start'
| 'left'
| 'left-end'
| 'left-start'
| 'right'
| 'right-end'
| 'right-start'
| 'top'
| 'top-end'
| 'top-start'
booleannumberboolean| 'absolute'
| 'fixed'
(data: {
updatePosition: () => Promise<void>
}) => void | Promise<void>