mtrl 0.2.2 → 0.2.4
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/.typedocignore +11 -0
- package/DOCS.md +153 -0
- package/index.ts +18 -3
- package/package.json +7 -2
- package/src/components/badge/_styles.scss +174 -0
- package/src/components/badge/api.ts +292 -0
- package/src/components/badge/badge.ts +52 -0
- package/src/components/badge/config.ts +68 -0
- package/src/components/badge/constants.ts +30 -0
- package/src/components/badge/features.ts +185 -0
- package/src/components/badge/index.ts +4 -0
- package/src/components/badge/types.ts +105 -0
- package/src/components/button/types.ts +174 -29
- package/src/components/carousel/_styles.scss +645 -0
- package/src/components/carousel/api.ts +147 -0
- package/src/components/carousel/carousel.ts +178 -0
- package/src/components/carousel/config.ts +91 -0
- package/src/components/carousel/constants.ts +95 -0
- package/src/components/carousel/features/drag.ts +388 -0
- package/src/components/carousel/features/index.ts +8 -0
- package/src/components/carousel/features/slides.ts +682 -0
- package/src/components/carousel/index.ts +38 -0
- package/src/components/carousel/types.ts +327 -0
- package/src/components/dialog/_styles.scss +213 -0
- package/src/components/dialog/api.ts +283 -0
- package/src/components/dialog/config.ts +113 -0
- package/src/components/dialog/constants.ts +32 -0
- package/src/components/dialog/dialog.ts +56 -0
- package/src/components/dialog/features.ts +713 -0
- package/src/components/dialog/index.ts +15 -0
- package/src/components/dialog/types.ts +221 -0
- package/src/components/progress/_styles.scss +13 -1
- package/src/components/progress/api.ts +2 -2
- package/src/components/progress/progress.ts +2 -2
- package/src/components/progress/types.ts +3 -0
- package/src/components/radios/_styles.scss +232 -0
- package/src/components/radios/api.ts +100 -0
- package/src/components/radios/config.ts +60 -0
- package/src/components/radios/constants.ts +28 -0
- package/src/components/radios/index.ts +4 -0
- package/src/components/radios/radio.ts +269 -0
- package/src/components/radios/radios.ts +42 -0
- package/src/components/radios/types.ts +232 -0
- package/src/components/sheet/_styles.scss +236 -0
- package/src/components/sheet/api.ts +96 -0
- package/src/components/sheet/config.ts +66 -0
- package/src/components/sheet/constants.ts +20 -0
- package/src/components/sheet/features/content.ts +51 -0
- package/src/components/sheet/features/gestures.ts +177 -0
- package/src/components/sheet/features/index.ts +6 -0
- package/src/components/sheet/features/position.ts +42 -0
- package/src/components/sheet/features/state.ts +116 -0
- package/src/components/sheet/features/title.ts +86 -0
- package/src/components/sheet/index.ts +4 -0
- package/src/components/sheet/sheet.ts +57 -0
- package/src/components/sheet/types.ts +266 -0
- package/src/components/slider/_styles.scss +518 -0
- package/src/components/slider/api.ts +336 -0
- package/src/components/slider/config.ts +145 -0
- package/src/components/slider/constants.ts +28 -0
- package/src/components/slider/features/appearance.ts +140 -0
- package/src/components/slider/features/disabled.ts +43 -0
- package/src/components/slider/features/events.ts +164 -0
- package/src/components/slider/features/index.ts +5 -0
- package/src/components/slider/features/interactions.ts +256 -0
- package/src/components/slider/features/keyboard.ts +114 -0
- package/src/components/slider/features/slider.ts +336 -0
- package/src/components/slider/features/structure.ts +264 -0
- package/src/components/slider/features/ui.ts +518 -0
- package/src/components/slider/index.ts +9 -0
- package/src/components/slider/slider.ts +58 -0
- package/src/components/slider/types.ts +166 -0
- package/src/components/tabs/_styles.scss +224 -0
- package/src/components/tabs/api.ts +443 -0
- package/src/components/tabs/config.ts +80 -0
- package/src/components/tabs/constants.ts +12 -0
- package/src/components/tabs/index.ts +4 -0
- package/src/components/tabs/tabs.ts +52 -0
- package/src/components/tabs/types.ts +247 -0
- package/src/components/textfield/_styles.scss +97 -4
- package/src/components/tooltip/_styles.scss +241 -0
- package/src/components/tooltip/api.ts +411 -0
- package/src/components/tooltip/config.ts +78 -0
- package/src/components/tooltip/constants.ts +27 -0
- package/src/components/tooltip/index.ts +4 -0
- package/src/components/tooltip/tooltip.ts +60 -0
- package/src/components/tooltip/types.ts +178 -0
- package/src/core/build/_ripple.scss +79 -0
- package/src/core/build/constants.ts +48 -0
- package/src/core/build/icon.ts +137 -0
- package/src/core/build/ripple.ts +216 -0
- package/src/core/build/text.ts +91 -0
- package/src/index.ts +9 -1
- package/src/styles/abstract/_variables.scss +24 -12
- package/tsconfig.json +22 -0
- package/typedoc.json +28 -0
- package/typedoc.simple.json +14 -0
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
// src/components/carousel/features/drag.ts
|
|
2
|
+
import { CAROUSEL_EVENTS, CAROUSEL_LAYOUTS, CAROUSEL_SCROLL_BEHAVIORS } from '../constants';
|
|
3
|
+
import { CarouselConfig } from '../types';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Adds drag functionality to the carousel component with Material Design 3 scroll behavior support
|
|
7
|
+
*
|
|
8
|
+
* @param {CarouselConfig} config - Carousel configuration
|
|
9
|
+
* @returns {Function} Higher-order function that adds drag navigation feature
|
|
10
|
+
*/
|
|
11
|
+
export const withDrag = (config: CarouselConfig) => (component) => {
|
|
12
|
+
let startX: number;
|
|
13
|
+
let startScrollLeft: number;
|
|
14
|
+
let currentX: number;
|
|
15
|
+
let isDragging = false;
|
|
16
|
+
let velocity = 0;
|
|
17
|
+
let lastTimestamp = 0;
|
|
18
|
+
let animationFrame: number;
|
|
19
|
+
|
|
20
|
+
// Scroll behavior from config
|
|
21
|
+
const scrollBehavior = config.scrollBehavior || 'default';
|
|
22
|
+
|
|
23
|
+
// Handle pointer events
|
|
24
|
+
const handlePointerDown = (event: PointerEvent) => {
|
|
25
|
+
// Only handle primary button (usually left click)
|
|
26
|
+
if (event.button !== 0) return;
|
|
27
|
+
|
|
28
|
+
// Cancel any ongoing scroll animations
|
|
29
|
+
cancelAnimationFrame(animationFrame);
|
|
30
|
+
|
|
31
|
+
startX = event.clientX;
|
|
32
|
+
startScrollLeft = component.slidesContainer.scrollLeft;
|
|
33
|
+
currentX = startX;
|
|
34
|
+
isDragging = true;
|
|
35
|
+
lastTimestamp = Date.now();
|
|
36
|
+
velocity = 0;
|
|
37
|
+
|
|
38
|
+
// Set dragging state via data attribute
|
|
39
|
+
component.slidesContainer.dataset.touchAction = 'none';
|
|
40
|
+
component.element.dataset.dragging = 'true';
|
|
41
|
+
|
|
42
|
+
// Prevent default behaviors that might cause resistance
|
|
43
|
+
component.slidesContainer.style.scrollBehavior = 'auto';
|
|
44
|
+
|
|
45
|
+
// Capture pointer to receive events outside element
|
|
46
|
+
component.element.setPointerCapture(event.pointerId);
|
|
47
|
+
|
|
48
|
+
// Stop click events during drag
|
|
49
|
+
event.preventDefault();
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const handlePointerMove = (event: PointerEvent) => {
|
|
53
|
+
if (!isDragging) return;
|
|
54
|
+
|
|
55
|
+
// Calculate how far the pointer has moved
|
|
56
|
+
const dx = event.clientX - startX;
|
|
57
|
+
|
|
58
|
+
// Directly set scroll position without any easing or calculations
|
|
59
|
+
component.slidesContainer.scrollLeft = startScrollLeft - dx;
|
|
60
|
+
|
|
61
|
+
// Calculate velocity for momentum scrolling
|
|
62
|
+
const now = Date.now();
|
|
63
|
+
const dt = now - lastTimestamp;
|
|
64
|
+
|
|
65
|
+
if (dt > 0) {
|
|
66
|
+
const dx = event.clientX - currentX;
|
|
67
|
+
velocity = dx / dt; // Pixels per millisecond
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
currentX = event.clientX;
|
|
71
|
+
lastTimestamp = now;
|
|
72
|
+
|
|
73
|
+
event.preventDefault();
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Finds the nearest snap position based on current scroll position
|
|
78
|
+
* Used for snap scrolling behavior
|
|
79
|
+
*/
|
|
80
|
+
const findSnapPosition = () => {
|
|
81
|
+
const slideElements = component.slides.getElements();
|
|
82
|
+
const containerWidth = component.slidesContainer.clientWidth;
|
|
83
|
+
const scrollLeft = component.slidesContainer.scrollLeft;
|
|
84
|
+
|
|
85
|
+
// For center-aligned hero layout
|
|
86
|
+
const isCentered = config.layout === 'hero' && config.centered;
|
|
87
|
+
|
|
88
|
+
let closestPosition = 0;
|
|
89
|
+
let closestDistance = Infinity;
|
|
90
|
+
|
|
91
|
+
// Find the closest slide position for snapping
|
|
92
|
+
slideElements.forEach((slide) => {
|
|
93
|
+
let targetPosition;
|
|
94
|
+
|
|
95
|
+
if (isCentered) {
|
|
96
|
+
// For centered layouts, snap to center-aligned position
|
|
97
|
+
const slideCenter = slide.offsetLeft + (slide.offsetWidth / 2);
|
|
98
|
+
targetPosition = slideCenter - (containerWidth / 2);
|
|
99
|
+
} else {
|
|
100
|
+
// For standard layouts, snap to start-aligned position
|
|
101
|
+
targetPosition = slide.offsetLeft;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const distance = Math.abs(targetPosition - scrollLeft);
|
|
105
|
+
|
|
106
|
+
if (distance < closestDistance) {
|
|
107
|
+
closestDistance = distance;
|
|
108
|
+
closestPosition = targetPosition;
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
return closestPosition;
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Animates scroll with momentum and snapping
|
|
117
|
+
* @param {number} startPosition - Starting scroll position
|
|
118
|
+
* @param {number} endPosition - Target scroll position
|
|
119
|
+
* @param {number} startVelocity - Initial velocity in pixels/ms
|
|
120
|
+
*/
|
|
121
|
+
const animateScroll = (startPosition: number, endPosition: number, startVelocity: number) => {
|
|
122
|
+
const startTime = Date.now();
|
|
123
|
+
const distance = endPosition - startPosition;
|
|
124
|
+
|
|
125
|
+
// Base animation duration on distance and velocity
|
|
126
|
+
// Faster flicks = shorter duration
|
|
127
|
+
let duration = 500; // Base duration in ms
|
|
128
|
+
|
|
129
|
+
if (Math.abs(startVelocity) > 0.5) {
|
|
130
|
+
// For faster flicks, reduce duration
|
|
131
|
+
duration = Math.min(duration, 300);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const animateStep = () => {
|
|
135
|
+
const elapsed = Date.now() - startTime;
|
|
136
|
+
let progress = Math.min(elapsed / duration, 1);
|
|
137
|
+
|
|
138
|
+
// Ease out cubic function for smooth deceleration
|
|
139
|
+
progress = 1 - Math.pow(1 - progress, 3);
|
|
140
|
+
|
|
141
|
+
const currentPosition = startPosition + (distance * progress);
|
|
142
|
+
component.slidesContainer.scrollLeft = currentPosition;
|
|
143
|
+
|
|
144
|
+
if (progress < 1) {
|
|
145
|
+
animationFrame = requestAnimationFrame(animateStep);
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
animationFrame = requestAnimationFrame(animateStep);
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
const handlePointerUp = (event: PointerEvent) => {
|
|
153
|
+
if (!isDragging) return;
|
|
154
|
+
|
|
155
|
+
isDragging = false;
|
|
156
|
+
delete component.element.dataset.dragging;
|
|
157
|
+
|
|
158
|
+
// Release pointer capture
|
|
159
|
+
component.element.releasePointerCapture(event.pointerId);
|
|
160
|
+
|
|
161
|
+
// Handle scroll behavior based on config
|
|
162
|
+
if (scrollBehavior === 'snap') {
|
|
163
|
+
// Find nearest snap position
|
|
164
|
+
const snapPosition = findSnapPosition();
|
|
165
|
+
|
|
166
|
+
// Use velocity for a more natural feel
|
|
167
|
+
animateScroll(component.slidesContainer.scrollLeft, snapPosition, velocity);
|
|
168
|
+
} else if (Math.abs(velocity) > 0.5) {
|
|
169
|
+
// For standard scrolling, add momentum effect for fast flicks
|
|
170
|
+
const momentumDistance = velocity * 100; // Arbitrary multiplier for momentum
|
|
171
|
+
const targetPosition = component.slidesContainer.scrollLeft - momentumDistance;
|
|
172
|
+
|
|
173
|
+
animateScroll(component.slidesContainer.scrollLeft, targetPosition, velocity);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Reset velocity
|
|
177
|
+
velocity = 0;
|
|
178
|
+
|
|
179
|
+
// Restore scrolling behavior
|
|
180
|
+
setTimeout(() => {
|
|
181
|
+
component.slidesContainer.style.scrollBehavior = '';
|
|
182
|
+
}, 0);
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
const handlePointerCancel = (event: PointerEvent) => {
|
|
186
|
+
if (isDragging) {
|
|
187
|
+
isDragging = false;
|
|
188
|
+
delete component.element.dataset.dragging;
|
|
189
|
+
component.element.releasePointerCapture(event.pointerId);
|
|
190
|
+
|
|
191
|
+
// Restore scrolling behavior
|
|
192
|
+
component.slidesContainer.style.scrollBehavior = '';
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Handle wheel events for horizontal scrolling
|
|
198
|
+
* @param {WheelEvent} event - Wheel event
|
|
199
|
+
*/
|
|
200
|
+
const handleWheel = (event: WheelEvent) => {
|
|
201
|
+
// For full-screen layout, allow vertical scrolling
|
|
202
|
+
if (config.layout === 'full-screen') {
|
|
203
|
+
// Let the default scroll behavior happen
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// For other layouts, transform vertical scrolling to horizontal
|
|
208
|
+
event.preventDefault();
|
|
209
|
+
|
|
210
|
+
// Determine the scroll delta
|
|
211
|
+
const delta = event.deltaY || event.deltaX;
|
|
212
|
+
|
|
213
|
+
// Calculate scroll increment based on wheel delta
|
|
214
|
+
const scrollIncrement = delta * 0.5;
|
|
215
|
+
|
|
216
|
+
// For snap scrolling, we want to snap after wheel events
|
|
217
|
+
if (scrollBehavior === 'snap') {
|
|
218
|
+
// First scroll normally
|
|
219
|
+
component.slidesContainer.scrollLeft += scrollIncrement;
|
|
220
|
+
|
|
221
|
+
// Clear previous snap timeout
|
|
222
|
+
clearTimeout(component['wheelSnapTimeout']);
|
|
223
|
+
|
|
224
|
+
// Set timeout to snap after wheel motion stops
|
|
225
|
+
component['wheelSnapTimeout'] = setTimeout(() => {
|
|
226
|
+
const snapPosition = findSnapPosition();
|
|
227
|
+
|
|
228
|
+
// Animate to snap position
|
|
229
|
+
animateScroll(component.slidesContainer.scrollLeft, snapPosition, 0);
|
|
230
|
+
}, 150); // Short delay to detect end of wheel motion
|
|
231
|
+
} else {
|
|
232
|
+
// Standard scrolling - just scroll directly
|
|
233
|
+
component.slidesContainer.scrollLeft += scrollIncrement;
|
|
234
|
+
}
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Apply parallax effect to slides during scroll
|
|
239
|
+
* Used for multi-browse layout with different sized items
|
|
240
|
+
*/
|
|
241
|
+
const applyParallaxEffect = () => {
|
|
242
|
+
// Only apply for multi-browse layout
|
|
243
|
+
if (config.layout !== 'multi-browse' || !component.element.dataset.enableParallax) {
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
const slides = component.slides.getElements();
|
|
248
|
+
const containerWidth = component.slidesContainer.clientWidth;
|
|
249
|
+
const scrollLeft = component.slidesContainer.scrollLeft;
|
|
250
|
+
|
|
251
|
+
slides.forEach((slide) => {
|
|
252
|
+
const slideLeft = slide.offsetLeft;
|
|
253
|
+
const slideWidth = slide.offsetWidth;
|
|
254
|
+
|
|
255
|
+
// Calculate how centered the slide is in the container
|
|
256
|
+
const slideCenterX = slideLeft + (slideWidth / 2);
|
|
257
|
+
const containerCenterX = scrollLeft + (containerWidth / 2);
|
|
258
|
+
const distanceFromCenter = slideCenterX - containerCenterX;
|
|
259
|
+
|
|
260
|
+
// Normalize to a -1 to 1 range
|
|
261
|
+
const normalizedDistance = Math.max(-1, Math.min(1, distanceFromCenter / (containerWidth / 2)));
|
|
262
|
+
|
|
263
|
+
// Apply a subtle parallax effect
|
|
264
|
+
// Move images in the opposite direction of the scroll by a small amount
|
|
265
|
+
const slideImage = slide.querySelector(`.${component.getClass('carousel')}-slide-image img`);
|
|
266
|
+
if (slideImage) {
|
|
267
|
+
(slideImage as HTMLElement).style.transform = `translateX(${normalizedDistance * -5}%)`;
|
|
268
|
+
}
|
|
269
|
+
});
|
|
270
|
+
};
|
|
271
|
+
|
|
272
|
+
// Handle scroll events for parallax and active slide detection
|
|
273
|
+
const handleScroll = () => {
|
|
274
|
+
// Apply parallax effect if enabled
|
|
275
|
+
applyParallaxEffect();
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
// Add parallax data attribute if it's multi-browse
|
|
279
|
+
if (config.layout === 'multi-browse') {
|
|
280
|
+
component.element.dataset.enableParallax = 'true';
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// Add data attribute for draggable UI
|
|
284
|
+
component.element.dataset.swipe = 'true';
|
|
285
|
+
|
|
286
|
+
// Add pointer event listeners
|
|
287
|
+
component.slidesContainer.addEventListener('pointerdown', handlePointerDown);
|
|
288
|
+
window.addEventListener('pointermove', handlePointerMove);
|
|
289
|
+
window.addEventListener('pointerup', handlePointerUp);
|
|
290
|
+
window.addEventListener('pointercancel', handlePointerCancel);
|
|
291
|
+
|
|
292
|
+
// Add wheel event listener with appropriate passive setting
|
|
293
|
+
component.slidesContainer.addEventListener('wheel', handleWheel, { passive: false });
|
|
294
|
+
|
|
295
|
+
// Add scroll event listener for parallax effect
|
|
296
|
+
component.slidesContainer.addEventListener('scroll', handleScroll, { passive: true });
|
|
297
|
+
|
|
298
|
+
// Add keyboard navigation
|
|
299
|
+
const handleKeyDown = (event: KeyboardEvent) => {
|
|
300
|
+
// Only handle keyboard navigation when the carousel has focus
|
|
301
|
+
if (component.element !== document.activeElement) {
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
switch (event.key) {
|
|
306
|
+
case 'ArrowLeft':
|
|
307
|
+
if (component.prev) {
|
|
308
|
+
component.prev();
|
|
309
|
+
} else {
|
|
310
|
+
// Fallback if prev method not available
|
|
311
|
+
component.slidesContainer.scrollBy({
|
|
312
|
+
left: -200,
|
|
313
|
+
behavior: scrollBehavior === 'snap' ? 'smooth' : 'auto'
|
|
314
|
+
});
|
|
315
|
+
}
|
|
316
|
+
event.preventDefault();
|
|
317
|
+
break;
|
|
318
|
+
|
|
319
|
+
case 'ArrowRight':
|
|
320
|
+
if (component.next) {
|
|
321
|
+
component.next();
|
|
322
|
+
} else {
|
|
323
|
+
// Fallback if next method not available
|
|
324
|
+
component.slidesContainer.scrollBy({
|
|
325
|
+
left: 200,
|
|
326
|
+
behavior: scrollBehavior === 'snap' ? 'smooth' : 'auto'
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
event.preventDefault();
|
|
330
|
+
break;
|
|
331
|
+
|
|
332
|
+
case 'Home':
|
|
333
|
+
// Go to first slide
|
|
334
|
+
if (component.goTo) {
|
|
335
|
+
component.goTo(0);
|
|
336
|
+
}
|
|
337
|
+
event.preventDefault();
|
|
338
|
+
break;
|
|
339
|
+
|
|
340
|
+
case 'End':
|
|
341
|
+
// Go to last slide
|
|
342
|
+
if (component.goTo && component.slides.getCount) {
|
|
343
|
+
component.goTo(component.slides.getCount() - 1);
|
|
344
|
+
}
|
|
345
|
+
event.preventDefault();
|
|
346
|
+
break;
|
|
347
|
+
}
|
|
348
|
+
};
|
|
349
|
+
|
|
350
|
+
// Make the carousel focusable for keyboard navigation
|
|
351
|
+
component.element.setAttribute('tabindex', '0');
|
|
352
|
+
component.element.addEventListener('keydown', handleKeyDown);
|
|
353
|
+
|
|
354
|
+
// Add aria attributes for accessibility
|
|
355
|
+
component.element.setAttribute('aria-label', 'Carousel');
|
|
356
|
+
|
|
357
|
+
// Return the component with additional cleanup
|
|
358
|
+
return {
|
|
359
|
+
...component,
|
|
360
|
+
|
|
361
|
+
// Add drag cleanup to lifecycle
|
|
362
|
+
lifecycle: {
|
|
363
|
+
...component.lifecycle,
|
|
364
|
+
destroy: () => {
|
|
365
|
+
// Cancel any animations
|
|
366
|
+
cancelAnimationFrame(animationFrame);
|
|
367
|
+
|
|
368
|
+
// Remove pointer event listeners
|
|
369
|
+
component.slidesContainer.removeEventListener('pointerdown', handlePointerDown);
|
|
370
|
+
window.removeEventListener('pointermove', handlePointerMove);
|
|
371
|
+
window.removeEventListener('pointerup', handlePointerUp);
|
|
372
|
+
window.removeEventListener('pointercancel', handlePointerCancel);
|
|
373
|
+
|
|
374
|
+
// Remove wheel and scroll event listeners
|
|
375
|
+
component.slidesContainer.removeEventListener('wheel', handleWheel);
|
|
376
|
+
component.slidesContainer.removeEventListener('scroll', handleScroll);
|
|
377
|
+
|
|
378
|
+
// Remove keyboard event listener
|
|
379
|
+
component.element.removeEventListener('keydown', handleKeyDown);
|
|
380
|
+
|
|
381
|
+
// Call original destroy if it exists
|
|
382
|
+
if (component.lifecycle && component.lifecycle.destroy) {
|
|
383
|
+
component.lifecycle.destroy();
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
};
|
|
388
|
+
};
|