ng-overlay-container
TypeScript icon, indicating that this package has built-in type declarations

16.0.3ย โ€ขย Publicย โ€ขย Published

NgOverlayContainer ๐Ÿ—๏ธ

Making the creation of overlays a piece of ๐Ÿฐ

NPM Version Downloads per Week Downloads per Week

ng-overlay-container makes creating floating overlays for an angular application a breeze. It abstracts the angular cdk and provides a highly customizable interface for you to plug-n-use.

Table of content

Supported Versions

The major versions reflect the used Angular version
16.x.x => Angular 16
15.x.x => Angular 15
14.x.x => Angular 14
13.x.x => Angular 13
12.x.x => Angular 12
11.x.x => Angular 11
10.x.x => Angular 10
0.0.x => Angular 9

Breaking Changes

  • From v16.0.2 on there will be no default width and heigth. The size adapts dynamically to the content.

Getting Started

Install with:

$ npm i ng-overlay-container

Validate the PeerDependencies:

"peerDependencies": {
    "@angular/cdk": "^16.0.0",
    "@angular/common": "^16.0.0",
    "@angular/core": "^16.0.0",
    "@angular/material": "^16.0.0"
}

Add a material theme e.g. a prebuild one (if not done already):

"styles": [
   "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
]

If you are not using Angular Material but the Angular CDK on its own, you have to include a small set of structural styles in your global stylessheet to use the overlay correctly:

@import '@angular/cdk/overlay-prebuilt.css';

Import the NgOverlayContainerModule in your app.module:

import { NgOverlayContainerModule } from 'ng-overlay-container';

@NgModule({
    declarations: [...],
    imports: [NgOverlayContainerModule], // <-- Module import
    bootstrap: [...]
})

Usage

Global

The overlay can be displayed in the viewport unrelated to any origin element by using NgOverlayContainerConfiguration.useGlobalPositionStrategy = true.


Flexible

The overlay can also be attached to any HTMLElement via #origin

In your HTML:

<button mat-button #origin (click)="showTemplate(template)">Click me</button>

<ng-template #template let-data="data" let-close="close">
  <h2>This is a Template</h2>
  <div>This is an example with utilizing ng-template.</div>
  <div>This is data passed to the template: {{data}}</div>
  <button mat-button (click)="close({id: 2})">Close</button>
</ng-template>

Import the service in your component.ts:

import { NgOverlayContainerService } from 'ng-overlay-container';

@Component({...})
export class YourComponent {
    @ViewChild('origin', { static: false, read: ViewContainerRef }) origin: ViewContainerRef;

    constructor(private overlayContainerService: NgOverlayContainerService) { }

    /**
     * Demonstrates how to use the service with a plain text
     */
    public showText(): void {

        /**
         * Opens the ngPopoverRef
         */
        const ngPopoverRef = this.overlayContainerService.open({
            content: 'Hello World ๐ŸŒ๐Ÿš€',
            origin: this.origin.element.nativeElement
        });

        /**
         * The ngPopoverRef can be used to get data back from the component
         */
        ngPopoverRef.afterClosed$.subscribe(result => {
            console.log(result);
        });
    }

    /**
     * Demonstrates how to use the service with a TemplateRef
     * @param content Reference to the ng-template
     */
    public showTemplate(content: TemplateRef<any>): void {

        const ngPopoverRef = this.overlayContainerService.open<string, { id: number }>({
            content,
            data: 'Demo Dummy',
            origin: this.origin.element.nativeElement
        });

        ngPopoverRef.afterClosed$.subscribe(result => {
            ...
        });
    }

    /**
     * Demonstrates how to use the service with any component
     * Make sure to include the Component (in this case DemoOverlayComponent) as entryComponent in your module
     */
    public showComponent(): void {

        /**
         * You can define what the input and output data types for the this.overlayContainerService.open<T, R>() are
         * @param T The data passed into the container to be available in the embedded e.g. component
         * @param R The response data type returned from the afterClosed$ observable when calling close(data?: R)
         */
        const ngPopoverRef = this.overlayContainerService.open<{ demoInput: number[] }, { returnValue: string }>({
            content: DemoOverlayComponent,
            origin: this.origin.element.nativeElement,
            data: {
                demoInput: [1, 2, 3, 4]
            },
            /* It is also possible to pass a custom NgOverlayContainerConfiguration to override the styles and behavior */
            configuration: this.overlayConfiguration
        });

        /**
         * Retrieve stongly typed return values
         */
        ngPopoverRef.afterClosed$.subscribe(result => {
            if (result.data) {
                this.returnedValue = result.data.returnValue;
            }
        });

        /**
         * Resize the popover
         */
        ngPopoverRef.resize('100%', '100%');


        /**
         * Toggle maximize of the popover
         */
        popoverRef.toggleMaximize();

    }

