wally-ui 1.11.1 → 1.11.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wally-ui",
3
- "version": "1.11.1",
3
+ "version": "1.11.2",
4
4
  "description": "About Where’s Wally? Right here — bringing you ready-to-use Angular components with Wally-UI. Stop searching, start building.",
5
5
  "bin": {
6
6
  "wally": "dist/cli.js"
@@ -1,36 +1,4 @@
1
1
  <div class="w-full h-full flex flex-col items-center gap-4 p-2">
2
- <div class="w-full h-full flex items-center gap-3">
3
- <div>
4
- <button type="button"
5
- class="group hidden sm:block bg-neutral-100 hover:bg-neutral-200 border-2 border-neutral-200 hover:border-neutral-300 dark:bg-[#1b1b1b] dark:hover:bg-[#1d1d1d] dark:border-neutral-700 hover:dark:border-neutral-600 p-2 rounded-full cursor-pointer transition-all duration-500 ease-in-out"
6
- aria-label="Go to previous slide">
7
- <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2"
8
- stroke="currentColor"
9
- class="size-5 text-neutral-500 dark:text-neutral-300 group-hover:dark:text-white transition-all duration-500 ease-in-out">
10
- <path stroke-linecap="round" stroke-linejoin="round" d="M10.5 19.5 3 12m0 0 7.5-7.5M3 12h18" />
11
- </svg>
12
- </button>
13
- </div>
14
-
15
- <div #carouselContainer class="w-full h-full flex gap-2">
16
- <ng-content></ng-content>
17
- </div>
18
-
19
- <div>
20
- <button type="button"
21
- class="group hidden sm:block bg-neutral-100 hover:bg-neutral-200 border-2 border-neutral-200 hover:border-neutral-300 dark:bg-[#1b1b1b] dark:hover:bg-[#1d1d1d] dark:border-neutral-700 hover:dark:border-neutral-600 p-2 rounded-full cursor-pointer transition-all duration-500 ease-in-out"
22
- aria-label="Go to next slide">
23
- <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2"
24
- stroke="currentColor"
25
- class="size-5 text-neutral-500 dark:text-neutral-300 group-hover:dark:text-white transition-all duration-500 ease-in-out">
26
- <path stroke-linecap="round" stroke-linejoin="round" d="M13.5 4.5 21 12m0 0-7.5 7.5M21 12H3" />
27
- </svg>
28
- </button>
29
- </div>
30
- </div>
31
- </div>
32
-
33
- <!-- <div class="w-full h-full flex flex-col items-center gap-4 p-2">
34
2
  <div class="w-full h-full flex items-center gap-3">
35
3
  <div>
36
4
  <button type="button"
@@ -75,4 +43,4 @@
75
43
  }
76
44
  </div>
77
45
  }
