All files / components/upp-visible upp-visible.ts

0% Statements 0/16
0% Branches 0/5
0% Functions 0/3
0% Lines 0/15

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                                                                                                                                                                     
import { Component, AfterViewInit } from '@angular/core';
import { ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
import { ViewChild } from '@angular/core';
import { Output, EventEmitter} from '@angular/core';
 
import { VisibleDirective } from '../../directives/upp-visible';
 
/**
 * @component UppVisibleControlComponent
 * @description
 * A wrapper component that utilizes the `VisibleDirective` to detect and manage visibility changes.
 * It optimizes performance by detaching and reattaching Angular's change detection mechanism
 * based on the component's visibility.
 * 
 * @example
 * ```html
 * <upp-visible-control (visibilityChange)="onVisibilityChange($event)">
 *   <p>Content inside this component will only update when visible.</p>
 * </upp-visible-control>
 * ```
 * 
 * ```typescript
 * onVisibilityChange(isVisible: boolean) {
 *   console.log('Component is visible:', isVisible);
 * }
 * ```
 */
@Component({
    selector: 'upp-visible-control',
    changeDetection: ChangeDetectionStrategy.OnPush,
    templateUrl: './upp-visible.html',
})
export class UppVisibleControlComponent implements AfterViewInit {
 
    /**
     * @output visibilityChange
     * @description
     * Emits a boolean value whenever the component's visibility changes.
     * `true` if the component is visible, `false` otherwise.
     */    
    @Output() visibilityChange: EventEmitter<boolean> = new EventEmitter();
 
    /**
     * @constructor
     * @param change A reference to Angular's ChangeDetectorRef, used to manually control change detection.
     */    
    constructor(private change: ChangeDetectorRef){
        // nothing to do
    }
 
    @ViewChild(VisibleDirective) _directive!: VisibleDirective | undefined;
 
    /**
     * @method ngAfterViewInit
     * @description
     * Lifecycle hook that runs after Angular has initialized the view.
     * It checks if the component is initially visible and detaches change detection if it is not.
     */    
    ngAfterViewInit() {
        Iif (this._directive && !this._directive.isVisible) {
            this.change.detach();
        }
    }
 
    /**
     * @method onVisibilityChange
     * @description
     * Handles visibility changes detected by the `VisibleDirective`.
     * Detaches Angular's change detection when the component is hidden and reattaches it when visible.
     * @param {boolean} isVisible - The new visibility state of the component.
     */    
    onVisibilityChange(isVisible: boolean) {
        this.visibilityChange.emit(isVisible);            
 
        if (!isVisible) {   // no not compute changes if not visible
            this.change.detach();
        } 
        else {              // detect changes whenever it becomes visible
            this.change.reattach();
            this.change.detectChanges()
        }
    }
}