@skyux/core 4.8.1 → 4.9.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 (39) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/bundles/skyux-core.umd.js +155 -33
  3. package/bundles/skyux-core.umd.js.map +1 -1
  4. package/bundles/skyux-core.umd.min.js +1 -1
  5. package/bundles/skyux-core.umd.min.js.map +1 -1
  6. package/esm2015/modules/dock/dock.component.js +1 -1
  7. package/esm2015/modules/scrollable-host/scrollable-host.module.js +16 -0
  8. package/esm2015/modules/scrollable-host/scrollable-host.service.js +89 -0
  9. package/esm2015/modules/viewkeeper/viewkeeper-host-options.js +1 -1
  10. package/esm2015/modules/viewkeeper/viewkeeper-options.js +1 -1
  11. package/esm2015/modules/viewkeeper/viewkeeper.directive.js +35 -16
  12. package/esm2015/modules/viewkeeper/viewkeeper.js +16 -11
  13. package/esm2015/modules/viewkeeper/viewkeeper.module.js +5 -1
  14. package/esm2015/public_api.js +2 -1
  15. package/esm2015/skyux-core.js +2 -1
  16. package/esm5/modules/dock/dock.component.js +1 -1
  17. package/esm5/modules/scrollable-host/scrollable-host.module.js +19 -0
  18. package/esm5/modules/scrollable-host/scrollable-host.service.js +91 -0
  19. package/esm5/modules/viewkeeper/viewkeeper-host-options.js +1 -1
  20. package/esm5/modules/viewkeeper/viewkeeper-options.js +1 -1
  21. package/esm5/modules/viewkeeper/viewkeeper.directive.js +45 -25
  22. package/esm5/modules/viewkeeper/viewkeeper.js +16 -11
  23. package/esm5/modules/viewkeeper/viewkeeper.module.js +5 -1
  24. package/esm5/public_api.js +2 -1
  25. package/esm5/skyux-core.js +2 -1
  26. package/fesm2015/skyux-core.js +140 -26
  27. package/fesm2015/skyux-core.js.map +1 -1
  28. package/fesm5/skyux-core.js +155 -35
  29. package/fesm5/skyux-core.js.map +1 -1
  30. package/modules/scrollable-host/scrollable-host.module.d.ts +2 -0
  31. package/modules/scrollable-host/scrollable-host.service.d.ts +13 -0
  32. package/modules/viewkeeper/viewkeeper-host-options.d.ts +1 -0
  33. package/modules/viewkeeper/viewkeeper-options.d.ts +5 -0
  34. package/modules/viewkeeper/viewkeeper.d.ts +1 -0
  35. package/modules/viewkeeper/viewkeeper.directive.d.ts +4 -1
  36. package/package.json +1 -1
  37. package/public_api.d.ts +1 -0
  38. package/skyux-core.d.ts +1 -0
  39. package/skyux-core.metadata.json +1 -1
@@ -2,7 +2,7 @@ import { __decorate, __param } from 'tslib';
2
2
  import { RendererFactory2, Injectable, NgModule, EventEmitter, ElementRef, Input, Output, Directive, ComponentFactoryResolver, ApplicationRef, Injector, ChangeDetectorRef, ViewChild, ViewContainerRef, Component, ChangeDetectionStrategy, ɵɵdefineInjectable, ɵɵinject, Renderer2, NgZone, Pipe, Optional } from '@angular/core';
3
3
  import { CommonModule } from '@angular/common';
4
4
  import { Subject, fromEvent, BehaviorSubject, of } from 'rxjs';
5
- import { takeUntil, debounceTime } from 'rxjs/operators';
5
+ import { takeUntil, debounceTime, take } from 'rxjs/operators';
6
6
  import { getStringForLocale, SKY_LIB_RESOURCES_PROVIDERS, SkyIntlNumberFormatStyle, SkyIntlNumberFormatter, SkyLibResourcesService, SkyAppLocaleProvider, SkyI18nModule } from '@skyux/i18n';
7
7
  import { NavigationStart, Router, RouterModule } from '@angular/router';
8
8
  import { Title } from '@angular/platform-browser';
