@libs-ui/components-click-outside 0.2.356-8 → 0.2.357-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,154 +1,240 @@
1
- # Click Outside Directive
1
+ # @libs-ui/components-click-outside
2
2
 
3
- Directive phát hiện click bên ngoài hoặc bên trong element, hữu ích cho dropdowns, modals, và popups.
3
+ > Directive phát hiện click bên ngoài hoặc bên trong một element hữu ích cho dropdown, modal, popover mọi UI cần đóng khi người dùng click ra ngoài.
4
4
 
5
- ## Features
5
+ ## Giới thiệu
6
6
 
7
- - Detect clicks outside element
8
- - ✅ Detect clicks inside element
9
- - ✅ Auto cleanup với `takeUntilDestroyed`
10
- - ✅ Sử dụng `mousedown` event để catch sớm hơn
11
- - ✅ Standalone directive - dễ dàng import
12
- - ✅ TypeScript support đầy đủ
7
+ `LibsUiComponentsClickOutsideDirective` một Angular Standalone Directive lắng nghe sự kiện `mousedown` trên `window` và phân biệt click xảy ra bên trong hay bên ngoài element được gắn directive. Directive tự động dọn dẹp subscription khi bị destroy thông qua `takeUntilDestroyed`, không gây memory leak. Sự kiện được phát sớm hơn so với `click` do dùng `mousedown`, giúp UI phản hồi nhanh hơn.
13
8
 
14
- ## Installation
9
+ ## Tính năng
10
+
11
+ - Phát hiện click bên ngoài element và emit `(outOutside)`
12
+ - Phát hiện click bên trong element và emit `(outInSide)`
13
+ - Sử dụng `mousedown` để bắt sự kiện sớm hơn `click`
14
+ - Tự động cleanup với `takeUntilDestroyed` — không cần `ngOnDestroy`
15
+ - Standalone directive — import trực tiếp, không cần NgModule
16
+ - Không có dependency ngoài Angular và RxJS
17
+
18
+ ## Khi nào sử dụng
19
+
20
+ - Đóng dropdown/menu khi người dùng click bên ngoài
21
+ - Đóng modal/dialog khi click vào vùng overlay xung quanh
22
+ - Đóng tooltip hoặc popover khi click ra ngoài
23
+ - Phát hiện tương tác của người dùng với một vùng element cụ thể
24
+ - Implement hành vi "click-away" cho custom components
25
+
26
+ ## Cài đặt
15
27
 
16
28
  ```bash
17
29
  npm install @libs-ui/components-click-outside
18
30
  ```
19
31
 
20
- ## Usage
32
+ ## Import
21
33
 
22
- ### Basic Example
34
+ ```typescript
35
+ import { LibsUiComponentsClickOutsideDirective } from '@libs-ui/components-click-outside';
36
+
37
+ @Component({
38
+ standalone: true,
39
+ imports: [LibsUiComponentsClickOutsideDirective],
40
+ // ...
41
+ })
42
+ export class MyComponent {}
43
+ ```
44
+
45
+ ## Ví dụ sử dụng
46
+
47
+ ### 1. Cơ bản — lắng nghe cả hai sự kiện
23
48
 
24
49
  ```typescript
25
50
  import { Component } from '@angular/core';
26
51
  import { LibsUiComponentsClickOutsideDirective } from '@libs-ui/components-click-outside';
27
52
 
28
53
  @Component({
29
- selector: 'app-example',
54
+ selector: 'app-basic-example',
30
55
  standalone: true,
31
56
  imports: [LibsUiComponentsClickOutsideDirective],
32
57
  template: `
33
58
  <div
34
59
  LibsUiComponentsClickOutsideDirective
35
- (outOutside)="onClickOutside($event)"
36
- (outInSide)="onClickInside($event)">
37
- Click inside or outside this element
60
+ (outOutside)="handlerClickOutside($event)"
61
+ (outInSide)="handlerClickInside($event)"
62
+ class="p-6 border-2 border-blue-500 rounded-lg">
63
+ <p>Click vào trong hoặc ngoài vùng này để thử</p>
38
64
  </div>
