@acorex/cdk 22.2.8 → 22.2.10
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/fesm2022/acorex-cdk-carousel.mjs +22 -4
- package/fesm2022/acorex-cdk-carousel.mjs.map +1 -1
- package/fesm2022/acorex-cdk-full-screen.mjs +24 -145
- package/fesm2022/acorex-cdk-full-screen.mjs.map +1 -1
- package/fesm2022/acorex-cdk-gesture.mjs +28 -2
- package/fesm2022/acorex-cdk-gesture.mjs.map +1 -1
- package/package.json +2 -6
- package/types/acorex-cdk-carousel.d.ts +2 -0
- package/types/acorex-cdk-full-screen.d.ts +18 -43
- package/types/acorex-cdk-gesture.d.ts +11 -1
- package/fesm2022/acorex-cdk-double-click.mjs +0 -178
- package/fesm2022/acorex-cdk-double-click.mjs.map +0 -1
- package/types/acorex-cdk-double-click.d.ts +0 -66
|
@@ -6,15 +6,24 @@ class AXCarouselDirective {
|
|
|
6
6
|
constructor() {
|
|
7
7
|
this.carousel = signal(null, /* @ts-ignore */
|
|
8
8
|
...(ngDevMode ? [{ debugName: "carousel" }] : /* istanbul ignore next */ []));
|
|
9
|
-
// carouselOptions = input<AXCarouselOptions>();
|
|
10
9
|
this.el = inject(ElementRef);
|
|
11
10
|
this.platformId = inject(PLATFORM_ID);
|
|
11
|
+
this.initId = 0;
|
|
12
|
+
}
|
|
13
|
+
destroy() {
|
|
14
|
+
const instance = this.carousel();
|
|
15
|
+
if (!instance)
|
|
16
|
+
return;
|
|
17
|
+
this.carousel.set(null);
|
|
18
|
+
if (instance.destroyed)
|
|
19
|
+
return;
|
|
20
|
+
instance.destroy(true, true);
|
|
12
21
|
}
|
|
13
22
|
async init(option) {
|
|
14
23
|
if (!isPlatformBrowser(this.platformId))
|
|
15
24
|
return;
|
|
16
|
-
|
|
17
|
-
|
|
25
|
+
const id = ++this.initId;
|
|
26
|
+
this.destroy();
|
|
18
27
|
const parentElem = this.el.nativeElement;
|
|
19
28
|
const slides = parentElem.querySelectorAll('.ax-carousel-slide');
|
|
20
29
|
parentElem.querySelector('.ax-carousel-wrapper')?.classList.add('swiper-wrapper');
|
|
@@ -28,7 +37,12 @@ class AXCarouselDirective {
|
|
|
28
37
|
item.classList.add('swiper-slide');
|
|
29
38
|
});
|
|
30
39
|
const { A11y, Autoplay, Controller, EffectCoverflow, EffectCube, EffectFade, EffectFlip, EffectCreative, EffectCards, HashNavigation, History, Keyboard, Mousewheel, Navigation, Pagination, Parallax, Scrollbar, Thumbs, Virtual, Zoom, FreeMode, Grid, Manipulation, } = await import('swiper/modules');
|
|
31
|
-
|
|
40
|
+
if (id !== this.initId)
|
|
41
|
+
return;
|
|
42
|
+
const SwiperCtor = (await import('swiper')).Swiper;
|
|
43
|
+
if (id !== this.initId)
|
|
44
|
+
return;
|
|
45
|
+
const res = new SwiperCtor(parentElem, {
|
|
32
46
|
...option,
|
|
33
47
|
modules: [
|
|
34
48
|
A11y,
|
|
@@ -56,6 +70,10 @@ class AXCarouselDirective {
|
|
|
56
70
|
Manipulation,
|
|
57
71
|
],
|
|
58
72
|
});
|
|
73
|
+
if (id !== this.initId) {
|
|
74
|
+
res.destroy(true, true);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
59
77
|
this.carousel.set(res);
|
|
60
78
|
}
|
|
61
79
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXCarouselDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"acorex-cdk-carousel.mjs","sources":["../../../../packages/cdk/carousel/src/carousel.directive.ts","../../../../packages/cdk/carousel/src/acorex-cdk-carousel.ts"],"sourcesContent":["import { isPlatformBrowser } from '@angular/common';\nimport { Directive, ElementRef, inject, PLATFORM_ID, signal } from '@angular/core';\nimport type { Swiper, SwiperOptions } from 'swiper/types';\n\nexport type AXCarousel = Swiper;\nexport type AXCarouselOptions = SwiperOptions;\n\n@Directive({\n selector: '[axCarousel]',\n exportAs: 'axCarousel',\n})\nexport class AXCarouselDirective {\n carousel = signal<AXCarousel>(null);\n
|
|
1
|
+
{"version":3,"file":"acorex-cdk-carousel.mjs","sources":["../../../../packages/cdk/carousel/src/carousel.directive.ts","../../../../packages/cdk/carousel/src/acorex-cdk-carousel.ts"],"sourcesContent":["import { isPlatformBrowser } from '@angular/common';\nimport { Directive, ElementRef, inject, PLATFORM_ID, signal } from '@angular/core';\nimport type { Swiper, SwiperOptions } from 'swiper/types';\n\nexport type AXCarousel = Swiper;\nexport type AXCarouselOptions = SwiperOptions;\n\n@Directive({\n selector: '[axCarousel]',\n exportAs: 'axCarousel',\n})\nexport class AXCarouselDirective {\n carousel = signal<AXCarousel>(null);\n private el = inject(ElementRef);\n private platformId = inject(PLATFORM_ID);\n private initId = 0;\n\n destroy(): void {\n const instance = this.carousel();\n if (!instance) return;\n this.carousel.set(null);\n if (instance.destroyed) return;\n instance.destroy(true, true);\n }\n\n async init(option: AXCarouselOptions) {\n if (!isPlatformBrowser(this.platformId)) return;\n const id = ++this.initId;\n this.destroy();\n const parentElem = this.el.nativeElement as HTMLElement;\n const slides = parentElem.querySelectorAll('.ax-carousel-slide');\n\n parentElem.querySelector('.ax-carousel-wrapper')?.classList.add('swiper-wrapper');\n parentElem.querySelector('.ax-carousel-pagination')?.classList.add('swiper-pagination');\n parentElem.querySelector('.ax-carousel-scrollbar')?.classList.add('swiper-scrollbar');\n parentElem.querySelector('.ax-carousel-button-prev')?.classList.add('swiper-button-prev');\n parentElem.querySelector('.ax-carousel-button-next')?.classList.add('swiper-button-next');\n\n slides?.forEach((item) => {\n if (item.classList.contains('swiper-slide')) return;\n item.classList.add('swiper-slide');\n });\n\n const {\n A11y,\n Autoplay,\n Controller,\n EffectCoverflow,\n EffectCube,\n EffectFade,\n EffectFlip,\n EffectCreative,\n EffectCards,\n HashNavigation,\n History,\n Keyboard,\n Mousewheel,\n Navigation,\n Pagination,\n Parallax,\n Scrollbar,\n Thumbs,\n Virtual,\n Zoom,\n FreeMode,\n Grid,\n Manipulation,\n } = await import('swiper/modules');\n\n if (id !== this.initId) return;\n\n const SwiperCtor = (await import('swiper')).Swiper;\n if (id !== this.initId) return;\n\n const res = new SwiperCtor(parentElem, {\n ...option,\n modules: [\n A11y,\n Autoplay,\n Controller,\n EffectCoverflow,\n EffectCube,\n EffectFade,\n EffectFlip,\n EffectCreative,\n EffectCards,\n HashNavigation,\n History,\n Keyboard,\n Mousewheel,\n Navigation,\n Pagination,\n Parallax,\n Scrollbar,\n Thumbs,\n Virtual,\n Zoom,\n FreeMode,\n Grid,\n Manipulation,\n ],\n });\n\n if (id !== this.initId) {\n res.destroy(true, true);\n return;\n }\n\n this.carousel.set(res);\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -1,193 +1,72 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AXFullScreenService } from '@acorex/core/full-screen';
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
|
-
import {
|
|
3
|
+
import { input, output, inject, ElementRef, effect, untracked, Directive } from '@angular/core';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* Fullscreen directive
|
|
6
|
+
* Fullscreen directive with overlay and browser modes.
|
|
7
7
|
* Usage: <element axFullscreen #fullscreen="axFullscreen"></element>
|
|
8
8
|
* Then: fullscreen.toggle() or fullscreen.enter() or fullscreen.exit()
|
|
9
9
|
*/
|
|
10
10
|
class AXFullScreenDirective {
|
|
11
11
|
constructor() {
|
|
12
12
|
/**
|
|
13
|
-
*
|
|
13
|
+
* Fullscreen implementation mode.
|
|
14
|
+
* @defaultValue 'overlay'
|
|
14
15
|
*/
|
|
15
|
-
this.
|
|
16
|
-
...(ngDevMode ? [{ debugName: "
|
|
16
|
+
this.mode = input('overlay', /* @ts-ignore */
|
|
17
|
+
...(ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []));
|
|
17
18
|
/**
|
|
18
|
-
*
|
|
19
|
-
*/
|
|
20
|
-
this.originalStyles = {};
|
|
21
|
-
/**
|
|
22
|
-
* Original parent element reference
|
|
23
|
-
*/
|
|
24
|
-
this.originalParent = null;
|
|
25
|
-
/**
|
|
26
|
-
* Fullscreen container element
|
|
27
|
-
*/
|
|
28
|
-
this.fullscreenContainer = null;
|
|
29
|
-
/**
|
|
30
|
-
* Fullscreen change event
|
|
19
|
+
* Fullscreen change event for this host element.
|
|
31
20
|
*/
|
|
32
21
|
this.fullscreenChange = output();
|
|
33
|
-
/**
|
|
34
|
-
* Z-index token for this fullscreen instance
|
|
35
|
-
*/
|
|
36
|
-
this.zToken = null;
|
|
37
|
-
this.renderer = inject(Renderer2);
|
|
38
22
|
this.elementRef = inject(ElementRef);
|
|
39
|
-
this.
|
|
40
|
-
// Sync state changes to output
|
|
23
|
+
this.fullScreenService = inject(AXFullScreenService);
|
|
41
24
|
effect(() => {
|
|
42
|
-
const
|
|
25
|
+
const isActive = this.fullScreenService.isActive(this.elementRef.nativeElement);
|
|
43
26
|
untracked(() => {
|
|
44
|
-
this.fullscreenChange.emit(
|
|
27
|
+
this.fullscreenChange.emit(isActive);
|
|
45
28
|
});
|
|
46
29
|
});
|
|
47
30
|
}
|
|
48
31
|
/**
|
|
49
|
-
* Toggle fullscreen state
|
|
32
|
+
* Toggle fullscreen state.
|
|
50
33
|
*/
|
|
51
34
|
toggle() {
|
|
52
|
-
|
|
53
|
-
this.exit();
|
|
54
|
-
}
|
|
55
|
-
else {
|
|
56
|
-
this.enter();
|
|
57
|
-
}
|
|
35
|
+
this.fullScreenService.toggle(this.elementRef.nativeElement, this.mode());
|
|
58
36
|
}
|
|
59
37
|
/**
|
|
60
|
-
* Enter fullscreen mode
|
|
38
|
+
* Enter fullscreen mode.
|
|
61
39
|
*/
|
|
62
40
|
enter() {
|
|
63
|
-
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
const element = this.elementRef.nativeElement;
|
|
67
|
-
try {
|
|
68
|
-
// Store original styles and parent
|
|
69
|
-
this.storeOriginalStyles(element);
|
|
70
|
-
this.originalParent = element.parentElement;
|
|
71
|
-
// Acquire z-index token
|
|
72
|
-
this.zToken = this.zIndexService.acquire();
|
|
73
|
-
// Create fullscreen container
|
|
74
|
-
this.fullscreenContainer = this.renderer.createElement('div');
|
|
75
|
-
this.renderer.setStyle(this.fullscreenContainer, 'position', 'fixed');
|
|
76
|
-
this.renderer.setStyle(this.fullscreenContainer, 'top', '0');
|
|
77
|
-
this.renderer.setStyle(this.fullscreenContainer, 'left', '0');
|
|
78
|
-
this.renderer.setStyle(this.fullscreenContainer, 'width', '100vw');
|
|
79
|
-
this.renderer.setStyle(this.fullscreenContainer, 'height', '100vh');
|
|
80
|
-
this.renderer.setStyle(this.fullscreenContainer, 'z-index', String(this.zToken.zIndex));
|
|
81
|
-
this.renderer.setStyle(this.fullscreenContainer, 'background-color', '#ffffff');
|
|
82
|
-
this.renderer.setStyle(this.fullscreenContainer, 'overflow', 'auto');
|
|
83
|
-
// Move element to container
|
|
84
|
-
this.renderer.appendChild(this.fullscreenContainer, element);
|
|
85
|
-
// Apply fullscreen styles to element
|
|
86
|
-
this.renderer.setStyle(element, 'position', 'relative');
|
|
87
|
-
this.renderer.setStyle(element, 'width', '100%');
|
|
88
|
-
this.renderer.setStyle(element, 'height', '100%');
|
|
89
|
-
this.renderer.setStyle(element, 'margin', '0');
|
|
90
|
-
this.renderer.setStyle(element, 'padding', '0');
|
|
91
|
-
// Append container to body
|
|
92
|
-
this.renderer.appendChild(document.body, this.fullscreenContainer);
|
|
93
|
-
// Prevent body scroll
|
|
94
|
-
this.renderer.setStyle(document.body, 'overflow', 'hidden');
|
|
95
|
-
this.isFullscreenState.set(true);
|
|
96
|
-
}
|
|
97
|
-
catch (error) {
|
|
98
|
-
console.error('Error entering fullscreen:', error);
|
|
99
|
-
this.restoreOriginalStyles(element);
|
|
100
|
-
}
|
|
41
|
+
this.fullScreenService.enter(this.elementRef.nativeElement, this.mode());
|
|
101
42
|
}
|
|
102
43
|
/**
|
|
103
|
-
* Exit fullscreen mode
|
|
44
|
+
* Exit fullscreen mode.
|
|
104
45
|
*/
|
|
105
46
|
exit() {
|
|
106
|
-
|
|
107
|
-
return;
|
|
108
|
-
}
|
|
109
|
-
const element = this.elementRef.nativeElement;
|
|
110
|
-
try {
|
|
111
|
-
// Restore body scroll
|
|
112
|
-
this.renderer.removeStyle(document.body, 'overflow');
|
|
113
|
-
// Move element back to original parent
|
|
114
|
-
if (this.fullscreenContainer && this.originalParent) {
|
|
115
|
-
this.renderer.removeChild(this.fullscreenContainer, element);
|
|
116
|
-
this.renderer.appendChild(this.originalParent, element);
|
|
117
|
-
// Remove container
|
|
118
|
-
this.renderer.removeChild(document.body, this.fullscreenContainer);
|
|
119
|
-
this.fullscreenContainer = null;
|
|
120
|
-
}
|
|
121
|
-
// Release z-index token
|
|
122
|
-
this.zIndexService.release(this.zToken);
|
|
123
|
-
this.zToken = null;
|
|
124
|
-
// Restore original styles
|
|
125
|
-
this.restoreOriginalStyles(element);
|
|
126
|
-
this.isFullscreenState.set(false);
|
|
127
|
-
}
|
|
128
|
-
catch (error) {
|
|
129
|
-
console.error('Error exiting fullscreen:', error);
|
|
130
|
-
}
|
|
47
|
+
this.fullScreenService.exit(this.elementRef.nativeElement);
|
|
131
48
|
}
|
|
132
49
|
/**
|
|
133
|
-
* Check if currently in fullscreen mode
|
|
50
|
+
* Check if this host is currently in fullscreen mode.
|
|
134
51
|
*/
|
|
135
52
|
isFullscreen() {
|
|
136
|
-
return this.
|
|
137
|
-
}
|
|
138
|
-
/**
|
|
139
|
-
* Store original element styles
|
|
140
|
-
*/
|
|
141
|
-
storeOriginalStyles(element) {
|
|
142
|
-
const computedStyle = window.getComputedStyle(element);
|
|
143
|
-
this.originalStyles = {
|
|
144
|
-
position: computedStyle.position,
|
|
145
|
-
top: computedStyle.top,
|
|
146
|
-
left: computedStyle.left,
|
|
147
|
-
width: computedStyle.width,
|
|
148
|
-
height: computedStyle.height,
|
|
149
|
-
zIndex: computedStyle.zIndex,
|
|
150
|
-
backgroundColor: computedStyle.backgroundColor,
|
|
151
|
-
margin: computedStyle.margin,
|
|
152
|
-
padding: computedStyle.padding,
|
|
153
|
-
};
|
|
53
|
+
return this.fullScreenService.isActive(this.elementRef.nativeElement);
|
|
154
54
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
restoreOriginalStyles(element) {
|
|
159
|
-
if (!this.originalStyles) {
|
|
160
|
-
return;
|
|
55
|
+
ngOnDestroy() {
|
|
56
|
+
if (this.fullScreenService.isActive(this.elementRef.nativeElement)) {
|
|
57
|
+
this.fullScreenService.exit(this.elementRef.nativeElement);
|
|
161
58
|
}
|
|
162
|
-
// Restore each style property
|
|
163
|
-
Object.entries(this.originalStyles).forEach(([key, value]) => {
|
|
164
|
-
const styleKey = this.camelToKebabCase(key);
|
|
165
|
-
if (value) {
|
|
166
|
-
this.renderer.setStyle(element, styleKey, value);
|
|
167
|
-
}
|
|
168
|
-
else {
|
|
169
|
-
this.renderer.removeStyle(element, styleKey);
|
|
170
|
-
}
|
|
171
|
-
});
|
|
172
|
-
this.originalStyles = {};
|
|
173
|
-
}
|
|
174
|
-
/**
|
|
175
|
-
* Convert camelCase to kebab-case for CSS properties
|
|
176
|
-
*/
|
|
177
|
-
camelToKebabCase(str) {
|
|
178
|
-
return str.replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g, '$1-$2').toLowerCase();
|
|
179
59
|
}
|
|
180
60
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXFullScreenDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
181
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "
|
|
61
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.8", type: AXFullScreenDirective, isStandalone: true, selector: "[axFullscreen]", inputs: { mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { fullscreenChange: "fullscreenChange" }, exportAs: ["axFullscreen"], ngImport: i0 }); }
|
|
182
62
|
}
|
|
183
63
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXFullScreenDirective, decorators: [{
|
|
184
64
|
type: Directive,
|
|
185
65
|
args: [{
|
|
186
66
|
selector: '[axFullscreen]',
|
|
187
|
-
standalone: true,
|
|
188
67
|
exportAs: 'axFullscreen',
|
|
189
68
|
}]
|
|
190
|
-
}], ctorParameters: () => [], propDecorators: { fullscreenChange: [{ type: i0.Output, args: ["fullscreenChange"] }] } });
|
|
69
|
+
}], ctorParameters: () => [], propDecorators: { mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], fullscreenChange: [{ type: i0.Output, args: ["fullscreenChange"] }] } });
|
|
191
70
|
|
|
192
71
|
/**
|
|
193
72
|
* Generated bundle index. Do not edit.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"acorex-cdk-full-screen.mjs","sources":["../../../../packages/cdk/full-screen/src/lib/full-screen.directive.ts","../../../../packages/cdk/full-screen/src/acorex-cdk-full-screen.ts"],"sourcesContent":["import { AXZIndexService, AXZToken } from '@acorex/core/z-index';\nimport { Directive, effect, ElementRef, inject, output, Renderer2, signal, untracked } from '@angular/core';\n\n/**\n * Fullscreen directive that provides CSS-based fullscreen functionality\n * Usage: <element axFullscreen #fullscreen=\"axFullscreen\"></element>\n * Then: fullscreen.toggle() or fullscreen.enter() or fullscreen.exit()\n */\n@Directive({\n selector: '[axFullscreen]',\n standalone: true,\n exportAs: 'axFullscreen',\n})\nexport class AXFullScreenDirective {\n /**\n * Current fullscreen state\n */\n private readonly isFullscreenState = signal<boolean>(false);\n\n /**\n * Original element styles to restore\n */\n private originalStyles: {\n position?: string;\n top?: string;\n left?: string;\n width?: string;\n height?: string;\n zIndex?: string;\n backgroundColor?: string;\n margin?: string;\n padding?: string;\n } = {};\n\n /**\n * Original parent element reference\n */\n private originalParent: HTMLElement | null = null;\n\n /**\n * Fullscreen container element\n */\n private fullscreenContainer: HTMLElement | null = null;\n\n /**\n * Fullscreen change event\n */\n readonly fullscreenChange = output<boolean>();\n\n /**\n * Z-index token for this fullscreen instance\n */\n private zToken: AXZToken | null = null;\n\n private readonly renderer = inject(Renderer2);\n private readonly elementRef = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly zIndexService = inject(AXZIndexService);\n\n constructor() {\n // Sync state changes to output\n effect(() => {\n const isFullscreen = this.isFullscreenState();\n untracked(() => {\n this.fullscreenChange.emit(isFullscreen);\n });\n });\n }\n\n /**\n * Toggle fullscreen state\n */\n toggle(): void {\n if (this.isFullscreenState()) {\n this.exit();\n } else {\n this.enter();\n }\n }\n\n /**\n * Enter fullscreen mode using CSS\n */\n enter(): void {\n if (this.isFullscreenState()) {\n return;\n }\n\n const element = this.elementRef.nativeElement;\n\n try {\n // Store original styles and parent\n this.storeOriginalStyles(element);\n this.originalParent = element.parentElement;\n\n // Acquire z-index token\n this.zToken = this.zIndexService.acquire();\n\n // Create fullscreen container\n this.fullscreenContainer = this.renderer.createElement('div');\n this.renderer.setStyle(this.fullscreenContainer, 'position', 'fixed');\n this.renderer.setStyle(this.fullscreenContainer, 'top', '0');\n this.renderer.setStyle(this.fullscreenContainer, 'left', '0');\n this.renderer.setStyle(this.fullscreenContainer, 'width', '100vw');\n this.renderer.setStyle(this.fullscreenContainer, 'height', '100vh');\n this.renderer.setStyle(this.fullscreenContainer, 'z-index', String(this.zToken.zIndex));\n this.renderer.setStyle(this.fullscreenContainer, 'background-color', '#ffffff');\n this.renderer.setStyle(this.fullscreenContainer, 'overflow', 'auto');\n\n // Move element to container\n this.renderer.appendChild(this.fullscreenContainer, element);\n\n // Apply fullscreen styles to element\n this.renderer.setStyle(element, 'position', 'relative');\n this.renderer.setStyle(element, 'width', '100%');\n this.renderer.setStyle(element, 'height', '100%');\n this.renderer.setStyle(element, 'margin', '0');\n this.renderer.setStyle(element, 'padding', '0');\n\n // Append container to body\n this.renderer.appendChild(document.body, this.fullscreenContainer);\n\n // Prevent body scroll\n this.renderer.setStyle(document.body, 'overflow', 'hidden');\n\n this.isFullscreenState.set(true);\n } catch (error) {\n console.error('Error entering fullscreen:', error);\n this.restoreOriginalStyles(element);\n }\n }\n\n /**\n * Exit fullscreen mode\n */\n exit(): void {\n if (!this.isFullscreenState()) {\n return;\n }\n\n const element = this.elementRef.nativeElement;\n\n try {\n // Restore body scroll\n this.renderer.removeStyle(document.body, 'overflow');\n\n // Move element back to original parent\n if (this.fullscreenContainer && this.originalParent) {\n this.renderer.removeChild(this.fullscreenContainer, element);\n this.renderer.appendChild(this.originalParent, element);\n\n // Remove container\n this.renderer.removeChild(document.body, this.fullscreenContainer);\n this.fullscreenContainer = null;\n }\n\n // Release z-index token\n this.zIndexService.release(this.zToken);\n this.zToken = null;\n\n // Restore original styles\n this.restoreOriginalStyles(element);\n\n this.isFullscreenState.set(false);\n } catch (error) {\n console.error('Error exiting fullscreen:', error);\n }\n }\n\n /**\n * Check if currently in fullscreen mode\n */\n isFullscreen(): boolean {\n return this.isFullscreenState();\n }\n\n /**\n * Store original element styles\n */\n private storeOriginalStyles(element: HTMLElement): void {\n const computedStyle = window.getComputedStyle(element);\n this.originalStyles = {\n position: computedStyle.position,\n top: computedStyle.top,\n left: computedStyle.left,\n width: computedStyle.width,\n height: computedStyle.height,\n zIndex: computedStyle.zIndex,\n backgroundColor: computedStyle.backgroundColor,\n margin: computedStyle.margin,\n padding: computedStyle.padding,\n };\n }\n\n /**\n * Restore original element styles\n */\n private restoreOriginalStyles(element: HTMLElement): void {\n if (!this.originalStyles) {\n return;\n }\n\n // Restore each style property\n Object.entries(this.originalStyles).forEach(([key, value]) => {\n const styleKey = this.camelToKebabCase(key);\n if (value) {\n this.renderer.setStyle(element, styleKey, value);\n } else {\n this.renderer.removeStyle(element, styleKey);\n }\n });\n\n this.originalStyles = {};\n }\n\n /**\n * Convert camelCase to kebab-case for CSS properties\n */\n private camelToKebabCase(str: string): string {\n return str.replace(/([a-z0-9]|(?=[A-Z]))([A-Z])/g, '$1-$2').toLowerCase();\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;AAGA;;;;AAIG;MAMU,qBAAqB,CAAA;AA6ChC,IAAA,WAAA,GAAA;AA5CA;;AAEG;QACc,IAAA,CAAA,iBAAiB,GAAG,MAAM,CAAU,KAAK;8FAAC;AAE3D;;AAEG;QACK,IAAA,CAAA,cAAc,GAUlB,EAAE;AAEN;;AAEG;QACK,IAAA,CAAA,cAAc,GAAuB,IAAI;AAEjD;;AAEG;QACK,IAAA,CAAA,mBAAmB,GAAuB,IAAI;AAEtD;;AAEG;QACM,IAAA,CAAA,gBAAgB,GAAG,MAAM,EAAW;AAE7C;;AAEG;QACK,IAAA,CAAA,MAAM,GAAoB,IAAI;AAErB,QAAA,IAAA,CAAA,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC;AAC5B,QAAA,IAAA,CAAA,UAAU,GAAG,MAAM,CAA0B,UAAU,CAAC;AACxD,QAAA,IAAA,CAAA,aAAa,GAAG,MAAM,CAAC,eAAe,CAAC;;QAItD,MAAM,CAAC,MAAK;AACV,YAAA,MAAM,YAAY,GAAG,IAAI,CAAC,iBAAiB,EAAE;YAC7C,SAAS,CAAC,MAAK;AACb,gBAAA,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,YAAY,CAAC;AAC1C,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC,CAAC;IACJ;AAEA;;AAEG;IACH,MAAM,GAAA;AACJ,QAAA,IAAI,IAAI,CAAC,iBAAiB,EAAE,EAAE;YAC5B,IAAI,CAAC,IAAI,EAAE;QACb;aAAO;YACL,IAAI,CAAC,KAAK,EAAE;QACd;IACF;AAEA;;AAEG;IACH,KAAK,GAAA;AACH,QAAA,IAAI,IAAI,CAAC,iBAAiB,EAAE,EAAE;YAC5B;QACF;AAEA,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa;AAE7C,QAAA,IAAI;;AAEF,YAAA,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC;AACjC,YAAA,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,aAAa;;YAG3C,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE;;YAG1C,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC;AAC7D,YAAA,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,mBAAmB,EAAE,UAAU,EAAE,OAAO,CAAC;AACrE,YAAA,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,mBAAmB,EAAE,KAAK,EAAE,GAAG,CAAC;AAC5D,YAAA,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,mBAAmB,EAAE,MAAM,EAAE,GAAG,CAAC;AAC7D,YAAA,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,mBAAmB,EAAE,OAAO,EAAE,OAAO,CAAC;AAClE,YAAA,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,mBAAmB,EAAE,QAAQ,EAAE,OAAO,CAAC;YACnE,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,mBAAmB,EAAE,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AACvF,YAAA,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,mBAAmB,EAAE,kBAAkB,EAAE,SAAS,CAAC;AAC/E,YAAA,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,mBAAmB,EAAE,UAAU,EAAE,MAAM,CAAC;;YAGpE,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,mBAAmB,EAAE,OAAO,CAAC;;YAG5D,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,EAAE,UAAU,EAAE,UAAU,CAAC;YACvD,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC;YAChD,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC;YACjD,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,CAAC;YAC9C,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,CAAC;;AAG/C,YAAA,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,mBAAmB,CAAC;;AAGlE,YAAA,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,CAAC;AAE3D,YAAA,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC;QAClC;QAAE,OAAO,KAAK,EAAE;AACd,YAAA,OAAO,CAAC,KAAK,CAAC,4BAA4B,EAAE,KAAK,CAAC;AAClD,YAAA,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC;QACrC;IACF;AAEA;;AAEG;IACH,IAAI,GAAA;AACF,QAAA,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE;YAC7B;QACF;AAEA,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa;AAE7C,QAAA,IAAI;;YAEF,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;;YAGpD,IAAI,IAAI,CAAC,mBAAmB,IAAI,IAAI,CAAC,cAAc,EAAE;gBACnD,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,mBAAmB,EAAE,OAAO,CAAC;gBAC5D,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,cAAc,EAAE,OAAO,CAAC;;AAGvD,gBAAA,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,mBAAmB,CAAC;AAClE,gBAAA,IAAI,CAAC,mBAAmB,GAAG,IAAI;YACjC;;YAGA,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;AACvC,YAAA,IAAI,CAAC,MAAM,GAAG,IAAI;;AAGlB,YAAA,IAAI,CAAC,qBAAqB,CAAC,OAAO,CAAC;AAEnC,YAAA,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC;QACnC;QAAE,OAAO,KAAK,EAAE;AACd,YAAA,OAAO,CAAC,KAAK,CAAC,2BAA2B,EAAE,KAAK,CAAC;QACnD;IACF;AAEA;;AAEG;IACH,YAAY,GAAA;AACV,QAAA,OAAO,IAAI,CAAC,iBAAiB,EAAE;IACjC;AAEA;;AAEG;AACK,IAAA,mBAAmB,CAAC,OAAoB,EAAA;QAC9C,MAAM,aAAa,GAAG,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC;QACtD,IAAI,CAAC,cAAc,GAAG;YACpB,QAAQ,EAAE,aAAa,CAAC,QAAQ;YAChC,GAAG,EAAE,aAAa,CAAC,GAAG;YACtB,IAAI,EAAE,aAAa,CAAC,IAAI;YACxB,KAAK,EAAE,aAAa,CAAC,KAAK;YAC1B,MAAM,EAAE,aAAa,CAAC,MAAM;YAC5B,MAAM,EAAE,aAAa,CAAC,MAAM;YAC5B,eAAe,EAAE,aAAa,CAAC,eAAe;YAC9C,MAAM,EAAE,aAAa,CAAC,MAAM;YAC5B,OAAO,EAAE,aAAa,CAAC,OAAO;SAC/B;IACH;AAEA;;AAEG;AACK,IAAA,qBAAqB,CAAC,OAAoB,EAAA;AAChD,QAAA,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE;YACxB;QACF;;AAGA,QAAA,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,KAAI;YAC3D,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC;YAC3C,IAAI,KAAK,EAAE;gBACT,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC;YAClD;iBAAO;gBACL,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,OAAO,EAAE,QAAQ,CAAC;YAC9C;AACF,QAAA,CAAC,CAAC;AAEF,QAAA,IAAI,CAAC,cAAc,GAAG,EAAE;IAC1B;AAEA;;AAEG;AACK,IAAA,gBAAgB,CAAC,GAAW,EAAA;QAClC,OAAO,GAAG,CAAC,OAAO,CAAC,8BAA8B,EAAE,OAAO,CAAC,CAAC,WAAW,EAAE;IAC3E;8GA9MW,qBAAqB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;kGAArB,qBAAqB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,OAAA,EAAA,EAAA,gBAAA,EAAA,kBAAA,EAAA,EAAA,QAAA,EAAA,CAAA,cAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA,CAAA;;2FAArB,qBAAqB,EAAA,UAAA,EAAA,CAAA;kBALjC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,gBAAgB;AAC1B,oBAAA,UAAU,EAAE,IAAI;AAChB,oBAAA,QAAQ,EAAE,cAAc;AACzB,iBAAA;;;ACZD;;AAEG;;;;"}
|
|
1
|
+
{"version":3,"file":"acorex-cdk-full-screen.mjs","sources":["../../../../packages/cdk/full-screen/src/lib/full-screen.directive.ts","../../../../packages/cdk/full-screen/src/acorex-cdk-full-screen.ts"],"sourcesContent":["import { AXFullScreenMode, AXFullScreenService } from '@acorex/core/full-screen';\nimport { Directive, effect, ElementRef, inject, input, OnDestroy, output, untracked } from '@angular/core';\n\n/**\n * Fullscreen directive with overlay and browser modes.\n * Usage: <element axFullscreen #fullscreen=\"axFullscreen\"></element>\n * Then: fullscreen.toggle() or fullscreen.enter() or fullscreen.exit()\n */\n@Directive({\n selector: '[axFullscreen]',\n exportAs: 'axFullscreen',\n})\nexport class AXFullScreenDirective implements OnDestroy {\n /**\n * Fullscreen implementation mode.\n * @defaultValue 'overlay'\n */\n readonly mode = input<AXFullScreenMode>('overlay');\n\n /**\n * Fullscreen change event for this host element.\n */\n readonly fullscreenChange = output<boolean>();\n\n private readonly elementRef = inject<ElementRef<HTMLElement>>(ElementRef);\n private readonly fullScreenService = inject(AXFullScreenService);\n\n constructor() {\n effect(() => {\n const isActive = this.fullScreenService.isActive(this.elementRef.nativeElement);\n untracked(() => {\n this.fullscreenChange.emit(isActive);\n });\n });\n }\n\n /**\n * Toggle fullscreen state.\n */\n toggle(): void {\n this.fullScreenService.toggle(this.elementRef.nativeElement, this.mode());\n }\n\n /**\n * Enter fullscreen mode.\n */\n enter(): void {\n this.fullScreenService.enter(this.elementRef.nativeElement, this.mode());\n }\n\n /**\n * Exit fullscreen mode.\n */\n exit(): void {\n this.fullScreenService.exit(this.elementRef.nativeElement);\n }\n\n /**\n * Check if this host is currently in fullscreen mode.\n */\n isFullscreen(): boolean {\n return this.fullScreenService.isActive(this.elementRef.nativeElement);\n }\n\n ngOnDestroy(): void {\n if (this.fullScreenService.isActive(this.elementRef.nativeElement)) {\n this.fullScreenService.exit(this.elementRef.nativeElement);\n }\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;AAGA;;;;AAIG;MAKU,qBAAqB,CAAA;AAehC,IAAA,WAAA,GAAA;AAdA;;;AAGG;QACM,IAAA,CAAA,IAAI,GAAG,KAAK,CAAmB,SAAS;iFAAC;AAElD;;AAEG;QACM,IAAA,CAAA,gBAAgB,GAAG,MAAM,EAAW;AAE5B,QAAA,IAAA,CAAA,UAAU,GAAG,MAAM,CAA0B,UAAU,CAAC;AACxD,QAAA,IAAA,CAAA,iBAAiB,GAAG,MAAM,CAAC,mBAAmB,CAAC;QAG9D,MAAM,CAAC,MAAK;AACV,YAAA,MAAM,QAAQ,GAAG,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC;YAC/E,SAAS,CAAC,MAAK;AACb,gBAAA,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC;AACtC,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC,CAAC;IACJ;AAEA;;AAEG;IACH,MAAM,GAAA;AACJ,QAAA,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,aAAa,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;IAC3E;AAEA;;AAEG;IACH,KAAK,GAAA;AACH,QAAA,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,aAAa,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;IAC1E;AAEA;;AAEG;IACH,IAAI,GAAA;QACF,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC;IAC5D;AAEA;;AAEG;IACH,YAAY,GAAA;AACV,QAAA,OAAO,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC;IACvE;IAEA,WAAW,GAAA;AACT,QAAA,IAAI,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE;YAClE,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC;QAC5D;IACF;8GAxDW,qBAAqB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;kGAArB,qBAAqB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,MAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,OAAA,EAAA,EAAA,gBAAA,EAAA,kBAAA,EAAA,EAAA,QAAA,EAAA,CAAA,cAAA,CAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA,CAAA;;2FAArB,qBAAqB,EAAA,UAAA,EAAA,CAAA;kBAJjC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,gBAAgB;AAC1B,oBAAA,QAAQ,EAAE,cAAc;AACzB,iBAAA;;;ACXD;;AAEG;;;;"}
|
|
@@ -43,6 +43,12 @@ class AXGestureDirective {
|
|
|
43
43
|
*/
|
|
44
44
|
this.disabled = input(false, /* @ts-ignore */
|
|
45
45
|
...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
46
|
+
/**
|
|
47
|
+
* Maximum interval in milliseconds between taps for double-tap recognition.
|
|
48
|
+
* Maps to Hammer.js tap recognizer `interval`. Defaults to Hammer's built-in value (300ms).
|
|
49
|
+
*/
|
|
50
|
+
this.tapInterval = input(undefined, /* @ts-ignore */
|
|
51
|
+
...(ngDevMode ? [{ debugName: "tapInterval" }] : /* istanbul ignore next */ []));
|
|
46
52
|
this.tap = output();
|
|
47
53
|
this.doubletap = output();
|
|
48
54
|
this.press = output();
|
|
@@ -81,6 +87,7 @@ class AXGestureDirective {
|
|
|
81
87
|
this.enablePinch();
|
|
82
88
|
this.enableRotate();
|
|
83
89
|
this.disabled();
|
|
90
|
+
this.tapInterval();
|
|
84
91
|
untracked(() => {
|
|
85
92
|
if (this.ready)
|
|
86
93
|
void this.setup();
|
|
@@ -106,6 +113,17 @@ class AXGestureDirective {
|
|
|
106
113
|
}
|
|
107
114
|
#init;
|
|
108
115
|
#config;
|
|
116
|
+
/**
|
|
117
|
+
* Suppresses native click propagation when Hammer.js is active so tap/doubletap
|
|
118
|
+
* outputs are the single source of click handling.
|
|
119
|
+
*/
|
|
120
|
+
onHostClick(event) {
|
|
121
|
+
if (this.disabled() || !this.hammer)
|
|
122
|
+
return;
|
|
123
|
+
event.preventDefault();
|
|
124
|
+
event.stopPropagation();
|
|
125
|
+
event.stopImmediatePropagation();
|
|
126
|
+
}
|
|
109
127
|
ngOnDestroy() {
|
|
110
128
|
this.setupId++;
|
|
111
129
|
this.teardown();
|
|
@@ -132,6 +150,11 @@ class AXGestureDirective {
|
|
|
132
150
|
hammer.get('swipe')?.set({ direction });
|
|
133
151
|
hammer.get('pinch')?.set({ enable: this.enablePinch() });
|
|
134
152
|
hammer.get('rotate')?.set({ enable: this.enableRotate() });
|
|
153
|
+
const interval = this.tapInterval();
|
|
154
|
+
if (interval != null) {
|
|
155
|
+
hammer.get('tap')?.set({ interval });
|
|
156
|
+
hammer.get('doubletap')?.set({ interval });
|
|
157
|
+
}
|
|
135
158
|
hammer.on(HAMMER_EVENTS, this.onHammerEvent);
|
|
136
159
|
this.hammer = hammer;
|
|
137
160
|
});
|
|
@@ -158,15 +181,18 @@ class AXGestureDirective {
|
|
|
158
181
|
this.hammer = null;
|
|
159
182
|
}
|
|
160
183
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXGestureDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
161
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.8", type: AXGestureDirective, isStandalone: true, selector: "[axGesture]", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null }, enablePinch: { classPropertyName: "enablePinch", publicName: "enablePinch", isSignal: true, isRequired: false, transformFunction: null }, enableRotate: { classPropertyName: "enableRotate", publicName: "enableRotate", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { tap: "tap", doubletap: "doubletap", press: "press", pan: "pan", panstart: "panstart", panmove: "panmove", panend: "panend", swipe: "swipe", pinch: "pinch", rotate: "rotate" }, exportAs: ["axGesture"], ngImport: i0 }); }
|
|
184
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.8", type: AXGestureDirective, isStandalone: true, selector: "[axGesture]", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null }, enablePinch: { classPropertyName: "enablePinch", publicName: "enablePinch", isSignal: true, isRequired: false, transformFunction: null }, enableRotate: { classPropertyName: "enableRotate", publicName: "enableRotate", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, tapInterval: { classPropertyName: "tapInterval", publicName: "tapInterval", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { tap: "tap", doubletap: "doubletap", press: "press", pan: "pan", panstart: "panstart", panmove: "panmove", panend: "panend", swipe: "swipe", pinch: "pinch", rotate: "rotate" }, host: { listeners: { "click": "onHostClick($event)" } }, exportAs: ["axGesture"], ngImport: i0 }); }
|
|
162
185
|
}
|
|
163
186
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXGestureDirective, decorators: [{
|
|
164
187
|
type: Directive,
|
|
165
188
|
args: [{
|
|
166
189
|
selector: '[axGesture]',
|
|
167
190
|
exportAs: 'axGesture',
|
|
191
|
+
host: {
|
|
192
|
+
'(click)': 'onHostClick($event)',
|
|
193
|
+
},
|
|
168
194
|
}]
|
|
169
|
-
}], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], direction: [{ type: i0.Input, args: [{ isSignal: true, alias: "direction", required: false }] }], enablePinch: [{ type: i0.Input, args: [{ isSignal: true, alias: "enablePinch", required: false }] }], enableRotate: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableRotate", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], tap: [{ type: i0.Output, args: ["tap"] }], doubletap: [{ type: i0.Output, args: ["doubletap"] }], press: [{ type: i0.Output, args: ["press"] }], pan: [{ type: i0.Output, args: ["pan"] }], panstart: [{ type: i0.Output, args: ["panstart"] }], panmove: [{ type: i0.Output, args: ["panmove"] }], panend: [{ type: i0.Output, args: ["panend"] }], swipe: [{ type: i0.Output, args: ["swipe"] }], pinch: [{ type: i0.Output, args: ["pinch"] }], rotate: [{ type: i0.Output, args: ["rotate"] }] } });
|
|
195
|
+
}], propDecorators: { options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], direction: [{ type: i0.Input, args: [{ isSignal: true, alias: "direction", required: false }] }], enablePinch: [{ type: i0.Input, args: [{ isSignal: true, alias: "enablePinch", required: false }] }], enableRotate: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableRotate", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], tapInterval: [{ type: i0.Input, args: [{ isSignal: true, alias: "tapInterval", required: false }] }], tap: [{ type: i0.Output, args: ["tap"] }], doubletap: [{ type: i0.Output, args: ["doubletap"] }], press: [{ type: i0.Output, args: ["press"] }], pan: [{ type: i0.Output, args: ["pan"] }], panstart: [{ type: i0.Output, args: ["panstart"] }], panmove: [{ type: i0.Output, args: ["panmove"] }], panend: [{ type: i0.Output, args: ["panend"] }], swipe: [{ type: i0.Output, args: ["swipe"] }], pinch: [{ type: i0.Output, args: ["pinch"] }], rotate: [{ type: i0.Output, args: ["rotate"] }] } });
|
|
170
196
|
|
|
171
197
|
/**
|
|
172
198
|
* Generated bundle index. Do not edit.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"acorex-cdk-gesture.mjs","sources":["../../../../packages/cdk/gesture/src/lib/gesture.directive.ts","../../../../packages/cdk/gesture/src/acorex-cdk-gesture.ts"],"sourcesContent":["import { isPlatformBrowser } from '@angular/common';\nimport {\n afterNextRender,\n Directive,\n effect,\n ElementRef,\n inject,\n input,\n linkedSignal,\n NgZone,\n OnDestroy,\n output,\n OutputEmitterRef,\n PLATFORM_ID,\n untracked,\n} from '@angular/core';\nimport { AXGestureDirection, AXGestureEvent, AXGestureManager, AXGestureOptions } from './gesture.types';\n\nconst HAMMER_EVENTS = 'tap doubletap press pan panstart panmove panend swipe pinch rotate';\nconst HIGH_FREQUENCY_EVENTS = new Set(['pan', 'panmove', 'pinch', 'rotate']);\n\ntype HammerStatic = {\n new (element: HTMLElement | SVGElement, options?: AXGestureOptions): AXGestureManager;\n DIRECTION_ALL: number;\n DIRECTION_HORIZONTAL: number;\n DIRECTION_VERTICAL: number;\n};\n\n/**\n * Attaches Hammer.js gesture recognition to the host element.\n *\n * Usage:\n * <div axGesture [direction]=\"'all'\" (tap)=\"onTap($event)\" (pan)=\"onPan($event)\"></div>\n */\n@Directive({\n selector: '[axGesture]',\n exportAs: 'axGesture',\n})\nexport class AXGestureDirective implements OnDestroy {\n private readonly el = inject(ElementRef<HTMLElement>);\n private readonly zone = inject(NgZone);\n private readonly platformId = inject(PLATFORM_ID);\n\n /**\n * Extra Hammer.js options forwarded to the manager constructor.\n */\n options = input<AXGestureOptions>({});\n\n /**\n * Pan and swipe direction. Defaults to horizontal, matching Hammer.js.\n */\n direction = input<AXGestureDirection>('horizontal');\n\n /** Internal direction state; can be overridden programmatically by host directives. */\n readonly gestureDirection = linkedSignal(() => this.direction());\n\n /**\n * Enables the multi-touch pinch recognizer. Disabled by default.\n */\n enablePinch = input(false);\n\n /**\n * Enables the multi-touch rotate recognizer. Disabled by default.\n */\n enableRotate = input(false);\n\n /**\n * Stops gesture recognition when true.\n */\n disabled = input(false);\n\n tap = output<AXGestureEvent>();\n doubletap = output<AXGestureEvent>();\n press = output<AXGestureEvent>();\n pan = output<AXGestureEvent>();\n panstart = output<AXGestureEvent>();\n panmove = output<AXGestureEvent>();\n panend = output<AXGestureEvent>();\n swipe = output<AXGestureEvent>();\n pinch = output<AXGestureEvent>();\n rotate = output<AXGestureEvent>();\n\n private hammer: AXGestureManager | null = null;\n private hammerLib: HammerStatic | null = null;\n private setupId = 0;\n private ready = false;\n\n private readonly emitters: Record<string, OutputEmitterRef<AXGestureEvent>> = {\n tap: this.tap,\n doubletap: this.doubletap,\n press: this.press,\n pan: this.pan,\n panstart: this.panstart,\n panmove: this.panmove,\n panend: this.panend,\n swipe: this.swipe,\n pinch: this.pinch,\n rotate: this.rotate,\n };\n\n /**\n * The underlying Hammer manager, or null when not initialized.\n */\n get manager(): AXGestureManager | null {\n return this.hammer;\n }\n\n #init = afterNextRender(() => {\n if (!isPlatformBrowser(this.platformId)) return;\n this.ready = true;\n void this.setup();\n });\n\n #config = effect(() => {\n this.options();\n this.gestureDirection();\n this.enablePinch();\n this.enableRotate();\n this.disabled();\n untracked(() => {\n if (this.ready) void this.setup();\n });\n });\n\n ngOnDestroy(): void {\n this.setupId++;\n this.teardown();\n }\n\n private async setup(): Promise<void> {\n const id = ++this.setupId;\n this.teardown();\n if (this.disabled() || !isPlatformBrowser(this.platformId)) return;\n\n const HammerLib = await this.loadHammer();\n if (id !== this.setupId) return;\n\n this.zone.runOutsideAngular(() => {\n const options: AXGestureOptions = { ...this.options() };\n if (!options.touchAction) {\n const hostTouchAction = this.el.nativeElement.style.touchAction;\n if (hostTouchAction) {\n options.touchAction = hostTouchAction;\n }\n }\n\n const hammer = new HammerLib(this.el.nativeElement, options);\n const direction = this.toHammerDirection(HammerLib, this.gestureDirection());\n\n hammer.get('pan')?.set({ direction });\n hammer.get('swipe')?.set({ direction });\n hammer.get('pinch')?.set({ enable: this.enablePinch() });\n hammer.get('rotate')?.set({ enable: this.enableRotate() });\n hammer.on(HAMMER_EVENTS, this.onHammerEvent);\n\n this.hammer = hammer;\n });\n }\n\n private async loadHammer(): Promise<HammerStatic> {\n if (this.hammerLib) return this.hammerLib;\n const mod = (await import('hammerjs')) as unknown as HammerStatic & { default?: HammerStatic };\n this.hammerLib = mod.default ?? mod;\n return this.hammerLib;\n }\n\n private toHammerDirection(HammerLib: HammerStatic, direction: AXGestureDirection): number {\n if (direction === 'all') return HammerLib.DIRECTION_ALL;\n if (direction === 'vertical') return HammerLib.DIRECTION_VERTICAL;\n return HammerLib.DIRECTION_HORIZONTAL;\n }\n\n private teardown(): void {\n if (!this.hammer) return;\n this.hammer.off(HAMMER_EVENTS, this.onHammerEvent);\n this.hammer.destroy();\n this.hammer = null;\n }\n\n private readonly onHammerEvent = (ev: AXGestureEvent) => {\n const emit = this.emitters[ev.type];\n if (!emit) return;\n if (HIGH_FREQUENCY_EVENTS.has(ev.type)) {\n emit.emit(ev);\n return;\n }\n this.zone.run(() => emit.emit(ev));\n };\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"acorex-cdk-gesture.mjs","sources":["../../../../packages/cdk/gesture/src/lib/gesture.directive.ts","../../../../packages/cdk/gesture/src/acorex-cdk-gesture.ts"],"sourcesContent":["import { isPlatformBrowser } from '@angular/common';\nimport {\n afterNextRender,\n Directive,\n effect,\n ElementRef,\n inject,\n input,\n linkedSignal,\n NgZone,\n OnDestroy,\n output,\n OutputEmitterRef,\n PLATFORM_ID,\n untracked,\n} from '@angular/core';\nimport { AXGestureDirection, AXGestureEvent, AXGestureManager, AXGestureOptions } from './gesture.types';\n\nconst HAMMER_EVENTS = 'tap doubletap press pan panstart panmove panend swipe pinch rotate';\nconst HIGH_FREQUENCY_EVENTS = new Set(['pan', 'panmove', 'pinch', 'rotate']);\n\ntype HammerStatic = {\n new (element: HTMLElement | SVGElement, options?: AXGestureOptions): AXGestureManager;\n DIRECTION_ALL: number;\n DIRECTION_HORIZONTAL: number;\n DIRECTION_VERTICAL: number;\n};\n\n/**\n * Attaches Hammer.js gesture recognition to the host element.\n *\n * Usage:\n * <div axGesture [direction]=\"'all'\" (tap)=\"onTap($event)\" (pan)=\"onPan($event)\"></div>\n */\n@Directive({\n selector: '[axGesture]',\n exportAs: 'axGesture',\n host: {\n '(click)': 'onHostClick($event)',\n },\n})\nexport class AXGestureDirective implements OnDestroy {\n private readonly el = inject(ElementRef<HTMLElement>);\n private readonly zone = inject(NgZone);\n private readonly platformId = inject(PLATFORM_ID);\n\n /**\n * Extra Hammer.js options forwarded to the manager constructor.\n */\n options = input<AXGestureOptions>({});\n\n /**\n * Pan and swipe direction. Defaults to horizontal, matching Hammer.js.\n */\n direction = input<AXGestureDirection>('horizontal');\n\n /** Internal direction state; can be overridden programmatically by host directives. */\n readonly gestureDirection = linkedSignal(() => this.direction());\n\n /**\n * Enables the multi-touch pinch recognizer. Disabled by default.\n */\n enablePinch = input(false);\n\n /**\n * Enables the multi-touch rotate recognizer. Disabled by default.\n */\n enableRotate = input(false);\n\n /**\n * Stops gesture recognition when true.\n */\n disabled = input(false);\n\n /**\n * Maximum interval in milliseconds between taps for double-tap recognition.\n * Maps to Hammer.js tap recognizer `interval`. Defaults to Hammer's built-in value (300ms).\n */\n tapInterval = input<number | undefined>(undefined);\n\n tap = output<AXGestureEvent>();\n doubletap = output<AXGestureEvent>();\n press = output<AXGestureEvent>();\n pan = output<AXGestureEvent>();\n panstart = output<AXGestureEvent>();\n panmove = output<AXGestureEvent>();\n panend = output<AXGestureEvent>();\n swipe = output<AXGestureEvent>();\n pinch = output<AXGestureEvent>();\n rotate = output<AXGestureEvent>();\n\n private hammer: AXGestureManager | null = null;\n private hammerLib: HammerStatic | null = null;\n private setupId = 0;\n private ready = false;\n\n private readonly emitters: Record<string, OutputEmitterRef<AXGestureEvent>> = {\n tap: this.tap,\n doubletap: this.doubletap,\n press: this.press,\n pan: this.pan,\n panstart: this.panstart,\n panmove: this.panmove,\n panend: this.panend,\n swipe: this.swipe,\n pinch: this.pinch,\n rotate: this.rotate,\n };\n\n /**\n * The underlying Hammer manager, or null when not initialized.\n */\n get manager(): AXGestureManager | null {\n return this.hammer;\n }\n\n #init = afterNextRender(() => {\n if (!isPlatformBrowser(this.platformId)) return;\n this.ready = true;\n void this.setup();\n });\n\n #config = effect(() => {\n this.options();\n this.gestureDirection();\n this.enablePinch();\n this.enableRotate();\n this.disabled();\n this.tapInterval();\n untracked(() => {\n if (this.ready) void this.setup();\n });\n });\n\n /**\n * Suppresses native click propagation when Hammer.js is active so tap/doubletap\n * outputs are the single source of click handling.\n */\n protected onHostClick(event: MouseEvent): void {\n if (this.disabled() || !this.hammer) return;\n event.preventDefault();\n event.stopPropagation();\n event.stopImmediatePropagation();\n }\n\n ngOnDestroy(): void {\n this.setupId++;\n this.teardown();\n }\n\n private async setup(): Promise<void> {\n const id = ++this.setupId;\n this.teardown();\n if (this.disabled() || !isPlatformBrowser(this.platformId)) return;\n\n const HammerLib = await this.loadHammer();\n if (id !== this.setupId) return;\n\n this.zone.runOutsideAngular(() => {\n const options: AXGestureOptions = { ...this.options() };\n if (!options.touchAction) {\n const hostTouchAction = this.el.nativeElement.style.touchAction;\n if (hostTouchAction) {\n options.touchAction = hostTouchAction;\n }\n }\n\n const hammer = new HammerLib(this.el.nativeElement, options);\n const direction = this.toHammerDirection(HammerLib, this.gestureDirection());\n\n hammer.get('pan')?.set({ direction });\n hammer.get('swipe')?.set({ direction });\n hammer.get('pinch')?.set({ enable: this.enablePinch() });\n hammer.get('rotate')?.set({ enable: this.enableRotate() });\n\n const interval = this.tapInterval();\n if (interval != null) {\n hammer.get('tap')?.set({ interval });\n hammer.get('doubletap')?.set({ interval });\n }\n\n hammer.on(HAMMER_EVENTS, this.onHammerEvent);\n\n this.hammer = hammer;\n });\n }\n\n private async loadHammer(): Promise<HammerStatic> {\n if (this.hammerLib) return this.hammerLib;\n const mod = (await import('hammerjs')) as unknown as HammerStatic & { default?: HammerStatic };\n this.hammerLib = mod.default ?? mod;\n return this.hammerLib;\n }\n\n private toHammerDirection(HammerLib: HammerStatic, direction: AXGestureDirection): number {\n if (direction === 'all') return HammerLib.DIRECTION_ALL;\n if (direction === 'vertical') return HammerLib.DIRECTION_VERTICAL;\n return HammerLib.DIRECTION_HORIZONTAL;\n }\n\n private teardown(): void {\n if (!this.hammer) return;\n this.hammer.off(HAMMER_EVENTS, this.onHammerEvent);\n this.hammer.destroy();\n this.hammer = null;\n }\n\n private readonly onHammerEvent = (ev: AXGestureEvent) => {\n const emit = this.emitters[ev.type];\n if (!emit) return;\n if (HIGH_FREQUENCY_EVENTS.has(ev.type)) {\n emit.emit(ev);\n return;\n }\n this.zone.run(() => emit.emit(ev));\n };\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@acorex/cdk",
|
|
3
|
-
"version": "22.2.
|
|
3
|
+
"version": "22.2.10",
|
|
4
4
|
"peerDependencies": {
|
|
5
|
-
"@acorex/core": "22.2.
|
|
5
|
+
"@acorex/core": "22.2.10",
|
|
6
6
|
"quill": ">=2.0.2",
|
|
7
7
|
"qrcode": ">=1.5.4",
|
|
8
8
|
"swiper": ">=11.1.15",
|
|
@@ -40,10 +40,6 @@
|
|
|
40
40
|
"types": "./types/acorex-cdk-dom.d.ts",
|
|
41
41
|
"default": "./fesm2022/acorex-cdk-dom.mjs"
|
|
42
42
|
},
|
|
43
|
-
"./double-click": {
|
|
44
|
-
"types": "./types/acorex-cdk-double-click.d.ts",
|
|
45
|
-
"default": "./fesm2022/acorex-cdk-double-click.mjs"
|
|
46
|
-
},
|
|
47
43
|
"./drag-drop": {
|
|
48
44
|
"types": "./types/acorex-cdk-drag-drop.d.ts",
|
|
49
45
|
"default": "./fesm2022/acorex-cdk-drag-drop.mjs"
|
|
@@ -7,6 +7,8 @@ declare class AXCarouselDirective {
|
|
|
7
7
|
carousel: i0.WritableSignal<Swiper>;
|
|
8
8
|
private el;
|
|
9
9
|
private platformId;
|
|
10
|
+
private initId;
|
|
11
|
+
destroy(): void;
|
|
10
12
|
init(option: AXCarouselOptions): Promise<void>;
|
|
11
13
|
static ɵfac: i0.ɵɵFactoryDeclaration<AXCarouselDirective, never>;
|
|
12
14
|
static ɵdir: i0.ɵɵDirectiveDeclaration<AXCarouselDirective, "[axCarousel]", ["axCarousel"], {}, {}, never, never, true, never>;
|
|
@@ -1,69 +1,44 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as _angular_core from '@angular/core';
|
|
2
|
+
import { OnDestroy } from '@angular/core';
|
|
3
|
+
import { AXFullScreenMode } from '@acorex/core/full-screen';
|
|
2
4
|
|
|
3
5
|
/**
|
|
4
|
-
* Fullscreen directive
|
|
6
|
+
* Fullscreen directive with overlay and browser modes.
|
|
5
7
|
* Usage: <element axFullscreen #fullscreen="axFullscreen"></element>
|
|
6
8
|
* Then: fullscreen.toggle() or fullscreen.enter() or fullscreen.exit()
|
|
7
9
|
*/
|
|
8
|
-
declare class AXFullScreenDirective {
|
|
10
|
+
declare class AXFullScreenDirective implements OnDestroy {
|
|
9
11
|
/**
|
|
10
|
-
*
|
|
12
|
+
* Fullscreen implementation mode.
|
|
13
|
+
* @defaultValue 'overlay'
|
|
11
14
|
*/
|
|
12
|
-
|
|
15
|
+
readonly mode: _angular_core.InputSignal<AXFullScreenMode>;
|
|
13
16
|
/**
|
|
14
|
-
*
|
|
17
|
+
* Fullscreen change event for this host element.
|
|
15
18
|
*/
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Original parent element reference
|
|
19
|
-
*/
|
|
20
|
-
private originalParent;
|
|
21
|
-
/**
|
|
22
|
-
* Fullscreen container element
|
|
23
|
-
*/
|
|
24
|
-
private fullscreenContainer;
|
|
25
|
-
/**
|
|
26
|
-
* Fullscreen change event
|
|
27
|
-
*/
|
|
28
|
-
readonly fullscreenChange: i0.OutputEmitterRef<boolean>;
|
|
29
|
-
/**
|
|
30
|
-
* Z-index token for this fullscreen instance
|
|
31
|
-
*/
|
|
32
|
-
private zToken;
|
|
33
|
-
private readonly renderer;
|
|
19
|
+
readonly fullscreenChange: _angular_core.OutputEmitterRef<boolean>;
|
|
34
20
|
private readonly elementRef;
|
|
35
|
-
private readonly
|
|
21
|
+
private readonly fullScreenService;
|
|
36
22
|
constructor();
|
|
37
23
|
/**
|
|
38
|
-
* Toggle fullscreen state
|
|
24
|
+
* Toggle fullscreen state.
|
|
39
25
|
*/
|
|
40
26
|
toggle(): void;
|
|
41
27
|
/**
|
|
42
|
-
* Enter fullscreen mode
|
|
28
|
+
* Enter fullscreen mode.
|
|
43
29
|
*/
|
|
44
30
|
enter(): void;
|
|
45
31
|
/**
|
|
46
|
-
* Exit fullscreen mode
|
|
32
|
+
* Exit fullscreen mode.
|
|
47
33
|
*/
|
|
48
34
|
exit(): void;
|
|
49
35
|
/**
|
|
50
|
-
* Check if currently in fullscreen mode
|
|
36
|
+
* Check if this host is currently in fullscreen mode.
|
|
51
37
|
*/
|
|
52
38
|
isFullscreen(): boolean;
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
private storeOriginalStyles;
|
|
57
|
-
/**
|
|
58
|
-
* Restore original element styles
|
|
59
|
-
*/
|
|
60
|
-
private restoreOriginalStyles;
|
|
61
|
-
/**
|
|
62
|
-
* Convert camelCase to kebab-case for CSS properties
|
|
63
|
-
*/
|
|
64
|
-
private camelToKebabCase;
|
|
65
|
-
static ɵfac: i0.ɵɵFactoryDeclaration<AXFullScreenDirective, never>;
|
|
66
|
-
static ɵdir: i0.ɵɵDirectiveDeclaration<AXFullScreenDirective, "[axFullscreen]", ["axFullscreen"], {}, { "fullscreenChange": "fullscreenChange"; }, never, never, true, never>;
|
|
39
|
+
ngOnDestroy(): void;
|
|
40
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXFullScreenDirective, never>;
|
|
41
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<AXFullScreenDirective, "[axFullscreen]", ["axFullscreen"], { "mode": { "alias": "mode"; "required": false; "isSignal": true; }; }, { "fullscreenChange": "fullscreenChange"; }, never, never, true, never>;
|
|
67
42
|
}
|
|
68
43
|
|
|
69
44
|
export { AXFullScreenDirective };
|
|
@@ -89,6 +89,11 @@ declare class AXGestureDirective implements OnDestroy {
|
|
|
89
89
|
* Stops gesture recognition when true.
|
|
90
90
|
*/
|
|
91
91
|
disabled: _angular_core.InputSignal<boolean>;
|
|
92
|
+
/**
|
|
93
|
+
* Maximum interval in milliseconds between taps for double-tap recognition.
|
|
94
|
+
* Maps to Hammer.js tap recognizer `interval`. Defaults to Hammer's built-in value (300ms).
|
|
95
|
+
*/
|
|
96
|
+
tapInterval: _angular_core.InputSignal<number>;
|
|
92
97
|
tap: OutputEmitterRef<AXGestureEvent>;
|
|
93
98
|
doubletap: OutputEmitterRef<AXGestureEvent>;
|
|
94
99
|
press: OutputEmitterRef<AXGestureEvent>;
|
|
@@ -108,6 +113,11 @@ declare class AXGestureDirective implements OnDestroy {
|
|
|
108
113
|
* The underlying Hammer manager, or null when not initialized.
|
|
109
114
|
*/
|
|
110
115
|
get manager(): AXGestureManager | null;
|
|
116
|
+
/**
|
|
117
|
+
* Suppresses native click propagation when Hammer.js is active so tap/doubletap
|
|
118
|
+
* outputs are the single source of click handling.
|
|
119
|
+
*/
|
|
120
|
+
protected onHostClick(event: MouseEvent): void;
|
|
111
121
|
ngOnDestroy(): void;
|
|
112
122
|
private setup;
|
|
113
123
|
private loadHammer;
|
|
@@ -115,7 +125,7 @@ declare class AXGestureDirective implements OnDestroy {
|
|
|
115
125
|
private teardown;
|
|
116
126
|
private readonly onHammerEvent;
|
|
117
127
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXGestureDirective, never>;
|
|
118
|
-
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<AXGestureDirective, "[axGesture]", ["axGesture"], { "options": { "alias": "options"; "required": false; "isSignal": true; }; "direction": { "alias": "direction"; "required": false; "isSignal": true; }; "enablePinch": { "alias": "enablePinch"; "required": false; "isSignal": true; }; "enableRotate": { "alias": "enableRotate"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, { "tap": "tap"; "doubletap": "doubletap"; "press": "press"; "pan": "pan"; "panstart": "panstart"; "panmove": "panmove"; "panend": "panend"; "swipe": "swipe"; "pinch": "pinch"; "rotate": "rotate"; }, never, never, true, never>;
|
|
128
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<AXGestureDirective, "[axGesture]", ["axGesture"], { "options": { "alias": "options"; "required": false; "isSignal": true; }; "direction": { "alias": "direction"; "required": false; "isSignal": true; }; "enablePinch": { "alias": "enablePinch"; "required": false; "isSignal": true; }; "enableRotate": { "alias": "enableRotate"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "tapInterval": { "alias": "tapInterval"; "required": false; "isSignal": true; }; }, { "tap": "tap"; "doubletap": "doubletap"; "press": "press"; "pan": "pan"; "panstart": "panstart"; "panmove": "panmove"; "panend": "panend"; "swipe": "swipe"; "pinch": "pinch"; "rotate": "rotate"; }, never, never, true, never>;
|
|
119
129
|
}
|
|
120
130
|
|
|
121
131
|
export { AXGestureDirective };
|
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, ElementRef, input, output, Directive } from '@angular/core';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Directive to detect single-click and double-click events on the host element.
|
|
6
|
-
* Supports both desktop (click-based detection) and mobile (touchend) events.
|
|
7
|
-
* Prevents native click event propagation and emits separate single-click and double-click events.
|
|
8
|
-
* Can be disabled to allow native DOM behavior (click and dblclick events).
|
|
9
|
-
*
|
|
10
|
-
* Usage:
|
|
11
|
-
* <button
|
|
12
|
-
* axDoubleClick
|
|
13
|
-
* [duration]="300"
|
|
14
|
-
* [disabled]="false"
|
|
15
|
-
* (onClick)="onSingleClick($event)"
|
|
16
|
-
* (onDblClick)="onDoubleClick($event)"
|
|
17
|
-
* >Click me</button>
|
|
18
|
-
*/
|
|
19
|
-
class AXDoubleClickDirective {
|
|
20
|
-
constructor() {
|
|
21
|
-
this.elementRef = inject(ElementRef);
|
|
22
|
-
/**
|
|
23
|
-
* Input to configure the duration in milliseconds for detecting double-clicks.
|
|
24
|
-
* Defaults to 250ms.
|
|
25
|
-
* Two clicks/taps within this duration are considered a double-click.
|
|
26
|
-
*/
|
|
27
|
-
this.duration = input(250, /* @ts-ignore */
|
|
28
|
-
...(ngDevMode ? [{ debugName: "duration" }] : /* istanbul ignore next */ []));
|
|
29
|
-
/**
|
|
30
|
-
* Input to disable the directive's custom click handling.
|
|
31
|
-
* When true, native click and dblclick events will fire normally (DOM default behavior).
|
|
32
|
-
* When false (default), the directive prevents default and emits custom single/double-click events.
|
|
33
|
-
* Defaults to false.
|
|
34
|
-
*/
|
|
35
|
-
this.disabled = input(false, /* @ts-ignore */
|
|
36
|
-
...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
37
|
-
/**
|
|
38
|
-
* Output event emitted when a single-click is detected.
|
|
39
|
-
* Emits after the configured duration milliseconds if no second click occurs.
|
|
40
|
-
* Emits the MouseEvent.
|
|
41
|
-
*/
|
|
42
|
-
this.onClick = output();
|
|
43
|
-
/**
|
|
44
|
-
* Output event emitted when a double-click is detected.
|
|
45
|
-
* Emits when two clicks occur within the configured duration milliseconds.
|
|
46
|
-
* Emits the Event (MouseEvent for desktop, TouchEvent for mobile).
|
|
47
|
-
*/
|
|
48
|
-
this.onDblClick = output();
|
|
49
|
-
this.lastClick = 0;
|
|
50
|
-
this.lastTap = 0;
|
|
51
|
-
this.clickTimeout = null;
|
|
52
|
-
this.pendingClickEvent = null;
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Handles click events and detects both single-clicks and double-clicks.
|
|
56
|
-
* Prevents native click propagation and emits appropriate events.
|
|
57
|
-
* When disabled is true, emits click immediately, still detects double-clicks, and allows native DOM behavior (no preventDefault).
|
|
58
|
-
*/
|
|
59
|
-
handleClick(event) {
|
|
60
|
-
const duration = this.duration();
|
|
61
|
-
const currentTime = new Date().getTime();
|
|
62
|
-
const clickGap = currentTime - this.lastClick;
|
|
63
|
-
// If disabled, emit click immediately and still track for double-click, but don't prevent default
|
|
64
|
-
if (this.disabled()) {
|
|
65
|
-
// Emit single click immediately
|
|
66
|
-
this.onClick.emit(event);
|
|
67
|
-
// Still track for double-click detection
|
|
68
|
-
if (clickGap > 0 && clickGap < duration) {
|
|
69
|
-
// Double-click detected - emit double-click
|
|
70
|
-
if (this.clickTimeout) {
|
|
71
|
-
clearTimeout(this.clickTimeout);
|
|
72
|
-
this.clickTimeout = null;
|
|
73
|
-
}
|
|
74
|
-
if (this.pendingClickEvent) {
|
|
75
|
-
this.pendingClickEvent = null;
|
|
76
|
-
}
|
|
77
|
-
this.onDblClick.emit(event);
|
|
78
|
-
this.lastClick = 0;
|
|
79
|
-
}
|
|
80
|
-
else {
|
|
81
|
-
// First click - store it and wait to see if a second click comes
|
|
82
|
-
this.lastClick = currentTime;
|
|
83
|
-
this.pendingClickEvent = event;
|
|
84
|
-
if (this.clickTimeout) {
|
|
85
|
-
clearTimeout(this.clickTimeout);
|
|
86
|
-
}
|
|
87
|
-
// Set timeout to emit double-click if second click occurs within duration
|
|
88
|
-
// Note: We already emitted single-click, so we just track for double-click here
|
|
89
|
-
this.clickTimeout = setTimeout(() => {
|
|
90
|
-
// No double-click detected within duration, reset state
|
|
91
|
-
this.pendingClickEvent = null;
|
|
92
|
-
this.lastClick = 0;
|
|
93
|
-
this.clickTimeout = null;
|
|
94
|
-
}, duration);
|
|
95
|
-
}
|
|
96
|
-
// Don't prevent default - allow native click and dblclick to fire
|
|
97
|
-
return;
|
|
98
|
-
}
|
|
99
|
-
// When enabled, prevent the native click event from propagating
|
|
100
|
-
event.preventDefault();
|
|
101
|
-
event.stopPropagation();
|
|
102
|
-
event.stopImmediatePropagation();
|
|
103
|
-
if (clickGap > 0 && clickGap < duration) {
|
|
104
|
-
// Double-click detected - clear pending single click and emit double-click
|
|
105
|
-
if (this.clickTimeout) {
|
|
106
|
-
clearTimeout(this.clickTimeout);
|
|
107
|
-
this.clickTimeout = null;
|
|
108
|
-
}
|
|
109
|
-
if (this.pendingClickEvent) {
|
|
110
|
-
this.pendingClickEvent = null;
|
|
111
|
-
}
|
|
112
|
-
this.onDblClick.emit(event);
|
|
113
|
-
this.lastClick = 0;
|
|
114
|
-
}
|
|
115
|
-
else {
|
|
116
|
-
// First click - store it and wait to see if a second click comes
|
|
117
|
-
this.lastClick = currentTime;
|
|
118
|
-
this.pendingClickEvent = event;
|
|
119
|
-
if (this.clickTimeout) {
|
|
120
|
-
clearTimeout(this.clickTimeout);
|
|
121
|
-
}
|
|
122
|
-
// Set timeout to emit single-click if no second click occurs
|
|
123
|
-
this.clickTimeout = setTimeout(() => {
|
|
124
|
-
// No double-click detected, emit single-click
|
|
125
|
-
if (this.pendingClickEvent) {
|
|
126
|
-
this.onClick.emit(this.pendingClickEvent);
|
|
127
|
-
this.pendingClickEvent = null;
|
|
128
|
-
}
|
|
129
|
-
this.lastClick = 0;
|
|
130
|
-
this.clickTimeout = null;
|
|
131
|
-
}, duration);
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
/**
|
|
135
|
-
* Handles touchend events (mobile) to detect double-tap.
|
|
136
|
-
* When disabled is true, allows native touch behavior.
|
|
137
|
-
*/
|
|
138
|
-
onTouchEnd(event) {
|
|
139
|
-
// If disabled, let native events fire normally
|
|
140
|
-
if (this.disabled()) {
|
|
141
|
-
return;
|
|
142
|
-
}
|
|
143
|
-
const duration = this.duration();
|
|
144
|
-
const currentTime = new Date().getTime();
|
|
145
|
-
const tapGap = currentTime - this.lastTap;
|
|
146
|
-
if (tapGap > 0 && tapGap < duration) {
|
|
147
|
-
// Detected a double-tap
|
|
148
|
-
this.onDblClick.emit(event);
|
|
149
|
-
event.preventDefault(); // Prevent further default actions
|
|
150
|
-
}
|
|
151
|
-
this.lastTap = currentTime;
|
|
152
|
-
}
|
|
153
|
-
ngOnDestroy() {
|
|
154
|
-
if (this.clickTimeout) {
|
|
155
|
-
clearTimeout(this.clickTimeout);
|
|
156
|
-
this.clickTimeout = null;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXDoubleClickDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
160
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.8", type: AXDoubleClickDirective, isStandalone: true, selector: "[axDoubleClick]", inputs: { duration: { classPropertyName: "duration", publicName: "duration", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onClick: "onClick", onDblClick: "onDblClick" }, host: { listeners: { "click": "handleClick($event)", "touchend": "onTouchEnd($event)" } }, ngImport: i0 }); }
|
|
161
|
-
}
|
|
162
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXDoubleClickDirective, decorators: [{
|
|
163
|
-
type: Directive,
|
|
164
|
-
args: [{
|
|
165
|
-
selector: '[axDoubleClick]',
|
|
166
|
-
host: {
|
|
167
|
-
'(click)': 'handleClick($event)',
|
|
168
|
-
'(touchend)': 'onTouchEnd($event)',
|
|
169
|
-
},
|
|
170
|
-
}]
|
|
171
|
-
}], propDecorators: { duration: [{ type: i0.Input, args: [{ isSignal: true, alias: "duration", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], onClick: [{ type: i0.Output, args: ["onClick"] }], onDblClick: [{ type: i0.Output, args: ["onDblClick"] }] } });
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* Generated bundle index. Do not edit.
|
|
175
|
-
*/
|
|
176
|
-
|
|
177
|
-
export { AXDoubleClickDirective };
|
|
178
|
-
//# sourceMappingURL=acorex-cdk-double-click.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"acorex-cdk-double-click.mjs","sources":["../../../../packages/cdk/double-click/src/lib/double-click.directive.ts","../../../../packages/cdk/double-click/src/acorex-cdk-double-click.ts"],"sourcesContent":["import { Directive, ElementRef, inject, input, OnDestroy, output } from '@angular/core';\n\n/**\n * Directive to detect single-click and double-click events on the host element.\n * Supports both desktop (click-based detection) and mobile (touchend) events.\n * Prevents native click event propagation and emits separate single-click and double-click events.\n * Can be disabled to allow native DOM behavior (click and dblclick events).\n *\n * Usage:\n * <button\n * axDoubleClick\n * [duration]=\"300\"\n * [disabled]=\"false\"\n * (onClick)=\"onSingleClick($event)\"\n * (onDblClick)=\"onDoubleClick($event)\"\n * >Click me</button>\n */\n@Directive({\n selector: '[axDoubleClick]',\n host: {\n '(click)': 'handleClick($event)',\n '(touchend)': 'onTouchEnd($event)',\n },\n})\nexport class AXDoubleClickDirective implements OnDestroy {\n private elementRef = inject(ElementRef);\n\n /**\n * Input to configure the duration in milliseconds for detecting double-clicks.\n * Defaults to 250ms.\n * Two clicks/taps within this duration are considered a double-click.\n */\n public duration = input<number>(250);\n\n /**\n * Input to disable the directive's custom click handling.\n * When true, native click and dblclick events will fire normally (DOM default behavior).\n * When false (default), the directive prevents default and emits custom single/double-click events.\n * Defaults to false.\n */\n public disabled = input<boolean>(false);\n\n /**\n * Output event emitted when a single-click is detected.\n * Emits after the configured duration milliseconds if no second click occurs.\n * Emits the MouseEvent.\n */\n public onClick = output<MouseEvent>();\n\n /**\n * Output event emitted when a double-click is detected.\n * Emits when two clicks occur within the configured duration milliseconds.\n * Emits the Event (MouseEvent for desktop, TouchEvent for mobile).\n */\n public onDblClick = output<Event>();\n\n private lastClick = 0;\n private lastTap = 0;\n private clickTimeout: ReturnType<typeof setTimeout> | null = null;\n private pendingClickEvent: MouseEvent | null = null;\n\n /**\n * Handles click events and detects both single-clicks and double-clicks.\n * Prevents native click propagation and emits appropriate events.\n * When disabled is true, emits click immediately, still detects double-clicks, and allows native DOM behavior (no preventDefault).\n */\n handleClick(event: MouseEvent): void {\n const duration = this.duration();\n const currentTime = new Date().getTime();\n const clickGap = currentTime - this.lastClick;\n\n // If disabled, emit click immediately and still track for double-click, but don't prevent default\n if (this.disabled()) {\n // Emit single click immediately\n this.onClick.emit(event);\n\n // Still track for double-click detection\n if (clickGap > 0 && clickGap < duration) {\n // Double-click detected - emit double-click\n if (this.clickTimeout) {\n clearTimeout(this.clickTimeout);\n this.clickTimeout = null;\n }\n if (this.pendingClickEvent) {\n this.pendingClickEvent = null;\n }\n this.onDblClick.emit(event);\n this.lastClick = 0;\n } else {\n // First click - store it and wait to see if a second click comes\n this.lastClick = currentTime;\n this.pendingClickEvent = event;\n\n if (this.clickTimeout) {\n clearTimeout(this.clickTimeout);\n }\n\n // Set timeout to emit double-click if second click occurs within duration\n // Note: We already emitted single-click, so we just track for double-click here\n this.clickTimeout = setTimeout(() => {\n // No double-click detected within duration, reset state\n this.pendingClickEvent = null;\n this.lastClick = 0;\n this.clickTimeout = null;\n }, duration);\n }\n\n // Don't prevent default - allow native click and dblclick to fire\n return;\n }\n\n // When enabled, prevent the native click event from propagating\n event.preventDefault();\n event.stopPropagation();\n event.stopImmediatePropagation();\n\n if (clickGap > 0 && clickGap < duration) {\n // Double-click detected - clear pending single click and emit double-click\n if (this.clickTimeout) {\n clearTimeout(this.clickTimeout);\n this.clickTimeout = null;\n }\n if (this.pendingClickEvent) {\n this.pendingClickEvent = null;\n }\n this.onDblClick.emit(event);\n this.lastClick = 0;\n } else {\n // First click - store it and wait to see if a second click comes\n this.lastClick = currentTime;\n this.pendingClickEvent = event;\n\n if (this.clickTimeout) {\n clearTimeout(this.clickTimeout);\n }\n\n // Set timeout to emit single-click if no second click occurs\n this.clickTimeout = setTimeout(() => {\n // No double-click detected, emit single-click\n if (this.pendingClickEvent) {\n this.onClick.emit(this.pendingClickEvent);\n this.pendingClickEvent = null;\n }\n this.lastClick = 0;\n this.clickTimeout = null;\n }, duration);\n }\n }\n\n /**\n * Handles touchend events (mobile) to detect double-tap.\n * When disabled is true, allows native touch behavior.\n */\n onTouchEnd(event: TouchEvent): void {\n // If disabled, let native events fire normally\n if (this.disabled()) {\n return;\n }\n\n const duration = this.duration();\n const currentTime = new Date().getTime();\n const tapGap = currentTime - this.lastTap;\n\n if (tapGap > 0 && tapGap < duration) {\n // Detected a double-tap\n this.onDblClick.emit(event);\n event.preventDefault(); // Prevent further default actions\n }\n this.lastTap = currentTime;\n }\n\n ngOnDestroy(): void {\n if (this.clickTimeout) {\n clearTimeout(this.clickTimeout);\n this.clickTimeout = null;\n }\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import * as _angular_core from '@angular/core';
|
|
2
|
-
import { OnDestroy } from '@angular/core';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Directive to detect single-click and double-click events on the host element.
|
|
6
|
-
* Supports both desktop (click-based detection) and mobile (touchend) events.
|
|
7
|
-
* Prevents native click event propagation and emits separate single-click and double-click events.
|
|
8
|
-
* Can be disabled to allow native DOM behavior (click and dblclick events).
|
|
9
|
-
*
|
|
10
|
-
* Usage:
|
|
11
|
-
* <button
|
|
12
|
-
* axDoubleClick
|
|
13
|
-
* [duration]="300"
|
|
14
|
-
* [disabled]="false"
|
|
15
|
-
* (onClick)="onSingleClick($event)"
|
|
16
|
-
* (onDblClick)="onDoubleClick($event)"
|
|
17
|
-
* >Click me</button>
|
|
18
|
-
*/
|
|
19
|
-
declare class AXDoubleClickDirective implements OnDestroy {
|
|
20
|
-
private elementRef;
|
|
21
|
-
/**
|
|
22
|
-
* Input to configure the duration in milliseconds for detecting double-clicks.
|
|
23
|
-
* Defaults to 250ms.
|
|
24
|
-
* Two clicks/taps within this duration are considered a double-click.
|
|
25
|
-
*/
|
|
26
|
-
duration: _angular_core.InputSignal<number>;
|
|
27
|
-
/**
|
|
28
|
-
* Input to disable the directive's custom click handling.
|
|
29
|
-
* When true, native click and dblclick events will fire normally (DOM default behavior).
|
|
30
|
-
* When false (default), the directive prevents default and emits custom single/double-click events.
|
|
31
|
-
* Defaults to false.
|
|
32
|
-
*/
|
|
33
|
-
disabled: _angular_core.InputSignal<boolean>;
|
|
34
|
-
/**
|
|
35
|
-
* Output event emitted when a single-click is detected.
|
|
36
|
-
* Emits after the configured duration milliseconds if no second click occurs.
|
|
37
|
-
* Emits the MouseEvent.
|
|
38
|
-
*/
|
|
39
|
-
onClick: _angular_core.OutputEmitterRef<MouseEvent>;
|
|
40
|
-
/**
|
|
41
|
-
* Output event emitted when a double-click is detected.
|
|
42
|
-
* Emits when two clicks occur within the configured duration milliseconds.
|
|
43
|
-
* Emits the Event (MouseEvent for desktop, TouchEvent for mobile).
|
|
44
|
-
*/
|
|
45
|
-
onDblClick: _angular_core.OutputEmitterRef<Event>;
|
|
46
|
-
private lastClick;
|
|
47
|
-
private lastTap;
|
|
48
|
-
private clickTimeout;
|
|
49
|
-
private pendingClickEvent;
|
|
50
|
-
/**
|
|
51
|
-
* Handles click events and detects both single-clicks and double-clicks.
|
|
52
|
-
* Prevents native click propagation and emits appropriate events.
|
|
53
|
-
* When disabled is true, emits click immediately, still detects double-clicks, and allows native DOM behavior (no preventDefault).
|
|
54
|
-
*/
|
|
55
|
-
handleClick(event: MouseEvent): void;
|
|
56
|
-
/**
|
|
57
|
-
* Handles touchend events (mobile) to detect double-tap.
|
|
58
|
-
* When disabled is true, allows native touch behavior.
|
|
59
|
-
*/
|
|
60
|
-
onTouchEnd(event: TouchEvent): void;
|
|
61
|
-
ngOnDestroy(): void;
|
|
62
|
-
static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXDoubleClickDirective, never>;
|
|
63
|
-
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<AXDoubleClickDirective, "[axDoubleClick]", never, { "duration": { "alias": "duration"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, { "onClick": "onClick"; "onDblClick": "onDblClick"; }, never, never, true, never>;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export { AXDoubleClickDirective };
|