diff --git a/.gitignore b/.gitignore
index 105c00f..e1f6bab 100644
--- a/.gitignore
+++ b/.gitignore
@@ -44,3 +44,4 @@ testem.log
# System Files
.DS_Store
Thumbs.db
+/.nx/
diff --git a/README.md b/README.md
index e85f1f3..88d7d19 100644
--- a/README.md
+++ b/README.md
@@ -42,14 +42,14 @@ If you use Angular <= 12 please use the original package. https://www.npmjs.com/
### Options
-| Property name | Type | Default | Description |
-| ------------- | ---- | ------- |---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| `attachOutsideOnClick` | boolean | `false` | By default, the outside click event handler is automatically attached. Explicitely setting this to `true` sets the handler after the element is clicked. The outside click event handler will then be removed after a click outside has occurred. |
-| `clickOutsideEnabled` | boolean | `true` | Enables directive. |
-| `clickOutsideEvents` | string | `'click'` | A comma-separated list of events to cause the trigger. For example, for additional mobile support: `[clickOutsideEvents]="'click,touchstart'"`. |
-| `delayClickOutsideInit` | boolean | `false` | Delays the initialization of the click outside handler. This may help for items that are conditionally shown ([see issue #13](https://github.com/arkon/ng-click-outside/issues/13)). |
-| `emitOnBlur` | boolean | `false` | If enabled, emits an event when user clicks outside of applications' window while it's visible. Especially useful if page contains iframes. |
-| `clickOutsideExclude` | string | | A comma-separated string of DOM element queries to exclude when clicking outside of the element. (Import NgClickOutsideExcludeDirective) For example: `[clickOutsideExclude]="'button,.btn-primary'"`. |
+| Property name | Type | Default | Description |
+| ------------- |---------|-----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| `attachOutsideOnClick` | boolean | `false` | By default, the outside click event handler is automatically attached. Explicitely setting this to `true` sets the handler after the element is clicked. The outside click event handler will then be removed after a click outside has occurred. |
+| `clickOutsideEnabled` | boolean | `true` | Enables directive. |
+| `clickOutsideEvents` | string | `'click'` | A comma-separated list of events to cause the trigger. For example, for additional mobile support: `[clickOutsideEvents]="'click,touchstart'"`. |
+| `delayClickOutsideInit` | boolean | `false` | Delays the initialization of the click outside handler. This may help for items that are conditionally shown ([see issue #13](https://github.com/arkon/ng-click-outside/issues/13)). |
+| `clickOutsideEmitOnBlur` | - | - | If enabled, emits an `blurWindow` event when user clicks outside of applications' window while it's visible. Especially useful if page contains iframes. (Import `NgClickOutsideEmitOnBlurDirective`) |
+| `clickOutsideExclude` | string | | A comma-separated string of DOM element queries to exclude when clicking outside of the element. (Import NgClickOutsideExcludeDirective) For example: `[clickOutsideExclude]="'button,.btn-primary'"`. |
## Example Usage
diff --git a/projects/ng-click-outside2/package.json b/projects/ng-click-outside2/package.json
index 791e3da..4850392 100644
--- a/projects/ng-click-outside2/package.json
+++ b/projects/ng-click-outside2/package.json
@@ -1,6 +1,6 @@
{
"name": "ng-click-outside2",
- "version": "13.0.0",
+ "version": "14.0.0",
"description": "Angular directive for handling click events outside an element.",
"license": "MIT",
"keywords": [
diff --git a/projects/ng-click-outside2/src/lib/ng-click-outside-emit-on-blur.directive.spec.ts b/projects/ng-click-outside2/src/lib/ng-click-outside-emit-on-blur.directive.spec.ts
new file mode 100644
index 0000000..d3da3d8
--- /dev/null
+++ b/projects/ng-click-outside2/src/lib/ng-click-outside-emit-on-blur.directive.spec.ts
@@ -0,0 +1,54 @@
+import {NgClickOutsideEmitOnBlurDirective} from './ng-click-outside-emit-on-blur.directive';
+import {ComponentFixture, TestBed} from "@angular/core/testing";
+import {DOCUMENT} from "@angular/common";
+import {Component, ViewChild} from "@angular/core";
+import {By} from "@angular/platform-browser";
+
+
+@Component({
+ // eslint-disable-next-line @angular-eslint/component-selector
+ selector: 'test-click',
+ standalone: true,
+ imports: [NgClickOutsideEmitOnBlurDirective],
+ template: `
+
+ `
+})
+class TestClickOutsideComponent {
+ @ViewChild(NgClickOutsideEmitOnBlurDirective) ngClickOutsideEmitOnBlurDirective?: NgClickOutsideEmitOnBlurDirective
+ blurWindowButton1 = 0;
+ clickButton1 = 0;
+}
+
+
+describe('NgClickOutsideEmitOnBlurDirective', () => {
+ let component: TestClickOutsideComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ imports: [TestClickOutsideComponent],
+ providers: [{provider: DOCUMENT, useValue: document}]
+ }).compileComponents();
+
+ fixture = TestBed.createComponent(TestClickOutsideComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ })
+
+ it('should create an instance', () => {
+ expect(component.ngClickOutsideEmitOnBlurDirective).toBeDefined();
+ });
+
+ it('should emit on window blur', () => {
+ const button1 = fixture.debugElement.query(By.css('#b-1'));
+
+ button1.nativeElement.click();
+ document.defaultView!.dispatchEvent(new Event('blur'));
+
+ expect(component.clickButton1).toBe(1);
+ expect(component.blurWindowButton1).toBe(1);
+ });
+});
diff --git a/projects/ng-click-outside2/src/lib/ng-click-outside-emit-on-blur.directive.ts b/projects/ng-click-outside2/src/lib/ng-click-outside-emit-on-blur.directive.ts
new file mode 100644
index 0000000..407cc7f
--- /dev/null
+++ b/projects/ng-click-outside2/src/lib/ng-click-outside-emit-on-blur.directive.ts
@@ -0,0 +1,47 @@
+import {afterNextRender, Directive, EventEmitter, inject, NgZone, OnDestroy, Output} from '@angular/core';
+import {DOCUMENT} from "@angular/common";
+
+/**
+ * emits an event when user clicks outside of applications' window while it's visible.
+ * Especially useful if page contains iframes.
+ */
+@Directive({
+ selector: '[clickOutsideEmitOnBlur]',
+ standalone: true
+})
+export class NgClickOutsideEmitOnBlurDirective implements OnDestroy {
+ private _ngZone = inject(NgZone);
+ private document = inject(DOCUMENT);
+ @Output() blurWindow: EventEmitter = new EventEmitter();
+
+ constructor() {
+ this._onWindowBlur = this._onWindowBlur.bind(this);
+ afterNextRender(() => this._initWindowBlurListener())
+ }
+
+ ngOnDestroy() {
+ this._removeWindowBlurListener();
+ }
+
+ private _initWindowBlurListener() {
+ this._ngZone.runOutsideAngular(() => {
+ this.document.defaultView?.addEventListener('blur', this._onWindowBlur);
+ });
+ }
+
+ /**
+ * Resolves problem with outside click on iframe
+ * @see https://github.com/arkon/ng-click-outside/issues/32
+ */
+ private _onWindowBlur(ev: Event) {
+ if (!this.document.hidden) {
+ this._ngZone.run(() => this.blurWindow.emit(ev));
+ }
+ }
+
+ private _removeWindowBlurListener() {
+ this._ngZone.runOutsideAngular(() => {
+ this.document.defaultView?.removeEventListener('blur', this._onWindowBlur);
+ });
+ }
+}
diff --git a/projects/ng-click-outside2/src/lib/ng-click-outside-exclude.directive.spec.ts b/projects/ng-click-outside2/src/lib/ng-click-outside-exclude.directive.spec.ts
index 264ffa8..0710f9d 100644
--- a/projects/ng-click-outside2/src/lib/ng-click-outside-exclude.directive.spec.ts
+++ b/projects/ng-click-outside2/src/lib/ng-click-outside-exclude.directive.spec.ts
@@ -53,6 +53,6 @@ describe('NgClickOutsideExcludeDirective', () => {
button3.nativeElement.click();
expect(component.clickButton3).toBe(1);
expect(component.clickButton2).toBe(0);
- expect(component.clickOutsideButton2).toBe(0); });
-
+ expect(component.clickOutsideButton2).toBe(0);
+ });
});
diff --git a/projects/ng-click-outside2/src/lib/ng-click-outside.directive.ts b/projects/ng-click-outside2/src/lib/ng-click-outside.directive.ts
index 633a301..1ebcb2c 100644
--- a/projects/ng-click-outside2/src/lib/ng-click-outside.directive.ts
+++ b/projects/ng-click-outside2/src/lib/ng-click-outside.directive.ts
@@ -54,11 +54,6 @@ export class NgClickOutsideDirective implements OnChanges, OnDestroy {
* This may help for items that are conditionally shown ([see issue #13](https://github.com/arkon/ng-click-outside/issues/13)).
*/
@Input() delayClickOutsideInit = false;
- /**
- * If enabled, emits an event when user clicks outside of applications' window while it's visible.
- * Especially useful if page contains iframes.
- */
- @Input() emitOnBlur = false;
/**
* A comma-separated list of events to cause the trigger.
@@ -81,14 +76,12 @@ export class NgClickOutsideDirective implements OnChanges, OnDestroy {
constructor() {
this._initOnClickBody = this._initOnClickBody.bind(this);
this._onClickBody = this._onClickBody.bind(this);
- this._onWindowBlur = this._onWindowBlur.bind(this);
afterNextRender(() => this._init())
}
ngOnDestroy() {
this._removeClickOutsideListener();
this._removeAttachOutsideOnClickListener();
- this._removeWindowBlurListener();
}
ngOnChanges(changes: SimpleChanges) {
@@ -107,10 +100,6 @@ export class NgClickOutsideDirective implements OnChanges, OnDestroy {
} else {
this._initOnClickBody();
}
-
- if (this.emitOnBlur) {
- this._initWindowBlurListener();
- }
}
private _initOnClickBody() {
@@ -136,18 +125,6 @@ export class NgClickOutsideDirective implements OnChanges, OnDestroy {
}
}
- /**
- * Resolves problem with outside click on iframe
- * @see https://github.com/arkon/ng-click-outside/issues/32
- */
- private _onWindowBlur(ev: Event) {
- setTimeout(() => {
- if (!this.document.hidden) {
- this._emit(ev);
- }
- });
- }
-
private _emit(ev: Event) {
if (!this.clickOutsideEnabled) {
return;
@@ -156,7 +133,6 @@ export class NgClickOutsideDirective implements OnChanges, OnDestroy {
this._ngZone.run(() => this.clickOutside.emit(ev));
}
-
private _initClickOutsideListener() {
this._ngZone.runOutsideAngular(() => {
this._events.forEach(e => this.document.addEventListener(e, this._onClickBody));
@@ -180,16 +156,4 @@ export class NgClickOutsideDirective implements OnChanges, OnDestroy {
this._events.forEach(e => this._el.nativeElement.removeEventListener(e, this._initOnClickBody));
});
}
-
- private _initWindowBlurListener() {
- this._ngZone.runOutsideAngular(() => {
- this.document.defaultView?.addEventListener('blur', this._onWindowBlur);
- });
- }
-
- private _removeWindowBlurListener() {
- this._ngZone.runOutsideAngular(() => {
- this.document.defaultView?.removeEventListener('blur', this._onWindowBlur);
- });
- }
}