{"version":3,"file":"alpine-mousedrag-plugin.cjs","sources":["../src/index.ts"],"sourcesContent":["import type { Alpine } from 'alpinejs';\n\ninterface MouseDragOptions {\n  disableInertia?: boolean;\n  friction?: number;\n  speedFactor?: number;\n}\n\nconst DEFAULT_OPTIONS: MouseDragOptions = {\n  disableInertia: false,\n  friction: 0.9,\n  speedFactor: 1.5,\n};\n\n/**\n * Alpine.js plugin that adds a mousedrag directive for scrolling elements with mouse drag and inertia\n */\nconst AlpineMouseDragPlugin = (Alpine: Alpine) => {\n  Alpine.directive(\n    'mousedrag',\n    (\n      el: HTMLElement,\n      {\n        modifiers,\n        expression,\n      }: {\n        type: string;\n        value: string;\n        modifiers: string[];\n        expression: string;\n        original: string;\n      },\n    ): (() => void) => {\n      // State variables\n      let isPointerDown = false;\n      let lastX = 0;\n      let lastY = 0;\n      let velocityX = 0;\n      let velocityY = 0;\n      let originalScrollSnap = '';\n\n      // Parse directive options\n      const options: MouseDragOptions = {\n        ...DEFAULT_OPTIONS,\n        disableInertia: modifiers.includes('disableinertia'),\n      };\n\n      if (expression && !isNaN(Number(expression))) {\n        options.speedFactor = Number(expression);\n      }\n\n      const friction = options.disableInertia ? 1 : (options.friction ?? 0.9);\n      const speedFactor = options.speedFactor ?? 1.5;\n\n      // Apply non-linear speed adjustment based on distance\n      const applySpeedCurve = (delta: number): number => {\n        const absDelta = Math.abs(delta);\n        return (\n          (Math.sign(delta) * Math.pow(absDelta, speedFactor)) /\n          Math.pow(10, speedFactor - 1)\n        );\n      };\n\n      // Common pointer handling\n      const handlePointerStart = (x: number, y: number, event?: Event) => {\n        isPointerDown = true;\n        lastX = x;\n        lastY = y;\n\n        originalScrollSnap = getComputedStyle(el).scrollSnapType;\n        el.style.scrollSnapType = 'none';\n\n        if (event) event.preventDefault?.();\n      };\n\n      const handlePointerMove = (x: number, y: number, event?: Event) => {\n        if (!isPointerDown) return;\n\n        const deltaX = x - lastX;\n        const deltaY = y - lastY;\n\n        lastX = x;\n        lastY = y;\n\n        const scaledDeltaX = applySpeedCurve(deltaX);\n        const scaledDeltaY = applySpeedCurve(deltaY);\n\n        velocityX = scaledDeltaX;\n        velocityY = scaledDeltaY;\n\n        el.scrollLeft -= scaledDeltaX;\n        el.scrollTop -= scaledDeltaY;\n\n        if (event) event.preventDefault?.();\n      };\n\n      const handlePointerEnd = () => {\n        if (!isPointerDown) return;\n        isPointerDown = false;\n\n        if (friction < 1) {\n          requestAnimationFrame(() => applyInertia());\n        } else {\n          el.style.scrollSnapType = originalScrollSnap;\n        }\n      };\n\n      const applyInertia = () => {\n        if (Math.abs(velocityX) > 1 || Math.abs(velocityY) > 1) {\n          el.scrollLeft -= velocityX;\n          el.scrollTop -= velocityY;\n          velocityX *= friction;\n          velocityY *= friction;\n          requestAnimationFrame(applyInertia);\n        } else {\n          el.style.scrollSnapType = originalScrollSnap;\n        }\n      };\n\n      // Mouse event handlers\n      const onMouseDown = (e: MouseEvent) => {\n        if (e.button !== 0) return; // Only left mouse button\n        handlePointerStart(e.clientX, e.clientY);\n      };\n\n      const onMouseMove = (e: MouseEvent) => {\n        handlePointerMove(e.clientX, e.clientY);\n      };\n\n      // Touch event handlers\n      const onTouchStart = (e: TouchEvent) => {\n        if (e.touches.length !== 1) return; // Only single touch\n        handlePointerStart(e.touches[0].clientX, e.touches[0].clientY, e);\n      };\n\n      const onTouchMove = (e: TouchEvent) => {\n        if (e.touches.length !== 1) return;\n        handlePointerMove(e.touches[0].clientX, e.touches[0].clientY, e);\n      };\n\n      // Add event listeners\n      el.addEventListener('mousedown', onMouseDown);\n      el.addEventListener('mousemove', onMouseMove);\n      window.addEventListener('mouseup', handlePointerEnd);\n\n      el.addEventListener('touchstart', onTouchStart, { passive: false });\n      el.addEventListener('touchmove', onTouchMove, { passive: false });\n      el.addEventListener('touchend', handlePointerEnd);\n\n      // Return cleanup function\n      return () => {\n        el.removeEventListener('mousedown', onMouseDown);\n        el.removeEventListener('mousemove', onMouseMove);\n        window.removeEventListener('mouseup', handlePointerEnd);\n\n        el.removeEventListener('touchstart', onTouchStart);\n        el.removeEventListener('touchmove', onTouchMove);\n        el.removeEventListener('touchend', handlePointerEnd);\n      };\n    },\n  );\n};\n\nexport default AlpineMouseDragPlugin;\n"],"names":["DEFAULT_OPTIONS","AlpineMouseDragPlugin","Alpine","el","modifiers","expression","isPointerDown","lastX","lastY","velocityX","velocityY","originalScrollSnap","options","friction","speedFactor","applySpeedCurve","delta","absDelta","handlePointerStart","x","y","event","handlePointerMove","deltaX","deltaY","scaledDeltaX","scaledDeltaY","handlePointerEnd","applyInertia","onMouseDown","e","onMouseMove","onTouchStart","onTouchMove"],"mappings":"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"}