angular/adev/shared-docs/directives/click-outside/click-outside.directive.ts
SkyZeroZx 6bc391c3d4 refactor(docs-infra): replace @Input with signal input for ignoredElementsIds in ClickOutside directive (#64302)
replace @Input with signal input for ignoredElementsIds in ClickOutside directive

PR Close #64302
2025-10-09 05:21:02 -07:00

46 lines
1.3 KiB
TypeScript

/*!
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import {DOCUMENT} from '@angular/common';
import {Directive, ElementRef, inject, input, output} from '@angular/core';
@Directive({
selector: '[docsClickOutside]',
host: {
'(document:click)': 'onClick($event)',
},
})
export class ClickOutside {
readonly ignoredElementsIds = input<string[]>([], {alias: 'docsClickOutsideIgnore'});
public readonly clickOutside = output<void>({alias: 'docsClickOutside'});
private readonly document = inject(DOCUMENT);
private readonly elementRef = inject(ElementRef<HTMLElement>);
onClick(event: MouseEvent): void {
if (
!this.elementRef.nativeElement.contains(event.target) &&
!this.wasClickedOnIgnoredElement(event)
) {
this.clickOutside.emit();
}
}
private wasClickedOnIgnoredElement(event: MouseEvent): boolean {
if (this.ignoredElementsIds().length === 0) {
return false;
}
return this.ignoredElementsIds().some((elementId) => {
const element = this.document.getElementById(elementId);
const target = event.target as Node;
const contains = element?.contains(target);
return contains;
});
}
}