@acorex/cdk 22.1.0-next.26 → 22.1.0-next.29

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.
@@ -3,8 +3,8 @@ import * as i0 from '@angular/core';
3
3
  import { inject, ElementRef, PLATFORM_ID, NgZone, input, afterNextRender, Directive } from '@angular/core';
4
4
 
5
5
  /**
6
- * Converts vertical mouse-wheel scrolling into horizontal scrolling on the host element.
7
- * Applies only when the host can scroll horizontally.
6
+ * Converts vertical mouse-wheel scrolling and pointer drag/swipe into horizontal scrolling on the host element.
7
+ * Applies only when the host can scroll horizontally. Pointer events cover mouse, touch, and pen.
8
8
  *
9
9
  * Usage:
10
10
  * <div axHorizontalScroll [speed]="150" class="overflow-x-auto">
@@ -17,7 +17,7 @@ class AXHorizontalScrollDirective {
17
17
  this.platformId = inject(PLATFORM_ID);
18
18
  this.zone = inject(NgZone);
19
19
  /**
20
- * Disables wheel-to-horizontal conversion when true.
20
+ * Disables wheel-to-horizontal conversion and pointer drag when true.
21
21
  */
22
22
  this.disabled = input(false, /* @ts-ignore */
23
23
  ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
@@ -31,12 +31,32 @@ class AXHorizontalScrollDirective {
31
31
  this.targetScrollLeft = null;
32
32
  this.scrollPosition = 0;
33
33
  this.lastFrameTime = 0;
34
+ this.pointerId = null;
35
+ this.pointerStartX = 0;
36
+ this.pointerStartY = 0;
37
+ this.pointerStartScrollLeft = 0;
38
+ this.pointerAxis = 'undecided';
39
+ this.lastPointerX = 0;
40
+ this.lastPointerTime = 0;
41
+ this.pointerVelocityX = 0;
42
+ this.suppressClickListener = null;
43
+ this.suppressClickTimer = null;
44
+ this.axisLockThreshold = 6;
45
+ this.interactiveSelector = 'input, textarea, select, option, [contenteditable]:not([contenteditable="false"])';
34
46
  this.wheelListener = (event) => this.handleWheel(event);
47
+ this.pointerDownListener = (event) => this.handlePointerDown(event);
48
+ this.pointerMoveListener = (event) => this.handlePointerMove(event);
49
+ this.pointerUpListener = (event) => this.handlePointerUp(event);
35
50
  this.#init = afterNextRender(() => {
36
51
  if (!isPlatformBrowser(this.platformId))
37
52
  return;
38
53
  this.zone.runOutsideAngular(() => {
39
54
  this.nativeElement.addEventListener('wheel', this.wheelListener, { passive: false });
55
+ this.nativeElement.addEventListener('pointerdown', this.pointerDownListener);
56
+ this.nativeElement.addEventListener('pointermove', this.pointerMoveListener, { passive: false });
57
+ this.nativeElement.addEventListener('pointerup', this.pointerUpListener);
58
+ this.nativeElement.addEventListener('pointercancel', this.pointerUpListener);
59
+ this.nativeElement.addEventListener('lostpointercapture', this.pointerUpListener);
40
60
  });
41
61
  });
42
62
  }
@@ -45,20 +65,26 @@ class AXHorizontalScrollDirective {
45
65
  if (!isPlatformBrowser(this.platformId))
46
66
  return;
47
67
  this.stopAnimation();
68
+ this.releasePointer();
69
+ this.clearClickSuppression();
48
70
  this.nativeElement.removeEventListener('wheel', this.wheelListener);
71
+ this.nativeElement.removeEventListener('pointerdown', this.pointerDownListener);
72
+ this.nativeElement.removeEventListener('pointermove', this.pointerMoveListener);
73
+ this.nativeElement.removeEventListener('pointerup', this.pointerUpListener);
74
+ this.nativeElement.removeEventListener('pointercancel', this.pointerUpListener);
75
+ this.nativeElement.removeEventListener('lostpointercapture', this.pointerUpListener);
49
76
  }
