Primitives
Display arbitrary content inside floating panels.
/** This example uses ng-primitives styles, which are imported from ng-primitives/example-theme/index.css in the global styles file **/
import { Component } from "@angular/core";
import { NgpButton } from "ng-primitives/button";
import { NgpPopover, NgpPopoverTrigger } from "ng-primitives/popover";
@Component({
selector: "app-root",
imports: [NgpPopoverTrigger, NgpPopover, NgpButton],
template: `
<button [ngpPopoverTrigger]="popover" ngpButton type="button">
Popover
</button>
<ng-template #popover>
<div ngpPopover>
<h3>Need Help?</h3>
<p>
Get quick tips and guidance on how to use this feature effectively.
Check out our documentation for more details!
</p>
<a target="_blank" href="https://www.youtube.com/watch?v=xvFZjo5PgG0"
>Learn More</a
>
</div>
</ng-template>
`,
styles: `
button {
padding-left: 1rem;
padding-right: 1rem;
border-radius: 0.5rem;
color: var(--ngp-text-primary);
outline: none;
height: 2.5rem;
font-weight: 500;
background-color: var(--ngp-background);
transition: background-color 300ms cubic-bezier(0.4, 0, 0.2, 1);
box-shadow: var(--ngp-button-shadow);
}
button[data-hover] {
background-color: var(--ngp-background-hover);
}
button[data-focus-visible] {
outline: 2px solid var(--ngp-focus-ring);
}
button[data-press] {
background-color: var(--ngp-background-active);
}
[ngpPopover] {
position: absolute;
display: flex;
flex-direction: column;
row-gap: 4px;
max-width: 280px;
border-radius: 0.75rem;
background: var(--ngp-background);
padding: 0.75rem 1rem;
box-shadow: var(--ngp-shadow);
border: 1px solid var(--ngp-border);
outline: none;
animation: popover-show 0.1s ease-out;
transform-origin: var(--ngp-popover-transform-origin);
}
[ngpPopover][data-exit] {
animation: popover-hide 0.1s ease-out;
}
[ngpPopover] h3 {
font-size: 13px;
font-weight: 500;
margin: 0;
color: var(--ngp-text-primary);
}
[ngpPopover] p {
font-size: 13px;
margin: 0;
color: var(--ngp-text-secondary);
}
[ngpPopover] a {
font-size: 13px;
color: var(--ngp-text-blue);
text-decoration: none;
}
@keyframes popover-show {
0% {
opacity: 0;
transform: scale(0.9);
}
100% {
opacity: 1;
transform: scale(1);
}
}
@keyframes popover-hide {
0% {
opacity: 1;
transform: scale(1);
}
100% {
opacity: 0;
transform: scale(0.9);
}
}
`,
})
export class AppComponent {}
Import the Popover primitives from ng-primitives/popover
.
import { NgpPopover, NgpPopoverTrigger } from 'ng-primitives/popover';
Assemble the popover directives in your template.
<button [ngpPopoverTrigger]="popover">Click me</button>
<ng-template #popover>
<div ngpPopover>Popover content</div>
</ng-template>
Create a popover component that uses the NgpPopover
directive.
import { Component } from '@angular/core';
import { NgpButton } from 'ng-primitives/button';
import { PopoverTrigger } from './popover-trigger';
@Component({
selector: 'app-root',
imports: [NgpButton, PopoverTrigger],
template: `
<button ngpButton appPopoverTrigger="Popover content">Popover</button>
`,
styles: `
[ngpButton] {
padding-left: 1rem;
padding-right: 1rem;
border-radius: 0.5rem;
color: var(--ngp-text-primary);
outline: none;
height: 2.5rem;
font-weight: 500;
border: none;
background-color: var(--ngp-background);
transition: background-color 300ms cubic-bezier(0.4, 0, 0.2, 1);
box-shadow: var(--ngp-button-shadow);
}
[ngpButton][data-hover] {
background-color: var(--ngp-background-hover);
}
[ngpButton][data-focus-visible] {
outline: 2px solid var(--ngp-focus-ring);
}
[ngpButton][data-press] {
background-color: var(--ngp-background-active);
}
`,
})
export default class App {}
The following directives are available to import from the ng-primitives/popover
package:
Apply the `ngpPopover` directive to an element that represents the popover. This typically would be a `div` inside an `ng-template`.[ngpPopover]
ngpPopover
Apply the `ngpPopoverTrigger` directive to an element that triggers the popover to show. Access the popover template ref.
Define if the trigger should be disabled.
Define the placement of the popover relative to the trigger.
Define the offset of the popover relative to the trigger.
Define the delay before the popover is displayed.
Define the delay before the popover is hidden.
Define whether the popover should flip when there is not enough space for the popover.
Define the container in which the popover should be attached.
Define whether the popover should close when clicking outside of it.
Define whether the popover should close when the escape key is pressed.
Defines how the popover behaves when the window is scrolled.
Provide context to the popover. This can be used to pass data to the popover content.
[ngpPopoverTrigger]
ngpPopoverTrigger
Attribute | Description |
---|---|
data-open |
Applied when the popover is open. |
For the popover to be positioned correctly relative to the trigger element, it must use absolute or fixed positioning. For example, you can use the following CSS:
[ngpPopover] {
position: absolute;
}
The ngpPopover
primitive adds a CSS custom property --ngp-popover-transform-origin
to the element that can be used to animate the popover from the trigger element.
The ngpPopover
will also add the data-enter
and data-exit
attributes to the element when it is being added or removed from the DOM. This can be used to trigger animations.
:host[data-enter] {
animation: fade-in 0.2s ease-in-out;
}
:host[data-exit] {
animation: fade-out 0.2s ease-in-out;
}
You can configure the default options for all popovers in your application by using the providePopoverConfig
function in a providers array.
import { providePopoverConfig } from 'ng-primitives/popover';
bootstrapApplication(AppComponent, {
providers: [
providePopoverConfig({
offset: 4,
placement: 'top',
showDelay: 0,
hideDelay: 0,
flip: true,
container: document.body,
closeOnOutsideClick: true,
scrollBehavior: 'reposition',
}),
],
});
Define the offset from the trigger element.
Define the placement of the popover.
Define the delay before the popover shows.
Define the delay before the popover hides.
Define if the popover should flip when it reaches the edge of the viewport.
Define the container element for the popover. This is the document body by default.
Define whether the popover should close when clicking outside of it.
Defines how the popover behaves when the window is scrolled. If set to `reposition`, the popover will adjust its position automatically during scrolling. Make sure the popover uses `position: absolute` in this mode. If set to `block`, scrolling will be disabled while the popover is open. In this case, the popover should use `position: fixed`.
Copyright © 2025 Angular Primitives