mirror of
https://github.com/angular/angular
synced 2026-05-24 09:28:37 +00:00
replace @Input with signal input for ignoredElementsIds in ClickOutside directive PR Close #64302
46 lines
1.3 KiB
TypeScript
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;
|
|
});
|
|
}
|
|
}
|