ngx-kit 1.0.0 → 2.0.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/dialog/README.md +169 -0
- package/fesm2022/{ngx-input-angle-selector.mjs → ngx-kit-angle-selector.mjs} +16 -16
- package/fesm2022/ngx-kit-angle-selector.mjs.map +1 -0
- package/fesm2022/{ngx-input-box-shadow.mjs → ngx-kit-box-shadow.mjs} +10 -10
- package/fesm2022/ngx-kit-box-shadow.mjs.map +1 -0
- package/fesm2022/{ngx-input-color-picker.mjs → ngx-kit-color-picker.mjs} +30 -14
- package/fesm2022/ngx-kit-color-picker.mjs.map +1 -0
- package/fesm2022/ngx-kit-date-picker.mjs +2280 -0
- package/fesm2022/ngx-kit-date-picker.mjs.map +1 -0
- package/fesm2022/ngx-kit-dialog.mjs +378 -0
- package/fesm2022/ngx-kit-dialog.mjs.map +1 -0
- package/fesm2022/{ngx-input-gradient-picker.mjs → ngx-kit-gradient-picker.mjs} +11 -11
- package/fesm2022/ngx-kit-gradient-picker.mjs.map +1 -0
- package/fesm2022/ngx-kit-menu.mjs +229 -0
- package/fesm2022/ngx-kit-menu.mjs.map +1 -0
- package/fesm2022/ngx-kit-notify.mjs +292 -0
- package/fesm2022/ngx-kit-notify.mjs.map +1 -0
- package/fesm2022/{ngx-input-shared.mjs → ngx-kit-shared.mjs} +262 -157
- package/fesm2022/ngx-kit-shared.mjs.map +1 -0
- package/fesm2022/{ngx-input.mjs → ngx-kit.mjs} +1 -1
- package/fesm2022/ngx-kit.mjs.map +1 -0
- package/package.json +31 -15
- package/styles/all.css +22 -0
- package/styles/overlay.css +22 -0
- package/types/{ngx-input-angle-selector.d.ts → ngx-kit-angle-selector.d.ts} +6 -5
- package/types/{ngx-input-box-shadow.d.ts → ngx-kit-box-shadow.d.ts} +7 -7
- package/types/{ngx-input-color-picker.d.ts → ngx-kit-color-picker.d.ts} +7 -7
- package/types/ngx-kit-date-picker.d.ts +294 -0
- package/types/ngx-kit-dialog.d.ts +139 -0
- package/types/{ngx-input-gradient-picker.d.ts → ngx-kit-gradient-picker.d.ts} +7 -7
- package/types/ngx-kit-menu.d.ts +69 -0
- package/types/ngx-kit-notify.d.ts +60 -0
- package/types/{ngx-input-shared.d.ts → ngx-kit-shared.d.ts} +87 -40
- package/fesm2022/ngx-input-angle-selector.mjs.map +0 -1
- package/fesm2022/ngx-input-box-shadow.mjs.map +0 -1
- package/fesm2022/ngx-input-color-picker.mjs.map +0 -1
- package/fesm2022/ngx-input-gradient-picker.mjs.map +0 -1
- package/fesm2022/ngx-input-shared.mjs.map +0 -1
- package/fesm2022/ngx-input.mjs.map +0 -1
- /package/types/{ngx-input.d.ts → ngx-kit.d.ts} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as i1 from '@angular/common';
|
|
2
2
|
import { CommonModule, isPlatformBrowser, DOCUMENT } from '@angular/common';
|
|
3
3
|
import * as i0 from '@angular/core';
|
|
4
|
-
import { EventEmitter, forwardRef, HostListener, ViewChild, Output, Input, ChangeDetectionStrategy, Component, PLATFORM_ID, Inject, Injectable, inject } from '@angular/core';
|
|
4
|
+
import { EventEmitter, forwardRef, HostListener, ViewChild, Output, Input, ChangeDetectionStrategy, Component, InjectionToken, PLATFORM_ID, Inject, Injectable, inject } from '@angular/core';
|
|
5
5
|
import { NG_VALUE_ACCESSOR, NG_VALIDATORS, FormControl, Validators } from '@angular/forms';
|
|
6
6
|
|
|
7
7
|
function getOffsetPosition(evt, parent) {
|
|
@@ -648,6 +648,37 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
648
648
|
args: ['document:touchend', ['$event']]
|
|
649
649
|
}] } });
|
|
650
650
|
|
|
651
|
+
const WINDOW = new InjectionToken('WINDOW', {
|
|
652
|
+
factory: () => (typeof window !== 'undefined' ? window : null),
|
|
653
|
+
});
|
|
654
|
+
|
|
655
|
+
function randomStrnig(extraLength = 4, useNumeric = false) {
|
|
656
|
+
const len = Math.max(0, Math.floor(extraLength));
|
|
657
|
+
if (len === 0)
|
|
658
|
+
return '';
|
|
659
|
+
let charset = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
|
660
|
+
if (useNumeric) {
|
|
661
|
+
charset += '0123456789';
|
|
662
|
+
}
|
|
663
|
+
const cryptoObj = typeof globalThis !== 'undefined'
|
|
664
|
+
? globalThis.crypto
|
|
665
|
+
: undefined;
|
|
666
|
+
const out = new Array(len);
|
|
667
|
+
if (cryptoObj?.getRandomValues) {
|
|
668
|
+
const bytes = new Uint8Array(len);
|
|
669
|
+
cryptoObj.getRandomValues(bytes);
|
|
670
|
+
for (let i = 0; i < len; i++) {
|
|
671
|
+
out[i] = charset[bytes[i] % charset.length];
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
else {
|
|
675
|
+
for (let i = 0; i < len; i++) {
|
|
676
|
+
out[i] = charset[Math.floor(Math.random() * charset.length)];
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
return `${Date.now().toString(36)}-${out.join('')}`;
|
|
680
|
+
}
|
|
681
|
+
|
|
651
682
|
class BrowserService {
|
|
652
683
|
platformId;
|
|
653
684
|
constructor(platformId) {
|
|
@@ -674,14 +705,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImpor
|
|
|
674
705
|
args: [PLATFORM_ID]
|
|
675
706
|
}] }] });
|
|
676
707
|
|
|
677
|
-
class
|
|
678
|
-
componentRef;
|
|
708
|
+
class OverlayRef {
|
|
679
709
|
dialogEl;
|
|
680
710
|
teardownFn;
|
|
681
|
-
|
|
682
|
-
|
|
711
|
+
componentRef;
|
|
712
|
+
templateRef;
|
|
713
|
+
constructor(dialogEl, teardownFn, componentRef, templateRef) {
|
|
683
714
|
this.dialogEl = dialogEl;
|
|
684
715
|
this.teardownFn = teardownFn;
|
|
716
|
+
this.componentRef = componentRef;
|
|
717
|
+
this.templateRef = templateRef;
|
|
685
718
|
}
|
|
686
719
|
close() {
|
|
687
720
|
this.teardownFn();
|
|
@@ -691,125 +724,234 @@ class DialogOverlayRef {
|
|
|
691
724
|
}
|
|
692
725
|
}
|
|
693
726
|
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
globalResizeListener;
|
|
702
|
-
globalClickListener;
|
|
727
|
+
const FOCUSABLE_SELECTOR = 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])';
|
|
728
|
+
const DIALOG_OVERLAY_CLASSNAME = 'ngx-ui-overlay';
|
|
729
|
+
class OverlayService {
|
|
730
|
+
overlayStacks = [];
|
|
731
|
+
zIndexCounter = 1000;
|
|
732
|
+
listenersAttached = false;
|
|
733
|
+
resizeRafPending = false;
|
|
703
734
|
doc = inject(DOCUMENT);
|
|
704
|
-
|
|
705
|
-
this.globalKeyDownListener = (e) => {
|
|
706
|
-
if (e.key === 'Escape') {
|
|
707
|
-
const lastDialog = this.getLastDialog();
|
|
708
|
-
if (lastDialog) {
|
|
709
|
-
lastDialog.cleanup();
|
|
710
|
-
}
|
|
711
|
-
}
|
|
712
|
-
};
|
|
713
|
-
this.globalResizeListener = () => {
|
|
714
|
-
this.repositionAll();
|
|
715
|
-
};
|
|
716
|
-
this.globalClickListener = (e) => {
|
|
717
|
-
this.handleClickOnBackdrop(e);
|
|
718
|
-
};
|
|
719
|
-
}
|
|
735
|
+
abortController = new AbortController();
|
|
720
736
|
ngOnDestroy() {
|
|
721
737
|
this.closeAll();
|
|
722
|
-
|
|
723
|
-
handleGlobalListeners() {
|
|
724
|
-
// مطمئن شویم لیسنرها فقط یک بار اضافه شدهاند
|
|
725
|
-
if (!this.globalKeyDownAdded) {
|
|
726
|
-
this.doc.addEventListener('keydown', this.globalKeyDownListener);
|
|
727
|
-
this.globalKeyDownAdded = true;
|
|
728
|
-
}
|
|
729
|
-
if (!this.globalResizeAdded) {
|
|
730
|
-
window.addEventListener('resize', this.globalResizeListener);
|
|
731
|
-
this.globalResizeAdded = true;
|
|
732
|
-
}
|
|
733
|
-
if (!this.globalClickAdded) {
|
|
734
|
-
this.doc.addEventListener('click', this.globalClickListener);
|
|
735
|
-
this.globalClickAdded = true;
|
|
736
|
-
}
|
|
738
|
+
this.abortController.abort();
|
|
737
739
|
}
|
|
738
740
|
open(options) {
|
|
739
|
-
const { anchor, component, viewContainerRef, configure, onClosed } = options;
|
|
741
|
+
const { anchor, point, component, viewContainerRef, configure, onClosed, placement, alignment, margin, } = options;
|
|
740
742
|
if (!viewContainerRef) {
|
|
741
|
-
throw new Error('ViewContainerRef is required to render
|
|
742
|
-
}
|
|
743
|
-
this.
|
|
744
|
-
const
|
|
745
|
-
const dialogElement = this.doc.createElement('dialog');
|
|
746
|
-
dialogElement.style.position = 'absolute';
|
|
747
|
-
dialogElement.style.outline = 'none';
|
|
748
|
-
dialogElement.style.padding = '0';
|
|
749
|
-
dialogElement.style.margin = '0';
|
|
750
|
-
dialogElement.style.border = 'none';
|
|
751
|
-
dialogElement.style.background = 'transparent';
|
|
752
|
-
dialogElement.style.maxWidth = '100vw';
|
|
753
|
-
dialogElement.style.maxHeight = '100vh';
|
|
754
|
-
dialogElement.style.overflow = 'visible';
|
|
755
|
-
dialogElement.style.zIndex = `${1000 + this.openDialogs.size}`;
|
|
756
|
-
this.doc.body.appendChild(dialogElement);
|
|
743
|
+
throw new Error('ViewContainerRef is required to render overlay content.');
|
|
744
|
+
}
|
|
745
|
+
this.attachGlobalListeners();
|
|
746
|
+
const element = this.createDialogElement();
|
|
757
747
|
const componentRef = viewContainerRef.createComponent(component);
|
|
758
748
|
if (componentRef.location.nativeElement) {
|
|
759
|
-
|
|
760
|
-
}
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
this.
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
onClosed?.();
|
|
749
|
+
element.appendChild(componentRef.location.nativeElement);
|
|
750
|
+
}
|
|
751
|
+
const instance = {
|
|
752
|
+
element,
|
|
753
|
+
anchor,
|
|
754
|
+
point,
|
|
755
|
+
placementConfig: this.resolvePlacementConfig(placement, alignment, margin),
|
|
756
|
+
componentRef,
|
|
757
|
+
onClosed,
|
|
758
|
+
rafId: null,
|
|
759
|
+
focusTimeoutId: null,
|
|
760
|
+
cleanup: () => { },
|
|
772
761
|
};
|
|
762
|
+
instance.cleanup = () => this.destroyInstance(instance);
|
|
763
|
+
this.overlayStacks.push(instance);
|
|
764
|
+
element.showModal();
|
|
765
|
+
const ref = new OverlayRef(element, instance.cleanup, componentRef);
|
|
766
|
+
configure?.(componentRef.instance, ref);
|
|
767
|
+
this.scheduleInitialLayout(instance);
|
|
768
|
+
return ref;
|
|
769
|
+
}
|
|
770
|
+
openTemplate(options) {
|
|
771
|
+
const { anchor, point, template, appRef, configure, onClosed, placement, alignment, margin } = options;
|
|
772
|
+
this.attachGlobalListeners();
|
|
773
|
+
const element = this.createDialogElement();
|
|
774
|
+
const view = template.createEmbeddedView({});
|
|
775
|
+
appRef.attachView(view);
|
|
776
|
+
element.append(...view.rootNodes);
|
|
773
777
|
const instance = {
|
|
774
|
-
|
|
778
|
+
element,
|
|
775
779
|
anchor,
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
+
point,
|
|
781
|
+
placementConfig: this.resolvePlacementConfig(placement, alignment, margin),
|
|
782
|
+
embeddedView: view,
|
|
783
|
+
appRef,
|
|
784
|
+
onClosed,
|
|
785
|
+
rafId: null,
|
|
786
|
+
focusTimeoutId: null,
|
|
787
|
+
cleanup: () => { },
|
|
780
788
|
};
|
|
781
|
-
this.
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
789
|
+
instance.cleanup = () => this.destroyInstance(instance);
|
|
790
|
+
this.overlayStacks.push(instance);
|
|
791
|
+
element.showModal();
|
|
792
|
+
const ref = new OverlayRef(element, instance.cleanup, undefined, template);
|
|
793
|
+
configure?.(instance, ref);
|
|
794
|
+
this.scheduleInitialLayout(instance);
|
|
795
|
+
return ref;
|
|
796
|
+
}
|
|
797
|
+
closeAll() {
|
|
798
|
+
// اسنپشات میگیریم چون cleanup حین اجرا آرایهی اصلی رو تغییر میده
|
|
799
|
+
[...this.overlayStacks].forEach((instance) => instance.cleanup());
|
|
800
|
+
}
|
|
801
|
+
// ---------------------------------------------------------------------
|
|
802
|
+
// lifecycle
|
|
803
|
+
// ---------------------------------------------------------------------
|
|
804
|
+
resolvePlacementConfig(placement, alignment, margin) {
|
|
805
|
+
return {
|
|
806
|
+
placement: placement ?? 'auto',
|
|
807
|
+
alignment: alignment ?? 'start',
|
|
808
|
+
margin: margin ?? 8,
|
|
809
|
+
};
|
|
810
|
+
}
|
|
811
|
+
createDialogElement() {
|
|
812
|
+
const element = this.doc.createElement('dialog');
|
|
813
|
+
element.className = DIALOG_OVERLAY_CLASSNAME;
|
|
814
|
+
const style = element.style;
|
|
815
|
+
style.position = 'absolute';
|
|
816
|
+
style.outline = 'none';
|
|
817
|
+
style.padding = '0';
|
|
818
|
+
style.margin = '0';
|
|
819
|
+
style.border = 'none';
|
|
820
|
+
style.background = 'transparent';
|
|
821
|
+
style.maxWidth = '100vw';
|
|
822
|
+
style.maxHeight = '100vh';
|
|
823
|
+
style.overflow = 'visible';
|
|
824
|
+
style.visibility = 'hidden';
|
|
825
|
+
style.animation = 'menu-enter 120ms cubic-bezier(0, 0, 0.2, 1)';
|
|
826
|
+
// شمارندهی صعودی مستقل از تعداد فعلی دیالوگهای باز؛ در نسخهی قبلی
|
|
827
|
+
// با استفاده از openDialogs.size محاسبه میشد که بعد از بستن دیالوگها
|
|
828
|
+
// میتونست باعث تکرار zIndex بین دو دیالوگ بشه.
|
|
829
|
+
style.zIndex = `${++this.zIndexCounter}`;
|
|
830
|
+
this.doc.body.appendChild(element);
|
|
831
|
+
return element;
|
|
832
|
+
}
|
|
833
|
+
scheduleInitialLayout(instance) {
|
|
834
|
+
instance.rafId = requestAnimationFrame(() => {
|
|
835
|
+
instance.rafId = null;
|
|
788
836
|
this.positionDialog(instance);
|
|
789
837
|
});
|
|
790
|
-
setTimeout(() => {
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
}
|
|
838
|
+
instance.focusTimeoutId = setTimeout(() => {
|
|
839
|
+
instance.focusTimeoutId = null;
|
|
840
|
+
const focusable = instance.element.querySelector(FOCUSABLE_SELECTOR);
|
|
841
|
+
focusable?.focus();
|
|
795
842
|
}, 0);
|
|
796
|
-
const ref = new DialogOverlayRef(componentRef, dialogElement, cleanup);
|
|
797
|
-
return ref;
|
|
798
843
|
}
|
|
844
|
+
destroyInstance(instance) {
|
|
845
|
+
const index = this.overlayStacks.indexOf(instance);
|
|
846
|
+
if (index === -1)
|
|
847
|
+
return; // جلوگیری از پاکسازی دوباره
|
|
848
|
+
this.overlayStacks.splice(index, 1);
|
|
849
|
+
// لغو کارهای زمانبندیشدهای که هنوز اجرا نشدن (نشتی حافظه در نسخهی قبلی)
|
|
850
|
+
if (instance.rafId !== null)
|
|
851
|
+
cancelAnimationFrame(instance.rafId);
|
|
852
|
+
if (instance.focusTimeoutId !== null)
|
|
853
|
+
clearTimeout(instance.focusTimeoutId);
|
|
854
|
+
if (instance.componentRef) {
|
|
855
|
+
instance.componentRef.location.nativeElement?.remove();
|
|
856
|
+
instance.componentRef.destroy();
|
|
857
|
+
}
|
|
858
|
+
if (instance.embeddedView && instance.appRef) {
|
|
859
|
+
instance.appRef.detachView(instance.embeddedView);
|
|
860
|
+
instance.embeddedView.destroy();
|
|
861
|
+
}
|
|
862
|
+
instance.element.remove();
|
|
863
|
+
instance.onClosed?.();
|
|
864
|
+
}
|
|
865
|
+
// ---------------------------------------------------------------------
|
|
866
|
+
// global listeners (فقط یکبار در کل عمر سرویس attach میشن)
|
|
867
|
+
// ---------------------------------------------------------------------
|
|
868
|
+
attachGlobalListeners() {
|
|
869
|
+
if (this.listenersAttached)
|
|
870
|
+
return;
|
|
871
|
+
this.listenersAttached = true;
|
|
872
|
+
const { signal } = this.abortController;
|
|
873
|
+
this.doc.addEventListener('keydown', this.onGlobalKeyDown, { signal });
|
|
874
|
+
window.addEventListener('resize', this.onGlobalResize, { signal, passive: true });
|
|
875
|
+
this.doc.addEventListener('click', this.onGlobalPointerEvent, { signal });
|
|
876
|
+
this.doc.addEventListener('contextmenu', this.onGlobalPointerEvent, { signal });
|
|
877
|
+
}
|
|
878
|
+
onGlobalKeyDown = (e) => {
|
|
879
|
+
if (e.key !== 'Escape')
|
|
880
|
+
return;
|
|
881
|
+
this.getLastDialog()?.cleanup();
|
|
882
|
+
};
|
|
883
|
+
onGlobalResize = () => {
|
|
884
|
+
// چند رویداد resize پشتسرهم فقط یک reposition واقعی اجرا میکنن
|
|
885
|
+
if (this.resizeRafPending)
|
|
886
|
+
return;
|
|
887
|
+
this.resizeRafPending = true;
|
|
888
|
+
requestAnimationFrame(() => {
|
|
889
|
+
this.resizeRafPending = false;
|
|
890
|
+
this.repositionAll();
|
|
891
|
+
});
|
|
892
|
+
};
|
|
893
|
+
onGlobalPointerEvent = (e) => {
|
|
894
|
+
this.handleClickOnBackdrop(e);
|
|
895
|
+
};
|
|
896
|
+
handleClickOnBackdrop(event) {
|
|
897
|
+
const lastDialog = this.getLastDialog();
|
|
898
|
+
if (!lastDialog || !lastDialog.element.open)
|
|
899
|
+
return;
|
|
900
|
+
event.preventDefault();
|
|
901
|
+
// کلیک باید دقیقاً روی خودِ دیالوگ (بکدراپ) باشه، نه محتوای داخلش
|
|
902
|
+
if (event.target !== lastDialog.element)
|
|
903
|
+
return;
|
|
904
|
+
// اگه فرم داخل دیالوگه، با کلیک بیرون بسته نشه
|
|
905
|
+
if (lastDialog.element.querySelector('form'))
|
|
906
|
+
return;
|
|
907
|
+
const rect = lastDialog.element.getBoundingClientRect();
|
|
908
|
+
const clickWasInsideDialog = rect.top <= event.clientY &&
|
|
909
|
+
event.clientY <= rect.bottom &&
|
|
910
|
+
rect.left <= event.clientX &&
|
|
911
|
+
event.clientX <= rect.right;
|
|
912
|
+
const anchRect = lastDialog.anchor.getBoundingClientRect();
|
|
913
|
+
const clickWasInsideAnchor = anchRect.top <= event.clientY &&
|
|
914
|
+
event.clientY <= anchRect.bottom &&
|
|
915
|
+
anchRect.left <= event.clientX &&
|
|
916
|
+
event.clientX <= anchRect.right;
|
|
917
|
+
if (!clickWasInsideDialog) {
|
|
918
|
+
if (event.type == 'contextmenu' && lastDialog.point && clickWasInsideAnchor) {
|
|
919
|
+
lastDialog.point = {
|
|
920
|
+
x: event.clientX,
|
|
921
|
+
y: event.clientY,
|
|
922
|
+
};
|
|
923
|
+
this.positionDialog(lastDialog);
|
|
924
|
+
}
|
|
925
|
+
else {
|
|
926
|
+
lastDialog.cleanup();
|
|
927
|
+
}
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
getLastDialog() {
|
|
931
|
+
return this.overlayStacks[this.overlayStacks.length - 1];
|
|
932
|
+
}
|
|
933
|
+
// ---------------------------------------------------------------------
|
|
934
|
+
// positioning
|
|
935
|
+
// ---------------------------------------------------------------------
|
|
799
936
|
repositionAll() {
|
|
800
|
-
|
|
801
|
-
if (instance.
|
|
937
|
+
this.overlayStacks.forEach((instance) => {
|
|
938
|
+
if (instance.element.isConnected) {
|
|
802
939
|
this.positionDialog(instance);
|
|
803
940
|
}
|
|
804
941
|
});
|
|
805
942
|
}
|
|
806
|
-
positionDialog(
|
|
807
|
-
const anchor =
|
|
808
|
-
const
|
|
809
|
-
|
|
810
|
-
if (!anchor || !dialog)
|
|
943
|
+
positionDialog(instance) {
|
|
944
|
+
const { anchor, element: dialog, placementConfig, point } = instance;
|
|
945
|
+
const { placement, alignment, margin } = placementConfig;
|
|
946
|
+
if (!dialog.isConnected)
|
|
811
947
|
return;
|
|
812
|
-
|
|
948
|
+
let anchorRect;
|
|
949
|
+
if (point) {
|
|
950
|
+
anchorRect = new DOMRect(point.x, point.y, 0, 0);
|
|
951
|
+
}
|
|
952
|
+
else {
|
|
953
|
+
anchorRect = anchor.getBoundingClientRect();
|
|
954
|
+
}
|
|
813
955
|
const dialogRect = dialog.getBoundingClientRect();
|
|
814
956
|
const vw = window.innerWidth;
|
|
815
957
|
const vh = window.innerHeight;
|
|
@@ -820,8 +962,8 @@ class DialogService {
|
|
|
820
962
|
const spaceBelow = vh - anchorRect.bottom;
|
|
821
963
|
const spaceAbove = anchorRect.top;
|
|
822
964
|
let verticalPos = 'above';
|
|
823
|
-
|
|
824
|
-
|
|
965
|
+
if (placement === 'bottom' ||
|
|
966
|
+
(placement === 'auto' && spaceBelow >= dialogRect.height + margin)) {
|
|
825
967
|
top = anchorRect.bottom + margin;
|
|
826
968
|
verticalPos = 'above';
|
|
827
969
|
if (top + dialogRect.height > vh - margin) {
|
|
@@ -837,13 +979,11 @@ class DialogService {
|
|
|
837
979
|
verticalPos = 'above';
|
|
838
980
|
}
|
|
839
981
|
}
|
|
840
|
-
// horizontal position
|
|
841
982
|
if (alignment === 'center') {
|
|
842
983
|
left = anchorRect.left + anchorRect.width / 2 - dialogRect.width / 2;
|
|
843
984
|
}
|
|
844
985
|
else if (alignment === 'start') {
|
|
845
986
|
if (isRTL) {
|
|
846
|
-
left = 'auto';
|
|
847
987
|
right = vw - anchorRect.right;
|
|
848
988
|
}
|
|
849
989
|
else {
|
|
@@ -851,65 +991,30 @@ class DialogService {
|
|
|
851
991
|
}
|
|
852
992
|
}
|
|
853
993
|
else {
|
|
854
|
-
|
|
855
|
-
left = isRTL ? anchorRect.left : anchorRect.right - dialogRect.width;
|
|
856
|
-
}
|
|
857
|
-
if (left != 'auto' && left < margin) {
|
|
858
|
-
left = margin;
|
|
994
|
+
left = isRTL ? anchorRect.left : anchorRect.right; //- dialogRect.width;
|
|
859
995
|
}
|
|
860
|
-
if (left
|
|
861
|
-
left = vw - dialogRect.width - margin;
|
|
862
|
-
}
|
|
863
|
-
dialog.className = `tips-${verticalPos}`;
|
|
864
|
-
dialog.style.top = `${top}px`;
|
|
865
|
-
dialog.style.left = left != 'auto' ? `${left}px` : left;
|
|
866
|
-
dialog.style.right = right != 'auto' ? `${right}px` : right;
|
|
867
|
-
dialog.style.transform = 'none';
|
|
868
|
-
}
|
|
869
|
-
getLastDialog() {
|
|
870
|
-
if (this.openDialogs.size === 0)
|
|
871
|
-
return undefined;
|
|
872
|
-
const lastKey = Array.from(this.openDialogs.keys()).pop();
|
|
873
|
-
return lastKey ? this.openDialogs.get(lastKey) : undefined;
|
|
874
|
-
}
|
|
875
|
-
closeAll() {
|
|
876
|
-
const ids = Array.from(this.openDialogs.keys());
|
|
877
|
-
ids.forEach((id) => {
|
|
878
|
-
const instance = this.openDialogs.get(id);
|
|
879
|
-
instance?.cleanup();
|
|
880
|
-
});
|
|
881
|
-
}
|
|
882
|
-
handleClickOnBackdrop(event) {
|
|
883
|
-
const target = event.target;
|
|
884
|
-
const lastDialog = this.getLastDialog();
|
|
885
|
-
if (!lastDialog)
|
|
886
|
-
return;
|
|
887
|
-
// The click target _must_ be the dialog element itself, and not elements underneath or inside.
|
|
888
|
-
if (target !== lastDialog.element || !lastDialog.element?.open)
|
|
889
|
-
return;
|
|
890
|
-
// If the dialog contains a form, do not close the dialog when clicking outside of the dialog
|
|
891
|
-
if (lastDialog.element.querySelector('form'))
|
|
892
|
-
return;
|
|
893
|
-
const rect = lastDialog.element.getBoundingClientRect();
|
|
894
|
-
const clickWasInsideDialog = rect.top <= event.clientY &&
|
|
895
|
-
event.clientY <= rect.top + rect.height &&
|
|
896
|
-
rect.left <= event.clientX &&
|
|
897
|
-
event.clientX <= rect.left + rect.width;
|
|
898
|
-
if (!clickWasInsideDialog) {
|
|
899
|
-
lastDialog.cleanup();
|
|
996
|
+
if (left !== 'auto') {
|
|
997
|
+
left = Math.min(Math.max(left, margin), vw - dialogRect.width - margin);
|
|
900
998
|
}
|
|
999
|
+
dialog.className = `${DIALOG_OVERLAY_CLASSNAME} tips-${verticalPos}`;
|
|
1000
|
+
dialog.style.top = `${top + window.scrollY}px`;
|
|
1001
|
+
dialog.style.left = left !== 'auto' ? `${left + window.scrollX}px` : 'auto';
|
|
1002
|
+
dialog.style.right = right !== 'auto' ? `${right + window.scrollX}px` : 'auto';
|
|
1003
|
+
dialog.style.transformOrigin = verticalPos == 'above' ? 'left top' : 'left bottom';
|
|
1004
|
+
// dialog.style.transform = 'none';
|
|
1005
|
+
dialog.style.visibility = 'visible';
|
|
901
1006
|
}
|
|
902
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type:
|
|
903
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type:
|
|
1007
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: OverlayService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
1008
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: OverlayService, providedIn: 'root' });
|
|
904
1009
|
}
|
|
905
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type:
|
|
1010
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.4", ngImport: i0, type: OverlayService, decorators: [{
|
|
906
1011
|
type: Injectable,
|
|
907
1012
|
args: [{ providedIn: 'root' }]
|
|
908
|
-
}]
|
|
1013
|
+
}] });
|
|
909
1014
|
|
|
910
1015
|
/**
|
|
911
1016
|
* Generated bundle index. Do not edit.
|
|
912
1017
|
*/
|
|
913
1018
|
|
|
914
|
-
export { BrowserService,
|
|
915
|
-
//# sourceMappingURL=ngx-
|
|
1019
|
+
export { BrowserService, DIALOG_OVERLAY_CLASSNAME, FOCUSABLE_SELECTOR, OverlayRef, OverlayService, RangeSliderComponent, SaturationComponent, SliderComponent, ValueModel, WINDOW, getOffsetPosition, randomStrnig };
|
|
1020
|
+
//# sourceMappingURL=ngx-kit-shared.mjs.map
|