39
65
  `,
40
66
  })
41
- export class ExampleComponent {
42
- onClickOutside(event: Event): void {
43
- console.log('Clicked outside!', event);
67
+ export class BasicExampleComponent {
68
+ handlerClickOutside(event: Event): void {
69
+ event.stopPropagation();
70
+ console.log('Đã click bên ngoài');
44
71
  }
45
72
 
46
- onClickInside(event: Event): void {
47
- console.log('Clicked inside!', event);
73
+ handlerClickInside(event: Event): void {
74
+ event.stopPropagation();
75
+ console.log('Đã click bên trong');
48
76
  }
49
77
  }
50
78
  ```
51
79
 
52
- ### Dropdown Example
80
+ ### 2. Dropdown — đóng khi click ra ngoài
53
81
 
54
82
  ```typescript
55
83
  import { Component, signal } from '@angular/core';
56
84
  import { LibsUiComponentsClickOutsideDirective } from '@libs-ui/components-click-outside';
57
85
 
58
86
  @Component({
87
+ selector: 'app-dropdown-example',
59
88
  standalone: true,
60
89
  imports: [LibsUiComponentsClickOutsideDirective],
61
90
  template: `
62
91
  <div class="relative">
63
- <button (click)="isOpen.set(!isOpen())">Toggle Dropdown</button>
92
+ <button
93
+ (click)="isOpen.set(!isOpen())"
94
+ class="px-4 py-2 bg-blue-500 text-white rounded">
95
+ Toggle Dropdown
96
+ </button>
64
97
 
65
98
  @if (isOpen()) {
66
99
  <div
67
100
  LibsUiComponentsClickOutsideDirective
68
- (outOutside)="isOpen.set(false)"
101
+ (outOutside)="handlerClose($event)"
69
102
  class="absolute mt-2 w-48 bg-white border rounded-lg shadow-lg">
70
- <ul>
71
- <li>Option 1</li>
72
- <li>Option 2</li>
73
- <li>Option 3</li>
103
+ <ul class="py-2">
104
+ <li class="px-4 py-2 hover:bg-gray-100 cursor-pointer">Option 1</li>
105
+ <li class="px-4 py-2 hover:bg-gray-100 cursor-pointer">Option 2</li>
106
+ <li class="px-4 py-2 hover:bg-gray-100 cursor-pointer">Option 3</li>
74
107
  </ul>
75
108
  </div>
76
109
  }
77
110
  </div>
78
111
  `,
79
112
  })
80
- export class DropdownExample {
113
+ export class DropdownExampleComponent {
81
114
  readonly isOpen = signal<boolean>(false);
115
+
116
+ handlerClose(event: Event): void {
117
+ event.stopPropagation();
118
+ this.isOpen.set(false);
119
+ }
82
120
  }
83
121
  ```
84
122
 
85
- ### Modal Example
123
+ ### 3. Modal — đóng khi click vào overlay
86
124
 
87
125
  ```typescript
88
126
  import { Component, signal } from '@angular/core';
89
127
  import { LibsUiComponentsClickOutsideDirective } from '@libs-ui/components-click-outside';
90
128
 
91
129
  @Component({
130
+ selector: 'app-modal-example',
92
131
  standalone: true,
93
132
  imports: [LibsUiComponentsClickOutsideDirective],
94
133
  template: `
134
+ <button
135
+ (click)="showModal.set(true)"
136
+ class="px-4 py-2 bg-blue-500 text-white rounded">
137
+ Mở Modal
138
+ </button>
139
+
95
140
  @if (showModal()) {
96
141
  <div class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center">
97
142
  <div
98
143
  LibsUiComponentsClickOutsideDirective
99
- (outOutside)="showModal.set(false)"
100
- class="bg-white p-6 rounded-lg shadow-xl">
101
- <h3>Modal Title</h3>
102
- <p>Click outside to close</p>
144
+ (outOutside)="handlerCloseModal($event)"
145
+ class="bg-white p-6 rounded-lg shadow-xl max-w-md w-full">
146
+ <h3 class="text-lg font-semibold mb-4">Tiêu đề modal</h3>
147
+ <p class="text-gray-600 mb-4">Click ra ngoài vùng trắng này để đóng modal.</p>
148
+ <button
149
+ (click)="showModal.set(false)"
150
+ class="px-4 py-2 bg-gray-200 rounded">
151
+ Đóng
152
+ </button>
103
153
  </div>
104
154
  </div>
105
155
  }
