ngx-bootstrap
Version:
Angular Bootstrap
842 lines (831 loc) • 30.1 kB
JavaScript
import { Injectable, InjectionToken, Component, ElementRef, Renderer2, HostListener, EventEmitter, Directive, ViewContainerRef, Optional, Inject, Input, Output, RendererFactory2, NgModule } from '@angular/core';
import { isBs3, Utils, document as document$1, window as window$1 } from 'ngx-bootstrap/utils';
import { ComponentLoaderFactory } from 'ngx-bootstrap/component-loader';
import { PositioningService } from 'ngx-bootstrap/positioning';
import { FocusTrapModule } from 'ngx-bootstrap/focus-trap';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
class BsModalRef {
constructor() {
/**
* Hides the modal
*/
this.hide = () => void 0;
/**
* Sets new class to modal window
*/
this.setClass = () => void 0;
}
}
BsModalRef.decorators = [
{ type: Injectable }
];
class ModalBackdropOptions {
constructor(options) {
this.animate = true;
Object.assign(this, options);
}
}
class ModalOptions {
}
ModalOptions.decorators = [
{ type: Injectable }
];
const modalConfigDefaults = {
backdrop: true,
keyboard: true,
focus: true,
show: false,
ignoreBackdropClick: false,
class: '',
animated: true,
initialState: {},
closeInterceptor: void 0
};
const MODAL_CONFIG_DEFAULT_OVERRIDE = new InjectionToken('override-default-config');
const CLASS_NAME = {
SCROLLBAR_MEASURER: 'modal-scrollbar-measure',
BACKDROP: 'modal-backdrop',
OPEN: 'modal-open',
FADE: 'fade',
IN: 'in',
SHOW: 'show' // bs4
};
const SELECTOR = {
DIALOG: '.modal-dialog',
DATA_TOGGLE: '[data-toggle="modal"]',
DATA_DISMISS: '[data-dismiss="modal"]',
FIXED_CONTENT: '.navbar-fixed-top, .navbar-fixed-bottom, .is-fixed'
};
const TRANSITION_DURATIONS = {
MODAL: 300,
BACKDROP: 150
};
const DISMISS_REASONS = {
BACKRDOP: 'backdrop-click',
ESC: 'esc',
BACK: 'browser-back-navigation-clicked'
};
class ModalContainerComponent {
constructor(options, _element, _renderer) {
this._element = _element;
this._renderer = _renderer;
this.isShown = false;
this.isAnimated = false;
this.isModalHiding = false;
this.clickStartedInContent = false;
this.config = Object.assign({}, options);
}
ngOnInit() {
if (this.isAnimated) {
this._renderer.addClass(this._element.nativeElement, CLASS_NAME.FADE);
}
this._renderer.setStyle(this._element.nativeElement, 'display', 'block');
setTimeout(() => {
this.isShown = true;
this._renderer.addClass(this._element.nativeElement, isBs3() ? CLASS_NAME.IN : CLASS_NAME.SHOW);
}, this.isAnimated ? TRANSITION_DURATIONS.BACKDROP : 0);
if (document && document.body) {
if (this.bsModalService && this.bsModalService.getModalsCount() === 1) {
this.bsModalService.checkScrollbar();
this.bsModalService.setScrollbar();
}
this._renderer.addClass(document.body, CLASS_NAME.OPEN);
}
if (this._element.nativeElement) {
this._element.nativeElement.focus();
}
}
onClickStarted(event) {
this.clickStartedInContent = event.target !== this._element.nativeElement;
}
onClickStop(event) {
var _a;
const clickedInBackdrop = event.target === this._element.nativeElement && !this.clickStartedInContent;
if (this.config.ignoreBackdropClick ||
this.config.backdrop === 'static' ||
!clickedInBackdrop) {
this.clickStartedInContent = false;
return;
}
(_a = this.bsModalService) === null || _a === void 0 ? void 0 : _a.setDismissReason(DISMISS_REASONS.BACKRDOP);
this.hide();
}
onPopState() {
var _a;
(_a = this.bsModalService) === null || _a === void 0 ? void 0 : _a.setDismissReason(DISMISS_REASONS.BACK);
this.hide();
}
onEsc(event) {
var _a, _b;
if (!this.isShown) {
return;
}
if (event.keyCode === 27 || event.key === 'Escape') {
event.preventDefault();
}
if (this.config.keyboard &&
this.level === ((_a = this.bsModalService) === null || _a === void 0 ? void 0 : _a.getModalsCount())) {
(_b = this.bsModalService) === null || _b === void 0 ? void 0 : _b.setDismissReason(DISMISS_REASONS.ESC);
this.hide();
}
}
ngOnDestroy() {
if (this.isShown) {
this._hide();
}
}
hide() {
if (this.isModalHiding || !this.isShown) {
return;
}
if (this.config.closeInterceptor) {
this.config.closeInterceptor().then(() => this._hide(), () => undefined);
return;
}
this._hide();
}
_hide() {
this.isModalHiding = true;
this._renderer.removeClass(this._element.nativeElement, isBs3() ? CLASS_NAME.IN : CLASS_NAME.SHOW);
setTimeout(() => {
var _a, _b;
this.isShown = false;
if (document &&
document.body &&
((_a = this.bsModalService) === null || _a === void 0 ? void 0 : _a.getModalsCount()) === 1) {
this._renderer.removeClass(document.body, CLASS_NAME.OPEN);
}
(_b = this.bsModalService) === null || _b === void 0 ? void 0 : _b.hide(this.config.id);
this.isModalHiding = false;
}, this.isAnimated ? TRANSITION_DURATIONS.MODAL : 0);
}
}
ModalContainerComponent.decorators = [
{ type: Component, args: [{
selector: 'modal-container',
template: `
<div [class]="'modal-dialog' + (config.class ? ' ' + config.class : '')"
role="document"
focusTrap>
<div class="modal-content">
<ng-content></ng-content>
</div>
</div>
`,
// eslint-disable-next-line @angular-eslint/no-host-metadata-property
host: {
class: 'modal',
role: 'dialog',
tabindex: '-1',
'[attr.aria-modal]': 'true',
'[attr.aria-labelledby]': 'config.ariaLabelledBy',
'[attr.aria-describedby]': 'config.ariaDescribedby'
}
},] }
];
ModalContainerComponent.ctorParameters = () => [
{ type: ModalOptions },
{ type: ElementRef },
{ type: Renderer2 }
];
ModalContainerComponent.propDecorators = {
onClickStarted: [{ type: HostListener, args: ['mousedown', ['$event'],] }],
onClickStop: [{ type: HostListener, args: ['click', ['$event'],] }],
onPopState: [{ type: HostListener, args: ['window:popstate',] }],
onEsc: [{ type: HostListener, args: ['window:keydown.esc', ['$event'],] }]
};
/** This component will be added as background layout for modals if enabled */
class ModalBackdropComponent {
constructor(element, renderer) {
this._isAnimated = false;
this._isShown = false;
this.element = element;
this.renderer = renderer;
}
get isAnimated() {
return this._isAnimated;
}
set isAnimated(value) {
this._isAnimated = value;
}
get isShown() {
return this._isShown;
}
set isShown(value) {
this._isShown = value;
if (value) {
this.renderer.addClass(this.element.nativeElement, `${CLASS_NAME.IN}`);
}
else {
this.renderer.removeClass(this.element.nativeElement, `${CLASS_NAME.IN}`);
}
if (!isBs3()) {
if (value) {
this.renderer.addClass(this.element.nativeElement, `${CLASS_NAME.SHOW}`);
}
else {
this.renderer.removeClass(this.element.nativeElement, `${CLASS_NAME.SHOW}`);
}
}
}
ngOnInit() {
if (this.isAnimated) {
this.renderer.addClass(this.element.nativeElement, `${CLASS_NAME.FADE}`);
Utils.reflow(this.element.nativeElement);
}
this.isShown = true;
}
}
ModalBackdropComponent.decorators = [
{ type: Component, args: [{
selector: 'bs-modal-backdrop',
template: ' ',
// eslint-disable-next-line @angular-eslint/no-host-metadata-property
host: { class: CLASS_NAME.BACKDROP }
},] }
];
ModalBackdropComponent.ctorParameters = () => [
{ type: ElementRef },
{ type: Renderer2 }
];
// todo: should we support enforce focus in?
const TRANSITION_DURATION = 300;
const BACKDROP_TRANSITION_DURATION = 150;
/** Mark any code with directive to show it's content in modal */
class ModalDirective {
constructor(_element, _viewContainerRef, _renderer, clf, modalDefaultOption) {
this._element = _element;
this._renderer = _renderer;
/** This event fires immediately when the `show` instance method is called. */
this.onShow = new EventEmitter();
/** This event is fired when the modal has been made visible to the user
* (will wait for CSS transitions to complete)
*/
this.onShown = new EventEmitter();
/** This event is fired immediately when
* the hide instance method has been called.
*/
this.onHide = new EventEmitter();
/** This event is fired when the modal has finished being
* hidden from the user (will wait for CSS transitions to complete).
*/
this.onHidden = new EventEmitter();
this._isShown = false;
this.isBodyOverflowing = false;
this.originalBodyPadding = 0;
this.scrollbarWidth = 0;
this.timerHideModal = 0;
this.timerRmBackDrop = 0;
this.isNested = false;
this.clickStartedInContent = false;
this._backdrop = clf.createLoader(_element, _viewContainerRef, _renderer);
this._config = modalDefaultOption || modalConfigDefaults;
}
/** allows to set modal configuration via element property */
set config(conf) {
this._config = this.getConfig(conf);
}
get config() {
return this._config;
}
get isShown() {
return this._isShown;
}
onClickStarted(event) {
this.clickStartedInContent = event.target !== this._element.nativeElement;
}
onClickStop(event) {
const clickedInBackdrop = event.target === this._element.nativeElement && !this.clickStartedInContent;
if (this.config.ignoreBackdropClick ||
this.config.backdrop === 'static' ||
!clickedInBackdrop) {
this.clickStartedInContent = false;
return;
}
this.dismissReason = DISMISS_REASONS.BACKRDOP;
this.hide(event);
}
// todo: consider preventing default and stopping propagation
onEsc(event) {
if (!this._isShown) {
return;
}
if (event.keyCode === 27 || event.key === 'Escape') {
event.preventDefault();
}
if (this.config.keyboard) {
this.dismissReason = DISMISS_REASONS.ESC;
this.hide();
}
}
ngOnDestroy() {
if (this._isShown) {
this._isShown = false;
this.hideModal();
this._backdrop.dispose();
}
}
ngOnInit() {
this._config = this._config || this.getConfig();
setTimeout(() => {
if (this._config.show) {
this.show();
}
}, 0);
}
/* Public methods */
/** Allows to manually toggle modal visibility */
toggle() {
return this._isShown ? this.hide() : this.show();
}
/** Allows to manually open modal */
show() {
this.dismissReason = void 0;
this.onShow.emit(this);
if (this._isShown) {
return;
}
clearTimeout(this.timerHideModal);
clearTimeout(this.timerRmBackDrop);
this._isShown = true;
this.checkScrollbar();
this.setScrollbar();
if (document$1 && document$1.body) {
if (document$1.body.classList.contains(CLASS_NAME.OPEN)) {
this.isNested = true;
}
else {
this._renderer.addClass(document$1.body, CLASS_NAME.OPEN);
}
}
this.showBackdrop(() => {
this.showElement();
});
}
/** Check if we can close the modal */
hide(event) {
if (!this._isShown) {
return;
}
if (event) {
event.preventDefault();
}
if (this.config.closeInterceptor) {
this.config.closeInterceptor().then(() => this._hide(), () => undefined);
return;
}
this._hide();
}
/** Private methods @internal */
/**
* Manually close modal
* @internal
*/
_hide() {
this.onHide.emit(this);
window$1.clearTimeout(this.timerHideModal);
window$1.clearTimeout(this.timerRmBackDrop);
this._isShown = false;
this._renderer.removeClass(this._element.nativeElement, CLASS_NAME.IN);
if (!isBs3()) {
this._renderer.removeClass(this._element.nativeElement, CLASS_NAME.SHOW);
}
// this._addClassIn = false;
if (this._config.animated) {
this.timerHideModal = window$1.setTimeout(() => this.hideModal(), TRANSITION_DURATION);
}
else {
this.hideModal();
}
}
getConfig(config) {
return Object.assign({}, this._config, config);
}
/**
* Show dialog
* @internal
*/
showElement() {
// todo: replace this with component loader usage
if (!this._element.nativeElement.parentNode ||
this._element.nativeElement.parentNode.nodeType !== Node.ELEMENT_NODE) {
// don't move modals dom position
if (document$1 && document$1.body) {
document$1.body.appendChild(this._element.nativeElement);
}
}
this._renderer.setAttribute(this._element.nativeElement, 'aria-hidden', 'false');
this._renderer.setAttribute(this._element.nativeElement, 'aria-modal', 'true');
this._renderer.setStyle(this._element.nativeElement, 'display', 'block');
this._renderer.setProperty(this._element.nativeElement, 'scrollTop', 0);
if (this._config.animated) {
Utils.reflow(this._element.nativeElement);
}
// this._addClassIn = true;
this._renderer.addClass(this._element.nativeElement, CLASS_NAME.IN);
if (!isBs3()) {
this._renderer.addClass(this._element.nativeElement, CLASS_NAME.SHOW);
}
const transitionComplete = () => {
if (this._config.focus) {
this._element.nativeElement.focus();
}
this.onShown.emit(this);
};
if (this._config.animated) {
setTimeout(transitionComplete, TRANSITION_DURATION);
}
else {
transitionComplete();
}
}
/** @internal */
hideModal() {
this._renderer.setAttribute(this._element.nativeElement, 'aria-hidden', 'true');
this._renderer.setStyle(this._element.nativeElement, 'display', 'none');
this.showBackdrop(() => {
if (!this.isNested) {
if (document$1 && document$1.body) {
this._renderer.removeClass(document$1.body, CLASS_NAME.OPEN);
}
this.resetScrollbar();
}
this.resetAdjustments();
this.focusOtherModal();
this.onHidden.emit(this);
});
}
// todo: original show was calling a callback when done, but we can use
// promise
/** @internal */
showBackdrop(callback) {
if (this._isShown &&
this.config.backdrop &&
(!this.backdrop || !this.backdrop.instance.isShown)) {
this.removeBackdrop();
this._backdrop
.attach(ModalBackdropComponent)
.to('body')
.show({ isAnimated: this._config.animated });
this.backdrop = this._backdrop._componentRef;
if (!callback) {
return;
}
if (!this._config.animated) {
callback();
return;
}
setTimeout(callback, BACKDROP_TRANSITION_DURATION);
}
else if (!this._isShown && this.backdrop) {
this.backdrop.instance.isShown = false;
const callbackRemove = () => {
this.removeBackdrop();
if (callback) {
callback();
}
};
if (this.backdrop.instance.isAnimated) {
this.timerRmBackDrop = window$1.setTimeout(callbackRemove, BACKDROP_TRANSITION_DURATION);
}
else {
callbackRemove();
}
}
else if (callback) {
callback();
}
}
/** @internal */
removeBackdrop() {
this._backdrop.hide();
}
/** Events tricks */
// no need for it
// protected setEscapeEvent():void {
// if (this._isShown && this._config.keyboard) {
// $(this._element).on(Event.KEYDOWN_DISMISS, (event) => {
// if (event.which === 27) {
// this.hide()
// }
// })
//
// } else if (!this._isShown) {
// $(this._element).off(Event.KEYDOWN_DISMISS)
// }
// }
// protected setResizeEvent():void {
// console.log(this.renderer.listenGlobal('', Event.RESIZE));
// if (this._isShown) {
// $(window).on(Event.RESIZE, $.proxy(this._handleUpdate, this))
// } else {
// $(window).off(Event.RESIZE)
// }
// }
focusOtherModal() {
if (this._element.nativeElement.parentElement == null) {
return;
}
const otherOpenedModals = this._element.nativeElement.parentElement.querySelectorAll('.in[bsModal]');
if (!otherOpenedModals.length) {
return;
}
otherOpenedModals[otherOpenedModals.length - 1].focus();
}
/** @internal */
resetAdjustments() {
this._renderer.setStyle(this._element.nativeElement, 'paddingLeft', '');
this._renderer.setStyle(this._element.nativeElement, 'paddingRight', '');
}
/** Scroll bar tricks */
/** @internal */
checkScrollbar() {
this.isBodyOverflowing = document$1.body.clientWidth < window$1.innerWidth;
this.scrollbarWidth = this.getScrollbarWidth();
}
setScrollbar() {
if (!document$1) {
return;
}
this.originalBodyPadding = parseInt(window$1
.getComputedStyle(document$1.body)
.getPropertyValue('padding-right') || 0, 10);
if (this.isBodyOverflowing) {
document$1.body.style.paddingRight = `${this.originalBodyPadding +
this.scrollbarWidth}px`;
}
}
resetScrollbar() {
document$1.body.style.paddingRight = `${this.originalBodyPadding}px`;
}
// thx d.walsh
getScrollbarWidth() {
const scrollDiv = this._renderer.createElement('div');
this._renderer.addClass(scrollDiv, CLASS_NAME.SCROLLBAR_MEASURER);
this._renderer.appendChild(document$1.body, scrollDiv);
const scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
this._renderer.removeChild(document$1.body, scrollDiv);
return scrollbarWidth;
}
}
ModalDirective.decorators = [
{ type: Directive, args: [{
selector: '[bsModal]',
exportAs: 'bs-modal'
},] }
];
ModalDirective.ctorParameters = () => [
{ type: ElementRef },
{ type: ViewContainerRef },
{ type: Renderer2 },
{ type: ComponentLoaderFactory },
{ type: ModalOptions, decorators: [{ type: Optional }, { type: Inject, args: [MODAL_CONFIG_DEFAULT_OVERRIDE,] }] }
];
ModalDirective.propDecorators = {
config: [{ type: Input }],
closeInterceptor: [{ type: Input }],
onShow: [{ type: Output }],
onShown: [{ type: Output }],
onHide: [{ type: Output }],
onHidden: [{ type: Output }],
onClickStarted: [{ type: HostListener, args: ['mousedown', ['$event'],] }],
onClickStop: [{ type: HostListener, args: ['mouseup', ['$event'],] }],
onEsc: [{ type: HostListener, args: ['keydown.esc', ['$event'],] }]
};
class BsModalService {
constructor(rendererFactory, clf, modalDefaultOption) {
this.clf = clf;
this.modalDefaultOption = modalDefaultOption;
this.onShow = new EventEmitter();
this.onShown = new EventEmitter();
this.onHide = new EventEmitter();
this.onHidden = new EventEmitter();
this.isBodyOverflowing = false;
this.originalBodyPadding = 0;
this.scrollbarWidth = 0;
this.modalsCount = 0;
this.loaders = [];
this._backdropLoader = this.clf.createLoader();
this._renderer = rendererFactory.createRenderer(null, null);
this.config = modalDefaultOption ?
(Object.assign({}, modalConfigDefaults, modalDefaultOption)) :
modalConfigDefaults;
}
/** Shows a modal */
show(
// eslint-disable-next-line @typescript-eslint/no-explicit-any
content, config) {
this.modalsCount++;
this._createLoaders();
// must be different per every show() call
const id = (config === null || config === void 0 ? void 0 : config.id) || (new Date()).getUTCMilliseconds();
this.config = this.modalDefaultOption ?
Object.assign({}, modalConfigDefaults, this.modalDefaultOption, config) :
Object.assign({}, modalConfigDefaults, config);
this.config.id = id;
this._showBackdrop();
this.lastDismissReason = void 0;
return this._showModal(content);
}
hide(id) {
if (this.modalsCount === 1 || id == null) {
this._hideBackdrop();
this.resetScrollbar();
}
this.modalsCount = this.modalsCount >= 1 && id != null ? this.modalsCount - 1 : 0;
setTimeout(() => {
this._hideModal(id);
this.removeLoaders(id);
}, this.config.animated ? TRANSITION_DURATIONS.BACKDROP : 0);
}
_showBackdrop() {
const isBackdropEnabled = this.config.backdrop === true || this.config.backdrop === 'static';
const isBackdropInDOM = !this.backdropRef || !this.backdropRef.instance.isShown;
if (this.modalsCount === 1) {
this.removeBackdrop();
if (isBackdropEnabled && isBackdropInDOM) {
this._backdropLoader
.attach(ModalBackdropComponent)
.to('body')
.show({ isAnimated: this.config.animated });
this.backdropRef = this._backdropLoader._componentRef;
}
}
}
_hideBackdrop() {
if (!this.backdropRef) {
return;
}
this.backdropRef.instance.isShown = false;
const duration = this.config.animated ? TRANSITION_DURATIONS.BACKDROP : 0;
setTimeout(() => this.removeBackdrop(), duration);
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
_showModal(content) {
var _a;
const modalLoader = this.loaders[this.loaders.length - 1];
if (this.config && this.config.providers) {
for (const provider of this.config.providers) {
modalLoader.provide(provider);
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const bsModalRef = new BsModalRef();
const modalContainerRef = modalLoader
.provide({ provide: ModalOptions, useValue: this.config })
.provide({ provide: BsModalRef, useValue: bsModalRef })
.attach(ModalContainerComponent)
.to('body');
bsModalRef.hide = () => { var _a; return (_a = modalContainerRef.instance) === null || _a === void 0 ? void 0 : _a.hide(); };
bsModalRef.setClass = (newClass) => {
if (modalContainerRef.instance) {
modalContainerRef.instance.config.class = newClass;
}
};
bsModalRef.onHidden = new EventEmitter();
bsModalRef.onHide = new EventEmitter();
this.copyEvent(modalLoader.onBeforeHide, bsModalRef.onHide);
this.copyEvent(modalLoader.onHidden, bsModalRef.onHidden);
// call 'show' method after assign setClass in bsModalRef.
// it makes modal component's bsModalRef available to call setClass method
modalContainerRef.show({
content,
isAnimated: this.config.animated,
initialState: this.config.initialState,
bsModalService: this,
id: this.config.id
});
if (modalContainerRef.instance) {
modalContainerRef.instance.level = this.getModalsCount();
bsModalRef.content = modalLoader.getInnerComponent();
bsModalRef.id = (_a = modalContainerRef.instance.config) === null || _a === void 0 ? void 0 : _a.id;
}
return bsModalRef;
}
_hideModal(id) {
if (id != null) {
const indexToRemove = this.loaders.findIndex(loader => { var _a; return ((_a = loader.instance) === null || _a === void 0 ? void 0 : _a.config.id) === id; });
const modalLoader = this.loaders[indexToRemove];
if (modalLoader) {
modalLoader.hide(id);
}
}
else {
this.loaders.forEach((loader) => {
if (loader.instance) {
loader.hide(loader.instance.config.id);
}
});
}
}
getModalsCount() {
return this.modalsCount;
}
setDismissReason(reason) {
this.lastDismissReason = reason;
}
removeBackdrop() {
this._renderer.removeClass(document.body, CLASS_NAME.OPEN);
this._backdropLoader.hide();
this.backdropRef = void 0;
}
/** Checks if the body is overflowing and sets scrollbar width */
/** @internal */
checkScrollbar() {
this.isBodyOverflowing = document.body.clientWidth < window.innerWidth;
this.scrollbarWidth = this.getScrollbarWidth();
}
setScrollbar() {
if (!document) {
return;
}
this.originalBodyPadding = parseInt(window
.getComputedStyle(document.body)
.getPropertyValue('padding-right') || '0', 10);
if (this.isBodyOverflowing) {
document.body.style.paddingRight = `${this.originalBodyPadding +
this.scrollbarWidth}px`;
}
}
resetScrollbar() {
document.body.style.paddingRight = `${this.originalBodyPadding}px`;
}
// thx d.walsh
getScrollbarWidth() {
const scrollDiv = this._renderer.createElement('div');
this._renderer.addClass(scrollDiv, CLASS_NAME.SCROLLBAR_MEASURER);
this._renderer.appendChild(document.body, scrollDiv);
const scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
this._renderer.removeChild(document.body, scrollDiv);
return scrollbarWidth;
}
_createLoaders() {
const loader = this.clf.createLoader();
this.copyEvent(loader.onBeforeShow, this.onShow);
this.copyEvent(loader.onShown, this.onShown);
this.copyEvent(loader.onBeforeHide, this.onHide);
this.copyEvent(loader.onHidden, this.onHidden);
this.loaders.push(loader);
}
removeLoaders(id) {
if (id != null) {
const indexToRemove = this.loaders.findIndex(loader => { var _a; return ((_a = loader.instance) === null || _a === void 0 ? void 0 : _a.config.id) === id; });
if (indexToRemove >= 0) {
this.loaders.splice(indexToRemove, 1);
this.loaders.forEach((loader, i) => {
if (loader.instance) {
loader.instance.level = i + 1;
}
});
}
}
else {
this.loaders.splice(0, this.loaders.length);
}
}
copyEvent(from, to) {
from.subscribe((data) => {
to.emit(this.lastDismissReason || data);
});
}
}
BsModalService.decorators = [
{ type: Injectable }
];
BsModalService.ctorParameters = () => [
{ type: RendererFactory2 },
{ type: ComponentLoaderFactory },
{ type: ModalOptions, decorators: [{ type: Optional }, { type: Inject, args: [MODAL_CONFIG_DEFAULT_OVERRIDE,] }] }
];
const focusTrapModule = FocusTrapModule.forRoot();
class ModalModule {
static forRoot() {
return {
ngModule: ModalModule,
providers: [BsModalService, ComponentLoaderFactory, PositioningService]
};
}
static forChild() {
return {
ngModule: ModalModule,
providers: [BsModalService, ComponentLoaderFactory, PositioningService]
};
}
}
ModalModule.decorators = [
{ type: NgModule, args: [{
imports: [FocusTrapModule],
declarations: [
ModalBackdropComponent,
ModalDirective,
ModalContainerComponent
],
exports: [ModalBackdropComponent, ModalDirective],
entryComponents: [ModalBackdropComponent, ModalContainerComponent]
},] }
];
/**
* Generated bundle index. Do not edit.
*/
export { BsModalRef, BsModalService, MODAL_CONFIG_DEFAULT_OVERRIDE, ModalBackdropComponent, ModalBackdropOptions, ModalContainerComponent, ModalDirective, ModalModule, ModalOptions, CLASS_NAME as ɵa };
//# sourceMappingURL=ngx-bootstrap-modal.js.map