All Components

Popup Overview

The Popup positions a content next to a specific anchor component.

Basic Usage

The following example demonstrates the Popup in action.

<style>
  .content {
    padding: 30px;
    color: #787878;
    background-color: #fcf7f8;
    border: 1px solid rgba(0,0,0,.05);
  }
  .example-wrapper {
    min-height: 100px;
  }
</style>
@Component({
  selector: 'my-app',
  template: `
      <div class="example-config">
        <button #anchor (click)="onToggle()" class="k-button">{{toggleText}} Popup</button>
      </div>
      <div class="example-wrapper">
        <kendo-popup [popupClass]="'content popup'" [anchor]="anchor" (anchorViewportLeave)="show = false" *ngIf="show">
            <!-- User-defined content -->
                Popup content.
        </kendo-popup>
      </div>
  `
})
class AppComponent {
    private toggleText: string = "Hide";
    private show: boolean = true;

    public onToggle(): void {
        this.show = !this.show;
        this.toggleText = this.show ? "Hidе" : "Show";
    }
}

Installation

  1. Download and install the package:

    npm install --save @progress/kendo-angular-popup @angular/animations
  2. Once installed, import the PopupModule in your application root module:

    import { NgModule } from '@angular/core';
    import { BrowserModule } from '@angular/platform-browser';
    import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
    import { PopupModule } from '@progress/kendo-angular-popup';
    import { AppComponent } from './app.component';
    
    @NgModule({
       bootstrap:    [AppComponent],
       declarations: [AppComponent],
       imports:      [BrowserModule, BrowserAnimationsModule, PopupModule]
    })
    export class AppModule {
    }

Dependencies

The Popup package requires the following peer dependencies that have to be installed by your application:

  • @angular/animations
  • @angular/common
  • @angular/core
  • rxjs

The following dependencies will be installed automatically:

  • @progress/kendo-popup-common

Features

The Popup delivers the following features:

Hidden State

To show or hide the Popup, use the *ngIf directive.

<style>
  .content {
    padding: 30px;
    color: #787878;
    background-color: #fcf7f8;
    border: 1px solid rgba(0,0,0,.05);
  }
</style>
@Component({
  selector: 'my-app',
  template: `
      <button #anchor (click)="onToggle()" class="k-button">{{toggleText}} Popup</button>
      <kendo-popup [anchor]="anchor" [popupClass]="'content popup'" *ngIf="show">
        Popup content.
      </kendo-popup>
  `
})
class AppComponent {
    private toggleText: string = "Show";
    private show: boolean = false;

    public onToggle(): void {
        this.show = !this.show;
        this.toggleText = this.show ? "Hide" : "Show";
    }
}

To hide the Popup when the anchor is scrolled outside the screen boundaries, refer to the section on scrolling outside the viewport.

Animations

To disable the open or close Popup animation, use the animate directive.

<style>
  .content {
    padding: 30px;
    color: #787878;
    background-color: #fcf7f8;
    border: 1px solid rgba(0,0,0,.05);
  }
</style>
@Component({
  selector: 'my-app',
  template: `
      <button #anchor (click)="onToggle()" class="k-button">{{toggleText}} Popup</button>
      <kendo-popup [animate]="false" [anchor]="anchor" [popupClass]="'content popup'" *ngIf="show">
        Popup content.
      </kendo-popup>
  `
})
class AppComponent {
    private toggleText: string = "Show";
    private show: boolean = false;

    public onToggle(): void {
        this.show = !this.show;
        this.toggleText = this.show ? "Hide" : "Show";
    }
}

Alignment

You can align the Popup to:

To Specific Components

To align the Popup to a specific component, use the anchor property binding. The Popup opens next to the defined anchor component.

If no anchor is provided, the Popup uses the offset property value.

<style>
  .content {
    padding: 30px;
    color: #787878;
    background-color: #fcf7f8;
    border: 1px solid rgba(0,0,0,.05);
  }

  .anchor {
    width: 80px;
    height: 40px;
  }

  .example {
      display: flex;
      margin: auto 30px;
  }

  .example-content {
      margin: 200px auto;
  }
</style>
@Component({
  selector: 'my-app',
  template: `
    <div class="example">
        <div class="example-content">
          <span class="anchor content" #anchor>ANCHOR</span>
          <kendo-popup [anchor]="anchor" [popupClass]="'content'">
            Popup content.
          </kendo-popup>
        </div>
    </div>
  `
})
class AppComponent { }

To Specific Absolute Points

To align the Popup to a specific absolute point that is relative to the document, use the offset property binding. The Popup opens next to the point and uses the specified popupAlign configuration.

<style>
  .content {
    padding: 30px;
    color: #787878;
    background-color: #fcf7f8;
    border: 1px solid rgba(0,0,0,.05);
  }
