1- import { Component , input , model , signal } from "@angular/core" ;
1+ import { Component , ElementRef , inject , input , model , Renderer2 , signal } from "@angular/core" ;
22import { SvgIconComponent } from "angular-svg-icon" ;
33
44@Component ( {
@@ -8,17 +8,46 @@ import { SvgIconComponent } from "angular-svg-icon";
88 styleUrl : './dropdown.component.css'
99} )
1010export class DropdownComponent {
11+ private renderer : Renderer2 = inject ( Renderer2 ) ;
12+ private elementRef : ElementRef = inject ( ElementRef ) ;
13+
1114 items = input . required < DropdownItem [ ] > ( ) ;
1215 selected = model . required < number > ( ) ;
1316
1417 isDropdownOpen = signal < boolean > ( false ) ;
1518
16- toggleDropdown ( ) {
19+ private documentClickListener ?: ( ( ) => void ) ;
20+
21+ toggleDropdown ( ) : void {
1722 this . isDropdownOpen . update ( value => ! value ) ;
23+ if ( this . isDropdownOpen ( ) ) {
24+ this . addClickOutsideListener ( ) ;
25+ } else {
26+ this . removeClickOutsideListener ( ) ;
27+ }
28+ }
29+
30+ private addClickOutsideListener ( ) : void {
31+ this . documentClickListener = this . renderer . listen ( 'document' , 'click' , ( event : Event ) => {
32+ if ( ! this . elementRef . nativeElement . contains ( event . target ) ) {
33+ this . toggleDropdown ( ) ;
34+ }
35+ } ) ;
36+ }
37+
38+ private removeClickOutsideListener ( ) : void {
39+ if ( this . documentClickListener ) {
40+ this . documentClickListener ( ) ;
41+ this . documentClickListener = undefined ;
42+ }
43+ }
44+
45+ ngOnDestroy ( ) : void {
46+ this . removeClickOutsideListener ( ) ;
1847 }
1948}
2049
2150interface DropdownItem {
2251 name : string ;
23- icon : string ;
52+ icon ? : string ;
2453}
0 commit comments