Skip to content

Commit 4a6656a

Browse files
Fix page scroll while dialog open
1 parent 8f906ed commit 4a6656a

2 files changed

Lines changed: 89 additions & 27 deletions

File tree

projects/ngsuite/src/lib/dialog/services/Dialog.ts

Lines changed: 11 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,23 @@
1-
import { ApplicationRef, ComponentRef, createComponent, createEnvironmentInjector, Injectable } from "@angular/core";
1+
import { ApplicationRef, ComponentRef, createComponent, createEnvironmentInjector, inject, Injectable } from "@angular/core";
22
import { Registry } from "../../Registry";
33
import { NGSuiteComponent } from "../../core";
44
import { NGSuiteDialogConfig, NGSuiteDialogPopupOptions, NGSuiteDialogRoot } from "../interfaces";
55
import { NGSuiteDialogInstance } from "./DialogInstance";
66
import { NGSuiteDialogAlertComponent } from "../popup/alert/alert.component";
77
import { NGSuiteDialogConfirmComponent } from "../popup/confirm/confirm.component";
88
import { Observable, throwError } from "rxjs";
9+
import { NGSuiteDialogRegistry } from "./DialogRegistry";
910

10-
const DialogInstances: NGSuiteDialogInstance[] = [];
1111
const DialogRootMap = new Map<NGSuiteDialog, NGSuiteDialogRoot>();
1212

1313
@Injectable({
1414
providedIn: 'root',
1515
})
1616
export class NGSuiteDialog {
1717

18-
constructor() {
19-
this.onEscape = this.onEscape.bind(this);
20-
this.onDocumentClick = this.onDocumentClick.bind(this);
18+
private readonly registry = inject(NGSuiteDialogRegistry);
2119

20+
constructor() {
2221
document.addEventListener('keydown', this.onEscape);
2322
document.addEventListener('click', this.onDocumentClick);
2423
}
@@ -32,26 +31,20 @@ export class NGSuiteDialog {
3231
DialogRootMap.delete(instance);
3332
}
3433

35-
private onEscape(e: KeyboardEvent) {
34+
private onEscape = (e: KeyboardEvent) => {
3635
if (e.key === 'Escape') {
3736
e.preventDefault();
3837

39-
if (!DialogInstances.length) return;
38+
const instance = this.registry.active();
4039

41-
const instance = DialogInstances[DialogInstances.length - 1];
42-
43-
instance.send({
40+
instance?.send({
4441
name: 'esc.close',
4542
value: false
4643
});
4744
}
4845
}
4946

50-
private onDocumentClick(e: MouseEvent) {
51-
if (!DialogInstances.length) return;
52-
const instance = DialogInstances[DialogInstances.length - 1];
53-
instance.focus();
54-
}
47+
private onDocumentClick = (e: MouseEvent) => this.registry.focus();
5548

5649
open(component: NGSuiteComponent<any>, config?: NGSuiteDialogConfig): NGSuiteDialogInstance {
5750
if(!config) config = null as any;
@@ -71,25 +64,16 @@ export class NGSuiteDialog {
7164
config
7265
);
7366

74-
DialogInstances.push(instance);
67+
this.registry.add(instance);
7568

7669
instance.afterClosed.subscribe(() => {
77-
const index = DialogInstances.indexOf(instance);
78-
DialogInstances.splice(index, 1);
79-
80-
const hasInstances = DialogInstances.length > 0;
81-
document.body.classList.toggle('ngs-dialog-open', hasInstances);
70+
this.registry.remove(instance);
8271
});
8372

8473
return instance;
8574
}
8675

87-
closeAll() {
88-
while (DialogInstances.length) {
89-
const instance = DialogInstances.pop();
90-
instance?.close(false);
91-
}
92-
}
76+
readonly closeAll = () => this.registry.closeAll();
9377

9478
alert(title: string, message: string) {
9579
const data: NGSuiteDialogPopupOptions = { title, message };
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import { computed, effect, Injectable, signal } from "@angular/core";
2+
import { Registry } from "../../Registry";
3+
import { NGSuiteDialogInstance } from "./DialogInstance";
4+
import { BehaviorSubject } from "rxjs";
5+
6+
@Injectable({
7+
providedIn: 'root'
8+
})
9+
export class NGSuiteDialogRegistry {
10+
11+
private readonly list = signal<NGSuiteDialogInstance[]>([]);
12+
13+
get count() { return this.xCount; }
14+
private xCount = 0;
15+
16+
constructor() {
17+
const body = document.querySelector('body');
18+
19+
effect(() => {
20+
const entries = this.list();
21+
22+
this.xCount = entries.length;
23+
24+
// =================
25+
26+
const isOpen = entries.length > 0;
27+
body?.classList.toggle('ngs-dialog-open', isOpen);
28+
});
29+
}
30+
31+
readonly active = () => {
32+
const entries = this.list();
33+
if (!entries.length) return null;
34+
35+
const lastIndex = entries.length - 1;
36+
return entries[lastIndex];
37+
}
38+
39+
readonly focus = () => {
40+
const item = this.active();
41+
item?.focus();
42+
}
43+
44+
readonly add = (...items: NGSuiteDialogInstance[]) => {
45+
const entries = this.list();
46+
47+
entries.push(...items);
48+
49+
this.list.set(entries);
50+
}
51+
52+
readonly remove = (item: NGSuiteDialogInstance) => {
53+
const entries = this.list();
54+
55+
const index = entries.indexOf(item);
56+
entries.splice(index, 1);
57+
58+
this.list.set(entries);
59+
}
60+
61+
readonly closeAll = () => {
62+
const entries = this.list();
63+
64+
while (entries.length) {
65+
const instance = entries.pop();
66+
instance?.close(false);
67+
}
68+
69+
this.list.set(entries);
70+
}
71+
72+
readonly clear = () => {
73+
this.list.set([]);
74+
}
75+
76+
}
77+
78+
Registry.add(NGSuiteDialogRegistry);

0 commit comments

Comments
 (0)