@@ -1222,7 +1222,7 @@ SkyDockComponent = __decorate([
1222
1222
  SkyDockDomAdapterService
1223
1223
  ],
1224
1224
  changeDetection: ChangeDetectionStrategy.OnPush,
1225
- styles: [":host{display:flex;flex-direction:column;width:100%}:host:not(.sky-dock-unbound){position:fixed;left:0;bottom:0;right:0}:host.sky-dock-sticky{position:sticky}"]
1225
+ styles: [":host{display:flex;flex-direction:column;width:100%}:host:not(.sky-dock-unbound){position:fixed;left:0;bottom:0;right:0}:host.sky-dock-sticky{position:-webkit-sticky;position:sticky}"]
1226
1226
  })
1227
1227
  ], SkyDockComponent);
1228
1228
 
@@ -2373,6 +2373,85 @@ SkyPercentPipeModule = __decorate([
2373
2373
  })
2374
2374
  ], SkyPercentPipeModule);
2375
2375
 
2376
+ let SkyScrollableHostService = class SkyScrollableHostService {
2377
+ constructor(mutationObserverSvc, windowRef) {
2378
+ this.mutationObserverSvc = mutationObserverSvc;
2379
+ this.windowRef = windowRef;
2380
+ }
2381
+ getScrollabeHost(elementRef) {
2382
+ return this.findScrollableHost(elementRef.nativeElement);
2383
+ }
2384
+ watchScrollableHost(elementRef, completionObservable) {
2385
+ let scrollableHost = this.findScrollableHost(elementRef.nativeElement);
2386
+ let behaviorSubject = new BehaviorSubject(scrollableHost);
2387
+ const mutationObserver = this.mutationObserverSvc.create(() => {
2388
+ let newScrollableHost = this.findScrollableHost(elementRef.nativeElement);
2389
+ if (newScrollableHost !== scrollableHost) {
2390
+ scrollableHost = newScrollableHost;
2391
+ this.observeForScrollableHostChanges(scrollableHost, mutationObserver);
2392
+ behaviorSubject.next(scrollableHost);
2393
+ }
2394
+ });
2395
+ this.observeForScrollableHostChanges(scrollableHost, mutationObserver);
2396
+ completionObservable.pipe(take(1)).subscribe(() => {
2397
+ mutationObserver.disconnect();
2398
+ });
2399
+ return behaviorSubject;
2400
+ }
2401
+ findScrollableHost(element) {
2402
+ const regex = /(auto|scroll)/;
2403
+ const windowObj = this.windowRef.nativeWindow;
2404
+ const bodyObj = windowObj.document.body;
2405
+ /* Sanity check */
2406
+ if (!element) {
2407
+ return windowObj;
2408
+ }
2409
+ let style = windowObj.getComputedStyle(element);
2410
+ let parent = element;
2411
+ do {
2412
+ parent = parent.parentNode;
2413
+ /* Sanity check for if this function is called for an element which has been removed from the DOM */
2414
+ if (!(parent instanceof HTMLElement)) {
2415
+ return windowObj;
2416
+ }
2417
+ style = windowObj.getComputedStyle(parent);
2418
+ } while (!regex.test(style.overflow) &&
2419
+ !regex.test(style.overflowY) &&
2420
+ parent !== bodyObj);
2421
+ if (parent === bodyObj) {
2422
+ return windowObj;
2423
+ }
2424
+ return parent;
2425
+ }
2426
+ observeForScrollableHostChanges(element, mutationObserver) {
2427
+ mutationObserver.disconnect();
2428
+ if (element instanceof HTMLElement) {
2429
+ mutationObserver.observe(element, {
2430
+ attributes: true,
2431
+ attributeFilter: ['class', 'style.overflow', 'style.overflow-y'],
2432
+ subtree: true
2433
+ });
2434
+ }
2435
+ else {
2436
+ mutationObserver.observe(document.documentElement, {
2437
+ attributes: true,
2438
+ attributeFilter: ['class', 'style.overflow', 'style.overflow-y'],
2439
+ subtree: true
2440
+ });
2441
+ }
2442
+ }
2443
+ };
2444
+ SkyScrollableHostService.ctorParameters = () => [
2445
+ { type: MutationObserverService },
2446
+ { type: SkyAppWindowRef }
2447
+ ];
2448
+ SkyScrollableHostService.ɵprov = ɵɵdefineInjectable({ factory: function SkyScrollableHostService_Factory() { return new SkyScrollableHostService(ɵɵinject(MutationObserverService), ɵɵinject(SkyAppWindowRef)); }, token: SkyScrollableHostService, providedIn: "root" });
2449
+ SkyScrollableHostService = __decorate([
2450
+ Injectable({
2451
+ providedIn: 'root'
2452
+ })
2453
+ ], SkyScrollableHostService);
2454
+
2376
2455
  /**
2377
2456
  * Provides a method for setting a formatted title on the current window.
2378
2457
  */