</style>
@Component({
  selector: 'my-app',
  template: `
      <kendo-popup [popupClass]="'content'" [offset]="offset">
        Popup content.
      </kendo-popup>
  `
})
class AppComponent {
    /* Change left or top value to reposition the popup */
    public offset: offset = { left: 100, top: 100 };
}

Viewport Boundary Detection

To define the boundary detection behavior of the Popup, use the collision binding property. It specifies the behavior of the component when it does not fit in the viewport. By default, the Popup fits horizontally and flips vertically.

<style>
  .content {
    padding: 30px;
    color: #787878;
    background-color: #fcf7f8;
    border: 1px solid rgba(0,0,0,.05);
  }

  .anchor {
    width: 80px;
    height: 40px;
    position: relative;
  }

  .example {
      position: absolute;
  }
</style>
@Component({
  selector: 'my-app',
  template: `
    <div class="example" [style.top.px]="exampleTop">
      <div [style.position]="'relative'">
          <span #anchor class="anchor content" (click)="onToggle()">ANCHOR</span>
          <kendo-popup *ngIf="show" [anchor]="anchor" [collision]="collision" [popupClass]="'content popup'">
            Popup content.
          </kendo-popup>
      </div>
    </div>
  `
})
class AppComponent {
    private collision: Collision = { horizontal: 'flip', vertical: 'fit' };

    /* Move the 'example' to the bottom to see the collision behavior */
    private exampleTop: number = 400;

    private toggleText: string = "Show";
    private show: boolean = false;
    public onToggle(): void {
        this.show = !this.show;
    }

}

Position

You can control the positioning of the Popup by specific pivot points. Both the anchor and the Popup are treated as rectangular elements, so each has nine pivot points. It is possible to align every Popup point to an anchor point. The Popup aligns to the anchor by using its own top-right point and the bottom-right point of the anchor.

@Component({
  selector: 'my-app',
  template: `
    <style>
      .content {
        padding: 30px;
        color: #fff;
        background-color: #999;
        border: 1px solid rgba(0,0,0,.05);
      }

      .content p {
        margin: 0;
      }

      .anchor {
        display: block;
        width: 120px;
        margin: 200px auto;
      }
    </style>


    <div class="example-config row">
      <div class="col-sm-4 col-xs-12">
        <h4>Anchor align point</h4>
        <p>
        Horizontal <br />
        <select #anchorHorizontal [(ngModel)]="anchorAlign.horizontal" class="k-textbox">
            <option value="left">Left</option>
            <option value="center">Center</option>
            <option value="right">Right</option>
        </select>
        </p>
        <p>
        Vertical <br />
        <select #anchorVertical [(ngModel)]="anchorAlign.vertical" class="k-textbox">
            <option value="top">Top</option>
            <option value="middle">Middle</option>
            <option value="bottom">Bottom</option>
        </select>
        </p>
      </div>
      <div class="col-sm-4 col-xs-12">
        <h4>Popup align point</h4>
        <p>
        Horizontal <br />
        <select #popupHorizontal [(ngModel)]="popupAlign.horizontal" class="k-textbox">
            <option value="left">Left</option>
            <option value="center">Center</option>
            <option value="right">Right</option>
        </select>
        </p>
        <p>
        Vertical <br />
        <select #popupVertical [(ngModel)]="popupAlign.vertical" class="k-textbox">
            <option value="top">Top</option>
            <option value="middle">Middle</option>
            <option value="bottom">Bottom</option>
        </select>
        </p>
      </div>
      <div class="col-sm-4 col-xs-12">
        <h4>Popup action</h4>
        <br />
        <button (click)="onClick()" class="k-button k-primary">{{show ? 'Close Popup' : 'Open Popup'}}</button>
      </div>
    </div>

    <span #anchor class="anchor content">ANCHOR</span>
    <kendo-popup [anchor]="anchor" [anchorAlign]="anchorAlign" [popupAlign]="popupAlign" *ngIf="show">
        <div class="content">
            <p>Popup content.</p>
        </div>
    </kendo-popup>
  `
})
class AppComponent {
    private anchorAlign: Align = { horizontal: "right", vertical: "bottom" };
    private popupAlign: Align = { horizontal: "right", vertical: "top" };
    private show: boolean = false;

    private onClick(): void {
        this.show = !this.show;
    }
}

Styling

To style the host element of the Popup, just decorate the component element.

@Component({
  selector: 'my-app',
  template: `
      <style>
        .wrapper {
          padding: 20px;
          color: #fff;
          background-color: red;
        }
      </style>
      <button #anchor (click)="onToggle()" class="k-button">{{toggleText}} Popup</button>
      <kendo-popup [anchor]="anchor" class="wrapper" *ngIf="show">
        Popup content.
      </kendo-popup>
  `
})
class AppComponent {
    private toggleText: string = "Show";
    private show: boolean = false;

