@browninglogic/ng-modal
Version:
A simple, lightweight interface for creating layered modal dialogs in Angular 6+
212 lines (205 loc) • 9.31 kB
JavaScript
import { __decorate, __metadata } from 'tslib';
import { EventEmitter, Output, Injectable, Input, Component, NgModule } from '@angular/core';
import { filter } from 'rxjs/operators';
import { CommonModule } from '@angular/common';
/**
* Maintains the indices of all active modal windows and reports index
* changes to the relevant modals so that each modal can layer itself
* accordingly with the correct z-index.
*/
var ModalManagerService = /** @class */ (function () {
function ModalManagerService() {
/** Informs subscribers when the index of a modal on the stack changes */
this.modalIndexChanged = new EventEmitter();
/** Maintains the currently-displayed modal windows in order */
this.activeModals = new Array();
/** Starting point for the z-index of the layered modal windows */
this.startingZIndex = 1000;
}
/**
* Pushes the provided modal to the top of the stack, if it's not already there, and
* returns its index so that the component knows where to place itself via z-index
* @param modal A reference to the the modal component instance that we want to register
*/
ModalManagerService.prototype.push = function (modal) {
var modalIndex = this.activeModals.indexOf(modal);
// If the modal isn't already on the stack, then push it to the top.
if (modalIndex === -1) {
this.activeModals.push(modal);
return this.activeModals.indexOf(modal);
}
else if (modalIndex === this.activeModals.length - 1) {
// If the modal is already on the top, then don't do anything: simply return the index
return modalIndex;
}
else {
/* If the modal is already on the stack, but not on the top, then remove it and
add it to the top. */
this.removeModal(modal);
this.activeModals.push(modal);
return this.activeModals.indexOf(modal);
}
};
/**
* Removes the specified modal, if it exists.
* @param modal The modal to remove
*/
ModalManagerService.prototype.removeModal = function (modal) {
// Find the index of the modal
var modalIndex = this.activeModals.indexOf(modal);
if (modalIndex > -1) {
// If the modal exists in the array, then remove it.
this.activeModals.splice(modalIndex, 1);
/*
If we removed a modal which was not at the top of the stack,
then inform each modal above the removed modal in the stack
so that they can update their index and, by extension, z-index.
*/
for (var i = modalIndex; i < this.activeModals.length; i++) {
this.modalIndexChanged.emit([this.activeModals[i], i]);
}
}
};
__decorate([
Output(),
__metadata("design:type", Object)
], ModalManagerService.prototype, "modalIndexChanged", void 0);
ModalManagerService = __decorate([
Injectable()
], ModalManagerService);
return ModalManagerService;
}());
var ModalWindowComponent = /** @class */ (function () {
function ModalWindowComponent(modalManagerService) {
this.modalManagerService = modalManagerService;
/** Custom CSS class(es) to apply to the modal*/
this.modalClass = '';
/** Custom CSS class(es) to apply to the overlay*/
this.overlayClass = '';
/** Specifies whether the modal will close if the user clicks on the surrounding overlay */
this.closeOnOverlayClick = true;
/** Specifies whether to show the built-in close button */
this.showCloseButton = false;
/** Visibility flag for internal use*/
this._visible = false;
}
Object.defineProperty(ModalWindowComponent.prototype, "visible", {
/** Reports the visibility status of the modal window*/
get: function () {
return this._visible;
},
enumerable: true,
configurable: true
});
ModalWindowComponent.prototype.ngOnInit = function () {
var _this = this;
/*
Subscribe to changes of this modal's index on the global modal stack
so that this modal can accurately maintain its z-index
with relation to other layered modal windows
*/
this.subIndexChanged = this.modalManagerService.modalIndexChanged.pipe(
// We only care about changes to the modal's own index.
filter(function (indexChange) { return indexChange[0] === _this; })).subscribe(function (indexChange) { return _this.onIndexChanged(indexChange[1]); });
};
ModalWindowComponent.prototype.ngOnDestroy = function () {
if (this.subIndexChanged) {
this.subIndexChanged.unsubscribe();
}
};
/**
* Updates the local copy of the index when necessary so that the
* corresponding z-index will be updated in the template.
* @param newIndex new index provided by the modal management service
*/
ModalWindowComponent.prototype.onIndexChanged = function (newIndex) {
this.modalIndex = newIndex;
};
Object.defineProperty(ModalWindowComponent.prototype, "zIndex", {
/** Provides the z-index to be used in the template for layering the modal */
get: function () {
return this.modalIndex != null ? this.modalManagerService.startingZIndex + this.modalIndex : null;
},
enumerable: true,
configurable: true
});
/** Shows the modal and registers it with the modal manager */
ModalWindowComponent.prototype.show = function () {
this.modalIndex = this.modalManagerService.push(this);
this._visible = true;
};
/** Hides the modal and de-registers it with the modal manager */
ModalWindowComponent.prototype.hide = function () {
this.modalManagerService.removeModal(this);
this._visible = false;
this.modalIndex = null;
};
/**
* Handles the click event when a user clicks on the overlay.
* If the user clicked on the overlay and closeOnOverlayClick is enabled,
* then close the modal.
* @param event The mouse event provided by the browser
*/
ModalWindowComponent.prototype.onOverlayClicked = function (event) {
if (event.target.classList.contains('nm-modal-overlay') && this.closeOnOverlayClick) {
this.hide();
}
};
ModalWindowComponent.ctorParameters = function () { return [
{ type: ModalManagerService }
]; };
__decorate([
Input(),
__metadata("design:type", Object)
], ModalWindowComponent.prototype, "modalClass", void 0);
__decorate([
Input(),
__metadata("design:type", Object)
], ModalWindowComponent.prototype, "overlayClass", void 0);
__decorate([
Input(),
__metadata("design:type", Object)
], ModalWindowComponent.prototype, "closeOnOverlayClick", void 0);
__decorate([
Input(),
__metadata("design:type", Object)
], ModalWindowComponent.prototype, "showCloseButton", void 0);
ModalWindowComponent = __decorate([
Component({
selector: 'nm-modal-window',
template: "<div [class]=\"'nm-modal-overlay ' + overlayClass\" (click)=\"onOverlayClicked($event)\" [style.display]=\"visible ? 'block' : 'none'\" [style.z-index]=\"zIndex\">\n <div [class]=\"'nm-modal-window ' + modalClass\">\n <div *ngIf=\"showCloseButton\" (click)=\"hide()\" class=\"nm-modal-close-btn\">×</div>\n\n <div>\n <ng-content select=\"[header]\"></ng-content>\n </div>\n <div>\n <ng-content select=\"[body]\"></ng-content>\n </div>\n <div>\n <ng-content select=\"[footer]\"></ng-content>\n </div>\n </div>\n</div>",
styles: [".nm-modal-overlay{position:fixed;left:0;top:0;width:100%;height:100%;background:rgba(0,0,0,.2)}.nm-modal-window{position:fixed;border:2px solid grey;border-radius:15px;text-align:center;background:#fff;padding:10px 23px;display:inline-block;top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.nm-modal-close-btn{position:absolute;right:3px;top:5px;color:#888;font-weight:700;font-size:20px;cursor:pointer;width:25px;line-height:23px}.nm-modal-close-btn:hover{color:#000}"]
}),
__metadata("design:paramtypes", [ModalManagerService])
], ModalWindowComponent);
return ModalWindowComponent;
}());
var ModalManagerModule = /** @class */ (function () {
function ModalManagerModule() {
}
ModalManagerModule = __decorate([
NgModule({
imports: [
CommonModule
],
providers: [
ModalManagerService
],
declarations: [
ModalWindowComponent
],
exports: [
ModalWindowComponent
]
})
], ModalManagerModule);
return ModalManagerModule;
}());
/*
* Public API Surface of ng-modal
*/
/**
* Generated bundle index. Do not edit.
*/
export { ModalManagerModule, ModalManagerService, ModalWindowComponent };
//# sourceMappingURL=browninglogic-ng-modal.js.map