50
77
  get nativeElement() {
51
78
  return this.elementRef.nativeElement;
52
79
  }
53
80
  handleWheel(event) {
54
- if (this.disabled() || !this.canScrollHorizontally())
81
+ if (this.disabled() || this.pointerId !== null || !this.canScrollHorizontally())
55
82
  return;
56
83
  if (event.shiftKey || Math.abs(event.deltaX) > Math.abs(event.deltaY))
57
84
  return;
58
85
  if (event.deltaY === 0)
59
86
  return;
60
- const element = this.nativeElement;
61
- const maxScrollLeft = element.scrollWidth - element.clientWidth;
87
+ const maxScrollLeft = this.getMaxScrollLeft();
62
88
  this.syncScrollState();
63
89
  const currentPosition = this.targetScrollLeft ?? this.scrollPosition;
64
90
  const atStart = currentPosition <= 0 && event.deltaY < 0;
@@ -75,6 +101,110 @@ class AXHorizontalScrollDirective {
75
101
  }
76
102
  this.startAnimation();
77
103
  }
104
+ handlePointerDown(event) {
105
+ if (this.disabled() || !event.isPrimary || !this.canScrollHorizontally())
106
+ return;
107
+ if (event.pointerType === 'mouse' && event.button !== 0)
108
+ return;
109
+ if (event.target instanceof Element && event.target.closest(this.interactiveSelector))
110
+ return;
111
+ this.stopAnimation();
112
+ this.targetScrollLeft = null;
113
+ this.scrollPosition = this.nativeElement.scrollLeft;
114
+ this.pointerId = event.pointerId;
115
+ this.pointerStartX = event.clientX;
116
+ this.pointerStartY = event.clientY;
117
+ this.pointerStartScrollLeft = this.scrollPosition;
118
+ this.pointerAxis = 'undecided';
119
+ this.lastPointerX = event.clientX;
120
+ this.lastPointerTime = performance.now();
121
+ this.pointerVelocityX = 0;
122
+ }
123
+ handlePointerMove(event) {
124
+ if (this.pointerId !== event.pointerId || this.disabled())
125
+ return;
126
+ const deltaX = event.clientX - this.pointerStartX;
127
+ const deltaY = event.clientY - this.pointerStartY;
128
+ if (this.pointerAxis === 'undecided') {
129
+ if (Math.hypot(deltaX, deltaY) < this.axisLockThreshold)
130
+ return;
131
+ this.pointerAxis = Math.abs(deltaX) > Math.abs(deltaY) ? 'horizontal' : 'vertical';
132
+ if (this.pointerAxis === 'vertical') {
133
+ this.releasePointer();
134
+ return;
135
+ }
136
+ this.nativeElement.setPointerCapture(event.pointerId);
137
+ this.nativeElement.style.userSelect = 'none';
138
+ if (event.pointerType === 'mouse') {
139
+ this.nativeElement.style.cursor = 'grabbing';
140
+ }
141
+ }
142
+ if (this.pointerAxis !== 'horizontal')
143
+ return;
144
+ event.preventDefault();
145
+ const now = performance.now();
146
+ const elapsed = now - this.lastPointerTime;
147
+ if (elapsed > 0) {
148
+ this.pointerVelocityX = (event.clientX - this.lastPointerX) / elapsed;
149
+ }
150
+ this.lastPointerX = event.clientX;
151
+ this.lastPointerTime = now;
152
+ const next = Math.max(0, Math.min(this.getMaxScrollLeft(), this.pointerStartScrollLeft - deltaX));
153
+ this.applyScrollPosition(next);
154
+ }
155
+ handlePointerUp(event) {
156
+ if (this.pointerId !== event.pointerId)
157
+ return;
158
+ const wasHorizontalDrag = this.pointerAxis === 'horizontal';
159
+ const velocityX = this.pointerVelocityX;
160
+ const lastMoveAge = performance.now() - this.lastPointerTime;
161
+ this.releasePointer();
162
+ if (!wasHorizontalDrag)
163
+ return;
164
+ this.suppressClick();
165
+ if (this.speed() <= 0 || lastMoveAge > 80)
166
+ return;
167
+ const distance = -velocityX * this.speed();
168
+ if (Math.abs(distance) < 8)
169
+ return;
170
+ this.targetScrollLeft = Math.max(0, Math.min(this.getMaxScrollLeft(), this.scrollPosition + distance));
171
+ this.startAnimation();
172
+ }
173
+ releasePointer() {
174
+ if (this.pointerId === null)
175
+ return;
176
+ const pointerId = this.pointerId;
177
+ this.pointerId = null;
178
+ this.pointerAxis = 'undecided';
179
+ this.pointerVelocityX = 0;
180
+ const element = this.nativeElement;
181
+ if (element.hasPointerCapture(pointerId)) {
182
+ element.releasePointerCapture(pointerId);
183
+ }
184
+ element.style.userSelect = '';
185
+ element.style.cursor = '';
186
+ }
187
+ suppressClick() {
188
+ this.clearClickSuppression();
189
+ const preventClick = (event) => {
190
+ event.preventDefault();
191
+ event.stopImmediatePropagation();
192
+ this.clearClickSuppression();
193
+ };
194
+ this.suppressClickListener = preventClick;
195
+ this.nativeElement.addEventListener('click', preventClick, true);
196
+ this.suppressClickTimer = setTimeout(() => this.clearClickSuppression(), 400);
197
+ }
198
+ clearClickSuppression() {
199
+ if (this.suppressClickTimer !== null) {
200
+ clearTimeout(this.suppressClickTimer);
201
+ this.suppressClickTimer = null;
202
+ }
203
+ if (!this.suppressClickListener)
204
+ return;
205
+ this.nativeElement.removeEventListener('click', this.suppressClickListener, true);
206
+ this.suppressClickListener = null;
207
+ }
78
208
  syncScrollState() {
79
209
  if (this.targetScrollLeft !== null)
80
210
  return;
@@ -120,13 +250,20 @@ class AXHorizontalScrollDirective {
120
250
  const element = this.nativeElement;
121
251
  return element.scrollWidth > element.clientWidth;
122
252
  }
253
+ getMaxScrollLeft() {
254
+ const element = this.nativeElement;
255
+ return element.scrollWidth - element.clientWidth;
256
+ }
123
257
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXHorizontalScrollDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
124
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.8", type: AXHorizontalScrollDirective, isStandalone: true, selector: "[axHorizontalScroll]", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, speed: { classPropertyName: "speed", publicName: "speed", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
258
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.8", type: AXHorizontalScrollDirective, isStandalone: true, selector: "[axHorizontalScroll]", inputs: { disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, speed: { classPropertyName: "speed", publicName: "speed", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "style.touch-action": "disabled() ? null : \"pan-y\"" } }, ngImport: i0 }); }
125
259
  }