106
156
  `,
107
157
  })
108
- export class ModalExample {
158
+ export class ModalExampleComponent {
109
159
  readonly showModal = signal<boolean>(false);
160
+
161
+ handlerCloseModal(event: Event): void {
162
+ event.stopPropagation();
163
+ this.showModal.set(false);
164
+ }
110
165
  }
111
166
  ```
112
167
 
113
- ## API Reference
168
+ ### 4. Click counter — đếm số lần click inside/outside
169
+
170
+ ```typescript
171
+ import { Component, signal } from '@angular/core';
172
+ import { LibsUiComponentsClickOutsideDirective } from '@libs-ui/components-click-outside';
173
+
174
+ @Component({
175
+ selector: 'app-counter-example',
176
+ standalone: true,
177
+ imports: [LibsUiComponentsClickOutsideDirective],
178
+ template: `
179
+ <div
180
+ LibsUiComponentsClickOutsideDirective
181
+ (outOutside)="handlerOutside($event)"
182
+ (outInSide)="handlerInside($event)"
183
+ class="p-6 border-2 border-purple-500 rounded-lg">
184
+ <p>Click bên trong: {{ insideCount() }}</p>
185
+ <p>Click bên ngoài: {{ outsideCount() }}</p>
186
+ </div>
187
+ `,
188
+ })
189
+ export class CounterExampleComponent {
190
+ readonly insideCount = signal<number>(0);
191
+ readonly outsideCount = signal<number>(0);
192
+
193
+ handlerInside(event: Event): void {
194
+ event.stopPropagation();
195
+ this.insideCount.update((count) => count + 1);
196
+ }
197
+
198
+ handlerOutside(event: Event): void {
199
+ event.stopPropagation();
200
+ this.outsideCount.update((count) => count + 1);
201
+ }
202
+ }
203
+ ```
114
204
 
115
- ### Outputs
205
+ ## @Output()
116
206
 
117
- | Property | Type | Description |
118
- | -------------- | ------- | -------------------------------- |
119
- | `(outOutside)` | `Event` | Emit khi click bên ngoài element |
120
- | `(outInSide)` | `Event` | Emit khi click bên trong element |
207
+ | Output | Type | Mô tả | Handler TS | Binding HTML |
208
+ |---|---|---|---|---|
209
+ | `(outOutside)` | `Event` | Emit khi `mousedown` xảy ra bên ngoài element | `handlerClickOutside(event: Event): void { event.stopPropagation(); ... }` | `(outOutside)="handlerClickOutside($event)"` |
210
+ | `(outInSide)` | `Event` | Emit khi `mousedown` xảy ra bên trong element | `handlerClickInside(event: Event): void { event.stopPropagation(); ... }` | `(outInSide)="handlerClickInside($event)"` |
121
211
 
122
- ## Important Notes
212
+ ## Selector
123
213
 
124
- ⚠️ **Event Timing**: Directive sử dụng `AfterViewInit`, event listener được setup sau khi view init.
214
+ Directive được gắn vào element bằng **attribute selector**:
125
215
 
126
- ⚠️ **Event Type**: Lắng nghe `mousedown` event thay vì `click` để catch event sớm hơn.
216
+ ```html
217
+ <div LibsUiComponentsClickOutsideDirective ...>
218
+ ```
127
219
 
128
- ⚠️ **stopPropagation**: Event được `stopPropagation()` để tránh conflicts với parent handlers.
220
+ > Selector: `[LibsUiComponentsClickOutsideDirective]`
129
221
 
130
- ⚠️ **Memory Leak**: Tự động cleanup với `takeUntilDestroyed` khi directive bị destroy.
222
+ ## Lưu ý quan trọng
131
223
 
132
- ## Use Cases
224
+ ⚠️ **Event Timing**: Directive setup listener trong `ngAfterViewInit` — event chỉ hoạt động sau khi view được khởi tạo hoàn chỉnh.
133
225
 
134
- - Đóng dropdown/menu khi click bên ngoài
135
- - Đóng modal/dialog khi click vào overlay
136
- - Đóng tooltip/popover khi click ra ngoài
137
- - Detect user interaction với element cụ thể
138
- - Implement click-away behavior cho custom components
226
+ ⚠️ **mousedown thay click**: Directive dùng `mousedown` để bắt sự kiện sớm hơn `click`, đảm bảo UI phản hồi ngay khi người dùng nhấn chuột xuống chứ không chờ nhả ra.
139
227
 
