lazer-slider 1.1.4 → 1.1.5
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/dist/index.cjs +7 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +7 -9
- package/dist/index.js.map +1 -1
- package/dist/lazer-slider.css +5 -9
- package/package.json +4 -2
package/dist/index.cjs
CHANGED
|
@@ -232,6 +232,7 @@ var setupDragToScroll = (config) => {
|
|
|
232
232
|
state.lastY = state.startY;
|
|
233
233
|
state.lastTime = performance.now();
|
|
234
234
|
feed.style.userSelect = "none";
|
|
235
|
+
feed.classList.add("is-dragging");
|
|
235
236
|
if (event.type === "mousedown") {
|
|
236
237
|
event.preventDefault();
|
|
237
238
|
}
|
|
@@ -266,6 +267,7 @@ var setupDragToScroll = (config) => {
|
|
|
266
267
|
if (!state.isDragging) return;
|
|
267
268
|
state.isDragging = false;
|
|
268
269
|
feed.style.userSelect = "";
|
|
270
|
+
feed.classList.remove("is-dragging");
|
|
269
271
|
if (Math.abs(state.velocity) > 1) {
|
|
270
272
|
applyMomentum(state, feed, slides, smoothScrollTo, onDragEnd, direction);
|
|
271
273
|
} else {
|
|
@@ -530,7 +532,6 @@ var CRITICAL_STYLES = `
|
|
|
530
532
|
overflow-y: hidden;
|
|
531
533
|
-webkit-overflow-scrolling: touch;
|
|
532
534
|
scrollbar-width: none;
|
|
533
|
-
scroll-snap-type: x mandatory;
|
|
534
535
|
}
|
|
535
536
|
|
|
536
537
|
.lazer-feed::-webkit-scrollbar {
|
|
@@ -541,22 +542,19 @@ var CRITICAL_STYLES = `
|
|
|
541
542
|
flex-direction: column;
|
|
542
543
|
overflow-x: hidden;
|
|
543
544
|
overflow-y: auto;
|
|
544
|
-
scroll-snap-type: y mandatory;
|
|
545
545
|
}
|
|
546
546
|
|
|
547
547
|
.lazer-slide {
|
|
548
|
-
scroll-snap-align: start;
|
|
549
548
|
flex-shrink: 0;
|
|
550
549
|
}
|
|
551
550
|
|
|
552
|
-
.lazer-feed.
|
|
553
|
-
cursor:
|
|
554
|
-
user-select: none;
|
|
555
|
-
scroll-snap-type: none;
|
|
551
|
+
.lazer-feed.lazer-draggable {
|
|
552
|
+
cursor: grab;
|
|
556
553
|
}
|
|
557
554
|
|
|
558
|
-
.lazer-feed
|
|
559
|
-
cursor:
|
|
555
|
+
.lazer-feed.lazer-draggable.is-dragging {
|
|
556
|
+
cursor: grabbing;
|
|
557
|
+
user-select: none;
|
|
560
558
|
}
|
|
561
559
|
`;
|
|
562
560
|
var stylesInjected = false;
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/core/easing.ts","../src/core/accessibility.ts","../src/core/drag.ts","../src/core/bullets.ts","../src/core/thumbs.ts","../src/core/marquee.ts","../src/core/styles.ts","../src/core/slider.ts"],"sourcesContent":["export { createSlider } from './core/slider.js'\n\nexport type {\n SliderSettings,\n SliderState,\n SliderDirection,\n SliderNavDirection,\n MarqueeDirection,\n ScrollStartParams,\n ScrollParams,\n EasingFunction,\n Slider,\n DragState\n} from './core/types.js'\n\nexport {\n easeOutExpo,\n easeOutCubic,\n easeInOutCubic,\n easeOutQuad,\n linear\n} from './core/easing.js'\n\nexport { generateBullets } from './core/bullets.js'\n\nexport { generateThumbs } from './core/thumbs.js'\n\nexport { injectStyles, removeStyles } from './core/styles.js'\n","import type { EasingFunction } from './types.js'\n\n/**\n * Exponential ease-out - starts fast, decelerates smoothly\n * Best for scroll animations as it feels natural and responsive\n */\nexport const easeOutExpo: EasingFunction = (t) =>\n t === 1 ? 1 : 1 - Math.pow(2, -10 * t)\n\n/**\n * Cubic ease-out - smoother deceleration than exponential\n */\nexport const easeOutCubic: EasingFunction = (t) => 1 - Math.pow(1 - t, 3)\n\n/**\n * Cubic ease-in-out - smooth acceleration and deceleration\n */\nexport const easeInOutCubic: EasingFunction = (t) =>\n t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2\n\n/**\n * Quadratic ease-out - gentle deceleration\n */\nexport const easeOutQuad: EasingFunction = (t) => 1 - (1 - t) * (1 - t)\n\n/**\n * Linear - no easing, constant speed\n */\nexport const linear: EasingFunction = (t) => t\n","import type { SliderSettings, SliderDirection } from './types.js'\n\n/**\n * Generate a unique ID for the slider\n */\nexport const generateSliderId = (): string =>\n `slider-${Math.random().toString(36).substring(2, 9)}`\n\n/**\n * Initialize ARIA attributes\n */\nexport const initAria = (settings: SliderSettings): void => {\n const { feed, prevSlideButton, nextSlideButton, thumbs, slides } = settings\n\n if (!feed.id) {\n feed.id = generateSliderId()\n }\n\n feed.setAttribute('role', 'region')\n feed.setAttribute('aria-label', 'Carousel')\n feed.setAttribute('aria-roledescription', 'carousel')\n\n feed.removeAttribute('tabindex')\n\n slides.forEach((slide, index) => {\n slide.setAttribute('role', 'group')\n slide.setAttribute('aria-roledescription', 'slide')\n slide.setAttribute('aria-label', `Slide ${index + 1} of ${slides.length}`)\n })\n\n if (prevSlideButton) {\n prevSlideButton.setAttribute('aria-label', 'Previous slide')\n prevSlideButton.setAttribute('aria-controls', feed.id)\n prevSlideButton.setAttribute('tabindex', '0')\n if (prevSlideButton.tagName !== 'BUTTON') {\n prevSlideButton.setAttribute('role', 'button')\n }\n }\n\n if (nextSlideButton) {\n nextSlideButton.setAttribute('aria-label', 'Next slide')\n nextSlideButton.setAttribute('aria-controls', feed.id)\n nextSlideButton.setAttribute('tabindex', '0')\n if (nextSlideButton.tagName !== 'BUTTON') {\n nextSlideButton.setAttribute('role', 'button')\n }\n }\n\n if (thumbs?.length) {\n thumbs.forEach((thumb, index) => {\n if (thumb.tagName !== 'BUTTON') {\n thumb.setAttribute('role', 'button')\n }\n thumb.setAttribute('aria-label', `Go to slide ${index + 1}`)\n thumb.setAttribute('tabindex', '0')\n thumb.setAttribute('aria-controls', feed.id)\n })\n }\n}\n\n/**\n * Toggle visibility of navigation controls\n */\nexport const toggleControlVisibility = (\n button: HTMLElement | null | undefined,\n shouldShow: boolean,\n feedElement?: HTMLElement\n): void => {\n if (!button) return\n\n if (!shouldShow && button === document.activeElement && feedElement) {\n feedElement.focus()\n }\n\n const transition = 'opacity 0.3s ease'\n const opacity = shouldShow ? '1' : '0'\n\n Object.assign(button.style, {\n opacity,\n transition,\n pointerEvents: shouldShow ? 'auto' : 'none'\n })\n\n if (!shouldShow) {\n button.setAttribute('aria-hidden', 'true')\n button.setAttribute('tabindex', '-1')\n } else {\n button.removeAttribute('aria-hidden')\n button.setAttribute('tabindex', '0')\n }\n\n if (!shouldShow) {\n setTimeout(() => {\n if (button.style.opacity === '0') {\n button.style.visibility = 'hidden'\n }\n }, 300)\n } else {\n button.style.visibility = 'visible'\n }\n}\n\n/**\n * Update active state on thumbs\n */\nexport const updateActiveThumb = (\n thumbs: HTMLElement[] | undefined,\n currentIndex: number,\n activeClass: string = 'active'\n): void => {\n if (!thumbs?.length) return\n\n thumbs.forEach((thumb, index) => {\n const isActive = index === currentIndex\n thumb.classList.toggle(activeClass, isActive)\n thumb.setAttribute('aria-selected', isActive.toString())\n })\n}\n\n/**\n * Keyboard navigation\n */\nexport const setupKeyboardNavigation = (\n feed: HTMLElement,\n onPrev: () => void,\n onNext: () => void,\n abortSignal: AbortSignal,\n direction: SliderDirection = 'horizontal'\n): void => {\n const isVertical = direction === 'vertical'\n const prevKey = isVertical ? 'ArrowUp' : 'ArrowLeft'\n const nextKey = isVertical ? 'ArrowDown' : 'ArrowRight'\n\n feed.addEventListener(\n 'keydown',\n (event: KeyboardEvent) => {\n switch (event.key) {\n case prevKey:\n event.preventDefault()\n onPrev()\n break\n case nextKey:\n event.preventDefault()\n onNext()\n break\n }\n },\n { signal: abortSignal }\n )\n\n if (!feed.hasAttribute('tabindex')) {\n feed.setAttribute('tabindex', '0')\n }\n}\n","import type { DragState, EasingFunction, SliderDirection } from './types.js'\nimport { easeOutCubic } from './easing.js'\n\n/**\n * Configuration for drag behavior\n */\ninterface DragConfig {\n /** Feed element to enable dragging on */\n feed: HTMLElement\n /** Slide elements for snap-to-slide calculation */\n slides: HTMLElement[]\n /** AbortSignal for cleanup */\n abortSignal: AbortSignal\n /** Callback to smooth scroll to a position */\n smoothScrollTo: (target: number, easing?: EasingFunction) => void\n /** Callback when drag ends (for updating state) */\n onDragEnd?: () => void\n /** Direction of the slider (horizontal or vertical) */\n direction?: SliderDirection\n}\n\nexport const createDragState = (): DragState => ({\n isDragging: false,\n startX: 0,\n startY: 0,\n startScrollLeft: 0,\n startScrollTop: 0,\n velocity: 0,\n lastX: 0,\n lastY: 0,\n lastTime: 0,\n momentumId: null\n})\n\nconst findNearestSlide = (\n feed: HTMLElement,\n slides: HTMLElement[],\n direction: SliderDirection = 'horizontal'\n): HTMLElement | null => {\n const feedRect = feed.getBoundingClientRect()\n const isVertical = direction === 'vertical'\n\n const feedCenter = isVertical\n ? feedRect.top + feedRect.height / 2\n : feedRect.left + feedRect.width / 2\n\n let nearestSlide: HTMLElement | null = null\n let minDistance = Infinity\n\n for (const slide of slides) {\n if (slide.offsetParent === null) continue\n\n const slideRect = slide.getBoundingClientRect()\n const slideCenter = isVertical\n ? slideRect.top + slideRect.height / 2\n : slideRect.left + slideRect.width / 2\n const distance = Math.abs(feedCenter - slideCenter)\n\n if (distance < minDistance) {\n minDistance = distance\n nearestSlide = slide\n }\n }\n\n return nearestSlide\n}\n\nconst applyMomentum = (\n state: DragState,\n feed: HTMLElement,\n slides: HTMLElement[],\n smoothScrollTo: (target: number, easing?: EasingFunction) => void,\n onDragEnd?: () => void,\n direction: SliderDirection = 'horizontal'\n): void => {\n const friction = 0.95\n const minVelocity = 0.5\n const isVertical = direction === 'vertical'\n\n const animate = () => {\n if (Math.abs(state.velocity) < minVelocity) {\n state.momentumId = null\n\n const nearestSlide = findNearestSlide(feed, slides, direction)\n if (nearestSlide) {\n const targetPosition = isVertical ? nearestSlide.offsetTop : nearestSlide.offsetLeft\n smoothScrollTo(targetPosition, easeOutCubic)\n }\n\n onDragEnd?.()\n return\n }\n\n if (isVertical) {\n feed.scrollTop += state.velocity\n } else {\n feed.scrollLeft += state.velocity\n }\n state.velocity *= friction\n\n state.momentumId = requestAnimationFrame(animate)\n }\n\n state.momentumId = requestAnimationFrame(animate)\n}\n\nconst getEventX = (event: MouseEvent | TouchEvent): number => {\n if ('touches' in event) {\n return event.touches[0]?.clientX ?? 0\n }\n return event.clientX\n}\n\nconst getEventY = (event: MouseEvent | TouchEvent): number => {\n if ('touches' in event) {\n return event.touches[0]?.clientY ?? 0\n }\n return event.clientY\n}\n\nexport const setupDragToScroll = (config: DragConfig): DragState => {\n const { feed, slides, abortSignal, smoothScrollTo, onDragEnd, direction = 'horizontal' } = config\n const state = createDragState()\n const isVertical = direction === 'vertical'\n\n const handleDragStart = (event: MouseEvent | TouchEvent) => {\n if (state.momentumId !== null) {\n cancelAnimationFrame(state.momentumId)\n state.momentumId = null\n }\n\n state.isDragging = true\n state.startX = getEventX(event)\n state.startY = getEventY(event)\n state.startScrollLeft = feed.scrollLeft\n state.startScrollTop = feed.scrollTop\n state.velocity = 0\n state.lastX = state.startX\n state.lastY = state.startY\n state.lastTime = performance.now()\n\n feed.style.userSelect = 'none'\n\n if (event.type === 'mousedown') {\n event.preventDefault()\n }\n }\n\n const handleDragMove = (event: MouseEvent | TouchEvent) => {\n if (!state.isDragging) return\n\n const currentX = getEventX(event)\n const currentY = getEventY(event)\n const currentTime = performance.now()\n const deltaTime = currentTime - state.lastTime\n\n if (isVertical) {\n const deltaY = state.startY - currentY\n feed.scrollTop = state.startScrollTop + deltaY\n\n if (deltaTime > 0) {\n state.velocity = (state.lastY - currentY) / deltaTime * 16\n }\n state.lastY = currentY\n } else {\n const deltaX = state.startX - currentX\n feed.scrollLeft = state.startScrollLeft + deltaX\n\n if (deltaTime > 0) {\n state.velocity = (state.lastX - currentX) / deltaTime * 16\n }\n state.lastX = currentX\n }\n\n state.lastTime = currentTime\n\n if (event.type === 'touchmove') {\n event.preventDefault()\n }\n }\n\n const handleDragEnd = () => {\n if (!state.isDragging) return\n\n state.isDragging = false\n\n feed.style.userSelect = ''\n\n if (Math.abs(state.velocity) > 1) {\n applyMomentum(state, feed, slides, smoothScrollTo, onDragEnd, direction)\n } else {\n const nearestSlide = findNearestSlide(feed, slides, direction)\n if (nearestSlide) {\n const targetPosition = isVertical ? nearestSlide.offsetTop : nearestSlide.offsetLeft\n smoothScrollTo(targetPosition, easeOutCubic)\n }\n onDragEnd?.()\n }\n }\n\n feed.addEventListener('mousedown', handleDragStart, { signal: abortSignal })\n document.addEventListener('mousemove', handleDragMove, { signal: abortSignal })\n document.addEventListener('mouseup', handleDragEnd, { signal: abortSignal })\n\n feed.addEventListener('touchstart', handleDragStart, {\n passive: true,\n signal: abortSignal\n })\n feed.addEventListener('touchmove', handleDragMove, {\n passive: false,\n signal: abortSignal\n })\n feed.addEventListener('touchend', handleDragEnd, { signal: abortSignal })\n\n document.addEventListener('mouseleave', handleDragEnd, { signal: abortSignal })\n\n return state\n}\n\nexport const cleanupDrag = (state: DragState): void => {\n if (state.momentumId !== null) {\n cancelAnimationFrame(state.momentumId)\n state.momentumId = null\n }\n}\n","export interface GenerateBulletsParams {\n bulletsContainer: HTMLElement\n slides: HTMLElement[]\n bulletClass: string\n bulletActiveClass: string\n feedId: string\n}\n\nexport const generateBullets = ({\n bulletsContainer,\n slides,\n bulletClass,\n bulletActiveClass,\n feedId,\n}: GenerateBulletsParams): HTMLElement[] => {\n if (!bulletsContainer || !(bulletsContainer instanceof HTMLElement)) {\n throw new Error('Invalid bulletsContainer: must be a valid HTMLElement')\n }\n\n if (!Array.isArray(slides) || slides.length === 0) {\n throw new Error('Invalid slides: must be a non-empty array')\n }\n\n if (!feedId || typeof feedId !== 'string') {\n throw new Error('Invalid feedId: must be a non-empty string')\n }\n\n if (!bulletClass || typeof bulletClass !== 'string') {\n throw new Error('Invalid bulletClass: must be a non-empty string')\n }\n\n bulletsContainer.innerHTML = ''\n bulletsContainer.setAttribute('role', 'tablist')\n bulletsContainer.setAttribute('aria-label', 'Slide navigation')\n\n const visibleSlides = slides\n .map((slide, originalIndex) => ({ slide, originalIndex }))\n .filter(({ slide }) => slide.offsetParent !== null)\n\n if (visibleSlides.length === 0) {\n console.warn('No visible slides found')\n return []\n }\n\n const bullets = visibleSlides.map(({ slide, originalIndex }, visibleIndex) => {\n const bullet = document.createElement('button')\n bullet.type = 'button'\n\n bullet.classList.add(bulletClass)\n if (visibleIndex === 0) {\n bullet.classList.add(bulletActiveClass)\n }\n\n bullet.setAttribute('role', 'tab')\n bullet.setAttribute('aria-selected', visibleIndex === 0 ? 'true' : 'false')\n bullet.setAttribute('aria-controls', feedId)\n bullet.setAttribute('aria-label', `Go to slide ${visibleIndex + 1}`)\n bullet.setAttribute('data-slide-index', String(visibleIndex))\n\n bulletsContainer.appendChild(bullet)\n\n return bullet\n })\n\n return bullets\n}\n\nexport const updateActiveBullet = (\n bullets: HTMLElement[],\n activeIndex: number,\n bulletActiveClass: string,\n): void => {\n if (!Array.isArray(bullets) || activeIndex < 0 || activeIndex >= bullets.length) {\n console.warn('Invalid activeIndex or bullets array')\n return\n }\n\n bullets.forEach((bullet, index) => {\n const isActive = index === activeIndex\n bullet.classList.toggle(bulletActiveClass, isActive)\n bullet.setAttribute('aria-selected', isActive ? 'true' : 'false')\n })\n}","export interface GenerateThumbsParams {\n thumbsContainer: HTMLElement\n slides: HTMLElement[]\n thumbClass: string\n thumbActiveClass: string\n feedId: string\n thumbImageSelector?: string\n thumbSize?: { width: number; height: number }\n}\n\nexport const generateThumbs = ({\n thumbsContainer,\n slides,\n thumbClass,\n thumbActiveClass,\n feedId,\n thumbImageSelector = 'img',\n thumbSize\n}: GenerateThumbsParams): HTMLElement[] => {\n if (!thumbsContainer || !(thumbsContainer instanceof HTMLElement)) {\n throw new Error('Invalid thumbsContainer: must be a valid HTMLElement')\n }\n\n if (!Array.isArray(slides) || slides.length === 0) {\n throw new Error('Invalid slides: must be a non-empty array')\n }\n\n if (!feedId || typeof feedId !== 'string') {\n throw new Error('Invalid feedId: must be a non-empty string')\n }\n\n if (!thumbClass || typeof thumbClass !== 'string') {\n throw new Error('Invalid thumbClass: must be a non-empty string')\n }\n\n thumbsContainer.innerHTML = ''\n thumbsContainer.setAttribute('role', 'tablist')\n thumbsContainer.setAttribute('aria-label', 'Slide thumbnails')\n\n const visibleSlides = slides\n .map((slide, originalIndex) => ({ slide, originalIndex }))\n .filter(({ slide }) => slide.offsetParent !== null)\n\n if (visibleSlides.length === 0) {\n console.warn('No visible slides found')\n return []\n }\n\n const thumbs = visibleSlides.map(({ slide, originalIndex }, visibleIndex) => {\n const thumb = document.createElement('button')\n thumb.type = 'button'\n\n thumb.classList.add(thumbClass)\n if (visibleIndex === 0) {\n thumb.classList.add(thumbActiveClass)\n }\n\n // Extract image from slide\n const sourceImage = slide.querySelector(thumbImageSelector) as HTMLImageElement | null\n if (sourceImage?.src) {\n const thumbImg = document.createElement('img')\n thumbImg.src = sourceImage.src\n thumbImg.alt = sourceImage.alt || `Slide ${visibleIndex + 1} thumbnail`\n thumbImg.draggable = false\n\n if (thumbSize) {\n thumbImg.style.width = `${thumbSize.width}px`\n thumbImg.style.height = `${thumbSize.height}px`\n thumbImg.style.objectFit = 'cover'\n }\n\n thumb.appendChild(thumbImg)\n }\n\n // Accessibility attributes\n thumb.setAttribute('role', 'tab')\n thumb.setAttribute('aria-selected', visibleIndex === 0 ? 'true' : 'false')\n thumb.setAttribute('aria-controls', feedId)\n thumb.setAttribute('aria-label', `Go to slide ${visibleIndex + 1}`)\n thumb.setAttribute('data-slide-index', String(visibleIndex))\n\n thumbsContainer.appendChild(thumb)\n\n return thumb\n })\n\n return thumbs\n}\n\nexport const updateActiveThumbnail = (\n thumbs: HTMLElement[],\n activeIndex: number,\n thumbActiveClass: string\n): void => {\n if (!Array.isArray(thumbs) || activeIndex < 0 || activeIndex >= thumbs.length) {\n console.warn('Invalid activeIndex or thumbs array')\n return\n }\n\n thumbs.forEach((thumb, index) => {\n const isActive = index === activeIndex\n thumb.classList.toggle(thumbActiveClass, isActive)\n thumb.setAttribute('aria-selected', isActive ? 'true' : 'false')\n })\n}\n\n","import type { SliderSettings, SliderState } from './types.js'\n\n/**\n * Marquee state - tracks cloned slides for marquee mode\n */\nexport interface MarqueeState {\n initialized: boolean\n clonedSlides: HTMLElement[]\n styleElement: HTMLStyleElement | null\n}\n\n/**\n * Create initial marquee state\n */\nexport const createMarqueeState = (): MarqueeState => ({\n initialized: false,\n clonedSlides: [],\n styleElement: null\n})\n\n/**\n * Inject CSS keyframes for smooth marquee animation\n */\nconst injectMarqueeKeyframes = (): HTMLStyleElement => {\n // Check if keyframes already exist\n const existingStyle = document.getElementById('lazer-marquee-keyframes')\n if (existingStyle) {\n return existingStyle as HTMLStyleElement\n }\n\n const style = document.createElement('style')\n style.id = 'lazer-marquee-keyframes'\n style.textContent = `\n @keyframes lazer-marquee-scroll {\n 0% {\n transform: translateX(0);\n }\n 100% {\n transform: translateX(-50%);\n }\n }\n `\n document.head.appendChild(style)\n return style\n}\n\n/**\n * Clone all slides and append for seamless marquee looping\n */\nexport const setupMarqueeClones = (\n settings: SliderSettings,\n marqueeState: MarqueeState\n): void => {\n if (marqueeState.initialized) return\n\n // Inject CSS keyframes\n marqueeState.styleElement = injectMarqueeKeyframes()\n\n // Ensure feed has proper CSS for transform animation\n // Note: Parent container should have overflow: hidden for marquee effect\n settings.feed.style.display = 'flex'\n settings.feed.style.willChange = 'transform'\n\n // Clone all original slides and append to create seamless loop\n settings.slides.forEach((slide) => {\n const clone = slide.cloneNode(true) as HTMLElement\n clone.setAttribute('data-lazer-marquee-clone', 'true')\n clone.setAttribute('aria-hidden', 'true')\n settings.feed.appendChild(clone)\n marqueeState.clonedSlides.push(clone)\n })\n\n marqueeState.initialized = true\n}\n\n/**\n * Remove marquee cloned slides from the DOM\n */\nexport const cleanupMarqueeClones = (marqueeState: MarqueeState): void => {\n if (!marqueeState.initialized) return\n\n marqueeState.clonedSlides.forEach((clone) => {\n clone.remove()\n })\n\n marqueeState.clonedSlides = []\n marqueeState.initialized = false\n}\n\n/**\n * Setup marquee CSS animation for smooth hardware-accelerated scrolling\n */\nconst setupMarqueeCss = (\n settings: SliderSettings,\n state: SliderState\n): void => {\n // Ensure keyframes exist first\n injectMarqueeKeyframes()\n\n // Wait a frame to ensure keyframes are parsed and layout is complete\n requestAnimationFrame(() => {\n const scrollWidth = settings.feed.scrollWidth\n const speed = settings.marqueeSpeed ?? 50 // pixels per second\n const direction = settings.marqueeDirection ?? 'left'\n\n // Distance is half the scroll width (the original content width)\n const distance = scrollWidth / 2\n\n // Validate values\n if (distance <= 0 || speed <= 0) {\n console.warn('[lazer-slider] Invalid marquee values:', { distance, speed, scrollWidth })\n return\n }\n\n // Calculate duration: distance / speed (how long to scroll through original content)\n const duration = distance / speed\n const animationDirection = direction === 'right' ? 'reverse' : 'normal'\n\n // Apply animation - use percentage-based keyframes for seamless loop\n const animationValue = `lazer-marquee-scroll ${duration}s linear infinite ${animationDirection}`\n\n // Remove any existing animation first\n settings.feed.style.animation = 'none'\n\n // Force reflow to reset animation\n void settings.feed.offsetWidth\n\n // Apply new animation\n settings.feed.style.animation = animationValue\n settings.feed.style.animationPlayState = state.marqueePaused ? 'paused' : 'running'\n })\n}\n\n/**\n * Start marquee animation using smooth CSS animations\n */\nexport const startMarquee = (\n settings: SliderSettings,\n state: SliderState\n): void => {\n // Setup CSS animation for smooth hardware-accelerated scrolling\n setupMarqueeCss(settings, state)\n}\n\n/**\n * Stop marquee animation\n */\nexport const stopMarquee = (state: SliderState, settings: SliderSettings): void => {\n // Remove animation\n settings.feed.style.animation = ''\n settings.feed.style.animationPlayState = ''\n\n // Reset transform\n settings.feed.style.transform = ''\n settings.feed.style.willChange = ''\n}\n\n/**\n * Pause marquee animation (temporary, resumes on mouse leave)\n */\nexport const pauseMarquee = (state: SliderState, settings: SliderSettings): void => {\n state.marqueePaused = true\n settings.feed.style.animationPlayState = 'paused'\n}\n\n/**\n * Resume marquee animation after pause\n */\nexport const resumeMarquee = (state: SliderState, settings: SliderSettings): void => {\n state.marqueePaused = false\n settings.feed.style.animationPlayState = 'running'\n}\n\n/**\n * Setup marquee mode (clones + animation)\n */\nexport const setupMarquee = (\n settings: SliderSettings,\n state: SliderState,\n marqueeState: MarqueeState\n): void => {\n if (!settings.marquee) return\n\n setupMarqueeClones(settings, marqueeState)\n startMarquee(settings, state)\n}\n\n/**\n * Attach marquee pause-on-hover event listeners\n */\nexport const attachMarqueeEventListeners = (\n settings: SliderSettings,\n state: SliderState,\n signal: AbortSignal\n): void => {\n if (!settings.marquee || settings.pauseOnHover === false) return\n\n settings.feed.addEventListener(\n 'mouseenter',\n () => pauseMarquee(state, settings),\n { signal }\n )\n settings.feed.addEventListener(\n 'mouseleave',\n () => resumeMarquee(state, settings),\n { signal }\n )\n settings.feed.addEventListener(\n 'touchstart',\n () => pauseMarquee(state, settings),\n { passive: true, signal }\n )\n settings.feed.addEventListener(\n 'touchend',\n () => resumeMarquee(state, settings),\n { signal }\n )\n}\n","/**\n * Critical CSS styles that are auto-injected for zero-config usage\n * Users can override these by using more specific selectors or !important\n */\nconst CRITICAL_STYLES = `\n/* Lazer Slider - Critical Styles (Auto-injected) */\n.lazer-feed {\n position: relative;\n display: flex;\n overflow-x: auto;\n overflow-y: hidden;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: none;\n scroll-snap-type: x mandatory;\n}\n\n.lazer-feed::-webkit-scrollbar {\n display: none;\n}\n\n.lazer-feed.lazer-vertical {\n flex-direction: column;\n overflow-x: hidden;\n overflow-y: auto;\n scroll-snap-type: y mandatory;\n}\n\n.lazer-slide {\n scroll-snap-align: start;\n flex-shrink: 0;\n}\n\n.lazer-feed.is-dragging {\n cursor: grabbing;\n user-select: none;\n scroll-snap-type: none;\n}\n\n.lazer-feed:not(.is-dragging) {\n cursor: grab;\n}\n`\n\nlet stylesInjected = false\nconst STYLE_ID = 'lazer-slider-critical-styles'\n\n/**\n * Injects critical CSS styles into the document head.\n * Safe to call multiple times - will only inject once.\n *\n * @example\n * ```typescript\n * import { injectStyles } from 'lazer-slider'\n *\n * // Manually inject styles (useful for SSR or early loading)\n * injectStyles()\n * ```\n */\nexport const injectStyles = (): void => {\n if (stylesInjected || typeof document === 'undefined') return\n\n const existingStyle = document.getElementById(STYLE_ID)\n if (existingStyle) {\n stylesInjected = true\n return\n }\n\n const style = document.createElement('style')\n style.id = STYLE_ID\n style.textContent = CRITICAL_STYLES\n document.head.appendChild(style)\n stylesInjected = true\n}\n\n/**\n * Internal function called by createSlider to ensure styles are injected\n * @internal\n */\nexport const injectStylesOnce = (): void => {\n injectStyles()\n}\n\n/**\n * Removes the injected styles from the document.\n * Useful for cleanup in testing or when completely removing the slider.\n *\n * @example\n * ```typescript\n * import { removeStyles } from 'lazer-slider'\n *\n * // Remove injected styles\n * removeStyles()\n * ```\n */\nexport const removeStyles = (): void => {\n if (typeof document === 'undefined') return\n\n const style = document.getElementById(STYLE_ID)\n if (style) {\n style.remove()\n stylesInjected = false\n }\n}\n\n","import type {\n SliderSettings,\n SliderState,\n SliderNavDirection,\n EasingFunction,\n Slider,\n DragState\n} from './types.js'\nimport { easeOutExpo } from './easing.js'\nimport {\n initAria,\n toggleControlVisibility,\n updateActiveThumb,\n setupKeyboardNavigation\n} from './accessibility.js'\nimport { setupDragToScroll, cleanupDrag } from './drag.js'\nimport { generateBullets } from './bullets.js'\nimport { generateThumbs } from './thumbs.js'\nimport {\n createMarqueeState,\n setupMarquee,\n startMarquee,\n stopMarquee,\n pauseMarquee,\n resumeMarquee,\n cleanupMarqueeClones,\n attachMarqueeEventListeners\n} from './marquee.js'\nimport { injectStylesOnce } from './styles.js'\n\nconst ANIMATION = {\n MIN_DURATION: 400,\n MAX_DURATION: 1000,\n SPEED_FACTOR: 1.5,\n SCROLL_END_DELAY: 50,\n THUMB_UPDATE_DELAY: 500\n} as const\n\nconst DESKTOP_BREAKPOINT = '(min-width: 64rem)'\n\nexport const createSlider = (settings: SliderSettings): Slider => {\n // Auto-inject critical CSS styles for zero-config usage\n injectStylesOnce()\n\n if (!settings.feed) {\n throw new Error('lazer-slider: feed element is required')\n }\n\n if (!settings.slides?.length) {\n throw new Error('lazer-slider: slides array is required and must not be empty')\n }\n\n if (!settings.feed.id) {\n settings.feed.id = `lazer-slider-feed-${Math.random().toString(36).substr(2, 9)}`\n }\n\n // Add classes for CSS targeting (if not already present)\n settings.feed.classList.add('lazer-feed')\n settings.slides.forEach((slide) => {\n slide.classList.add('lazer-slide')\n })\n\n if (settings.bulletsContainer && !settings.thumbs) {\n const bullets = generateBullets({\n bulletsContainer: settings.bulletsContainer,\n slides: settings.slides,\n bulletClass: settings.bulletsClass ?? 'lazer-bullet',\n bulletActiveClass: settings.bulletsActiveClass ?? 'active',\n feedId: settings.feed.id\n })\n settings.thumbs = bullets\n }\n\n if (settings.thumbsContainer && !settings.thumbs) {\n const thumbs = generateThumbs({\n thumbsContainer: settings.thumbsContainer,\n slides: settings.slides,\n thumbClass: settings.thumbsClass ?? 'lazer-thumb',\n thumbActiveClass: settings.thumbsActiveClass ?? 'active',\n feedId: settings.feed.id,\n thumbImageSelector: settings.thumbImageSelector ?? 'img',\n thumbSize: settings.thumbSize\n })\n settings.thumbs = thumbs\n }\n\n const direction = settings.direction ?? 'horizontal'\n const isVertical = direction === 'vertical'\n\n // Add vertical class for CSS targeting\n if (isVertical) {\n settings.feed.classList.add('lazer-vertical')\n }\n\n // Add marquee class if enabled\n if (settings.marquee) {\n settings.feed.classList.add('lazer-marquee')\n }\n\n const state: SliderState = {\n currentSlideIndex: 0,\n isScrolling: false,\n ticking: false,\n cachedFeedRect: null,\n lastWidth: 0,\n updateThumbTimeout: null,\n scrollEndTimeout: null,\n abortController: new AbortController(),\n autoplayIntervalId: null,\n autoplayPaused: false,\n marqueeAnimationId: null,\n marqueePaused: false,\n marqueeLastTimestamp: 0,\n isLoopRepositioning: false\n }\n\n let dragState: DragState | null = null\n\n const loopState = {\n initialized: false,\n clonedSlides: [] as HTMLElement[],\n realSlides: [...settings.slides] as HTMLElement[],\n clonesPerSide: 0\n }\n\n const marqueeState = createMarqueeState()\n\n const easing = settings.easing ?? easeOutExpo\n\n const getFeedRect = (): DOMRect => {\n const currentSize = isVertical ? settings.feed.clientHeight : settings.feed.clientWidth\n if (!state.cachedFeedRect || state.lastWidth !== currentSize) {\n state.cachedFeedRect = settings.feed.getBoundingClientRect()\n state.lastWidth = currentSize\n }\n return state.cachedFeedRect\n }\n\n const getVisibleSlides = (): HTMLElement[] => {\n return settings.slides.filter((slide) => slide.offsetParent !== null)\n }\n\n const isDesktop = (): boolean => {\n return window.matchMedia(DESKTOP_BREAKPOINT).matches\n }\n\n const getLoopClonesCount = (): number => {\n const perView = isDesktop()\n ? settings.desktopSlidesPerView\n : settings.mobileSlidesPerView\n\n if (!perView || perView === 'auto') {\n return 1\n }\n return Math.ceil(perView)\n }\n\n const setupLoopClones = (): void => {\n if (!settings.loop || loopState.initialized) return\n\n const realSlides = loopState.realSlides\n const clonesCount = getLoopClonesCount()\n loopState.clonesPerSide = clonesCount\n\n for (let i = realSlides.length - clonesCount; i < realSlides.length; i++) {\n const slide = realSlides[i]\n if (!slide) continue\n\n const clone = slide.cloneNode(true) as HTMLElement\n clone.setAttribute('data-lazer-clone', 'prepend')\n clone.setAttribute('aria-hidden', 'true')\n settings.feed.insertBefore(clone, settings.feed.firstChild)\n loopState.clonedSlides.push(clone)\n }\n\n for (let i = 0; i < clonesCount; i++) {\n const slide = realSlides[i]\n if (!slide) continue\n\n const clone = slide.cloneNode(true) as HTMLElement\n clone.setAttribute('data-lazer-clone', 'append')\n clone.setAttribute('aria-hidden', 'true')\n settings.feed.appendChild(clone)\n loopState.clonedSlides.push(clone)\n }\n\n requestAnimationFrame(() => {\n const firstRealSlide = realSlides[0]\n if (firstRealSlide) {\n if (isVertical) {\n settings.feed.scrollTop = firstRealSlide.offsetTop\n } else {\n settings.feed.scrollLeft = firstRealSlide.offsetLeft\n }\n }\n })\n\n loopState.initialized = true\n }\n\n const handleLoopReposition = (navDirection: SliderNavDirection): void => {\n if (!settings.loop || !loopState.initialized) return\n\n state.isLoopRepositioning = true\n\n const realSlides = loopState.realSlides\n const totalRealSlides = realSlides.length\n\n if (navDirection === 'next') {\n const firstRealSlide = realSlides[0]\n if (firstRealSlide) {\n if (isVertical) {\n settings.feed.scrollTop = firstRealSlide.offsetTop\n } else {\n settings.feed.scrollLeft = firstRealSlide.offsetLeft\n }\n }\n state.currentSlideIndex = 0\n } else {\n const lastRealSlide = realSlides[totalRealSlides - 1]\n if (lastRealSlide) {\n if (isVertical) {\n settings.feed.scrollTop = lastRealSlide.offsetTop\n } else {\n settings.feed.scrollLeft = lastRealSlide.offsetLeft\n }\n }\n state.currentSlideIndex = totalRealSlides - 1\n }\n\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n state.isLoopRepositioning = false\n updateControlsVisibility()\n })\n })\n }\n\n const cleanupLoopClones = (): void => {\n if (!loopState.initialized) return\n\n loopState.clonedSlides.forEach((clone) => {\n clone.remove()\n })\n\n loopState.clonedSlides = []\n loopState.initialized = false\n loopState.clonesPerSide = 0\n }\n\n const applySlideWidths = (): void => {\n const perView = isDesktop()\n ? settings.desktopSlidesPerView\n : settings.mobileSlidesPerView\n\n const gap = settings.slideGap ?? 0\n\n if (gap > 0) {\n settings.feed.style.gap = `${gap}px`\n }\n\n if (!perView || perView === 'auto') {\n settings.slides.forEach((slide) => {\n slide.style.flex = ''\n slide.style.minWidth = ''\n slide.style.minHeight = ''\n })\n return\n }\n\n const totalGapSize = gap * (perView - 1)\n const slideSize = `calc((100% - ${totalGapSize}px) / ${perView})`\n\n if (isVertical) {\n settings.slides.forEach((slide) => {\n slide.style.flex = `0 0 ${slideSize}`\n slide.style.minHeight = slideSize\n slide.style.minWidth = ''\n })\n } else {\n settings.slides.forEach((slide) => {\n slide.style.flex = `0 0 ${slideSize}`\n slide.style.minWidth = slideSize\n slide.style.minHeight = ''\n })\n }\n }\n\n const updateScrollbar = (): void => {\n if (!settings.scrollbarThumb) return\n\n const feedRect = getFeedRect()\n\n if (isVertical) {\n const thumbHeight = (feedRect.height / settings.feed.scrollHeight) * 100\n settings.scrollbarThumb.style.height = `${thumbHeight}%`\n settings.scrollbarThumb.style.width = ''\n } else {\n const thumbWidth = (feedRect.width / settings.feed.scrollWidth) * 100\n settings.scrollbarThumb.style.width = `${thumbWidth}%`\n settings.scrollbarThumb.style.height = ''\n }\n }\n\n const updateScrollbarPosition = (): void => {\n if (!settings.scrollbarThumb || !settings.scrollbarTrack) return\n\n if (isVertical) {\n const trackHeight = settings.scrollbarTrack.getBoundingClientRect().height\n const thumbHeight = settings.scrollbarThumb.getBoundingClientRect().height\n const totalTransform = trackHeight - thumbHeight\n\n const maxScroll = settings.feed.scrollHeight - settings.feed.clientHeight\n const scrollProgress = maxScroll > 0 ? settings.feed.scrollTop / maxScroll : 0\n\n settings.scrollbarThumb.style.transform = `translateY(${totalTransform * scrollProgress}px)`\n } else {\n const trackWidth = settings.scrollbarTrack.getBoundingClientRect().width\n const thumbWidth = settings.scrollbarThumb.getBoundingClientRect().width\n const totalTransform = trackWidth - thumbWidth\n\n const maxScroll = settings.feed.scrollWidth - settings.feed.clientWidth\n const scrollProgress = maxScroll > 0 ? settings.feed.scrollLeft / maxScroll : 0\n\n settings.scrollbarThumb.style.transform = `translateX(${totalTransform * scrollProgress}px)`\n }\n }\n\n const updateControlsVisibility = (): void => {\n // Skip visibility updates during loop repositioning to prevent flicker\n if (state.isLoopRepositioning) {\n return\n }\n\n const feedRect = getFeedRect()\n\n let isAtStart: boolean\n let isAtEnd: boolean\n let shouldHideScrollbar: boolean\n\n if (isVertical) {\n isAtStart = settings.feed.scrollTop <= 1\n isAtEnd = settings.feed.scrollTop + feedRect.height >= settings.feed.scrollHeight - 1\n shouldHideScrollbar = settings.feed.scrollHeight <= feedRect.height\n } else {\n isAtStart = settings.feed.scrollLeft <= 1\n isAtEnd = settings.feed.scrollLeft + feedRect.width >= settings.feed.scrollWidth - 1\n shouldHideScrollbar = settings.feed.scrollWidth <= feedRect.width\n }\n\n if (settings.scrollbarTrack) {\n settings.scrollbarTrack.style.display = shouldHideScrollbar ? 'none' : 'block'\n }\n\n if (settings.loop) {\n toggleControlVisibility(\n settings.prevSlideButton,\n !shouldHideScrollbar,\n settings.feed\n )\n toggleControlVisibility(\n settings.nextSlideButton,\n !shouldHideScrollbar,\n settings.feed\n )\n return\n }\n\n toggleControlVisibility(\n settings.prevSlideButton,\n !isAtStart && !shouldHideScrollbar,\n settings.feed\n )\n toggleControlVisibility(\n settings.nextSlideButton,\n !isAtEnd && !shouldHideScrollbar,\n settings.feed\n )\n }\n\n const updateCurrentSlideIndex = (): void => {\n const feedRect = getFeedRect()\n\n const slidesToCheck = loopState.initialized\n ? loopState.realSlides\n : getVisibleSlides()\n\n const viewportVisibleSlides = slidesToCheck.filter((slide) => {\n const slideRect = slide.getBoundingClientRect()\n const tolerance = 20\n\n if (isVertical) {\n return (\n slideRect.bottom > feedRect.top + tolerance &&\n slideRect.top < feedRect.bottom - tolerance\n )\n }\n\n return (\n slideRect.right > feedRect.left + tolerance &&\n slideRect.left < feedRect.right - tolerance\n )\n })\n\n if (viewportVisibleSlides.length && viewportVisibleSlides[0]) {\n const newIndex = slidesToCheck.indexOf(viewportVisibleSlides[0])\n if (newIndex !== -1) {\n state.currentSlideIndex = newIndex\n const currentScroll = isVertical ? settings.feed.scrollTop : settings.feed.scrollLeft\n settings.onScroll?.({\n currentScroll,\n currentSlideIndex: state.currentSlideIndex\n })\n }\n }\n }\n\n const smoothScrollTo = (\n target: number,\n customEasing: EasingFunction = easing,\n onComplete?: () => void\n ): void => {\n const start = isVertical ? settings.feed.scrollTop : settings.feed.scrollLeft\n const distance = Math.abs(target - start)\n\n const duration = Math.min(\n ANIMATION.MAX_DURATION,\n Math.max(ANIMATION.MIN_DURATION, distance / ANIMATION.SPEED_FACTOR)\n )\n\n const startTime = performance.now()\n\n const animateScroll = (currentTime: number): void => {\n const elapsed = (currentTime - startTime) / duration\n const progress = Math.min(elapsed, 1)\n const ease = customEasing(progress)\n\n const scrollPosition = start + (target - start) * ease\n\n if (isVertical) {\n settings.feed.scrollTop = scrollPosition\n } else {\n settings.feed.scrollLeft = scrollPosition\n }\n\n if (progress < 1) {\n requestAnimationFrame(animateScroll)\n } else {\n if (isVertical) {\n settings.feed.scrollTop = target\n } else {\n settings.feed.scrollLeft = target\n }\n onComplete?.()\n }\n }\n\n requestAnimationFrame(animateScroll)\n }\n\n const handleThumbClick = (thumb: HTMLElement): void => {\n if (!settings.thumbs) return\n\n const index = settings.thumbs.indexOf(thumb)\n if (index === -1 || !settings.slides[index]) return\n\n state.currentSlideIndex = index\n updateActiveThumb(settings.thumbs, index)\n state.isScrolling = true\n\n if (state.updateThumbTimeout) {\n clearTimeout(state.updateThumbTimeout)\n }\n\n state.updateThumbTimeout = setTimeout(() => {\n state.isScrolling = false\n }, ANIMATION.THUMB_UPDATE_DELAY)\n\n const targetPosition = isVertical\n ? settings.slides[index].offsetTop\n : settings.slides[index].offsetLeft\n smoothScrollTo(targetPosition)\n }\n\n const handleNavButtonClick = (navDirection: SliderNavDirection): void => {\n const realSlides = loopState.initialized ? loopState.realSlides : getVisibleSlides()\n const slidesToScroll = isDesktop()\n ? settings.desktopSlidesPerScroll ?? 1\n : settings.mobileSlidesPerScroll ?? 1\n const totalRealSlides = realSlides.length\n\n updateCurrentSlideIndex()\n\n let targetSlide: HTMLElement | undefined\n let needsReposition = false\n\n if (navDirection === 'prev') {\n if (settings.loop && loopState.initialized && state.currentSlideIndex === 0) {\n\n const prependedClones = loopState.clonedSlides.filter(\n (clone) => clone.getAttribute('data-lazer-clone') === 'prepend'\n )\n targetSlide = prependedClones[prependedClones.length - 1]\n needsReposition = true\n } else {\n state.currentSlideIndex = Math.max(0, state.currentSlideIndex - slidesToScroll)\n targetSlide = realSlides[state.currentSlideIndex]\n }\n } else {\n if (settings.loop && loopState.initialized && state.currentSlideIndex >= totalRealSlides - 1) {\n const appendedClones = loopState.clonedSlides.filter(\n (clone) => clone.getAttribute('data-lazer-clone') === 'append'\n )\n targetSlide = appendedClones[0]\n needsReposition = true\n } else {\n state.currentSlideIndex = Math.min(\n totalRealSlides - 1,\n state.currentSlideIndex + slidesToScroll\n )\n targetSlide = realSlides[state.currentSlideIndex]\n }\n }\n\n if (!targetSlide) return\n\n const currentScroll = isVertical ? settings.feed.scrollTop : settings.feed.scrollLeft\n settings.onScrollStart?.({\n currentScroll,\n target: targetSlide,\n direction: navDirection\n })\n\n const targetPosition = isVertical ? targetSlide.offsetTop : targetSlide.offsetLeft\n\n if (needsReposition) {\n smoothScrollTo(targetPosition, easing, () => {\n handleLoopReposition(navDirection)\n })\n } else {\n smoothScrollTo(targetPosition)\n }\n }\n\n const updateScrollPosition = (): void => {\n updateScrollbarPosition()\n updateControlsVisibility()\n updateCurrentSlideIndex()\n\n if (!state.isScrolling) {\n updateActiveThumb(settings.thumbs, state.currentSlideIndex)\n }\n\n if (state.scrollEndTimeout) {\n clearTimeout(state.scrollEndTimeout)\n }\n\n state.scrollEndTimeout = setTimeout(() => {\n state.isScrolling = false\n const currentScroll = isVertical ? settings.feed.scrollTop : settings.feed.scrollLeft\n settings.onScrollEnd?.({\n currentScroll,\n currentSlideIndex: state.currentSlideIndex\n })\n }, ANIMATION.SCROLL_END_DELAY)\n }\n\n const handleFeedScroll = (): void => {\n if (!state.ticking) {\n requestAnimationFrame(() => {\n updateScrollPosition()\n state.ticking = false\n })\n state.ticking = true\n }\n }\n\n const handleWindowResize = (): void => {\n state.cachedFeedRect = null\n refresh()\n }\n\n const attachEventListeners = (): void => {\n const { signal } = state.abortController\n\n window.addEventListener('resize', handleWindowResize)\n\n settings.feed.addEventListener('scroll', handleFeedScroll, {\n passive: true,\n signal\n })\n\n if (settings.prevSlideButton) {\n settings.prevSlideButton.addEventListener(\n 'click',\n () => handleNavButtonClick('prev'),\n { signal }\n )\n }\n\n if (settings.nextSlideButton) {\n settings.nextSlideButton.addEventListener(\n 'click',\n () => handleNavButtonClick('next'),\n { signal }\n )\n }\n\n if (settings.thumbs?.length) {\n settings.thumbs[0]?.classList.add('active')\n settings.thumbs.forEach((thumb) => {\n thumb.addEventListener('click', () => handleThumbClick(thumb), { signal })\n })\n }\n\n setupKeyboardNavigation(\n settings.feed,\n () => handleNavButtonClick('prev'),\n () => handleNavButtonClick('next'),\n signal,\n direction\n )\n\n if (settings.enableDragToScroll !== false) {\n dragState = setupDragToScroll({\n feed: settings.feed,\n slides: settings.slides,\n abortSignal: signal,\n smoothScrollTo,\n onDragEnd: () => {\n updateCurrentSlideIndex()\n updateActiveThumb(settings.thumbs, state.currentSlideIndex)\n },\n direction\n })\n }\n\n if (settings.autoplay && settings.pauseOnHover !== false) {\n settings.feed.addEventListener(\n 'mouseenter',\n pauseAutoplay,\n { signal }\n )\n settings.feed.addEventListener(\n 'mouseleave',\n resumeAutoplay,\n { signal }\n )\n settings.feed.addEventListener(\n 'touchstart',\n pauseAutoplay,\n { passive: true, signal }\n )\n settings.feed.addEventListener(\n 'touchend',\n resumeAutoplay,\n { signal }\n )\n }\n\n attachMarqueeEventListeners(settings, state, signal)\n }\n\n const startAutoplay = (): void => {\n if (state.autoplayIntervalId) return;\n\n const interval = settings.autoplayInterval ?? 3000\n state.autoplayIntervalId = setInterval(() => {\n if (!state.autoplayPaused) {\n handleNavButtonClick('next')\n }\n }, interval)\n }\n\n const stopAutoplay = (): void => {\n if (state.autoplayIntervalId) {\n clearInterval(state.autoplayIntervalId)\n state.autoplayIntervalId = null\n }\n }\n\n const pauseAutoplay = (): void => {\n state.autoplayPaused = true\n }\n\n const resumeAutoplay = (): void => {\n state.autoplayPaused = false\n }\n\n const goToIndex = (index: number): void => {\n const slides = loopState.initialized ? loopState.realSlides : getVisibleSlides()\n const safeIndex = Math.max(0, Math.min(index, slides.length - 1))\n const targetSlide = slides[safeIndex]\n\n if (!targetSlide) return\n\n state.currentSlideIndex = safeIndex\n updateActiveThumb(settings.thumbs, safeIndex)\n const targetPosition = isVertical ? targetSlide.offsetTop : targetSlide.offsetLeft\n smoothScrollTo(targetPosition)\n }\n\n const refresh = (): void => {\n state.cachedFeedRect = null\n applySlideWidths()\n updateScrollbar()\n updateControlsVisibility()\n\n if (settings.marquee && !state.marqueePaused) {\n startMarquee(settings, state)\n }\n }\n\n const unload = (): void => {\n stopAutoplay()\n stopMarquee(state, settings)\n\n state.abortController.abort()\n window.removeEventListener('resize', handleWindowResize)\n\n if (state.updateThumbTimeout) {\n clearTimeout(state.updateThumbTimeout)\n }\n if (state.scrollEndTimeout) {\n clearTimeout(state.scrollEndTimeout)\n }\n\n if (dragState) {\n cleanupDrag(dragState)\n }\n\n cleanupLoopClones()\n cleanupMarqueeClones(marqueeState)\n\n state.cachedFeedRect = null\n }\n\n initAria(settings)\n applySlideWidths()\n\n if (settings.marquee) {\n setupMarquee(settings, state, marqueeState)\n } else {\n setupLoopClones()\n if (settings.autoplay) {\n startAutoplay()\n }\n }\n\n updateControlsVisibility()\n attachEventListeners()\n updateScrollbar()\n\n const play = (): void => {\n if (settings.marquee) {\n if (state.marqueePaused) {\n resumeMarquee(state, settings)\n } else {\n startMarquee(settings, state)\n }\n } else if (settings.autoplay) {\n startAutoplay()\n }\n }\n\n const pause = (): void => {\n if (settings.marquee) {\n pauseMarquee(state, settings)\n } else {\n stopAutoplay()\n }\n }\n\n return {\n goToIndex,\n refresh,\n unload,\n play,\n pause,\n next: () => handleNavButtonClick('next'),\n prev: () => handleNavButtonClick('prev')\n }\n}"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/core/easing.ts","../src/core/accessibility.ts","../src/core/drag.ts","../src/core/bullets.ts","../src/core/thumbs.ts","../src/core/marquee.ts","../src/core/styles.ts","../src/core/slider.ts"],"sourcesContent":["export { createSlider } from './core/slider.js'\n\nexport type {\n SliderSettings,\n SliderState,\n SliderDirection,\n SliderNavDirection,\n MarqueeDirection,\n ScrollStartParams,\n ScrollParams,\n EasingFunction,\n Slider,\n DragState\n} from './core/types.js'\n\nexport {\n easeOutExpo,\n easeOutCubic,\n easeInOutCubic,\n easeOutQuad,\n linear\n} from './core/easing.js'\n\nexport { generateBullets } from './core/bullets.js'\n\nexport { generateThumbs } from './core/thumbs.js'\n\nexport { injectStyles, removeStyles } from './core/styles.js'\n","import type { EasingFunction } from './types.js'\n\n/**\n * Exponential ease-out - starts fast, decelerates smoothly\n * Best for scroll animations as it feels natural and responsive\n */\nexport const easeOutExpo: EasingFunction = (t) =>\n t === 1 ? 1 : 1 - Math.pow(2, -10 * t)\n\n/**\n * Cubic ease-out - smoother deceleration than exponential\n */\nexport const easeOutCubic: EasingFunction = (t) => 1 - Math.pow(1 - t, 3)\n\n/**\n * Cubic ease-in-out - smooth acceleration and deceleration\n */\nexport const easeInOutCubic: EasingFunction = (t) =>\n t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2\n\n/**\n * Quadratic ease-out - gentle deceleration\n */\nexport const easeOutQuad: EasingFunction = (t) => 1 - (1 - t) * (1 - t)\n\n/**\n * Linear - no easing, constant speed\n */\nexport const linear: EasingFunction = (t) => t\n","import type { SliderSettings, SliderDirection } from './types.js'\n\n/**\n * Generate a unique ID for the slider\n */\nexport const generateSliderId = (): string =>\n `slider-${Math.random().toString(36).substring(2, 9)}`\n\n/**\n * Initialize ARIA attributes\n */\nexport const initAria = (settings: SliderSettings): void => {\n const { feed, prevSlideButton, nextSlideButton, thumbs, slides } = settings\n\n if (!feed.id) {\n feed.id = generateSliderId()\n }\n\n feed.setAttribute('role', 'region')\n feed.setAttribute('aria-label', 'Carousel')\n feed.setAttribute('aria-roledescription', 'carousel')\n\n feed.removeAttribute('tabindex')\n\n slides.forEach((slide, index) => {\n slide.setAttribute('role', 'group')\n slide.setAttribute('aria-roledescription', 'slide')\n slide.setAttribute('aria-label', `Slide ${index + 1} of ${slides.length}`)\n })\n\n if (prevSlideButton) {\n prevSlideButton.setAttribute('aria-label', 'Previous slide')\n prevSlideButton.setAttribute('aria-controls', feed.id)\n prevSlideButton.setAttribute('tabindex', '0')\n if (prevSlideButton.tagName !== 'BUTTON') {\n prevSlideButton.setAttribute('role', 'button')\n }\n }\n\n if (nextSlideButton) {\n nextSlideButton.setAttribute('aria-label', 'Next slide')\n nextSlideButton.setAttribute('aria-controls', feed.id)\n nextSlideButton.setAttribute('tabindex', '0')\n if (nextSlideButton.tagName !== 'BUTTON') {\n nextSlideButton.setAttribute('role', 'button')\n }\n }\n\n if (thumbs?.length) {\n thumbs.forEach((thumb, index) => {\n if (thumb.tagName !== 'BUTTON') {\n thumb.setAttribute('role', 'button')\n }\n thumb.setAttribute('aria-label', `Go to slide ${index + 1}`)\n thumb.setAttribute('tabindex', '0')\n thumb.setAttribute('aria-controls', feed.id)\n })\n }\n}\n\n/**\n * Toggle visibility of navigation controls\n */\nexport const toggleControlVisibility = (\n button: HTMLElement | null | undefined,\n shouldShow: boolean,\n feedElement?: HTMLElement\n): void => {\n if (!button) return\n\n if (!shouldShow && button === document.activeElement && feedElement) {\n feedElement.focus()\n }\n\n const transition = 'opacity 0.3s ease'\n const opacity = shouldShow ? '1' : '0'\n\n Object.assign(button.style, {\n opacity,\n transition,\n pointerEvents: shouldShow ? 'auto' : 'none'\n })\n\n if (!shouldShow) {\n button.setAttribute('aria-hidden', 'true')\n button.setAttribute('tabindex', '-1')\n } else {\n button.removeAttribute('aria-hidden')\n button.setAttribute('tabindex', '0')\n }\n\n if (!shouldShow) {\n setTimeout(() => {\n if (button.style.opacity === '0') {\n button.style.visibility = 'hidden'\n }\n }, 300)\n } else {\n button.style.visibility = 'visible'\n }\n}\n\n/**\n * Update active state on thumbs\n */\nexport const updateActiveThumb = (\n thumbs: HTMLElement[] | undefined,\n currentIndex: number,\n activeClass: string = 'active'\n): void => {\n if (!thumbs?.length) return\n\n thumbs.forEach((thumb, index) => {\n const isActive = index === currentIndex\n thumb.classList.toggle(activeClass, isActive)\n thumb.setAttribute('aria-selected', isActive.toString())\n })\n}\n\n/**\n * Keyboard navigation\n */\nexport const setupKeyboardNavigation = (\n feed: HTMLElement,\n onPrev: () => void,\n onNext: () => void,\n abortSignal: AbortSignal,\n direction: SliderDirection = 'horizontal'\n): void => {\n const isVertical = direction === 'vertical'\n const prevKey = isVertical ? 'ArrowUp' : 'ArrowLeft'\n const nextKey = isVertical ? 'ArrowDown' : 'ArrowRight'\n\n feed.addEventListener(\n 'keydown',\n (event: KeyboardEvent) => {\n switch (event.key) {\n case prevKey:\n event.preventDefault()\n onPrev()\n break\n case nextKey:\n event.preventDefault()\n onNext()\n break\n }\n },\n { signal: abortSignal }\n )\n\n if (!feed.hasAttribute('tabindex')) {\n feed.setAttribute('tabindex', '0')\n }\n}\n","import type { DragState, EasingFunction, SliderDirection } from './types.js'\nimport { easeOutCubic } from './easing.js'\n\n/**\n * Configuration for drag behavior\n */\ninterface DragConfig {\n /** Feed element to enable dragging on */\n feed: HTMLElement\n /** Slide elements for snap-to-slide calculation */\n slides: HTMLElement[]\n /** AbortSignal for cleanup */\n abortSignal: AbortSignal\n /** Callback to smooth scroll to a position */\n smoothScrollTo: (target: number, easing?: EasingFunction) => void\n /** Callback when drag ends (for updating state) */\n onDragEnd?: () => void\n /** Direction of the slider (horizontal or vertical) */\n direction?: SliderDirection\n}\n\nexport const createDragState = (): DragState => ({\n isDragging: false,\n startX: 0,\n startY: 0,\n startScrollLeft: 0,\n startScrollTop: 0,\n velocity: 0,\n lastX: 0,\n lastY: 0,\n lastTime: 0,\n momentumId: null\n})\n\nconst findNearestSlide = (\n feed: HTMLElement,\n slides: HTMLElement[],\n direction: SliderDirection = 'horizontal'\n): HTMLElement | null => {\n const feedRect = feed.getBoundingClientRect()\n const isVertical = direction === 'vertical'\n\n const feedCenter = isVertical\n ? feedRect.top + feedRect.height / 2\n : feedRect.left + feedRect.width / 2\n\n let nearestSlide: HTMLElement | null = null\n let minDistance = Infinity\n\n for (const slide of slides) {\n if (slide.offsetParent === null) continue\n\n const slideRect = slide.getBoundingClientRect()\n const slideCenter = isVertical\n ? slideRect.top + slideRect.height / 2\n : slideRect.left + slideRect.width / 2\n const distance = Math.abs(feedCenter - slideCenter)\n\n if (distance < minDistance) {\n minDistance = distance\n nearestSlide = slide\n }\n }\n\n return nearestSlide\n}\n\nconst applyMomentum = (\n state: DragState,\n feed: HTMLElement,\n slides: HTMLElement[],\n smoothScrollTo: (target: number, easing?: EasingFunction) => void,\n onDragEnd?: () => void,\n direction: SliderDirection = 'horizontal'\n): void => {\n const friction = 0.95\n const minVelocity = 0.5\n const isVertical = direction === 'vertical'\n\n const animate = () => {\n if (Math.abs(state.velocity) < minVelocity) {\n state.momentumId = null\n\n const nearestSlide = findNearestSlide(feed, slides, direction)\n if (nearestSlide) {\n const targetPosition = isVertical ? nearestSlide.offsetTop : nearestSlide.offsetLeft\n smoothScrollTo(targetPosition, easeOutCubic)\n }\n\n onDragEnd?.()\n return\n }\n\n if (isVertical) {\n feed.scrollTop += state.velocity\n } else {\n feed.scrollLeft += state.velocity\n }\n state.velocity *= friction\n\n state.momentumId = requestAnimationFrame(animate)\n }\n\n state.momentumId = requestAnimationFrame(animate)\n}\n\nconst getEventX = (event: MouseEvent | TouchEvent): number => {\n if ('touches' in event) {\n return event.touches[0]?.clientX ?? 0\n }\n return event.clientX\n}\n\nconst getEventY = (event: MouseEvent | TouchEvent): number => {\n if ('touches' in event) {\n return event.touches[0]?.clientY ?? 0\n }\n return event.clientY\n}\n\nexport const setupDragToScroll = (config: DragConfig): DragState => {\n const { feed, slides, abortSignal, smoothScrollTo, onDragEnd, direction = 'horizontal' } = config\n const state = createDragState()\n const isVertical = direction === 'vertical'\n\n const handleDragStart = (event: MouseEvent | TouchEvent) => {\n if (state.momentumId !== null) {\n cancelAnimationFrame(state.momentumId)\n state.momentumId = null\n }\n\n state.isDragging = true\n state.startX = getEventX(event)\n state.startY = getEventY(event)\n state.startScrollLeft = feed.scrollLeft\n state.startScrollTop = feed.scrollTop\n state.velocity = 0\n state.lastX = state.startX\n state.lastY = state.startY\n state.lastTime = performance.now()\n\n feed.style.userSelect = 'none'\n feed.classList.add('is-dragging')\n\n if (event.type === 'mousedown') {\n event.preventDefault()\n }\n }\n\n const handleDragMove = (event: MouseEvent | TouchEvent) => {\n if (!state.isDragging) return\n\n const currentX = getEventX(event)\n const currentY = getEventY(event)\n const currentTime = performance.now()\n const deltaTime = currentTime - state.lastTime\n\n if (isVertical) {\n const deltaY = state.startY - currentY\n feed.scrollTop = state.startScrollTop + deltaY\n\n if (deltaTime > 0) {\n state.velocity = (state.lastY - currentY) / deltaTime * 16\n }\n state.lastY = currentY\n } else {\n const deltaX = state.startX - currentX\n feed.scrollLeft = state.startScrollLeft + deltaX\n\n if (deltaTime > 0) {\n state.velocity = (state.lastX - currentX) / deltaTime * 16\n }\n state.lastX = currentX\n }\n\n state.lastTime = currentTime\n\n if (event.type === 'touchmove') {\n event.preventDefault()\n }\n }\n\n const handleDragEnd = () => {\n if (!state.isDragging) return\n\n state.isDragging = false\n\n feed.style.userSelect = ''\n feed.classList.remove('is-dragging')\n\n if (Math.abs(state.velocity) > 1) {\n applyMomentum(state, feed, slides, smoothScrollTo, onDragEnd, direction)\n } else {\n const nearestSlide = findNearestSlide(feed, slides, direction)\n if (nearestSlide) {\n const targetPosition = isVertical ? nearestSlide.offsetTop : nearestSlide.offsetLeft\n smoothScrollTo(targetPosition, easeOutCubic)\n }\n onDragEnd?.()\n }\n }\n\n feed.addEventListener('mousedown', handleDragStart, { signal: abortSignal })\n document.addEventListener('mousemove', handleDragMove, { signal: abortSignal })\n document.addEventListener('mouseup', handleDragEnd, { signal: abortSignal })\n\n feed.addEventListener('touchstart', handleDragStart, {\n passive: true,\n signal: abortSignal\n })\n feed.addEventListener('touchmove', handleDragMove, {\n passive: false,\n signal: abortSignal\n })\n feed.addEventListener('touchend', handleDragEnd, { signal: abortSignal })\n\n document.addEventListener('mouseleave', handleDragEnd, { signal: abortSignal })\n\n return state\n}\n\nexport const cleanupDrag = (state: DragState): void => {\n if (state.momentumId !== null) {\n cancelAnimationFrame(state.momentumId)\n state.momentumId = null\n }\n}\n","export interface GenerateBulletsParams {\n bulletsContainer: HTMLElement\n slides: HTMLElement[]\n bulletClass: string\n bulletActiveClass: string\n feedId: string\n}\n\nexport const generateBullets = ({\n bulletsContainer,\n slides,\n bulletClass,\n bulletActiveClass,\n feedId,\n}: GenerateBulletsParams): HTMLElement[] => {\n if (!bulletsContainer || !(bulletsContainer instanceof HTMLElement)) {\n throw new Error('Invalid bulletsContainer: must be a valid HTMLElement')\n }\n\n if (!Array.isArray(slides) || slides.length === 0) {\n throw new Error('Invalid slides: must be a non-empty array')\n }\n\n if (!feedId || typeof feedId !== 'string') {\n throw new Error('Invalid feedId: must be a non-empty string')\n }\n\n if (!bulletClass || typeof bulletClass !== 'string') {\n throw new Error('Invalid bulletClass: must be a non-empty string')\n }\n\n bulletsContainer.innerHTML = ''\n bulletsContainer.setAttribute('role', 'tablist')\n bulletsContainer.setAttribute('aria-label', 'Slide navigation')\n\n const visibleSlides = slides\n .map((slide, originalIndex) => ({ slide, originalIndex }))\n .filter(({ slide }) => slide.offsetParent !== null)\n\n if (visibleSlides.length === 0) {\n console.warn('No visible slides found')\n return []\n }\n\n const bullets = visibleSlides.map(({ slide, originalIndex }, visibleIndex) => {\n const bullet = document.createElement('button')\n bullet.type = 'button'\n\n bullet.classList.add(bulletClass)\n if (visibleIndex === 0) {\n bullet.classList.add(bulletActiveClass)\n }\n\n bullet.setAttribute('role', 'tab')\n bullet.setAttribute('aria-selected', visibleIndex === 0 ? 'true' : 'false')\n bullet.setAttribute('aria-controls', feedId)\n bullet.setAttribute('aria-label', `Go to slide ${visibleIndex + 1}`)\n bullet.setAttribute('data-slide-index', String(visibleIndex))\n\n bulletsContainer.appendChild(bullet)\n\n return bullet\n })\n\n return bullets\n}\n\nexport const updateActiveBullet = (\n bullets: HTMLElement[],\n activeIndex: number,\n bulletActiveClass: string,\n): void => {\n if (!Array.isArray(bullets) || activeIndex < 0 || activeIndex >= bullets.length) {\n console.warn('Invalid activeIndex or bullets array')\n return\n }\n\n bullets.forEach((bullet, index) => {\n const isActive = index === activeIndex\n bullet.classList.toggle(bulletActiveClass, isActive)\n bullet.setAttribute('aria-selected', isActive ? 'true' : 'false')\n })\n}","export interface GenerateThumbsParams {\n thumbsContainer: HTMLElement\n slides: HTMLElement[]\n thumbClass: string\n thumbActiveClass: string\n feedId: string\n thumbImageSelector?: string\n thumbSize?: { width: number; height: number }\n}\n\nexport const generateThumbs = ({\n thumbsContainer,\n slides,\n thumbClass,\n thumbActiveClass,\n feedId,\n thumbImageSelector = 'img',\n thumbSize\n}: GenerateThumbsParams): HTMLElement[] => {\n if (!thumbsContainer || !(thumbsContainer instanceof HTMLElement)) {\n throw new Error('Invalid thumbsContainer: must be a valid HTMLElement')\n }\n\n if (!Array.isArray(slides) || slides.length === 0) {\n throw new Error('Invalid slides: must be a non-empty array')\n }\n\n if (!feedId || typeof feedId !== 'string') {\n throw new Error('Invalid feedId: must be a non-empty string')\n }\n\n if (!thumbClass || typeof thumbClass !== 'string') {\n throw new Error('Invalid thumbClass: must be a non-empty string')\n }\n\n thumbsContainer.innerHTML = ''\n thumbsContainer.setAttribute('role', 'tablist')\n thumbsContainer.setAttribute('aria-label', 'Slide thumbnails')\n\n const visibleSlides = slides\n .map((slide, originalIndex) => ({ slide, originalIndex }))\n .filter(({ slide }) => slide.offsetParent !== null)\n\n if (visibleSlides.length === 0) {\n console.warn('No visible slides found')\n return []\n }\n\n const thumbs = visibleSlides.map(({ slide, originalIndex }, visibleIndex) => {\n const thumb = document.createElement('button')\n thumb.type = 'button'\n\n thumb.classList.add(thumbClass)\n if (visibleIndex === 0) {\n thumb.classList.add(thumbActiveClass)\n }\n\n // Extract image from slide\n const sourceImage = slide.querySelector(thumbImageSelector) as HTMLImageElement | null\n if (sourceImage?.src) {\n const thumbImg = document.createElement('img')\n thumbImg.src = sourceImage.src\n thumbImg.alt = sourceImage.alt || `Slide ${visibleIndex + 1} thumbnail`\n thumbImg.draggable = false\n\n if (thumbSize) {\n thumbImg.style.width = `${thumbSize.width}px`\n thumbImg.style.height = `${thumbSize.height}px`\n thumbImg.style.objectFit = 'cover'\n }\n\n thumb.appendChild(thumbImg)\n }\n\n // Accessibility attributes\n thumb.setAttribute('role', 'tab')\n thumb.setAttribute('aria-selected', visibleIndex === 0 ? 'true' : 'false')\n thumb.setAttribute('aria-controls', feedId)\n thumb.setAttribute('aria-label', `Go to slide ${visibleIndex + 1}`)\n thumb.setAttribute('data-slide-index', String(visibleIndex))\n\n thumbsContainer.appendChild(thumb)\n\n return thumb\n })\n\n return thumbs\n}\n\nexport const updateActiveThumbnail = (\n thumbs: HTMLElement[],\n activeIndex: number,\n thumbActiveClass: string\n): void => {\n if (!Array.isArray(thumbs) || activeIndex < 0 || activeIndex >= thumbs.length) {\n console.warn('Invalid activeIndex or thumbs array')\n return\n }\n\n thumbs.forEach((thumb, index) => {\n const isActive = index === activeIndex\n thumb.classList.toggle(thumbActiveClass, isActive)\n thumb.setAttribute('aria-selected', isActive ? 'true' : 'false')\n })\n}\n\n","import type { SliderSettings, SliderState } from './types.js'\n\n/**\n * Marquee state - tracks cloned slides for marquee mode\n */\nexport interface MarqueeState {\n initialized: boolean\n clonedSlides: HTMLElement[]\n styleElement: HTMLStyleElement | null\n}\n\n/**\n * Create initial marquee state\n */\nexport const createMarqueeState = (): MarqueeState => ({\n initialized: false,\n clonedSlides: [],\n styleElement: null\n})\n\n/**\n * Inject CSS keyframes for smooth marquee animation\n */\nconst injectMarqueeKeyframes = (): HTMLStyleElement => {\n // Check if keyframes already exist\n const existingStyle = document.getElementById('lazer-marquee-keyframes')\n if (existingStyle) {\n return existingStyle as HTMLStyleElement\n }\n\n const style = document.createElement('style')\n style.id = 'lazer-marquee-keyframes'\n style.textContent = `\n @keyframes lazer-marquee-scroll {\n 0% {\n transform: translateX(0);\n }\n 100% {\n transform: translateX(-50%);\n }\n }\n `\n document.head.appendChild(style)\n return style\n}\n\n/**\n * Clone all slides and append for seamless marquee looping\n */\nexport const setupMarqueeClones = (\n settings: SliderSettings,\n marqueeState: MarqueeState\n): void => {\n if (marqueeState.initialized) return\n\n // Inject CSS keyframes\n marqueeState.styleElement = injectMarqueeKeyframes()\n\n // Ensure feed has proper CSS for transform animation\n // Note: Parent container should have overflow: hidden for marquee effect\n settings.feed.style.display = 'flex'\n settings.feed.style.willChange = 'transform'\n\n // Clone all original slides and append to create seamless loop\n settings.slides.forEach((slide) => {\n const clone = slide.cloneNode(true) as HTMLElement\n clone.setAttribute('data-lazer-marquee-clone', 'true')\n clone.setAttribute('aria-hidden', 'true')\n settings.feed.appendChild(clone)\n marqueeState.clonedSlides.push(clone)\n })\n\n marqueeState.initialized = true\n}\n\n/**\n * Remove marquee cloned slides from the DOM\n */\nexport const cleanupMarqueeClones = (marqueeState: MarqueeState): void => {\n if (!marqueeState.initialized) return\n\n marqueeState.clonedSlides.forEach((clone) => {\n clone.remove()\n })\n\n marqueeState.clonedSlides = []\n marqueeState.initialized = false\n}\n\n/**\n * Setup marquee CSS animation for smooth hardware-accelerated scrolling\n */\nconst setupMarqueeCss = (\n settings: SliderSettings,\n state: SliderState\n): void => {\n // Ensure keyframes exist first\n injectMarqueeKeyframes()\n\n // Wait a frame to ensure keyframes are parsed and layout is complete\n requestAnimationFrame(() => {\n const scrollWidth = settings.feed.scrollWidth\n const speed = settings.marqueeSpeed ?? 50 // pixels per second\n const direction = settings.marqueeDirection ?? 'left'\n\n // Distance is half the scroll width (the original content width)\n const distance = scrollWidth / 2\n\n // Validate values\n if (distance <= 0 || speed <= 0) {\n console.warn('[lazer-slider] Invalid marquee values:', { distance, speed, scrollWidth })\n return\n }\n\n // Calculate duration: distance / speed (how long to scroll through original content)\n const duration = distance / speed\n const animationDirection = direction === 'right' ? 'reverse' : 'normal'\n\n // Apply animation - use percentage-based keyframes for seamless loop\n const animationValue = `lazer-marquee-scroll ${duration}s linear infinite ${animationDirection}`\n\n // Remove any existing animation first\n settings.feed.style.animation = 'none'\n\n // Force reflow to reset animation\n void settings.feed.offsetWidth\n\n // Apply new animation\n settings.feed.style.animation = animationValue\n settings.feed.style.animationPlayState = state.marqueePaused ? 'paused' : 'running'\n })\n}\n\n/**\n * Start marquee animation using smooth CSS animations\n */\nexport const startMarquee = (\n settings: SliderSettings,\n state: SliderState\n): void => {\n // Setup CSS animation for smooth hardware-accelerated scrolling\n setupMarqueeCss(settings, state)\n}\n\n/**\n * Stop marquee animation\n */\nexport const stopMarquee = (state: SliderState, settings: SliderSettings): void => {\n // Remove animation\n settings.feed.style.animation = ''\n settings.feed.style.animationPlayState = ''\n\n // Reset transform\n settings.feed.style.transform = ''\n settings.feed.style.willChange = ''\n}\n\n/**\n * Pause marquee animation (temporary, resumes on mouse leave)\n */\nexport const pauseMarquee = (state: SliderState, settings: SliderSettings): void => {\n state.marqueePaused = true\n settings.feed.style.animationPlayState = 'paused'\n}\n\n/**\n * Resume marquee animation after pause\n */\nexport const resumeMarquee = (state: SliderState, settings: SliderSettings): void => {\n state.marqueePaused = false\n settings.feed.style.animationPlayState = 'running'\n}\n\n/**\n * Setup marquee mode (clones + animation)\n */\nexport const setupMarquee = (\n settings: SliderSettings,\n state: SliderState,\n marqueeState: MarqueeState\n): void => {\n if (!settings.marquee) return\n\n setupMarqueeClones(settings, marqueeState)\n startMarquee(settings, state)\n}\n\n/**\n * Attach marquee pause-on-hover event listeners\n */\nexport const attachMarqueeEventListeners = (\n settings: SliderSettings,\n state: SliderState,\n signal: AbortSignal\n): void => {\n if (!settings.marquee || settings.pauseOnHover === false) return\n\n settings.feed.addEventListener(\n 'mouseenter',\n () => pauseMarquee(state, settings),\n { signal }\n )\n settings.feed.addEventListener(\n 'mouseleave',\n () => resumeMarquee(state, settings),\n { signal }\n )\n settings.feed.addEventListener(\n 'touchstart',\n () => pauseMarquee(state, settings),\n { passive: true, signal }\n )\n settings.feed.addEventListener(\n 'touchend',\n () => resumeMarquee(state, settings),\n { signal }\n )\n}\n","/**\n * Critical CSS styles that are auto-injected for zero-config usage\n * Users can override these by using more specific selectors or !important\n */\nconst CRITICAL_STYLES = `\n/* Lazer Slider - Critical Styles (Auto-injected) */\n.lazer-feed {\n position: relative;\n display: flex;\n overflow-x: auto;\n overflow-y: hidden;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: none;\n}\n\n.lazer-feed::-webkit-scrollbar {\n display: none;\n}\n\n.lazer-feed.lazer-vertical {\n flex-direction: column;\n overflow-x: hidden;\n overflow-y: auto;\n}\n\n.lazer-slide {\n flex-shrink: 0;\n}\n\n.lazer-feed.lazer-draggable {\n cursor: grab;\n}\n\n.lazer-feed.lazer-draggable.is-dragging {\n cursor: grabbing;\n user-select: none;\n}\n`\n\nlet stylesInjected = false\nconst STYLE_ID = 'lazer-slider-critical-styles'\n\n/**\n * Injects critical CSS styles into the document head.\n * Safe to call multiple times - will only inject once.\n *\n * @example\n * ```typescript\n * import { injectStyles } from 'lazer-slider'\n *\n * // Manually inject styles (useful for SSR or early loading)\n * injectStyles()\n * ```\n */\nexport const injectStyles = (): void => {\n if (stylesInjected || typeof document === 'undefined') return\n\n const existingStyle = document.getElementById(STYLE_ID)\n if (existingStyle) {\n stylesInjected = true\n return\n }\n\n const style = document.createElement('style')\n style.id = STYLE_ID\n style.textContent = CRITICAL_STYLES\n document.head.appendChild(style)\n stylesInjected = true\n}\n\n/**\n * Internal function called by createSlider to ensure styles are injected\n * @internal\n */\nexport const injectStylesOnce = (): void => {\n injectStyles()\n}\n\n/**\n * Removes the injected styles from the document.\n * Useful for cleanup in testing or when completely removing the slider.\n *\n * @example\n * ```typescript\n * import { removeStyles } from 'lazer-slider'\n *\n * // Remove injected styles\n * removeStyles()\n * ```\n */\nexport const removeStyles = (): void => {\n if (typeof document === 'undefined') return\n\n const style = document.getElementById(STYLE_ID)\n if (style) {\n style.remove()\n stylesInjected = false\n }\n}\n\n","import type {\n SliderSettings,\n SliderState,\n SliderNavDirection,\n EasingFunction,\n Slider,\n DragState\n} from './types.js'\nimport { easeOutExpo } from './easing.js'\nimport {\n initAria,\n toggleControlVisibility,\n updateActiveThumb,\n setupKeyboardNavigation\n} from './accessibility.js'\nimport { setupDragToScroll, cleanupDrag } from './drag.js'\nimport { generateBullets } from './bullets.js'\nimport { generateThumbs } from './thumbs.js'\nimport {\n createMarqueeState,\n setupMarquee,\n startMarquee,\n stopMarquee,\n pauseMarquee,\n resumeMarquee,\n cleanupMarqueeClones,\n attachMarqueeEventListeners\n} from './marquee.js'\nimport { injectStylesOnce } from './styles.js'\n\nconst ANIMATION = {\n MIN_DURATION: 400,\n MAX_DURATION: 1000,\n SPEED_FACTOR: 1.5,\n SCROLL_END_DELAY: 50,\n THUMB_UPDATE_DELAY: 500\n} as const\n\nconst DESKTOP_BREAKPOINT = '(min-width: 64rem)'\n\nexport const createSlider = (settings: SliderSettings): Slider => {\n // Auto-inject critical CSS styles for zero-config usage\n injectStylesOnce()\n\n if (!settings.feed) {\n throw new Error('lazer-slider: feed element is required')\n }\n\n if (!settings.slides?.length) {\n throw new Error('lazer-slider: slides array is required and must not be empty')\n }\n\n if (!settings.feed.id) {\n settings.feed.id = `lazer-slider-feed-${Math.random().toString(36).substr(2, 9)}`\n }\n\n // Add classes for CSS targeting (if not already present)\n settings.feed.classList.add('lazer-feed')\n settings.slides.forEach((slide) => {\n slide.classList.add('lazer-slide')\n })\n\n if (settings.bulletsContainer && !settings.thumbs) {\n const bullets = generateBullets({\n bulletsContainer: settings.bulletsContainer,\n slides: settings.slides,\n bulletClass: settings.bulletsClass ?? 'lazer-bullet',\n bulletActiveClass: settings.bulletsActiveClass ?? 'active',\n feedId: settings.feed.id\n })\n settings.thumbs = bullets\n }\n\n if (settings.thumbsContainer && !settings.thumbs) {\n const thumbs = generateThumbs({\n thumbsContainer: settings.thumbsContainer,\n slides: settings.slides,\n thumbClass: settings.thumbsClass ?? 'lazer-thumb',\n thumbActiveClass: settings.thumbsActiveClass ?? 'active',\n feedId: settings.feed.id,\n thumbImageSelector: settings.thumbImageSelector ?? 'img',\n thumbSize: settings.thumbSize\n })\n settings.thumbs = thumbs\n }\n\n const direction = settings.direction ?? 'horizontal'\n const isVertical = direction === 'vertical'\n\n // Add vertical class for CSS targeting\n if (isVertical) {\n settings.feed.classList.add('lazer-vertical')\n }\n\n // Add marquee class if enabled\n if (settings.marquee) {\n settings.feed.classList.add('lazer-marquee')\n }\n\n const state: SliderState = {\n currentSlideIndex: 0,\n isScrolling: false,\n ticking: false,\n cachedFeedRect: null,\n lastWidth: 0,\n updateThumbTimeout: null,\n scrollEndTimeout: null,\n abortController: new AbortController(),\n autoplayIntervalId: null,\n autoplayPaused: false,\n marqueeAnimationId: null,\n marqueePaused: false,\n marqueeLastTimestamp: 0,\n isLoopRepositioning: false\n }\n\n let dragState: DragState | null = null\n\n const loopState = {\n initialized: false,\n clonedSlides: [] as HTMLElement[],\n realSlides: [...settings.slides] as HTMLElement[],\n clonesPerSide: 0\n }\n\n const marqueeState = createMarqueeState()\n\n const easing = settings.easing ?? easeOutExpo\n\n const getFeedRect = (): DOMRect => {\n const currentSize = isVertical ? settings.feed.clientHeight : settings.feed.clientWidth\n if (!state.cachedFeedRect || state.lastWidth !== currentSize) {\n state.cachedFeedRect = settings.feed.getBoundingClientRect()\n state.lastWidth = currentSize\n }\n return state.cachedFeedRect\n }\n\n const getVisibleSlides = (): HTMLElement[] => {\n return settings.slides.filter((slide) => slide.offsetParent !== null)\n }\n\n const isDesktop = (): boolean => {\n return window.matchMedia(DESKTOP_BREAKPOINT).matches\n }\n\n const getLoopClonesCount = (): number => {\n const perView = isDesktop()\n ? settings.desktopSlidesPerView\n : settings.mobileSlidesPerView\n\n if (!perView || perView === 'auto') {\n return 1\n }\n return Math.ceil(perView)\n }\n\n const setupLoopClones = (): void => {\n if (!settings.loop || loopState.initialized) return\n\n const realSlides = loopState.realSlides\n const clonesCount = getLoopClonesCount()\n loopState.clonesPerSide = clonesCount\n\n for (let i = realSlides.length - clonesCount; i < realSlides.length; i++) {\n const slide = realSlides[i]\n if (!slide) continue\n\n const clone = slide.cloneNode(true) as HTMLElement\n clone.setAttribute('data-lazer-clone', 'prepend')\n clone.setAttribute('aria-hidden', 'true')\n settings.feed.insertBefore(clone, settings.feed.firstChild)\n loopState.clonedSlides.push(clone)\n }\n\n for (let i = 0; i < clonesCount; i++) {\n const slide = realSlides[i]\n if (!slide) continue\n\n const clone = slide.cloneNode(true) as HTMLElement\n clone.setAttribute('data-lazer-clone', 'append')\n clone.setAttribute('aria-hidden', 'true')\n settings.feed.appendChild(clone)\n loopState.clonedSlides.push(clone)\n }\n\n requestAnimationFrame(() => {\n const firstRealSlide = realSlides[0]\n if (firstRealSlide) {\n if (isVertical) {\n settings.feed.scrollTop = firstRealSlide.offsetTop\n } else {\n settings.feed.scrollLeft = firstRealSlide.offsetLeft\n }\n }\n })\n\n loopState.initialized = true\n }\n\n const handleLoopReposition = (navDirection: SliderNavDirection): void => {\n if (!settings.loop || !loopState.initialized) return\n\n state.isLoopRepositioning = true\n\n const realSlides = loopState.realSlides\n const totalRealSlides = realSlides.length\n\n if (navDirection === 'next') {\n const firstRealSlide = realSlides[0]\n if (firstRealSlide) {\n if (isVertical) {\n settings.feed.scrollTop = firstRealSlide.offsetTop\n } else {\n settings.feed.scrollLeft = firstRealSlide.offsetLeft\n }\n }\n state.currentSlideIndex = 0\n } else {\n const lastRealSlide = realSlides[totalRealSlides - 1]\n if (lastRealSlide) {\n if (isVertical) {\n settings.feed.scrollTop = lastRealSlide.offsetTop\n } else {\n settings.feed.scrollLeft = lastRealSlide.offsetLeft\n }\n }\n state.currentSlideIndex = totalRealSlides - 1\n }\n\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n state.isLoopRepositioning = false\n updateControlsVisibility()\n })\n })\n }\n\n const cleanupLoopClones = (): void => {\n if (!loopState.initialized) return\n\n loopState.clonedSlides.forEach((clone) => {\n clone.remove()\n })\n\n loopState.clonedSlides = []\n loopState.initialized = false\n loopState.clonesPerSide = 0\n }\n\n const applySlideWidths = (): void => {\n const perView = isDesktop()\n ? settings.desktopSlidesPerView\n : settings.mobileSlidesPerView\n\n const gap = settings.slideGap ?? 0\n\n if (gap > 0) {\n settings.feed.style.gap = `${gap}px`\n }\n\n if (!perView || perView === 'auto') {\n settings.slides.forEach((slide) => {\n slide.style.flex = ''\n slide.style.minWidth = ''\n slide.style.minHeight = ''\n })\n return\n }\n\n const totalGapSize = gap * (perView - 1)\n const slideSize = `calc((100% - ${totalGapSize}px) / ${perView})`\n\n if (isVertical) {\n settings.slides.forEach((slide) => {\n slide.style.flex = `0 0 ${slideSize}`\n slide.style.minHeight = slideSize\n slide.style.minWidth = ''\n })\n } else {\n settings.slides.forEach((slide) => {\n slide.style.flex = `0 0 ${slideSize}`\n slide.style.minWidth = slideSize\n slide.style.minHeight = ''\n })\n }\n }\n\n const updateScrollbar = (): void => {\n if (!settings.scrollbarThumb) return\n\n const feedRect = getFeedRect()\n\n if (isVertical) {\n const thumbHeight = (feedRect.height / settings.feed.scrollHeight) * 100\n settings.scrollbarThumb.style.height = `${thumbHeight}%`\n settings.scrollbarThumb.style.width = ''\n } else {\n const thumbWidth = (feedRect.width / settings.feed.scrollWidth) * 100\n settings.scrollbarThumb.style.width = `${thumbWidth}%`\n settings.scrollbarThumb.style.height = ''\n }\n }\n\n const updateScrollbarPosition = (): void => {\n if (!settings.scrollbarThumb || !settings.scrollbarTrack) return\n\n if (isVertical) {\n const trackHeight = settings.scrollbarTrack.getBoundingClientRect().height\n const thumbHeight = settings.scrollbarThumb.getBoundingClientRect().height\n const totalTransform = trackHeight - thumbHeight\n\n const maxScroll = settings.feed.scrollHeight - settings.feed.clientHeight\n const scrollProgress = maxScroll > 0 ? settings.feed.scrollTop / maxScroll : 0\n\n settings.scrollbarThumb.style.transform = `translateY(${totalTransform * scrollProgress}px)`\n } else {\n const trackWidth = settings.scrollbarTrack.getBoundingClientRect().width\n const thumbWidth = settings.scrollbarThumb.getBoundingClientRect().width\n const totalTransform = trackWidth - thumbWidth\n\n const maxScroll = settings.feed.scrollWidth - settings.feed.clientWidth\n const scrollProgress = maxScroll > 0 ? settings.feed.scrollLeft / maxScroll : 0\n\n settings.scrollbarThumb.style.transform = `translateX(${totalTransform * scrollProgress}px)`\n }\n }\n\n const updateControlsVisibility = (): void => {\n // Skip visibility updates during loop repositioning to prevent flicker\n if (state.isLoopRepositioning) {\n return\n }\n\n const feedRect = getFeedRect()\n\n let isAtStart: boolean\n let isAtEnd: boolean\n let shouldHideScrollbar: boolean\n\n if (isVertical) {\n isAtStart = settings.feed.scrollTop <= 1\n isAtEnd = settings.feed.scrollTop + feedRect.height >= settings.feed.scrollHeight - 1\n shouldHideScrollbar = settings.feed.scrollHeight <= feedRect.height\n } else {\n isAtStart = settings.feed.scrollLeft <= 1\n isAtEnd = settings.feed.scrollLeft + feedRect.width >= settings.feed.scrollWidth - 1\n shouldHideScrollbar = settings.feed.scrollWidth <= feedRect.width\n }\n\n if (settings.scrollbarTrack) {\n settings.scrollbarTrack.style.display = shouldHideScrollbar ? 'none' : 'block'\n }\n\n if (settings.loop) {\n toggleControlVisibility(\n settings.prevSlideButton,\n !shouldHideScrollbar,\n settings.feed\n )\n toggleControlVisibility(\n settings.nextSlideButton,\n !shouldHideScrollbar,\n settings.feed\n )\n return\n }\n\n toggleControlVisibility(\n settings.prevSlideButton,\n !isAtStart && !shouldHideScrollbar,\n settings.feed\n )\n toggleControlVisibility(\n settings.nextSlideButton,\n !isAtEnd && !shouldHideScrollbar,\n settings.feed\n )\n }\n\n const updateCurrentSlideIndex = (): void => {\n const feedRect = getFeedRect()\n\n const slidesToCheck = loopState.initialized\n ? loopState.realSlides\n : getVisibleSlides()\n\n const viewportVisibleSlides = slidesToCheck.filter((slide) => {\n const slideRect = slide.getBoundingClientRect()\n const tolerance = 20\n\n if (isVertical) {\n return (\n slideRect.bottom > feedRect.top + tolerance &&\n slideRect.top < feedRect.bottom - tolerance\n )\n }\n\n return (\n slideRect.right > feedRect.left + tolerance &&\n slideRect.left < feedRect.right - tolerance\n )\n })\n\n if (viewportVisibleSlides.length && viewportVisibleSlides[0]) {\n const newIndex = slidesToCheck.indexOf(viewportVisibleSlides[0])\n if (newIndex !== -1) {\n state.currentSlideIndex = newIndex\n const currentScroll = isVertical ? settings.feed.scrollTop : settings.feed.scrollLeft\n settings.onScroll?.({\n currentScroll,\n currentSlideIndex: state.currentSlideIndex\n })\n }\n }\n }\n\n const smoothScrollTo = (\n target: number,\n customEasing: EasingFunction = easing,\n onComplete?: () => void\n ): void => {\n const start = isVertical ? settings.feed.scrollTop : settings.feed.scrollLeft\n const distance = Math.abs(target - start)\n\n const duration = Math.min(\n ANIMATION.MAX_DURATION,\n Math.max(ANIMATION.MIN_DURATION, distance / ANIMATION.SPEED_FACTOR)\n )\n\n const startTime = performance.now()\n\n const animateScroll = (currentTime: number): void => {\n const elapsed = (currentTime - startTime) / duration\n const progress = Math.min(elapsed, 1)\n const ease = customEasing(progress)\n\n const scrollPosition = start + (target - start) * ease\n\n if (isVertical) {\n settings.feed.scrollTop = scrollPosition\n } else {\n settings.feed.scrollLeft = scrollPosition\n }\n\n if (progress < 1) {\n requestAnimationFrame(animateScroll)\n } else {\n if (isVertical) {\n settings.feed.scrollTop = target\n } else {\n settings.feed.scrollLeft = target\n }\n onComplete?.()\n }\n }\n\n requestAnimationFrame(animateScroll)\n }\n\n const handleThumbClick = (thumb: HTMLElement): void => {\n if (!settings.thumbs) return\n\n const index = settings.thumbs.indexOf(thumb)\n if (index === -1 || !settings.slides[index]) return\n\n state.currentSlideIndex = index\n updateActiveThumb(settings.thumbs, index)\n state.isScrolling = true\n\n if (state.updateThumbTimeout) {\n clearTimeout(state.updateThumbTimeout)\n }\n\n state.updateThumbTimeout = setTimeout(() => {\n state.isScrolling = false\n }, ANIMATION.THUMB_UPDATE_DELAY)\n\n const targetPosition = isVertical\n ? settings.slides[index].offsetTop\n : settings.slides[index].offsetLeft\n smoothScrollTo(targetPosition)\n }\n\n const handleNavButtonClick = (navDirection: SliderNavDirection): void => {\n const realSlides = loopState.initialized ? loopState.realSlides : getVisibleSlides()\n const slidesToScroll = isDesktop()\n ? settings.desktopSlidesPerScroll ?? 1\n : settings.mobileSlidesPerScroll ?? 1\n const totalRealSlides = realSlides.length\n\n updateCurrentSlideIndex()\n\n let targetSlide: HTMLElement | undefined\n let needsReposition = false\n\n if (navDirection === 'prev') {\n if (settings.loop && loopState.initialized && state.currentSlideIndex === 0) {\n\n const prependedClones = loopState.clonedSlides.filter(\n (clone) => clone.getAttribute('data-lazer-clone') === 'prepend'\n )\n targetSlide = prependedClones[prependedClones.length - 1]\n needsReposition = true\n } else {\n state.currentSlideIndex = Math.max(0, state.currentSlideIndex - slidesToScroll)\n targetSlide = realSlides[state.currentSlideIndex]\n }\n } else {\n if (settings.loop && loopState.initialized && state.currentSlideIndex >= totalRealSlides - 1) {\n const appendedClones = loopState.clonedSlides.filter(\n (clone) => clone.getAttribute('data-lazer-clone') === 'append'\n )\n targetSlide = appendedClones[0]\n needsReposition = true\n } else {\n state.currentSlideIndex = Math.min(\n totalRealSlides - 1,\n state.currentSlideIndex + slidesToScroll\n )\n targetSlide = realSlides[state.currentSlideIndex]\n }\n }\n\n if (!targetSlide) return\n\n const currentScroll = isVertical ? settings.feed.scrollTop : settings.feed.scrollLeft\n settings.onScrollStart?.({\n currentScroll,\n target: targetSlide,\n direction: navDirection\n })\n\n const targetPosition = isVertical ? targetSlide.offsetTop : targetSlide.offsetLeft\n\n if (needsReposition) {\n smoothScrollTo(targetPosition, easing, () => {\n handleLoopReposition(navDirection)\n })\n } else {\n smoothScrollTo(targetPosition)\n }\n }\n\n const updateScrollPosition = (): void => {\n updateScrollbarPosition()\n updateControlsVisibility()\n updateCurrentSlideIndex()\n\n if (!state.isScrolling) {\n updateActiveThumb(settings.thumbs, state.currentSlideIndex)\n }\n\n if (state.scrollEndTimeout) {\n clearTimeout(state.scrollEndTimeout)\n }\n\n state.scrollEndTimeout = setTimeout(() => {\n state.isScrolling = false\n const currentScroll = isVertical ? settings.feed.scrollTop : settings.feed.scrollLeft\n settings.onScrollEnd?.({\n currentScroll,\n currentSlideIndex: state.currentSlideIndex\n })\n }, ANIMATION.SCROLL_END_DELAY)\n }\n\n const handleFeedScroll = (): void => {\n if (!state.ticking) {\n requestAnimationFrame(() => {\n updateScrollPosition()\n state.ticking = false\n })\n state.ticking = true\n }\n }\n\n const handleWindowResize = (): void => {\n state.cachedFeedRect = null\n refresh()\n }\n\n const attachEventListeners = (): void => {\n const { signal } = state.abortController\n\n window.addEventListener('resize', handleWindowResize)\n\n settings.feed.addEventListener('scroll', handleFeedScroll, {\n passive: true,\n signal\n })\n\n if (settings.prevSlideButton) {\n settings.prevSlideButton.addEventListener(\n 'click',\n () => handleNavButtonClick('prev'),\n { signal }\n )\n }\n\n if (settings.nextSlideButton) {\n settings.nextSlideButton.addEventListener(\n 'click',\n () => handleNavButtonClick('next'),\n { signal }\n )\n }\n\n if (settings.thumbs?.length) {\n settings.thumbs[0]?.classList.add('active')\n settings.thumbs.forEach((thumb) => {\n thumb.addEventListener('click', () => handleThumbClick(thumb), { signal })\n })\n }\n\n setupKeyboardNavigation(\n settings.feed,\n () => handleNavButtonClick('prev'),\n () => handleNavButtonClick('next'),\n signal,\n direction\n )\n\n if (settings.enableDragToScroll !== false) {\n dragState = setupDragToScroll({\n feed: settings.feed,\n slides: settings.slides,\n abortSignal: signal,\n smoothScrollTo,\n onDragEnd: () => {\n updateCurrentSlideIndex()\n updateActiveThumb(settings.thumbs, state.currentSlideIndex)\n },\n direction\n })\n }\n\n if (settings.autoplay && settings.pauseOnHover !== false) {\n settings.feed.addEventListener(\n 'mouseenter',\n pauseAutoplay,\n { signal }\n )\n settings.feed.addEventListener(\n 'mouseleave',\n resumeAutoplay,\n { signal }\n )\n settings.feed.addEventListener(\n 'touchstart',\n pauseAutoplay,\n { passive: true, signal }\n )\n settings.feed.addEventListener(\n 'touchend',\n resumeAutoplay,\n { signal }\n )\n }\n\n attachMarqueeEventListeners(settings, state, signal)\n }\n\n const startAutoplay = (): void => {\n if (state.autoplayIntervalId) return;\n\n const interval = settings.autoplayInterval ?? 3000\n state.autoplayIntervalId = setInterval(() => {\n if (!state.autoplayPaused) {\n handleNavButtonClick('next')\n }\n }, interval)\n }\n\n const stopAutoplay = (): void => {\n if (state.autoplayIntervalId) {\n clearInterval(state.autoplayIntervalId)\n state.autoplayIntervalId = null\n }\n }\n\n const pauseAutoplay = (): void => {\n state.autoplayPaused = true\n }\n\n const resumeAutoplay = (): void => {\n state.autoplayPaused = false\n }\n\n const goToIndex = (index: number): void => {\n const slides = loopState.initialized ? loopState.realSlides : getVisibleSlides()\n const safeIndex = Math.max(0, Math.min(index, slides.length - 1))\n const targetSlide = slides[safeIndex]\n\n if (!targetSlide) return\n\n state.currentSlideIndex = safeIndex\n updateActiveThumb(settings.thumbs, safeIndex)\n const targetPosition = isVertical ? targetSlide.offsetTop : targetSlide.offsetLeft\n smoothScrollTo(targetPosition)\n }\n\n const refresh = (): void => {\n state.cachedFeedRect = null\n applySlideWidths()\n updateScrollbar()\n updateControlsVisibility()\n\n if (settings.marquee && !state.marqueePaused) {\n startMarquee(settings, state)\n }\n }\n\n const unload = (): void => {\n stopAutoplay()\n stopMarquee(state, settings)\n\n state.abortController.abort()\n window.removeEventListener('resize', handleWindowResize)\n\n if (state.updateThumbTimeout) {\n clearTimeout(state.updateThumbTimeout)\n }\n if (state.scrollEndTimeout) {\n clearTimeout(state.scrollEndTimeout)\n }\n\n if (dragState) {\n cleanupDrag(dragState)\n }\n\n cleanupLoopClones()\n cleanupMarqueeClones(marqueeState)\n\n state.cachedFeedRect = null\n }\n\n initAria(settings)\n applySlideWidths()\n\n if (settings.marquee) {\n setupMarquee(settings, state, marqueeState)\n } else {\n setupLoopClones()\n if (settings.autoplay) {\n startAutoplay()\n }\n }\n\n updateControlsVisibility()\n attachEventListeners()\n updateScrollbar()\n\n const play = (): void => {\n if (settings.marquee) {\n if (state.marqueePaused) {\n resumeMarquee(state, settings)\n } else {\n startMarquee(settings, state)\n }\n } else if (settings.autoplay) {\n startAutoplay()\n }\n }\n\n const pause = (): void => {\n if (settings.marquee) {\n pauseMarquee(state, settings)\n } else {\n stopAutoplay()\n }\n }\n\n return {\n goToIndex,\n refresh,\n unload,\n play,\n pause,\n next: () => handleNavButtonClick('next'),\n prev: () => handleNavButtonClick('prev')\n }\n}"],"mappings":"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","names":[]}
|
package/dist/index.js
CHANGED
|
@@ -197,6 +197,7 @@ var setupDragToScroll = (config) => {
|
|
|
197
197
|
state.lastY = state.startY;
|
|
198
198
|
state.lastTime = performance.now();
|
|
199
199
|
feed.style.userSelect = "none";
|
|
200
|
+
feed.classList.add("is-dragging");
|
|
200
201
|
if (event.type === "mousedown") {
|
|
201
202
|
event.preventDefault();
|
|
202
203
|
}
|
|
@@ -231,6 +232,7 @@ var setupDragToScroll = (config) => {
|
|
|
231
232
|
if (!state.isDragging) return;
|
|
232
233
|
state.isDragging = false;
|
|
233
234
|
feed.style.userSelect = "";
|
|
235
|
+
feed.classList.remove("is-dragging");
|
|
234
236
|
if (Math.abs(state.velocity) > 1) {
|
|
235
237
|
applyMomentum(state, feed, slides, smoothScrollTo, onDragEnd, direction);
|
|
236
238
|
} else {
|
|
@@ -495,7 +497,6 @@ var CRITICAL_STYLES = `
|
|
|
495
497
|
overflow-y: hidden;
|
|
496
498
|
-webkit-overflow-scrolling: touch;
|
|
497
499
|
scrollbar-width: none;
|
|
498
|
-
scroll-snap-type: x mandatory;
|
|
499
500
|
}
|
|
500
501
|
|
|
501
502
|
.lazer-feed::-webkit-scrollbar {
|
|
@@ -506,22 +507,19 @@ var CRITICAL_STYLES = `
|
|
|
506
507
|
flex-direction: column;
|
|
507
508
|
overflow-x: hidden;
|
|
508
509
|
overflow-y: auto;
|
|
509
|
-
scroll-snap-type: y mandatory;
|
|
510
510
|
}
|
|
511
511
|
|
|
512
512
|
.lazer-slide {
|
|
513
|
-
scroll-snap-align: start;
|
|
514
513
|
flex-shrink: 0;
|
|
515
514
|
}
|
|
516
515
|
|
|
517
|
-
.lazer-feed.
|
|
518
|
-
cursor:
|
|
519
|
-
user-select: none;
|
|
520
|
-
scroll-snap-type: none;
|
|
516
|
+
.lazer-feed.lazer-draggable {
|
|
517
|
+
cursor: grab;
|
|
521
518
|
}
|
|
522
519
|
|
|
523
|
-
.lazer-feed
|
|
524
|
-
cursor:
|
|
520
|
+
.lazer-feed.lazer-draggable.is-dragging {
|
|
521
|
+
cursor: grabbing;
|
|
522
|
+
user-select: none;
|
|
525
523
|
}
|
|
526
524
|
`;
|
|
527
525
|
var stylesInjected = false;
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/easing.ts","../src/core/accessibility.ts","../src/core/drag.ts","../src/core/bullets.ts","../src/core/thumbs.ts","../src/core/marquee.ts","../src/core/styles.ts","../src/core/slider.ts"],"sourcesContent":["import type { EasingFunction } from './types.js'\n\n/**\n * Exponential ease-out - starts fast, decelerates smoothly\n * Best for scroll animations as it feels natural and responsive\n */\nexport const easeOutExpo: EasingFunction = (t) =>\n t === 1 ? 1 : 1 - Math.pow(2, -10 * t)\n\n/**\n * Cubic ease-out - smoother deceleration than exponential\n */\nexport const easeOutCubic: EasingFunction = (t) => 1 - Math.pow(1 - t, 3)\n\n/**\n * Cubic ease-in-out - smooth acceleration and deceleration\n */\nexport const easeInOutCubic: EasingFunction = (t) =>\n t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2\n\n/**\n * Quadratic ease-out - gentle deceleration\n */\nexport const easeOutQuad: EasingFunction = (t) => 1 - (1 - t) * (1 - t)\n\n/**\n * Linear - no easing, constant speed\n */\nexport const linear: EasingFunction = (t) => t\n","import type { SliderSettings, SliderDirection } from './types.js'\n\n/**\n * Generate a unique ID for the slider\n */\nexport const generateSliderId = (): string =>\n `slider-${Math.random().toString(36).substring(2, 9)}`\n\n/**\n * Initialize ARIA attributes\n */\nexport const initAria = (settings: SliderSettings): void => {\n const { feed, prevSlideButton, nextSlideButton, thumbs, slides } = settings\n\n if (!feed.id) {\n feed.id = generateSliderId()\n }\n\n feed.setAttribute('role', 'region')\n feed.setAttribute('aria-label', 'Carousel')\n feed.setAttribute('aria-roledescription', 'carousel')\n\n feed.removeAttribute('tabindex')\n\n slides.forEach((slide, index) => {\n slide.setAttribute('role', 'group')\n slide.setAttribute('aria-roledescription', 'slide')\n slide.setAttribute('aria-label', `Slide ${index + 1} of ${slides.length}`)\n })\n\n if (prevSlideButton) {\n prevSlideButton.setAttribute('aria-label', 'Previous slide')\n prevSlideButton.setAttribute('aria-controls', feed.id)\n prevSlideButton.setAttribute('tabindex', '0')\n if (prevSlideButton.tagName !== 'BUTTON') {\n prevSlideButton.setAttribute('role', 'button')\n }\n }\n\n if (nextSlideButton) {\n nextSlideButton.setAttribute('aria-label', 'Next slide')\n nextSlideButton.setAttribute('aria-controls', feed.id)\n nextSlideButton.setAttribute('tabindex', '0')\n if (nextSlideButton.tagName !== 'BUTTON') {\n nextSlideButton.setAttribute('role', 'button')\n }\n }\n\n if (thumbs?.length) {\n thumbs.forEach((thumb, index) => {\n if (thumb.tagName !== 'BUTTON') {\n thumb.setAttribute('role', 'button')\n }\n thumb.setAttribute('aria-label', `Go to slide ${index + 1}`)\n thumb.setAttribute('tabindex', '0')\n thumb.setAttribute('aria-controls', feed.id)\n })\n }\n}\n\n/**\n * Toggle visibility of navigation controls\n */\nexport const toggleControlVisibility = (\n button: HTMLElement | null | undefined,\n shouldShow: boolean,\n feedElement?: HTMLElement\n): void => {\n if (!button) return\n\n if (!shouldShow && button === document.activeElement && feedElement) {\n feedElement.focus()\n }\n\n const transition = 'opacity 0.3s ease'\n const opacity = shouldShow ? '1' : '0'\n\n Object.assign(button.style, {\n opacity,\n transition,\n pointerEvents: shouldShow ? 'auto' : 'none'\n })\n\n if (!shouldShow) {\n button.setAttribute('aria-hidden', 'true')\n button.setAttribute('tabindex', '-1')\n } else {\n button.removeAttribute('aria-hidden')\n button.setAttribute('tabindex', '0')\n }\n\n if (!shouldShow) {\n setTimeout(() => {\n if (button.style.opacity === '0') {\n button.style.visibility = 'hidden'\n }\n }, 300)\n } else {\n button.style.visibility = 'visible'\n }\n}\n\n/**\n * Update active state on thumbs\n */\nexport const updateActiveThumb = (\n thumbs: HTMLElement[] | undefined,\n currentIndex: number,\n activeClass: string = 'active'\n): void => {\n if (!thumbs?.length) return\n\n thumbs.forEach((thumb, index) => {\n const isActive = index === currentIndex\n thumb.classList.toggle(activeClass, isActive)\n thumb.setAttribute('aria-selected', isActive.toString())\n })\n}\n\n/**\n * Keyboard navigation\n */\nexport const setupKeyboardNavigation = (\n feed: HTMLElement,\n onPrev: () => void,\n onNext: () => void,\n abortSignal: AbortSignal,\n direction: SliderDirection = 'horizontal'\n): void => {\n const isVertical = direction === 'vertical'\n const prevKey = isVertical ? 'ArrowUp' : 'ArrowLeft'\n const nextKey = isVertical ? 'ArrowDown' : 'ArrowRight'\n\n feed.addEventListener(\n 'keydown',\n (event: KeyboardEvent) => {\n switch (event.key) {\n case prevKey:\n event.preventDefault()\n onPrev()\n break\n case nextKey:\n event.preventDefault()\n onNext()\n break\n }\n },\n { signal: abortSignal }\n )\n\n if (!feed.hasAttribute('tabindex')) {\n feed.setAttribute('tabindex', '0')\n }\n}\n","import type { DragState, EasingFunction, SliderDirection } from './types.js'\nimport { easeOutCubic } from './easing.js'\n\n/**\n * Configuration for drag behavior\n */\ninterface DragConfig {\n /** Feed element to enable dragging on */\n feed: HTMLElement\n /** Slide elements for snap-to-slide calculation */\n slides: HTMLElement[]\n /** AbortSignal for cleanup */\n abortSignal: AbortSignal\n /** Callback to smooth scroll to a position */\n smoothScrollTo: (target: number, easing?: EasingFunction) => void\n /** Callback when drag ends (for updating state) */\n onDragEnd?: () => void\n /** Direction of the slider (horizontal or vertical) */\n direction?: SliderDirection\n}\n\nexport const createDragState = (): DragState => ({\n isDragging: false,\n startX: 0,\n startY: 0,\n startScrollLeft: 0,\n startScrollTop: 0,\n velocity: 0,\n lastX: 0,\n lastY: 0,\n lastTime: 0,\n momentumId: null\n})\n\nconst findNearestSlide = (\n feed: HTMLElement,\n slides: HTMLElement[],\n direction: SliderDirection = 'horizontal'\n): HTMLElement | null => {\n const feedRect = feed.getBoundingClientRect()\n const isVertical = direction === 'vertical'\n\n const feedCenter = isVertical\n ? feedRect.top + feedRect.height / 2\n : feedRect.left + feedRect.width / 2\n\n let nearestSlide: HTMLElement | null = null\n let minDistance = Infinity\n\n for (const slide of slides) {\n if (slide.offsetParent === null) continue\n\n const slideRect = slide.getBoundingClientRect()\n const slideCenter = isVertical\n ? slideRect.top + slideRect.height / 2\n : slideRect.left + slideRect.width / 2\n const distance = Math.abs(feedCenter - slideCenter)\n\n if (distance < minDistance) {\n minDistance = distance\n nearestSlide = slide\n }\n }\n\n return nearestSlide\n}\n\nconst applyMomentum = (\n state: DragState,\n feed: HTMLElement,\n slides: HTMLElement[],\n smoothScrollTo: (target: number, easing?: EasingFunction) => void,\n onDragEnd?: () => void,\n direction: SliderDirection = 'horizontal'\n): void => {\n const friction = 0.95\n const minVelocity = 0.5\n const isVertical = direction === 'vertical'\n\n const animate = () => {\n if (Math.abs(state.velocity) < minVelocity) {\n state.momentumId = null\n\n const nearestSlide = findNearestSlide(feed, slides, direction)\n if (nearestSlide) {\n const targetPosition = isVertical ? nearestSlide.offsetTop : nearestSlide.offsetLeft\n smoothScrollTo(targetPosition, easeOutCubic)\n }\n\n onDragEnd?.()\n return\n }\n\n if (isVertical) {\n feed.scrollTop += state.velocity\n } else {\n feed.scrollLeft += state.velocity\n }\n state.velocity *= friction\n\n state.momentumId = requestAnimationFrame(animate)\n }\n\n state.momentumId = requestAnimationFrame(animate)\n}\n\nconst getEventX = (event: MouseEvent | TouchEvent): number => {\n if ('touches' in event) {\n return event.touches[0]?.clientX ?? 0\n }\n return event.clientX\n}\n\nconst getEventY = (event: MouseEvent | TouchEvent): number => {\n if ('touches' in event) {\n return event.touches[0]?.clientY ?? 0\n }\n return event.clientY\n}\n\nexport const setupDragToScroll = (config: DragConfig): DragState => {\n const { feed, slides, abortSignal, smoothScrollTo, onDragEnd, direction = 'horizontal' } = config\n const state = createDragState()\n const isVertical = direction === 'vertical'\n\n const handleDragStart = (event: MouseEvent | TouchEvent) => {\n if (state.momentumId !== null) {\n cancelAnimationFrame(state.momentumId)\n state.momentumId = null\n }\n\n state.isDragging = true\n state.startX = getEventX(event)\n state.startY = getEventY(event)\n state.startScrollLeft = feed.scrollLeft\n state.startScrollTop = feed.scrollTop\n state.velocity = 0\n state.lastX = state.startX\n state.lastY = state.startY\n state.lastTime = performance.now()\n\n feed.style.userSelect = 'none'\n\n if (event.type === 'mousedown') {\n event.preventDefault()\n }\n }\n\n const handleDragMove = (event: MouseEvent | TouchEvent) => {\n if (!state.isDragging) return\n\n const currentX = getEventX(event)\n const currentY = getEventY(event)\n const currentTime = performance.now()\n const deltaTime = currentTime - state.lastTime\n\n if (isVertical) {\n const deltaY = state.startY - currentY\n feed.scrollTop = state.startScrollTop + deltaY\n\n if (deltaTime > 0) {\n state.velocity = (state.lastY - currentY) / deltaTime * 16\n }\n state.lastY = currentY\n } else {\n const deltaX = state.startX - currentX\n feed.scrollLeft = state.startScrollLeft + deltaX\n\n if (deltaTime > 0) {\n state.velocity = (state.lastX - currentX) / deltaTime * 16\n }\n state.lastX = currentX\n }\n\n state.lastTime = currentTime\n\n if (event.type === 'touchmove') {\n event.preventDefault()\n }\n }\n\n const handleDragEnd = () => {\n if (!state.isDragging) return\n\n state.isDragging = false\n\n feed.style.userSelect = ''\n\n if (Math.abs(state.velocity) > 1) {\n applyMomentum(state, feed, slides, smoothScrollTo, onDragEnd, direction)\n } else {\n const nearestSlide = findNearestSlide(feed, slides, direction)\n if (nearestSlide) {\n const targetPosition = isVertical ? nearestSlide.offsetTop : nearestSlide.offsetLeft\n smoothScrollTo(targetPosition, easeOutCubic)\n }\n onDragEnd?.()\n }\n }\n\n feed.addEventListener('mousedown', handleDragStart, { signal: abortSignal })\n document.addEventListener('mousemove', handleDragMove, { signal: abortSignal })\n document.addEventListener('mouseup', handleDragEnd, { signal: abortSignal })\n\n feed.addEventListener('touchstart', handleDragStart, {\n passive: true,\n signal: abortSignal\n })\n feed.addEventListener('touchmove', handleDragMove, {\n passive: false,\n signal: abortSignal\n })\n feed.addEventListener('touchend', handleDragEnd, { signal: abortSignal })\n\n document.addEventListener('mouseleave', handleDragEnd, { signal: abortSignal })\n\n return state\n}\n\nexport const cleanupDrag = (state: DragState): void => {\n if (state.momentumId !== null) {\n cancelAnimationFrame(state.momentumId)\n state.momentumId = null\n }\n}\n","export interface GenerateBulletsParams {\n bulletsContainer: HTMLElement\n slides: HTMLElement[]\n bulletClass: string\n bulletActiveClass: string\n feedId: string\n}\n\nexport const generateBullets = ({\n bulletsContainer,\n slides,\n bulletClass,\n bulletActiveClass,\n feedId,\n}: GenerateBulletsParams): HTMLElement[] => {\n if (!bulletsContainer || !(bulletsContainer instanceof HTMLElement)) {\n throw new Error('Invalid bulletsContainer: must be a valid HTMLElement')\n }\n\n if (!Array.isArray(slides) || slides.length === 0) {\n throw new Error('Invalid slides: must be a non-empty array')\n }\n\n if (!feedId || typeof feedId !== 'string') {\n throw new Error('Invalid feedId: must be a non-empty string')\n }\n\n if (!bulletClass || typeof bulletClass !== 'string') {\n throw new Error('Invalid bulletClass: must be a non-empty string')\n }\n\n bulletsContainer.innerHTML = ''\n bulletsContainer.setAttribute('role', 'tablist')\n bulletsContainer.setAttribute('aria-label', 'Slide navigation')\n\n const visibleSlides = slides\n .map((slide, originalIndex) => ({ slide, originalIndex }))\n .filter(({ slide }) => slide.offsetParent !== null)\n\n if (visibleSlides.length === 0) {\n console.warn('No visible slides found')\n return []\n }\n\n const bullets = visibleSlides.map(({ slide, originalIndex }, visibleIndex) => {\n const bullet = document.createElement('button')\n bullet.type = 'button'\n\n bullet.classList.add(bulletClass)\n if (visibleIndex === 0) {\n bullet.classList.add(bulletActiveClass)\n }\n\n bullet.setAttribute('role', 'tab')\n bullet.setAttribute('aria-selected', visibleIndex === 0 ? 'true' : 'false')\n bullet.setAttribute('aria-controls', feedId)\n bullet.setAttribute('aria-label', `Go to slide ${visibleIndex + 1}`)\n bullet.setAttribute('data-slide-index', String(visibleIndex))\n\n bulletsContainer.appendChild(bullet)\n\n return bullet\n })\n\n return bullets\n}\n\nexport const updateActiveBullet = (\n bullets: HTMLElement[],\n activeIndex: number,\n bulletActiveClass: string,\n): void => {\n if (!Array.isArray(bullets) || activeIndex < 0 || activeIndex >= bullets.length) {\n console.warn('Invalid activeIndex or bullets array')\n return\n }\n\n bullets.forEach((bullet, index) => {\n const isActive = index === activeIndex\n bullet.classList.toggle(bulletActiveClass, isActive)\n bullet.setAttribute('aria-selected', isActive ? 'true' : 'false')\n })\n}","export interface GenerateThumbsParams {\n thumbsContainer: HTMLElement\n slides: HTMLElement[]\n thumbClass: string\n thumbActiveClass: string\n feedId: string\n thumbImageSelector?: string\n thumbSize?: { width: number; height: number }\n}\n\nexport const generateThumbs = ({\n thumbsContainer,\n slides,\n thumbClass,\n thumbActiveClass,\n feedId,\n thumbImageSelector = 'img',\n thumbSize\n}: GenerateThumbsParams): HTMLElement[] => {\n if (!thumbsContainer || !(thumbsContainer instanceof HTMLElement)) {\n throw new Error('Invalid thumbsContainer: must be a valid HTMLElement')\n }\n\n if (!Array.isArray(slides) || slides.length === 0) {\n throw new Error('Invalid slides: must be a non-empty array')\n }\n\n if (!feedId || typeof feedId !== 'string') {\n throw new Error('Invalid feedId: must be a non-empty string')\n }\n\n if (!thumbClass || typeof thumbClass !== 'string') {\n throw new Error('Invalid thumbClass: must be a non-empty string')\n }\n\n thumbsContainer.innerHTML = ''\n thumbsContainer.setAttribute('role', 'tablist')\n thumbsContainer.setAttribute('aria-label', 'Slide thumbnails')\n\n const visibleSlides = slides\n .map((slide, originalIndex) => ({ slide, originalIndex }))\n .filter(({ slide }) => slide.offsetParent !== null)\n\n if (visibleSlides.length === 0) {\n console.warn('No visible slides found')\n return []\n }\n\n const thumbs = visibleSlides.map(({ slide, originalIndex }, visibleIndex) => {\n const thumb = document.createElement('button')\n thumb.type = 'button'\n\n thumb.classList.add(thumbClass)\n if (visibleIndex === 0) {\n thumb.classList.add(thumbActiveClass)\n }\n\n // Extract image from slide\n const sourceImage = slide.querySelector(thumbImageSelector) as HTMLImageElement | null\n if (sourceImage?.src) {\n const thumbImg = document.createElement('img')\n thumbImg.src = sourceImage.src\n thumbImg.alt = sourceImage.alt || `Slide ${visibleIndex + 1} thumbnail`\n thumbImg.draggable = false\n\n if (thumbSize) {\n thumbImg.style.width = `${thumbSize.width}px`\n thumbImg.style.height = `${thumbSize.height}px`\n thumbImg.style.objectFit = 'cover'\n }\n\n thumb.appendChild(thumbImg)\n }\n\n // Accessibility attributes\n thumb.setAttribute('role', 'tab')\n thumb.setAttribute('aria-selected', visibleIndex === 0 ? 'true' : 'false')\n thumb.setAttribute('aria-controls', feedId)\n thumb.setAttribute('aria-label', `Go to slide ${visibleIndex + 1}`)\n thumb.setAttribute('data-slide-index', String(visibleIndex))\n\n thumbsContainer.appendChild(thumb)\n\n return thumb\n })\n\n return thumbs\n}\n\nexport const updateActiveThumbnail = (\n thumbs: HTMLElement[],\n activeIndex: number,\n thumbActiveClass: string\n): void => {\n if (!Array.isArray(thumbs) || activeIndex < 0 || activeIndex >= thumbs.length) {\n console.warn('Invalid activeIndex or thumbs array')\n return\n }\n\n thumbs.forEach((thumb, index) => {\n const isActive = index === activeIndex\n thumb.classList.toggle(thumbActiveClass, isActive)\n thumb.setAttribute('aria-selected', isActive ? 'true' : 'false')\n })\n}\n\n","import type { SliderSettings, SliderState } from './types.js'\n\n/**\n * Marquee state - tracks cloned slides for marquee mode\n */\nexport interface MarqueeState {\n initialized: boolean\n clonedSlides: HTMLElement[]\n styleElement: HTMLStyleElement | null\n}\n\n/**\n * Create initial marquee state\n */\nexport const createMarqueeState = (): MarqueeState => ({\n initialized: false,\n clonedSlides: [],\n styleElement: null\n})\n\n/**\n * Inject CSS keyframes for smooth marquee animation\n */\nconst injectMarqueeKeyframes = (): HTMLStyleElement => {\n // Check if keyframes already exist\n const existingStyle = document.getElementById('lazer-marquee-keyframes')\n if (existingStyle) {\n return existingStyle as HTMLStyleElement\n }\n\n const style = document.createElement('style')\n style.id = 'lazer-marquee-keyframes'\n style.textContent = `\n @keyframes lazer-marquee-scroll {\n 0% {\n transform: translateX(0);\n }\n 100% {\n transform: translateX(-50%);\n }\n }\n `\n document.head.appendChild(style)\n return style\n}\n\n/**\n * Clone all slides and append for seamless marquee looping\n */\nexport const setupMarqueeClones = (\n settings: SliderSettings,\n marqueeState: MarqueeState\n): void => {\n if (marqueeState.initialized) return\n\n // Inject CSS keyframes\n marqueeState.styleElement = injectMarqueeKeyframes()\n\n // Ensure feed has proper CSS for transform animation\n // Note: Parent container should have overflow: hidden for marquee effect\n settings.feed.style.display = 'flex'\n settings.feed.style.willChange = 'transform'\n\n // Clone all original slides and append to create seamless loop\n settings.slides.forEach((slide) => {\n const clone = slide.cloneNode(true) as HTMLElement\n clone.setAttribute('data-lazer-marquee-clone', 'true')\n clone.setAttribute('aria-hidden', 'true')\n settings.feed.appendChild(clone)\n marqueeState.clonedSlides.push(clone)\n })\n\n marqueeState.initialized = true\n}\n\n/**\n * Remove marquee cloned slides from the DOM\n */\nexport const cleanupMarqueeClones = (marqueeState: MarqueeState): void => {\n if (!marqueeState.initialized) return\n\n marqueeState.clonedSlides.forEach((clone) => {\n clone.remove()\n })\n\n marqueeState.clonedSlides = []\n marqueeState.initialized = false\n}\n\n/**\n * Setup marquee CSS animation for smooth hardware-accelerated scrolling\n */\nconst setupMarqueeCss = (\n settings: SliderSettings,\n state: SliderState\n): void => {\n // Ensure keyframes exist first\n injectMarqueeKeyframes()\n\n // Wait a frame to ensure keyframes are parsed and layout is complete\n requestAnimationFrame(() => {\n const scrollWidth = settings.feed.scrollWidth\n const speed = settings.marqueeSpeed ?? 50 // pixels per second\n const direction = settings.marqueeDirection ?? 'left'\n\n // Distance is half the scroll width (the original content width)\n const distance = scrollWidth / 2\n\n // Validate values\n if (distance <= 0 || speed <= 0) {\n console.warn('[lazer-slider] Invalid marquee values:', { distance, speed, scrollWidth })\n return\n }\n\n // Calculate duration: distance / speed (how long to scroll through original content)\n const duration = distance / speed\n const animationDirection = direction === 'right' ? 'reverse' : 'normal'\n\n // Apply animation - use percentage-based keyframes for seamless loop\n const animationValue = `lazer-marquee-scroll ${duration}s linear infinite ${animationDirection}`\n\n // Remove any existing animation first\n settings.feed.style.animation = 'none'\n\n // Force reflow to reset animation\n void settings.feed.offsetWidth\n\n // Apply new animation\n settings.feed.style.animation = animationValue\n settings.feed.style.animationPlayState = state.marqueePaused ? 'paused' : 'running'\n })\n}\n\n/**\n * Start marquee animation using smooth CSS animations\n */\nexport const startMarquee = (\n settings: SliderSettings,\n state: SliderState\n): void => {\n // Setup CSS animation for smooth hardware-accelerated scrolling\n setupMarqueeCss(settings, state)\n}\n\n/**\n * Stop marquee animation\n */\nexport const stopMarquee = (state: SliderState, settings: SliderSettings): void => {\n // Remove animation\n settings.feed.style.animation = ''\n settings.feed.style.animationPlayState = ''\n\n // Reset transform\n settings.feed.style.transform = ''\n settings.feed.style.willChange = ''\n}\n\n/**\n * Pause marquee animation (temporary, resumes on mouse leave)\n */\nexport const pauseMarquee = (state: SliderState, settings: SliderSettings): void => {\n state.marqueePaused = true\n settings.feed.style.animationPlayState = 'paused'\n}\n\n/**\n * Resume marquee animation after pause\n */\nexport const resumeMarquee = (state: SliderState, settings: SliderSettings): void => {\n state.marqueePaused = false\n settings.feed.style.animationPlayState = 'running'\n}\n\n/**\n * Setup marquee mode (clones + animation)\n */\nexport const setupMarquee = (\n settings: SliderSettings,\n state: SliderState,\n marqueeState: MarqueeState\n): void => {\n if (!settings.marquee) return\n\n setupMarqueeClones(settings, marqueeState)\n startMarquee(settings, state)\n}\n\n/**\n * Attach marquee pause-on-hover event listeners\n */\nexport const attachMarqueeEventListeners = (\n settings: SliderSettings,\n state: SliderState,\n signal: AbortSignal\n): void => {\n if (!settings.marquee || settings.pauseOnHover === false) return\n\n settings.feed.addEventListener(\n 'mouseenter',\n () => pauseMarquee(state, settings),\n { signal }\n )\n settings.feed.addEventListener(\n 'mouseleave',\n () => resumeMarquee(state, settings),\n { signal }\n )\n settings.feed.addEventListener(\n 'touchstart',\n () => pauseMarquee(state, settings),\n { passive: true, signal }\n )\n settings.feed.addEventListener(\n 'touchend',\n () => resumeMarquee(state, settings),\n { signal }\n )\n}\n","/**\n * Critical CSS styles that are auto-injected for zero-config usage\n * Users can override these by using more specific selectors or !important\n */\nconst CRITICAL_STYLES = `\n/* Lazer Slider - Critical Styles (Auto-injected) */\n.lazer-feed {\n position: relative;\n display: flex;\n overflow-x: auto;\n overflow-y: hidden;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: none;\n scroll-snap-type: x mandatory;\n}\n\n.lazer-feed::-webkit-scrollbar {\n display: none;\n}\n\n.lazer-feed.lazer-vertical {\n flex-direction: column;\n overflow-x: hidden;\n overflow-y: auto;\n scroll-snap-type: y mandatory;\n}\n\n.lazer-slide {\n scroll-snap-align: start;\n flex-shrink: 0;\n}\n\n.lazer-feed.is-dragging {\n cursor: grabbing;\n user-select: none;\n scroll-snap-type: none;\n}\n\n.lazer-feed:not(.is-dragging) {\n cursor: grab;\n}\n`\n\nlet stylesInjected = false\nconst STYLE_ID = 'lazer-slider-critical-styles'\n\n/**\n * Injects critical CSS styles into the document head.\n * Safe to call multiple times - will only inject once.\n *\n * @example\n * ```typescript\n * import { injectStyles } from 'lazer-slider'\n *\n * // Manually inject styles (useful for SSR or early loading)\n * injectStyles()\n * ```\n */\nexport const injectStyles = (): void => {\n if (stylesInjected || typeof document === 'undefined') return\n\n const existingStyle = document.getElementById(STYLE_ID)\n if (existingStyle) {\n stylesInjected = true\n return\n }\n\n const style = document.createElement('style')\n style.id = STYLE_ID\n style.textContent = CRITICAL_STYLES\n document.head.appendChild(style)\n stylesInjected = true\n}\n\n/**\n * Internal function called by createSlider to ensure styles are injected\n * @internal\n */\nexport const injectStylesOnce = (): void => {\n injectStyles()\n}\n\n/**\n * Removes the injected styles from the document.\n * Useful for cleanup in testing or when completely removing the slider.\n *\n * @example\n * ```typescript\n * import { removeStyles } from 'lazer-slider'\n *\n * // Remove injected styles\n * removeStyles()\n * ```\n */\nexport const removeStyles = (): void => {\n if (typeof document === 'undefined') return\n\n const style = document.getElementById(STYLE_ID)\n if (style) {\n style.remove()\n stylesInjected = false\n }\n}\n\n","import type {\n SliderSettings,\n SliderState,\n SliderNavDirection,\n EasingFunction,\n Slider,\n DragState\n} from './types.js'\nimport { easeOutExpo } from './easing.js'\nimport {\n initAria,\n toggleControlVisibility,\n updateActiveThumb,\n setupKeyboardNavigation\n} from './accessibility.js'\nimport { setupDragToScroll, cleanupDrag } from './drag.js'\nimport { generateBullets } from './bullets.js'\nimport { generateThumbs } from './thumbs.js'\nimport {\n createMarqueeState,\n setupMarquee,\n startMarquee,\n stopMarquee,\n pauseMarquee,\n resumeMarquee,\n cleanupMarqueeClones,\n attachMarqueeEventListeners\n} from './marquee.js'\nimport { injectStylesOnce } from './styles.js'\n\nconst ANIMATION = {\n MIN_DURATION: 400,\n MAX_DURATION: 1000,\n SPEED_FACTOR: 1.5,\n SCROLL_END_DELAY: 50,\n THUMB_UPDATE_DELAY: 500\n} as const\n\nconst DESKTOP_BREAKPOINT = '(min-width: 64rem)'\n\nexport const createSlider = (settings: SliderSettings): Slider => {\n // Auto-inject critical CSS styles for zero-config usage\n injectStylesOnce()\n\n if (!settings.feed) {\n throw new Error('lazer-slider: feed element is required')\n }\n\n if (!settings.slides?.length) {\n throw new Error('lazer-slider: slides array is required and must not be empty')\n }\n\n if (!settings.feed.id) {\n settings.feed.id = `lazer-slider-feed-${Math.random().toString(36).substr(2, 9)}`\n }\n\n // Add classes for CSS targeting (if not already present)\n settings.feed.classList.add('lazer-feed')\n settings.slides.forEach((slide) => {\n slide.classList.add('lazer-slide')\n })\n\n if (settings.bulletsContainer && !settings.thumbs) {\n const bullets = generateBullets({\n bulletsContainer: settings.bulletsContainer,\n slides: settings.slides,\n bulletClass: settings.bulletsClass ?? 'lazer-bullet',\n bulletActiveClass: settings.bulletsActiveClass ?? 'active',\n feedId: settings.feed.id\n })\n settings.thumbs = bullets\n }\n\n if (settings.thumbsContainer && !settings.thumbs) {\n const thumbs = generateThumbs({\n thumbsContainer: settings.thumbsContainer,\n slides: settings.slides,\n thumbClass: settings.thumbsClass ?? 'lazer-thumb',\n thumbActiveClass: settings.thumbsActiveClass ?? 'active',\n feedId: settings.feed.id,\n thumbImageSelector: settings.thumbImageSelector ?? 'img',\n thumbSize: settings.thumbSize\n })\n settings.thumbs = thumbs\n }\n\n const direction = settings.direction ?? 'horizontal'\n const isVertical = direction === 'vertical'\n\n // Add vertical class for CSS targeting\n if (isVertical) {\n settings.feed.classList.add('lazer-vertical')\n }\n\n // Add marquee class if enabled\n if (settings.marquee) {\n settings.feed.classList.add('lazer-marquee')\n }\n\n const state: SliderState = {\n currentSlideIndex: 0,\n isScrolling: false,\n ticking: false,\n cachedFeedRect: null,\n lastWidth: 0,\n updateThumbTimeout: null,\n scrollEndTimeout: null,\n abortController: new AbortController(),\n autoplayIntervalId: null,\n autoplayPaused: false,\n marqueeAnimationId: null,\n marqueePaused: false,\n marqueeLastTimestamp: 0,\n isLoopRepositioning: false\n }\n\n let dragState: DragState | null = null\n\n const loopState = {\n initialized: false,\n clonedSlides: [] as HTMLElement[],\n realSlides: [...settings.slides] as HTMLElement[],\n clonesPerSide: 0\n }\n\n const marqueeState = createMarqueeState()\n\n const easing = settings.easing ?? easeOutExpo\n\n const getFeedRect = (): DOMRect => {\n const currentSize = isVertical ? settings.feed.clientHeight : settings.feed.clientWidth\n if (!state.cachedFeedRect || state.lastWidth !== currentSize) {\n state.cachedFeedRect = settings.feed.getBoundingClientRect()\n state.lastWidth = currentSize\n }\n return state.cachedFeedRect\n }\n\n const getVisibleSlides = (): HTMLElement[] => {\n return settings.slides.filter((slide) => slide.offsetParent !== null)\n }\n\n const isDesktop = (): boolean => {\n return window.matchMedia(DESKTOP_BREAKPOINT).matches\n }\n\n const getLoopClonesCount = (): number => {\n const perView = isDesktop()\n ? settings.desktopSlidesPerView\n : settings.mobileSlidesPerView\n\n if (!perView || perView === 'auto') {\n return 1\n }\n return Math.ceil(perView)\n }\n\n const setupLoopClones = (): void => {\n if (!settings.loop || loopState.initialized) return\n\n const realSlides = loopState.realSlides\n const clonesCount = getLoopClonesCount()\n loopState.clonesPerSide = clonesCount\n\n for (let i = realSlides.length - clonesCount; i < realSlides.length; i++) {\n const slide = realSlides[i]\n if (!slide) continue\n\n const clone = slide.cloneNode(true) as HTMLElement\n clone.setAttribute('data-lazer-clone', 'prepend')\n clone.setAttribute('aria-hidden', 'true')\n settings.feed.insertBefore(clone, settings.feed.firstChild)\n loopState.clonedSlides.push(clone)\n }\n\n for (let i = 0; i < clonesCount; i++) {\n const slide = realSlides[i]\n if (!slide) continue\n\n const clone = slide.cloneNode(true) as HTMLElement\n clone.setAttribute('data-lazer-clone', 'append')\n clone.setAttribute('aria-hidden', 'true')\n settings.feed.appendChild(clone)\n loopState.clonedSlides.push(clone)\n }\n\n requestAnimationFrame(() => {\n const firstRealSlide = realSlides[0]\n if (firstRealSlide) {\n if (isVertical) {\n settings.feed.scrollTop = firstRealSlide.offsetTop\n } else {\n settings.feed.scrollLeft = firstRealSlide.offsetLeft\n }\n }\n })\n\n loopState.initialized = true\n }\n\n const handleLoopReposition = (navDirection: SliderNavDirection): void => {\n if (!settings.loop || !loopState.initialized) return\n\n state.isLoopRepositioning = true\n\n const realSlides = loopState.realSlides\n const totalRealSlides = realSlides.length\n\n if (navDirection === 'next') {\n const firstRealSlide = realSlides[0]\n if (firstRealSlide) {\n if (isVertical) {\n settings.feed.scrollTop = firstRealSlide.offsetTop\n } else {\n settings.feed.scrollLeft = firstRealSlide.offsetLeft\n }\n }\n state.currentSlideIndex = 0\n } else {\n const lastRealSlide = realSlides[totalRealSlides - 1]\n if (lastRealSlide) {\n if (isVertical) {\n settings.feed.scrollTop = lastRealSlide.offsetTop\n } else {\n settings.feed.scrollLeft = lastRealSlide.offsetLeft\n }\n }\n state.currentSlideIndex = totalRealSlides - 1\n }\n\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n state.isLoopRepositioning = false\n updateControlsVisibility()\n })\n })\n }\n\n const cleanupLoopClones = (): void => {\n if (!loopState.initialized) return\n\n loopState.clonedSlides.forEach((clone) => {\n clone.remove()\n })\n\n loopState.clonedSlides = []\n loopState.initialized = false\n loopState.clonesPerSide = 0\n }\n\n const applySlideWidths = (): void => {\n const perView = isDesktop()\n ? settings.desktopSlidesPerView\n : settings.mobileSlidesPerView\n\n const gap = settings.slideGap ?? 0\n\n if (gap > 0) {\n settings.feed.style.gap = `${gap}px`\n }\n\n if (!perView || perView === 'auto') {\n settings.slides.forEach((slide) => {\n slide.style.flex = ''\n slide.style.minWidth = ''\n slide.style.minHeight = ''\n })\n return\n }\n\n const totalGapSize = gap * (perView - 1)\n const slideSize = `calc((100% - ${totalGapSize}px) / ${perView})`\n\n if (isVertical) {\n settings.slides.forEach((slide) => {\n slide.style.flex = `0 0 ${slideSize}`\n slide.style.minHeight = slideSize\n slide.style.minWidth = ''\n })\n } else {\n settings.slides.forEach((slide) => {\n slide.style.flex = `0 0 ${slideSize}`\n slide.style.minWidth = slideSize\n slide.style.minHeight = ''\n })\n }\n }\n\n const updateScrollbar = (): void => {\n if (!settings.scrollbarThumb) return\n\n const feedRect = getFeedRect()\n\n if (isVertical) {\n const thumbHeight = (feedRect.height / settings.feed.scrollHeight) * 100\n settings.scrollbarThumb.style.height = `${thumbHeight}%`\n settings.scrollbarThumb.style.width = ''\n } else {\n const thumbWidth = (feedRect.width / settings.feed.scrollWidth) * 100\n settings.scrollbarThumb.style.width = `${thumbWidth}%`\n settings.scrollbarThumb.style.height = ''\n }\n }\n\n const updateScrollbarPosition = (): void => {\n if (!settings.scrollbarThumb || !settings.scrollbarTrack) return\n\n if (isVertical) {\n const trackHeight = settings.scrollbarTrack.getBoundingClientRect().height\n const thumbHeight = settings.scrollbarThumb.getBoundingClientRect().height\n const totalTransform = trackHeight - thumbHeight\n\n const maxScroll = settings.feed.scrollHeight - settings.feed.clientHeight\n const scrollProgress = maxScroll > 0 ? settings.feed.scrollTop / maxScroll : 0\n\n settings.scrollbarThumb.style.transform = `translateY(${totalTransform * scrollProgress}px)`\n } else {\n const trackWidth = settings.scrollbarTrack.getBoundingClientRect().width\n const thumbWidth = settings.scrollbarThumb.getBoundingClientRect().width\n const totalTransform = trackWidth - thumbWidth\n\n const maxScroll = settings.feed.scrollWidth - settings.feed.clientWidth\n const scrollProgress = maxScroll > 0 ? settings.feed.scrollLeft / maxScroll : 0\n\n settings.scrollbarThumb.style.transform = `translateX(${totalTransform * scrollProgress}px)`\n }\n }\n\n const updateControlsVisibility = (): void => {\n // Skip visibility updates during loop repositioning to prevent flicker\n if (state.isLoopRepositioning) {\n return\n }\n\n const feedRect = getFeedRect()\n\n let isAtStart: boolean\n let isAtEnd: boolean\n let shouldHideScrollbar: boolean\n\n if (isVertical) {\n isAtStart = settings.feed.scrollTop <= 1\n isAtEnd = settings.feed.scrollTop + feedRect.height >= settings.feed.scrollHeight - 1\n shouldHideScrollbar = settings.feed.scrollHeight <= feedRect.height\n } else {\n isAtStart = settings.feed.scrollLeft <= 1\n isAtEnd = settings.feed.scrollLeft + feedRect.width >= settings.feed.scrollWidth - 1\n shouldHideScrollbar = settings.feed.scrollWidth <= feedRect.width\n }\n\n if (settings.scrollbarTrack) {\n settings.scrollbarTrack.style.display = shouldHideScrollbar ? 'none' : 'block'\n }\n\n if (settings.loop) {\n toggleControlVisibility(\n settings.prevSlideButton,\n !shouldHideScrollbar,\n settings.feed\n )\n toggleControlVisibility(\n settings.nextSlideButton,\n !shouldHideScrollbar,\n settings.feed\n )\n return\n }\n\n toggleControlVisibility(\n settings.prevSlideButton,\n !isAtStart && !shouldHideScrollbar,\n settings.feed\n )\n toggleControlVisibility(\n settings.nextSlideButton,\n !isAtEnd && !shouldHideScrollbar,\n settings.feed\n )\n }\n\n const updateCurrentSlideIndex = (): void => {\n const feedRect = getFeedRect()\n\n const slidesToCheck = loopState.initialized\n ? loopState.realSlides\n : getVisibleSlides()\n\n const viewportVisibleSlides = slidesToCheck.filter((slide) => {\n const slideRect = slide.getBoundingClientRect()\n const tolerance = 20\n\n if (isVertical) {\n return (\n slideRect.bottom > feedRect.top + tolerance &&\n slideRect.top < feedRect.bottom - tolerance\n )\n }\n\n return (\n slideRect.right > feedRect.left + tolerance &&\n slideRect.left < feedRect.right - tolerance\n )\n })\n\n if (viewportVisibleSlides.length && viewportVisibleSlides[0]) {\n const newIndex = slidesToCheck.indexOf(viewportVisibleSlides[0])\n if (newIndex !== -1) {\n state.currentSlideIndex = newIndex\n const currentScroll = isVertical ? settings.feed.scrollTop : settings.feed.scrollLeft\n settings.onScroll?.({\n currentScroll,\n currentSlideIndex: state.currentSlideIndex\n })\n }\n }\n }\n\n const smoothScrollTo = (\n target: number,\n customEasing: EasingFunction = easing,\n onComplete?: () => void\n ): void => {\n const start = isVertical ? settings.feed.scrollTop : settings.feed.scrollLeft\n const distance = Math.abs(target - start)\n\n const duration = Math.min(\n ANIMATION.MAX_DURATION,\n Math.max(ANIMATION.MIN_DURATION, distance / ANIMATION.SPEED_FACTOR)\n )\n\n const startTime = performance.now()\n\n const animateScroll = (currentTime: number): void => {\n const elapsed = (currentTime - startTime) / duration\n const progress = Math.min(elapsed, 1)\n const ease = customEasing(progress)\n\n const scrollPosition = start + (target - start) * ease\n\n if (isVertical) {\n settings.feed.scrollTop = scrollPosition\n } else {\n settings.feed.scrollLeft = scrollPosition\n }\n\n if (progress < 1) {\n requestAnimationFrame(animateScroll)\n } else {\n if (isVertical) {\n settings.feed.scrollTop = target\n } else {\n settings.feed.scrollLeft = target\n }\n onComplete?.()\n }\n }\n\n requestAnimationFrame(animateScroll)\n }\n\n const handleThumbClick = (thumb: HTMLElement): void => {\n if (!settings.thumbs) return\n\n const index = settings.thumbs.indexOf(thumb)\n if (index === -1 || !settings.slides[index]) return\n\n state.currentSlideIndex = index\n updateActiveThumb(settings.thumbs, index)\n state.isScrolling = true\n\n if (state.updateThumbTimeout) {\n clearTimeout(state.updateThumbTimeout)\n }\n\n state.updateThumbTimeout = setTimeout(() => {\n state.isScrolling = false\n }, ANIMATION.THUMB_UPDATE_DELAY)\n\n const targetPosition = isVertical\n ? settings.slides[index].offsetTop\n : settings.slides[index].offsetLeft\n smoothScrollTo(targetPosition)\n }\n\n const handleNavButtonClick = (navDirection: SliderNavDirection): void => {\n const realSlides = loopState.initialized ? loopState.realSlides : getVisibleSlides()\n const slidesToScroll = isDesktop()\n ? settings.desktopSlidesPerScroll ?? 1\n : settings.mobileSlidesPerScroll ?? 1\n const totalRealSlides = realSlides.length\n\n updateCurrentSlideIndex()\n\n let targetSlide: HTMLElement | undefined\n let needsReposition = false\n\n if (navDirection === 'prev') {\n if (settings.loop && loopState.initialized && state.currentSlideIndex === 0) {\n\n const prependedClones = loopState.clonedSlides.filter(\n (clone) => clone.getAttribute('data-lazer-clone') === 'prepend'\n )\n targetSlide = prependedClones[prependedClones.length - 1]\n needsReposition = true\n } else {\n state.currentSlideIndex = Math.max(0, state.currentSlideIndex - slidesToScroll)\n targetSlide = realSlides[state.currentSlideIndex]\n }\n } else {\n if (settings.loop && loopState.initialized && state.currentSlideIndex >= totalRealSlides - 1) {\n const appendedClones = loopState.clonedSlides.filter(\n (clone) => clone.getAttribute('data-lazer-clone') === 'append'\n )\n targetSlide = appendedClones[0]\n needsReposition = true\n } else {\n state.currentSlideIndex = Math.min(\n totalRealSlides - 1,\n state.currentSlideIndex + slidesToScroll\n )\n targetSlide = realSlides[state.currentSlideIndex]\n }\n }\n\n if (!targetSlide) return\n\n const currentScroll = isVertical ? settings.feed.scrollTop : settings.feed.scrollLeft\n settings.onScrollStart?.({\n currentScroll,\n target: targetSlide,\n direction: navDirection\n })\n\n const targetPosition = isVertical ? targetSlide.offsetTop : targetSlide.offsetLeft\n\n if (needsReposition) {\n smoothScrollTo(targetPosition, easing, () => {\n handleLoopReposition(navDirection)\n })\n } else {\n smoothScrollTo(targetPosition)\n }\n }\n\n const updateScrollPosition = (): void => {\n updateScrollbarPosition()\n updateControlsVisibility()\n updateCurrentSlideIndex()\n\n if (!state.isScrolling) {\n updateActiveThumb(settings.thumbs, state.currentSlideIndex)\n }\n\n if (state.scrollEndTimeout) {\n clearTimeout(state.scrollEndTimeout)\n }\n\n state.scrollEndTimeout = setTimeout(() => {\n state.isScrolling = false\n const currentScroll = isVertical ? settings.feed.scrollTop : settings.feed.scrollLeft\n settings.onScrollEnd?.({\n currentScroll,\n currentSlideIndex: state.currentSlideIndex\n })\n }, ANIMATION.SCROLL_END_DELAY)\n }\n\n const handleFeedScroll = (): void => {\n if (!state.ticking) {\n requestAnimationFrame(() => {\n updateScrollPosition()\n state.ticking = false\n })\n state.ticking = true\n }\n }\n\n const handleWindowResize = (): void => {\n state.cachedFeedRect = null\n refresh()\n }\n\n const attachEventListeners = (): void => {\n const { signal } = state.abortController\n\n window.addEventListener('resize', handleWindowResize)\n\n settings.feed.addEventListener('scroll', handleFeedScroll, {\n passive: true,\n signal\n })\n\n if (settings.prevSlideButton) {\n settings.prevSlideButton.addEventListener(\n 'click',\n () => handleNavButtonClick('prev'),\n { signal }\n )\n }\n\n if (settings.nextSlideButton) {\n settings.nextSlideButton.addEventListener(\n 'click',\n () => handleNavButtonClick('next'),\n { signal }\n )\n }\n\n if (settings.thumbs?.length) {\n settings.thumbs[0]?.classList.add('active')\n settings.thumbs.forEach((thumb) => {\n thumb.addEventListener('click', () => handleThumbClick(thumb), { signal })\n })\n }\n\n setupKeyboardNavigation(\n settings.feed,\n () => handleNavButtonClick('prev'),\n () => handleNavButtonClick('next'),\n signal,\n direction\n )\n\n if (settings.enableDragToScroll !== false) {\n dragState = setupDragToScroll({\n feed: settings.feed,\n slides: settings.slides,\n abortSignal: signal,\n smoothScrollTo,\n onDragEnd: () => {\n updateCurrentSlideIndex()\n updateActiveThumb(settings.thumbs, state.currentSlideIndex)\n },\n direction\n })\n }\n\n if (settings.autoplay && settings.pauseOnHover !== false) {\n settings.feed.addEventListener(\n 'mouseenter',\n pauseAutoplay,\n { signal }\n )\n settings.feed.addEventListener(\n 'mouseleave',\n resumeAutoplay,\n { signal }\n )\n settings.feed.addEventListener(\n 'touchstart',\n pauseAutoplay,\n { passive: true, signal }\n )\n settings.feed.addEventListener(\n 'touchend',\n resumeAutoplay,\n { signal }\n )\n }\n\n attachMarqueeEventListeners(settings, state, signal)\n }\n\n const startAutoplay = (): void => {\n if (state.autoplayIntervalId) return;\n\n const interval = settings.autoplayInterval ?? 3000\n state.autoplayIntervalId = setInterval(() => {\n if (!state.autoplayPaused) {\n handleNavButtonClick('next')\n }\n }, interval)\n }\n\n const stopAutoplay = (): void => {\n if (state.autoplayIntervalId) {\n clearInterval(state.autoplayIntervalId)\n state.autoplayIntervalId = null\n }\n }\n\n const pauseAutoplay = (): void => {\n state.autoplayPaused = true\n }\n\n const resumeAutoplay = (): void => {\n state.autoplayPaused = false\n }\n\n const goToIndex = (index: number): void => {\n const slides = loopState.initialized ? loopState.realSlides : getVisibleSlides()\n const safeIndex = Math.max(0, Math.min(index, slides.length - 1))\n const targetSlide = slides[safeIndex]\n\n if (!targetSlide) return\n\n state.currentSlideIndex = safeIndex\n updateActiveThumb(settings.thumbs, safeIndex)\n const targetPosition = isVertical ? targetSlide.offsetTop : targetSlide.offsetLeft\n smoothScrollTo(targetPosition)\n }\n\n const refresh = (): void => {\n state.cachedFeedRect = null\n applySlideWidths()\n updateScrollbar()\n updateControlsVisibility()\n\n if (settings.marquee && !state.marqueePaused) {\n startMarquee(settings, state)\n }\n }\n\n const unload = (): void => {\n stopAutoplay()\n stopMarquee(state, settings)\n\n state.abortController.abort()\n window.removeEventListener('resize', handleWindowResize)\n\n if (state.updateThumbTimeout) {\n clearTimeout(state.updateThumbTimeout)\n }\n if (state.scrollEndTimeout) {\n clearTimeout(state.scrollEndTimeout)\n }\n\n if (dragState) {\n cleanupDrag(dragState)\n }\n\n cleanupLoopClones()\n cleanupMarqueeClones(marqueeState)\n\n state.cachedFeedRect = null\n }\n\n initAria(settings)\n applySlideWidths()\n\n if (settings.marquee) {\n setupMarquee(settings, state, marqueeState)\n } else {\n setupLoopClones()\n if (settings.autoplay) {\n startAutoplay()\n }\n }\n\n updateControlsVisibility()\n attachEventListeners()\n updateScrollbar()\n\n const play = (): void => {\n if (settings.marquee) {\n if (state.marqueePaused) {\n resumeMarquee(state, settings)\n } else {\n startMarquee(settings, state)\n }\n } else if (settings.autoplay) {\n startAutoplay()\n }\n }\n\n const pause = (): void => {\n if (settings.marquee) {\n pauseMarquee(state, settings)\n } else {\n stopAutoplay()\n }\n }\n\n return {\n goToIndex,\n refresh,\n unload,\n play,\n pause,\n next: () => handleNavButtonClick('next'),\n prev: () => handleNavButtonClick('prev')\n }\n}"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/core/easing.ts","../src/core/accessibility.ts","../src/core/drag.ts","../src/core/bullets.ts","../src/core/thumbs.ts","../src/core/marquee.ts","../src/core/styles.ts","../src/core/slider.ts"],"sourcesContent":["import type { EasingFunction } from './types.js'\n\n/**\n * Exponential ease-out - starts fast, decelerates smoothly\n * Best for scroll animations as it feels natural and responsive\n */\nexport const easeOutExpo: EasingFunction = (t) =>\n t === 1 ? 1 : 1 - Math.pow(2, -10 * t)\n\n/**\n * Cubic ease-out - smoother deceleration than exponential\n */\nexport const easeOutCubic: EasingFunction = (t) => 1 - Math.pow(1 - t, 3)\n\n/**\n * Cubic ease-in-out - smooth acceleration and deceleration\n */\nexport const easeInOutCubic: EasingFunction = (t) =>\n t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2\n\n/**\n * Quadratic ease-out - gentle deceleration\n */\nexport const easeOutQuad: EasingFunction = (t) => 1 - (1 - t) * (1 - t)\n\n/**\n * Linear - no easing, constant speed\n */\nexport const linear: EasingFunction = (t) => t\n","import type { SliderSettings, SliderDirection } from './types.js'\n\n/**\n * Generate a unique ID for the slider\n */\nexport const generateSliderId = (): string =>\n `slider-${Math.random().toString(36).substring(2, 9)}`\n\n/**\n * Initialize ARIA attributes\n */\nexport const initAria = (settings: SliderSettings): void => {\n const { feed, prevSlideButton, nextSlideButton, thumbs, slides } = settings\n\n if (!feed.id) {\n feed.id = generateSliderId()\n }\n\n feed.setAttribute('role', 'region')\n feed.setAttribute('aria-label', 'Carousel')\n feed.setAttribute('aria-roledescription', 'carousel')\n\n feed.removeAttribute('tabindex')\n\n slides.forEach((slide, index) => {\n slide.setAttribute('role', 'group')\n slide.setAttribute('aria-roledescription', 'slide')\n slide.setAttribute('aria-label', `Slide ${index + 1} of ${slides.length}`)\n })\n\n if (prevSlideButton) {\n prevSlideButton.setAttribute('aria-label', 'Previous slide')\n prevSlideButton.setAttribute('aria-controls', feed.id)\n prevSlideButton.setAttribute('tabindex', '0')\n if (prevSlideButton.tagName !== 'BUTTON') {\n prevSlideButton.setAttribute('role', 'button')\n }\n }\n\n if (nextSlideButton) {\n nextSlideButton.setAttribute('aria-label', 'Next slide')\n nextSlideButton.setAttribute('aria-controls', feed.id)\n nextSlideButton.setAttribute('tabindex', '0')\n if (nextSlideButton.tagName !== 'BUTTON') {\n nextSlideButton.setAttribute('role', 'button')\n }\n }\n\n if (thumbs?.length) {\n thumbs.forEach((thumb, index) => {\n if (thumb.tagName !== 'BUTTON') {\n thumb.setAttribute('role', 'button')\n }\n thumb.setAttribute('aria-label', `Go to slide ${index + 1}`)\n thumb.setAttribute('tabindex', '0')\n thumb.setAttribute('aria-controls', feed.id)\n })\n }\n}\n\n/**\n * Toggle visibility of navigation controls\n */\nexport const toggleControlVisibility = (\n button: HTMLElement | null | undefined,\n shouldShow: boolean,\n feedElement?: HTMLElement\n): void => {\n if (!button) return\n\n if (!shouldShow && button === document.activeElement && feedElement) {\n feedElement.focus()\n }\n\n const transition = 'opacity 0.3s ease'\n const opacity = shouldShow ? '1' : '0'\n\n Object.assign(button.style, {\n opacity,\n transition,\n pointerEvents: shouldShow ? 'auto' : 'none'\n })\n\n if (!shouldShow) {\n button.setAttribute('aria-hidden', 'true')\n button.setAttribute('tabindex', '-1')\n } else {\n button.removeAttribute('aria-hidden')\n button.setAttribute('tabindex', '0')\n }\n\n if (!shouldShow) {\n setTimeout(() => {\n if (button.style.opacity === '0') {\n button.style.visibility = 'hidden'\n }\n }, 300)\n } else {\n button.style.visibility = 'visible'\n }\n}\n\n/**\n * Update active state on thumbs\n */\nexport const updateActiveThumb = (\n thumbs: HTMLElement[] | undefined,\n currentIndex: number,\n activeClass: string = 'active'\n): void => {\n if (!thumbs?.length) return\n\n thumbs.forEach((thumb, index) => {\n const isActive = index === currentIndex\n thumb.classList.toggle(activeClass, isActive)\n thumb.setAttribute('aria-selected', isActive.toString())\n })\n}\n\n/**\n * Keyboard navigation\n */\nexport const setupKeyboardNavigation = (\n feed: HTMLElement,\n onPrev: () => void,\n onNext: () => void,\n abortSignal: AbortSignal,\n direction: SliderDirection = 'horizontal'\n): void => {\n const isVertical = direction === 'vertical'\n const prevKey = isVertical ? 'ArrowUp' : 'ArrowLeft'\n const nextKey = isVertical ? 'ArrowDown' : 'ArrowRight'\n\n feed.addEventListener(\n 'keydown',\n (event: KeyboardEvent) => {\n switch (event.key) {\n case prevKey:\n event.preventDefault()\n onPrev()\n break\n case nextKey:\n event.preventDefault()\n onNext()\n break\n }\n },\n { signal: abortSignal }\n )\n\n if (!feed.hasAttribute('tabindex')) {\n feed.setAttribute('tabindex', '0')\n }\n}\n","import type { DragState, EasingFunction, SliderDirection } from './types.js'\nimport { easeOutCubic } from './easing.js'\n\n/**\n * Configuration for drag behavior\n */\ninterface DragConfig {\n /** Feed element to enable dragging on */\n feed: HTMLElement\n /** Slide elements for snap-to-slide calculation */\n slides: HTMLElement[]\n /** AbortSignal for cleanup */\n abortSignal: AbortSignal\n /** Callback to smooth scroll to a position */\n smoothScrollTo: (target: number, easing?: EasingFunction) => void\n /** Callback when drag ends (for updating state) */\n onDragEnd?: () => void\n /** Direction of the slider (horizontal or vertical) */\n direction?: SliderDirection\n}\n\nexport const createDragState = (): DragState => ({\n isDragging: false,\n startX: 0,\n startY: 0,\n startScrollLeft: 0,\n startScrollTop: 0,\n velocity: 0,\n lastX: 0,\n lastY: 0,\n lastTime: 0,\n momentumId: null\n})\n\nconst findNearestSlide = (\n feed: HTMLElement,\n slides: HTMLElement[],\n direction: SliderDirection = 'horizontal'\n): HTMLElement | null => {\n const feedRect = feed.getBoundingClientRect()\n const isVertical = direction === 'vertical'\n\n const feedCenter = isVertical\n ? feedRect.top + feedRect.height / 2\n : feedRect.left + feedRect.width / 2\n\n let nearestSlide: HTMLElement | null = null\n let minDistance = Infinity\n\n for (const slide of slides) {\n if (slide.offsetParent === null) continue\n\n const slideRect = slide.getBoundingClientRect()\n const slideCenter = isVertical\n ? slideRect.top + slideRect.height / 2\n : slideRect.left + slideRect.width / 2\n const distance = Math.abs(feedCenter - slideCenter)\n\n if (distance < minDistance) {\n minDistance = distance\n nearestSlide = slide\n }\n }\n\n return nearestSlide\n}\n\nconst applyMomentum = (\n state: DragState,\n feed: HTMLElement,\n slides: HTMLElement[],\n smoothScrollTo: (target: number, easing?: EasingFunction) => void,\n onDragEnd?: () => void,\n direction: SliderDirection = 'horizontal'\n): void => {\n const friction = 0.95\n const minVelocity = 0.5\n const isVertical = direction === 'vertical'\n\n const animate = () => {\n if (Math.abs(state.velocity) < minVelocity) {\n state.momentumId = null\n\n const nearestSlide = findNearestSlide(feed, slides, direction)\n if (nearestSlide) {\n const targetPosition = isVertical ? nearestSlide.offsetTop : nearestSlide.offsetLeft\n smoothScrollTo(targetPosition, easeOutCubic)\n }\n\n onDragEnd?.()\n return\n }\n\n if (isVertical) {\n feed.scrollTop += state.velocity\n } else {\n feed.scrollLeft += state.velocity\n }\n state.velocity *= friction\n\n state.momentumId = requestAnimationFrame(animate)\n }\n\n state.momentumId = requestAnimationFrame(animate)\n}\n\nconst getEventX = (event: MouseEvent | TouchEvent): number => {\n if ('touches' in event) {\n return event.touches[0]?.clientX ?? 0\n }\n return event.clientX\n}\n\nconst getEventY = (event: MouseEvent | TouchEvent): number => {\n if ('touches' in event) {\n return event.touches[0]?.clientY ?? 0\n }\n return event.clientY\n}\n\nexport const setupDragToScroll = (config: DragConfig): DragState => {\n const { feed, slides, abortSignal, smoothScrollTo, onDragEnd, direction = 'horizontal' } = config\n const state = createDragState()\n const isVertical = direction === 'vertical'\n\n const handleDragStart = (event: MouseEvent | TouchEvent) => {\n if (state.momentumId !== null) {\n cancelAnimationFrame(state.momentumId)\n state.momentumId = null\n }\n\n state.isDragging = true\n state.startX = getEventX(event)\n state.startY = getEventY(event)\n state.startScrollLeft = feed.scrollLeft\n state.startScrollTop = feed.scrollTop\n state.velocity = 0\n state.lastX = state.startX\n state.lastY = state.startY\n state.lastTime = performance.now()\n\n feed.style.userSelect = 'none'\n feed.classList.add('is-dragging')\n\n if (event.type === 'mousedown') {\n event.preventDefault()\n }\n }\n\n const handleDragMove = (event: MouseEvent | TouchEvent) => {\n if (!state.isDragging) return\n\n const currentX = getEventX(event)\n const currentY = getEventY(event)\n const currentTime = performance.now()\n const deltaTime = currentTime - state.lastTime\n\n if (isVertical) {\n const deltaY = state.startY - currentY\n feed.scrollTop = state.startScrollTop + deltaY\n\n if (deltaTime > 0) {\n state.velocity = (state.lastY - currentY) / deltaTime * 16\n }\n state.lastY = currentY\n } else {\n const deltaX = state.startX - currentX\n feed.scrollLeft = state.startScrollLeft + deltaX\n\n if (deltaTime > 0) {\n state.velocity = (state.lastX - currentX) / deltaTime * 16\n }\n state.lastX = currentX\n }\n\n state.lastTime = currentTime\n\n if (event.type === 'touchmove') {\n event.preventDefault()\n }\n }\n\n const handleDragEnd = () => {\n if (!state.isDragging) return\n\n state.isDragging = false\n\n feed.style.userSelect = ''\n feed.classList.remove('is-dragging')\n\n if (Math.abs(state.velocity) > 1) {\n applyMomentum(state, feed, slides, smoothScrollTo, onDragEnd, direction)\n } else {\n const nearestSlide = findNearestSlide(feed, slides, direction)\n if (nearestSlide) {\n const targetPosition = isVertical ? nearestSlide.offsetTop : nearestSlide.offsetLeft\n smoothScrollTo(targetPosition, easeOutCubic)\n }\n onDragEnd?.()\n }\n }\n\n feed.addEventListener('mousedown', handleDragStart, { signal: abortSignal })\n document.addEventListener('mousemove', handleDragMove, { signal: abortSignal })\n document.addEventListener('mouseup', handleDragEnd, { signal: abortSignal })\n\n feed.addEventListener('touchstart', handleDragStart, {\n passive: true,\n signal: abortSignal\n })\n feed.addEventListener('touchmove', handleDragMove, {\n passive: false,\n signal: abortSignal\n })\n feed.addEventListener('touchend', handleDragEnd, { signal: abortSignal })\n\n document.addEventListener('mouseleave', handleDragEnd, { signal: abortSignal })\n\n return state\n}\n\nexport const cleanupDrag = (state: DragState): void => {\n if (state.momentumId !== null) {\n cancelAnimationFrame(state.momentumId)\n state.momentumId = null\n }\n}\n","export interface GenerateBulletsParams {\n bulletsContainer: HTMLElement\n slides: HTMLElement[]\n bulletClass: string\n bulletActiveClass: string\n feedId: string\n}\n\nexport const generateBullets = ({\n bulletsContainer,\n slides,\n bulletClass,\n bulletActiveClass,\n feedId,\n}: GenerateBulletsParams): HTMLElement[] => {\n if (!bulletsContainer || !(bulletsContainer instanceof HTMLElement)) {\n throw new Error('Invalid bulletsContainer: must be a valid HTMLElement')\n }\n\n if (!Array.isArray(slides) || slides.length === 0) {\n throw new Error('Invalid slides: must be a non-empty array')\n }\n\n if (!feedId || typeof feedId !== 'string') {\n throw new Error('Invalid feedId: must be a non-empty string')\n }\n\n if (!bulletClass || typeof bulletClass !== 'string') {\n throw new Error('Invalid bulletClass: must be a non-empty string')\n }\n\n bulletsContainer.innerHTML = ''\n bulletsContainer.setAttribute('role', 'tablist')\n bulletsContainer.setAttribute('aria-label', 'Slide navigation')\n\n const visibleSlides = slides\n .map((slide, originalIndex) => ({ slide, originalIndex }))\n .filter(({ slide }) => slide.offsetParent !== null)\n\n if (visibleSlides.length === 0) {\n console.warn('No visible slides found')\n return []\n }\n\n const bullets = visibleSlides.map(({ slide, originalIndex }, visibleIndex) => {\n const bullet = document.createElement('button')\n bullet.type = 'button'\n\n bullet.classList.add(bulletClass)\n if (visibleIndex === 0) {\n bullet.classList.add(bulletActiveClass)\n }\n\n bullet.setAttribute('role', 'tab')\n bullet.setAttribute('aria-selected', visibleIndex === 0 ? 'true' : 'false')\n bullet.setAttribute('aria-controls', feedId)\n bullet.setAttribute('aria-label', `Go to slide ${visibleIndex + 1}`)\n bullet.setAttribute('data-slide-index', String(visibleIndex))\n\n bulletsContainer.appendChild(bullet)\n\n return bullet\n })\n\n return bullets\n}\n\nexport const updateActiveBullet = (\n bullets: HTMLElement[],\n activeIndex: number,\n bulletActiveClass: string,\n): void => {\n if (!Array.isArray(bullets) || activeIndex < 0 || activeIndex >= bullets.length) {\n console.warn('Invalid activeIndex or bullets array')\n return\n }\n\n bullets.forEach((bullet, index) => {\n const isActive = index === activeIndex\n bullet.classList.toggle(bulletActiveClass, isActive)\n bullet.setAttribute('aria-selected', isActive ? 'true' : 'false')\n })\n}","export interface GenerateThumbsParams {\n thumbsContainer: HTMLElement\n slides: HTMLElement[]\n thumbClass: string\n thumbActiveClass: string\n feedId: string\n thumbImageSelector?: string\n thumbSize?: { width: number; height: number }\n}\n\nexport const generateThumbs = ({\n thumbsContainer,\n slides,\n thumbClass,\n thumbActiveClass,\n feedId,\n thumbImageSelector = 'img',\n thumbSize\n}: GenerateThumbsParams): HTMLElement[] => {\n if (!thumbsContainer || !(thumbsContainer instanceof HTMLElement)) {\n throw new Error('Invalid thumbsContainer: must be a valid HTMLElement')\n }\n\n if (!Array.isArray(slides) || slides.length === 0) {\n throw new Error('Invalid slides: must be a non-empty array')\n }\n\n if (!feedId || typeof feedId !== 'string') {\n throw new Error('Invalid feedId: must be a non-empty string')\n }\n\n if (!thumbClass || typeof thumbClass !== 'string') {\n throw new Error('Invalid thumbClass: must be a non-empty string')\n }\n\n thumbsContainer.innerHTML = ''\n thumbsContainer.setAttribute('role', 'tablist')\n thumbsContainer.setAttribute('aria-label', 'Slide thumbnails')\n\n const visibleSlides = slides\n .map((slide, originalIndex) => ({ slide, originalIndex }))\n .filter(({ slide }) => slide.offsetParent !== null)\n\n if (visibleSlides.length === 0) {\n console.warn('No visible slides found')\n return []\n }\n\n const thumbs = visibleSlides.map(({ slide, originalIndex }, visibleIndex) => {\n const thumb = document.createElement('button')\n thumb.type = 'button'\n\n thumb.classList.add(thumbClass)\n if (visibleIndex === 0) {\n thumb.classList.add(thumbActiveClass)\n }\n\n // Extract image from slide\n const sourceImage = slide.querySelector(thumbImageSelector) as HTMLImageElement | null\n if (sourceImage?.src) {\n const thumbImg = document.createElement('img')\n thumbImg.src = sourceImage.src\n thumbImg.alt = sourceImage.alt || `Slide ${visibleIndex + 1} thumbnail`\n thumbImg.draggable = false\n\n if (thumbSize) {\n thumbImg.style.width = `${thumbSize.width}px`\n thumbImg.style.height = `${thumbSize.height}px`\n thumbImg.style.objectFit = 'cover'\n }\n\n thumb.appendChild(thumbImg)\n }\n\n // Accessibility attributes\n thumb.setAttribute('role', 'tab')\n thumb.setAttribute('aria-selected', visibleIndex === 0 ? 'true' : 'false')\n thumb.setAttribute('aria-controls', feedId)\n thumb.setAttribute('aria-label', `Go to slide ${visibleIndex + 1}`)\n thumb.setAttribute('data-slide-index', String(visibleIndex))\n\n thumbsContainer.appendChild(thumb)\n\n return thumb\n })\n\n return thumbs\n}\n\nexport const updateActiveThumbnail = (\n thumbs: HTMLElement[],\n activeIndex: number,\n thumbActiveClass: string\n): void => {\n if (!Array.isArray(thumbs) || activeIndex < 0 || activeIndex >= thumbs.length) {\n console.warn('Invalid activeIndex or thumbs array')\n return\n }\n\n thumbs.forEach((thumb, index) => {\n const isActive = index === activeIndex\n thumb.classList.toggle(thumbActiveClass, isActive)\n thumb.setAttribute('aria-selected', isActive ? 'true' : 'false')\n })\n}\n\n","import type { SliderSettings, SliderState } from './types.js'\n\n/**\n * Marquee state - tracks cloned slides for marquee mode\n */\nexport interface MarqueeState {\n initialized: boolean\n clonedSlides: HTMLElement[]\n styleElement: HTMLStyleElement | null\n}\n\n/**\n * Create initial marquee state\n */\nexport const createMarqueeState = (): MarqueeState => ({\n initialized: false,\n clonedSlides: [],\n styleElement: null\n})\n\n/**\n * Inject CSS keyframes for smooth marquee animation\n */\nconst injectMarqueeKeyframes = (): HTMLStyleElement => {\n // Check if keyframes already exist\n const existingStyle = document.getElementById('lazer-marquee-keyframes')\n if (existingStyle) {\n return existingStyle as HTMLStyleElement\n }\n\n const style = document.createElement('style')\n style.id = 'lazer-marquee-keyframes'\n style.textContent = `\n @keyframes lazer-marquee-scroll {\n 0% {\n transform: translateX(0);\n }\n 100% {\n transform: translateX(-50%);\n }\n }\n `\n document.head.appendChild(style)\n return style\n}\n\n/**\n * Clone all slides and append for seamless marquee looping\n */\nexport const setupMarqueeClones = (\n settings: SliderSettings,\n marqueeState: MarqueeState\n): void => {\n if (marqueeState.initialized) return\n\n // Inject CSS keyframes\n marqueeState.styleElement = injectMarqueeKeyframes()\n\n // Ensure feed has proper CSS for transform animation\n // Note: Parent container should have overflow: hidden for marquee effect\n settings.feed.style.display = 'flex'\n settings.feed.style.willChange = 'transform'\n\n // Clone all original slides and append to create seamless loop\n settings.slides.forEach((slide) => {\n const clone = slide.cloneNode(true) as HTMLElement\n clone.setAttribute('data-lazer-marquee-clone', 'true')\n clone.setAttribute('aria-hidden', 'true')\n settings.feed.appendChild(clone)\n marqueeState.clonedSlides.push(clone)\n })\n\n marqueeState.initialized = true\n}\n\n/**\n * Remove marquee cloned slides from the DOM\n */\nexport const cleanupMarqueeClones = (marqueeState: MarqueeState): void => {\n if (!marqueeState.initialized) return\n\n marqueeState.clonedSlides.forEach((clone) => {\n clone.remove()\n })\n\n marqueeState.clonedSlides = []\n marqueeState.initialized = false\n}\n\n/**\n * Setup marquee CSS animation for smooth hardware-accelerated scrolling\n */\nconst setupMarqueeCss = (\n settings: SliderSettings,\n state: SliderState\n): void => {\n // Ensure keyframes exist first\n injectMarqueeKeyframes()\n\n // Wait a frame to ensure keyframes are parsed and layout is complete\n requestAnimationFrame(() => {\n const scrollWidth = settings.feed.scrollWidth\n const speed = settings.marqueeSpeed ?? 50 // pixels per second\n const direction = settings.marqueeDirection ?? 'left'\n\n // Distance is half the scroll width (the original content width)\n const distance = scrollWidth / 2\n\n // Validate values\n if (distance <= 0 || speed <= 0) {\n console.warn('[lazer-slider] Invalid marquee values:', { distance, speed, scrollWidth })\n return\n }\n\n // Calculate duration: distance / speed (how long to scroll through original content)\n const duration = distance / speed\n const animationDirection = direction === 'right' ? 'reverse' : 'normal'\n\n // Apply animation - use percentage-based keyframes for seamless loop\n const animationValue = `lazer-marquee-scroll ${duration}s linear infinite ${animationDirection}`\n\n // Remove any existing animation first\n settings.feed.style.animation = 'none'\n\n // Force reflow to reset animation\n void settings.feed.offsetWidth\n\n // Apply new animation\n settings.feed.style.animation = animationValue\n settings.feed.style.animationPlayState = state.marqueePaused ? 'paused' : 'running'\n })\n}\n\n/**\n * Start marquee animation using smooth CSS animations\n */\nexport const startMarquee = (\n settings: SliderSettings,\n state: SliderState\n): void => {\n // Setup CSS animation for smooth hardware-accelerated scrolling\n setupMarqueeCss(settings, state)\n}\n\n/**\n * Stop marquee animation\n */\nexport const stopMarquee = (state: SliderState, settings: SliderSettings): void => {\n // Remove animation\n settings.feed.style.animation = ''\n settings.feed.style.animationPlayState = ''\n\n // Reset transform\n settings.feed.style.transform = ''\n settings.feed.style.willChange = ''\n}\n\n/**\n * Pause marquee animation (temporary, resumes on mouse leave)\n */\nexport const pauseMarquee = (state: SliderState, settings: SliderSettings): void => {\n state.marqueePaused = true\n settings.feed.style.animationPlayState = 'paused'\n}\n\n/**\n * Resume marquee animation after pause\n */\nexport const resumeMarquee = (state: SliderState, settings: SliderSettings): void => {\n state.marqueePaused = false\n settings.feed.style.animationPlayState = 'running'\n}\n\n/**\n * Setup marquee mode (clones + animation)\n */\nexport const setupMarquee = (\n settings: SliderSettings,\n state: SliderState,\n marqueeState: MarqueeState\n): void => {\n if (!settings.marquee) return\n\n setupMarqueeClones(settings, marqueeState)\n startMarquee(settings, state)\n}\n\n/**\n * Attach marquee pause-on-hover event listeners\n */\nexport const attachMarqueeEventListeners = (\n settings: SliderSettings,\n state: SliderState,\n signal: AbortSignal\n): void => {\n if (!settings.marquee || settings.pauseOnHover === false) return\n\n settings.feed.addEventListener(\n 'mouseenter',\n () => pauseMarquee(state, settings),\n { signal }\n )\n settings.feed.addEventListener(\n 'mouseleave',\n () => resumeMarquee(state, settings),\n { signal }\n )\n settings.feed.addEventListener(\n 'touchstart',\n () => pauseMarquee(state, settings),\n { passive: true, signal }\n )\n settings.feed.addEventListener(\n 'touchend',\n () => resumeMarquee(state, settings),\n { signal }\n )\n}\n","/**\n * Critical CSS styles that are auto-injected for zero-config usage\n * Users can override these by using more specific selectors or !important\n */\nconst CRITICAL_STYLES = `\n/* Lazer Slider - Critical Styles (Auto-injected) */\n.lazer-feed {\n position: relative;\n display: flex;\n overflow-x: auto;\n overflow-y: hidden;\n -webkit-overflow-scrolling: touch;\n scrollbar-width: none;\n}\n\n.lazer-feed::-webkit-scrollbar {\n display: none;\n}\n\n.lazer-feed.lazer-vertical {\n flex-direction: column;\n overflow-x: hidden;\n overflow-y: auto;\n}\n\n.lazer-slide {\n flex-shrink: 0;\n}\n\n.lazer-feed.lazer-draggable {\n cursor: grab;\n}\n\n.lazer-feed.lazer-draggable.is-dragging {\n cursor: grabbing;\n user-select: none;\n}\n`\n\nlet stylesInjected = false\nconst STYLE_ID = 'lazer-slider-critical-styles'\n\n/**\n * Injects critical CSS styles into the document head.\n * Safe to call multiple times - will only inject once.\n *\n * @example\n * ```typescript\n * import { injectStyles } from 'lazer-slider'\n *\n * // Manually inject styles (useful for SSR or early loading)\n * injectStyles()\n * ```\n */\nexport const injectStyles = (): void => {\n if (stylesInjected || typeof document === 'undefined') return\n\n const existingStyle = document.getElementById(STYLE_ID)\n if (existingStyle) {\n stylesInjected = true\n return\n }\n\n const style = document.createElement('style')\n style.id = STYLE_ID\n style.textContent = CRITICAL_STYLES\n document.head.appendChild(style)\n stylesInjected = true\n}\n\n/**\n * Internal function called by createSlider to ensure styles are injected\n * @internal\n */\nexport const injectStylesOnce = (): void => {\n injectStyles()\n}\n\n/**\n * Removes the injected styles from the document.\n * Useful for cleanup in testing or when completely removing the slider.\n *\n * @example\n * ```typescript\n * import { removeStyles } from 'lazer-slider'\n *\n * // Remove injected styles\n * removeStyles()\n * ```\n */\nexport const removeStyles = (): void => {\n if (typeof document === 'undefined') return\n\n const style = document.getElementById(STYLE_ID)\n if (style) {\n style.remove()\n stylesInjected = false\n }\n}\n\n","import type {\n SliderSettings,\n SliderState,\n SliderNavDirection,\n EasingFunction,\n Slider,\n DragState\n} from './types.js'\nimport { easeOutExpo } from './easing.js'\nimport {\n initAria,\n toggleControlVisibility,\n updateActiveThumb,\n setupKeyboardNavigation\n} from './accessibility.js'\nimport { setupDragToScroll, cleanupDrag } from './drag.js'\nimport { generateBullets } from './bullets.js'\nimport { generateThumbs } from './thumbs.js'\nimport {\n createMarqueeState,\n setupMarquee,\n startMarquee,\n stopMarquee,\n pauseMarquee,\n resumeMarquee,\n cleanupMarqueeClones,\n attachMarqueeEventListeners\n} from './marquee.js'\nimport { injectStylesOnce } from './styles.js'\n\nconst ANIMATION = {\n MIN_DURATION: 400,\n MAX_DURATION: 1000,\n SPEED_FACTOR: 1.5,\n SCROLL_END_DELAY: 50,\n THUMB_UPDATE_DELAY: 500\n} as const\n\nconst DESKTOP_BREAKPOINT = '(min-width: 64rem)'\n\nexport const createSlider = (settings: SliderSettings): Slider => {\n // Auto-inject critical CSS styles for zero-config usage\n injectStylesOnce()\n\n if (!settings.feed) {\n throw new Error('lazer-slider: feed element is required')\n }\n\n if (!settings.slides?.length) {\n throw new Error('lazer-slider: slides array is required and must not be empty')\n }\n\n if (!settings.feed.id) {\n settings.feed.id = `lazer-slider-feed-${Math.random().toString(36).substr(2, 9)}`\n }\n\n // Add classes for CSS targeting (if not already present)\n settings.feed.classList.add('lazer-feed')\n settings.slides.forEach((slide) => {\n slide.classList.add('lazer-slide')\n })\n\n if (settings.bulletsContainer && !settings.thumbs) {\n const bullets = generateBullets({\n bulletsContainer: settings.bulletsContainer,\n slides: settings.slides,\n bulletClass: settings.bulletsClass ?? 'lazer-bullet',\n bulletActiveClass: settings.bulletsActiveClass ?? 'active',\n feedId: settings.feed.id\n })\n settings.thumbs = bullets\n }\n\n if (settings.thumbsContainer && !settings.thumbs) {\n const thumbs = generateThumbs({\n thumbsContainer: settings.thumbsContainer,\n slides: settings.slides,\n thumbClass: settings.thumbsClass ?? 'lazer-thumb',\n thumbActiveClass: settings.thumbsActiveClass ?? 'active',\n feedId: settings.feed.id,\n thumbImageSelector: settings.thumbImageSelector ?? 'img',\n thumbSize: settings.thumbSize\n })\n settings.thumbs = thumbs\n }\n\n const direction = settings.direction ?? 'horizontal'\n const isVertical = direction === 'vertical'\n\n // Add vertical class for CSS targeting\n if (isVertical) {\n settings.feed.classList.add('lazer-vertical')\n }\n\n // Add marquee class if enabled\n if (settings.marquee) {\n settings.feed.classList.add('lazer-marquee')\n }\n\n const state: SliderState = {\n currentSlideIndex: 0,\n isScrolling: false,\n ticking: false,\n cachedFeedRect: null,\n lastWidth: 0,\n updateThumbTimeout: null,\n scrollEndTimeout: null,\n abortController: new AbortController(),\n autoplayIntervalId: null,\n autoplayPaused: false,\n marqueeAnimationId: null,\n marqueePaused: false,\n marqueeLastTimestamp: 0,\n isLoopRepositioning: false\n }\n\n let dragState: DragState | null = null\n\n const loopState = {\n initialized: false,\n clonedSlides: [] as HTMLElement[],\n realSlides: [...settings.slides] as HTMLElement[],\n clonesPerSide: 0\n }\n\n const marqueeState = createMarqueeState()\n\n const easing = settings.easing ?? easeOutExpo\n\n const getFeedRect = (): DOMRect => {\n const currentSize = isVertical ? settings.feed.clientHeight : settings.feed.clientWidth\n if (!state.cachedFeedRect || state.lastWidth !== currentSize) {\n state.cachedFeedRect = settings.feed.getBoundingClientRect()\n state.lastWidth = currentSize\n }\n return state.cachedFeedRect\n }\n\n const getVisibleSlides = (): HTMLElement[] => {\n return settings.slides.filter((slide) => slide.offsetParent !== null)\n }\n\n const isDesktop = (): boolean => {\n return window.matchMedia(DESKTOP_BREAKPOINT).matches\n }\n\n const getLoopClonesCount = (): number => {\n const perView = isDesktop()\n ? settings.desktopSlidesPerView\n : settings.mobileSlidesPerView\n\n if (!perView || perView === 'auto') {\n return 1\n }\n return Math.ceil(perView)\n }\n\n const setupLoopClones = (): void => {\n if (!settings.loop || loopState.initialized) return\n\n const realSlides = loopState.realSlides\n const clonesCount = getLoopClonesCount()\n loopState.clonesPerSide = clonesCount\n\n for (let i = realSlides.length - clonesCount; i < realSlides.length; i++) {\n const slide = realSlides[i]\n if (!slide) continue\n\n const clone = slide.cloneNode(true) as HTMLElement\n clone.setAttribute('data-lazer-clone', 'prepend')\n clone.setAttribute('aria-hidden', 'true')\n settings.feed.insertBefore(clone, settings.feed.firstChild)\n loopState.clonedSlides.push(clone)\n }\n\n for (let i = 0; i < clonesCount; i++) {\n const slide = realSlides[i]\n if (!slide) continue\n\n const clone = slide.cloneNode(true) as HTMLElement\n clone.setAttribute('data-lazer-clone', 'append')\n clone.setAttribute('aria-hidden', 'true')\n settings.feed.appendChild(clone)\n loopState.clonedSlides.push(clone)\n }\n\n requestAnimationFrame(() => {\n const firstRealSlide = realSlides[0]\n if (firstRealSlide) {\n if (isVertical) {\n settings.feed.scrollTop = firstRealSlide.offsetTop\n } else {\n settings.feed.scrollLeft = firstRealSlide.offsetLeft\n }\n }\n })\n\n loopState.initialized = true\n }\n\n const handleLoopReposition = (navDirection: SliderNavDirection): void => {\n if (!settings.loop || !loopState.initialized) return\n\n state.isLoopRepositioning = true\n\n const realSlides = loopState.realSlides\n const totalRealSlides = realSlides.length\n\n if (navDirection === 'next') {\n const firstRealSlide = realSlides[0]\n if (firstRealSlide) {\n if (isVertical) {\n settings.feed.scrollTop = firstRealSlide.offsetTop\n } else {\n settings.feed.scrollLeft = firstRealSlide.offsetLeft\n }\n }\n state.currentSlideIndex = 0\n } else {\n const lastRealSlide = realSlides[totalRealSlides - 1]\n if (lastRealSlide) {\n if (isVertical) {\n settings.feed.scrollTop = lastRealSlide.offsetTop\n } else {\n settings.feed.scrollLeft = lastRealSlide.offsetLeft\n }\n }\n state.currentSlideIndex = totalRealSlides - 1\n }\n\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n state.isLoopRepositioning = false\n updateControlsVisibility()\n })\n })\n }\n\n const cleanupLoopClones = (): void => {\n if (!loopState.initialized) return\n\n loopState.clonedSlides.forEach((clone) => {\n clone.remove()\n })\n\n loopState.clonedSlides = []\n loopState.initialized = false\n loopState.clonesPerSide = 0\n }\n\n const applySlideWidths = (): void => {\n const perView = isDesktop()\n ? settings.desktopSlidesPerView\n : settings.mobileSlidesPerView\n\n const gap = settings.slideGap ?? 0\n\n if (gap > 0) {\n settings.feed.style.gap = `${gap}px`\n }\n\n if (!perView || perView === 'auto') {\n settings.slides.forEach((slide) => {\n slide.style.flex = ''\n slide.style.minWidth = ''\n slide.style.minHeight = ''\n })\n return\n }\n\n const totalGapSize = gap * (perView - 1)\n const slideSize = `calc((100% - ${totalGapSize}px) / ${perView})`\n\n if (isVertical) {\n settings.slides.forEach((slide) => {\n slide.style.flex = `0 0 ${slideSize}`\n slide.style.minHeight = slideSize\n slide.style.minWidth = ''\n })\n } else {\n settings.slides.forEach((slide) => {\n slide.style.flex = `0 0 ${slideSize}`\n slide.style.minWidth = slideSize\n slide.style.minHeight = ''\n })\n }\n }\n\n const updateScrollbar = (): void => {\n if (!settings.scrollbarThumb) return\n\n const feedRect = getFeedRect()\n\n if (isVertical) {\n const thumbHeight = (feedRect.height / settings.feed.scrollHeight) * 100\n settings.scrollbarThumb.style.height = `${thumbHeight}%`\n settings.scrollbarThumb.style.width = ''\n } else {\n const thumbWidth = (feedRect.width / settings.feed.scrollWidth) * 100\n settings.scrollbarThumb.style.width = `${thumbWidth}%`\n settings.scrollbarThumb.style.height = ''\n }\n }\n\n const updateScrollbarPosition = (): void => {\n if (!settings.scrollbarThumb || !settings.scrollbarTrack) return\n\n if (isVertical) {\n const trackHeight = settings.scrollbarTrack.getBoundingClientRect().height\n const thumbHeight = settings.scrollbarThumb.getBoundingClientRect().height\n const totalTransform = trackHeight - thumbHeight\n\n const maxScroll = settings.feed.scrollHeight - settings.feed.clientHeight\n const scrollProgress = maxScroll > 0 ? settings.feed.scrollTop / maxScroll : 0\n\n settings.scrollbarThumb.style.transform = `translateY(${totalTransform * scrollProgress}px)`\n } else {\n const trackWidth = settings.scrollbarTrack.getBoundingClientRect().width\n const thumbWidth = settings.scrollbarThumb.getBoundingClientRect().width\n const totalTransform = trackWidth - thumbWidth\n\n const maxScroll = settings.feed.scrollWidth - settings.feed.clientWidth\n const scrollProgress = maxScroll > 0 ? settings.feed.scrollLeft / maxScroll : 0\n\n settings.scrollbarThumb.style.transform = `translateX(${totalTransform * scrollProgress}px)`\n }\n }\n\n const updateControlsVisibility = (): void => {\n // Skip visibility updates during loop repositioning to prevent flicker\n if (state.isLoopRepositioning) {\n return\n }\n\n const feedRect = getFeedRect()\n\n let isAtStart: boolean\n let isAtEnd: boolean\n let shouldHideScrollbar: boolean\n\n if (isVertical) {\n isAtStart = settings.feed.scrollTop <= 1\n isAtEnd = settings.feed.scrollTop + feedRect.height >= settings.feed.scrollHeight - 1\n shouldHideScrollbar = settings.feed.scrollHeight <= feedRect.height\n } else {\n isAtStart = settings.feed.scrollLeft <= 1\n isAtEnd = settings.feed.scrollLeft + feedRect.width >= settings.feed.scrollWidth - 1\n shouldHideScrollbar = settings.feed.scrollWidth <= feedRect.width\n }\n\n if (settings.scrollbarTrack) {\n settings.scrollbarTrack.style.display = shouldHideScrollbar ? 'none' : 'block'\n }\n\n if (settings.loop) {\n toggleControlVisibility(\n settings.prevSlideButton,\n !shouldHideScrollbar,\n settings.feed\n )\n toggleControlVisibility(\n settings.nextSlideButton,\n !shouldHideScrollbar,\n settings.feed\n )\n return\n }\n\n toggleControlVisibility(\n settings.prevSlideButton,\n !isAtStart && !shouldHideScrollbar,\n settings.feed\n )\n toggleControlVisibility(\n settings.nextSlideButton,\n !isAtEnd && !shouldHideScrollbar,\n settings.feed\n )\n }\n\n const updateCurrentSlideIndex = (): void => {\n const feedRect = getFeedRect()\n\n const slidesToCheck = loopState.initialized\n ? loopState.realSlides\n : getVisibleSlides()\n\n const viewportVisibleSlides = slidesToCheck.filter((slide) => {\n const slideRect = slide.getBoundingClientRect()\n const tolerance = 20\n\n if (isVertical) {\n return (\n slideRect.bottom > feedRect.top + tolerance &&\n slideRect.top < feedRect.bottom - tolerance\n )\n }\n\n return (\n slideRect.right > feedRect.left + tolerance &&\n slideRect.left < feedRect.right - tolerance\n )\n })\n\n if (viewportVisibleSlides.length && viewportVisibleSlides[0]) {\n const newIndex = slidesToCheck.indexOf(viewportVisibleSlides[0])\n if (newIndex !== -1) {\n state.currentSlideIndex = newIndex\n const currentScroll = isVertical ? settings.feed.scrollTop : settings.feed.scrollLeft\n settings.onScroll?.({\n currentScroll,\n currentSlideIndex: state.currentSlideIndex\n })\n }\n }\n }\n\n const smoothScrollTo = (\n target: number,\n customEasing: EasingFunction = easing,\n onComplete?: () => void\n ): void => {\n const start = isVertical ? settings.feed.scrollTop : settings.feed.scrollLeft\n const distance = Math.abs(target - start)\n\n const duration = Math.min(\n ANIMATION.MAX_DURATION,\n Math.max(ANIMATION.MIN_DURATION, distance / ANIMATION.SPEED_FACTOR)\n )\n\n const startTime = performance.now()\n\n const animateScroll = (currentTime: number): void => {\n const elapsed = (currentTime - startTime) / duration\n const progress = Math.min(elapsed, 1)\n const ease = customEasing(progress)\n\n const scrollPosition = start + (target - start) * ease\n\n if (isVertical) {\n settings.feed.scrollTop = scrollPosition\n } else {\n settings.feed.scrollLeft = scrollPosition\n }\n\n if (progress < 1) {\n requestAnimationFrame(animateScroll)\n } else {\n if (isVertical) {\n settings.feed.scrollTop = target\n } else {\n settings.feed.scrollLeft = target\n }\n onComplete?.()\n }\n }\n\n requestAnimationFrame(animateScroll)\n }\n\n const handleThumbClick = (thumb: HTMLElement): void => {\n if (!settings.thumbs) return\n\n const index = settings.thumbs.indexOf(thumb)\n if (index === -1 || !settings.slides[index]) return\n\n state.currentSlideIndex = index\n updateActiveThumb(settings.thumbs, index)\n state.isScrolling = true\n\n if (state.updateThumbTimeout) {\n clearTimeout(state.updateThumbTimeout)\n }\n\n state.updateThumbTimeout = setTimeout(() => {\n state.isScrolling = false\n }, ANIMATION.THUMB_UPDATE_DELAY)\n\n const targetPosition = isVertical\n ? settings.slides[index].offsetTop\n : settings.slides[index].offsetLeft\n smoothScrollTo(targetPosition)\n }\n\n const handleNavButtonClick = (navDirection: SliderNavDirection): void => {\n const realSlides = loopState.initialized ? loopState.realSlides : getVisibleSlides()\n const slidesToScroll = isDesktop()\n ? settings.desktopSlidesPerScroll ?? 1\n : settings.mobileSlidesPerScroll ?? 1\n const totalRealSlides = realSlides.length\n\n updateCurrentSlideIndex()\n\n let targetSlide: HTMLElement | undefined\n let needsReposition = false\n\n if (navDirection === 'prev') {\n if (settings.loop && loopState.initialized && state.currentSlideIndex === 0) {\n\n const prependedClones = loopState.clonedSlides.filter(\n (clone) => clone.getAttribute('data-lazer-clone') === 'prepend'\n )\n targetSlide = prependedClones[prependedClones.length - 1]\n needsReposition = true\n } else {\n state.currentSlideIndex = Math.max(0, state.currentSlideIndex - slidesToScroll)\n targetSlide = realSlides[state.currentSlideIndex]\n }\n } else {\n if (settings.loop && loopState.initialized && state.currentSlideIndex >= totalRealSlides - 1) {\n const appendedClones = loopState.clonedSlides.filter(\n (clone) => clone.getAttribute('data-lazer-clone') === 'append'\n )\n targetSlide = appendedClones[0]\n needsReposition = true\n } else {\n state.currentSlideIndex = Math.min(\n totalRealSlides - 1,\n state.currentSlideIndex + slidesToScroll\n )\n targetSlide = realSlides[state.currentSlideIndex]\n }\n }\n\n if (!targetSlide) return\n\n const currentScroll = isVertical ? settings.feed.scrollTop : settings.feed.scrollLeft\n settings.onScrollStart?.({\n currentScroll,\n target: targetSlide,\n direction: navDirection\n })\n\n const targetPosition = isVertical ? targetSlide.offsetTop : targetSlide.offsetLeft\n\n if (needsReposition) {\n smoothScrollTo(targetPosition, easing, () => {\n handleLoopReposition(navDirection)\n })\n } else {\n smoothScrollTo(targetPosition)\n }\n }\n\n const updateScrollPosition = (): void => {\n updateScrollbarPosition()\n updateControlsVisibility()\n updateCurrentSlideIndex()\n\n if (!state.isScrolling) {\n updateActiveThumb(settings.thumbs, state.currentSlideIndex)\n }\n\n if (state.scrollEndTimeout) {\n clearTimeout(state.scrollEndTimeout)\n }\n\n state.scrollEndTimeout = setTimeout(() => {\n state.isScrolling = false\n const currentScroll = isVertical ? settings.feed.scrollTop : settings.feed.scrollLeft\n settings.onScrollEnd?.({\n currentScroll,\n currentSlideIndex: state.currentSlideIndex\n })\n }, ANIMATION.SCROLL_END_DELAY)\n }\n\n const handleFeedScroll = (): void => {\n if (!state.ticking) {\n requestAnimationFrame(() => {\n updateScrollPosition()\n state.ticking = false\n })\n state.ticking = true\n }\n }\n\n const handleWindowResize = (): void => {\n state.cachedFeedRect = null\n refresh()\n }\n\n const attachEventListeners = (): void => {\n const { signal } = state.abortController\n\n window.addEventListener('resize', handleWindowResize)\n\n settings.feed.addEventListener('scroll', handleFeedScroll, {\n passive: true,\n signal\n })\n\n if (settings.prevSlideButton) {\n settings.prevSlideButton.addEventListener(\n 'click',\n () => handleNavButtonClick('prev'),\n { signal }\n )\n }\n\n if (settings.nextSlideButton) {\n settings.nextSlideButton.addEventListener(\n 'click',\n () => handleNavButtonClick('next'),\n { signal }\n )\n }\n\n if (settings.thumbs?.length) {\n settings.thumbs[0]?.classList.add('active')\n settings.thumbs.forEach((thumb) => {\n thumb.addEventListener('click', () => handleThumbClick(thumb), { signal })\n })\n }\n\n setupKeyboardNavigation(\n settings.feed,\n () => handleNavButtonClick('prev'),\n () => handleNavButtonClick('next'),\n signal,\n direction\n )\n\n if (settings.enableDragToScroll !== false) {\n dragState = setupDragToScroll({\n feed: settings.feed,\n slides: settings.slides,\n abortSignal: signal,\n smoothScrollTo,\n onDragEnd: () => {\n updateCurrentSlideIndex()\n updateActiveThumb(settings.thumbs, state.currentSlideIndex)\n },\n direction\n })\n }\n\n if (settings.autoplay && settings.pauseOnHover !== false) {\n settings.feed.addEventListener(\n 'mouseenter',\n pauseAutoplay,\n { signal }\n )\n settings.feed.addEventListener(\n 'mouseleave',\n resumeAutoplay,\n { signal }\n )\n settings.feed.addEventListener(\n 'touchstart',\n pauseAutoplay,\n { passive: true, signal }\n )\n settings.feed.addEventListener(\n 'touchend',\n resumeAutoplay,\n { signal }\n )\n }\n\n attachMarqueeEventListeners(settings, state, signal)\n }\n\n const startAutoplay = (): void => {\n if (state.autoplayIntervalId) return;\n\n const interval = settings.autoplayInterval ?? 3000\n state.autoplayIntervalId = setInterval(() => {\n if (!state.autoplayPaused) {\n handleNavButtonClick('next')\n }\n }, interval)\n }\n\n const stopAutoplay = (): void => {\n if (state.autoplayIntervalId) {\n clearInterval(state.autoplayIntervalId)\n state.autoplayIntervalId = null\n }\n }\n\n const pauseAutoplay = (): void => {\n state.autoplayPaused = true\n }\n\n const resumeAutoplay = (): void => {\n state.autoplayPaused = false\n }\n\n const goToIndex = (index: number): void => {\n const slides = loopState.initialized ? loopState.realSlides : getVisibleSlides()\n const safeIndex = Math.max(0, Math.min(index, slides.length - 1))\n const targetSlide = slides[safeIndex]\n\n if (!targetSlide) return\n\n state.currentSlideIndex = safeIndex\n updateActiveThumb(settings.thumbs, safeIndex)\n const targetPosition = isVertical ? targetSlide.offsetTop : targetSlide.offsetLeft\n smoothScrollTo(targetPosition)\n }\n\n const refresh = (): void => {\n state.cachedFeedRect = null\n applySlideWidths()\n updateScrollbar()\n updateControlsVisibility()\n\n if (settings.marquee && !state.marqueePaused) {\n startMarquee(settings, state)\n }\n }\n\n const unload = (): void => {\n stopAutoplay()\n stopMarquee(state, settings)\n\n state.abortController.abort()\n window.removeEventListener('resize', handleWindowResize)\n\n if (state.updateThumbTimeout) {\n clearTimeout(state.updateThumbTimeout)\n }\n if (state.scrollEndTimeout) {\n clearTimeout(state.scrollEndTimeout)\n }\n\n if (dragState) {\n cleanupDrag(dragState)\n }\n\n cleanupLoopClones()\n cleanupMarqueeClones(marqueeState)\n\n state.cachedFeedRect = null\n }\n\n initAria(settings)\n applySlideWidths()\n\n if (settings.marquee) {\n setupMarquee(settings, state, marqueeState)\n } else {\n setupLoopClones()\n if (settings.autoplay) {\n startAutoplay()\n }\n }\n\n updateControlsVisibility()\n attachEventListeners()\n updateScrollbar()\n\n const play = (): void => {\n if (settings.marquee) {\n if (state.marqueePaused) {\n resumeMarquee(state, settings)\n } else {\n startMarquee(settings, state)\n }\n } else if (settings.autoplay) {\n startAutoplay()\n }\n }\n\n const pause = (): void => {\n if (settings.marquee) {\n pauseMarquee(state, settings)\n } else {\n stopAutoplay()\n }\n }\n\n return {\n goToIndex,\n refresh,\n unload,\n play,\n pause,\n next: () => handleNavButtonClick('next'),\n prev: () => handleNavButtonClick('prev')\n }\n}"],"mappings":"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","names":[]}
|
package/dist/lazer-slider.css
CHANGED
|
@@ -61,7 +61,6 @@
|
|
|
61
61
|
overflow-y: hidden;
|
|
62
62
|
-webkit-overflow-scrolling: touch;
|
|
63
63
|
scrollbar-width: none;
|
|
64
|
-
scroll-snap-type: x mandatory;
|
|
65
64
|
}
|
|
66
65
|
|
|
67
66
|
.lazer-feed::-webkit-scrollbar {
|
|
@@ -73,28 +72,25 @@
|
|
|
73
72
|
flex-direction: column;
|
|
74
73
|
overflow-x: hidden;
|
|
75
74
|
overflow-y: auto;
|
|
76
|
-
scroll-snap-type: y mandatory;
|
|
77
75
|
}
|
|
78
76
|
|
|
79
77
|
/* ============================================
|
|
80
78
|
Slides
|
|
81
79
|
============================================ */
|
|
82
80
|
.lazer-slide {
|
|
83
|
-
scroll-snap-align: start;
|
|
84
81
|
flex-shrink: 0;
|
|
85
82
|
}
|
|
86
83
|
|
|
87
84
|
/* ============================================
|
|
88
85
|
Drag State
|
|
89
86
|
============================================ */
|
|
90
|
-
.lazer-feed.
|
|
91
|
-
cursor:
|
|
92
|
-
user-select: none;
|
|
93
|
-
scroll-snap-type: none;
|
|
87
|
+
.lazer-feed.lazer-draggable {
|
|
88
|
+
cursor: grab;
|
|
94
89
|
}
|
|
95
90
|
|
|
96
|
-
.lazer-feed
|
|
97
|
-
cursor:
|
|
91
|
+
.lazer-feed.lazer-draggable.is-dragging {
|
|
92
|
+
cursor: grabbing;
|
|
93
|
+
user-select: none;
|
|
98
94
|
}
|
|
99
95
|
|
|
100
96
|
/* ============================================
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lazer-slider",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.5",
|
|
4
4
|
"description": "A lightweight, accessible slider with smooth scroll-to-snap animations and drag-to-scroll support",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -46,7 +46,9 @@
|
|
|
46
46
|
"type": "git",
|
|
47
47
|
"url": "https://github.com/lazer-technologies/lazer-slider"
|
|
48
48
|
},
|
|
49
|
-
"sideEffects":
|
|
49
|
+
"sideEffects": [
|
|
50
|
+
"*.css"
|
|
51
|
+
],
|
|
50
52
|
"engines": {
|
|
51
53
|
"node": ">=16"
|
|
52
54
|
}
|