126
260
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AXHorizontalScrollDirective, decorators: [{
127
261
  type: Directive,
128
262
  args: [{
129
263
  selector: '[axHorizontalScroll]',
264
+ host: {
265
+ '[style.touch-action]': 'disabled() ? null : "pan-y"',
266
+ },
130
267
  }]
131
268
  }], propDecorators: { disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], speed: [{ type: i0.Input, args: [{ isSignal: true, alias: "speed", required: false }] }] } });
132
269
 
@@ -1 +1 @@
1
- {"version":3,"file":"acorex-cdk-horizontal-scroll.mjs","sources":["../../../../packages/cdk/horizontal-scroll/src/lib/horizontal-scroll.directive.ts","../../../../packages/cdk/horizontal-scroll/src/acorex-cdk-horizontal-scroll.ts"],"sourcesContent":["import { isPlatformBrowser } from '@angular/common';\nimport { afterNextRender, Directive, ElementRef, inject, input, NgZone, OnDestroy, PLATFORM_ID } from '@angular/core';\n\n/**\n * Converts vertical mouse-wheel scrolling into horizontal scrolling on the host element.\n * Applies only when the host can scroll horizontally.\n *\n * Usage:\n * <div axHorizontalScroll [speed]=\"150\" class=\"overflow-x-auto\">\n * ...\n * </div>\n */\n@Directive({\n selector: '[axHorizontalScroll]',\n})\nexport class AXHorizontalScrollDirective implements OnDestroy {\n private elementRef = inject(ElementRef<HTMLElement>);\n private platformId = inject(PLATFORM_ID);\n private zone = inject(NgZone);\n\n /**\n * Disables wheel-to-horizontal conversion when true.\n */\n disabled = input(false);\n\n /**\n * Horizontal scroll animation duration in milliseconds.\n * Lower values scroll faster; `0` applies the scroll instantly.\n */\n speed = input(200);\n\n private animationFrameId: number | null = null;\n private targetScrollLeft: number | null = null;\n private scrollPosition = 0;\n private lastFrameTime = 0;\n\n private readonly wheelListener = (event: WheelEvent) => this.handleWheel(event);\n\n #init = afterNextRender(() => {\n if (!isPlatformBrowser(this.platformId)) return;\n\n this.zone.runOutsideAngular(() => {\n this.nativeElement.addEventListener('wheel', this.wheelListener, { passive: false });\n });\n });\n\n ngOnDestroy(): void {\n if (!isPlatformBrowser(this.platformId)) return;\n\n this.stopAnimation();\n this.nativeElement.removeEventListener('wheel', this.wheelListener);\n }\n\n private get nativeElement(): HTMLElement {\n return this.elementRef.nativeElement;\n }\n\n private handleWheel(event: WheelEvent): void {\n if (this.disabled() || !this.canScrollHorizontally()) return;\n if (event.shiftKey || Math.abs(event.deltaX) > Math.abs(event.deltaY)) return;\n if (event.deltaY === 0) return;\n\n const element = this.nativeElement;\n const maxScrollLeft = element.scrollWidth - element.clientWidth;\n\n this.syncScrollState();\n\n const currentPosition = this.targetScrollLeft ?? this.scrollPosition;\n const atStart = currentPosition <= 0 && event.deltaY < 0;\n const atEnd = currentPosition >= maxScrollLeft && event.deltaY > 0;\n\n if (atStart || atEnd) return;\n\n event.preventDefault();\n\n const nextTarget = Math.max(0, Math.min(maxScrollLeft, currentPosition + event.deltaY));\n this.targetScrollLeft = nextTarget;\n\n if (this.speed() <= 0) {\n this.applyScrollPosition(nextTarget);\n this.targetScrollLeft = null;\n return;\n }\n\n this.startAnimation();\n }\n\n private syncScrollState(): void {\n if (this.targetScrollLeft !== null) return;\n\n this.scrollPosition = this.nativeElement.scrollLeft;\n this.targetScrollLeft = this.scrollPosition;\n }\n\n private startAnimation(): void {\n if (this.animationFrameId !== null) return;\n\n this.lastFrameTime = performance.now();\n\n const step = (currentTime: number): void => {\n const target = this.targetScrollLeft;\n\n if (target === null) {\n this.stopAnimation();\n return;\n }\n\n const deltaTime = Math.max(currentTime - this.lastFrameTime, 1);\n this.lastFrameTime = currentTime;\n\n const factor = 1 - Math.exp(-deltaTime / this.speed());\n this.scrollPosition += (target - this.scrollPosition) * factor;\n this.applyScrollPosition(this.scrollPosition);\n\n if (Math.abs(target - this.scrollPosition) < 0.5) {\n this.applyScrollPosition(target);\n this.targetScrollLeft = null;\n this.stopAnimation();\n return;\n }\n\n this.animationFrameId = requestAnimationFrame(step);\n };\n\n this.animationFrameId = requestAnimationFrame(step);\n }\n\n private applyScrollPosition(position: number): void {\n this.scrollPosition = position;\n this.nativeElement.scrollLeft = position;\n }\n\n private stopAnimation(): void {\n if (this.animationFrameId === null) return;\n\n cancelAnimationFrame(this.animationFrameId);\n this.animationFrameId = null;\n }\n\n private canScrollHorizontally(): boolean {\n const element = this.nativeElement;\n return element.scrollWidth > element.clientWidth;\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-horizontal-scroll.mjs","sources":["../../../../packages/cdk/horizontal-scroll/src/lib/horizontal-scroll.directive.ts","../../../../packages/cdk/horizontal-scroll/src/acorex-cdk-horizontal-scroll.ts"],"sourcesContent":["import { isPlatformBrowser } from '@angular/common';\nimport { afterNextRender, Directive, ElementRef, inject, input, NgZone, OnDestroy, PLATFORM_ID } from '@angular/core';\n\n/**\n * Converts vertical mouse-wheel scrolling and pointer drag/swipe into horizontal scrolling on the host element.\n * Applies only when the host can scroll horizontally. Pointer events cover mouse, touch, and pen.\n *\n * Usage:\n * <div axHorizontalScroll [speed]=\"150\" class=\"overflow-x-auto\">\n * ...\n * </div>\n */\n@Directive({\n selector: '[axHorizontalScroll]',\n host: {\n '[style.touch-action]': 'disabled() ? null : \"pan-y\"',\n },\n})\nexport class AXHorizontalScrollDirective implements OnDestroy {\n private elementRef = inject(ElementRef<HTMLElement>);\n private platformId = inject(PLATFORM_ID);\n private zone = inject(NgZone);\n\n /**\n * Disables wheel-to-horizontal conversion and pointer drag when true.\n */\n disabled = input(false);\n\n /**\n * Horizontal scroll animation duration in milliseconds.\n * Lower values scroll faster; `0` applies the scroll instantly.\n */\n speed = input(200);\n\n private animationFrameId: number | null = null;\n private targetScrollLeft: number | null = null;\n private scrollPosition = 0;\n private lastFrameTime = 0;\n\n private pointerId: number | null = null;\n private pointerStartX = 0;\n private pointerStartY = 0;\n private pointerStartScrollLeft = 0;\n private pointerAxis: 'undecided' | 'horizontal' | 'vertical' = 'undecided';\n private lastPointerX = 0;\n private lastPointerTime = 0;\n private pointerVelocityX = 0;\n private suppressClickListener: ((event: Event) => void) | null = null;\n private suppressClickTimer: ReturnType<typeof setTimeout> | null = null;\n\n private readonly axisLockThreshold = 6;\n private readonly interactiveSelector =\n 'input, textarea, select, option, [contenteditable]:not([contenteditable=\"false\"])';\n\n private readonly wheelListener = (event: WheelEvent) => this.handleWheel(event);\n private readonly pointerDownListener = (event: PointerEvent) => this.handlePointerDown(event);\n private readonly pointerMoveListener = (event: PointerEvent) => this.handlePointerMove(event);\n private readonly pointerUpListener = (event: PointerEvent) => this.handlePointerUp(event);\n\n #init = afterNextRender(() => {\n if (!isPlatformBrowser(this.platformId)) return;\n\n this.zone.runOutsideAngular(() => {\n this.nativeElement.addEventListener('wheel', this.wheelListener, { passive: false });\n this.nativeElement.addEventListener('pointerdown', this.pointerDownListener);\n this.nativeElement.addEventListener('pointermove', this.pointerMoveListener, { passive: false });\n this.nativeElement.addEventListener('pointerup', this.pointerUpListener);\n this.nativeElement.addEventListener('pointercancel', this.pointerUpListener);\n this.nativeElement.addEventListener('lostpointercapture', this.pointerUpListener);\n });\n });\n\n ngOnDestroy(): void {\n if (!isPlatformBrowser(this.platformId)) return;\n\n this.stopAnimation();\n this.releasePointer();\n this.clearClickSuppression();\n this.nativeElement.removeEventListener('wheel', this.wheelListener);\n this.nativeElement.removeEventListener('pointerdown', this.pointerDownListener);\n this.nativeElement.removeEventListener('pointermove', this.pointerMoveListener);\n this.nativeElement.removeEventListener('pointerup', this.pointerUpListener);\n this.nativeElement.removeEventListener('pointercancel', this.pointerUpListener);\n this.nativeElement.removeEventListener('lostpointercapture', this.pointerUpListener);\n }\n\n private get nativeElement(): HTMLElement {\n return this.elementRef.nativeElement;\n }\n\n private handleWheel(event: WheelEvent): void {\n if (this.disabled() || this.pointerId !== null || !this.canScrollHorizontally()) return;\n if (event.shiftKey || Math.abs(event.deltaX) > Math.abs(event.deltaY)) return;\n if (event.deltaY === 0) return;\n\n const maxScrollLeft = this.getMaxScrollLeft();\n\n this.syncScrollState();\n\n const currentPosition = this.targetScrollLeft ?? this.scrollPosition;\n const atStart = currentPosition <= 0 && event.deltaY < 0;\n const atEnd = currentPosition >= maxScrollLeft && event.deltaY > 0;\n\n if (atStart || atEnd) return;\n\n event.preventDefault();\n\n const nextTarget = Math.max(0, Math.min(maxScrollLeft, currentPosition + event.deltaY));\n this.targetScrollLeft = nextTarget;\n\n if (this.speed() <= 0) {\n this.applyScrollPosition(nextTarget);\n this.targetScrollLeft = null;\n return;\n }\n\n this.startAnimation();\n }\n\n private handlePointerDown(event: PointerEvent): void {\n if (this.disabled() || !event.isPrimary || !this.canScrollHorizontally()) return;\n if (event.pointerType === 'mouse' && event.button !== 0) return;\n if (event.target instanceof Element && event.target.closest(this.interactiveSelector)) return;\n\n this.stopAnimation();\n this.targetScrollLeft = null;\n this.scrollPosition = this.nativeElement.scrollLeft;\n\n this.pointerId = event.pointerId;\n this.pointerStartX = event.clientX;\n this.pointerStartY = event.clientY;\n this.pointerStartScrollLeft = this.scrollPosition;\n this.pointerAxis = 'undecided';\n this.lastPointerX = event.clientX;\n this.lastPointerTime = performance.now();\n this.pointerVelocityX = 0;\n }\n\n private handlePointerMove(event: PointerEvent): void {\n if (this.pointerId !== event.pointerId || this.disabled()) return;\n\n const deltaX = event.clientX - this.pointerStartX;\n const deltaY = event.clientY - this.pointerStartY;\n\n if (this.pointerAxis === 'undecided') {\n if (Math.hypot(deltaX, deltaY) < this.axisLockThreshold) return;\n\n this.pointerAxis = Math.abs(deltaX) > Math.abs(deltaY) ? 'horizontal' : 'vertical';\n\n if (this.pointerAxis === 'vertical') {\n this.releasePointer();\n return;\n }\n\n this.nativeElement.setPointerCapture(event.pointerId);\n this.nativeElement.style.userSelect = 'none';\n if (event.pointerType === 'mouse') {\n this.nativeElement.style.cursor = 'grabbing';\n }\n }\n\n if (this.pointerAxis !== 'horizontal') return;\n\n event.preventDefault();\n\n const now = performance.now();\n const elapsed = now - this.lastPointerTime;\n if (elapsed > 0) {\n this.pointerVelocityX = (event.clientX - this.lastPointerX) / elapsed;\n }\n this.lastPointerX = event.clientX;\n this.lastPointerTime = now;\n\n const next = Math.max(0, Math.min(this.getMaxScrollLeft(), this.pointerStartScrollLeft - deltaX));\n this.applyScrollPosition(next);\n }\n\n private handlePointerUp(event: PointerEvent): void {\n if (this.pointerId !== event.pointerId) return;\n\n const wasHorizontalDrag = this.pointerAxis === 'horizontal';\n const velocityX = this.pointerVelocityX;\n const lastMoveAge = performance.now() - this.lastPointerTime;\n\n this.releasePointer();\n\n if (!wasHorizontalDrag) return;\n\n this.suppressClick();\n\n if (this.speed() <= 0 || lastMoveAge > 80) return;\n\n const distance = -velocityX * this.speed();\n if (Math.abs(distance) < 8) return;\n\n this.targetScrollLeft = Math.max(0, Math.min(this.getMaxScrollLeft(), this.scrollPosition + distance));\n this.startAnimation();\n }\n\n private releasePointer(): void {\n if (this.pointerId === null) return;\n\n const pointerId = this.pointerId;\n this.pointerId = null;\n this.pointerAxis = 'undecided';\n this.pointerVelocityX = 0;\n\n const element = this.nativeElement;\n if (element.hasPointerCapture(pointerId)) {\n element.releasePointerCapture(pointerId);\n }\n\n element.style.userSelect = '';\n element.style.cursor = '';\n }\n\n private suppressClick(): void {\n this.clearClickSuppression();\n\n const preventClick = (event: Event): void => {\n event.preventDefault();\n event.stopImmediatePropagation();\n this.clearClickSuppression();\n };\n\n this.suppressClickListener = preventClick;\n this.nativeElement.addEventListener('click', preventClick, true);\n this.suppressClickTimer = setTimeout(() => this.clearClickSuppression(), 400);\n }\n\n private clearClickSuppression(): void {\n if (this.suppressClickTimer !== null) {\n clearTimeout(this.suppressClickTimer);\n this.suppressClickTimer = null;\n }\n\n if (!this.suppressClickListener) return;\n\n this.nativeElement.removeEventListener('click', this.suppressClickListener, true);\n this.suppressClickListener = null;\n }\n\n private syncScrollState(): void {\n if (this.targetScrollLeft !== null) return;\n\n this.scrollPosition = this.nativeElement.scrollLeft;\n this.targetScrollLeft = this.scrollPosition;\n }\n\n private startAnimation(): void {\n if (this.animationFrameId !== null) return;\n\n this.lastFrameTime = performance.now();\n\n const step = (currentTime: number): void => {\n const target = this.targetScrollLeft;\n\n if (target === null) {\n this.stopAnimation();\n return;\n }\n\n const deltaTime = Math.max(currentTime - this.lastFrameTime, 1);\n this.lastFrameTime = currentTime;\n\n const factor = 1 - Math.exp(-deltaTime / this.speed());\n this.scrollPosition += (target - this.scrollPosition) * factor;\n this.applyScrollPosition(this.scrollPosition);\n\n if (Math.abs(target - this.scrollPosition) < 0.5) {\n this.applyScrollPosition(target);\n this.targetScrollLeft = null;\n this.stopAnimation();\n return;\n }\n\n this.animationFrameId = requestAnimationFrame(step);\n };\n\n this.animationFrameId = requestAnimationFrame(step);\n }\n\n private applyScrollPosition(position: number): void {\n this.scrollPosition = position;\n this.nativeElement.scrollLeft = position;\n }\n\n private stopAnimation(): void {\n if (this.animationFrameId === null) return;\n\n cancelAnimationFrame(this.animationFrameId);\n this.animationFrameId = null;\n }\n\n private canScrollHorizontally(): boolean {\n const element = this.nativeElement;\n return element.scrollWidth > element.clientWidth;\n }\n\n private getMaxScrollLeft(): number {\n const element = this.nativeElement;\n return element.scrollWidth - element.clientWidth;\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -2,4 +2,4 @@
2
2
 
3
3
  Secondary entry point of `@acorex/cdk`. It can be used by importing from `@acorex/cdk/horizontal-scroll`.
4
4
 
5
- Converts vertical mouse-wheel scrolling into horizontal scrolling on scrollable host elements.
5
+ Converts vertical mouse-wheel scrolling and pointer drag/swipe into horizontal scrolling on scrollable host elements. Pointer events cover mouse, touch, and pen.
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@acorex/cdk",
3
- "version": "22.1.0-next.26",
3
+ "version": "22.1.0-next.29",
4
4
  "peerDependencies": {
5
- "@acorex/core": "22.1.0-next.26",
5
+ "@acorex/core": "22.1.0-next.29",
6
6
  "quill": ">=2.0.2",
7
7
  "qrcode": ">=1.5.4",
8
8
  "swiper": ">=11.1.15",
@@ -2,8 +2,8 @@ import * as _angular_core from '@angular/core';
2
2
  import { OnDestroy } from '@angular/core';
3
3
 
4
4
  /**
5
- * Converts vertical mouse-wheel scrolling into horizontal scrolling on the host element.
6
- * Applies only when the host can scroll horizontally.
5
+ * Converts vertical mouse-wheel scrolling and pointer drag/swipe into horizontal scrolling on the host element.
6
+ * Applies only when the host can scroll horizontally. Pointer events cover mouse, touch, and pen.
7
7
  *
8
8
  * Usage:
9
9
  * <div axHorizontalScroll [speed]="150" class="overflow-x-auto">
@@ -16,7 +16,7 @@ declare class AXHorizontalScrollDirective implements OnDestroy {
16
16
  private platformId;
17
17
  private zone;
18
18
  /**
19
- * Disables wheel-to-horizontal conversion when true.
19
+ * Disables wheel-to-horizontal conversion and pointer drag when true.
20
20
  */
21
21
  disabled: _angular_core.InputSignal<boolean>;
22
22
  /**
@@ -28,15 +28,37 @@ declare class AXHorizontalScrollDirective implements OnDestroy {
28
28
  private targetScrollLeft;
29
29
  private scrollPosition;
30
30
  private lastFrameTime;
31
+ private pointerId;
32
+ private pointerStartX;
33
+ private pointerStartY;
34
+ private pointerStartScrollLeft;
35
+ private pointerAxis;
36
+ private lastPointerX;
37
+ private lastPointerTime;
38
+ private pointerVelocityX;
39
+ private suppressClickListener;
40
+ private suppressClickTimer;
41
+ private readonly axisLockThreshold;
42
+ private readonly interactiveSelector;
31
43
  private readonly wheelListener;
44
+ private readonly pointerDownListener;
45
+ private readonly pointerMoveListener;
46
+ private readonly pointerUpListener;
32
47
  ngOnDestroy(): void;
33
48
  private get nativeElement();
34
49
  private handleWheel;
50
+ private handlePointerDown;
51
+ private handlePointerMove;
52
+ private handlePointerUp;
53
+ private releasePointer;
54
+ private suppressClick;
55
+ private clearClickSuppression;
35
56
  private syncScrollState;
36
57
  private startAnimation;
37
58
  private applyScrollPosition;
38
59
  private stopAnimation;
39
60
  private canScrollHorizontally;
61
+ private getMaxScrollLeft;
40
62
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<AXHorizontalScrollDirective, never>;
41
63
  static ɵdir: _angular_core.ɵɵDirectiveDeclaration<AXHorizontalScrollDirective, "[axHorizontalScroll]", never, { "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "speed": { "alias": "speed"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
42
64
  }