@skyux/flyout 5.0.4 → 5.5.0-beta.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.
Files changed (74) hide show
  1. package/README.md +6 -4
  2. package/bundles/skyux-flyout.umd.js +123 -31
  3. package/documentation.json +486 -162
  4. package/esm2015/index.js +14 -0
  5. package/esm2015/index.js.map +1 -0
  6. package/esm2015/lib/modules/flyout/flyout-adapter.service.js +64 -0
  7. package/esm2015/lib/modules/flyout/flyout-adapter.service.js.map +1 -0
  8. package/esm2015/lib/modules/flyout/flyout-instance.js +109 -0
  9. package/esm2015/lib/modules/flyout/flyout-instance.js.map +1 -0
  10. package/esm2015/lib/modules/flyout/flyout-iterator.component.js +59 -0
  11. package/esm2015/lib/modules/flyout/flyout-iterator.component.js.map +1 -0
  12. package/esm2015/lib/modules/flyout/flyout-media-query.service.js +72 -0
  13. package/esm2015/lib/modules/flyout/flyout-media-query.service.js.map +1 -0
  14. package/esm2015/lib/modules/flyout/flyout.component.js +505 -0
  15. package/esm2015/lib/modules/flyout/flyout.component.js.map +1 -0
  16. package/esm2015/lib/modules/flyout/flyout.module.js +56 -0
  17. package/esm2015/lib/modules/flyout/flyout.module.js.map +1 -0
  18. package/esm2015/lib/modules/flyout/flyout.service.js +167 -0
  19. package/esm2015/lib/modules/flyout/flyout.service.js.map +1 -0
  20. package/esm2015/lib/modules/flyout/types/flyout-action.js +2 -0
  21. package/esm2015/lib/modules/flyout/types/flyout-action.js.map +1 -0
  22. package/esm2015/lib/modules/flyout/types/flyout-before-close-handler.js +9 -0
  23. package/esm2015/lib/modules/flyout/types/flyout-before-close-handler.js.map +1 -0
  24. package/esm2015/lib/modules/flyout/types/flyout-close-args.js +2 -0
  25. package/esm2015/lib/modules/flyout/types/flyout-close-args.js.map +1 -0
  26. package/esm2015/lib/modules/flyout/types/flyout-config.js +2 -0
  27. package/esm2015/lib/modules/flyout/types/flyout-config.js.map +1 -0
  28. package/esm2015/lib/modules/flyout/types/flyout-message-type.js +13 -0
  29. package/esm2015/lib/modules/flyout/types/flyout-message-type.js.map +1 -0
  30. package/esm2015/lib/modules/flyout/types/flyout-message.js +2 -0
  31. package/esm2015/lib/modules/flyout/types/flyout-message.js.map +1 -0
  32. package/esm2015/lib/modules/flyout/types/flyout-permalink.js +2 -0
  33. package/esm2015/lib/modules/flyout/types/flyout-permalink.js.map +1 -0
  34. package/esm2015/lib/modules/shared/sky-flyout-resources.module.js +54 -0
  35. package/esm2015/lib/modules/shared/sky-flyout-resources.module.js.map +1 -0
  36. package/esm2015/skyux-flyout.js +2 -2
  37. package/esm2015/skyux-flyout.js.map +1 -0
  38. package/fesm2015/skyux-flyout.js +110 -25
  39. package/fesm2015/skyux-flyout.js.map +1 -1
  40. package/index.d.ts +11 -0
  41. package/{modules → lib/modules}/flyout/flyout-adapter.service.d.ts +0 -0
  42. package/{modules → lib/modules}/flyout/flyout-instance.d.ts +12 -2
  43. package/{modules → lib/modules}/flyout/flyout-iterator.component.d.ts +0 -0
  44. package/{modules → lib/modules}/flyout/flyout-media-query.service.d.ts +0 -0
  45. package/{modules → lib/modules}/flyout/flyout.component.d.ts +11 -2
  46. package/lib/modules/flyout/flyout.module.d.ts +17 -0
  47. package/{modules → lib/modules}/flyout/flyout.service.d.ts +7 -3
  48. package/{modules → lib/modules}/flyout/types/flyout-action.d.ts +0 -0
  49. package/lib/modules/flyout/types/flyout-before-close-handler.d.ts +10 -0
  50. package/lib/modules/flyout/types/flyout-close-args.d.ts +9 -0
  51. package/{modules → lib/modules}/flyout/types/flyout-config.d.ts +11 -1
  52. package/{modules → lib/modules}/flyout/types/flyout-message-type.d.ts +0 -0
  53. package/{modules → lib/modules}/flyout/types/flyout-message.d.ts +3 -0
  54. package/{modules → lib/modules}/flyout/types/flyout-permalink.d.ts +0 -0
  55. package/{modules → lib/modules}/shared/sky-flyout-resources.module.d.ts +0 -0
  56. package/package.json +21 -6
  57. package/skyux-flyout.d.ts +1 -1
  58. package/LICENSE +0 -21
  59. package/esm2015/modules/flyout/flyout-adapter.service.js +0 -64
  60. package/esm2015/modules/flyout/flyout-instance.js +0 -98
  61. package/esm2015/modules/flyout/flyout-iterator.component.js +0 -59
  62. package/esm2015/modules/flyout/flyout-media-query.service.js +0 -72
  63. package/esm2015/modules/flyout/flyout.component.js +0 -456
  64. package/esm2015/modules/flyout/flyout.module.js +0 -52
  65. package/esm2015/modules/flyout/flyout.service.js +0 -152
  66. package/esm2015/modules/flyout/types/flyout-action.js +0 -2
  67. package/esm2015/modules/flyout/types/flyout-config.js +0 -2
  68. package/esm2015/modules/flyout/types/flyout-message-type.js +0 -13
  69. package/esm2015/modules/flyout/types/flyout-message.js +0 -2
  70. package/esm2015/modules/flyout/types/flyout-permalink.js +0 -2
  71. package/esm2015/modules/shared/sky-flyout-resources.module.js +0 -54
  72. package/esm2015/public-api.js +0 -12
  73. package/modules/flyout/flyout.module.d.ts +0 -16
  74. package/public-api.d.ts +0 -9
