@skyux/modals 8.7.2 → 9.0.0-alpha.1
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.
- package/documentation.json +56 -56
- package/esm2022/lib/modules/confirm/confirm.component.mjs +112 -0
- package/{esm2020 → esm2022}/lib/modules/confirm/confirm.module.mjs +13 -13
- package/esm2022/lib/modules/confirm/confirm.service.mjs +54 -0
- package/esm2022/lib/modules/modal/modal-adapter.service.mjs +99 -0
- package/esm2022/lib/modules/modal/modal-component-adapter.service.mjs +101 -0
- package/{esm2020 → esm2022}/lib/modules/modal/modal-configuration.mjs +4 -4
- package/{esm2020 → esm2022}/lib/modules/modal/modal-content.component.mjs +4 -4
- package/esm2022/lib/modules/modal/modal-errors.service.mjs +21 -0
- package/{esm2020 → esm2022}/lib/modules/modal/modal-footer.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/modules/modal/modal-header.component.mjs +4 -4
- package/{esm2020 → esm2022}/lib/modules/modal/modal-host-context.mjs +4 -4
- package/esm2022/lib/modules/modal/modal-host.component.mjs +163 -0
- package/esm2022/lib/modules/modal/modal-host.service.mjs +62 -0
- package/esm2022/lib/modules/modal/modal-instance.mjs +123 -0
- package/esm2022/lib/modules/modal/modal-is-dirty.directive.mjs +94 -0
- package/esm2022/lib/modules/modal/modal-scroll-shadow.directive.mjs +129 -0
- package/esm2022/lib/modules/modal/modal.component.mjs +229 -0
- package/{esm2020 → esm2022}/lib/modules/modal/modal.module.mjs +29 -29
- package/esm2022/lib/modules/modal/modal.service.mjs +97 -0
- package/esm2022/lib/modules/shared/sky-modals-resources.module.mjs +61 -0
- package/esm2022/testing/confirm/confirm-button-harness.mjs +46 -0
- package/esm2022/testing/confirm/confirm-harness.mjs +90 -0
- package/esm2022/testing/modal/modal-harness.mjs +75 -0
- package/esm2022/testing/modal-fixture.mjs +143 -0
- package/{fesm2020 → fesm2022}/skyux-modals-testing.mjs +60 -73
- package/{fesm2020 → fesm2022}/skyux-modals-testing.mjs.map +1 -1
- package/fesm2022/skyux-modals.mjs +1502 -0
- package/{fesm2015 → fesm2022}/skyux-modals.mjs.map +1 -1
- package/lib/modules/modal/modal-is-dirty.directive.d.ts +1 -1
- package/lib/modules/modal/modal.component.d.ts +1 -1
- package/package.json +16 -24
- package/esm2020/lib/modules/confirm/confirm.component.mjs +0 -114
- package/esm2020/lib/modules/confirm/confirm.service.mjs +0 -57
- package/esm2020/lib/modules/modal/modal-adapter.service.mjs +0 -101
- package/esm2020/lib/modules/modal/modal-component-adapter.service.mjs +0 -104
- package/esm2020/lib/modules/modal/modal-errors.service.mjs +0 -24
- package/esm2020/lib/modules/modal/modal-host.component.mjs +0 -164
- package/esm2020/lib/modules/modal/modal-host.service.mjs +0 -65
- package/esm2020/lib/modules/modal/modal-instance.mjs +0 -127
- package/esm2020/lib/modules/modal/modal-is-dirty.directive.mjs +0 -93
- package/esm2020/lib/modules/modal/modal-scroll-shadow.directive.mjs +0 -127
- package/esm2020/lib/modules/modal/modal.component.mjs +0 -228
- package/esm2020/lib/modules/modal/modal.service.mjs +0 -99
- package/esm2020/lib/modules/shared/sky-modals-resources.module.mjs +0 -61
- package/esm2020/testing/confirm/confirm-button-harness.mjs +0 -46
- package/esm2020/testing/confirm/confirm-harness.mjs +0 -97
- package/esm2020/testing/modal/modal-harness.mjs +0 -81
- package/esm2020/testing/modal-fixture.mjs +0 -145
- package/fesm2015/skyux-modals-testing.mjs +0 -409
- package/fesm2015/skyux-modals-testing.mjs.map +0 -1
- package/fesm2015/skyux-modals.mjs +0 -1522
- package/fesm2020/skyux-modals.mjs +0 -1510
- package/fesm2020/skyux-modals.mjs.map +0 -1
- /package/{esm2020 → esm2022}/index.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/modules/confirm/confirm-button-action.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/modules/confirm/confirm-button-config.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/modules/confirm/confirm-button-style-type.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/modules/confirm/confirm-button.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/modules/confirm/confirm-closed-event-args.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/modules/confirm/confirm-config-token.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/modules/confirm/confirm-config.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/modules/confirm/confirm-instance.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/modules/confirm/confirm-type.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/modules/modal/modal-before-close-handler.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/modules/modal/modal-close-args.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/modules/modal/modal-error.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/modules/modal/modal-host-context-args.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/modules/modal/modal-scroll-shadow-event-args.mjs +0 -0
- /package/{esm2020 → esm2022}/lib/modules/modal/modal.interface.mjs +0 -0
- /package/{esm2020 → esm2022}/skyux-modals.mjs +0 -0
- /package/{esm2020 → esm2022}/testing/confirm/confirm-button-harness-filters.mjs +0 -0
- /package/{esm2020 → esm2022}/testing/modal/modal-harness-filters.mjs +0 -0
- /package/{esm2020 → esm2022}/testing/public-api.mjs +0 -0
- /package/{esm2020 → esm2022}/testing/skyux-modals-testing.mjs +0 -0
|
@@ -0,0 +1,1502 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { EventEmitter, NgModule, Component, ViewEncapsulation, Injectable, inject, Inject, Injector, ViewContainerRef, Optional, ViewChild, InjectionToken, Directive, Output, HostListener, ChangeDetectorRef, ElementRef, Host, HostBinding, Input } from '@angular/core';
|
|
3
|
+
import * as i1 from '@angular/common';
|
|
4
|
+
import { CommonModule } from '@angular/common';
|
|
5
|
+
import * as i3 from '@skyux/core';
|
|
6
|
+
import { SkyMediaQueryService, SkyResizeObserverMediaQueryService, SKY_STACKING_CONTEXT, SkyLiveAnnouncerService, SkyDockLocation, SkyDockService, SkyIdModule, SkyTrimModule } from '@skyux/core';
|
|
7
|
+
import * as i2$1 from '@skyux/theme';
|
|
8
|
+
import { SkyTheme, SkyThemeModule } from '@skyux/theme';
|
|
9
|
+
import * as i3$1 from '@angular/router';
|
|
10
|
+
import { NavigationStart, RouterModule } from '@angular/router';
|
|
11
|
+
import * as i2 from '@skyux/indicators';
|
|
12
|
+
import { SkyIconModule, SkyStatusIndicatorModule } from '@skyux/indicators';
|
|
13
|
+
import * as i2$2 from '@skyux/i18n';
|
|
14
|
+
import { getLibStringForLocale, SkyI18nModule, SKY_LIB_RESOURCES_PROVIDERS, SkyLibResourcesService } from '@skyux/i18n';
|
|
15
|
+
import { BehaviorSubject, Subject, ReplaySubject } from 'rxjs';
|
|
16
|
+
import { takeUntil, takeWhile, take } from 'rxjs/operators';
|
|
17
|
+
|
|
18
|
+
class SkyConfirmInstance {
|
|
19
|
+
constructor() {
|
|
20
|
+
/**
|
|
21
|
+
* Fires when users select an action to close the dialog. This event
|
|
22
|
+
* returns a `SkyConfirmCloseEventArgs` object with information about the button that
|
|
23
|
+
* users select. It returns the `'cancel'` action when users press the <kbd>Escape</kbd> key.
|
|
24
|
+
*/
|
|
25
|
+
this.closed = new EventEmitter();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
var SkyConfirmType;
|
|
30
|
+
(function (SkyConfirmType) {
|
|
31
|
+
/**
|
|
32
|
+
* Allows you to define your own buttons using the `buttons` property of `SkyConfirmConfig`.
|
|
33
|
+
*/
|
|
34
|
+
SkyConfirmType[SkyConfirmType["Custom"] = 0] = "Custom";
|
|
35
|
+
/**
|
|
36
|
+
* Displays one button with an **OK** label and an `'ok'` action.
|
|
37
|
+
*/
|
|
38
|
+
SkyConfirmType[SkyConfirmType["OK"] = 1] = "OK";
|
|
39
|
+
/**
|
|
40
|
+
* Displays two buttons with **Yes** and **Cancel** labels.
|
|
41
|
+
* @deprecated Use the `Custom` type to follow the guidance that labels
|
|
42
|
+
* should clearly indicate the actions that occur when users select buttons.
|
|
43
|
+
*/
|
|
44
|
+
SkyConfirmType[SkyConfirmType["YesCancel"] = 2] = "YesCancel";
|
|
45
|
+
/**
|
|
46
|
+
* Displays three buttons with **Yes**, **No**, and **Cancel** labels.
|
|
47
|
+
* @deprecated Use the `Custom` type to follow the guidance that labels
|
|
48
|
+
* should clearly indicate the actions that occur when users select buttons.
|
|
49
|
+
*/
|
|
50
|
+
SkyConfirmType[SkyConfirmType["YesNoCancel"] = 3] = "YesNoCancel";
|
|
51
|
+
})(SkyConfirmType || (SkyConfirmType = {}));
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* NOTICE: DO NOT MODIFY THIS FILE!
|
|
55
|
+
* The contents of this file were automatically generated by
|
|
56
|
+
* the 'ng generate @skyux/i18n:lib-resources-module lib/modules/shared/sky-modals' schematic.
|
|
57
|
+
* To update this file, simply rerun the command.
|
|
58
|
+
*/
|
|
59
|
+
const RESOURCES = {
|
|
60
|
+
'EN-US': {
|
|
61
|
+
skyux_confirm_dialog_default_ok_text: { message: 'OK' },
|
|
62
|
+
skyux_confirm_dialog_default_yes_text: { message: 'Yes' },
|
|
63
|
+
skyux_confirm_dialog_default_no_text: { message: 'No' },
|
|
64
|
+
skyux_confirm_dialog_default_cancel_text: { message: 'Cancel' },
|
|
65
|
+
skyux_modal_close: { message: 'Close modal' },
|
|
66
|
+
skyux_modal_open_help: { message: 'Open Help' },
|
|
67
|
+
skyux_modal_footer_cancel_button: { message: 'Cancel' },
|
|
68
|
+
skyux_modal_footer_primary_button: { message: 'Save' },
|
|
69
|
+
skyux_modal_dirty_default_message: {
|
|
70
|
+
message: 'Are you sure you want to discard your changes?',
|
|
71
|
+
},
|
|
72
|
+
skyux_modal_dirty_default_discard_changes_text: {
|
|
73
|
+
message: 'Discard changes',
|
|
74
|
+
},
|
|
75
|
+
skyux_modal_dirty_default_keep_working_text: { message: 'Keep working' },
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
class SkyModalsResourcesProvider {
|
|
79
|
+
getString(localeInfo, name) {
|
|
80
|
+
return getLibStringForLocale(RESOURCES, localeInfo.locale, name);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Import into any component library module that needs to use resource strings.
|
|
85
|
+
*/
|
|
86
|
+
class SkyModalsResourcesModule {
|
|
87
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyModalsResourcesModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
88
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.1.7", ngImport: i0, type: SkyModalsResourcesModule, exports: [SkyI18nModule] }); }
|
|
89
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyModalsResourcesModule, providers: [
|
|
90
|
+
{
|
|
91
|
+
provide: SKY_LIB_RESOURCES_PROVIDERS,
|
|
92
|
+
useClass: SkyModalsResourcesProvider,
|
|
93
|
+
multi: true,
|
|
94
|
+
},
|
|
95
|
+
], imports: [SkyI18nModule] }); }
|
|
96
|
+
}
|
|
97
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyModalsResourcesModule, decorators: [{
|
|
98
|
+
type: NgModule,
|
|
99
|
+
args: [{
|
|
100
|
+
exports: [SkyI18nModule],
|
|
101
|
+
providers: [
|
|
102
|
+
{
|
|
103
|
+
provide: SKY_LIB_RESOURCES_PROVIDERS,
|
|
104
|
+
useClass: SkyModalsResourcesProvider,
|
|
105
|
+
multi: true,
|
|
106
|
+
},
|
|
107
|
+
],
|
|
108
|
+
}]
|
|
109
|
+
}] });
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Specifies content to display in the modal's body.
|
|
113
|
+
*/
|
|
114
|
+
class SkyModalContentComponent {
|
|
115
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyModalContentComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
116
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: SkyModalContentComponent, selector: "sky-modal-content", ngImport: i0, template: "<ng-content></ng-content>\n", styles: ["sky-modal-content{display:block;min-height:100%}.sky-theme-modern sky-modal-content{padding:10px 30px 30px}\n"], encapsulation: i0.ViewEncapsulation.None }); }
|
|
117
|
+
}
|
|
118
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyModalContentComponent, decorators: [{
|
|
119
|
+
type: Component,
|
|
120
|
+
args: [{ selector: 'sky-modal-content', encapsulation: ViewEncapsulation.None, template: "<ng-content></ng-content>\n", styles: ["sky-modal-content{display:block;min-height:100%}.sky-theme-modern sky-modal-content{padding:10px 30px 30px}\n"] }]
|
|
121
|
+
}] });
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* @internal
|
|
125
|
+
*/
|
|
126
|
+
class SkyModalErrorsService {
|
|
127
|
+
#formErrors = new BehaviorSubject(undefined);
|
|
128
|
+
constructor() {
|
|
129
|
+
this.formErrors = this.#formErrors.asObservable();
|
|
130
|
+
}
|
|
131
|
+
updateErrors(value) {
|
|
132
|
+
this.#formErrors.next(value);
|
|
133
|
+
}
|
|
134
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyModalErrorsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
135
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyModalErrorsService }); }
|
|
136
|
+
}
|
|
137
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyModalErrorsService, decorators: [{
|
|
138
|
+
type: Injectable
|
|
139
|
+
}], ctorParameters: function () { return []; } });
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Specifies content to display in the modal's footer.
|
|
143
|
+
*/
|
|
144
|
+
class SkyModalFooterComponent {
|
|
145
|
+
constructor() {
|
|
146
|
+
this.errorsSvc = inject(SkyModalErrorsService);
|
|
147
|
+
}
|
|
148
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyModalFooterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
149
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: SkyModalFooterComponent, selector: "sky-modal-footer", ngImport: i0, template: "<div class=\"sky-modal-footer-container sky-padding-even-large\">\n <div aria-live=\"polite\">\n <div\n *ngIf=\"errorsSvc.formErrors | async as formErrors\"\n class=\"sky-modal-footer-errors sky-margin-stacked-lg\"\n >\n <sky-status-indicator\n *ngFor=\"let formError of formErrors\"\n [ngClass]=\"{\n 'sky-margin-stacked-lg':\n formErrors.indexOf(formError) < formErrors.length - 1,\n 'footer-error': true\n }\"\n descriptionType=\"error\"\n indicatorType=\"danger\"\n >\n {{ formError.message }}\n </sky-status-indicator>\n </div>\n </div>\n <ng-content></ng-content>\n</div>\n", styles: [".sky-modal-footer-container{background-color:#fff;border-top:1px solid #e2e3e4}.sky-modal-footer-container .sky-btn-link:first-child{margin-left:-12px}.sky-modal-footer-container .sky-btn+.sky-btn{margin-left:10px}.sky-modal-footer-container .sky-btn+.sky-btn-link{margin-left:-2px}.sky-modal-footer-container .sky-modal-footer-errors{max-height:100px;overflow-y:auto}.sky-modal-footer-container .sky-modal-footer-errors .footer-error{display:block}.sky-theme-modern .sky-modal-footer-container{border-top:none;padding:20px 30px}.sky-theme-modern .sky-modal-footer-container .sky-btn-link:first-child{margin-left:0}.sky-theme-modern .sky-modal-footer-container .sky-btn+.sky-btn-link{margin-left:var(--sky-compat-modal-footer-adjacent-btn-btn-link-margin, 10px)}.sky-theme-modern-dark .sky-modal-footer-container{background-color:transparent}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.λ10, selector: "sky-status-indicator", inputs: ["indicatorType", "descriptionType", "customDescription"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
150
|
+
}
|
|
151
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyModalFooterComponent, decorators: [{
|
|
152
|
+
type: Component,
|
|
153
|
+
args: [{ selector: 'sky-modal-footer', encapsulation: ViewEncapsulation.None, template: "<div class=\"sky-modal-footer-container sky-padding-even-large\">\n <div aria-live=\"polite\">\n <div\n *ngIf=\"errorsSvc.formErrors | async as formErrors\"\n class=\"sky-modal-footer-errors sky-margin-stacked-lg\"\n >\n <sky-status-indicator\n *ngFor=\"let formError of formErrors\"\n [ngClass]=\"{\n 'sky-margin-stacked-lg':\n formErrors.indexOf(formError) < formErrors.length - 1,\n 'footer-error': true\n }\"\n descriptionType=\"error\"\n indicatorType=\"danger\"\n >\n {{ formError.message }}\n </sky-status-indicator>\n </div>\n </div>\n <ng-content></ng-content>\n</div>\n", styles: [".sky-modal-footer-container{background-color:#fff;border-top:1px solid #e2e3e4}.sky-modal-footer-container .sky-btn-link:first-child{margin-left:-12px}.sky-modal-footer-container .sky-btn+.sky-btn{margin-left:10px}.sky-modal-footer-container .sky-btn+.sky-btn-link{margin-left:-2px}.sky-modal-footer-container .sky-modal-footer-errors{max-height:100px;overflow-y:auto}.sky-modal-footer-container .sky-modal-footer-errors .footer-error{display:block}.sky-theme-modern .sky-modal-footer-container{border-top:none;padding:20px 30px}.sky-theme-modern .sky-modal-footer-container .sky-btn-link:first-child{margin-left:0}.sky-theme-modern .sky-modal-footer-container .sky-btn+.sky-btn-link{margin-left:var(--sky-compat-modal-footer-adjacent-btn-btn-link-margin, 10px)}.sky-theme-modern-dark .sky-modal-footer-container{background-color:transparent}\n"] }]
|
|
154
|
+
}] });
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Specifies a header for the modal.
|
|
158
|
+
*/
|
|
159
|
+
class SkyModalHeaderComponent {
|
|
160
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyModalHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
161
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: SkyModalHeaderComponent, selector: "sky-modal-header", ngImport: i0, template: "<h2\n class=\"sky-font-emphasized\"\n [skyThemeClass]=\"{\n 'sky-font-heading-4': 'default',\n 'sky-font-display-3': 'modern'\n }\"\n skyTrim\n>\n <ng-content></ng-content>\n</h2>\n<span class=\"sky-control-help-container\" skyTrim\n ><ng-content select=\".sky-control-help\"></ng-content\n></span>\n", styles: ["h2{margin:0;line-height:1.2;display:inline}:host-context(.sky-theme-modern.sky-theme-mode-dark) h2{color:#fbfcfe}.sky-theme-modern.sky-theme-mode-dark h2{color:#fbfcfe}\n"], dependencies: [{ kind: "directive", type: i2$1.λ2, selector: "[skyThemeClass]", inputs: ["class", "skyThemeClass"] }, { kind: "directive", type: i3.λ4, selector: "[skyTrim]" }] }); }
|
|
162
|
+
}
|
|
163
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyModalHeaderComponent, decorators: [{
|
|
164
|
+
type: Component,
|
|
165
|
+
args: [{ selector: 'sky-modal-header', template: "<h2\n class=\"sky-font-emphasized\"\n [skyThemeClass]=\"{\n 'sky-font-heading-4': 'default',\n 'sky-font-display-3': 'modern'\n }\"\n skyTrim\n>\n <ng-content></ng-content>\n</h2>\n<span class=\"sky-control-help-container\" skyTrim\n ><ng-content select=\".sky-control-help\"></ng-content\n></span>\n", styles: ["h2{margin:0;line-height:1.2;display:inline}:host-context(.sky-theme-modern.sky-theme-mode-dark) h2{color:#fbfcfe}.sky-theme-modern.sky-theme-mode-dark h2{color:#fbfcfe}\n"] }]
|
|
166
|
+
}] });
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* @internal
|
|
170
|
+
*/
|
|
171
|
+
class SkyModalAdapterService {
|
|
172
|
+
static { this.MODAL_BODY_FULL_CLASS = 'sky-modal-body-full-page'; }
|
|
173
|
+
static { this.MODAL_BODY_CLASS = 'sky-modal-body-open'; }
|
|
174
|
+
#docRef;
|
|
175
|
+
#bodyEl;
|
|
176
|
+
#windowRef;
|
|
177
|
+
#hostSiblingAriaHiddenCache = new Map();
|
|
178
|
+
constructor(windowRef) {
|
|
179
|
+
this.#windowRef = windowRef;
|
|
180
|
+
this.#docRef = this.#windowRef.nativeWindow.document;
|
|
181
|
+
this.#bodyEl = this.#windowRef.nativeWindow.document.body;
|
|
182
|
+
}
|
|
183
|
+
toggleFullPageModalClass(isAddFull) {
|
|
184
|
+
if (isAddFull) {
|
|
185
|
+
this.#addClassToBody(SkyModalAdapterService.MODAL_BODY_FULL_CLASS);
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
this.#removeClassFromBody(SkyModalAdapterService.MODAL_BODY_FULL_CLASS);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
setPageScroll(isAdd) {
|
|
192
|
+
if (isAdd) {
|
|
193
|
+
this.#addClassToBody(SkyModalAdapterService.MODAL_BODY_CLASS);
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
this.#removeClassFromBody(SkyModalAdapterService.MODAL_BODY_CLASS);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
getModalOpener() {
|
|
200
|
+
return this.#docRef.activeElement;
|
|
201
|
+
}
|
|
202
|
+
#addClassToBody(className) {
|
|
203
|
+
this.#bodyEl.classList.add(className);
|
|
204
|
+
}
|
|
205
|
+
#removeClassFromBody(className) {
|
|
206
|
+
this.#bodyEl.classList.remove(className);
|
|
207
|
+
}
|
|
208
|
+
scrollContentToTop(element) {
|
|
209
|
+
element.nativeElement.querySelector('.sky-modal-content').scrollTop = 0;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Hides siblings of modal-host from screen readers
|
|
213
|
+
* @param hostElRef reference to modal-host element
|
|
214
|
+
*/
|
|
215
|
+
hideHostSiblingsFromScreenReaders(hostElRef) {
|
|
216
|
+
const hostElement = hostElRef.nativeElement;
|
|
217
|
+
const hostSiblings = hostElement.parentElement.children;
|
|
218
|
+
for (let i = 0; i < hostSiblings.length; i++) {
|
|
219
|
+
const element = hostSiblings[i];
|
|
220
|
+
if (element !== hostElement &&
|
|
221
|
+
!element.hasAttribute('aria-live') &&
|
|
222
|
+
element.nodeName.toLowerCase() !== 'script' &&
|
|
223
|
+
element.nodeName.toLowerCase() !== 'style') {
|
|
224
|
+
// preserve previous aria-hidden status of elements outside of modal host
|
|
225
|
+
this.#hostSiblingAriaHiddenCache.set(element, element.getAttribute('aria-hidden'));
|
|
226
|
+
element.setAttribute('aria-hidden', 'true');
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Restores modal-host siblings to screen reader status prior to modals being opened
|
|
232
|
+
*/
|
|
233
|
+
unhideOrRestoreHostSiblingsFromScreenReaders() {
|
|
234
|
+
this.#hostSiblingAriaHiddenCache.forEach((previousValue, element) => {
|
|
235
|
+
// if element had aria-hidden status prior, restore status
|
|
236
|
+
if (element.parentElement) {
|
|
237
|
+
if (previousValue) {
|
|
238
|
+
element.setAttribute('aria-hidden', previousValue);
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
element.removeAttribute('aria-hidden');
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
this.#hostSiblingAriaHiddenCache.clear();
|
|
246
|
+
}
|
|
247
|
+
hidePreviousModalFromScreenReaders(topModal) {
|
|
248
|
+
if (topModal && topModal.nativeElement.previousElementSibling) {
|
|
249
|
+
topModal.nativeElement.previousElementSibling.setAttribute('aria-hidden', 'true');
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
unhidePreviousModalFromScreenReaders(topModal) {
|
|
253
|
+
if (topModal && topModal.nativeElement.previousElementSibling) {
|
|
254
|
+
topModal.nativeElement.previousElementSibling.removeAttribute('aria-hidden');
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyModalAdapterService, deps: [{ token: i3.SkyAppWindowRef }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
258
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyModalAdapterService }); }
|
|
259
|
+
}
|
|
260
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyModalAdapterService, decorators: [{
|
|
261
|
+
type: Injectable
|
|
262
|
+
}], ctorParameters: function () { return [{ type: i3.SkyAppWindowRef }]; } });
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* @internal
|
|
266
|
+
*/
|
|
267
|
+
class SkyModalConfiguration {
|
|
268
|
+
constructor() {
|
|
269
|
+
this.size = 'medium';
|
|
270
|
+
}
|
|
271
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyModalConfiguration, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
272
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyModalConfiguration, providedIn: 'any' }); }
|
|
273
|
+
}
|
|
274
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyModalConfiguration, decorators: [{
|
|
275
|
+
type: Injectable,
|
|
276
|
+
args: [{
|
|
277
|
+
providedIn: 'any',
|
|
278
|
+
}]
|
|
279
|
+
}], ctorParameters: function () { return []; } });
|
|
280
|
+
|
|
281
|
+
const BASE_Z_INDEX = 1040;
|
|
282
|
+
const modalHosts = [];
|
|
283
|
+
/**
|
|
284
|
+
* @internal
|
|
285
|
+
* @dynamic
|
|
286
|
+
*/
|
|
287
|
+
class SkyModalHostService {
|
|
288
|
+
static get openModalCount() {
|
|
289
|
+
return modalHosts.length;
|
|
290
|
+
}
|
|
291
|
+
static get fullPageModalCount() {
|
|
292
|
+
const fullPageModals = modalHosts.filter((modal) => modal.fullPage);
|
|
293
|
+
return fullPageModals.length;
|
|
294
|
+
}
|
|
295
|
+
static get backdropZIndex() {
|
|
296
|
+
return BASE_Z_INDEX + modalHosts.length * 10;
|
|
297
|
+
}
|
|
298
|
+
static get topModal() {
|
|
299
|
+
return modalHosts[modalHosts.length - 1];
|
|
300
|
+
}
|
|
301
|
+
constructor() {
|
|
302
|
+
this.close = new Subject();
|
|
303
|
+
this.fullPage = false;
|
|
304
|
+
this.openHelp = new Subject();
|
|
305
|
+
this.zIndex = this.#calculateZIndex();
|
|
306
|
+
modalHosts.push(this);
|
|
307
|
+
}
|
|
308
|
+
getModalZIndex() {
|
|
309
|
+
return this.zIndex;
|
|
310
|
+
}
|
|
311
|
+
onClose() {
|
|
312
|
+
this.close.next();
|
|
313
|
+
}
|
|
314
|
+
onOpenHelp(helpKey) {
|
|
315
|
+
this.openHelp.next(helpKey);
|
|
316
|
+
}
|
|
317
|
+
destroy() {
|
|
318
|
+
modalHosts.splice(modalHosts.indexOf(this), 1);
|
|
319
|
+
}
|
|
320
|
+
#calculateZIndex() {
|
|
321
|
+
const zIndexArray = modalHosts.map((hostService) => hostService.zIndex);
|
|
322
|
+
if (zIndexArray.length === 0) {
|
|
323
|
+
return BASE_Z_INDEX + 11;
|
|
324
|
+
}
|
|
325
|
+
else {
|
|
326
|
+
const currentMaxZIndex = Math.max(...zIndexArray);
|
|
327
|
+
return currentMaxZIndex + 10;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyModalHostService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
331
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyModalHostService, providedIn: 'root' }); }
|
|
332
|
+
}
|
|
333
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyModalHostService, decorators: [{
|
|
334
|
+
type: Injectable,
|
|
335
|
+
args: [{
|
|
336
|
+
providedIn: 'root',
|
|
337
|
+
}]
|
|
338
|
+
}], ctorParameters: function () { return []; } });
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* Provided by the modal service to give the modal host
|
|
342
|
+
* component additional context and features.
|
|
343
|
+
* @internal
|
|
344
|
+
*/
|
|
345
|
+
class SkyModalHostContext {
|
|
346
|
+
constructor(args) {
|
|
347
|
+
this.args = args;
|
|
348
|
+
}
|
|
349
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyModalHostContext, deps: [{ token: 'SkyModalHostContextArgs' }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
350
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyModalHostContext }); }
|
|
351
|
+
}
|
|
352
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyModalHostContext, decorators: [{
|
|
353
|
+
type: Injectable
|
|
354
|
+
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
|
|
355
|
+
type: Inject,
|
|
356
|
+
args: ['SkyModalHostContextArgs']
|
|
357
|
+
}] }]; } });
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* @internal
|
|
361
|
+
*/
|
|
362
|
+
class SkyModalHostComponent {
|
|
363
|
+
get modalOpen() {
|
|
364
|
+
return SkyModalHostService.openModalCount > 0;
|
|
365
|
+
}
|
|
366
|
+
get backdropZIndex() {
|
|
367
|
+
return SkyModalHostService.backdropZIndex;
|
|
368
|
+
}
|
|
369
|
+
#resolver;
|
|
370
|
+
#adapter;
|
|
371
|
+
#injector;
|
|
372
|
+
#router;
|
|
373
|
+
#changeDetector;
|
|
374
|
+
#modalHostContext;
|
|
375
|
+
#elRef;
|
|
376
|
+
#modalInstances = [];
|
|
377
|
+
constructor(resolver, adapter, injector, changeDetector, modalHostContext, elRef, router) {
|
|
378
|
+
this.#resolver = resolver;
|
|
379
|
+
this.#adapter = adapter;
|
|
380
|
+
this.#injector = injector;
|
|
381
|
+
this.#router = router;
|
|
382
|
+
this.#changeDetector = changeDetector;
|
|
383
|
+
this.#modalHostContext = modalHostContext;
|
|
384
|
+
this.#elRef = elRef;
|
|
385
|
+
}
|
|
386
|
+
ngOnDestroy() {
|
|
387
|
+
// Close all modal instances before disposing of the host container.
|
|
388
|
+
this.#closeAllModalInstances();
|
|
389
|
+
this.#modalHostContext.args.teardownCallback();
|
|
390
|
+
}
|
|
391
|
+
open(modalInstance, component, config) {
|
|
392
|
+
/* Ignore coverage as we specify the target element and so the view child should never be undefined unless
|
|
393
|
+
* we were to call the `open` method in an early lifecycle hook. */
|
|
394
|
+
/* istanbul ignore next */
|
|
395
|
+
if (!this.target) {
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
const params = Object.assign({}, config);
|
|
399
|
+
const factory = this.#resolver.resolveComponentFactory(component);
|
|
400
|
+
const hostService = new SkyModalHostService();
|
|
401
|
+
hostService.fullPage = !!params.fullPage;
|
|
402
|
+
const adapter = this.#adapter;
|
|
403
|
+
const modalOpener = adapter.getModalOpener();
|
|
404
|
+
let isOpen = true;
|
|
405
|
+
params.providers ||= [];
|
|
406
|
+
params.providers.push({
|
|
407
|
+
provide: SkyModalHostService,
|
|
408
|
+
useValue: hostService,
|
|
409
|
+
}, {
|
|
410
|
+
provide: SkyModalConfiguration,
|
|
411
|
+
useValue: params,
|
|
412
|
+
}, {
|
|
413
|
+
provide: SkyMediaQueryService,
|
|
414
|
+
useExisting: SkyResizeObserverMediaQueryService,
|
|
415
|
+
}, {
|
|
416
|
+
provide: SKY_STACKING_CONTEXT,
|
|
417
|
+
useValue: {
|
|
418
|
+
zIndex: new BehaviorSubject(hostService.getModalZIndex())
|
|
419
|
+
.asObservable()
|
|
420
|
+
.pipe(takeUntil(modalInstance.closed)),
|
|
421
|
+
},
|
|
422
|
+
});
|
|
423
|
+
adapter.setPageScroll(SkyModalHostService.openModalCount > 0);
|
|
424
|
+
adapter.toggleFullPageModalClass(SkyModalHostService.fullPageModalCount > 0);
|
|
425
|
+
const providers = params.providers || /* istanbul ignore next */ [];
|
|
426
|
+
const injector = Injector.create({
|
|
427
|
+
providers,
|
|
428
|
+
parent: this.#injector,
|
|
429
|
+
});
|
|
430
|
+
const modalComponentRef = this.target.createComponent(factory, undefined, injector);
|
|
431
|
+
// modal element that was just opened
|
|
432
|
+
const modalElement = modalComponentRef.location;
|
|
433
|
+
modalInstance.adapter = this.#adapter;
|
|
434
|
+
modalInstance.componentRef = modalComponentRef;
|
|
435
|
+
this.#registerModalInstance(modalInstance);
|
|
436
|
+
// hiding all elements at the modal-host level from screen readers when the a modal is opened
|
|
437
|
+
this.#adapter.hideHostSiblingsFromScreenReaders(this.#elRef);
|
|
438
|
+
if (SkyModalHostService.openModalCount > 1 &&
|
|
439
|
+
SkyModalHostService.topModal === hostService) {
|
|
440
|
+
// hiding the lower modals when more than one modal is opened
|
|
441
|
+
this.#adapter.hidePreviousModalFromScreenReaders(modalElement);
|
|
442
|
+
}
|
|
443
|
+
const closeModal = () => {
|
|
444
|
+
// unhide siblings if last modal is closing
|
|
445
|
+
if (SkyModalHostService.openModalCount === 1) {
|
|
446
|
+
this.#adapter.unhideOrRestoreHostSiblingsFromScreenReaders();
|
|
447
|
+
}
|
|
448
|
+
else if (SkyModalHostService.topModal === hostService) {
|
|
449
|
+
// if there are more than 1 modal then unhide the one behind this one before closing it
|
|
450
|
+
this.#adapter.unhidePreviousModalFromScreenReaders(modalElement);
|
|
451
|
+
}
|
|
452
|
+
hostService.destroy();
|
|
453
|
+
adapter.setPageScroll(SkyModalHostService.openModalCount > 0);
|
|
454
|
+
adapter.toggleFullPageModalClass(SkyModalHostService.fullPageModalCount > 0);
|
|
455
|
+
/* istanbul ignore else */
|
|
456
|
+
/* sanity check */
|
|
457
|
+
if (modalOpener && modalOpener.focus) {
|
|
458
|
+
modalOpener.focus();
|
|
459
|
+
}
|
|
460
|
+
modalComponentRef.destroy();
|
|
461
|
+
};
|
|
462
|
+
hostService.openHelp.subscribe((helpKey) => {
|
|
463
|
+
modalInstance.openHelp(helpKey);
|
|
464
|
+
});
|
|
465
|
+
hostService.close.subscribe(() => {
|
|
466
|
+
modalInstance.close();
|
|
467
|
+
});
|
|
468
|
+
this.#router?.events.pipe(takeWhile(() => isOpen)).subscribe((event) => {
|
|
469
|
+
/* istanbul ignore else */
|
|
470
|
+
if (event instanceof NavigationStart) {
|
|
471
|
+
modalInstance.close();
|
|
472
|
+
}
|
|
473
|
+
});
|
|
474
|
+
modalInstance.closed.subscribe(() => {
|
|
475
|
+
isOpen = false;
|
|
476
|
+
this.#unregisterModalInstance(modalInstance);
|
|
477
|
+
closeModal();
|
|
478
|
+
});
|
|
479
|
+
// Necessary if the host was created via a consumer's lifecycle hook such as ngOnInit
|
|
480
|
+
this.#changeDetector.detectChanges();
|
|
481
|
+
}
|
|
482
|
+
#registerModalInstance(instance) {
|
|
483
|
+
this.#modalInstances.push(instance);
|
|
484
|
+
}
|
|
485
|
+
#unregisterModalInstance(instance) {
|
|
486
|
+
this.#modalInstances.slice(this.#modalInstances.indexOf(instance), 1);
|
|
487
|
+
}
|
|
488
|
+
#closeAllModalInstances() {
|
|
489
|
+
for (const instance of this.#modalInstances) {
|
|
490
|
+
instance.close();
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyModalHostComponent, deps: [{ token: i0.ComponentFactoryResolver }, { token: SkyModalAdapterService }, { token: i0.Injector }, { token: i0.ChangeDetectorRef }, { token: SkyModalHostContext }, { token: i0.ElementRef }, { token: i3$1.Router, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
494
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: SkyModalHostComponent, selector: "sky-modal-host", viewQueries: [{ propertyName: "target", first: true, predicate: ["target"], descendants: true, read: ViewContainerRef, static: true }], ngImport: i0, template: "<div\n class=\"sky-modal-host-backdrop\"\n [hidden]=\"!modalOpen\"\n [ngStyle]=\"{\n zIndex: backdropZIndex\n }\"\n></div>\n<div #target></div>\n", styles: [".sky-modal-host-backdrop{background-color:#00000080;position:fixed;inset:0}\n"], dependencies: [{ kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], viewProviders: [SkyModalAdapterService] }); }
|
|
495
|
+
}
|
|
496
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyModalHostComponent, decorators: [{
|
|
497
|
+
type: Component,
|
|
498
|
+
args: [{ selector: 'sky-modal-host', viewProviders: [SkyModalAdapterService], template: "<div\n class=\"sky-modal-host-backdrop\"\n [hidden]=\"!modalOpen\"\n [ngStyle]=\"{\n zIndex: backdropZIndex\n }\"\n></div>\n<div #target></div>\n", styles: [".sky-modal-host-backdrop{background-color:#00000080;position:fixed;inset:0}\n"] }]
|
|
499
|
+
}], ctorParameters: function () { return [{ type: i0.ComponentFactoryResolver }, { type: SkyModalAdapterService }, { type: i0.Injector }, { type: i0.ChangeDetectorRef }, { type: SkyModalHostContext }, { type: i0.ElementRef }, { type: i3$1.Router, decorators: [{
|
|
500
|
+
type: Optional
|
|
501
|
+
}] }]; }, propDecorators: { target: [{
|
|
502
|
+
type: ViewChild,
|
|
503
|
+
args: ['target', {
|
|
504
|
+
read: ViewContainerRef,
|
|
505
|
+
static: true,
|
|
506
|
+
}]
|
|
507
|
+
}] } });
|
|
508
|
+
|
|
509
|
+
/**
|
|
510
|
+
* @internal
|
|
511
|
+
*/
|
|
512
|
+
const SKY_CONFIRM_CONFIG = new InjectionToken('SkyConfirmConfig');
|
|
513
|
+
|
|
514
|
+
/**
|
|
515
|
+
* Properties about the modal close action and a method to close the modal.
|
|
516
|
+
*/
|
|
517
|
+
class SkyModalBeforeCloseHandler {
|
|
518
|
+
constructor(closeModal, closeArgs) {
|
|
519
|
+
this.closeArgs = closeArgs;
|
|
520
|
+
this.closeModal = closeModal;
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
/**
|
|
525
|
+
* Contains an object with the data passed from users when
|
|
526
|
+
* a modal is closed and the reason that the modal was closed.
|
|
527
|
+
*/
|
|
528
|
+
class SkyModalCloseArgs {
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
class SkyModalInstance {
|
|
532
|
+
/**
|
|
533
|
+
* An event that the modal instance emits when it is about to close.
|
|
534
|
+
* It emits a `SkyModalBeforeCloseHandler` object with a `closeModal` method
|
|
535
|
+
* that closes the modal. If a subscription exists for this event,
|
|
536
|
+
* the modal does not close until the subscriber calls the `closeModal` method.
|
|
537
|
+
*/
|
|
538
|
+
get beforeClose() {
|
|
539
|
+
return this.#_beforeClose;
|
|
540
|
+
}
|
|
541
|
+
/**
|
|
542
|
+
* An event that the modal instance emits when it closes.
|
|
543
|
+
* It emits a `SkyModalCloseArgs` object with a `data` property that includes
|
|
544
|
+
* data passed from users on close or save and a `reason` property that indicates
|
|
545
|
+
* whether the modal was saved or closed without saving.
|
|
546
|
+
* The `reason` property accepts any string value.
|
|
547
|
+
* Common examples include `"cancel"`, `"close"`, and `"save"`.
|
|
548
|
+
*/
|
|
549
|
+
get closed() {
|
|
550
|
+
return this.#_closed;
|
|
551
|
+
}
|
|
552
|
+
/**
|
|
553
|
+
* An event that the modal instance emits when users click
|
|
554
|
+
* the <i class="fa fa-question-circle" aria-hidden="true"></i> button.
|
|
555
|
+
* If a `helpKey` parameter was specified, the `helpOpened` event broadcasts the `helpKey`.
|
|
556
|
+
*/
|
|
557
|
+
get helpOpened() {
|
|
558
|
+
return this.#_helpOpened;
|
|
559
|
+
}
|
|
560
|
+
/**
|
|
561
|
+
* Sets the component adapter for the instance. This is used internally for actions such as scrolling the content.
|
|
562
|
+
* @internal
|
|
563
|
+
*/
|
|
564
|
+
set adapter(value) {
|
|
565
|
+
this.#adapter = value;
|
|
566
|
+
}
|
|
567
|
+
/**
|
|
568
|
+
* Sets the component ref for the instance. This is used to extract the component instance for the public API and the element ref for internal use.
|
|
569
|
+
* @internal
|
|
570
|
+
*/
|
|
571
|
+
set componentRef(value) {
|
|
572
|
+
this.componentInstance = value.instance;
|
|
573
|
+
this.#elementRef = value.location;
|
|
574
|
+
}
|
|
575
|
+
#_beforeClose = new Subject();
|
|
576
|
+
#_closed = new Subject();
|
|
577
|
+
#_helpOpened = new Subject();
|
|
578
|
+
#adapter;
|
|
579
|
+
#elementRef;
|
|
580
|
+
/**
|
|
581
|
+
* Closes the modal instance.
|
|
582
|
+
* @param result Specifies an object to emit to subscribers of the `closed` event of the
|
|
583
|
+
* modal instance. The `SkyModalInstance` provider can be injected into a component's constructor
|
|
584
|
+
* so that this `close` function can be called from a button in the `sky-modal-footer`.
|
|
585
|
+
* @param reason Specifies the reason for the modal closing, with the default reason of `"close"`.
|
|
586
|
+
* @param ignoreBeforeClose Indicates whether to ignore the modal instance's `beforeClose` event.
|
|
587
|
+
*/
|
|
588
|
+
close(result, reason, ignoreBeforeClose) {
|
|
589
|
+
if (reason === undefined) {
|
|
590
|
+
reason = 'close';
|
|
591
|
+
}
|
|
592
|
+
this.#closeModal(reason, result, ignoreBeforeClose);
|
|
593
|
+
}
|
|
594
|
+
/**
|
|
595
|
+
* Closes the modal instance with `reason="cancel"`.
|
|
596
|
+
* @param result Specifies an object to emit to subscribers of the `closed` event of the modal
|
|
597
|
+
* instance. The `SkyModalInstance` provider can be injected into a component's constructor so
|
|
598
|
+
* that this cancel function can be called from a button in the `sky-modal-footer`.
|
|
599
|
+
*/
|
|
600
|
+
cancel(result) {
|
|
601
|
+
this.#closeModal('cancel', result);
|
|
602
|
+
}
|
|
603
|
+
/**
|
|
604
|
+
* Closes the modal instance with `reason="save"`.
|
|
605
|
+
* @param result Specifies an object to emit to subscribers of the `closed` event of the modal
|
|
606
|
+
* instance. The `SkyModalInstance` provider can be injected into a component's constructor so
|
|
607
|
+
* that this `save` function can be called from a button in `the sky-modal-footer`.
|
|
608
|
+
*/
|
|
609
|
+
save(result) {
|
|
610
|
+
this.#closeModal('save', result);
|
|
611
|
+
}
|
|
612
|
+
/**
|
|
613
|
+
* Scrolls the modal content area to the top of its scrollable area.
|
|
614
|
+
*/
|
|
615
|
+
scrollContentToTop() {
|
|
616
|
+
if (this.#adapter && this.#elementRef) {
|
|
617
|
+
this.#adapter.scrollContentToTop(this.#elementRef);
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
/**
|
|
621
|
+
* Triggers the `helpOpened` event that broadcasts a `helpKey` parameter to open
|
|
622
|
+
* when users click the <i class="fa fa-question-circle" aria-hidden="true"></i> button.
|
|
623
|
+
* @param helpKey Specifies a string to emit to subscribers of
|
|
624
|
+
* the modal instance's `helpOpened` event. Consumers can inject the `SkyModalInstance` provider
|
|
625
|
+
* into a component's constructor to call the `openHelp` function in the modal template.
|
|
626
|
+
*/
|
|
627
|
+
openHelp(helpKey) {
|
|
628
|
+
this.#_helpOpened.next(helpKey);
|
|
629
|
+
}
|
|
630
|
+
#closeModal(type, result, ignoreBeforeClose = false) {
|
|
631
|
+
const args = new SkyModalCloseArgs();
|
|
632
|
+
args.reason = type;
|
|
633
|
+
args.data = result;
|
|
634
|
+
if (this.#_beforeClose.observers.length === 0 || ignoreBeforeClose) {
|
|
635
|
+
this.#notifyClosed(args);
|
|
636
|
+
}
|
|
637
|
+
else {
|
|
638
|
+
this.#_beforeClose.next(new SkyModalBeforeCloseHandler(() => {
|
|
639
|
+
this.#notifyClosed(args);
|
|
640
|
+
}, args));
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
#notifyClosed(args) {
|
|
644
|
+
this.#_closed.next(args);
|
|
645
|
+
this.#_closed.complete();
|
|
646
|
+
this.#_beforeClose.complete();
|
|
647
|
+
this.#_helpOpened.complete();
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
/**
|
|
652
|
+
* @internal
|
|
653
|
+
*/
|
|
654
|
+
class SkyModalComponentAdapterService {
|
|
655
|
+
#coreAdapter;
|
|
656
|
+
constructor(coreAdapter) {
|
|
657
|
+
this.#coreAdapter = coreAdapter;
|
|
658
|
+
}
|
|
659
|
+
handleWindowChange(modalEl) {
|
|
660
|
+
const boundedHeightEl = modalEl.nativeElement.querySelector('.sky-modal');
|
|
661
|
+
const fullPageModalEl = modalEl.nativeElement.querySelector('.sky-modal-full-page');
|
|
662
|
+
/*
|
|
663
|
+
Set modal height equal to max height of window (accounting for padding above and below modal)
|
|
664
|
+
*/
|
|
665
|
+
const newHeight = window.innerHeight - 40;
|
|
666
|
+
boundedHeightEl.style.maxHeight = newHeight.toString() + 'px';
|
|
667
|
+
if (fullPageModalEl) {
|
|
668
|
+
this.#setFullPageHeight(fullPageModalEl);
|
|
669
|
+
}
|
|
670
|
+
else {
|
|
671
|
+
/*
|
|
672
|
+
IE11 doesn't handle flex and max-height correctly so we have to explicitly add
|
|
673
|
+
max-height to the content that accounts for standard header and footer height.
|
|
674
|
+
*/
|
|
675
|
+
const modalContentEl = modalEl.nativeElement.querySelector('.sky-modal-content');
|
|
676
|
+
const contentHeight = newHeight - 114;
|
|
677
|
+
modalContentEl.style.maxHeight = contentHeight.toString() + 'px';
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
isFocusInFirstItem(event, list) {
|
|
681
|
+
/* istanbul ignore next */
|
|
682
|
+
/* sanity check */
|
|
683
|
+
const eventTarget = event.target || event.srcElement;
|
|
684
|
+
return list.length > 0 && eventTarget === list[0];
|
|
685
|
+
}
|
|
686
|
+
isFocusInLastItem(event, list) {
|
|
687
|
+
/* istanbul ignore next */
|
|
688
|
+
/* sanity check */
|
|
689
|
+
const eventTarget = event.target || event.srcElement;
|
|
690
|
+
return list.length > 0 && eventTarget === list[list.length - 1];
|
|
691
|
+
}
|
|
692
|
+
isModalFocused(event, modalEl) {
|
|
693
|
+
/* istanbul ignore next */
|
|
694
|
+
/* sanity check */
|
|
695
|
+
const eventTarget = event.target || event.srcElement;
|
|
696
|
+
return (modalEl &&
|
|
697
|
+
eventTarget === modalEl.nativeElement.querySelector('.sky-modal-dialog'));
|
|
698
|
+
}
|
|
699
|
+
focusLastElement(list) {
|
|
700
|
+
if (list.length > 0) {
|
|
701
|
+
list[list.length - 1].focus();
|
|
702
|
+
return true;
|
|
703
|
+
}
|
|
704
|
+
return false;
|
|
705
|
+
}
|
|
706
|
+
focusFirstElement(list) {
|
|
707
|
+
if (list.length > 0) {
|
|
708
|
+
list[0].focus();
|
|
709
|
+
return true;
|
|
710
|
+
}
|
|
711
|
+
return false;
|
|
712
|
+
}
|
|
713
|
+
modalContentHasDirectChildViewkeeper(modalContentEl) {
|
|
714
|
+
return !!modalContentEl.nativeElement.querySelector('sky-modal-content > .sky-viewkeeper-fixed');
|
|
715
|
+
}
|
|
716
|
+
modalOpened(modalEl) {
|
|
717
|
+
/* istanbul ignore else */
|
|
718
|
+
/* handle the case where somehow there is a focused element already in the modal */
|
|
719
|
+
if (!(document.activeElement &&
|
|
720
|
+
modalEl.nativeElement.contains(document.activeElement))) {
|
|
721
|
+
const currentScrollX = window.pageXOffset;
|
|
722
|
+
const currentScrollY = window.pageYOffset;
|
|
723
|
+
const inputWithAutofocus = modalEl.nativeElement.querySelector('[autofocus]');
|
|
724
|
+
if (inputWithAutofocus) {
|
|
725
|
+
inputWithAutofocus.focus();
|
|
726
|
+
}
|
|
727
|
+
else {
|
|
728
|
+
this.#coreAdapter.getFocusableChildrenAndApplyFocus(modalEl, '.sky-modal-content', true);
|
|
729
|
+
}
|
|
730
|
+
window.scrollTo(currentScrollX, currentScrollY);
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
#setFullPageHeight(fullPageModalEl) {
|
|
734
|
+
const windowHeight = window.innerHeight;
|
|
735
|
+
const fullPageModalStyle = getComputedStyle(fullPageModalEl);
|
|
736
|
+
const marginTopBottom = parseInt(fullPageModalStyle.marginTop, 10) +
|
|
737
|
+
parseInt(fullPageModalStyle.marginBottom, 10);
|
|
738
|
+
const fullPageModalHeight = windowHeight - marginTopBottom + 'px';
|
|
739
|
+
fullPageModalEl.style.height = fullPageModalHeight;
|
|
740
|
+
fullPageModalEl.style.maxHeight = fullPageModalHeight;
|
|
741
|
+
}
|
|
742
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyModalComponentAdapterService, deps: [{ token: i3.SkyCoreAdapterService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
743
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyModalComponentAdapterService }); }
|
|
744
|
+
}
|
|
745
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyModalComponentAdapterService, decorators: [{
|
|
746
|
+
type: Injectable
|
|
747
|
+
}], ctorParameters: function () { return [{ type: i3.SkyCoreAdapterService }]; } });
|
|
748
|
+
|
|
749
|
+
/**
|
|
750
|
+
* Raises an event when the box shadow for the modal header or footer should be adjusted
|
|
751
|
+
* based on the scroll position of the host element.
|
|
752
|
+
* @internal
|
|
753
|
+
*/
|
|
754
|
+
class SkyModalScrollShadowDirective {
|
|
755
|
+
#currentShadow;
|
|
756
|
+
#currentTheme;
|
|
757
|
+
#mutationObserver;
|
|
758
|
+
#ngUnsubscribe;
|
|
759
|
+
#elRef;
|
|
760
|
+
#mutationObserverSvc;
|
|
761
|
+
#ngZone;
|
|
762
|
+
#themeSvc;
|
|
763
|
+
constructor(elRef, mutationObserverSvc, ngZone, themeSvc) {
|
|
764
|
+
this.skyModalScrollShadow = new EventEmitter();
|
|
765
|
+
this.#ngUnsubscribe = new Subject();
|
|
766
|
+
this.#elRef = elRef;
|
|
767
|
+
this.#mutationObserverSvc = mutationObserverSvc;
|
|
768
|
+
this.#ngZone = ngZone;
|
|
769
|
+
this.#themeSvc = themeSvc;
|
|
770
|
+
}
|
|
771
|
+
windowResize() {
|
|
772
|
+
this.#checkForShadow();
|
|
773
|
+
}
|
|
774
|
+
scroll() {
|
|
775
|
+
this.#checkForShadow();
|
|
776
|
+
}
|
|
777
|
+
ngOnInit() {
|
|
778
|
+
if (this.#themeSvc) {
|
|
779
|
+
this.#themeSvc.settingsChange
|
|
780
|
+
.pipe(takeUntil(this.#ngUnsubscribe))
|
|
781
|
+
.subscribe((themeSettings) => {
|
|
782
|
+
this.#currentTheme = themeSettings.currentSettings.theme;
|
|
783
|
+
if (this.#currentTheme === SkyTheme.presets.modern) {
|
|
784
|
+
this.#initMutationObserver();
|
|
785
|
+
}
|
|
786
|
+
else {
|
|
787
|
+
this.#emitShadow({
|
|
788
|
+
bottomShadow: 'none',
|
|
789
|
+
topShadow: 'none',
|
|
790
|
+
});
|
|
791
|
+
this.#destroyMutationObserver();
|
|
792
|
+
}
|
|
793
|
+
});
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
ngOnDestroy() {
|
|
797
|
+
this.#ngUnsubscribe.next();
|
|
798
|
+
this.#ngUnsubscribe.complete();
|
|
799
|
+
this.#destroyMutationObserver();
|
|
800
|
+
}
|
|
801
|
+
#initMutationObserver() {
|
|
802
|
+
if (!this.#mutationObserver) {
|
|
803
|
+
const el = this.#elRef.nativeElement;
|
|
804
|
+
// MutationObserver is patched by Zone.js and therefore becomes part of the
|
|
805
|
+
// Angular change detection cycle, but this can lead to infinite loops in some
|
|
806
|
+
// scenarios. This will keep MutationObserver from triggering change detection.
|
|
807
|
+
this.#ngZone.runOutsideAngular(() => {
|
|
808
|
+
this.#mutationObserver = this.#mutationObserverSvc.create(() => {
|
|
809
|
+
this.#checkForShadow();
|
|
810
|
+
});
|
|
811
|
+
this.#mutationObserver.observe(el, {
|
|
812
|
+
attributes: true,
|
|
813
|
+
characterData: true,
|
|
814
|
+
childList: true,
|
|
815
|
+
subtree: true,
|
|
816
|
+
});
|
|
817
|
+
});
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
#destroyMutationObserver() {
|
|
821
|
+
if (this.#mutationObserver) {
|
|
822
|
+
this.#mutationObserver.disconnect();
|
|
823
|
+
this.#mutationObserver = undefined;
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
#checkForShadow() {
|
|
827
|
+
if (this.#currentTheme === SkyTheme.presets.modern) {
|
|
828
|
+
const el = this.#elRef.nativeElement;
|
|
829
|
+
const topShadow = this.#buildShadowStyle(el.scrollTop);
|
|
830
|
+
const bottomShadow = this.#buildShadowStyle(el.scrollHeight - el.scrollTop - el.clientHeight);
|
|
831
|
+
this.#emitShadow({
|
|
832
|
+
bottomShadow,
|
|
833
|
+
topShadow,
|
|
834
|
+
});
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
#buildShadowStyle(pixelsFromEnd) {
|
|
838
|
+
// Progressively darken the shadow until the user scrolls 30 pixels from the top or bottom
|
|
839
|
+
// of the scrollable element, with a max opacity of 0.3.
|
|
840
|
+
const opacity = Math.min(pixelsFromEnd / 30, 1) * 0.3;
|
|
841
|
+
return opacity > 0 ? `0px 1px 8px 0px rgba(0, 0, 0, ${opacity})` : 'none';
|
|
842
|
+
}
|
|
843
|
+
#emitShadow(shadow) {
|
|
844
|
+
if (!this.#currentShadow ||
|
|
845
|
+
this.#currentShadow.bottomShadow !== shadow.bottomShadow ||
|
|
846
|
+
this.#currentShadow.topShadow !== shadow.topShadow) {
|
|
847
|
+
this.skyModalScrollShadow.emit(shadow);
|
|
848
|
+
this.#currentShadow = shadow;
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyModalScrollShadowDirective, deps: [{ token: i0.ElementRef }, { token: i3.SkyMutationObserverService }, { token: i0.NgZone }, { token: i2$1.SkyThemeService, optional: true }], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
852
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.1.7", type: SkyModalScrollShadowDirective, selector: "[skyModalScrollShadow]", outputs: { skyModalScrollShadow: "skyModalScrollShadow" }, host: { listeners: { "window:resize": "windowResize()", "scroll": "scroll()" } }, ngImport: i0 }); }
|
|
853
|
+
}
|
|
854
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyModalScrollShadowDirective, decorators: [{
|
|
855
|
+
type: Directive,
|
|
856
|
+
args: [{
|
|
857
|
+
selector: '[skyModalScrollShadow]',
|
|
858
|
+
}]
|
|
859
|
+
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i3.SkyMutationObserverService }, { type: i0.NgZone }, { type: i2$1.SkyThemeService, decorators: [{
|
|
860
|
+
type: Optional
|
|
861
|
+
}] }]; }, propDecorators: { skyModalScrollShadow: [{
|
|
862
|
+
type: Output
|
|
863
|
+
}], windowResize: [{
|
|
864
|
+
type: HostListener,
|
|
865
|
+
args: ['window:resize']
|
|
866
|
+
}], scroll: [{
|
|
867
|
+
type: HostListener,
|
|
868
|
+
args: ['scroll']
|
|
869
|
+
}] } });
|
|
870
|
+
|
|
871
|
+
const ARIA_ROLE_DEFAULT = 'dialog';
|
|
872
|
+
/**
|
|
873
|
+
* Provides a common look-and-feel for modal content with options to display
|
|
874
|
+
* a common modal header, specify body content, and display a common modal footer
|
|
875
|
+
* and buttons.
|
|
876
|
+
*/
|
|
877
|
+
class SkyModalComponent {
|
|
878
|
+
/**
|
|
879
|
+
* A list of form-level errors to display to the user.
|
|
880
|
+
*/
|
|
881
|
+
set formErrors(value) {
|
|
882
|
+
this.#errorsSvc.updateErrors(value);
|
|
883
|
+
}
|
|
884
|
+
/**
|
|
885
|
+
* @internal
|
|
886
|
+
*/
|
|
887
|
+
set ariaRole(value) {
|
|
888
|
+
this.ariaRoleOrDefault = value || ARIA_ROLE_DEFAULT;
|
|
889
|
+
}
|
|
890
|
+
/**
|
|
891
|
+
* @internal
|
|
892
|
+
*/
|
|
893
|
+
set ariaDescribedBy(id) {
|
|
894
|
+
this.#_ariaDescribedBy = id;
|
|
895
|
+
}
|
|
896
|
+
get ariaDescribedBy() {
|
|
897
|
+
return this.#_ariaDescribedBy;
|
|
898
|
+
}
|
|
899
|
+
/**
|
|
900
|
+
* @internal
|
|
901
|
+
*/
|
|
902
|
+
set ariaLabelledBy(id) {
|
|
903
|
+
this.#_ariaLabelledBy = id;
|
|
904
|
+
}
|
|
905
|
+
get ariaLabelledBy() {
|
|
906
|
+
return this.#_ariaLabelledBy;
|
|
907
|
+
}
|
|
908
|
+
#hostService;
|
|
909
|
+
#elRef;
|
|
910
|
+
#windowRef;
|
|
911
|
+
#componentAdapter;
|
|
912
|
+
#coreAdapter;
|
|
913
|
+
#dockService;
|
|
914
|
+
#mediaQueryService;
|
|
915
|
+
#ngUnsubscribe;
|
|
916
|
+
#_ariaDescribedBy;
|
|
917
|
+
#_ariaLabelledBy;
|
|
918
|
+
#changeDetector;
|
|
919
|
+
#errorsSvc;
|
|
920
|
+
#liveAnnouncerSvc;
|
|
921
|
+
constructor(hostService, config, elRef, windowRef, componentAdapter, coreAdapter, dockService, mediaQueryService) {
|
|
922
|
+
this.ariaRoleOrDefault = ARIA_ROLE_DEFAULT;
|
|
923
|
+
this.ariaOwns = null;
|
|
924
|
+
this.modalState = 'in';
|
|
925
|
+
this.#ngUnsubscribe = new Subject();
|
|
926
|
+
this.#changeDetector = inject(ChangeDetectorRef);
|
|
927
|
+
this.#errorsSvc = inject(SkyModalErrorsService);
|
|
928
|
+
this.#liveAnnouncerSvc = inject(SkyLiveAnnouncerService);
|
|
929
|
+
this.#hostService = hostService;
|
|
930
|
+
this.#elRef = elRef;
|
|
931
|
+
this.#windowRef = windowRef;
|
|
932
|
+
this.#componentAdapter = componentAdapter;
|
|
933
|
+
this.#coreAdapter = coreAdapter;
|
|
934
|
+
this.#dockService = dockService;
|
|
935
|
+
this.#mediaQueryService = mediaQueryService;
|
|
936
|
+
this.ariaDescribedBy = config.ariaDescribedBy;
|
|
937
|
+
this.ariaLabelledBy = config.ariaLabelledBy;
|
|
938
|
+
this.ariaRole = config.ariaRole;
|
|
939
|
+
this.helpKey = config.helpKey;
|
|
940
|
+
this.tiledBody = config.tiledBody;
|
|
941
|
+
this.wrapperClass = config.wrapperClass;
|
|
942
|
+
this.size = config.fullPage
|
|
943
|
+
? 'full-page'
|
|
944
|
+
: config.size?.toLowerCase() || 'medium';
|
|
945
|
+
this.modalZIndex = this.#hostService.zIndex;
|
|
946
|
+
}
|
|
947
|
+
onDocumentKeyUp(event) {
|
|
948
|
+
/* istanbul ignore else */
|
|
949
|
+
/* sanity check */
|
|
950
|
+
if (SkyModalHostService.openModalCount > 0) {
|
|
951
|
+
const topModal = SkyModalHostService.topModal;
|
|
952
|
+
if (topModal && topModal === this.#hostService) {
|
|
953
|
+
if (event.which === 27) {
|
|
954
|
+
// Escape key up
|
|
955
|
+
event.preventDefault();
|
|
956
|
+
this.closeButtonClick();
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
onDocumentKeyDown(event) {
|
|
962
|
+
/* istanbul ignore else */
|
|
963
|
+
/* sanity check */
|
|
964
|
+
if (SkyModalHostService.openModalCount > 0) {
|
|
965
|
+
const topModal = SkyModalHostService.topModal;
|
|
966
|
+
if (topModal && topModal === this.#hostService) {
|
|
967
|
+
if (event.which === 9) {
|
|
968
|
+
// Tab pressed
|
|
969
|
+
let focusChanged = false;
|
|
970
|
+
const focusElementList = this.#coreAdapter.getFocusableChildren(this.#elRef.nativeElement);
|
|
971
|
+
if (event.shiftKey &&
|
|
972
|
+
(this.#componentAdapter.isFocusInFirstItem(event, focusElementList) ||
|
|
973
|
+
this.#componentAdapter.isModalFocused(event, this.#elRef))) {
|
|
974
|
+
focusChanged =
|
|
975
|
+
this.#componentAdapter.focusLastElement(focusElementList);
|
|
976
|
+
}
|
|
977
|
+
else if (!event.shiftKey &&
|
|
978
|
+
this.#componentAdapter.isFocusInLastItem(event, focusElementList)) {
|
|
979
|
+
focusChanged =
|
|
980
|
+
this.#componentAdapter.focusFirstElement(focusElementList);
|
|
981
|
+
}
|
|
982
|
+
if (focusChanged) {
|
|
983
|
+
event.preventDefault();
|
|
984
|
+
event.stopPropagation();
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
ngOnInit() {
|
|
991
|
+
this.#liveAnnouncerSvc.announcerElementChanged
|
|
992
|
+
.pipe(takeUntil(this.#ngUnsubscribe))
|
|
993
|
+
.subscribe((element) => {
|
|
994
|
+
if (element?.id) {
|
|
995
|
+
this.ariaOwns = element.id;
|
|
996
|
+
this.#changeDetector.markForCheck();
|
|
997
|
+
}
|
|
998
|
+
});
|
|
999
|
+
}
|
|
1000
|
+
ngAfterViewInit() {
|
|
1001
|
+
this.#componentAdapter.handleWindowChange(this.#elRef);
|
|
1002
|
+
// Adding a timeout to avoid ExpressionChangedAfterItHasBeenCheckedError.
|
|
1003
|
+
// https://stackoverflow.com/questions/40562845
|
|
1004
|
+
this.#windowRef.nativeWindow.setTimeout(() => {
|
|
1005
|
+
this.#componentAdapter.modalOpened(this.#elRef);
|
|
1006
|
+
});
|
|
1007
|
+
this.#dockService.setDockOptions({
|
|
1008
|
+
location: SkyDockLocation.ElementBottom,
|
|
1009
|
+
referenceEl: this.modalContentWrapperElement.nativeElement,
|
|
1010
|
+
zIndex: 5,
|
|
1011
|
+
});
|
|
1012
|
+
/* istanbul ignore next */
|
|
1013
|
+
if (this.#mediaQueryService) {
|
|
1014
|
+
this.#mediaQueryService.observe(this.modalContentWrapperElement);
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
ngOnDestroy() {
|
|
1018
|
+
/* istanbul ignore next */
|
|
1019
|
+
if (this.#mediaQueryService) {
|
|
1020
|
+
this.#mediaQueryService.unobserve();
|
|
1021
|
+
}
|
|
1022
|
+
this.#ngUnsubscribe.next();
|
|
1023
|
+
this.#ngUnsubscribe.complete();
|
|
1024
|
+
}
|
|
1025
|
+
helpButtonClick() {
|
|
1026
|
+
if (this.helpKey) {
|
|
1027
|
+
this.#hostService.onOpenHelp(this.helpKey);
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
closeButtonClick() {
|
|
1031
|
+
this.#hostService.onClose();
|
|
1032
|
+
}
|
|
1033
|
+
windowResize() {
|
|
1034
|
+
this.#componentAdapter.handleWindowChange(this.#elRef);
|
|
1035
|
+
}
|
|
1036
|
+
scrollShadowChange(args) {
|
|
1037
|
+
this.scrollShadow = args;
|
|
1038
|
+
}
|
|
1039
|
+
viewkeeperEnabled() {
|
|
1040
|
+
return this.#componentAdapter.modalContentHasDirectChildViewkeeper(this.#elRef);
|
|
1041
|
+
}
|
|
1042
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyModalComponent, deps: [{ token: SkyModalHostService }, { token: SkyModalConfiguration }, { token: i0.ElementRef }, { token: i3.SkyAppWindowRef }, { token: SkyModalComponentAdapterService }, { token: i3.SkyCoreAdapterService }, { token: i3.SkyDockService, host: true }, { token: i3.SkyResizeObserverMediaQueryService, optional: true }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1043
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: SkyModalComponent, selector: "sky-modal", inputs: { formErrors: "formErrors", ariaRole: "ariaRole", tiledBody: "tiledBody", ariaDescribedBy: "ariaDescribedBy", ariaLabelledBy: "ariaLabelledBy" }, host: { listeners: { "document:keyup": "onDocumentKeyUp($event)", "document:keydown": "onDocumentKeyDown($event)" }, properties: { "class": "this.wrapperClass" } }, providers: [
|
|
1044
|
+
SkyModalComponentAdapterService,
|
|
1045
|
+
SkyModalErrorsService,
|
|
1046
|
+
SkyDockService,
|
|
1047
|
+
], viewQueries: [{ propertyName: "modalContentWrapperElement", first: true, predicate: ["modalContentWrapper"], descendants: true, read: ElementRef }], ngImport: i0, template: "<div\n class=\"sky-modal-dialog\"\n aria-modal=\"true\"\n [attr.aria-describedby]=\"ariaDescribedBy || modalContentId.id\"\n [attr.aria-labelledby]=\"ariaLabelledBy || headerId.id\"\n [attr.aria-owns]=\"ariaOwns\"\n [attr.role]=\"ariaRoleOrDefault\"\n (window:resize)=\"windowResize()\"\n>\n <div\n class=\"sky-modal sky-shadow sky-box sky-elevation-16 sky-modal-{{ size }}\"\n tabindex=\"-1\"\n [ngClass]=\"{\n 'sky-modal-tiled': tiledBody,\n 'sky-modal-viewkeeper': viewkeeperEnabled()\n }\"\n [ngStyle]=\"{\n zIndex: modalZIndex\n }\"\n >\n <div\n class=\"sky-modal-header\"\n [hidden]=\"!headerContent || !headerContent.children || headerContent.children.length < 1\"\n [ngStyle]=\"{\n 'box-shadow': scrollShadow?.topShadow\n }\"\n >\n <div\n class=\"sky-modal-header-content\"\n skyId\n [ngClass]=\"{\n 'sky-font-heading-2': size === 'full-page'\n }\"\n #headerContent\n #headerId=\"skyId\"\n >\n <ng-content select=\"sky-modal-header\"></ng-content>\n </div>\n <div class=\"sky-modal-header-buttons\">\n <button\n *ngIf=\"helpKey\"\n class=\"sky-btn sky-modal-btn-help\"\n name=\"help-button\"\n type=\"button\"\n [attr.aria-label]=\"'skyux_modal_open_help' | skyLibResources\"\n (click)=\"helpButtonClick()\"\n >\n <sky-icon icon=\"question-circle\"></sky-icon>\n </button>\n\n <button\n type=\"button\"\n class=\"sky-btn sky-modal-btn-close\"\n [attr.aria-label]=\"'skyux_modal_close' | skyLibResources\"\n (click)=\"closeButtonClick()\"\n >\n <sky-icon icon=\"close\"></sky-icon>\n </button>\n </div>\n </div>\n <div\n class=\"sky-modal-content sky-padding-even-large\"\n role=\"region\"\n tabindex=\"0\"\n skyId\n [attr.aria-labelledby]=\"headerId.id\"\n (skyModalScrollShadow)=\"scrollShadowChange($event)\"\n #modalContentId=\"skyId\"\n #modalContentWrapper\n >\n <ng-content select=\"sky-modal-content\"></ng-content>\n </div>\n <div\n class=\"sky-modal-footer\"\n [ngStyle]=\"{\n 'box-shadow': scrollShadow?.bottomShadow\n }\"\n >\n <ng-content select=\"sky-modal-footer\"></ng-content>\n </div>\n </div>\n</div>\n", styles: [".sky-modal{border-top:1px solid #cdcfd2;border-bottom:1px solid #cdcfd2;border-left:1px solid #cdcfd2;border-right:1px solid #cdcfd2;position:fixed;width:auto;left:0;right:0;top:20px;margin:10px;display:flex;flex-direction:column;overflow:hidden}.sky-modal:focus{outline:none}@media (min-width: 768px){.sky-modal:not(.sky-modal-large){margin:0 auto}.sky-modal-small{width:300px}.sky-modal-small .sky-modal-content,.sky-modal-small .sky-modal-header,.sky-modal-small .sky-modal-footer{max-width:300px}.sky-modal-medium{width:600px}.sky-modal-medium .sky-modal-content,.sky-modal-medium .sky-modal-header,.sky-modal-medium .sky-modal-footer{max-width:600px}}@media (min-width: 920px){.sky-modal-large{margin:0 auto;width:900px}.sky-modal-large .sky-modal-content,.sky-modal-large .sky-modal-header,.sky-modal-large .sky-modal-footer{max-width:900px}}.sky-modal-content{background-color:#fff;--sky-background-color-page-default: #fff}.sky-modal-content:focus{outline-style:dotted;outline-width:thin;outline-offset:-1px}.sky-modal-tiled .sky-modal-content{background-color:#eeeeef;--sky-background-color-page-default: $sky-background-color-neutral-light}.sky-modal-tiled .sky-modal-content ::ng-deep .sky-tile-title{font-family:BLKB Sans,Helvetica Neue,Arial,sans-serif;color:var(--sky-text-color-deemphasized);font-weight:300;font-size:19px}.sky-modal-header{padding:9px 3px 9px 15px;background-color:#fff;display:flex;align-items:baseline;border-bottom:1px solid #e2e3e4}.sky-modal-header-buttons{flex-shrink:.0001}.sky-modal-header-buttons .sky-btn{border:none;color:#cdcfd2;cursor:pointer}.sky-modal-header-buttons .sky-btn:hover{color:#979ba2;transition:color .15s}.sky-modal-header-content{flex-grow:1}.sky-modal-header{flex-shrink:0;z-index:2}.sky-modal-content{overflow-y:auto}.sky-modal-footer{flex-shrink:0;z-index:2}.sky-modal-full-page{width:100%;top:0;margin:0}.sky-modal-full-page .sky-modal-header-buttons sky-icon[icon=close]{font-size:20px}.sky-modal-full-page .sky-modal-content{flex-grow:1}:host ::ng-deep .sky-sectioned-form{min-height:460px;margin:-15px}.sky-modal-content>::ng-deep sky-dock{bottom:-15px;margin-left:-15px;margin-bottom:-15px;padding-top:15px;width:calc(100% + 30px)}:host-context(.sky-theme-modern) .sky-modal-header{border:none;padding:20px 30px}:host-context(.sky-theme-modern) .sky-modal-btn-help,:host-context(.sky-theme-modern) .sky-modal-btn-close{display:none}:host-context(.sky-theme-modern) .sky-modal-content{padding:0}:host-context(.sky-theme-modern) .sky-modal-full-page{width:calc(100% - 60px);margin:30px}:host-context(.sky-theme-modern) .sky-modal-content>::ng-deep sky-dock{bottom:0;margin-left:initial;margin-bottom:initial;padding-top:initial;width:100%}:host-context(.sky-theme-modern) .sky-modal-viewkeeper .sky-modal-header{box-shadow:none!important}:host-context(.sky-theme-modern) .sky-modal-viewkeeper .sky-modal-content ::ng-deep sky-modal-content>.sky-viewkeeper-fixed{box-shadow:0 4px 8px -4px #0000004d}:host-context(.sky-theme-modern) .sky-modal-viewkeeper .sky-modal-content ::ng-deep sky-modal-content>.sky-viewkeeper-fixed>sky-toolbar .sky-toolbar-container{background-color:#fff;--sky-background-color-page-default: #fff;padding-left:30px;padding-right:30px}.sky-theme-modern .sky-modal-header{border:none;padding:20px 30px}.sky-theme-modern .sky-modal-btn-help,.sky-theme-modern .sky-modal-btn-close{display:none}.sky-theme-modern .sky-modal-content{padding:0}.sky-theme-modern .sky-modal-full-page{width:calc(100% - 60px);margin:30px}.sky-theme-modern .sky-modal-content>::ng-deep sky-dock{bottom:0;margin-left:initial;margin-bottom:initial;padding-top:initial;width:100%}.sky-theme-modern .sky-modal-viewkeeper .sky-modal-header{box-shadow:none!important}.sky-theme-modern .sky-modal-viewkeeper .sky-modal-content ::ng-deep sky-modal-content>.sky-viewkeeper-fixed{box-shadow:0 4px 8px -4px #0000004d}.sky-theme-modern .sky-modal-viewkeeper .sky-modal-content ::ng-deep sky-modal-content>.sky-viewkeeper-fixed>sky-toolbar .sky-toolbar-container{background-color:#fff;--sky-background-color-page-default: #fff;padding-left:30px;padding-right:30px}:host-context(.sky-theme-modern.sky-theme-mode-dark) .sky-modal{border-color:#121212}:host-context(.sky-theme-modern.sky-theme-mode-dark) .sky-modal-header{color:#fbfcfe}:host-context(.sky-theme-modern.sky-theme-mode-dark) .sky-modal-header,:host-context(.sky-theme-modern.sky-theme-mode-dark) .sky-modal-content{background-color:transparent;--sky-background-color-page-default: $sky-theme-modern-mode-dark-background-color-page-default}.sky-theme-modern.sky-theme-mode-dark .sky-modal{border-color:#121212}.sky-theme-modern.sky-theme-mode-dark .sky-modal-header{color:#fbfcfe}.sky-theme-modern.sky-theme-mode-dark .sky-modal-header,.sky-theme-modern.sky-theme-mode-dark .sky-modal-content{background-color:transparent;--sky-background-color-page-default: $sky-theme-modern-mode-dark-background-color-page-default}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i2.λ4, selector: "sky-icon", inputs: ["icon", "iconType", "size", "fixedWidth", "variant"] }, { kind: "directive", type: i3.λ2, selector: "[skyId]", exportAs: ["skyId"] }, { kind: "directive", type: SkyModalScrollShadowDirective, selector: "[skyModalScrollShadow]", outputs: ["skyModalScrollShadow"] }, { kind: "pipe", type: i2$2.SkyLibResourcesPipe, name: "skyLibResources" }] }); }
|
|
1048
|
+
}
|
|
1049
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyModalComponent, decorators: [{
|
|
1050
|
+
type: Component,
|
|
1051
|
+
args: [{ selector: 'sky-modal', providers: [
|
|
1052
|
+
SkyModalComponentAdapterService,
|
|
1053
|
+
SkyModalErrorsService,
|
|
1054
|
+
SkyDockService,
|
|
1055
|
+
], template: "<div\n class=\"sky-modal-dialog\"\n aria-modal=\"true\"\n [attr.aria-describedby]=\"ariaDescribedBy || modalContentId.id\"\n [attr.aria-labelledby]=\"ariaLabelledBy || headerId.id\"\n [attr.aria-owns]=\"ariaOwns\"\n [attr.role]=\"ariaRoleOrDefault\"\n (window:resize)=\"windowResize()\"\n>\n <div\n class=\"sky-modal sky-shadow sky-box sky-elevation-16 sky-modal-{{ size }}\"\n tabindex=\"-1\"\n [ngClass]=\"{\n 'sky-modal-tiled': tiledBody,\n 'sky-modal-viewkeeper': viewkeeperEnabled()\n }\"\n [ngStyle]=\"{\n zIndex: modalZIndex\n }\"\n >\n <div\n class=\"sky-modal-header\"\n [hidden]=\"!headerContent || !headerContent.children || headerContent.children.length < 1\"\n [ngStyle]=\"{\n 'box-shadow': scrollShadow?.topShadow\n }\"\n >\n <div\n class=\"sky-modal-header-content\"\n skyId\n [ngClass]=\"{\n 'sky-font-heading-2': size === 'full-page'\n }\"\n #headerContent\n #headerId=\"skyId\"\n >\n <ng-content select=\"sky-modal-header\"></ng-content>\n </div>\n <div class=\"sky-modal-header-buttons\">\n <button\n *ngIf=\"helpKey\"\n class=\"sky-btn sky-modal-btn-help\"\n name=\"help-button\"\n type=\"button\"\n [attr.aria-label]=\"'skyux_modal_open_help' | skyLibResources\"\n (click)=\"helpButtonClick()\"\n >\n <sky-icon icon=\"question-circle\"></sky-icon>\n </button>\n\n <button\n type=\"button\"\n class=\"sky-btn sky-modal-btn-close\"\n [attr.aria-label]=\"'skyux_modal_close' | skyLibResources\"\n (click)=\"closeButtonClick()\"\n >\n <sky-icon icon=\"close\"></sky-icon>\n </button>\n </div>\n </div>\n <div\n class=\"sky-modal-content sky-padding-even-large\"\n role=\"region\"\n tabindex=\"0\"\n skyId\n [attr.aria-labelledby]=\"headerId.id\"\n (skyModalScrollShadow)=\"scrollShadowChange($event)\"\n #modalContentId=\"skyId\"\n #modalContentWrapper\n >\n <ng-content select=\"sky-modal-content\"></ng-content>\n </div>\n <div\n class=\"sky-modal-footer\"\n [ngStyle]=\"{\n 'box-shadow': scrollShadow?.bottomShadow\n }\"\n >\n <ng-content select=\"sky-modal-footer\"></ng-content>\n </div>\n </div>\n</div>\n", styles: [".sky-modal{border-top:1px solid #cdcfd2;border-bottom:1px solid #cdcfd2;border-left:1px solid #cdcfd2;border-right:1px solid #cdcfd2;position:fixed;width:auto;left:0;right:0;top:20px;margin:10px;display:flex;flex-direction:column;overflow:hidden}.sky-modal:focus{outline:none}@media (min-width: 768px){.sky-modal:not(.sky-modal-large){margin:0 auto}.sky-modal-small{width:300px}.sky-modal-small .sky-modal-content,.sky-modal-small .sky-modal-header,.sky-modal-small .sky-modal-footer{max-width:300px}.sky-modal-medium{width:600px}.sky-modal-medium .sky-modal-content,.sky-modal-medium .sky-modal-header,.sky-modal-medium .sky-modal-footer{max-width:600px}}@media (min-width: 920px){.sky-modal-large{margin:0 auto;width:900px}.sky-modal-large .sky-modal-content,.sky-modal-large .sky-modal-header,.sky-modal-large .sky-modal-footer{max-width:900px}}.sky-modal-content{background-color:#fff;--sky-background-color-page-default: #fff}.sky-modal-content:focus{outline-style:dotted;outline-width:thin;outline-offset:-1px}.sky-modal-tiled .sky-modal-content{background-color:#eeeeef;--sky-background-color-page-default: $sky-background-color-neutral-light}.sky-modal-tiled .sky-modal-content ::ng-deep .sky-tile-title{font-family:BLKB Sans,Helvetica Neue,Arial,sans-serif;color:var(--sky-text-color-deemphasized);font-weight:300;font-size:19px}.sky-modal-header{padding:9px 3px 9px 15px;background-color:#fff;display:flex;align-items:baseline;border-bottom:1px solid #e2e3e4}.sky-modal-header-buttons{flex-shrink:.0001}.sky-modal-header-buttons .sky-btn{border:none;color:#cdcfd2;cursor:pointer}.sky-modal-header-buttons .sky-btn:hover{color:#979ba2;transition:color .15s}.sky-modal-header-content{flex-grow:1}.sky-modal-header{flex-shrink:0;z-index:2}.sky-modal-content{overflow-y:auto}.sky-modal-footer{flex-shrink:0;z-index:2}.sky-modal-full-page{width:100%;top:0;margin:0}.sky-modal-full-page .sky-modal-header-buttons sky-icon[icon=close]{font-size:20px}.sky-modal-full-page .sky-modal-content{flex-grow:1}:host ::ng-deep .sky-sectioned-form{min-height:460px;margin:-15px}.sky-modal-content>::ng-deep sky-dock{bottom:-15px;margin-left:-15px;margin-bottom:-15px;padding-top:15px;width:calc(100% + 30px)}:host-context(.sky-theme-modern) .sky-modal-header{border:none;padding:20px 30px}:host-context(.sky-theme-modern) .sky-modal-btn-help,:host-context(.sky-theme-modern) .sky-modal-btn-close{display:none}:host-context(.sky-theme-modern) .sky-modal-content{padding:0}:host-context(.sky-theme-modern) .sky-modal-full-page{width:calc(100% - 60px);margin:30px}:host-context(.sky-theme-modern) .sky-modal-content>::ng-deep sky-dock{bottom:0;margin-left:initial;margin-bottom:initial;padding-top:initial;width:100%}:host-context(.sky-theme-modern) .sky-modal-viewkeeper .sky-modal-header{box-shadow:none!important}:host-context(.sky-theme-modern) .sky-modal-viewkeeper .sky-modal-content ::ng-deep sky-modal-content>.sky-viewkeeper-fixed{box-shadow:0 4px 8px -4px #0000004d}:host-context(.sky-theme-modern) .sky-modal-viewkeeper .sky-modal-content ::ng-deep sky-modal-content>.sky-viewkeeper-fixed>sky-toolbar .sky-toolbar-container{background-color:#fff;--sky-background-color-page-default: #fff;padding-left:30px;padding-right:30px}.sky-theme-modern .sky-modal-header{border:none;padding:20px 30px}.sky-theme-modern .sky-modal-btn-help,.sky-theme-modern .sky-modal-btn-close{display:none}.sky-theme-modern .sky-modal-content{padding:0}.sky-theme-modern .sky-modal-full-page{width:calc(100% - 60px);margin:30px}.sky-theme-modern .sky-modal-content>::ng-deep sky-dock{bottom:0;margin-left:initial;margin-bottom:initial;padding-top:initial;width:100%}.sky-theme-modern .sky-modal-viewkeeper .sky-modal-header{box-shadow:none!important}.sky-theme-modern .sky-modal-viewkeeper .sky-modal-content ::ng-deep sky-modal-content>.sky-viewkeeper-fixed{box-shadow:0 4px 8px -4px #0000004d}.sky-theme-modern .sky-modal-viewkeeper .sky-modal-content ::ng-deep sky-modal-content>.sky-viewkeeper-fixed>sky-toolbar .sky-toolbar-container{background-color:#fff;--sky-background-color-page-default: #fff;padding-left:30px;padding-right:30px}:host-context(.sky-theme-modern.sky-theme-mode-dark) .sky-modal{border-color:#121212}:host-context(.sky-theme-modern.sky-theme-mode-dark) .sky-modal-header{color:#fbfcfe}:host-context(.sky-theme-modern.sky-theme-mode-dark) .sky-modal-header,:host-context(.sky-theme-modern.sky-theme-mode-dark) .sky-modal-content{background-color:transparent;--sky-background-color-page-default: $sky-theme-modern-mode-dark-background-color-page-default}.sky-theme-modern.sky-theme-mode-dark .sky-modal{border-color:#121212}.sky-theme-modern.sky-theme-mode-dark .sky-modal-header{color:#fbfcfe}.sky-theme-modern.sky-theme-mode-dark .sky-modal-header,.sky-theme-modern.sky-theme-mode-dark .sky-modal-content{background-color:transparent;--sky-background-color-page-default: $sky-theme-modern-mode-dark-background-color-page-default}\n"] }]
|
|
1056
|
+
}], ctorParameters: function () { return [{ type: SkyModalHostService }, { type: SkyModalConfiguration }, { type: i0.ElementRef }, { type: i3.SkyAppWindowRef }, { type: SkyModalComponentAdapterService }, { type: i3.SkyCoreAdapterService }, { type: i3.SkyDockService, decorators: [{
|
|
1057
|
+
type: Host
|
|
1058
|
+
}] }, { type: i3.SkyResizeObserverMediaQueryService, decorators: [{
|
|
1059
|
+
type: Optional
|
|
1060
|
+
}] }]; }, propDecorators: { wrapperClass: [{
|
|
1061
|
+
type: HostBinding,
|
|
1062
|
+
args: ['class']
|
|
1063
|
+
}], formErrors: [{
|
|
1064
|
+
type: Input
|
|
1065
|
+
}], ariaRole: [{
|
|
1066
|
+
type: Input
|
|
1067
|
+
}], tiledBody: [{
|
|
1068
|
+
type: Input
|
|
1069
|
+
}], ariaDescribedBy: [{
|
|
1070
|
+
type: Input
|
|
1071
|
+
}], ariaLabelledBy: [{
|
|
1072
|
+
type: Input
|
|
1073
|
+
}], modalContentWrapperElement: [{
|
|
1074
|
+
type: ViewChild,
|
|
1075
|
+
args: ['modalContentWrapper', { read: ElementRef }]
|
|
1076
|
+
}], onDocumentKeyUp: [{
|
|
1077
|
+
type: HostListener,
|
|
1078
|
+
args: ['document:keyup', ['$event']]
|
|
1079
|
+
}], onDocumentKeyDown: [{
|
|
1080
|
+
type: HostListener,
|
|
1081
|
+
args: ['document:keydown', ['$event']]
|
|
1082
|
+
}] } });
|
|
1083
|
+
|
|
1084
|
+
class SkyConfirmComponent {
|
|
1085
|
+
#config;
|
|
1086
|
+
#modal;
|
|
1087
|
+
#resourcesService;
|
|
1088
|
+
constructor(config, modal, resourcesService, idService) {
|
|
1089
|
+
this.preserveWhiteSpace = false;
|
|
1090
|
+
this.isOkType = false;
|
|
1091
|
+
this.#config = config;
|
|
1092
|
+
this.#modal = modal;
|
|
1093
|
+
this.#resourcesService = resourcesService;
|
|
1094
|
+
if (config.type === SkyConfirmType.Custom &&
|
|
1095
|
+
config.buttons &&
|
|
1096
|
+
config.buttons.length > 0) {
|
|
1097
|
+
this.buttons = this.#getCustomButtons(config.buttons);
|
|
1098
|
+
}
|
|
1099
|
+
else {
|
|
1100
|
+
this.#getPresetButtons()
|
|
1101
|
+
.pipe(take(1))
|
|
1102
|
+
.subscribe((buttons) => {
|
|
1103
|
+
this.buttons = buttons;
|
|
1104
|
+
});
|
|
1105
|
+
}
|
|
1106
|
+
this.message = config.message;
|
|
1107
|
+
this.body = config.body;
|
|
1108
|
+
// Using the service here instead of the directive due to the confirm component's "body" container being conditional and thus a template variable being unavailable at an outer scope
|
|
1109
|
+
this.bodyId = idService.generateId();
|
|
1110
|
+
this.preserveWhiteSpace = !!config.preserveWhiteSpace;
|
|
1111
|
+
this.isOkType = config.type === SkyConfirmType.OK;
|
|
1112
|
+
}
|
|
1113
|
+
close(button) {
|
|
1114
|
+
const result = {
|
|
1115
|
+
action: button.action,
|
|
1116
|
+
};
|
|
1117
|
+
this.#modal.close(result);
|
|
1118
|
+
}
|
|
1119
|
+
#getPresetButtons() {
|
|
1120
|
+
const emitter = new ReplaySubject(1);
|
|
1121
|
+
this.#resourcesService
|
|
1122
|
+
.getStrings({
|
|
1123
|
+
cancel: 'skyux_confirm_dialog_default_cancel_text',
|
|
1124
|
+
no: 'skyux_confirm_dialog_default_no_text',
|
|
1125
|
+
ok: 'skyux_confirm_dialog_default_ok_text',
|
|
1126
|
+
yes: 'skyux_confirm_dialog_default_yes_text',
|
|
1127
|
+
})
|
|
1128
|
+
.subscribe((values) => {
|
|
1129
|
+
const confirmButtons = [];
|
|
1130
|
+
switch (this.#config.type) {
|
|
1131
|
+
case SkyConfirmType.YesNoCancel:
|
|
1132
|
+
case SkyConfirmType.YesCancel:
|
|
1133
|
+
confirmButtons.push({
|
|
1134
|
+
text: values.yes,
|
|
1135
|
+
autofocus: true,
|
|
1136
|
+
styleType: 'primary',
|
|
1137
|
+
action: 'yes',
|
|
1138
|
+
});
|
|
1139
|
+
if (this.#config.type === SkyConfirmType.YesNoCancel) {
|
|
1140
|
+
confirmButtons.push({
|
|
1141
|
+
text: values.no,
|
|
1142
|
+
styleType: 'default',
|
|
1143
|
+
action: 'no',
|
|
1144
|
+
});
|
|
1145
|
+
}
|
|
1146
|
+
confirmButtons.push({
|
|
1147
|
+
text: values.cancel,
|
|
1148
|
+
styleType: 'link',
|
|
1149
|
+
action: 'cancel',
|
|
1150
|
+
});
|
|
1151
|
+
break;
|
|
1152
|
+
default:
|
|
1153
|
+
confirmButtons.push({
|
|
1154
|
+
text: values.ok,
|
|
1155
|
+
autofocus: true,
|
|
1156
|
+
styleType: 'primary',
|
|
1157
|
+
action: 'ok',
|
|
1158
|
+
});
|
|
1159
|
+
}
|
|
1160
|
+
emitter.next(confirmButtons);
|
|
1161
|
+
});
|
|
1162
|
+
return emitter.asObservable();
|
|
1163
|
+
}
|
|
1164
|
+
#getCustomButtons(buttonConfig) {
|
|
1165
|
+
return buttonConfig.map((config) => ({
|
|
1166
|
+
text: config.text,
|
|
1167
|
+
action: config.action,
|
|
1168
|
+
styleType: config.styleType || 'default',
|
|
1169
|
+
autofocus: config.autofocus || false,
|
|
1170
|
+
}));
|
|
1171
|
+
}
|
|
1172
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyConfirmComponent, deps: [{ token: SKY_CONFIRM_CONFIG }, { token: SkyModalInstance }, { token: i2$2.SkyLibResourcesService }, { token: i3.SkyIdService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1173
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.1.7", type: SkyConfirmComponent, selector: "sky-confirm", ngImport: i0, template: "<div class=\"sky-confirm\" [ngClass]=\"{ 'sky-confirm-type-ok': isOkType }\">\n <sky-modal\n ariaRole=\"alertdialog\"\n [ariaLabelledBy]=\"confirmMessage.id\"\n [ariaDescribedBy]=\"body ? bodyId : undefined\"\n >\n <sky-modal-content class=\"sky-confirm-content\">\n <!--\n The following \"magic comment\" keeps Prettier from adding line breaks\n inside the div and causing leading and trailing whitespace when\n `preserveWhiteSpace` is `true`.\n https://prettier.io/blog/2018/11/07/1.15.0.html#whitespace-sensitive-formatting\n -->\n <!-- display: inline -->\n <div\n class=\"sky-confirm-message\"\n [ngClass]=\"{\n 'sky-confirm-preserve-white-space': preserveWhiteSpace\n }\"\n [skyThemeClass]=\"{\n 'sky-font-display-4': 'default',\n 'sky-font-heading-1 sky-font-display-3': 'modern'\n }\"\n skyId\n #confirmMessage=\"skyId\"\n >{{ message }}</div\n >\n\n <!--\n The following \"magic comment\" keeps Prettier from adding line breaks\n inside the div and causing leading and trailing whitespace when\n `preserveWhiteSpace` is `true`.\n https://prettier.io/blog/2018/11/07/1.15.0.html#whitespace-sensitive-formatting\n -->\n <!-- display: inline -->\n <div\n *ngIf=\"body\"\n class=\"sky-confirm-body\"\n [id]=\"bodyId\"\n [ngClass]=\"{\n 'sky-confirm-preserve-white-space': preserveWhiteSpace\n }\"\n >{{ body }}</div\n >\n\n <div class=\"sky-confirm-buttons\">\n <button\n *ngFor=\"let button of buttons\"\n type=\"button\"\n class=\"sky-btn\"\n [ngClass]=\"'sky-btn-' + button.styleType\"\n [skyThemeClass]=\"{\n 'sky-margin-inline-sm': 'modern',\n 'sky-margin-inline-compact': 'default'\n }\"\n (click)=\"close(button)\"\n [attr.autofocus]=\"button.autofocus ? 'autofocus' : null\"\n >\n {{ button.text }}\n </button>\n </div>\n </sky-modal-content>\n </sky-modal>\n</div>\n", styles: [".sky-confirm{--sky-confirm-body-margin-top: var(--sky-margin-stacked-sm);--sky-confirm-buttons-margin-top: var(--sky-margin-stacked-xl);--sky-confirm-content-padding: 0;--sky-confirm-message-padding-bottom: 0}:host-context(.sky-theme-modern) .sky-confirm{--sky-confirm-body-margin-top: 0;--sky-confirm-buttons-margin-top: var(--sky-margin-stacked-lg);--sky-confirm-content-padding: var(--sky-margin-stacked-lg) var(--sky-margin-inline-xl);--sky-confirm-message-padding-bottom: var(--sky-margin-stacked-lg)}.sky-theme-modern .sky-confirm{--sky-confirm-body-margin-top: 0;--sky-confirm-buttons-margin-top: var(--sky-margin-stacked-lg);--sky-confirm-content-padding: var(--sky-margin-stacked-lg) var(--sky-margin-inline-xl);--sky-confirm-message-padding-bottom: var(--sky-margin-stacked-lg)}.sky-confirm-content{padding:var(--sky-confirm-content-padding)}.sky-confirm-message{margin-top:var(--sky-margin-stacked-xs);padding-bottom:var(--sky-confirm-message-padding-bottom)}.sky-confirm-body{margin-top:var(--sky-confirm-body-margin-top)}.sky-confirm-buttons{margin-top:var(--sky-confirm-buttons-margin-top)}.sky-confirm-preserve-white-space{white-space:pre-wrap}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i3.λ2, selector: "[skyId]", exportAs: ["skyId"] }, { kind: "component", type: SkyModalComponent, selector: "sky-modal", inputs: ["formErrors", "ariaRole", "tiledBody", "ariaDescribedBy", "ariaLabelledBy"] }, { kind: "component", type: SkyModalContentComponent, selector: "sky-modal-content" }, { kind: "directive", type: i2$1.λ2, selector: "[skyThemeClass]", inputs: ["class", "skyThemeClass"] }] }); }
|
|
1174
|
+
}
|
|
1175
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyConfirmComponent, decorators: [{
|
|
1176
|
+
type: Component,
|
|
1177
|
+
args: [{ selector: 'sky-confirm', template: "<div class=\"sky-confirm\" [ngClass]=\"{ 'sky-confirm-type-ok': isOkType }\">\n <sky-modal\n ariaRole=\"alertdialog\"\n [ariaLabelledBy]=\"confirmMessage.id\"\n [ariaDescribedBy]=\"body ? bodyId : undefined\"\n >\n <sky-modal-content class=\"sky-confirm-content\">\n <!--\n The following \"magic comment\" keeps Prettier from adding line breaks\n inside the div and causing leading and trailing whitespace when\n `preserveWhiteSpace` is `true`.\n https://prettier.io/blog/2018/11/07/1.15.0.html#whitespace-sensitive-formatting\n -->\n <!-- display: inline -->\n <div\n class=\"sky-confirm-message\"\n [ngClass]=\"{\n 'sky-confirm-preserve-white-space': preserveWhiteSpace\n }\"\n [skyThemeClass]=\"{\n 'sky-font-display-4': 'default',\n 'sky-font-heading-1 sky-font-display-3': 'modern'\n }\"\n skyId\n #confirmMessage=\"skyId\"\n >{{ message }}</div\n >\n\n <!--\n The following \"magic comment\" keeps Prettier from adding line breaks\n inside the div and causing leading and trailing whitespace when\n `preserveWhiteSpace` is `true`.\n https://prettier.io/blog/2018/11/07/1.15.0.html#whitespace-sensitive-formatting\n -->\n <!-- display: inline -->\n <div\n *ngIf=\"body\"\n class=\"sky-confirm-body\"\n [id]=\"bodyId\"\n [ngClass]=\"{\n 'sky-confirm-preserve-white-space': preserveWhiteSpace\n }\"\n >{{ body }}</div\n >\n\n <div class=\"sky-confirm-buttons\">\n <button\n *ngFor=\"let button of buttons\"\n type=\"button\"\n class=\"sky-btn\"\n [ngClass]=\"'sky-btn-' + button.styleType\"\n [skyThemeClass]=\"{\n 'sky-margin-inline-sm': 'modern',\n 'sky-margin-inline-compact': 'default'\n }\"\n (click)=\"close(button)\"\n [attr.autofocus]=\"button.autofocus ? 'autofocus' : null\"\n >\n {{ button.text }}\n </button>\n </div>\n </sky-modal-content>\n </sky-modal>\n</div>\n", styles: [".sky-confirm{--sky-confirm-body-margin-top: var(--sky-margin-stacked-sm);--sky-confirm-buttons-margin-top: var(--sky-margin-stacked-xl);--sky-confirm-content-padding: 0;--sky-confirm-message-padding-bottom: 0}:host-context(.sky-theme-modern) .sky-confirm{--sky-confirm-body-margin-top: 0;--sky-confirm-buttons-margin-top: var(--sky-margin-stacked-lg);--sky-confirm-content-padding: var(--sky-margin-stacked-lg) var(--sky-margin-inline-xl);--sky-confirm-message-padding-bottom: var(--sky-margin-stacked-lg)}.sky-theme-modern .sky-confirm{--sky-confirm-body-margin-top: 0;--sky-confirm-buttons-margin-top: var(--sky-margin-stacked-lg);--sky-confirm-content-padding: var(--sky-margin-stacked-lg) var(--sky-margin-inline-xl);--sky-confirm-message-padding-bottom: var(--sky-margin-stacked-lg)}.sky-confirm-content{padding:var(--sky-confirm-content-padding)}.sky-confirm-message{margin-top:var(--sky-margin-stacked-xs);padding-bottom:var(--sky-confirm-message-padding-bottom)}.sky-confirm-body{margin-top:var(--sky-confirm-body-margin-top)}.sky-confirm-buttons{margin-top:var(--sky-confirm-buttons-margin-top)}.sky-confirm-preserve-white-space{white-space:pre-wrap}\n"] }]
|
|
1178
|
+
}], ctorParameters: function () { return [{ type: undefined, decorators: [{
|
|
1179
|
+
type: Inject,
|
|
1180
|
+
args: [SKY_CONFIRM_CONFIG]
|
|
1181
|
+
}] }, { type: SkyModalInstance }, { type: i2$2.SkyLibResourcesService }, { type: i3.SkyIdService }]; } });
|
|
1182
|
+
|
|
1183
|
+
/**
|
|
1184
|
+
* A service that launches modals.
|
|
1185
|
+
* @dynamic
|
|
1186
|
+
*/
|
|
1187
|
+
class SkyModalService {
|
|
1188
|
+
#dynamicComponentService;
|
|
1189
|
+
constructor(dynamicComponentService) {
|
|
1190
|
+
this.#dynamicComponentService = dynamicComponentService;
|
|
1191
|
+
}
|
|
1192
|
+
/**
|
|
1193
|
+
* @internal
|
|
1194
|
+
* Removes the modal host from the DOM.
|
|
1195
|
+
*/
|
|
1196
|
+
dispose() {
|
|
1197
|
+
if (SkyModalService.host) {
|
|
1198
|
+
this.#dynamicComponentService.removeComponent(SkyModalService.host);
|
|
1199
|
+
SkyModalService.host = undefined;
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1202
|
+
/**
|
|
1203
|
+
* Opens a modal using the specified component.
|
|
1204
|
+
* @param component Determines the component to render.
|
|
1205
|
+
* @param {SkyModalConfigurationInterface} config Specifies configuration options for the modal.
|
|
1206
|
+
*/
|
|
1207
|
+
open(component, config) {
|
|
1208
|
+
const modalInstance = new SkyModalInstance();
|
|
1209
|
+
this.#createHostComponent();
|
|
1210
|
+
const params = this.#getConfigFromParameter(config);
|
|
1211
|
+
params.providers ||= [];
|
|
1212
|
+
params.providers.push({
|
|
1213
|
+
provide: SkyModalInstance,
|
|
1214
|
+
useValue: modalInstance,
|
|
1215
|
+
});
|
|
1216
|
+
if (SkyModalService.host) {
|
|
1217
|
+
SkyModalService.host.instance.open(modalInstance, component, params);
|
|
1218
|
+
}
|
|
1219
|
+
return modalInstance;
|
|
1220
|
+
}
|
|
1221
|
+
#getConfigFromParameter(providersOrConfig) {
|
|
1222
|
+
const defaultParams = {
|
|
1223
|
+
providers: [],
|
|
1224
|
+
fullPage: false,
|
|
1225
|
+
size: 'medium',
|
|
1226
|
+
tiledBody: false,
|
|
1227
|
+
};
|
|
1228
|
+
let params = {};
|
|
1229
|
+
let method = undefined;
|
|
1230
|
+
// Object Literal Lookup for backwards compatibility.
|
|
1231
|
+
method = {
|
|
1232
|
+
'providers?': Object.assign({}, defaultParams, {
|
|
1233
|
+
providers: providersOrConfig,
|
|
1234
|
+
}),
|
|
1235
|
+
config: Object.assign({}, defaultParams, providersOrConfig),
|
|
1236
|
+
};
|
|
1237
|
+
if (Array.isArray(providersOrConfig) === true) {
|
|
1238
|
+
params = method['providers?'];
|
|
1239
|
+
}
|
|
1240
|
+
else {
|
|
1241
|
+
params = method['config'];
|
|
1242
|
+
}
|
|
1243
|
+
return params;
|
|
1244
|
+
}
|
|
1245
|
+
#createHostComponent() {
|
|
1246
|
+
if (!SkyModalService.host) {
|
|
1247
|
+
SkyModalService.host = this.#dynamicComponentService.createComponent(SkyModalHostComponent, {
|
|
1248
|
+
providers: [
|
|
1249
|
+
{
|
|
1250
|
+
provide: SkyModalHostContext,
|
|
1251
|
+
useValue: new SkyModalHostContext({
|
|
1252
|
+
teardownCallback: () => {
|
|
1253
|
+
this.dispose();
|
|
1254
|
+
},
|
|
1255
|
+
}),
|
|
1256
|
+
},
|
|
1257
|
+
],
|
|
1258
|
+
});
|
|
1259
|
+
}
|
|
1260
|
+
}
|
|
1261
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyModalService, deps: [{ token: i3.SkyDynamicComponentService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1262
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyModalService, providedIn: 'any' }); }
|
|
1263
|
+
}
|
|
1264
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyModalService, decorators: [{
|
|
1265
|
+
type: Injectable,
|
|
1266
|
+
args: [{
|
|
1267
|
+
// Must be 'any' so that the modal component is created in the context of its module's injector.
|
|
1268
|
+
// If set to 'root', the component's dependency injections would only be derived from the root
|
|
1269
|
+
// injector and may lose context if the modal was opened from within a lazy-loaded module.
|
|
1270
|
+
providedIn: 'any',
|
|
1271
|
+
}]
|
|
1272
|
+
}], ctorParameters: function () { return [{ type: i3.SkyDynamicComponentService }]; } });
|
|
1273
|
+
|
|
1274
|
+
/**
|
|
1275
|
+
* Launches a dialog.
|
|
1276
|
+
*/
|
|
1277
|
+
class SkyConfirmService {
|
|
1278
|
+
#modalService;
|
|
1279
|
+
constructor(modalService) {
|
|
1280
|
+
this.#modalService = modalService;
|
|
1281
|
+
}
|
|
1282
|
+
/**
|
|
1283
|
+
* Opens a dialog using the specified options.
|
|
1284
|
+
* @param config Specifies configuration options for the dialog.
|
|
1285
|
+
*/
|
|
1286
|
+
open(config) {
|
|
1287
|
+
const modalInstance = this.#modalService.open(SkyConfirmComponent, {
|
|
1288
|
+
providers: [
|
|
1289
|
+
{
|
|
1290
|
+
provide: SKY_CONFIRM_CONFIG,
|
|
1291
|
+
useValue: config,
|
|
1292
|
+
},
|
|
1293
|
+
],
|
|
1294
|
+
});
|
|
1295
|
+
const confirmInstance = new SkyConfirmInstance();
|
|
1296
|
+
modalInstance.closed.subscribe((args) => {
|
|
1297
|
+
let result = args.data;
|
|
1298
|
+
// The modal was closed using the ESC key.
|
|
1299
|
+
if (result === undefined) {
|
|
1300
|
+
result = {
|
|
1301
|
+
action: 'cancel',
|
|
1302
|
+
};
|
|
1303
|
+
}
|
|
1304
|
+
confirmInstance.closed.emit(result);
|
|
1305
|
+
confirmInstance.closed.complete();
|
|
1306
|
+
});
|
|
1307
|
+
return confirmInstance;
|
|
1308
|
+
}
|
|
1309
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyConfirmService, deps: [{ token: SkyModalService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1310
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyConfirmService, providedIn: 'any' }); }
|
|
1311
|
+
}
|
|
1312
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyConfirmService, decorators: [{
|
|
1313
|
+
type: Injectable,
|
|
1314
|
+
args: [{
|
|
1315
|
+
// Must be 'any' so that the modal component is created in the context of its module's injector.
|
|
1316
|
+
// If set to 'root', the component's dependency injections would only be derived from the root
|
|
1317
|
+
// injector and may loose context if the modal was opened from within a lazy-loaded module.
|
|
1318
|
+
providedIn: 'any',
|
|
1319
|
+
}]
|
|
1320
|
+
}], ctorParameters: function () { return [{ type: SkyModalService }]; } });
|
|
1321
|
+
|
|
1322
|
+
/**
|
|
1323
|
+
* Provides a way to mark a modal as "dirty" and displays a confirmation
|
|
1324
|
+
* message when a user closes the modal without saving.
|
|
1325
|
+
*/
|
|
1326
|
+
class SkyModalIsDirtyDirective {
|
|
1327
|
+
constructor() {
|
|
1328
|
+
/**
|
|
1329
|
+
* Whether the user edited an input on the modal.
|
|
1330
|
+
* @required
|
|
1331
|
+
*/
|
|
1332
|
+
this.isDirty = false;
|
|
1333
|
+
this.#ngUnsubscribe = new Subject();
|
|
1334
|
+
this.#modalInstance = inject(SkyModalInstance);
|
|
1335
|
+
this.#confirmSvc = inject(SkyConfirmService);
|
|
1336
|
+
this.#resourcesSvc = inject(SkyLibResourcesService);
|
|
1337
|
+
}
|
|
1338
|
+
#ngUnsubscribe;
|
|
1339
|
+
#modalInstance;
|
|
1340
|
+
#confirmSvc;
|
|
1341
|
+
#resourcesSvc;
|
|
1342
|
+
ngOnInit() {
|
|
1343
|
+
this.#modalInstance.beforeClose
|
|
1344
|
+
.pipe(takeUntil(this.#ngUnsubscribe))
|
|
1345
|
+
.subscribe((handler) => this.#promptIfDirty(handler));
|
|
1346
|
+
}
|
|
1347
|
+
ngOnDestroy() {
|
|
1348
|
+
this.#ngUnsubscribe.next();
|
|
1349
|
+
this.#ngUnsubscribe.complete();
|
|
1350
|
+
}
|
|
1351
|
+
#promptIfDirty(handler) {
|
|
1352
|
+
if (this.isDirty && handler.closeArgs.reason === 'close') {
|
|
1353
|
+
this.#resourcesSvc
|
|
1354
|
+
.getStrings({
|
|
1355
|
+
message: 'skyux_modal_dirty_default_message',
|
|
1356
|
+
discardActionText: 'skyux_modal_dirty_default_discard_changes_text',
|
|
1357
|
+
keepActionText: 'skyux_modal_dirty_default_keep_working_text',
|
|
1358
|
+
})
|
|
1359
|
+
.subscribe((textValues) => {
|
|
1360
|
+
const discardAction = 'discard';
|
|
1361
|
+
const keepAction = 'keep';
|
|
1362
|
+
this.#confirmSvc
|
|
1363
|
+
.open({
|
|
1364
|
+
message: textValues.message,
|
|
1365
|
+
buttons: [
|
|
1366
|
+
{
|
|
1367
|
+
action: discardAction,
|
|
1368
|
+
text: textValues.discardActionText,
|
|
1369
|
+
styleType: 'primary',
|
|
1370
|
+
},
|
|
1371
|
+
{
|
|
1372
|
+
action: keepAction,
|
|
1373
|
+
text: textValues.keepActionText,
|
|
1374
|
+
styleType: 'link',
|
|
1375
|
+
},
|
|
1376
|
+
],
|
|
1377
|
+
type: SkyConfirmType.Custom,
|
|
1378
|
+
})
|
|
1379
|
+
.closed.subscribe((args) => {
|
|
1380
|
+
if (args.action === discardAction) {
|
|
1381
|
+
handler.closeModal();
|
|
1382
|
+
}
|
|
1383
|
+
});
|
|
1384
|
+
});
|
|
1385
|
+
}
|
|
1386
|
+
else {
|
|
1387
|
+
handler.closeModal();
|
|
1388
|
+
}
|
|
1389
|
+
}
|
|
1390
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyModalIsDirtyDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
1391
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.1.7", type: SkyModalIsDirtyDirective, selector: "sky-modal[isDirty]", inputs: { isDirty: "isDirty" }, host: { properties: { "attr.data-sky-modal-is-dirty": "this.isDirty" } }, ngImport: i0 }); }
|
|
1392
|
+
}
|
|
1393
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyModalIsDirtyDirective, decorators: [{
|
|
1394
|
+
type: Directive,
|
|
1395
|
+
args: [{
|
|
1396
|
+
// Since this is limited to sky-modal, it should be safe to
|
|
1397
|
+
// leave off the sky prefix.
|
|
1398
|
+
// eslint-disable-next-line @angular-eslint/directive-selector
|
|
1399
|
+
selector: 'sky-modal[isDirty]',
|
|
1400
|
+
}]
|
|
1401
|
+
}], propDecorators: { isDirty: [{
|
|
1402
|
+
type: Input
|
|
1403
|
+
}, {
|
|
1404
|
+
type: HostBinding,
|
|
1405
|
+
args: ['attr.data-sky-modal-is-dirty']
|
|
1406
|
+
}] } });
|
|
1407
|
+
|
|
1408
|
+
class SkyModalModule {
|
|
1409
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyModalModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
1410
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.1.7", ngImport: i0, type: SkyModalModule, declarations: [SkyModalComponent,
|
|
1411
|
+
SkyModalContentComponent,
|
|
1412
|
+
SkyModalFooterComponent,
|
|
1413
|
+
SkyModalHeaderComponent,
|
|
1414
|
+
SkyModalHostComponent,
|
|
1415
|
+
SkyModalIsDirtyDirective,
|
|
1416
|
+
SkyModalScrollShadowDirective], imports: [CommonModule,
|
|
1417
|
+
RouterModule,
|
|
1418
|
+
SkyIconModule,
|
|
1419
|
+
SkyIdModule,
|
|
1420
|
+
SkyModalsResourcesModule,
|
|
1421
|
+
SkyStatusIndicatorModule,
|
|
1422
|
+
SkyThemeModule,
|
|
1423
|
+
SkyTrimModule], exports: [SkyModalComponent,
|
|
1424
|
+
SkyModalContentComponent,
|
|
1425
|
+
SkyModalFooterComponent,
|
|
1426
|
+
SkyModalHeaderComponent,
|
|
1427
|
+
SkyModalIsDirtyDirective] }); }
|
|
1428
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyModalModule, imports: [CommonModule,
|
|
1429
|
+
RouterModule,
|
|
1430
|
+
SkyIconModule,
|
|
1431
|
+
SkyIdModule,
|
|
1432
|
+
SkyModalsResourcesModule,
|
|
1433
|
+
SkyStatusIndicatorModule,
|
|
1434
|
+
SkyThemeModule,
|
|
1435
|
+
SkyTrimModule] }); }
|
|
1436
|
+
}
|
|
1437
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyModalModule, decorators: [{
|
|
1438
|
+
type: NgModule,
|
|
1439
|
+
args: [{
|
|
1440
|
+
declarations: [
|
|
1441
|
+
SkyModalComponent,
|
|
1442
|
+
SkyModalContentComponent,
|
|
1443
|
+
SkyModalFooterComponent,
|
|
1444
|
+
SkyModalHeaderComponent,
|
|
1445
|
+
SkyModalHostComponent,
|
|
1446
|
+
SkyModalIsDirtyDirective,
|
|
1447
|
+
SkyModalScrollShadowDirective,
|
|
1448
|
+
],
|
|
1449
|
+
imports: [
|
|
1450
|
+
CommonModule,
|
|
1451
|
+
RouterModule,
|
|
1452
|
+
SkyIconModule,
|
|
1453
|
+
SkyIdModule,
|
|
1454
|
+
SkyModalsResourcesModule,
|
|
1455
|
+
SkyStatusIndicatorModule,
|
|
1456
|
+
SkyThemeModule,
|
|
1457
|
+
SkyTrimModule,
|
|
1458
|
+
],
|
|
1459
|
+
exports: [
|
|
1460
|
+
SkyModalComponent,
|
|
1461
|
+
SkyModalContentComponent,
|
|
1462
|
+
SkyModalFooterComponent,
|
|
1463
|
+
SkyModalHeaderComponent,
|
|
1464
|
+
SkyModalIsDirtyDirective,
|
|
1465
|
+
],
|
|
1466
|
+
}]
|
|
1467
|
+
}] });
|
|
1468
|
+
|
|
1469
|
+
class SkyConfirmModule {
|
|
1470
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyConfirmModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
1471
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.1.7", ngImport: i0, type: SkyConfirmModule, declarations: [SkyConfirmComponent], imports: [CommonModule,
|
|
1472
|
+
SkyIdModule,
|
|
1473
|
+
SkyModalModule,
|
|
1474
|
+
SkyModalsResourcesModule,
|
|
1475
|
+
SkyThemeModule], exports: [SkyConfirmComponent] }); }
|
|
1476
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyConfirmModule, imports: [CommonModule,
|
|
1477
|
+
SkyIdModule,
|
|
1478
|
+
SkyModalModule,
|
|
1479
|
+
SkyModalsResourcesModule,
|
|
1480
|
+
SkyThemeModule] }); }
|
|
1481
|
+
}
|
|
1482
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.7", ngImport: i0, type: SkyConfirmModule, decorators: [{
|
|
1483
|
+
type: NgModule,
|
|
1484
|
+
args: [{
|
|
1485
|
+
declarations: [SkyConfirmComponent],
|
|
1486
|
+
imports: [
|
|
1487
|
+
CommonModule,
|
|
1488
|
+
SkyIdModule,
|
|
1489
|
+
SkyModalModule,
|
|
1490
|
+
SkyModalsResourcesModule,
|
|
1491
|
+
SkyThemeModule,
|
|
1492
|
+
],
|
|
1493
|
+
exports: [SkyConfirmComponent],
|
|
1494
|
+
}]
|
|
1495
|
+
}] });
|
|
1496
|
+
|
|
1497
|
+
/**
|
|
1498
|
+
* Generated bundle index. Do not edit.
|
|
1499
|
+
*/
|
|
1500
|
+
|
|
1501
|
+
export { SkyConfirmInstance, SkyConfirmModule, SkyConfirmService, SkyConfirmType, SkyModalBeforeCloseHandler, SkyModalCloseArgs, SkyModalConfiguration, SkyModalErrorsService, SkyModalHostService, SkyModalInstance, SkyModalModule, SkyModalService, SkyConfirmComponent as λ1, SkyModalContentComponent as λ2, SkyModalFooterComponent as λ3, SkyModalHeaderComponent as λ4, SkyModalComponent as λ5, SkyModalIsDirtyDirective as λ6 };
|
|
1502
|
+
//# sourceMappingURL=skyux-modals.mjs.map
|