@@ -2445,11 +2524,12 @@ function nextId() {
2445
2524
  nextIdIndex = (nextIdIndex || 0) + 1;
2446
2525
  return 'viewkeeper-' + nextIdIndex;
2447
2526
  }
2448
- function getOffset(el) {
2527
+ function getOffset(el, scrollableHost) {
2449
2528
  const rect = el.getBoundingClientRect();
2529
+ const parent = scrollableHost ? scrollableHost : document.documentElement;
2450
2530
  return {
2451
- top: rect.top + document.documentElement.scrollTop,
2452
- left: rect.left + document.documentElement.scrollLeft
2531
+ top: rect.top + parent.scrollTop,
2532
+ left: rect.left + parent.scrollLeft
2453
2533
  };
2454
2534
  }
2455
2535
  function px(value) {
@@ -2485,6 +2565,7 @@ class SkyViewkeeper {
2485
2565
  this.id = nextId();
2486
2566
  this.el = options.el;
2487
2567
  this.boundaryEl = options.boundaryEl;
2568
+ this.scrollableHost = options.scrollableHost;
2488
2569
  this.verticalOffset = options.verticalOffset || 0;
2489
2570
  this.verticalOffsetEl = options.verticalOffsetEl;
2490
2571
  this.viewportMarginTop = options.viewportMarginTop || 0;
@@ -2492,7 +2573,7 @@ class SkyViewkeeper {
2492
2573
  if (this.verticalOffsetEl) {
2493
2574
  this.verticalOffsetEl.addEventListener(EVT_AFTER_VIEWKEEPER_SYNC, this.syncElPositionHandler);
2494
2575
  }
2495
- window.addEventListener('scroll', this.syncElPositionHandler);
2576
+ window.addEventListener('scroll', this.syncElPositionHandler, true);
2496
2577
  window.addEventListener('resize', this.syncElPositionHandler);
2497
2578
  window.addEventListener('orientationchange', this.syncElPositionHandler);
2498
2579
  ensureStyleEl();
@@ -2520,7 +2601,7 @@ class SkyViewkeeper {
2520
2601
  }
2521
2602
  destroy() {
2522
2603
  if (!this.isDestroyed) {
2523
- window.removeEventListener('scroll', this.syncElPositionHandler);
2604
+ window.removeEventListener('scroll', this.syncElPositionHandler, true);
2524
2605
  window.removeEventListener('resize', this.syncElPositionHandler);
2525
2606
  window.removeEventListener('orientationchange', this.syncElPositionHandler);
2526
2607
  this.unfixEl();
@@ -2558,16 +2639,19 @@ class SkyViewkeeper {
2558
2639
  const verticalOffsetElTop = parseInt(verticalOffsetElTopStyle, 10) || 0;
2559
2640
  offset += (this.verticalOffsetEl.offsetHeight + verticalOffsetElTop);
2560
2641
  }
2642
+ else if (this.scrollableHost) {
2643
+ offset += this.scrollableHost.getBoundingClientRect().top;
2644
+ }
2561
2645
  return offset;
2562
2646
  }
2563
2647
  shouldFixEl(boundaryInfo, verticalOffset) {
2564
2648
  let anchorTop;
2565
2649
  let doFixEl;
2566
2650
  if (boundaryInfo.spacerEl) {
2567
- anchorTop = getOffset(boundaryInfo.spacerEl).top;
2651
+ anchorTop = getOffset(boundaryInfo.spacerEl, this.scrollableHost).top;
2568
2652
  }
2569
2653
  else {
2570
- anchorTop = getOffset(this.el).top;
2654
+ anchorTop = getOffset(this.el, this.scrollableHost).top;
2571
2655
  }
2572
2656
  doFixEl = boundaryInfo.scrollTop + verticalOffset + this.viewportMarginTop > anchorTop;
2573
2657
  return doFixEl;
@@ -2626,11 +2710,11 @@ class SkyViewkeeper {
2626
2710
  const spacerId = this.getSpacerId();
2627
2711
  const spacerEl = document.getElementById(spacerId);
2628
2712
  const boundaryEl = this.boundaryEl;
2629
- const boundaryOffset = getOffset(boundaryEl);
2713
+ const boundaryOffset = getOffset(boundaryEl, this.scrollableHost);
2630
2714
  const boundaryTop = boundaryOffset.top;
2631
2715
  const boundaryBottom = boundaryTop + boundaryEl.getBoundingClientRect().height;
2632
- const scrollLeft = document.documentElement.scrollLeft;
2633
- const scrollTop = document.documentElement.scrollTop;
2716
+ const scrollLeft = this.scrollableHost ? this.scrollableHost.scrollLeft : document.documentElement.scrollLeft;
2717
+ const scrollTop = this.scrollableHost ? this.scrollableHost.scrollTop : document.documentElement.scrollTop;
2634
2718
  const elHeight = getHeightWithMargin(this.el);
2635
2719
  return {
2636
2720
  boundaryBottom,
@@ -2677,11 +2761,13 @@ SkyViewkeeperService = __decorate([
2677
2761
  ], SkyViewkeeperService);
2678
2762
 
2679
2763
  let SkyViewkeeperDirective = class SkyViewkeeperDirective {
2680
- constructor(el, mutationObserverSvc, viewkeeperSvc) {
2764
+ constructor(el, mutationObserverSvc, viewkeeperSvc, scrollableHostService) {
2681
2765
  this.el = el;
2682
2766
  this.mutationObserverSvc = mutationObserverSvc;
2683
2767
  this.viewkeeperSvc = viewkeeperSvc;
2768
+ this.scrollableHostService = scrollableHostService;
2684
2769
  this.viewkeepers = [];
2770
+ this.scrollableHostWatchUnsubscribe = undefined;
2685
2771
  }
2686
2772
  set skyViewkeeper(value) {
2687
2773
  this._skyViewkeeper = value;
@@ -2737,17 +2823,29 @@ let SkyViewkeeperDirective = class SkyViewkeeperDirective {
2737
2823
  detectElements() {
2738
2824
  let viewkeeperEls = this.getViewkeeperEls();
2739
2825
  if (this.viewkeeperElsChanged(viewkeeperEls)) {
2740
- this.destroyViewkeepers();
2741
- let previousViewkeeperEl;
2742
- for (const viewkeeperEl of viewkeeperEls) {
2743
- this.viewkeepers.push(this.viewkeeperSvc.create({
2744
- boundaryEl: this.el.nativeElement,
2745
- el: viewkeeperEl,
2746
- setWidth: true,
2747
- verticalOffsetEl: previousViewkeeperEl
2748
- }));
2749
- previousViewkeeperEl = viewkeeperEl;
2826
+ if (this.scrollableHostWatchUnsubscribe) {
2827
+ this.scrollableHostWatchUnsubscribe.next();
2828
+ this.scrollableHostWatchUnsubscribe = new Subject();
2750
2829
  }
2830
+ else {
2831
+ this.scrollableHostWatchUnsubscribe = new Subject();
2832
+ }
2833
+ this.scrollableHostService.watchScrollableHost(this.el, this.scrollableHostWatchUnsubscribe)
2834
+ .pipe(takeUntil(this.scrollableHostWatchUnsubscribe))
2835
+ .subscribe(scrollableHost => {
2836
+ this.destroyViewkeepers();
2837
+ let previousViewkeeperEl;
2838
+ for (const viewkeeperEl of viewkeeperEls) {
2839
+ this.viewkeepers.push(this.viewkeeperSvc.create({
2840
+ boundaryEl: this.el.nativeElement,
2841
+ scrollableHost: scrollableHost instanceof HTMLElement ? scrollableHost : undefined,
2842
+ el: viewkeeperEl,
2843
+ setWidth: true,
2844
+ verticalOffsetEl: previousViewkeeperEl
2845
+ }));
2846
+ previousViewkeeperEl = viewkeeperEl;
2847
+ }
2848
+ });
2751
2849
  this.currentViewkeeperEls = viewkeeperEls;
2752
2850
  }
2753
2851
  }
@@ -2755,7 +2853,8 @@ let SkyViewkeeperDirective = class SkyViewkeeperDirective {
2755
2853
  SkyViewkeeperDirective.ctorParameters = () => [
2756
2854
  { type: ElementRef },
2757
2855
  { type: MutationObserverService },
2758
- { type: SkyViewkeeperService }
2856
+ { type: SkyViewkeeperService },
2857
+ { type: SkyScrollableHostService, decorators: [{ type: Optional }] }
2759
2858
  ];
2760
2859
  __decorate([
2761
2860
  Input()
@@ -2763,9 +2862,21 @@ __decorate([
2763
2862
  SkyViewkeeperDirective = __decorate([
2764
2863
  Directive({
2765
2864
  selector: '[skyViewkeeper]'
2766
- })
2865
+ }),
2866
+ __param(3, Optional())
2767
2867
  ], SkyViewkeeperDirective);
2768
2868
 
2869
+ let SkyScrollableHostModule = class SkyScrollableHostModule {
2870
+ };
2871
+ SkyScrollableHostModule = __decorate([
2872
+ NgModule({
2873
+ providers: [
2874
+ MutationObserverService,
2875
+ SkyAppWindowRef
2876
+ ]
2877
+ })
2878
+ ], SkyScrollableHostModule);
2879
+
2769
2880
  let SkyViewkeeperModule = class SkyViewkeeperModule {
2770
2881
  };
2771
2882
  SkyViewkeeperModule = __decorate([
@@ -2773,6 +2884,9 @@ SkyViewkeeperModule = __decorate([
2773
2884
  declarations: [
2774
2885
  SkyViewkeeperDirective
2775
2886
  ],
2887
+ imports: [
2888
+ SkyScrollableHostModule
2889
+ ],
2776
2890
  exports: [
2777
2891
  SkyViewkeeperDirective
2778
2892
  ],
@@ -2787,5 +2901,5 @@ SkyViewkeeperModule = __decorate([
2787
2901
  * Generated bundle index. Do not edit.
2788
2902
  */
2789
2903
 
2790
- export { MutationObserverService, NumericOptions, SkyAffixAutoFitContext, SkyAffixModule, SkyAffixService, SkyAffixer, SkyAppFormat, SkyAppTitleService, SkyAppWindowRef, SkyCoreAdapterModule, SkyCoreAdapterService, SkyDockItem, SkyDockLocation, SkyDockModule, SkyDockService, SkyDynamicComponentLocation, SkyDynamicComponentModule, SkyDynamicComponentService, SkyIdModule, SkyLogModule, SkyLogService, SkyMediaBreakpoints, SkyMediaQueryModule, SkyMediaQueryService, SkyNumericModule, SkyNumericPipe, SkyNumericService, SkyOverlayInstance, SkyOverlayModule, SkyOverlayService, SkyPercentPipe, SkyPercentPipeModule, SkyUIConfigService, SkyViewkeeperHostOptions, SkyViewkeeperModule, SkyViewkeeperService, getWindow, SkyAffixDirective as ɵa, SkyDockComponent as ɵb, SkyDockDomAdapterService as ɵc, SkyIdDirective as ɵd, SkyCoreResourcesModule as ɵe, SkyCoreResourcesProvider as ɵf, SkyOverlayComponent as ɵg, SkyOverlayContext as ɵh, SkyOverlayAdapterService as ɵi, SkyViewkeeperDirective as ɵj };
2904
+ export { MutationObserverService, NumericOptions, SkyAffixAutoFitContext, SkyAffixModule, SkyAffixService, SkyAffixer, SkyAppFormat, SkyAppTitleService, SkyAppWindowRef, SkyCoreAdapterModule, SkyCoreAdapterService, SkyDockItem, SkyDockLocation, SkyDockModule, SkyDockService, SkyDynamicComponentLocation, SkyDynamicComponentModule, SkyDynamicComponentService, SkyIdModule, SkyLogModule, SkyLogService, SkyMediaBreakpoints, SkyMediaQueryModule, SkyMediaQueryService, SkyNumericModule, SkyNumericPipe, SkyNumericService, SkyOverlayInstance, SkyOverlayModule, SkyOverlayService, SkyPercentPipe, SkyPercentPipeModule, SkyScrollableHostService, SkyUIConfigService, SkyViewkeeperHostOptions, SkyViewkeeperModule, SkyViewkeeperService, getWindow, SkyAffixDirective as ɵa, SkyDockComponent as ɵb, SkyDockDomAdapterService as ɵc, SkyIdDirective as ɵd, SkyCoreResourcesModule as ɵe, SkyCoreResourcesProvider as ɵf, SkyOverlayComponent as ɵg, SkyOverlayContext as ɵh, SkyOverlayAdapterService as ɵi, SkyViewkeeperDirective as ɵj, SkyScrollableHostModule as ɵk };
2791
2905
  //# sourceMappingURL=skyux-core.js.map