140
- ## Browser Support
228
+ ⚠️ **stopPropagation nội bộ**: Bên trong directive, sự kiện đã được gọi `stopPropagation()` để tránh conflict với các handler ở parent. Tuy nhiên, các handler ở phía consumer (component sử dụng directive) vẫn nên gọi `event.stopPropagation()` theo convention của project để ngăn sự kiện lan lên trên.
141
229
 
142
- - Chrome (latest)
143
- - Firefox (latest)
144
- - Safari (latest)
145
- - Edge (latest)
230
+ ⚠️ **Không có @Input()**: Directive này không nhận bất kỳ input nào — chỉ cần gắn vào element và lắng nghe output.
146
231
 
147
- ## Dependencies
232
+ ⚠️ **Cleanup tự động**: Subscription được dọn dẹp qua `takeUntilDestroyed(destroyRef)` — không cần tự unsubscribe hay implement `ngOnDestroy`.
148
233
 
149
- - `@angular/core` >= 18.0.0
150
- - `rxjs` ~7.8.0
234
+ ## Demo
151
235
 
152
- ## License
236
+ ```bash
237
+ npx nx serve core-ui
238
+ ```
153
239
 
154
- MIT
240
+ Truy cập: http://localhost:4500/directives/click-outside
@@ -3,8 +3,8 @@ import * as i0 from "@angular/core";
3
3
  export declare class LibsUiComponentsClickOutsideDirective implements AfterViewInit {
4
4
  readonly outOutside: import("@angular/core").OutputEmitterRef<Event>;
5
5
  readonly outInSide: import("@angular/core").OutputEmitterRef<Event>;
6
- private elementRef;
7
- private destroyRef;
6
+ private readonly elementRef;
7
+ private readonly destroyRef;
8
8
  ngAfterViewInit(): void;
9
9
  static ɵfac: i0.ɵɵFactoryDeclaration<LibsUiComponentsClickOutsideDirective, never>;
10
10
  static ɵdir: i0.ɵɵDirectiveDeclaration<LibsUiComponentsClickOutsideDirective, "[LibsUiComponentsClickOutsideDirective]", never, {}, { "outOutside": "outOutside"; "outInSide": "outInSide"; }, never, never, true, never>;
@@ -31,4 +31,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
31
31
  standalone: true,
32
32
  }]
33
33
  }] });