    public onToggle(): void {
        this.show = !this.show;
        this.toggleText = this.show ? "Hide" : "Show";
    }
}

To style the element that holds the content, use the popupClass property binding.

<style>
  .inner-wrapper {
    padding: 20px;
    color: #fff;
    background-color: red;
  }
</style>
@Component({
  selector: 'my-app',
  template: `
      <button #anchor (click)="onToggle()" class="k-button">{{toggleText}} Popup</button>
      <kendo-popup [anchor]="anchor" [popupClass]="'inner-wrapper'" *ngIf="show">
        Popup content.
      </kendo-popup>
  `
})
class AppComponent {
    private toggleText: string = "Show";
    private show: boolean = false;

    public onToggle(): void {
        this.show = !this.show;
        this.toggleText = this.show ? "Hide" : "Show";
    }
}

Common Scenarios

The Popup provides events which facilitate common use cases such as:

Scrolling outside the Viewport

The anchorViewportLeave event is triggered when the anchor is scrolled outside the screen boundaries.

<style>
    .example {
        display: flex;
        position: relative;
        margin: auto 30px;
    }

    .parent-content {
        position: relative;
        width: 300px;
        height: 300px;
        overflow: auto;
        margin: 100px auto;
        border: 2px solid #5ec232;
    }

    .content {
        position: relative;
        width: 200px;
        height: 200px;
        overflow: auto;
        margin: 300px;
        border: 2px solid #3e80ed;
    }

    .anchor {
        position: absolute;
        top: 200px;
        left: 200px;
    }
</style>
import { Component, ElementRef, Renderer } from '@angular/core';

@Component({
  selector: 'my-app',
  template: `
    <div class="example">
        <div style="position: absolute">
            <h4>Parent with overflow:scroll</h4>
        </div>
        <div class="parent-content" [scrollLeft]="250" [scrollTop]="250">
            <div class="content" [scrollLeft]="170" [scrollTop]="165">
              <button #anchor class="anchor k-button" (click)="onToggle()">Click me!</button>
              <kendo-popup class="popup" [anchor]="anchor" (anchorViewportLeave)="close()" *ngIf="show">
                Popup content.
              </kendo-popup>

              <span style="position: absolute; top: 400px; left: 400px">Bottom/Right</span>
            </div>
            <span style="position: absolute; top: 600px; left: 600px">Bottom/Right</span>
        </div>
    </div>
  `
})
class AppComponent {
    private show: boolean = false;

    public onToggle(): void {
        this.show = !this.show;
    }

    public close(): void {
        this.show = false;
    }

}

Closing the Popup on Clicking outside Its Boundaries

The document.click event closes the Popup when the user clicks outside its boundary and on the target document. If the user clicks on the Popup itself, the component remains open.

For more information about how to show or hide the Popup, refer to the section on its hidden state.

import { Component, ElementRef, HostListener, ViewChild, ViewEncapsulation } from '@angular/core';

@Component({
  selector: 'my-app',
  styles: [`
      .content {
        padding: 30px;
        color: #787878;
        background-color: #fcf7f8;
        border: 1px solid rgba(0,0,0,.05);
      }
  `],
  template: `
      <button #anchor (click)="toggle()" class="k-button">{{toggleText}} Popup</button>
      <kendo-popup #popup [anchor]="anchor" popupClass="content" *ngIf="show">
        Popup content.
      </kendo-popup>
  `,
  encapsulation: ViewEncapsulation.None
})
export class AppComponent {
    private toggleText: string = "Show";
    private show: boolean = false;

    @ViewChild('anchor') public anchor: ElementRef;
    @ViewChild('popup', { read: ElementRef }) public popup: ElementRef;

    @HostListener('keydown', ['$event'])
    public keydown(event: any): void {
        if (event.keyCode === 27) {
            this.toggle(false);
        }
    }

    @HostListener('document:click', ['$event'])
    public documentClick(event: any): void {
        if (!this.contains(event.target)) {
          this.toggle(false);
        }
    }

    public toggle(show?: boolean): void {
        this.show = show !== undefined ? show : !this.show;
        this.toggleText = this.show ? "Hide" : "Show";
    }

    private contains(target: any): boolean {
        return this.anchor.nativeElement.contains(target) ||
            (this.popup ? this.popup.nativeElement.contains(target): false);
    }
}
import { NgModule } from '@angular/core';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { BrowserModule } from '@angular/platform-browser';
import { PopupModule }  from '@progress/kendo-angular-popup';

import { AppComponent }  from './app.component';

@NgModule({
    bootstrap:    [ AppComponent ],
    declarations: [ AppComponent ],
    imports: [
      PopupModule,
      BrowserModule,
      BrowserAnimationsModule
    ]
})
export class AppModule {}
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './ng.module';

enableProdMode();

const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);
In this article