@@ -1,6 +1,8 @@
1
1
  import * as i0 from '@angular/core';
2
- import { EventEmitter, NgModule, Injectable, Component, Input, Output, ReflectiveInjector, ElementRef, ViewContainerRef, ChangeDetectionStrategy, ViewChild, HostListener } from '@angular/core';
2
+ import { EventEmitter, NgModule, Injectable, Component, Input, Output, Injector, ElementRef, ViewContainerRef, ChangeDetectionStrategy, ViewChild, HostListener } from '@angular/core';
3
3
  import { Subject, BehaviorSubject, fromEvent } from 'rxjs';
4
+ import * as i9 from '@angular/cdk/a11y';
5
+ import { A11yModule } from '@angular/cdk/a11y';
4
6
  import * as i7 from '@angular/common';
5
7
  import { CommonModule } from '@angular/common';
6
8
  import { FormsModule } from '@angular/forms';
@@ -10,7 +12,7 @@ import * as i1$1 from '@skyux/indicators';
10
12
  import { SkyIconModule } from '@skyux/indicators';
11
13
  import * as i2$1 from '@skyux/i18n';
12
14
  import { getLibStringForLocale, SkyI18nModule, SKY_LIB_RESOURCES_PROVIDERS } from '@skyux/i18n';
13
- import * as i9 from '@skyux/router';
15
+ import * as i10 from '@skyux/router';
14
16
  import { SkyHrefModule } from '@skyux/router';
15
17
  import * as i2 from '@skyux/theme';
16
18
  import { SkyThemeModule } from '@skyux/theme';
@@ -46,6 +48,7 @@ class SkyFlyoutInstance {
46
48
  * @default true
47
49
  */
48
50
  this.isOpen = true;
51
+ this._beforeClose = new Subject();
49
52
  this._iteratorNextButtonClick = new EventEmitter();
50
53
  this._iteratorPreviousButtonClick = new EventEmitter();
51
54
  this._iteratorNextButtonDisabled = false;
@@ -55,6 +58,14 @@ class SkyFlyoutInstance {
55
58
  this.isOpen = false;
56
59
  });
57
60
  }
61
+ /**
62
+ * An event that the modal instance emits when it is about to close.
63
+ * If a subscription exists for this event,
64
+ * the modal does not close until the subscriber calls the handler's `closeModal` method.
65
+ */
66
+ get beforeClose() {
67
+ return this._beforeClose;
68
+ }
58
69
  /**
59
70
  * Used to communicate with the host component.
60
71
  * @internal
@@ -116,10 +127,12 @@ class SkyFlyoutInstance {
116
127
  }
117
128
  /**
118
129
  * Closes the flyout instance and emits its `closed` event.
130
+ * @param args Arguments used when closing the flyout.
119
131
  */
120
- close() {
132
+ close(args) {
121
133
  this.hostController.next({
122
134
  type: SkyFlyoutMessageType.Close,
135
+ data: { ignoreBeforeClose: args ? args.ignoreBeforeClose : false },
123
136
  });
124
137
  this._iteratorPreviousButtonClick.complete();
125
138
  this._iteratorNextButtonClick.complete();
@@ -306,6 +319,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
306
319
  type: Injectable
307
320
  }], ctorParameters: function () { return []; } });
308
321
 
322
+ /**
323
+ * Handler for notifying the flyout when it is appropriate to close the flyout. This will be returned from the flyout instance's `beforeClose` observable.
324
+ */
325
+ class SkyFlyoutBeforeCloseHandler {
326
+ constructor(closeFlyoutFunction) {
327
+ this.closeFlyout = closeFlyoutFunction;
328
+ }
329
+ }
330
+
309
331
  /**
310
332
  * @internal
311
333
  */
@@ -366,7 +388,7 @@ let nextId = 0;
366
388
  * @internal
367
389
  */
