mn-angular-lib 0.0.87 → 0.0.89
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, Injectable, Optional, Inject, HostBinding, Input, Component, inject, ChangeDetectionStrategy, signal, ElementRef, DestroyRef, Self, APP_INITIALIZER, HostListener, forwardRef, Directive, Renderer2, EventEmitter, ChangeDetectorRef, TemplateRef, Output, ViewContainerRef,
|
|
2
|
+
import { InjectionToken, Injectable, Optional, Inject, HostBinding, Input, Component, inject, ChangeDetectionStrategy, signal, ElementRef, DestroyRef, Self, APP_INITIALIZER, HostListener, ViewChild, forwardRef, Directive, Renderer2, EventEmitter, ChangeDetectorRef, TemplateRef, Output, ViewContainerRef, ViewChildren, ApplicationRef, EnvironmentInjector, createComponent, Pipe, SkipSelf, Attribute } from '@angular/core';
|
|
3
3
|
export { TemplateRef, Type } from '@angular/core';
|
|
4
4
|
import { BehaviorSubject, firstValueFrom, skip, Subject, debounceTime, of, takeUntil, map, catchError } from 'rxjs';
|
|
5
5
|
import * as i1 from '@angular/common';
|
|
@@ -2133,11 +2133,15 @@ class MnMultiSelect {
|
|
|
2133
2133
|
elRef = inject(ElementRef);
|
|
2134
2134
|
lang = inject(MnLanguageService);
|
|
2135
2135
|
destroyRef = inject(DestroyRef);
|
|
2136
|
+
/** Reference to the trigger element for positioning the dropdown */
|
|
2137
|
+
triggerRef;
|
|
2136
2138
|
/** Currently selected values */
|
|
2137
2139
|
selectedValues = [];
|
|
2138
2140
|
isOpen = false;
|
|
2139
2141
|
isDisabled = false;
|
|
2140
2142
|
searchTerm = '';
|
|
2143
|
+
/** Dropdown position calculated from trigger bounding rect */
|
|
2144
|
+
dropdownStyle = { top: '0px', left: '0px', width: '0px' };
|
|
2141
2145
|
onChange = () => { };
|
|
2142
2146
|
onTouched = () => { };
|
|
2143
2147
|
builtInErrorMessages = {
|
|
@@ -2183,10 +2187,24 @@ class MnMultiSelect {
|
|
|
2183
2187
|
if (this.isDisabled)
|
|
2184
2188
|
return;
|
|
2185
2189
|
this.isOpen = !this.isOpen;
|
|
2186
|
-
if (
|
|
2190
|
+
if (this.isOpen) {
|
|
2191
|
+
this.updateDropdownPosition();
|
|
2192
|
+
}
|
|
2193
|
+
else {
|
|
2187
2194
|
this.searchTerm = '';
|
|
2188
2195
|
}
|
|
2189
2196
|
}
|
|
2197
|
+
/** Calculates the fixed position for the dropdown based on the trigger element */
|
|
2198
|
+
updateDropdownPosition() {
|
|
2199
|
+
if (!this.triggerRef)
|
|
2200
|
+
return;
|
|
2201
|
+
const rect = this.triggerRef.nativeElement.getBoundingClientRect();
|
|
2202
|
+
this.dropdownStyle = {
|
|
2203
|
+
top: `${rect.bottom}px`,
|
|
2204
|
+
left: `${rect.left}px`,
|
|
2205
|
+
width: `${rect.width}px`,
|
|
2206
|
+
};
|
|
2207
|
+
}
|
|
2190
2208
|
onDocumentClick(event) {
|
|
2191
2209
|
if (!this.elRef.nativeElement.contains(event.target)) {
|
|
2192
2210
|
if (this.isOpen) {
|
|
@@ -2195,6 +2213,13 @@ class MnMultiSelect {
|
|
|
2195
2213
|
}
|
|
2196
2214
|
}
|
|
2197
2215
|
}
|
|
2216
|
+
/** Closes the dropdown when the page or a scrollable parent is scrolled */
|
|
2217
|
+
onWindowScrollOrResize() {
|
|
2218
|
+
if (this.isOpen) {
|
|
2219
|
+
this.isOpen = false;
|
|
2220
|
+
this.searchTerm = '';
|
|
2221
|
+
}
|
|
2222
|
+
}
|
|
2198
2223
|
toggleOption(option) {
|
|
2199
2224
|
if (option.disabled)
|
|
2200
2225
|
return;
|
|
@@ -2307,11 +2332,11 @@ class MnMultiSelect {
|
|
|
2307
2332
|
});
|
|
2308
2333
|
}
|
|
2309
2334
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: MnMultiSelect, deps: [{ token: i1$2.NgControl, optional: true, self: true }], target: i0.ɵɵFactoryTarget.Component });
|
|
2310
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: MnMultiSelect, isStandalone: true, selector: "mn-lib-multi-select", inputs: { props: "props" }, host: { listeners: { "document:click": "onDocumentClick($event)" } }, ngImport: i0, template: "<div class=\"flex flex-col h-full\" [class.is-fullwidth]=\"props.fullWidth\">\n @if (uiConfig.label || props.label) {\n <label class=\"pl-2 pb-1 flex flex-row gap-x-0.5! text-base!\" [attr.for]=\"resolvedId\">\n <p>{{ uiConfig.label || props.label }}</p>\n @if (isRequired()) {\n <span class=\"text-red-500\">*</span>\n }\n </label>\n }\n\n <!-- Trigger -->\n <div\n [id]=\"resolvedId\"\n [ngClass]=\"triggerClasses\"\n class=\"relative\"\n [attr.aria-label]=\"uiConfig.ariaLabel || uiConfig.label || props.label || null\"\n [attr.aria-invalid]=\"showError || null\"\n [attr.aria-describedby]=\"showError ? resolvedId + '-error' : null\"\n [attr.aria-expanded]=\"isOpen\"\n role=\"combobox\"\n tabindex=\"0\"\n (click)=\"toggle()\"\n (keydown.enter)=\"toggle()\"\n (keydown.space)=\"toggle(); $event.preventDefault()\"\n (blur)=\"handleBlur()\"\n >\n <div class=\"flex flex-row items-center gap-x-1 flex-wrap min-h-[1.5rem]\">\n @if (selectedOptions.length === 0) {\n <span class=\"text-base-content/50\">{{ uiConfig.placeholder || props.placeholder || 'Select...' }}</span>\n } @else {\n @for (opt of selectedOptions; track opt.value) {\n <span class=\"inline-flex items-center gap-x-1 bg-base-200 text-base-content text-xs px-2 py-0.5 rounded-md\">\n {{ opt.label }}\n <button\n mnButton\n [data]=\"{ size: 'sm', variant: 'text', color: 'secondary' }\"\n type=\"button\"\n class=\"text-base-content/50 hover:text-base-content cursor-pointer\"\n (click)=\"removeOption(opt, $event)\"\n [attr.aria-label]=\"'Remove ' + opt.label\"\n >\u00D7</button>\n </span>\n }\n }\n </div>\n <div class=\"absolute right-2 top-1/2 -translate-y-1/2 pointer-events-none\">\n <svg class=\"w-4 h-4 text-base-content/50\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 12 12\">\n <path fill=\"currentColor\" d=\"M6 8L1 3h10z\"/>\n </svg>\n </div>\n </div>\n\n <!-- Dropdown -->\n @if (isOpen) {\n <div
|
|
2335
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: MnMultiSelect, isStandalone: true, selector: "mn-lib-multi-select", inputs: { props: "props" }, host: { listeners: { "document:click": "onDocumentClick($event)", "window:scroll": "onWindowScrollOrResize()", "window:resize": "onWindowScrollOrResize()" } }, viewQueries: [{ propertyName: "triggerRef", first: true, predicate: ["trigger"], descendants: true }], ngImport: i0, template: "<div class=\"flex flex-col h-full\" [class.is-fullwidth]=\"props.fullWidth\">\n @if (uiConfig.label || props.label) {\n <label class=\"pl-2 pb-1 flex flex-row gap-x-0.5! text-base!\" [attr.for]=\"resolvedId\">\n <p>{{ uiConfig.label || props.label }}</p>\n @if (isRequired()) {\n <span class=\"text-red-500\">*</span>\n }\n </label>\n }\n\n <!-- Trigger -->\n <div\n #trigger\n [id]=\"resolvedId\"\n [ngClass]=\"triggerClasses\"\n class=\"relative\"\n [attr.aria-label]=\"uiConfig.ariaLabel || uiConfig.label || props.label || null\"\n [attr.aria-invalid]=\"showError || null\"\n [attr.aria-describedby]=\"showError ? resolvedId + '-error' : null\"\n [attr.aria-expanded]=\"isOpen\"\n role=\"combobox\"\n tabindex=\"0\"\n (click)=\"toggle()\"\n (keydown.enter)=\"toggle()\"\n (keydown.space)=\"toggle(); $event.preventDefault()\"\n (blur)=\"handleBlur()\"\n >\n <div class=\"flex flex-row items-center gap-x-1 flex-wrap min-h-[1.5rem]\">\n @if (selectedOptions.length === 0) {\n <span class=\"text-base-content/50\">{{ uiConfig.placeholder || props.placeholder || 'Select...' }}</span>\n } @else {\n @for (opt of selectedOptions; track opt.value) {\n <span class=\"inline-flex items-center gap-x-1 bg-base-200 text-base-content text-xs px-2 py-0.5 rounded-md\">\n {{ opt.label }}\n <button\n mnButton\n [data]=\"{ size: 'sm', variant: 'text', color: 'secondary' }\"\n type=\"button\"\n class=\"text-base-content/50 hover:text-base-content cursor-pointer\"\n (click)=\"removeOption(opt, $event)\"\n [attr.aria-label]=\"'Remove ' + opt.label\"\n >\u00D7</button>\n </span>\n }\n }\n </div>\n <div class=\"absolute right-2 top-1/2 -translate-y-1/2 pointer-events-none\">\n <svg class=\"w-4 h-4 text-base-content/50\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 12 12\">\n <path fill=\"currentColor\" d=\"M6 8L1 3h10z\"/>\n </svg>\n </div>\n </div>\n\n <!-- Dropdown -->\n @if (isOpen) {\n <div\n class=\"fixed z-[9999] bg-base-100 border border-base-300 rounded-md shadow-lg max-h-60 overflow-auto\"\n [style.top]=\"dropdownStyle.top\"\n [style.left]=\"dropdownStyle.left\"\n [style.width]=\"dropdownStyle.width\"\n (click)=\"$event.stopPropagation()\"\n >\n @if (props.searchable) {\n <div class=\"p-2 border-b border-base-300\">\n <input\n type=\"text\"\n class=\"w-full p-1.5 text-sm border border-base-300 rounded-md outline-none focus:border-brand-500 bg-base-200 text-base-content placeholder-base-content/50\"\n [placeholder]=\"props.searchPlaceholder || 'Search...'\"\n [value]=\"searchTerm\"\n (input)=\"onSearch(($any($event.target)).value)\"\n (click)=\"$event.stopPropagation()\"\n />\n </div>\n }\n @for (opt of filteredOptions; track opt.value) {\n <div\n class=\"flex items-center gap-x-2 px-3 py-2 text-sm cursor-pointer text-base-content hover:bg-base-200\"\n [class.opacity-50]=\"opt.disabled || isMaxReached(opt)\"\n [class.pointer-events-none]=\"opt.disabled || isMaxReached(opt)\"\n (click)=\"toggleOption(opt); $event.stopPropagation()\"\n >\n <input\n type=\"checkbox\"\n class=\"w-4 h-4 accent-brand-500 pointer-events-none\"\n [checked]=\"isSelected(opt)\"\n [disabled]=\"opt.disabled || isMaxReached(opt)\"\n tabindex=\"-1\"\n />\n <span>{{ opt.label }}</span>\n </div>\n }\n @if (filteredOptions.length === 0) {\n <div class=\"px-3 py-2 text-sm text-base-content/50\">{{ uiConfig.noOptionsFound || 'No options found' }}</div>\n }\n </div>\n }\n\n @if (showError) {\n @if (props.showAllErrors) {\n <div class=\"flex flex-col gap-y-1 mt-1\">\n @for (error of errorMessages; track $index) {\n <lib-mn-error-message [errorMessage]=\"error\" [id]=\"resolvedId + '-' + $index\"></lib-mn-error-message>\n }\n </div>\n } @else {\n @if (errorMessage != null) {\n <lib-mn-error-message [errorMessage]=\"errorMessage\" [id]=\"resolvedId\"></lib-mn-error-message>\n }\n }\n }\n</div>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: MnErrorMessage, selector: "lib-mn-error-message", inputs: ["errorMessage", "id"] }, { kind: "component", type: MnButton, selector: "button[mnButton], a[mnButton]", inputs: ["data"] }] });
|
|
2311
2336
|
}
|
|
2312
2337
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: MnMultiSelect, decorators: [{
|
|
2313
2338
|
type: Component,
|
|
2314
|
-
args: [{ selector: 'mn-lib-multi-select', standalone: true, imports: [NgClass, MnErrorMessage, MnButton], template: "<div class=\"flex flex-col h-full\" [class.is-fullwidth]=\"props.fullWidth\">\n @if (uiConfig.label || props.label) {\n <label class=\"pl-2 pb-1 flex flex-row gap-x-0.5! text-base!\" [attr.for]=\"resolvedId\">\n <p>{{ uiConfig.label || props.label }}</p>\n @if (isRequired()) {\n <span class=\"text-red-500\">*</span>\n }\n </label>\n }\n\n <!-- Trigger -->\n <div\n [id]=\"resolvedId\"\n [ngClass]=\"triggerClasses\"\n class=\"relative\"\n [attr.aria-label]=\"uiConfig.ariaLabel || uiConfig.label || props.label || null\"\n [attr.aria-invalid]=\"showError || null\"\n [attr.aria-describedby]=\"showError ? resolvedId + '-error' : null\"\n [attr.aria-expanded]=\"isOpen\"\n role=\"combobox\"\n tabindex=\"0\"\n (click)=\"toggle()\"\n (keydown.enter)=\"toggle()\"\n (keydown.space)=\"toggle(); $event.preventDefault()\"\n (blur)=\"handleBlur()\"\n >\n <div class=\"flex flex-row items-center gap-x-1 flex-wrap min-h-[1.5rem]\">\n @if (selectedOptions.length === 0) {\n <span class=\"text-base-content/50\">{{ uiConfig.placeholder || props.placeholder || 'Select...' }}</span>\n } @else {\n @for (opt of selectedOptions; track opt.value) {\n <span class=\"inline-flex items-center gap-x-1 bg-base-200 text-base-content text-xs px-2 py-0.5 rounded-md\">\n {{ opt.label }}\n <button\n mnButton\n [data]=\"{ size: 'sm', variant: 'text', color: 'secondary' }\"\n type=\"button\"\n class=\"text-base-content/50 hover:text-base-content cursor-pointer\"\n (click)=\"removeOption(opt, $event)\"\n [attr.aria-label]=\"'Remove ' + opt.label\"\n >\u00D7</button>\n </span>\n }\n }\n </div>\n <div class=\"absolute right-2 top-1/2 -translate-y-1/2 pointer-events-none\">\n <svg class=\"w-4 h-4 text-base-content/50\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 12 12\">\n <path fill=\"currentColor\" d=\"M6 8L1 3h10z\"/>\n </svg>\n </div>\n </div>\n\n <!-- Dropdown -->\n @if (isOpen) {\n <div
|
|
2339
|
+
args: [{ selector: 'mn-lib-multi-select', standalone: true, imports: [NgClass, MnErrorMessage, MnButton], template: "<div class=\"flex flex-col h-full\" [class.is-fullwidth]=\"props.fullWidth\">\n @if (uiConfig.label || props.label) {\n <label class=\"pl-2 pb-1 flex flex-row gap-x-0.5! text-base!\" [attr.for]=\"resolvedId\">\n <p>{{ uiConfig.label || props.label }}</p>\n @if (isRequired()) {\n <span class=\"text-red-500\">*</span>\n }\n </label>\n }\n\n <!-- Trigger -->\n <div\n #trigger\n [id]=\"resolvedId\"\n [ngClass]=\"triggerClasses\"\n class=\"relative\"\n [attr.aria-label]=\"uiConfig.ariaLabel || uiConfig.label || props.label || null\"\n [attr.aria-invalid]=\"showError || null\"\n [attr.aria-describedby]=\"showError ? resolvedId + '-error' : null\"\n [attr.aria-expanded]=\"isOpen\"\n role=\"combobox\"\n tabindex=\"0\"\n (click)=\"toggle()\"\n (keydown.enter)=\"toggle()\"\n (keydown.space)=\"toggle(); $event.preventDefault()\"\n (blur)=\"handleBlur()\"\n >\n <div class=\"flex flex-row items-center gap-x-1 flex-wrap min-h-[1.5rem]\">\n @if (selectedOptions.length === 0) {\n <span class=\"text-base-content/50\">{{ uiConfig.placeholder || props.placeholder || 'Select...' }}</span>\n } @else {\n @for (opt of selectedOptions; track opt.value) {\n <span class=\"inline-flex items-center gap-x-1 bg-base-200 text-base-content text-xs px-2 py-0.5 rounded-md\">\n {{ opt.label }}\n <button\n mnButton\n [data]=\"{ size: 'sm', variant: 'text', color: 'secondary' }\"\n type=\"button\"\n class=\"text-base-content/50 hover:text-base-content cursor-pointer\"\n (click)=\"removeOption(opt, $event)\"\n [attr.aria-label]=\"'Remove ' + opt.label\"\n >\u00D7</button>\n </span>\n }\n }\n </div>\n <div class=\"absolute right-2 top-1/2 -translate-y-1/2 pointer-events-none\">\n <svg class=\"w-4 h-4 text-base-content/50\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 12 12\">\n <path fill=\"currentColor\" d=\"M6 8L1 3h10z\"/>\n </svg>\n </div>\n </div>\n\n <!-- Dropdown -->\n @if (isOpen) {\n <div\n class=\"fixed z-[9999] bg-base-100 border border-base-300 rounded-md shadow-lg max-h-60 overflow-auto\"\n [style.top]=\"dropdownStyle.top\"\n [style.left]=\"dropdownStyle.left\"\n [style.width]=\"dropdownStyle.width\"\n (click)=\"$event.stopPropagation()\"\n >\n @if (props.searchable) {\n <div class=\"p-2 border-b border-base-300\">\n <input\n type=\"text\"\n class=\"w-full p-1.5 text-sm border border-base-300 rounded-md outline-none focus:border-brand-500 bg-base-200 text-base-content placeholder-base-content/50\"\n [placeholder]=\"props.searchPlaceholder || 'Search...'\"\n [value]=\"searchTerm\"\n (input)=\"onSearch(($any($event.target)).value)\"\n (click)=\"$event.stopPropagation()\"\n />\n </div>\n }\n @for (opt of filteredOptions; track opt.value) {\n <div\n class=\"flex items-center gap-x-2 px-3 py-2 text-sm cursor-pointer text-base-content hover:bg-base-200\"\n [class.opacity-50]=\"opt.disabled || isMaxReached(opt)\"\n [class.pointer-events-none]=\"opt.disabled || isMaxReached(opt)\"\n (click)=\"toggleOption(opt); $event.stopPropagation()\"\n >\n <input\n type=\"checkbox\"\n class=\"w-4 h-4 accent-brand-500 pointer-events-none\"\n [checked]=\"isSelected(opt)\"\n [disabled]=\"opt.disabled || isMaxReached(opt)\"\n tabindex=\"-1\"\n />\n <span>{{ opt.label }}</span>\n </div>\n }\n @if (filteredOptions.length === 0) {\n <div class=\"px-3 py-2 text-sm text-base-content/50\">{{ uiConfig.noOptionsFound || 'No options found' }}</div>\n }\n </div>\n }\n\n @if (showError) {\n @if (props.showAllErrors) {\n <div class=\"flex flex-col gap-y-1 mt-1\">\n @for (error of errorMessages; track $index) {\n <lib-mn-error-message [errorMessage]=\"error\" [id]=\"resolvedId + '-' + $index\"></lib-mn-error-message>\n }\n </div>\n } @else {\n @if (errorMessage != null) {\n <lib-mn-error-message [errorMessage]=\"errorMessage\" [id]=\"resolvedId\"></lib-mn-error-message>\n }\n }\n }\n</div>\n" }]
|
|
2315
2340
|
}], ctorParameters: () => [{ type: i1$2.NgControl, decorators: [{
|
|
2316
2341
|
type: Optional
|
|
2317
2342
|
}, {
|
|
@@ -2319,9 +2344,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImpor
|
|
|
2319
2344
|
}] }], propDecorators: { props: [{
|
|
2320
2345
|
type: Input,
|
|
2321
2346
|
args: [{ required: true }]
|
|
2347
|
+
}], triggerRef: [{
|
|
2348
|
+
type: ViewChild,
|
|
2349
|
+
args: ['trigger', { static: false }]
|
|
2322
2350
|
}], onDocumentClick: [{
|
|
2323
2351
|
type: HostListener,
|
|
2324
2352
|
args: ['document:click', ['$event']]
|
|
2353
|
+
}], onWindowScrollOrResize: [{
|
|
2354
|
+
type: HostListener,
|
|
2355
|
+
args: ['window:scroll', []]
|
|
2356
|
+
}, {
|
|
2357
|
+
type: HostListener,
|
|
2358
|
+
args: ['window:resize', []]
|
|
2325
2359
|
}] } });
|
|
2326
2360
|
|
|
2327
2361
|
// =========================
|
|
@@ -3316,21 +3350,30 @@ var ColumnSortType;
|
|
|
3316
3350
|
* Attribute directive that applies responsive-hiding classes to table cells/headers.
|
|
3317
3351
|
* Hides the element by default and shows it as `table-cell` at the specified breakpoint.
|
|
3318
3352
|
*
|
|
3353
|
+
* Uses a static class map so Tailwind CSS can detect the full class names at build time.
|
|
3354
|
+
*
|
|
3319
3355
|
* Usage: `<td [mnHiddenBelow]="column.hiddenBelow">`
|
|
3320
3356
|
*/
|
|
3321
3357
|
class MnHiddenBelowDirective {
|
|
3358
|
+
/** The breakpoint below which the element is hidden. */
|
|
3322
3359
|
mnHiddenBelow;
|
|
3323
3360
|
el = inject(ElementRef);
|
|
3324
3361
|
renderer = inject(Renderer2);
|
|
3325
3362
|
appliedClasses = [];
|
|
3363
|
+
/** Static mapping of breakpoints to their full Tailwind class names. */
|
|
3364
|
+
classMap = {
|
|
3365
|
+
sm: ['hidden', 'sm:table-cell'],
|
|
3366
|
+
md: ['hidden', 'md:table-cell'],
|
|
3367
|
+
lg: ['hidden', 'lg:table-cell'],
|
|
3368
|
+
};
|
|
3326
3369
|
ngOnChanges() {
|
|
3327
3370
|
// Remove previously applied classes
|
|
3328
3371
|
for (const cls of this.appliedClasses) {
|
|
3329
3372
|
this.renderer.removeClass(this.el.nativeElement, cls);
|
|
3330
3373
|
}
|
|
3331
3374
|
this.appliedClasses = [];
|
|
3332
|
-
if (this.mnHiddenBelow) {
|
|
3333
|
-
const classes = [
|
|
3375
|
+
if (this.mnHiddenBelow && this.classMap[this.mnHiddenBelow]) {
|
|
3376
|
+
const classes = this.classMap[this.mnHiddenBelow];
|
|
3334
3377
|
for (const cls of classes) {
|
|
3335
3378
|
this.renderer.addClass(this.el.nativeElement, cls);
|
|
3336
3379
|
}
|
|
@@ -5017,10 +5060,15 @@ class MnModalShellComponent {
|
|
|
5017
5060
|
const stacked = this.isStacked ? ' is-stacked' : '';
|
|
5018
5061
|
return `modal-shell modal-${size}${closing}${animation}${stacked}`;
|
|
5019
5062
|
}
|
|
5063
|
+
/** Triggers the closing animation. Deferred to avoid NG0100 when called during a CD cycle. */
|
|
5020
5064
|
startClosing() {
|
|
5021
|
-
|
|
5022
|
-
|
|
5023
|
-
|
|
5065
|
+
return new Promise(resolve => {
|
|
5066
|
+
setTimeout(() => {
|
|
5067
|
+
this.isClosing = true;
|
|
5068
|
+
this.cdr.detectChanges();
|
|
5069
|
+
setTimeout(resolve, 150);
|
|
5070
|
+
});
|
|
5071
|
+
});
|
|
5024
5072
|
}
|
|
5025
5073
|
onEscapeKey(event) {
|
|
5026
5074
|
if (this.config.keyboard === KeyboardMode.ENABLED) {
|