All Components

Popup Overview

The Popup positions a piece of 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 {
    }
  3. You are required to install one of the Kendo UI themes for Angular to style your component. For more information on how to add the styles, refer to the article on getting started.

Dependencies

The Popup package requires you to install the following peer dependencies in your application:

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

The following dependencies are automatically installed:

  • @progress/kendo-popup-common
  • The version of the @angular/animations module has to be exactly the same as the version of the other @angular modules that are included in your project. To sync the package versions, you might need to run npm update.
  • The Popup package utilizes the Angular animation system, which supports a specific set of browsers.

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 opening or closing 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 specific:

Align to Components

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

If an anchor is not provided, the Popup will use 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 { }

Align to 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

Both the anchor and the Popup are treated as rectangular elements and, as a result, each has nine pivot points. You can align every point of the Popup to an anchor point. The component will position itself by aligning its top-right point to 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, 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 which 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:

Closing after Leaving the Viewport

The anchorViewportLeave event is triggered when the anchor is scrolled outside the screen boundaries. When the anchor is not visible, use anchorViewportLeave to close the Popup—otherwise, it will remain visible within the screen boundaries.

The control over the visibility of the Popup depends on you. As a result, when the container is scrolled, the Popup will not close automatically.

<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, Renderer2 } 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 on Document or Esc Click

To close the Popup when the user clicks outside its boundaries, wire the document.click event and determine whether the Popup was clicked. If clicked, the Popup remains open.

The control over the visibility of the Popup depends on you. As a result, upon a document or Esc click, the Popup will not close automatically.

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