368
390
  class SkyFlyoutComponent {
369
- constructor(adapter, changeDetector, injector, resolver, resourcesService, flyoutMediaQueryService, elementRef, uiConfigService) {
391
+ constructor(adapter, changeDetector, injector, resolver, resourcesService, flyoutMediaQueryService, elementRef, uiConfigService, _ngZone) {
370
392
  this.adapter = adapter;
371
393
  this.changeDetector = changeDetector;
372
394
  this.injector = injector;
@@ -375,11 +397,13 @@ class SkyFlyoutComponent {
375
397
  this.flyoutMediaQueryService = flyoutMediaQueryService;
376
398
  this.elementRef = elementRef;
377
399
  this.uiConfigService = uiConfigService;
400
+ this._ngZone = _ngZone;
378
401
  this.flyoutId = `sky-flyout-${++nextId}`;
379
402
  this.flyoutState = FLYOUT_CLOSED_STATE;
380
403
  this.isOpen = false;
381
404
  this.isOpening = false;
382
405
  this.flyoutWidth = 0;
406
+ this.instanceReady = false;
383
407
  this.isDragging = false;
384
408
  this.isFullscreen = false;
385
409
  this.resizeKeyControlActive = false;
@@ -465,16 +489,16 @@ class SkyFlyoutComponent {
465
489
  this.config.iteratorPreviousButtonDisabled =
466
490
  this.config.iteratorPreviousButtonDisabled || false;
467
491
  const factory = this.resolver.resolveComponentFactory(component);
468
- /* tslint:disable:deprecation */
469
- /**
470
- * NOTE: We need to update this to use the new Injector.create(options) method
471
- * after Angular 4 support is dropped.
472
- */
473
- const providers = ReflectiveInjector.resolve(this.config.providers);
474
- const injector = ReflectiveInjector.fromResolvedProviders(providers, this.injector);
475
- /* tslint:enable:deprecation */
492
+ const injector = Injector.create({
493
+ parent: this.injector,
494
+ providers: this.config.providers,
495
+ });
476
496
  const componentRef = this.target.createComponent(factory, undefined, injector);
477
497
  this.flyoutInstance = this.createFlyoutInstance(componentRef.instance);
498
+ // This is used to ensure we do not render the flyout until we have attached the component.
499
+ // This allows the aria-labelledby to function correctly.
500
+ this.instanceReady = true;
501
+ this.changeDetector.markForCheck();
478
502
  // Open the flyout immediately.
479
503
  this.messageStream.next({
480
504
  type: SkyFlyoutMessageType.Open,
@@ -513,7 +537,9 @@ class SkyFlyoutComponent {
513
537
  return false;
514
538
  }
515
539
  getAnimationState() {
516
- return this.isOpening ? FLYOUT_OPEN_STATE : FLYOUT_CLOSED_STATE;
540
+ return this.instanceReady && this.isOpening
541
+ ? FLYOUT_OPEN_STATE
542
+ : FLYOUT_CLOSED_STATE;
517
543
  }
518
544
  animationDone(event) {
519
545
  if (event.toState === FLYOUT_OPEN_STATE) {
@@ -607,6 +633,7 @@ class SkyFlyoutComponent {
607
633
  return instance;
608
634
  }
609
635
  handleIncomingMessages(message) {
636
+ var _a;
610
637
  /* tslint:disable-next-line:switch-default */
611
638
  switch (message.type) {
612
639
  case SkyFlyoutMessageType.Open:
@@ -614,10 +641,21 @@ class SkyFlyoutComponent {
614
641
  this.isOpen = false;
615
642
  this.isOpening = true;
616
643
  }
644
+ this.initFocusTrap();
617
645
  break;
618
646
  case SkyFlyoutMessageType.Close:
619
- this.isOpen = true;
620
- this.isOpening = false;
647
+ if (this.flyoutInstance.beforeClose.observers.length ===
648
+ 0 ||
649
+ ((_a = message.data) === null || _a === void 0 ? void 0 : _a.ignoreBeforeClose)) {
650
+ this.isOpen = true;
651
+ this.isOpening = false;
652
+ }
653
+ else {
654
+ this.flyoutInstance.beforeClose.next(new SkyFlyoutBeforeCloseHandler(() => {
655
+ this.isOpen = true;
656
+ this.isOpening = false;
657
+ }));
658
+ }
621
659
  break;
622
660
  case SkyFlyoutMessageType.EnableIteratorNextButton:
623
661
  this.config.iteratorNextButtonDisabled = false;
@@ -730,13 +768,31 @@ class SkyFlyoutComponent {
730
768
  }
731
769
  }
732
770
  }
771
+ /** Executes a function when the zone is stable. */
772
+ _executeOnStable(fn) {
773
+ if (this._ngZone.isStable) {
774
+ fn();
775
+ }
776
+ else {
777
+ this._ngZone.onStable.pipe(take(1)).subscribe(fn);
778
+ }
779
+ }
780
+ initFocusTrap() {
781
+ this.enableTrapFocusAutoCapture = false;
782
+ this.enableTrapFocus = false;
783
+ // Waiting for zone to be stable will avoid ExpressionChangeAfterCheckedError.
784
+ this._executeOnStable(() => {
785
+ this.enableTrapFocusAutoCapture = true;
786
+ this.enableTrapFocus = true;
787
+ });
788
+ }
733
789
  }
734
- SkyFlyoutComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SkyFlyoutComponent, deps: [{ token: SkyFlyoutAdapterService }, { token: i0.ChangeDetectorRef }, { token: i0.Injector }, { token: i0.ComponentFactoryResolver }, { token: i2$1.SkyLibResourcesService }, { token: SkyFlyoutMediaQueryService }, { token: i0.ElementRef }, { token: i1.SkyUIConfigService }], target: i0.ɵɵFactoryTarget.Component });
790
+ SkyFlyoutComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SkyFlyoutComponent, deps: [{ token: SkyFlyoutAdapterService }, { token: i0.ChangeDetectorRef }, { token: i0.Injector }, { token: i0.ComponentFactoryResolver }, { token: i2$1.SkyLibResourcesService }, { token: SkyFlyoutMediaQueryService }, { token: i0.ElementRef }, { token: i1.SkyUIConfigService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
735
791
  SkyFlyoutComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.16", type: SkyFlyoutComponent, selector: "sky-flyout", host: { listeners: { "window:resize": "onWindowResize($event)" } }, providers: [
736
792
  SkyFlyoutAdapterService,
737
793
  SkyFlyoutMediaQueryService,
738
794
  { provide: SkyMediaQueryService, useExisting: SkyFlyoutMediaQueryService },
739
- ], viewQueries: [{ propertyName: "flyoutRef", first: true, predicate: ["flyoutRef"], descendants: true, read: ElementRef, static: true }, { propertyName: "target", first: true, predicate: ["target"], descendants: true, read: ViewContainerRef, static: true }, { propertyName: "flyoutHeader", first: true, predicate: ["flyoutHeader"], descendants: true, read: ElementRef, static: true }], ngImport: i0, template: "<div\n class=\"sky-flyout\"\n tabindex=\"-1\"\n [attr.role]=\"config?.ariaRole\"\n [attr.aria-describedby]=\"config?.ariaDescribedBy\"\n [attr.aria-labelledby]=\"config?.ariaLabelledBy\"\n [id]=\"flyoutId\"\n [ngClass]=\"{\n 'sky-flyout-hidden': !isOpen && !isOpening,\n 'sky-flyout-fullscreen': isFullscreen\n }\"\n [skyThemeClass]=\"{\n 'sky-shadow': 'default',\n 'sky-elevation-8': 'modern'\n }\"\n (@flyoutState.done)=\"animationDone($event)\"\n [@flyoutState]=\"getAnimationState()\"\n [style.width.px]=\"flyoutWidth\"\n #flyoutRef\n>\n <div\n class=\"sky-flyout-resize-handle\"\n role=\"separator\"\n tabindex=\"0\"\n type=\"range\"\n [attr.aria-controls]=\"flyoutId\"\n [attr.aria-label]=\"'skyux_flyout_resize_handle' | skyLibResources\"\n [attr.aria-valuemax]=\"config.maxWidth\"\n [attr.aria-valuemin]=\"config.minWidth\"\n [attr.aria-valuenow]=\"flyoutWidth\"\n (keydown)=\"onResizeHandleKeyDown($event)\"\n (mousedown)=\"onResizeHandleMouseDown($event)\"\n ></div>\n\n <div\n class=\"sky-flyout-header\"\n [skyThemeClass]=\"{\n 'sky-padding-squish-large': 'default'\n }\"\n #flyoutHeader\n >\n <div class=\"sky-flyout-header-content\">\n <button\n *skyThemeIf=\"'modern'\"\n class=\"\n sky-btn\n sky-btn-icon-borderless\n sky-margin-inline-sm\n sky-flyout-header-grab-handle\n \"\n [attr.aria-label]=\"'skyux_flyout_resize_handle' | skyLibResources\"\n (keydown)=\"onHeaderGrabHandleKeyDown($event)\"\n (mousedown)=\"onHeaderGrabHandleMouseDown($event)\"\n >\n <sky-icon icon=\"tile-drag\" iconType=\"skyux\" size=\"lg\"> </sky-icon>\n </button>\n\n <sky-flyout-iterator\n *ngIf=\"config.showIterator\"\n [nextButtonDisabled]=\"config.iteratorNextButtonDisabled\"\n [previousButtonDisabled]=\"config.iteratorPreviousButtonDisabled\"\n (nextButtonClick)=\"onIteratorNextButtonClick()\"\n (previousButtonClick)=\"onIteratorPreviousButtonClick()\"\n >\n </sky-flyout-iterator>\n </div>\n <div class=\"sky-flyout-header-buttons\">\n <ng-container *ngTemplateOutlet=\"permalinkTemplate\"> </ng-container>\n <ng-container *ngTemplateOutlet=\"primaryActionTemplate\"> </ng-container>\n <button\n class=\"sky-btn sky-flyout-btn-close sky-label-icon-theme-default\"\n type=\"button\"\n [attr.aria-label]=\"'skyux_flyout_close' | skyLibResources\"\n [skyThemeClass]=\"{\n 'sky-btn-default': 'default',\n 'sky-btn-icon-borderless': 'modern'\n }\"\n (click)=\"close()\"\n >\n <sky-icon *skyThemeIf=\"'default'\" icon=\"close\"> </sky-icon>\n <sky-icon\n *skyThemeIf=\"'modern'\"\n icon=\"close\"\n iconType=\"skyux\"\n size=\"lg\"\n >\n </sky-icon>\n </button>\n </div>\n </div>\n <div class=\"sky-flyout-content\">\n <div #target></div>\n </div>\n</div>\n\n<ng-template #permalinkTemplate>\n <ng-template [ngIf]=\"permalink\">\n <ng-template [ngIf]=\"permalink.url\">\n <a\n class=\"sky-btn sky-flyout-btn-permalink sky-margin-inline-default\"\n [skyHref]=\"permalink.url\"\n [skyThemeClass]=\"{\n 'sky-btn-default': 'default',\n 'sky-btn-borderless': 'modern'\n }\"\n (click)=\"close()\"\n >\n {{ permalinkLabel }}\n </a>\n </ng-template>\n <ng-template [ngIf]=\"permalink.route\">\n <a\n class=\"sky-btn sky-flyout-btn-permalink sky-margin-inline-default\"\n [routerLink]=\"permalink.route.commands\"\n [fragment]=\"permalink.route.extras?.fragment\"\n [skyThemeClass]=\"{\n 'sky-btn-default': 'default',\n 'sky-btn-borderless': 'modern'\n }\"\n [queryParams]=\"permalink.route.extras?.queryParams\"\n [queryParamsHandling]=\"permalink.route.extras?.queryParamsHandling\"\n [state]=\"permalink.route.extras?.state\"\n (click)=\"close()\"\n >\n {{ permalinkLabel }}\n </a>\n </ng-template>\n </ng-template>\n</ng-template>\n\n<ng-template #primaryActionTemplate>\n <ng-template [ngIf]=\"primaryAction && primaryAction.callback\">\n <button\n type=\"button\"\n class=\"\n sky-btn\n sky-btn-default\n sky-flyout-btn-primary-action\n sky-margin-inline-default\n \"\n (click)=\"invokePrimaryAction()\"\n >\n {{ primaryActionLabel }}\n </button>\n </ng-template>\n</ng-template>\n", styles: [".sky-flyout{position:fixed;right:0;top:0;bottom:0;height:100%;background-color:#fff;border-left:6px solid #0974a1;z-index:1001}.sky-flyout:focus{outline:none}.sky-flyout.sky-flyout-fullscreen{min-width:100%;max-width:100%}.sky-flyout.sky-flyout-fullscreen .sky-flyout-resize-handle{cursor:initial}.sky-flyout.sky-flyout-hidden{visibility:hidden}.sky-flyout .sky-flyout-input-aria-only{width:0;height:0;padding:0;opacity:0;position:absolute;margin:-1px;border:0;overflow:hidden;clip:rect(0 0 0 0);outline:none}.sky-flyout-resize-handle{-webkit-appearance:none;-moz-appearance:none;height:100%;width:14px;position:absolute;left:-10px;cursor:ew-resize;padding:0;border:0;background:transparent;display:block;top:0;bottom:0;direction:rtl}.sky-flyout-resize-handle::-moz-range-thumb,.sky-flyout-resize-handle::-moz-range-track{-webkit-appearance:none;-moz-appearance:none;width:0;height:0;border-radius:0;border:0 none;background:none;display:none}.sky-flyout-resize-handle::-ms-thumb,.sky-flyout-resize-handle::-ms-track{-webkit-appearance:none;-moz-appearance:none;width:0;height:0;border-radius:0;border:0 none;background:none;display:none}.sky-flyout-resize-handle::-webkit-slider-thumb{-webkit-appearance:none;-moz-appearance:none;width:0;height:0;border-radius:0;border:0 none;background:none;display:none}.sky-flyout-header{border-bottom:1px solid #cdcfd2;width:100%;background:#eeeeef;height:50px;display:flex;align-items:flex-start}.sky-flyout-header-content{flex-grow:1}.sky-flyout-btn-permalink:hover{text-decoration:none}.sky-flyout-help-shim{padding-right:8px}@media (min-width: 768px){.sky-flyout-help-shim{padding-right:50px}}.sky-flyout-content{overflow-y:auto;height:calc(100% - 50px)}:host-context(.sky-theme-modern) .sky-flyout{border-left:0}:host-context(.sky-theme-modern) .sky-flyout-header{border-bottom:none;background:#fff;padding:15px 10px}:host-context(.sky-theme-modern) .sky-flyout-header-grab-handle{cursor:move;cursor:-moz-grab}.sky-theme-modern .sky-flyout{border-left:0}.sky-theme-modern .sky-flyout-header{border-bottom:none;background:#fff;padding:15px 10px}.sky-theme-modern .sky-flyout-header-grab-handle{cursor:move;cursor:-moz-grab}:host-context(.sky-theme-modern.sky-theme-mode-dark) .sky-flyout{background:#000}:host-context(.sky-theme-modern.sky-theme-mode-dark) .sky-flyout-header{background:#000}.sky-theme-modern.sky-theme-mode-dark .sky-flyout{background:#000}.sky-theme-modern.sky-theme-mode-dark .sky-flyout-header{background:#000}\n"], components: [{ type: i1$1.λ4, selector: "sky-icon", inputs: ["icon", "iconType", "size", "fixedWidth", "variant"] }, { type: SkyFlyoutIteratorComponent, selector: "sky-flyout-iterator", inputs: ["nextButtonDisabled", "previousButtonDisabled"], outputs: ["previousButtonClick", "nextButtonClick"] }], directives: [{ type: i7.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i2.λ2, selector: "[skyThemeClass]", inputs: ["class", "skyThemeClass"] }, { type: i2.λ3, selector: "[skyThemeIf]", inputs: ["skyThemeIf"] }, { type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i7.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i9.λ1, selector: "[skyHref]", inputs: ["skyHref", "skyHrefElse"] }, { type: i2$2.RouterLinkWithHref, selector: "a[routerLink],area[routerLink]", inputs: ["routerLink", "target", "queryParams", "fragment", "queryParamsHandling", "preserveFragment", "skipLocationChange", "replaceUrl", "state", "relativeTo"] }], pipes: { "skyLibResources": i2$1.SkyLibResourcesPipe }, animations: [
795
+ ], viewQueries: [{ propertyName: "flyoutRef", first: true, predicate: ["flyoutRef"], descendants: true, read: ElementRef, static: true }, { propertyName: "target", first: true, predicate: ["target"], descendants: true, read: ViewContainerRef, static: true }, { propertyName: "flyoutCloseButton", first: true, predicate: ["flyoutCloseButton"], descendants: true, read: ElementRef, static: true }, { propertyName: "flyoutContent", first: true, predicate: ["flyoutContent"], descendants: true, read: ElementRef, static: true }, { propertyName: "flyoutHeader", first: true, predicate: ["flyoutHeader"], descendants: true, read: ElementRef, static: true }], ngImport: i0, template: "<div\n class=\"sky-flyout\"\n tabindex=\"-1\"\n [attr.role]=\"config?.ariaRole ? config.ariaRole : 'dialog'\"\n [attr.aria-describedby]=\"config?.ariaDescribedBy\"\n [attr.aria-label]=\"config?.ariaLabel\"\n [attr.aria-labelledby]=\"config?.ariaLabelledBy\"\n [attr.aria-modal]=\"\n config?.ariaRole === 'dialog' || !config?.ariaRole ? true : false\n \"\n [attr.hidden]=\"!instanceReady ? true : undefined\"\n [id]=\"flyoutId\"\n [ngClass]=\"{\n 'sky-flyout-hidden': !isOpen && !isOpening,\n 'sky-flyout-fullscreen': isFullscreen\n }\"\n [skyThemeClass]=\"{\n 'sky-shadow': 'default',\n 'sky-elevation-8': 'modern'\n }\"\n (@flyoutState.done)=\"animationDone($event)\"\n [@flyoutState]=\"getAnimationState()\"\n [style.width.px]=\"flyoutWidth\"\n #flyoutRef\n [cdkTrapFocus]=\"enableTrapFocus\"\n [cdkTrapFocusAutoCapture]=\"enableTrapFocusAutoCapture\"\n>\n <div\n class=\"sky-flyout-header\"\n [skyThemeClass]=\"{\n 'sky-padding-squish-large': 'default'\n }\"\n #flyoutHeader\n >\n <div class=\"sky-flyout-header-content\">\n <button\n *skyThemeIf=\"'modern'\"\n class=\"\n sky-btn\n sky-btn-icon-borderless\n sky-margin-inline-sm\n sky-flyout-header-grab-handle\n \"\n [attr.aria-label]=\"'skyux_flyout_resize_handle' | skyLibResources\"\n (keydown)=\"onHeaderGrabHandleKeyDown($event)\"\n (mousedown)=\"onHeaderGrabHandleMouseDown($event)\"\n >\n <sky-icon icon=\"tile-drag\" iconType=\"skyux\" size=\"lg\"> </sky-icon>\n </button>\n\n <sky-flyout-iterator\n *ngIf=\"config.showIterator\"\n [nextButtonDisabled]=\"config.iteratorNextButtonDisabled\"\n [previousButtonDisabled]=\"config.iteratorPreviousButtonDisabled\"\n (nextButtonClick)=\"onIteratorNextButtonClick()\"\n (previousButtonClick)=\"onIteratorPreviousButtonClick()\"\n >\n </sky-flyout-iterator>\n </div>\n <div class=\"sky-flyout-header-buttons\">\n <ng-container *ngTemplateOutlet=\"permalinkTemplate\"> </ng-container>\n <ng-container *ngTemplateOutlet=\"primaryActionTemplate\"> </ng-container>\n <button\n class=\"sky-btn sky-flyout-btn-close sky-label-icon-theme-default\"\n type=\"button\"\n [attr.aria-label]=\"'skyux_flyout_close' | skyLibResources\"\n [skyThemeClass]=\"{\n 'sky-btn-default': 'default',\n 'sky-btn-icon-borderless': 'modern'\n }\"\n (click)=\"close()\"\n #flyoutCloseButton\n >\n <sky-icon *skyThemeIf=\"'default'\" icon=\"close\"> </sky-icon>\n <sky-icon\n *skyThemeIf=\"'modern'\"\n icon=\"close\"\n iconType=\"skyux\"\n size=\"lg\"\n >\n </sky-icon>\n </button>\n </div>\n </div>\n <div class=\"sky-flyout-content\" #flyoutContent>\n <div #target></div>\n </div>\n <div\n class=\"sky-flyout-resize-handle\"\n role=\"separator\"\n tabindex=\"0\"\n type=\"range\"\n [attr.aria-controls]=\"flyoutId\"\n [attr.aria-label]=\"'skyux_flyout_resize_handle' | skyLibResources\"\n [attr.aria-valuemax]=\"config.maxWidth\"\n [attr.aria-valuemin]=\"config.minWidth\"\n [attr.aria-valuenow]=\"flyoutWidth\"\n (keydown)=\"onResizeHandleKeyDown($event)\"\n (mousedown)=\"onResizeHandleMouseDown($event)\"\n ></div>\n</div>\n\n<ng-template #permalinkTemplate>\n <ng-template [ngIf]=\"permalink\">\n <ng-template [ngIf]=\"permalink.url\">\n <a\n class=\"sky-btn sky-flyout-btn-permalink sky-margin-inline-default\"\n [skyHref]=\"permalink.url\"\n [skyThemeClass]=\"{\n 'sky-btn-default': 'default',\n 'sky-btn-borderless': 'modern'\n }\"\n (click)=\"close()\"\n >\n {{ permalinkLabel }}\n </a>\n </ng-template>\n <ng-template [ngIf]=\"permalink.route\">\n <a\n class=\"sky-btn sky-flyout-btn-permalink sky-margin-inline-default\"\n [routerLink]=\"permalink.route.commands\"\n [fragment]=\"permalink.route.extras?.fragment\"\n [skyThemeClass]=\"{\n 'sky-btn-default': 'default',\n 'sky-btn-borderless': 'modern'\n }\"\n [queryParams]=\"permalink.route.extras?.queryParams\"\n [queryParamsHandling]=\"permalink.route.extras?.queryParamsHandling\"\n [state]=\"permalink.route.extras?.state\"\n (click)=\"close()\"\n >\n {{ permalinkLabel }}\n </a>\n </ng-template>\n </ng-template>\n</ng-template>\n\n<ng-template #primaryActionTemplate>\n <ng-template [ngIf]=\"primaryAction && primaryAction.callback\">\n <button\n type=\"button\"\n class=\"\n sky-btn\n sky-btn-default\n sky-flyout-btn-primary-action\n sky-margin-inline-default\n \"\n (click)=\"invokePrimaryAction()\"\n >\n {{ primaryActionLabel }}\n </button>\n </ng-template>\n</ng-template>\n", styles: [".sky-flyout{position:fixed;right:0;top:0;bottom:0;height:100%;background-color:#fff;border-left:6px solid #0974a1;z-index:1001}.sky-flyout:focus{outline:none}.sky-flyout.sky-flyout-fullscreen{min-width:100%;max-width:100%}.sky-flyout.sky-flyout-fullscreen .sky-flyout-resize-handle{cursor:initial}.sky-flyout.sky-flyout-hidden{visibility:hidden}.sky-flyout .sky-flyout-input-aria-only{width:0;height:0;padding:0;opacity:0;position:absolute;margin:-1px;border:0;overflow:hidden;clip:rect(0 0 0 0);outline:none}.sky-flyout-resize-handle{-webkit-appearance:none;-moz-appearance:none;height:100%;width:14px;position:absolute;left:-10px;cursor:ew-resize;padding:0;border:0;background:transparent;display:block;top:0;bottom:0;direction:rtl}.sky-flyout-resize-handle::-moz-range-thumb,.sky-flyout-resize-handle::-moz-range-track{-webkit-appearance:none;-moz-appearance:none;width:0;height:0;border-radius:0;border:0 none;background:none;display:none}.sky-flyout-resize-handle::-ms-thumb,.sky-flyout-resize-handle::-ms-track{-webkit-appearance:none;-moz-appearance:none;width:0;height:0;border-radius:0;border:0 none;background:none;display:none}.sky-flyout-resize-handle::-webkit-slider-thumb{-webkit-appearance:none;-moz-appearance:none;width:0;height:0;border-radius:0;border:0 none;background:none;display:none}.sky-flyout-header{border-bottom:1px solid #cdcfd2;width:100%;background:#eeeeef;height:50px;display:flex;align-items:flex-start}.sky-flyout-header-content{flex-grow:1}.sky-flyout-btn-permalink:hover{text-decoration:none}.sky-flyout-help-shim{padding-right:8px}@media (min-width: 768px){.sky-flyout-help-shim{padding-right:50px}}.sky-flyout-content{overflow-y:auto;height:calc(100% - 50px)}:host-context(.sky-theme-modern) .sky-flyout{border-left:0}:host-context(.sky-theme-modern) .sky-flyout-header{border-bottom:none;background:#fff;padding:15px 10px}:host-context(.sky-theme-modern) .sky-flyout-header-grab-handle{cursor:move;cursor:-moz-grab}.sky-theme-modern .sky-flyout{border-left:0}.sky-theme-modern .sky-flyout-header{border-bottom:none;background:#fff;padding:15px 10px}.sky-theme-modern .sky-flyout-header-grab-handle{cursor:move;cursor:-moz-grab}:host-context(.sky-theme-modern.sky-theme-mode-dark) .sky-flyout{background:#000}:host-context(.sky-theme-modern.sky-theme-mode-dark) .sky-flyout-header{background:#000}.sky-theme-modern.sky-theme-mode-dark .sky-flyout{background:#000}.sky-theme-modern.sky-theme-mode-dark .sky-flyout-header{background:#000}\n"], components: [{ type: i1$1.λ4, selector: "sky-icon", inputs: ["icon", "iconType", "size", "fixedWidth", "variant"] }, { type: SkyFlyoutIteratorComponent, selector: "sky-flyout-iterator", inputs: ["nextButtonDisabled", "previousButtonDisabled"], outputs: ["previousButtonClick", "nextButtonClick"] }], directives: [{ type: i7.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i2.λ2, selector: "[skyThemeClass]", inputs: ["class", "skyThemeClass"] }, { type: i9.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { type: i2.λ3, selector: "[skyThemeIf]", inputs: ["skyThemeIf"] }, { type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i7.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }, { type: i10.λ1, selector: "[skyHref]", inputs: ["skyHref", "skyHrefElse"] }, { type: i2$2.RouterLinkWithHref, selector: "a[routerLink],area[routerLink]", inputs: ["routerLink", "target", "queryParams", "fragment", "queryParamsHandling", "preserveFragment", "skipLocationChange", "replaceUrl", "state", "relativeTo"] }], pipes: { "skyLibResources": i2$1.SkyLibResourcesPipe }, animations: [
740
796
  trigger('flyoutState', [
741
797
  state(FLYOUT_OPEN_STATE, style({ transform: 'initial' })),
742
798
  state(FLYOUT_CLOSED_STATE, style({ transform: 'translateX(100%)' })),
@@ -772,7 +828,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
772
828
  // Allow automatic change detection for child components.
773
829
  changeDetection: ChangeDetectionStrategy.Default,
774
830
  }]
775
- }], ctorParameters: function () { return [{ type: SkyFlyoutAdapterService }, { type: i0.ChangeDetectorRef }, { type: i0.Injector }, { type: i0.ComponentFactoryResolver }, { type: i2$1.SkyLibResourcesService }, { type: SkyFlyoutMediaQueryService }, { type: i0.ElementRef }, { type: i1.SkyUIConfigService }]; }, propDecorators: { flyoutRef: [{
831
+ }], ctorParameters: function () { return [{ type: SkyFlyoutAdapterService }, { type: i0.ChangeDetectorRef }, { type: i0.Injector }, { type: i0.ComponentFactoryResolver }, { type: i2$1.SkyLibResourcesService }, { type: SkyFlyoutMediaQueryService }, { type: i0.ElementRef }, { type: i1.SkyUIConfigService }, { type: i0.NgZone }]; }, propDecorators: { flyoutRef: [{
776
832
  type: ViewChild,
777
833
  args: ['flyoutRef', {
778
834
  read: ElementRef,
@@ -784,6 +840,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
784
840
  read: ViewContainerRef,
785
841
  static: true,
786
842
  }]
843
+ }], flyoutCloseButton: [{
844
+ type: ViewChild,
845
+ args: ['flyoutCloseButton', {
846
+ read: ElementRef,
847
+ static: true,
848
+ }]
849
+ }], flyoutContent: [{
850
+ type: ViewChild,
851
+ args: ['flyoutContent', {
852
+ read: ElementRef,
853
+ static: true,
854
+ }]
787
855
  }], flyoutHeader: [{
788
856
  type: ViewChild,
789
857
  args: ['flyoutHeader', {
@@ -798,7 +866,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
798
866
  class SkyFlyoutModule {
799
867
  }
800
868
  SkyFlyoutModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SkyFlyoutModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
801
- SkyFlyoutModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SkyFlyoutModule, declarations: [SkyFlyoutComponent, SkyFlyoutIteratorComponent], imports: [CommonModule,
869
+ SkyFlyoutModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SkyFlyoutModule, declarations: [SkyFlyoutComponent, SkyFlyoutIteratorComponent], imports: [A11yModule,
870
+ CommonModule,
802
871
  FormsModule,
803
872
  RouterModule,
804
873
  SkyI18nModule,
@@ -807,6 +876,7 @@ SkyFlyoutModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version
807
876
  SkyThemeModule,
808
877
  SkyHrefModule], exports: [SkyFlyoutComponent] });
809
878
  SkyFlyoutModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SkyFlyoutModule, imports: [[
879
+ A11yModule,
810
880
  CommonModule,
811
881
  FormsModule,
812
882
  RouterModule,
@@ -821,6 +891,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
821
891
  args: [{
822
892
  declarations: [SkyFlyoutComponent, SkyFlyoutIteratorComponent],
823
893
  imports: [
894
+ A11yModule,
824
895
  CommonModule,
825
896
  FormsModule,
826
897
  RouterModule,
@@ -841,11 +912,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImpo
841
912
  * document's `body` element. The `SkyFlyoutInstance` class watches for and triggers flyout events.
842
913
  */
843
914
  class SkyFlyoutService {
844
- constructor(coreAdapter, windowRef, dynamicComponentService, router) {
915
+ constructor(coreAdapter, windowRef, dynamicComponentService, router, _ngZone, applicationRef) {
845
916
  this.coreAdapter = coreAdapter;
846
917
  this.windowRef = windowRef;
847
918
  this.dynamicComponentService = dynamicComponentService;
848
919
  this.router = router;
920
+ this._ngZone = _ngZone;
921
+ this.applicationRef = applicationRef;
849
922
  this.removeAfterClosed = false;
850
923
  this.isOpening = false;
851
924
  this.ngUnsubscribe = new Subject();
@@ -858,12 +931,16 @@ class SkyFlyoutService {
858
931
  }
859
932
  /**
860
933
  * Closes the flyout. This method also removes the flyout's HTML elements from the DOM.
934
+ * @param args Arguments used when closing the flyout.
861
935
  */
862
- close() {
936
+ close(args) {
863
937
  if (this.host && !this.isOpening) {
864
938
  this.removeAfterClosed = true;
865
939
  this.host.instance.messageStream.next({
866
940
  type: SkyFlyoutMessageType.Close,
941
+ data: {
942
+ ignoreBeforeClose: args ? args.ignoreBeforeClose : false,
943
+ },
867
944
  });
868
945
  }
869
946
  }
@@ -885,6 +962,14 @@ class SkyFlyoutService {
885
962
  .subscribe((event) => {
886
963
  if (event instanceof NavigationStart) {
887
964
  this.close();
965
+ // Sanity check - if the host still exists after animations should have completed - remove host
966
+ this._ngZone.onStable.pipe(take(1)).subscribe(() => {
967
+ if (this.host) {
968
+ this.removeHostComponent();
969
+ // Without this tick - the host does not actually get removed on initial navigation in this case.
970
+ this.applicationRef.tick();
971
+ }
972
+ });
888
973
  }
889
974
  });
890
975
  }
@@ -948,7 +1033,7 @@ class SkyFlyoutService {
948
1033
  });
949
1034
  this.removeAfterClosed = false;
950
1035
  flyoutInstance.messageStream
951
- .pipe(take(1))
1036
+ .pipe(takeUntil(this.ngUnsubscribe))
952
1037
  .subscribe((message) => {
953
1038
  if (message.type === SkyFlyoutMessageType.Close) {
954
1039
  this.removeAfterClosed = true;
@@ -969,18 +1054,18 @@ class SkyFlyoutService {
969
1054
  this.ngUnsubscribe = new Subject();
970
1055
  }
971
1056
  }
972
- SkyFlyoutService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SkyFlyoutService, deps: [{ token: i1.SkyCoreAdapterService }, { token: i1.SkyAppWindowRef }, { token: i1.SkyDynamicComponentService }, { token: i2$2.Router }], target: i0.ɵɵFactoryTarget.Injectable });
1057
+ SkyFlyoutService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SkyFlyoutService, deps: [{ token: i1.SkyCoreAdapterService }, { token: i1.SkyAppWindowRef }, { token: i1.SkyDynamicComponentService }, { token: i2$2.Router }, { token: i0.NgZone }, { token: i0.ApplicationRef }], target: i0.ɵɵFactoryTarget.Injectable });
973
1058
  SkyFlyoutService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SkyFlyoutService, providedIn: 'any' });
974
1059
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.16", ngImport: i0, type: SkyFlyoutService, decorators: [{
975
1060
  type: Injectable,
976
1061
  args: [{
977
1062
  providedIn: 'any',
978
1063
  }]
979
- }], ctorParameters: function () { return [{ type: i1.SkyCoreAdapterService }, { type: i1.SkyAppWindowRef }, { type: i1.SkyDynamicComponentService }, { type: i2$2.Router }]; } });
1064
+ }], ctorParameters: function () { return [{ type: i1.SkyCoreAdapterService }, { type: i1.SkyAppWindowRef }, { type: i1.SkyDynamicComponentService }, { type: i2$2.Router }, { type: i0.NgZone }, { type: i0.ApplicationRef }]; } });
980
1065
 
981
1066
  /**
982
1067
  * Generated bundle index. Do not edit.
983
1068
  */
984
1069
 
985
- export { SkyFlyoutInstance, SkyFlyoutMessageType, SkyFlyoutModule, SkyFlyoutService, SkyFlyoutComponent as λ1 };
1070
+ export { SkyFlyoutBeforeCloseHandler, SkyFlyoutInstance, SkyFlyoutMessageType, SkyFlyoutModule, SkyFlyoutService, SkyFlyoutComponent as λ1 };
986
1071
  //# sourceMappingURL=skyux-flyout.js.map