@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.
@@ -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, SkyAppWindowRef, SkyDockLocation, SkyIdModule, SkyScrollShadowDirective, SkyIdService, SkyDynamicComponentService, SKY_STACKING_CONTEXT } from '@skyux/core';
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: [{ token: i1.SkyCoreAdapterService }], target: i0.ɵɵFactoryTarget.Injectable }); }
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
- }], ctorParameters: () => [{ type: i1.SkyCoreAdapterService }] });
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.children;
943
- for (const element of hostSiblings) {
944
- if (element !== hostElement &&
945
- !element.hasAttribute('aria-live') &&
946
- element.nodeName.toLowerCase() !== 'script' &&
947
- element.nodeName.toLowerCase() !== 'style') {
948
- // preserve previous aria-hidden status of elements outside of modal host
949
- this.#hostSiblingAriaHiddenCache.set(element, element.getAttribute('aria-hidden'));
950
- element.setAttribute('aria-hidden', 'true');
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
- // 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
- }
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) {