@skyux/modals 11.27.0 → 11.28.0
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 +564 -564
- package/esm2022/lib/modules/modal/modal-adapter.service.mjs +35 -11
- package/esm2022/lib/modules/modal/modal-component-adapter.service.mjs +3 -25
- package/esm2022/lib/modules/modal/modal-host.component.mjs +15 -9
- package/esm2022/lib/modules/modal/modal.component.mjs +2 -9
- package/fesm2022/skyux-modals.mjs +48 -47
- package/fesm2022/skyux-modals.mjs.map +1 -1
- package/lib/modules/modal/modal-adapter.service.d.ts +1 -0
- package/lib/modules/modal/modal-component-adapter.service.d.ts +0 -3
- package/package.json +7 -7
|
@@ -4,7 +4,7 @@ import { NgModule, InjectionToken, Component, ViewEncapsulation, Injectable, inj
|
|
|
4
4
|
import * as i1$2 from '@angular/common';
|
|
5
5
|
import { CommonModule } from '@angular/common';
|
|
6
6
|
import * as i1 from '@skyux/core';
|
|
7
|
-
import { SkyResponsiveHostDirective, SkyTrimModule, SkyCoreAdapterService, SkyDockService, SkyLiveAnnouncerService,
|
|
7
|
+
import { SkyResponsiveHostDirective, SkyTrimModule, SkyCoreAdapterService, SkyDockService, SkyLiveAnnouncerService, SkyDockLocation, SkyIdModule, SkyScrollShadowDirective, SkyIdService, SkyDynamicComponentService, SkyAppWindowRef, SKY_STACKING_CONTEXT } from '@skyux/core';
|
|
8
8
|
import * as i5 from '@skyux/i18n';
|
|
9
9
|
import { SkyLibResourcesService, SkyI18nModule } from '@skyux/i18n';
|
|
10
10
|
import * as i1$1 from '@skyux/theme';
|
|
@@ -282,10 +282,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
|
|
|
282
282
|
* @internal
|
|
283
283
|
*/
|
|
284
284
|
class SkyModalComponentAdapterService {
|
|
285
|
-
#coreAdapter;
|
|
286
|
-
constructor(coreAdapter) {
|
|
287
|
-
this.#coreAdapter = coreAdapter;
|
|
288
|
-
}
|
|
289
285
|
handleWindowChange(modalEl) {
|
|
290
286
|
const boundedHeightEl = modalEl.nativeElement.querySelector('.sky-modal');
|
|
291
287
|
const fullPageModalEl = modalEl.nativeElement.querySelector('.sky-modal-full-page');
|
|
@@ -343,23 +339,6 @@ class SkyModalComponentAdapterService {
|
|
|
343
339
|
modalContentHasDirectChildViewkeeper(modalContentEl) {
|
|
344
340
|
return !!modalContentEl.nativeElement.querySelector('sky-modal-content > .sky-viewkeeper-fixed');
|
|
345
341
|
}
|
|
346
|
-
modalOpened(modalEl) {
|
|
347
|
-
/* istanbul ignore else */
|
|
348
|
-
/* handle the case where somehow there is a focused element already in the modal */
|
|
349
|
-
if (!(document.activeElement &&
|
|
350
|
-
modalEl.nativeElement.contains(document.activeElement))) {
|
|
351
|
-
const currentScrollX = window.pageXOffset;
|
|
352
|
-
const currentScrollY = window.pageYOffset;
|
|
353
|
-
const inputWithAutofocus = modalEl.nativeElement.querySelector('[autofocus]');
|
|
354
|
-
if (inputWithAutofocus) {
|
|
355
|
-
inputWithAutofocus.focus();
|
|
356
|
-
}
|
|
357
|
-
else {
|
|
358
|
-
this.#coreAdapter.getFocusableChildrenAndApplyFocus(modalEl, '.sky-modal-content', true);
|
|
359
|
-
}
|
|
360
|
-
window.scrollTo(currentScrollX, currentScrollY);
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
342
|
#setFullPageHeight(fullPageModalEl) {
|
|
364
343
|
const windowHeight = window.innerHeight;
|
|
365
344
|
const fullPageModalStyle = getComputedStyle(fullPageModalEl);
|
|
@@ -369,12 +348,12 @@ class SkyModalComponentAdapterService {
|
|
|
369
348
|
fullPageModalEl.style.height = fullPageModalHeight;
|
|
370
349
|
fullPageModalEl.style.maxHeight = fullPageModalHeight;
|
|
371
350
|
}
|
|
372
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SkyModalComponentAdapterService, deps: [
|
|
351
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SkyModalComponentAdapterService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
373
352
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SkyModalComponentAdapterService }); }
|
|
374
353
|
}
|
|
375
354
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SkyModalComponentAdapterService, decorators: [{
|
|
376
355
|
type: Injectable
|
|
377
|
-
}]
|
|
356
|
+
}] });
|
|
378
357
|
|
|
379
358
|
/**
|
|
380
359
|
* @internal
|
|
@@ -538,7 +517,6 @@ class SkyModalComponent {
|
|
|
538
517
|
#errorsSvc;
|
|
539
518
|
#hostService;
|
|
540
519
|
#liveAnnouncerSvc;
|
|
541
|
-
#windowRef;
|
|
542
520
|
/**
|
|
543
521
|
* This provider is optional to account for situations where a modal component
|
|
544
522
|
* is implemented without the modal service. For example, when a consumer tests
|
|
@@ -565,7 +543,6 @@ class SkyModalComponent {
|
|
|
565
543
|
this.#errorsSvc = inject(SkyModalErrorsService);
|
|
566
544
|
this.#hostService = inject(SkyModalHostService);
|
|
567
545
|
this.#liveAnnouncerSvc = inject(SkyLiveAnnouncerService);
|
|
568
|
-
this.#windowRef = inject(SkyAppWindowRef);
|
|
569
546
|
/**
|
|
570
547
|
* This provider is optional to account for situations where a modal component
|
|
571
548
|
* is implemented without the modal service. For example, when a consumer tests
|
|
@@ -649,11 +626,6 @@ class SkyModalComponent {
|
|
|
649
626
|
}
|
|
650
627
|
ngAfterViewInit() {
|
|
651
628
|
this.#componentAdapter.handleWindowChange(this.#elRef);
|
|
652
|
-
// Adding a timeout to avoid ExpressionChangedAfterItHasBeenCheckedError.
|
|
653
|
-
// https://stackoverflow.com/questions/40562845
|
|
654
|
-
this.#windowRef.nativeWindow.setTimeout(() => {
|
|
655
|
-
this.#componentAdapter.modalOpened(this.#elRef);
|
|
656
|
-
});
|
|
657
629
|
this.#dockService.setDockOptions({
|
|
658
630
|
location: SkyDockLocation.ElementBottom,
|
|
659
631
|
referenceEl: this.modalContentWrapperElement.nativeElement,
|
|
@@ -898,6 +870,7 @@ class SkyModalAdapterService {
|
|
|
898
870
|
static { this.MODAL_BODY_CLASS = 'sky-modal-body-open'; }
|
|
899
871
|
#docRef;
|
|
900
872
|
#bodyEl;
|
|
873
|
+
#coreAdapter = inject(SkyCoreAdapterService);
|
|
901
874
|
#windowRef;
|
|
902
875
|
#hostSiblingAriaHiddenCache = new Map();
|
|
903
876
|
constructor(windowRef) {
|
|
@@ -939,16 +912,38 @@ class SkyModalAdapterService {
|
|
|
939
912
|
*/
|
|
940
913
|
hideHostSiblingsFromScreenReaders(hostElRef) {
|
|
941
914
|
const hostElement = hostElRef.nativeElement;
|
|
942
|
-
const hostSiblings = hostElement.parentElement
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
915
|
+
const hostSiblings = hostElement.parentElement?.children;
|
|
916
|
+
if (hostSiblings) {
|
|
917
|
+
for (const element of hostSiblings) {
|
|
918
|
+
if (element.contains(document.activeElement)) {
|
|
919
|
+
document.body.focus();
|
|
920
|
+
}
|
|
921
|
+
if (element !== hostElement &&
|
|
922
|
+
!element.hasAttribute('aria-live') &&
|
|
923
|
+
element.nodeName.toLowerCase() !== 'script' &&
|
|
924
|
+
element.nodeName.toLowerCase() !== 'style') {
|
|
925
|
+
// preserve previous aria-hidden status of elements outside of modal host
|
|
926
|
+
this.#hostSiblingAriaHiddenCache.set(element, element.getAttribute('aria-hidden'));
|
|
927
|
+
element.setAttribute('aria-hidden', 'true');
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
focusFirstElement(modalEl) {
|
|
933
|
+
/* istanbul ignore else */
|
|
934
|
+
/* handle the case where somehow there is a focused element already in the modal */
|
|
935
|
+
if (!(document.activeElement &&
|
|
936
|
+
modalEl.nativeElement.contains(document.activeElement))) {
|
|
937
|
+
const currentScrollX = window.pageXOffset;
|
|
938
|
+
const currentScrollY = window.pageYOffset;
|
|
939
|
+
const inputWithAutofocus = modalEl.nativeElement.querySelector('[autofocus]');
|
|
940
|
+
if (inputWithAutofocus) {
|
|
941
|
+
inputWithAutofocus.focus();
|
|
942
|
+
}
|
|
943
|
+
else {
|
|
944
|
+
this.#coreAdapter.getFocusableChildrenAndApplyFocus(modalEl, '.sky-modal-content', true);
|
|
951
945
|
}
|
|
946
|
+
window.scrollTo(currentScrollX, currentScrollY);
|
|
952
947
|
}
|
|
953
948
|
}
|
|
954
949
|
/**
|
|
@@ -1003,6 +998,7 @@ class SkyModalHostComponent {
|
|
|
1003
998
|
#environmentInjector = inject(EnvironmentInjector);
|
|
1004
999
|
#modalHostContext = inject(SkyModalHostContext);
|
|
1005
1000
|
#router = inject(Router, { optional: true });
|
|
1001
|
+
#windowRef = inject(SkyAppWindowRef);
|
|
1006
1002
|
ngOnDestroy() {
|
|
1007
1003
|
// Close all modal instances before disposing of the host container.
|
|
1008
1004
|
this.#closeAllModalInstances();
|
|
@@ -1049,13 +1045,18 @@ class SkyModalHostComponent {
|
|
|
1049
1045
|
modalInstance.adapter = this.#adapter;
|
|
1050
1046
|
modalInstance.componentRef = modalComponentRef;
|
|
1051
1047
|
this.#registerModalInstance(modalInstance);
|
|
1052
|
-
//
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
// hiding the
|
|
1057
|
-
this.#adapter.
|
|
1058
|
-
|
|
1048
|
+
// Adding a timeout to avoid ExpressionChangedAfterItHasBeenCheckedError.
|
|
1049
|
+
// https://stackoverflow.com/questions/40562845
|
|
1050
|
+
this.#windowRef.nativeWindow.setTimeout(() => {
|
|
1051
|
+
this.#adapter.focusFirstElement(modalElement);
|
|
1052
|
+
// hiding all elements at the modal-host level from screen readers when the a modal is opened
|
|
1053
|
+
this.#adapter.hideHostSiblingsFromScreenReaders(this.#elRef);
|
|
1054
|
+
if (SkyModalHostService.openModalCount > 1 &&
|
|
1055
|
+
SkyModalHostService.topModal === hostService) {
|
|
1056
|
+
// hiding the lower modals when more than one modal is opened
|
|
1057
|
+
this.#adapter.hidePreviousModalFromScreenReaders(modalElement);
|
|
1058
|
+
}
|
|
1059
|
+
});
|
|
1059
1060
|
const closeModal = () => {
|
|
1060
1061
|
// unhide siblings if last modal is closing
|
|
1061
1062
|
if (SkyModalHostService.openModalCount === 1) {
|