78
- </div> -->
46
+ </div>
@@ -10,276 +10,225 @@ import { it } from 'node:test';
10
10
  export class Carousel implements AfterViewInit {
11
11
  @ViewChild('carouselContainer', { static: false }) carouselContainer!: ElementRef;
12
12
 
13
+ isNavigationIndicator: InputSignal<boolean> = input<boolean>(false);
14
+ totalItemsCount: WritableSignal<number> = signal<number>(0);
15
+ currentVisibleItemIndex: WritableSignal<number> = signal<number>(0);
13
16
  carouselItemElements: HTMLElement[] = [];
14
17
 
18
+ private gestureState = {
19
+ startPositionX: 0,
20
+ startPositionY: 0,
21
+ currentPositionX: 0,
22
+ currentPositionY: 0,
23
+ isCurrentlyDragging: false,
24
+ gestureStartTime: 0
25
+ };
26
+
27
+ private readonly MINIMUM_SWIPE_DISTANCE = 50;
28
+ private readonly MINIMUM_SWIPE_VELOCITY = 0.3;
29
+ private readonly MAXIMUM_SWIPE_DURATION = 300;
30
+
31
+ private eventListenerCleanupFunctions: (() => void)[] = [];
32
+
33
+ get navigationIndicatorsArray() {
34
+ return Array(this.totalItemsCount()).fill(0);
35
+ }
36
+
15
37
  constructor(
16
38
  private renderer: Renderer2
17
39
  ) { }
18
40
 
19
41
  ngAfterViewInit(): void {
20
- console.log('carouselContainer', this.carouselContainer.nativeElement.children);
42
+ if (this.carouselContainer) {
43
+ this.initializeCarouselItems();
44
+ this.setupTouchAndMouseEvents();
45
+ this.setupAccessibilityAttributes();
46
+ }
47
+ }
21
48
 
22
- this.carouselItemElements = Array.from(this.carouselContainer.nativeElement.children);
23
- console.log('carouselItemElements', this.carouselItemElements);
49
+ ngOnDestroy(): void {
50
+ this.eventListenerCleanupFunctions.forEach(cleanupFunction => cleanupFunction());
51
+ }
52
+
53
+ calculateNextItemIndex(currentItemIndex: number): number {
54
+ return (currentItemIndex + 1) % this.totalItemsCount();
55
+ }
24
56
 
57
+ calculatePreviousItemIndex(currentItemIndex: number): number {
58
+ return (currentItemIndex - 1 + this.totalItemsCount()) % this.totalItemsCount();
59
+ }
60
+
61
+ navigateToNextItem(): void {
62
+ this.currentVisibleItemIndex.set(this.calculateNextItemIndex(this.currentVisibleItemIndex()));
63
+ this.updateAllItemElementPositions();
64
+ }
25
65
 
66
+ navigateToPreviousItem(): void {
67
+ this.currentVisibleItemIndex.set(this.calculatePreviousItemIndex(this.currentVisibleItemIndex()));
68
+ this.updateAllItemElementPositions();
69
+ }
70
+
71
+ navigateToSpecificItem(targetItemIndex: number): void {
72
+ this.currentVisibleItemIndex.set(targetItemIndex);
73
+ this.updateAllItemElementPositions();
74
+ }
75
+
76
+ updateItemElementPosition(carouselItemElement: HTMLElement, itemIndex: number): void {
77
+ const currentVisibleIndex = this.currentVisibleItemIndex();
78
+
79
+ if (itemIndex === currentVisibleIndex) {
80
+ this.renderer.setStyle(carouselItemElement, 'transform', 'translateX(0)');
81
+ } else if (itemIndex > currentVisibleIndex) {
82
+ this.renderer.setStyle(carouselItemElement, 'transform', 'translateX(110%)');
83
+ } else {
84
+ this.renderer.setStyle(carouselItemElement, 'transform', 'translateX(-110%)');
85
+ }
86
+ }
87
+
88
+ updateAllItemElementPositions(): void {
26
89
  this.carouselItemElements.forEach((itemElement, itemIndex) => {
27
- // this.renderer.setStyle(itemElement, 'position', 'absolute');
28
- // this.renderer.setStyle(itemElement, 'display', 'flex');
29
- // this.renderer.setStyle(itemElement, 'align-items', 'center');
30
- // this.renderer.setStyle(itemElement, 'justify-content', 'center');
31
- // this.renderer.setStyle(itemElement, 'inset', '0');
32
- // this.renderer.setStyle(itemElement, 'padding', '8px');
33
- // this.renderer.setStyle(itemElement, 'border-radius', '8px');
34
- // this.renderer.setStyle(itemElement, 'transition', 'transform 700ms ease-out');
35
-
36
- // this.renderer.addClass(item, 'flex flex-col items-center gap-4 p-2 rounded-sm transition-all duration-700 ease-in-out');
90
+ this.updateItemElementPosition(itemElement, itemIndex);
37
91
  });
92
+ }
93
+
94
+ @HostListener('keydown', ['$event'])
95
+ handleKeyboardNavigation(keyboardEvent: KeyboardEvent): void {
96
+ switch (keyboardEvent.key) {
97
+ case 'ArrowLeft':
98
+ keyboardEvent.preventDefault();
99
+ this.navigateToPreviousItem();
100
+ break;
101
+ case 'ArrowRight':
102
+ keyboardEvent.preventDefault();
103
+ this.navigateToNextItem();
104
+ break;
105
+ case 'Home':
106
+ keyboardEvent.preventDefault();
107
+ this.navigateToSpecificItem(0);
108
+ break;
109
+ case 'End':
110
+ keyboardEvent.preventDefault();
111
+ this.navigateToSpecificItem(this.totalItemsCount() - 1);
112
+ break;
113
+ }
114
+ }
115
+
116
+ private initializeCarouselItems(): void {
117
+ this.carouselItemElements = Array.from(this.carouselContainer.nativeElement.children);
118
+ this.totalItemsCount.set(this.carouselItemElements.length);
38
119
 
39
120
  this.carouselItemElements.forEach((itemElement, itemIndex) => {
121
+ this.renderer.setStyle(itemElement, 'position', 'absolute');
122
+ this.renderer.setStyle(itemElement, 'inset', '0');
123
+ this.renderer.setStyle(itemElement, 'transition', 'transform 700ms ease-out');
124
+ this.renderer.setStyle(itemElement, 'display', 'flex');
125
+ this.renderer.setStyle(itemElement, 'align-items', 'center');
126
+ this.renderer.setStyle(itemElement, 'justify-content', 'center');
40
127
  this.updateItemElementPosition(itemElement, itemIndex);
41
128
  });
42
129
  }
43
130
 
44
- updateItemElementPosition(carouselItemElement: HTMLElement, itemIndex: number): void {
45
- // const currentVisibleIndex = this.currentVisibleItemIndex();
131
+ private setupTouchAndMouseEvents(): void {
132
+ const carouselContainerElement = this.carouselContainer.nativeElement;
133
+
134
+ const touchStartListener = this.renderer.listen(carouselContainerElement, 'touchstart', (event) => this.handleTouchStart(event));
135
+ const touchMoveListener = this.renderer.listen(carouselContainerElement, 'touchmove', (event) => this.handleTouchMove(event));
136
+ const touchEndListener = this.renderer.listen(carouselContainerElement, 'touchend', () => this.handleTouchEnd());
137
+
138
+ const mouseDownListener = this.renderer.listen(carouselContainerElement, 'mousedown', (event) => this.handleMouseDown(event));
139
+ const mouseMoveListener = this.renderer.listen(carouselContainerElement, 'mousemove', (event) => this.handleMouseMove(event));
140
+ const mouseUpListener = this.renderer.listen(carouselContainerElement, 'mouseup', () => this.handleMouseUp());
141
+ const mouseLeaveListener = this.renderer.listen(carouselContainerElement, 'mouseleave', () => this.handleMouseUp());
142
+
143
+ this.eventListenerCleanupFunctions.push(
144
+ touchStartListener,
145
+ touchMoveListener,
146
+ touchEndListener,
147
+ mouseDownListener,
148
+ mouseMoveListener,
149
+ mouseUpListener,
150
+ mouseLeaveListener
151
+ );
152
+
153
+ this.renderer.setStyle(carouselContainerElement, 'touch-action', 'pan-x');
154
+ }
155
+
156
+ private setupAccessibilityAttributes(): void {
157
+ const carouselContainerElement = this.carouselContainer.nativeElement;
46
158
 
47
- // if (itemIndex === currentVisibleIndex) {
48
- if (itemIndex === 2) {
49
- console.log('itemIndex', itemIndex);
50
- this.renderer.setStyle(carouselItemElement, 'transform', 'translateX(10%)');
159
+ this.renderer.setAttribute(carouselContainerElement, 'role', 'region');
160
+ this.renderer.setAttribute(carouselContainerElement, 'aria-label', 'Carousel');
161
+ this.renderer.setAttribute(carouselContainerElement, 'tabindex', '0');
162
+ }
163
+
164
+ private handleTouchStart(touchEvent: TouchEvent): void {
165
+ this.initializeGesture(touchEvent.touches[0].clientX, touchEvent.touches[0].clientY);
166
+ }
167
+
168
+ private handleTouchMove(touchEvent: TouchEvent): void {
169
+ if (this.gestureState.isCurrentlyDragging) {
170
+ touchEvent.preventDefault();
171
+ this.updateGesturePosition(touchEvent.touches[0].clientX, touchEvent.touches[0].clientY);
51
172
  }
52
- if (itemIndex !== 2) {
53
- this.renderer.setStyle(carouselItemElement, 'transform', 'translateX(0)');
173
+ }
174
+
175
+ private handleTouchEnd(): void {
176
+ this.finalizeGestureAndNavigate();
177
+ }
178
+
179
+ private handleMouseDown(mouseEvent: MouseEvent): void {
180
+ this.initializeGesture(mouseEvent.clientX, mouseEvent.clientY);
181
+ }
182
+
183
+ private handleMouseMove(mouseEvent: MouseEvent): void {
184
+ if (this.gestureState.isCurrentlyDragging) {
185
+ mouseEvent.preventDefault();
186
+ this.updateGesturePosition(mouseEvent.clientX, mouseEvent.clientY);
54
187
  }
55
- // } else if (itemIndex > currentVisibleIndex) {
56
- // this.renderer.setStyle(carouselItemElement, 'transform', 'translateX(110%)');
57
- // } else {
58
- // this.renderer.setStyle(carouselItemElement, 'transform', 'translateX(-110%)');
59
- // }
60
188
  }
61
189
 
62
- // @ViewChild('carouselContainer', { static: false }) carouselContainer!: ElementRef;
63
-
64
- // isNavigationIndicator: InputSignal<boolean> = input<boolean>(false);
65
- // totalItemsCount: WritableSignal<number> = signal<number>(0);
66
- // currentVisibleItemIndex: WritableSignal<number> = signal<number>(0);
67
- // carouselItemElements: HTMLElement[] = [];
68
-
69
- // private gestureState = {
70
- // startPositionX: 0,
71
- // startPositionY: 0,
72
- // currentPositionX: 0,
73
- // currentPositionY: 0,
74
- // isCurrentlyDragging: false,
75
- // gestureStartTime: 0
76
- // };
77
-
78
- // private readonly MINIMUM_SWIPE_DISTANCE = 50;
79
- // private readonly MINIMUM_SWIPE_VELOCITY = 0.3;
80
- // private readonly MAXIMUM_SWIPE_DURATION = 300;
81
-
82
- // private eventListenerCleanupFunctions: (() => void)[] = [];
83
-
84
- // get navigationIndicatorsArray() {
85
- // return Array(this.totalItemsCount()).fill(0);
86
- // }
87
-
88
- // constructor(
89
- // private renderer: Renderer2
90
- // ) { }
91
-
92
- // ngAfterViewInit(): void {
93
- // if (this.carouselContainer) {
94
- // this.initializeCarouselItems();
95
- // this.setupTouchAndMouseEvents();
96
- // this.setupAccessibilityAttributes();
97
- // }
98
- // }
99
-
100
- // ngOnDestroy(): void {
101
- // this.eventListenerCleanupFunctions.forEach(cleanupFunction => cleanupFunction());
102
- // }
103
-
104
- // calculateNextItemIndex(currentItemIndex: number): number {
105
- // return (currentItemIndex + 1) % this.totalItemsCount();
106
- // }
107
-
108
- // calculatePreviousItemIndex(currentItemIndex: number): number {
109
- // return (currentItemIndex - 1 + this.totalItemsCount()) % this.totalItemsCount();
110
- // }
111
-
112
- // navigateToNextItem(): void {
113
- // this.currentVisibleItemIndex.set(this.calculateNextItemIndex(this.currentVisibleItemIndex()));
114
- // this.updateAllItemElementPositions();
115
- // }
116
-
117
- // navigateToPreviousItem(): void {
118
- // this.currentVisibleItemIndex.set(this.calculatePreviousItemIndex(this.currentVisibleItemIndex()));
119
- // this.updateAllItemElementPositions();
120
- // }
121
-
122
- // navigateToSpecificItem(targetItemIndex: number): void {
123
- // this.currentVisibleItemIndex.set(targetItemIndex);
124
- // this.updateAllItemElementPositions();
125
- // }
126
-
127
- // updateItemElementPosition(carouselItemElement: HTMLElement, itemIndex: number): void {
128
- // const currentVisibleIndex = this.currentVisibleItemIndex();
129
-
130
- // if (itemIndex === currentVisibleIndex) {
131
- // this.renderer.setStyle(carouselItemElement, 'transform', 'translateX(0)');
132
- // } else if (itemIndex > currentVisibleIndex) {
133
- // this.renderer.setStyle(carouselItemElement, 'transform', 'translateX(110%)');
134
- // } else {
135
- // this.renderer.setStyle(carouselItemElement, 'transform', 'translateX(-110%)');
136
- // }
137
- // }
138
-
139
- // updateAllItemElementPositions(): void {
140
- // this.carouselItemElements.forEach((itemElement, itemIndex) => {
141
- // this.updateItemElementPosition(itemElement, itemIndex);
142
- // });
143
- // }
144
-
145
- // @HostListener('keydown', ['$event'])
146
- // handleKeyboardNavigation(keyboardEvent: KeyboardEvent): void {
147
- // switch (keyboardEvent.key) {
148
- // case 'ArrowLeft':
149
- // keyboardEvent.preventDefault();
150
- // this.navigateToPreviousItem();
151
- // break;
152
- // case 'ArrowRight':
153
- // keyboardEvent.preventDefault();
154
- // this.navigateToNextItem();
155
- // break;
156
- // case 'Home':
157
- // keyboardEvent.preventDefault();
158
- // this.navigateToSpecificItem(0);
159
- // break;
160
- // case 'End':
161
- // keyboardEvent.preventDefault();
162
- // this.navigateToSpecificItem(this.totalItemsCount() - 1);
163
- // break;
164
- // }
165
- // }
166
-
167
- // private initializeCarouselItems(): void {
168
- // this.carouselItemElements = Array.from(this.carouselContainer.nativeElement.children);
169
- // this.totalItemsCount.set(this.carouselItemElements.length);
170
-
171
- // this.carouselItemElements.forEach((itemElement, itemIndex) => {
172
- // this.renderer.setStyle(itemElement, 'position', 'absolute');
173
- // this.renderer.setStyle(itemElement, 'inset', '0');
174
- // this.renderer.setStyle(itemElement, 'transition', 'transform 700ms ease-out');
175
- // this.renderer.setStyle(itemElement, 'display', 'flex');
176
- // this.renderer.setStyle(itemElement, 'align-items', 'center');
177
- // this.renderer.setStyle(itemElement, 'justify-content', 'center');
178
- // this.updateItemElementPosition(itemElement, itemIndex);
179
- // });
180
- // }
181
-
182
- // private setupTouchAndMouseEvents(): void {
183
- // const carouselContainerElement = this.carouselContainer.nativeElement;
184
-
185
- // const touchStartListener = this.renderer.listen(carouselContainerElement, 'touchstart', (event) => this.handleTouchStart(event));
186
- // const touchMoveListener = this.renderer.listen(carouselContainerElement, 'touchmove', (event) => this.handleTouchMove(event));
187
- // const touchEndListener = this.renderer.listen(carouselContainerElement, 'touchend', () => this.handleTouchEnd());
188
-
189
- // const mouseDownListener = this.renderer.listen(carouselContainerElement, 'mousedown', (event) => this.handleMouseDown(event));
190
- // const mouseMoveListener = this.renderer.listen(carouselContainerElement, 'mousemove', (event) => this.handleMouseMove(event));
191
- // const mouseUpListener = this.renderer.listen(carouselContainerElement, 'mouseup', () => this.handleMouseUp());
192
- // const mouseLeaveListener = this.renderer.listen(carouselContainerElement, 'mouseleave', () => this.handleMouseUp());
193
-
194
- // this.eventListenerCleanupFunctions.push(
195
- // touchStartListener,
196
- // touchMoveListener,
197
- // touchEndListener,
198
- // mouseDownListener,
199
- // mouseMoveListener,
200
- // mouseUpListener,
201
- // mouseLeaveListener
202
- // );
203
-
204
- // this.renderer.setStyle(carouselContainerElement, 'touch-action', 'pan-x');
205
- // }
206
-
207
- // private setupAccessibilityAttributes(): void {
208
- // const carouselContainerElement = this.carouselContainer.nativeElement;
209
-
210
- // this.renderer.setAttribute(carouselContainerElement, 'role', 'region');
211
- // this.renderer.setAttribute(carouselContainerElement, 'aria-label', 'Carousel');
212
- // this.renderer.setAttribute(carouselContainerElement, 'tabindex', '0');
213
- // }
214
-
215
- // private handleTouchStart(touchEvent: TouchEvent): void {
216
- // this.initializeGesture(touchEvent.touches[0].clientX, touchEvent.touches[0].clientY);
217
- // }
218
-
219
- // private handleTouchMove(touchEvent: TouchEvent): void {
220
- // if (this.gestureState.isCurrentlyDragging) {
221
- // touchEvent.preventDefault();
222
- // this.updateGesturePosition(touchEvent.touches[0].clientX, touchEvent.touches[0].clientY);
223
- // }
224
- // }
225
-
226
- // private handleTouchEnd(): void {
227
- // this.finalizeGestureAndNavigate();
228
- // }
229
-
230
- // private handleMouseDown(mouseEvent: MouseEvent): void {
231
- // this.initializeGesture(mouseEvent.clientX, mouseEvent.clientY);
232
- // }
233
-
234
- // private handleMouseMove(mouseEvent: MouseEvent): void {
235
- // if (this.gestureState.isCurrentlyDragging) {
236
- // mouseEvent.preventDefault();
237
- // this.updateGesturePosition(mouseEvent.clientX, mouseEvent.clientY);
238
- // }
239
- // }
240
-
241
- // private handleMouseUp(): void {
242
- // this.finalizeGestureAndNavigate();
243
- // }
244
-
245
- // private initializeGesture(xPosition: number, yPosition: number): void {
246
- // this.gestureState = {
247
- // startPositionX: xPosition,
248
- // startPositionY: yPosition,
249
- // currentPositionX: xPosition,
250
- // currentPositionY: yPosition,
251
- // isCurrentlyDragging: true,
252
- // gestureStartTime: Date.now()
253
- // };
254
- // }
255
-
256
- // private updateGesturePosition(xPosition: number, yPosition: number): void {
257
- // if (!this.gestureState.isCurrentlyDragging) return;
258
-
259
- // this.gestureState.currentPositionX = xPosition;
260
- // this.gestureState.currentPositionY = yPosition;
261
- // }
262
-
263
- // private finalizeGestureAndNavigate(): void {
264
- // if (!this.gestureState.isCurrentlyDragging) return;
265
-
266
- // const horizontalDistanceMoved = this.gestureState.currentPositionX - this.gestureState.startPositionX;
267
- // const verticalDistanceMoved = this.gestureState.currentPositionY - this.gestureState.startPositionY;
268
- // const gestureDuration = Date.now() - this.gestureState.gestureStartTime;
269
- // const gestureVelocity = Math.abs(horizontalDistanceMoved) / gestureDuration;
270
-
271
- // if (Math.abs(horizontalDistanceMoved) > Math.abs(verticalDistanceMoved)) {
272
- // const isValidSwipeGesture = Math.abs(horizontalDistanceMoved) > this.MINIMUM_SWIPE_DISTANCE ||
273
- // (gestureVelocity > this.MINIMUM_SWIPE_VELOCITY && gestureDuration < this.MAXIMUM_SWIPE_DURATION);
274
-
275
- // if (isValidSwipeGesture) {
276
- // if (horizontalDistanceMoved > 0) {
277
- // this.navigateToPreviousItem();
278
- // } else {
279
- // this.navigateToNextItem();
280
- // }
281
- // }
282
- // }
283
- // this.gestureState.isCurrentlyDragging = false;
284
- // }
190
+ private handleMouseUp(): void {
191
+ this.finalizeGestureAndNavigate();
192
+ }
193
+
194
+ private initializeGesture(xPosition: number, yPosition: number): void {
195
+ this.gestureState = {
196
+ startPositionX: xPosition,
197
+ startPositionY: yPosition,
198
+ currentPositionX: xPosition,
199
+ currentPositionY: yPosition,
200
+ isCurrentlyDragging: true,
201
+ gestureStartTime: Date.now()
202
+ };
203
+ }
204
+
205
+ private updateGesturePosition(xPosition: number, yPosition: number): void {
206
+ if (!this.gestureState.isCurrentlyDragging) return;
207
+
208
+ this.gestureState.currentPositionX = xPosition;
209
+ this.gestureState.currentPositionY = yPosition;
210
+ }
211
+
212
+ private finalizeGestureAndNavigate(): void {
213
+ if (!this.gestureState.isCurrentlyDragging) return;
214
+
215
+ const horizontalDistanceMoved = this.gestureState.currentPositionX - this.gestureState.startPositionX;
216
+ const verticalDistanceMoved = this.gestureState.currentPositionY - this.gestureState.startPositionY;
217
+ const gestureDuration = Date.now() - this.gestureState.gestureStartTime;
218
+ const gestureVelocity = Math.abs(horizontalDistanceMoved) / gestureDuration;
219
+
220
+ if (Math.abs(horizontalDistanceMoved) > Math.abs(verticalDistanceMoved)) {
221
+ const isValidSwipeGesture = Math.abs(horizontalDistanceMoved) > this.MINIMUM_SWIPE_DISTANCE ||
222
+ (gestureVelocity > this.MINIMUM_SWIPE_VELOCITY && gestureDuration < this.MAXIMUM_SWIPE_DURATION);
223
+
224
+ if (isValidSwipeGesture) {
225
+ if (horizontalDistanceMoved > 0) {
226
+ this.navigateToPreviousItem();
227
+ } else {
228
+ this.navigateToNextItem();
229
+ }
230
+ }
231
+ }
232
+ this.gestureState.isCurrentlyDragging = false;
233
+ }
285
234
  }