File

src/directives/sq-click-outside/sq-click-outside.directive.ts

Description

Directive that emits an event when a click occurs outside of the bound element.

Example :
<!-- Add the clickOutside directive to an element and listen for the clickOutside event. -->
<div [clickOutside]="true" (clickOutside)="handleClickOutside()">
  <!-- Content here -->
</div>

Implements

OnDestroy OnChanges

Metadata

Index

Properties
Methods
Inputs
Outputs

Inputs

clickOutsideEnabled
Type : boolean
Default value : false

Indicates whether the clickOutside functionality is enabled.

Outputs

clickOutside
Type : EventEmitter

Event emitted when a click occurs outside of the bound element.

Methods

createListener
createListener()

Creates a click event listener to detect clicks outside of the bound element. Uses a small delay to prevent the opening click from being detected.

Returns : void
ngOnChanges
ngOnChanges(changes: SimpleChanges)

Lifecycle hook that handles changes to the clickOutsideEnabled property.

Parameters :
Name Type Optional Description
changes SimpleChanges No
  • The changes to input properties.
Returns : void
ngOnDestroy
ngOnDestroy()

Lifecycle hook that cleans up the directive when it is destroyed.

Returns : void

Properties

Private elementRef
Default value : inject(ElementRef)

The ElementRef of the bound element.

listener
Type : function

Listener function to handle click events.

Private renderer
Default value : inject(Renderer2)

The Renderer2 for DOM manipulation.

import {
  Directive,
  ElementRef,
  Output,
  EventEmitter,
  OnDestroy,
  Renderer2,
  Input,
  OnChanges,
  SimpleChanges,
  inject,
} from '@angular/core';
/**
 * Directive that emits an event when a click occurs outside of the bound element.
 *
 * @example
 * <!-- Add the clickOutside directive to an element and listen for the clickOutside event. -->
 * <div [clickOutside]="true" (clickOutside)="handleClickOutside()">
 *   <!-- Content here -->
 * </div>
 */
@Directive({
  selector: '[clickOutside]',
  standalone: true,
})
export class SqClickOutsideDirective implements OnDestroy, OnChanges {
  /**
   * Indicates whether the clickOutside functionality is enabled.
   */
  @Input() clickOutsideEnabled = false;

  /**
   * Event emitted when a click occurs outside of the bound element.
   */
  @Output() public clickOutside = new EventEmitter();

  /**
   * Listener function to handle click events.
   */
  listener!: () => void;

  /**
   * The ElementRef of the bound element.
   */
  private elementRef = inject(ElementRef);

  /**
   * The Renderer2 for DOM manipulation.
   */
  private renderer = inject(Renderer2);

  /**
   * Lifecycle hook that handles changes to the clickOutsideEnabled property.
   *
   * @param {SimpleChanges} changes - The changes to input properties.
   */
  ngOnChanges(changes: SimpleChanges): void {
    if (changes['clickOutsideEnabled']) {
      if (changes['clickOutsideEnabled'].currentValue) {
        this.createListener();
      } else if (typeof this.listener === 'function') {
        this.listener();
      }
    }
  }

  /**
   * Lifecycle hook that cleans up the directive when it is destroyed.
   */
  ngOnDestroy() {
    this.listener = () => null;
  }

  /**
   * Creates a click event listener to detect clicks outside of the bound element.
   * Uses a small delay to prevent the opening click from being detected.
   */
  createListener() {
    // Delay to prevent the click that opened the modal from being detected
    setTimeout(() => {
    this.listener = this.renderer.listen('window', 'click', $event => {
      const isClickedInside = this.elementRef.nativeElement.contains($event.target);
      if (!isClickedInside) {
        this.clickOutside.emit();
      }
    });
    }, 100);
  }
}

results matching ""

    No results matching ""