@libs-ui/components-click-outside 0.2.355-9 → 0.2.356-1
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 +153 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,3 +1,154 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Click Outside Directive
|
|
2
2
|
|
|
3
|
-
|
|
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.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
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 đủ
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install @libs-ui/components-click-outside
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
### Basic Example
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
import { Component } from '@angular/core';
|
|
26
|
+
import { LibsUiComponentsClickOutsideDirective } from '@libs-ui/components-click-outside';
|
|
27
|
+
|
|
28
|
+
@Component({
|
|
29
|
+
selector: 'app-example',
|
|
30
|
+
standalone: true,
|
|
31
|
+
imports: [LibsUiComponentsClickOutsideDirective],
|
|
32
|
+
template: `
|
|
33
|
+
<div
|
|
34
|
+
LibsUiComponentsClickOutsideDirective
|
|
35
|
+
(outOutside)="onClickOutside($event)"
|
|
36
|
+
(outInSide)="onClickInside($event)">
|
|
37
|
+
Click inside or outside this element
|
|
38
|
+
</div>
|
|
39
|
+
`,
|
|
40
|
+
})
|
|
41
|
+
export class ExampleComponent {
|
|
42
|
+
onClickOutside(event: Event): void {
|
|
43
|
+
console.log('Clicked outside!', event);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
onClickInside(event: Event): void {
|
|
47
|
+
console.log('Clicked inside!', event);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Dropdown Example
|
|
53
|
+
|
|
54
|
+
```typescript
|
|
55
|
+
import { Component, signal } from '@angular/core';
|
|
56
|
+
import { LibsUiComponentsClickOutsideDirective } from '@libs-ui/components-click-outside';
|
|
57
|
+
|
|
58
|
+
@Component({
|
|
59
|
+
standalone: true,
|
|
60
|
+
imports: [LibsUiComponentsClickOutsideDirective],
|
|
61
|
+
template: `
|
|
62
|
+
<div class="relative">
|
|
63
|
+
<button (click)="isOpen.set(!isOpen())">Toggle Dropdown</button>
|
|
64
|
+
|
|
65
|
+
@if (isOpen()) {
|
|
66
|
+
<div
|
|
67
|
+
LibsUiComponentsClickOutsideDirective
|
|
68
|
+
(outOutside)="isOpen.set(false)"
|
|
69
|
+
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>
|
|
74
|
+
</ul>
|
|
75
|
+
</div>
|
|
76
|
+
}
|
|
77
|
+
</div>
|
|
78
|
+
`,
|
|
79
|
+
})
|
|
80
|
+
export class DropdownExample {
|
|
81
|
+
readonly isOpen = signal<boolean>(false);
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Modal Example
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
import { Component, signal } from '@angular/core';
|
|
89
|
+
import { LibsUiComponentsClickOutsideDirective } from '@libs-ui/components-click-outside';
|
|
90
|
+
|
|
91
|
+
@Component({
|
|
92
|
+
standalone: true,
|
|
93
|
+
imports: [LibsUiComponentsClickOutsideDirective],
|
|
94
|
+
template: `
|
|
95
|
+
@if (showModal()) {
|
|
96
|
+
<div class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center">
|
|
97
|
+
<div
|
|
98
|
+
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>
|
|
103
|
+
</div>
|
|
104
|
+
</div>
|
|
105
|
+
}
|
|
106
|
+
`,
|
|
107
|
+
})
|
|
108
|
+
export class ModalExample {
|
|
109
|
+
readonly showModal = signal<boolean>(false);
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## API Reference
|
|
114
|
+
|
|
115
|
+
### Outputs
|
|
116
|
+
|
|
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 |
|
|
121
|
+
|
|
122
|
+
## Important Notes
|
|
123
|
+
|
|
124
|
+
⚠️ **Event Timing**: Directive sử dụng `AfterViewInit`, event listener được setup sau khi view init.
|
|
125
|
+
|
|
126
|
+
⚠️ **Event Type**: Lắng nghe `mousedown` event thay vì `click` để catch event sớm hơn.
|
|
127
|
+
|
|
128
|
+
⚠️ **stopPropagation**: Event được `stopPropagation()` để tránh conflicts với parent handlers.
|
|
129
|
+
|
|
130
|
+
⚠️ **Memory Leak**: Tự động cleanup với `takeUntilDestroyed` khi directive bị destroy.
|
|
131
|
+
|
|
132
|
+
## Use Cases
|
|
133
|
+
|
|
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
|
|
139
|
+
|
|
140
|
+
## Browser Support
|
|
141
|
+
|
|
142
|
+
- Chrome (latest)
|
|
143
|
+
- Firefox (latest)
|
|
144
|
+
- Safari (latest)
|
|
145
|
+
- Edge (latest)
|
|
146
|
+
|
|
147
|
+
## Dependencies
|
|
148
|
+
|
|
149
|
+
- `@angular/core` >= 18.0.0
|
|
150
|
+
- `rxjs` ~7.8.0
|
|
151
|
+
|
|
152
|
+
## License
|
|
153
|
+
|
|
154
|
+
MIT
|