    /**
    * Demonstrates ho to use the service to open the overlay unrelated to any origin element by using `NgOverlayContainerConfiguration.useGlobalPositionStrategy = true`
    */
    public showWithoutOrigin(): void {
        const ngPopoverRef = this.ngOverlayContainerService.open({
            content: 'Demonstration Centered',
            configuration: {useGlobalPositionStrategy: true}
        });
    }
}

API

Open Method Definition

/**
 * Opens an popover relative to the {@param origin} with the provided {@param content}.
 * @param T The data passed into the container to be available in the embedded e.g. component
 * @param R The response data type returned from the afterClosed$ observable when calling close(data?: R)
 * @param content The dynamic content to be rendered: 'template' | 'component' | 'text'
 * @param origin The origin to which the popover is attached. Not needed if used in combination with NgOverlayContainerConfiguration.useGlobalPositionStrategy = true. If the overlay can't be displayed on the screen, fallback positions are used
 * @param data Any data that is needed in the rendered component (accessible from the component constructor via the PopoverRef (DI)) or in the template via template variable let-data
 * @param configuration Any custom overlay configuration
 * @returns The reference to the NgPopoverRef
 */
public open<T = any, R = any>({ origin, content, data, configuration }: NgOverlayContainerParameters<T>): NgPopoverRef<T, R>

NgOverlayContainerParameters

/**
 * Parameter structure to open an overlay container
 */
export interface NgOverlayContainerParameters<T> {
  origin: HTMLElement;
  content: NgOverlayContainerContent;
  data?: T;
  configuration?: NgOverlayContainerConfiguration;
}

NgOverlayContainerContent

/**
 * Supported types of embedded content
 */
export type NgOverlayContainerContent = TemplateRef<any> | Type<any> | string;

NgOverlayContainerConfiguration

/**
 * Configuration for the overlay container
 */
export interface NgOverlayContainerConfiguration {
  width?: string;
  height?: string;
  minWidth?: number | string;
  minHeight?: number | string;
  panelClass?: string;
  hasBackdrop?: boolean;
  backdropClass?: string;
  useGlobalPositionStrategy?: boolean;
  originX?: HorizontalConnectionPos;
  originY?: VerticalConnectionPos;
  overlayX?: HorizontalConnectionPos;
  overlayY?: VerticalConnectionPos;
  offsetX?: number;
  offsetY?: number;
  isDraggable?: boolean;
  isResizable?: boolean;
  disableBackdropClose?: boolean;
  fallbackPositions?: ConnectionPositionPair[]
}

Default NgOverlayContainerConfiguration

By default the following container configuration is applied if no custom configuration is provided. Any provided panelClass will extend the ng-overlay-container.

/**
 * Default overlay container configuration
 */
export const DEFAULT_OVERLAY_CONFIGURATION: NgOverlayContainerConfiguration = {
  hasBackdrop: true,
  backdropClass: "cdk-overlay-transparent-backdrop",
  panelClass: "ng-overlay-container",
  useGlobalPositionStrategy: false,
  originX: "center",
  originY: "bottom",
  overlayX: "center",
  overlayY: "top",
  offsetX: 0,
  offsetY: 10,
  isDraggable: false,
  isResizable: true,
  disableBackdropClose: false,
  fallbackPositions: []
};

Order Of Fallback Positions

The order of fallback positions, if the overlay can't be displayed onscreen.

Custom fallback positions will have priority over the default positions.

{
  // Bottom
  originX: 'center',
  originY: 'bottom',
  overlayX: 'center',
  overlayY: 'top'
},
{
  // Right
  originX: 'end',
  originY: 'center',
  overlayX: 'start',
  overlayY: 'center'
},
{
  // Left
  originX: 'start',
  originY: 'center',
  overlayX: 'end',
  overlayY: 'center'
},
{
  // Top
  originX: 'center',
  originY: 'top',
  overlayX: 'center',
  overlayY: 'bottom'
}

Contribute

First of, thank you for considering to contribute! ๐ŸŽ‰๐Ÿ‘

Contributions, enhancements, and bug-fixes are welcome! Open an issue on GitHub and submit a pull request.

To do so, follow these steps:

  1. Fork the repository as described on the official Github Docs
  2. Open the ng-overlay-container.code-workspace
  3. Run npm install
  4. Run npm run start to run the demo application
  5. Make your changes/fix
    • Write unit tests for any code change
    • Update the README.md accordingly
    • Increase the version number in projects/ng-overlay-container/package.json
  6. Run npm run test to execute all unit tests locally
  7. Submit a pull request to bring your changes to this repository
    • Provide a description for your changes

Versions

Current Tags

  • Version
    Downloads (Last 7 Days)
    • Tag
  • 16.0.3
    17
    • latest

Version History

Package Sidebar

Install

npm i ng-overlay-container

Weekly Downloads

129

Version

16.0.3

License

MIT

Unpacked Size

120 kB

Total Files

28

Last publish

Collaborators

  • schulzi66