All files / resize-observer si-responsive-container.directive.ts

97.22% Statements 35/36
84.61% Branches 11/13
100% Functions 4/4
97.22% Lines 35/36

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127                                    1x                                               1x   32x         32x   32x         32x   32x         32x   32x         32x   32x         32x   32x         32x     32x 32x       32x 32x     32x   11x       32x       10x       10x   10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x 10x      
/**
 * Copyright (c) Siemens 2016 - 2025
 * SPDX-License-Identifier: MIT
 */
import { Directive, ElementRef, inject, input, OnDestroy, OnInit, signal } from '@angular/core';
import { Subscription } from 'rxjs';
 
import { ResizeObserverService } from './resize-observer.service';
 
export interface Breakpoints {
  smMinimum: number;
  mdMinimum: number;
  lgMinimum: number;
  xlMinimum: number;
  xxlMinimum: number;
}
 
// keep in sync with the Bootstrap variables
export const BOOTSTRAP_BREAKPOINTS: Breakpoints = {
  smMinimum: 576,
  mdMinimum: 768,
  lgMinimum: 992,
  xlMinimum: 1200,
  xxlMinimum: 1400
};
 
/**
 * Directive to automatically set `si-container-*` classes so Bootstrap column classes work
 * in the context of the container instead of viewport size.
 */
@Directive({
  selector: '[siResponsiveContainer]',
  host: {
    '[class.si-container-xs]': 'xs()',
    '[class.si-container-sm]': 'sm()',
    '[class.si-container-md]': 'md()',
    '[class.si-container-lg]': 'lg()',
    '[class.si-container-xl]': 'xl()',
    '[class.si-container-xxl]': 'xxl()'
  },
  exportAs: 'siResponsiveContainer'
})
export class SiResponsiveContainerDirective implements OnInit, OnDestroy {
  /** @defaultValue false */
  readonly xs = signal(false);
  /**
   * @deprecated Use {@link xs} instead.
   * @defaultValue false
   **/
  isXs = false;
  /** @defaultValue false */
  readonly sm = signal(false);
  /**
   * @deprecated Use {@link sm} instead.
   * @defaultValue false
   **/
  isSm = false;
  /** @defaultValue false */
  readonly md = signal(false);
  /**
   * @deprecated Use {@link md} instead.
   * @defaultValue false
   **/
  isMd = false;
  /** @defaultValue false */
  readonly lg = signal(false);
  /**
   * @deprecated Use {@link lg} instead.
   * @defaultValue false
   **/
  isLg = false;
  /** @defaultValue false */
  readonly xl = signal(false);
  /**
   * @deprecated Use {@link xl} instead.
   * @defaultValue false
   **/
  isXl = false;
  /** @defaultValue false */
  readonly xxl = signal(false);
  /**
   * @deprecated Use {@link xxl} instead.
   * @defaultValue false
   **/
  isXxl = false;
 
  /** @defaultValue 100 */
  readonly resizeThrottle = input(100);
  readonly breakpoints = input<Breakpoints>();
 
  private subs?: Subscription;
 
  private element = inject(ElementRef);
  private service = inject(ResizeObserverService);
 
  ngOnInit(): void {
    this.subs = this.service
      .observe(this.element.nativeElement, this.resizeThrottle(), true)
      .subscribe(event => this.setResponsiveSize(event.width, event.height));
  }
 
  ngOnDestroy(): void {
    this.subs?.unsubscribe();
  }
 
  private setResponsiveSize(width: number, height: number): void {
    Iif (!width && !height) {
      // element is not visible, no point in changing anything
      return;
    }
    const breakpoints = this.breakpoints() ?? BOOTSTRAP_BREAKPOINTS;
 
    this.xs.set(width < breakpoints.smMinimum);
    this.isXs = this.xs();
    this.sm.set(width >= breakpoints.smMinimum && width < breakpoints.mdMinimum);
    this.isSm = this.sm();
    this.md.set(width >= breakpoints.mdMinimum && width < breakpoints.lgMinimum);
    this.isMd = this.md();
    this.lg.set(width >= breakpoints.lgMinimum && width < breakpoints.xlMinimum);
    this.isLg = this.lg();
    this.xl.set(width >= breakpoints.xlMinimum && width < breakpoints.xxlMinimum);
    this.isXl = this.xl();
    this.xxl.set(width >= breakpoints.xxlMinimum);
    this.isXxl = this.xxl();
  }
}