34
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpY2stb3V0c2lkZS5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9saWJzLXVpL2NvbXBvbmVudHMvY2xpY2stb3V0c2lkZS9zcmMvY2xpY2stb3V0c2lkZS5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFpQixVQUFVLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2pHLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ2hFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDakMsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDOztBQU9yQyxNQUFNLE9BQU8scUNBQXFDO0lBQ3ZDLFVBQVUsR0FBRyxNQUFNLEVBQVMsQ0FBQztJQUM3QixTQUFTLEdBQUcsTUFBTSxFQUFTLENBQUM7SUFFN0IsVUFBVSxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUNoQyxVQUFVLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ3hDLGVBQWU7UUFDYixTQUFTLENBQVEsTUFBTSxFQUFFLFdBQVcsQ0FBQzthQUNsQyxJQUFJLENBQ0gsR0FBRyxDQUFDLENBQUMsQ0FBUSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsZUFBZSxFQUFFLENBQUMsRUFDdEMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUNwQzthQUNBLFNBQVMsQ0FBQyxDQUFDLENBQVEsRUFBRSxFQUFFO1lBQ3RCLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUM7WUFFdkUsSUFBSSxhQUFhLEVBQUUsQ0FBQztnQkFDbEIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBRXZCLE9BQU87WUFDVCxDQUFDO1lBQ0QsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDMUIsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO3dHQXRCVSxxQ0FBcUM7NEZBQXJDLHFDQUFxQzs7NEZBQXJDLHFDQUFxQztrQkFMakQsU0FBUzttQkFBQztvQkFDVCw4REFBOEQ7b0JBQzlELFFBQVEsRUFBRSx5Q0FBeUM7b0JBQ25ELFVBQVUsRUFBRSxJQUFJO2lCQUNqQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFmdGVyVmlld0luaXQsIERlc3Ryb3lSZWYsIERpcmVjdGl2ZSwgRWxlbWVudFJlZiwgaW5qZWN0LCBvdXRwdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IHRha2VVbnRpbERlc3Ryb3llZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUvcnhqcy1pbnRlcm9wJztcbmltcG9ydCB7IGZyb21FdmVudCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgdGFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5ARGlyZWN0aXZlKHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEBhbmd1bGFyLWVzbGludC9kaXJlY3RpdmUtc2VsZWN0b3JcbiAgc2VsZWN0b3I6ICdbTGlic1VpQ29tcG9uZW50c0NsaWNrT3V0c2lkZURpcmVjdGl2ZV0nLFxuICBzdGFuZGFsb25lOiB0cnVlLFxufSlcbmV4cG9ydCBjbGFzcyBMaWJzVWlDb21wb25lbnRzQ2xpY2tPdXRzaWRlRGlyZWN0aXZlIGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCB7XG4gIHJlYWRvbmx5IG91dE91dHNpZGUgPSBvdXRwdXQ8RXZlbnQ+KCk7XG4gIHJlYWRvbmx5IG91dEluU2lkZSA9IG91dHB1dDxFdmVudD4oKTtcblxuICBwcml2YXRlIGVsZW1lbnRSZWYgPSBpbmplY3QoRWxlbWVudFJlZik7XG4gIHByaXZhdGUgZGVzdHJveVJlZiA9IGluamVjdChEZXN0cm95UmVmKTtcbiAgbmdBZnRlclZpZXdJbml0KCkge1xuICAgIGZyb21FdmVudDxFdmVudD4od2luZG93LCAnbW91c2Vkb3duJylcbiAgICAgIC5waXBlKFxuICAgICAgICB0YXAoKGU6IEV2ZW50KSA9PiBlLnN0b3BQcm9wYWdhdGlvbigpKSxcbiAgICAgICAgdGFrZVVudGlsRGVzdHJveWVkKHRoaXMuZGVzdHJveVJlZilcbiAgICAgIClcbiAgICAgIC5zdWJzY3JpYmUoKGU6IEV2ZW50KSA9PiB7XG4gICAgICAgIGNvbnN0IGNsaWNrZWRJbnNpZGUgPSB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5jb250YWlucyhlLnRhcmdldCk7XG5cbiAgICAgICAgaWYgKGNsaWNrZWRJbnNpZGUpIHtcbiAgICAgICAgICB0aGlzLm91dEluU2lkZS5lbWl0KGUpO1xuXG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub3V0T3V0c2lkZS5lbWl0KGUpO1xuICAgICAgfSk7XG4gIH1cbn1cbiJdfQ==
34
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpY2stb3V0c2lkZS5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9saWJzLXVpL2NvbXBvbmVudHMvY2xpY2stb3V0c2lkZS9zcmMvY2xpY2stb3V0c2lkZS5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFpQixVQUFVLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2pHLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ2hFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDakMsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDOztBQU9yQyxNQUFNLE9BQU8scUNBQXFDO0lBQ3ZDLFVBQVUsR0FBRyxNQUFNLEVBQVMsQ0FBQztJQUM3QixTQUFTLEdBQUcsTUFBTSxFQUFTLENBQUM7SUFFcEIsVUFBVSxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUNoQyxVQUFVLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ2pELGVBQWU7UUFDYixTQUFTLENBQVEsTUFBTSxFQUFFLFdBQVcsQ0FBQzthQUNsQyxJQUFJLENBQ0gsR0FBRyxDQUFDLENBQUMsQ0FBUSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsZUFBZSxFQUFFLENBQUMsRUFDdEMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUNwQzthQUNBLFNBQVMsQ0FBQyxDQUFDLENBQVEsRUFBRSxFQUFFO1lBQ3RCLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUM7WUFFdkUsSUFBSSxhQUFhLEVBQUUsQ0FBQztnQkFDbEIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBRXZCLE9BQU87WUFDVCxDQUFDO1lBQ0QsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDMUIsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO3dHQXRCVSxxQ0FBcUM7NEZBQXJDLHFDQUFxQzs7NEZBQXJDLHFDQUFxQztrQkFMakQsU0FBUzttQkFBQztvQkFDVCw4REFBOEQ7b0JBQzlELFFBQVEsRUFBRSx5Q0FBeUM7b0JBQ25ELFVBQVUsRUFBRSxJQUFJO2lCQUNqQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFmdGVyVmlld0luaXQsIERlc3Ryb3lSZWYsIERpcmVjdGl2ZSwgRWxlbWVudFJlZiwgaW5qZWN0LCBvdXRwdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IHRha2VVbnRpbERlc3Ryb3llZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUvcnhqcy1pbnRlcm9wJztcbmltcG9ydCB7IGZyb21FdmVudCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgdGFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5ARGlyZWN0aXZlKHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEBhbmd1bGFyLWVzbGludC9kaXJlY3RpdmUtc2VsZWN0b3JcbiAgc2VsZWN0b3I6ICdbTGlic1VpQ29tcG9uZW50c0NsaWNrT3V0c2lkZURpcmVjdGl2ZV0nLFxuICBzdGFuZGFsb25lOiB0cnVlLFxufSlcbmV4cG9ydCBjbGFzcyBMaWJzVWlDb21wb25lbnRzQ2xpY2tPdXRzaWRlRGlyZWN0aXZlIGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCB7XG4gIHJlYWRvbmx5IG91dE91dHNpZGUgPSBvdXRwdXQ8RXZlbnQ+KCk7XG4gIHJlYWRvbmx5IG91dEluU2lkZSA9IG91dHB1dDxFdmVudD4oKTtcblxuICBwcml2YXRlIHJlYWRvbmx5IGVsZW1lbnRSZWYgPSBpbmplY3QoRWxlbWVudFJlZik7XG4gIHByaXZhdGUgcmVhZG9ubHkgZGVzdHJveVJlZiA9IGluamVjdChEZXN0cm95UmVmKTtcbiAgbmdBZnRlclZpZXdJbml0KCkge1xuICAgIGZyb21FdmVudDxFdmVudD4od2luZG93LCAnbW91c2Vkb3duJylcbiAgICAgIC5waXBlKFxuICAgICAgICB0YXAoKGU6IEV2ZW50KSA9PiBlLnN0b3BQcm9wYWdhdGlvbigpKSxcbiAgICAgICAgdGFrZVVudGlsRGVzdHJveWVkKHRoaXMuZGVzdHJveVJlZilcbiAgICAgIClcbiAgICAgIC5zdWJzY3JpYmUoKGU6IEV2ZW50KSA9PiB7XG4gICAgICAgIGNvbnN0IGNsaWNrZWRJbnNpZGUgPSB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5jb250YWlucyhlLnRhcmdldCk7XG5cbiAgICAgICAgaWYgKGNsaWNrZWRJbnNpZGUpIHtcbiAgICAgICAgICB0aGlzLm91dEluU2lkZS5lbWl0KGUpO1xuXG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub3V0T3V0c2lkZS5lbWl0KGUpO1xuICAgICAgfSk7XG4gIH1cbn1cbiJdfQ==
@@ -1 +1 @@
1
- {"version":3,"file":"libs-ui-components-click-outside.mjs","sources":["../../../../../libs-ui/components/click-outside/src/click-outside.directive.ts","../../../../../libs-ui/components/click-outside/src/libs-ui-components-click-outside.ts"],"sourcesContent":["import { AfterViewInit, DestroyRef, Directive, ElementRef, inject, output } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { fromEvent } from 'rxjs';\nimport { tap } from 'rxjs/operators';\n\n@Directive({\n // eslint-disable-next-line @angular-eslint/directive-selector\n selector: '[LibsUiComponentsClickOutsideDirective]',\n standalone: true,\n})\nexport class LibsUiComponentsClickOutsideDirective implements AfterViewInit {\n readonly outOutside = output<Event>();\n readonly outInSide = output<Event>();\n\n private elementRef = inject(ElementRef);\n private destroyRef = inject(DestroyRef);\n ngAfterViewInit() {\n fromEvent<Event>(window, 'mousedown')\n .pipe(\n tap((e: Event) => e.stopPropagation()),\n takeUntilDestroyed(this.destroyRef)\n )\n .subscribe((e: Event) => {\n const clickedInside = this.elementRef.nativeElement.contains(e.target);\n\n if (clickedInside) {\n this.outInSide.emit(e);\n\n return;\n }\n this.outOutside.emit(e);\n });\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;MAUa,qCAAqC,CAAA;IACvC,UAAU,GAAG,MAAM,EAAS;IAC5B,SAAS,GAAG,MAAM,EAAS;AAE5B,IAAA,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;AAC/B,IAAA,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;IACvC,eAAe,GAAA;AACb,QAAA,SAAS,CAAQ,MAAM,EAAE,WAAW;aACjC,IAAI,CACH,GAAG,CAAC,CAAC,CAAQ,KAAK,CAAC,CAAC,eAAe,EAAE,CAAC,EACtC,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC;AAEpC,aAAA,SAAS,CAAC,CAAC,CAAQ,KAAI;AACtB,YAAA,MAAM,aAAa,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;YAEtE,IAAI,aAAa,EAAE;AACjB,gBAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;gBAEtB;YACF;AACA,YAAA,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;AACzB,QAAA,CAAC,CAAC;IACN;wGAtBW,qCAAqC,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA;4FAArC,qCAAqC,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,yCAAA,EAAA,OAAA,EAAA,EAAA,UAAA,EAAA,YAAA,EAAA,SAAA,EAAA,WAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA;;4FAArC,qCAAqC,EAAA,UAAA,EAAA,CAAA;kBALjD,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;;AAET,oBAAA,QAAQ,EAAE,yCAAyC;AACnD,oBAAA,UAAU,EAAE,IAAI;AACjB,iBAAA;;;ACTD;;AAEG;;;;"}
1
+ {"version":3,"file":"libs-ui-components-click-outside.mjs","sources":["../../../../../libs-ui/components/click-outside/src/click-outside.directive.ts","../../../../../libs-ui/components/click-outside/src/libs-ui-components-click-outside.ts"],"sourcesContent":["import { AfterViewInit, DestroyRef, Directive, ElementRef, inject, output } from '@angular/core';\nimport { takeUntilDestroyed } from '@angular/core/rxjs-interop';\nimport { fromEvent } from 'rxjs';\nimport { tap } from 'rxjs/operators';\n\n@Directive({\n // eslint-disable-next-line @angular-eslint/directive-selector\n selector: '[LibsUiComponentsClickOutsideDirective]',\n standalone: true,\n})\nexport class LibsUiComponentsClickOutsideDirective implements AfterViewInit {\n readonly outOutside = output<Event>();\n readonly outInSide = output<Event>();\n\n private readonly elementRef = inject(ElementRef);\n private readonly destroyRef = inject(DestroyRef);\n ngAfterViewInit() {\n fromEvent<Event>(window, 'mousedown')\n .pipe(\n tap((e: Event) => e.stopPropagation()),\n takeUntilDestroyed(this.destroyRef)\n )\n .subscribe((e: Event) => {\n const clickedInside = this.elementRef.nativeElement.contains(e.target);\n\n if (clickedInside) {\n this.outInSide.emit(e);\n\n return;\n }\n this.outOutside.emit(e);\n });\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;MAUa,qCAAqC,CAAA;IACvC,UAAU,GAAG,MAAM,EAAS,CAAC;IAC7B,SAAS,GAAG,MAAM,EAAS,CAAC;AAEpB,IAAA,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;AAChC,IAAA,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;IACjD,eAAe,GAAA;AACb,QAAA,SAAS,CAAQ,MAAM,EAAE,WAAW,CAAC;aAClC,IAAI,CACH,GAAG,CAAC,CAAC,CAAQ,KAAK,CAAC,CAAC,eAAe,EAAE,CAAC,EACtC,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC,CACpC;AACA,aAAA,SAAS,CAAC,CAAC,CAAQ,KAAI;AACtB,YAAA,MAAM,aAAa,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YAEvE,IAAI,aAAa,EAAE;AACjB,gBAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBAEvB,OAAO;aACR;AACD,YAAA,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAC1B,SAAC,CAAC,CAAC;KACN;wGAtBU,qCAAqC,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;4FAArC,qCAAqC,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,yCAAA,EAAA,OAAA,EAAA,EAAA,UAAA,EAAA,YAAA,EAAA,SAAA,EAAA,WAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA,CAAA;;4FAArC,qCAAqC,EAAA,UAAA,EAAA,CAAA;kBALjD,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;;AAET,oBAAA,QAAQ,EAAE,yCAAyC;AACnD,oBAAA,UAAU,EAAE,IAAI;AACjB,iBAAA,CAAA;;;ACTD;;AAEG;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@libs-ui/components-click-outside",
3
- "version": "0.2.356-8",
3
+ "version": "0.2.357-0",
4
4
  "peerDependencies": {
5
5
  "@angular/core": ">=18.0.0",
6
6
  "rxjs": "~7.8.0"