UNPKG

angular-confirmation-popover

Version:
370 lines (360 loc) 20.6 kB
import * as i0 from '@angular/core'; import { Injectable, Directive, Input, Component, EventEmitter, Injector, Output, HostListener, InjectionToken, NgModule } from '@angular/core'; import * as i2 from '@angular/common'; import { CommonModule } from '@angular/common'; import { positionElements } from 'positioning'; class ConfirmationPopoverOptions { constructor() { this.confirmText = 'Confirm'; this.cancelText = 'Cancel'; this.confirmButtonType = 'success'; this.cancelButtonType = 'outline-secondary'; this.placement = 'top'; this.hideConfirmButton = false; this.hideCancelButton = false; this.popoverClass = ''; this.appendToBody = false; this.reverseButtonOrder = false; this.closeOnOutsideClick = true; } } ConfirmationPopoverOptions.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.8", ngImport: i0, type: ConfirmationPopoverOptions, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); ConfirmationPopoverOptions.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.8", ngImport: i0, type: ConfirmationPopoverOptions }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.8", ngImport: i0, type: ConfirmationPopoverOptions, decorators: [{ type: Injectable }] }); /** * @internal */ class ConfirmationPopoverWindowOptions extends ConfirmationPopoverOptions { } ConfirmationPopoverWindowOptions.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.8", ngImport: i0, type: ConfirmationPopoverWindowOptions, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); ConfirmationPopoverWindowOptions.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.8", ngImport: i0, type: ConfirmationPopoverWindowOptions }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.8", ngImport: i0, type: ConfirmationPopoverWindowOptions, decorators: [{ type: Injectable }] }); /** * A helper directive to focus buttons. You will only need this if using a custom template */ class FocusDirective { constructor(elm) { this.elm = elm; } ngOnChanges(changes) { if (changes.mwlFocus && this.mwlFocus === true) { this.elm.nativeElement.focus(); } } } FocusDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.8", ngImport: i0, type: FocusDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); FocusDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.8", type: FocusDirective, selector: "[mwlFocus]", inputs: { mwlFocus: "mwlFocus" }, usesOnChanges: true, ngImport: i0 }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.8", ngImport: i0, type: FocusDirective, decorators: [{ type: Directive, args: [{ selector: '[mwlFocus]', }] }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { mwlFocus: [{ type: Input }] } }); /** * @internal */ class ConfirmationPopoverWindowComponent { constructor(options) { this.options = options; } ngAfterViewInit() { this.options.onAfterViewInit(); } } ConfirmationPopoverWindowComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.8", ngImport: i0, type: ConfirmationPopoverWindowComponent, deps: [{ token: ConfirmationPopoverWindowOptions }], target: i0.ɵɵFactoryTarget.Component }); ConfirmationPopoverWindowComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.8", type: ConfirmationPopoverWindowComponent, selector: "mwl-confirmation-popover-window", ngImport: i0, template: "<ng-template #defaultTemplate let-options=\"options\">\n <div\n [ngClass]=\"[\n 'popover',\n options.placement,\n 'popover-' + options.placement,\n 'bs-popover-' + options.placement,\n options.popoverClass\n ]\"\n >\n <div class=\"popover-arrow arrow\"></div>\n <h3\n class=\"popover-title popover-header\"\n [innerHTML]=\"options.popoverTitle\"\n ></h3>\n <div class=\"popover-content popover-body\">\n <p [innerHTML]=\"options.popoverMessage\"></p>\n <div\n class=\"confirm-btns\"\n [class.confirm-btns-reversed]=\"options.reverseButtonOrder\"\n >\n <div class=\"confirm-btn-container\" *ngIf=\"!options.hideCancelButton\">\n <button\n type=\"button\"\n [mwlFocus]=\"options.focusButton === 'cancel'\"\n [class]=\"'btn btn-block btn-' + options.cancelButtonType\"\n (click)=\"options.onCancel({ clickEvent: $event })\"\n [innerHtml]=\"options.cancelText\"\n ></button>\n </div>\n <div class=\"confirm-btn-container\" *ngIf=\"!options.hideConfirmButton\">\n <button\n type=\"button\"\n [mwlFocus]=\"options.focusButton === 'confirm'\"\n [class]=\"'btn btn-block btn-' + options.confirmButtonType\"\n (click)=\"options.onConfirm({ clickEvent: $event })\"\n [innerHtml]=\"options.confirmText\"\n ></button>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n<ng-template\n [ngTemplateOutlet]=\"options.customTemplate || defaultTemplate\"\n [ngTemplateOutletContext]=\"{ options: options }\"\n>\n</ng-template>\n", styles: [".popover{display:block}.bs-popover-top .arrow,.bs-popover-bottom .arrow{left:50%}.bs-popover-left .arrow,.bs-popover-right .arrow{top:calc(50% - 8px)}.btn{transition:none}.confirm-btns{display:flex;justify-content:space-around}.confirm-btn-container{flex-basis:50%}.confirm-btn-container:not(:first-child){margin-left:4px}.confirm-btn-container:not(:last-child){margin-right:4px}.confirm-btns-reversed{flex-direction:row-reverse}.confirm-btns-reversed .confirm-btn-container:not(:first-child){margin-right:4px;margin-left:0}.confirm-btns-reversed .confirm-btn-container:not(:last-child){margin-right:0;margin-left:4px}\n"], dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: FocusDirective, selector: "[mwlFocus]", inputs: ["mwlFocus"] }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.8", ngImport: i0, type: ConfirmationPopoverWindowComponent, decorators: [{ type: Component, args: [{ selector: 'mwl-confirmation-popover-window', template: "<ng-template #defaultTemplate let-options=\"options\">\n <div\n [ngClass]=\"[\n 'popover',\n options.placement,\n 'popover-' + options.placement,\n 'bs-popover-' + options.placement,\n options.popoverClass\n ]\"\n >\n <div class=\"popover-arrow arrow\"></div>\n <h3\n class=\"popover-title popover-header\"\n [innerHTML]=\"options.popoverTitle\"\n ></h3>\n <div class=\"popover-content popover-body\">\n <p [innerHTML]=\"options.popoverMessage\"></p>\n <div\n class=\"confirm-btns\"\n [class.confirm-btns-reversed]=\"options.reverseButtonOrder\"\n >\n <div class=\"confirm-btn-container\" *ngIf=\"!options.hideCancelButton\">\n <button\n type=\"button\"\n [mwlFocus]=\"options.focusButton === 'cancel'\"\n [class]=\"'btn btn-block btn-' + options.cancelButtonType\"\n (click)=\"options.onCancel({ clickEvent: $event })\"\n [innerHtml]=\"options.cancelText\"\n ></button>\n </div>\n <div class=\"confirm-btn-container\" *ngIf=\"!options.hideConfirmButton\">\n <button\n type=\"button\"\n [mwlFocus]=\"options.focusButton === 'confirm'\"\n [class]=\"'btn btn-block btn-' + options.confirmButtonType\"\n (click)=\"options.onConfirm({ clickEvent: $event })\"\n [innerHtml]=\"options.confirmText\"\n ></button>\n </div>\n </div>\n </div>\n </div>\n</ng-template>\n<ng-template\n [ngTemplateOutlet]=\"options.customTemplate || defaultTemplate\"\n [ngTemplateOutletContext]=\"{ options: options }\"\n>\n</ng-template>\n", styles: [".popover{display:block}.bs-popover-top .arrow,.bs-popover-bottom .arrow{left:50%}.bs-popover-left .arrow,.bs-popover-right .arrow{top:calc(50% - 8px)}.btn{transition:none}.confirm-btns{display:flex;justify-content:space-around}.confirm-btn-container{flex-basis:50%}.confirm-btn-container:not(:first-child){margin-left:4px}.confirm-btn-container:not(:last-child){margin-right:4px}.confirm-btns-reversed{flex-direction:row-reverse}.confirm-btns-reversed .confirm-btn-container:not(:first-child){margin-right:4px;margin-left:0}.confirm-btns-reversed .confirm-btn-container:not(:last-child){margin-right:0;margin-left:4px}\n"] }] }], ctorParameters: function () { return [{ type: ConfirmationPopoverWindowOptions }]; } }); /** All properties can be set on the directive as attributes like so (use `ConfirmationPopoverModule.forRoot()` to configure them globally): ```html <button class="btn btn-outline-secondary" mwlConfirmationPopover [popoverTitle]="popoverTitle" [popoverMessage]="popoverMessage" placement="left" (confirm)="confirmClicked = true" (cancel)="cancelClicked = true" [(isOpen)]="isOpen"> Show confirm popover! </button> ``` */ class ConfirmationPopoverDirective { /** * @internal */ constructor(viewContainerRef, elm, defaultOptions, renderer) { this.viewContainerRef = viewContainerRef; this.elm = elm; this.defaultOptions = defaultOptions; this.renderer = renderer; /** * Whether to disable showing the popover. Default `false`. */ this.isDisabled = false; /** * Will open or show the popover when changed. * Can be sugared with `isOpenChange` to emulate 2-way binding like so `[(isOpen)]="isOpen"` */ this.isOpen = false; /** * Will emit when the popover is opened or closed */ this.isOpenChange = new EventEmitter(true); /** * An expression that is called when the confirm button is clicked. */ this.confirm = new EventEmitter(); /** * An expression that is called when the cancel button is clicked. */ this.cancel = new EventEmitter(); this.eventListeners = []; } /** * @internal */ ngOnInit() { this.isOpenChange.emit(false); } /** * @internal */ ngOnChanges(changes) { if (changes.isOpen) { if (changes.isOpen.currentValue === true) { this.showPopover(); } else { this.hidePopover(); } } } /** * @internal */ ngOnDestroy() { this.hidePopover(); } /** * @internal */ onConfirm(event) { this.confirm.emit(event); this.hidePopover(); } /** * @internal */ onCancel(event) { this.cancel.emit(event); this.hidePopover(); } /** * @internal */ togglePopover() { if (!this.popover) { this.showPopover(); } else { this.hidePopover(); } } onDocumentClick(event) { const closeOnOutsideClick = typeof this.closeOnOutsideClick !== 'undefined' ? this.closeOnOutsideClick : this.defaultOptions.closeOnOutsideClick; if (this.popover && !this.elm.nativeElement.contains(event.target) && !this.popover.location.nativeElement.contains(event.target) && closeOnOutsideClick) { this.hidePopover(); } } showPopover() { if (!this.popover && !this.isDisabled) { // work around for https://github.com/mattlewis92/angular-confirmation-popover/issues/65 // otherwise the document click event gets fired after the click event // that triggered the popover to open (no idea why this is so) setTimeout(() => { this.eventListeners = [ this.renderer.listen('document', 'click', (event) => this.onDocumentClick(event)), this.renderer.listen('document', 'touchend', (event) => this.onDocumentClick(event)), this.renderer.listen('window', 'resize', () => this.positionPopover()), ]; }); const options = new ConfirmationPopoverWindowOptions(); Object.assign(options, this.defaultOptions, { onConfirm: (event) => { this.onConfirm(event); }, onCancel: (event) => { this.onCancel(event); }, onAfterViewInit: () => { this.positionPopover(); }, }); const optionalParams = [ 'confirmText', 'cancelText', 'placement', 'confirmButtonType', 'cancelButtonType', 'focusButton', 'hideConfirmButton', 'hideCancelButton', 'popoverClass', 'appendToBody', 'customTemplate', 'reverseButtonOrder', 'popoverTitle', 'popoverMessage', ]; optionalParams.forEach((param) => { if (typeof this[param] !== 'undefined') { options[param] = this[param]; } }); const childInjector = Injector.create({ providers: [ { provide: ConfirmationPopoverWindowOptions, useValue: options, }, ], }); this.popover = this.viewContainerRef.createComponent(ConfirmationPopoverWindowComponent, { injector: childInjector }); if (options.appendToBody) { document.body.appendChild(this.popover.location.nativeElement); } this.isOpenChange.emit(true); } } positionPopover() { if (this.popover) { const popoverElement = this.popover.location.nativeElement.children[0]; positionElements(this.elm.nativeElement, popoverElement, this.placement || this.defaultOptions.placement, this.appendToBody || this.defaultOptions.appendToBody); } } hidePopover() { if (this.popover) { this.popover.destroy(); delete this.popover; this.isOpenChange.emit(false); this.eventListeners.forEach((fn) => fn()); this.eventListeners = []; } } } ConfirmationPopoverDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.8", ngImport: i0, type: ConfirmationPopoverDirective, deps: [{ token: i0.ViewContainerRef }, { token: i0.ElementRef }, { token: ConfirmationPopoverOptions }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive }); ConfirmationPopoverDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.8", type: ConfirmationPopoverDirective, selector: "[mwlConfirmationPopover]", inputs: { popoverTitle: "popoverTitle", popoverMessage: "popoverMessage", confirmText: "confirmText", cancelText: "cancelText", placement: "placement", confirmButtonType: "confirmButtonType", cancelButtonType: "cancelButtonType", focusButton: "focusButton", hideConfirmButton: "hideConfirmButton", hideCancelButton: "hideCancelButton", isDisabled: "isDisabled", isOpen: "isOpen", customTemplate: "customTemplate", popoverClass: "popoverClass", appendToBody: "appendToBody", reverseButtonOrder: "reverseButtonOrder", closeOnOutsideClick: "closeOnOutsideClick" }, outputs: { isOpenChange: "isOpenChange", confirm: "confirm", cancel: "cancel" }, host: { listeners: { "click": "togglePopover()" } }, usesOnChanges: true, ngImport: i0 }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.8", ngImport: i0, type: ConfirmationPopoverDirective, decorators: [{ type: Directive, args: [{ selector: '[mwlConfirmationPopover]', }] }], ctorParameters: function () { return [{ type: i0.ViewContainerRef }, { type: i0.ElementRef }, { type: ConfirmationPopoverOptions }, { type: i0.Renderer2 }]; }, propDecorators: { popoverTitle: [{ type: Input }], popoverMessage: [{ type: Input }], confirmText: [{ type: Input }], cancelText: [{ type: Input }], placement: [{ type: Input }], confirmButtonType: [{ type: Input }], cancelButtonType: [{ type: Input }], focusButton: [{ type: Input }], hideConfirmButton: [{ type: Input }], hideCancelButton: [{ type: Input }], isDisabled: [{ type: Input }], isOpen: [{ type: Input }], customTemplate: [{ type: Input }], isOpenChange: [{ type: Output }], confirm: [{ type: Output }], cancel: [{ type: Output }], popoverClass: [{ type: Input }], appendToBody: [{ type: Input }], reverseButtonOrder: [{ type: Input }], closeOnOutsideClick: [{ type: Input }], togglePopover: [{ type: HostListener, args: ['click'] }] } }); const USER_OPTIONS = new InjectionToken('confirmation popover user options'); function optionsFactory(userOptions) { const options = new ConfirmationPopoverOptions(); Object.assign(options, userOptions); return options; } class ConfirmationPopoverModule { static forRoot(options = {}) { return { ngModule: ConfirmationPopoverModule, providers: [ { provide: USER_OPTIONS, useValue: options, }, { provide: ConfirmationPopoverOptions, useFactory: optionsFactory, deps: [USER_OPTIONS], }, ], }; } } ConfirmationPopoverModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.8", ngImport: i0, type: ConfirmationPopoverModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); ConfirmationPopoverModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.8", ngImport: i0, type: ConfirmationPopoverModule, declarations: [ConfirmationPopoverDirective, ConfirmationPopoverWindowComponent, FocusDirective], imports: [CommonModule], exports: [ConfirmationPopoverDirective, FocusDirective] }); ConfirmationPopoverModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.8", ngImport: i0, type: ConfirmationPopoverModule, imports: [CommonModule] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.8", ngImport: i0, type: ConfirmationPopoverModule, decorators: [{ type: NgModule, args: [{ declarations: [ ConfirmationPopoverDirective, ConfirmationPopoverWindowComponent, FocusDirective, ], imports: [CommonModule], exports: [ConfirmationPopoverDirective, FocusDirective] }] }] }); /* * Public API Surface of angular-confirmation-popover */ /** * Generated bundle index. Do not edit. */ export { ConfirmationPopoverDirective, ConfirmationPopoverModule, FocusDirective }; //# sourceMappingURL=angular-confirmation-popover.mjs.map