{"version":3,"file":"hooks-Df47kgIl.cjs","names":["ReactCompareSliderCssVars","ReactCompareSliderClip","ReactCompareSliderCssVars","KeyboardEventKeys"],"sources":["../src/register.ts","../src/hooks.ts"],"sourcesContent":["'use client';\n\nimport { ReactCompareSliderCssVars } from './consts';\n\nexport const register = () => {\n  try {\n    if (typeof CSS !== 'undefined') {\n      /**\n       * We use a custom property to optimise the transition performance of the slider. It ensures the\n       * transitions fire smoothly at the exact same time on different elements. Otherwise, the handle\n       * and item transitions may not move in sync. This is especially noticeable in Safari.\n       */\n      CSS.registerProperty({\n        name: ReactCompareSliderCssVars.rawPosition,\n        syntax: '<percentage>',\n        inherits: true,\n        initialValue: '50%',\n      });\n    }\n  } catch (error) {\n    // biome-ignore lint/suspicious/noConsole: This should never happen but if it does we want to know.\n    console.debug('[react-compare-slider] register CSS property:', error);\n  }\n};\n","'use client';\n\nimport { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';\n\nimport { KeyboardEventKeys } from './components/internal-hooks';\nimport { ReactCompareSliderClip, ReactCompareSliderCssVars } from './consts';\nimport { register } from './register';\nimport type {\n  SetPositionFromBoundsProps,\n  UseReactCompareSliderProps,\n  UseReactCompareSliderReturn,\n} from './types';\n\nregister();\n\nconst getDefaultTransition = () =>\n  globalThis.matchMedia?.('(prefers-reduced-motion: no-preference)')?.matches ? '0.15s ease-out' : 'none';\n\nconst getDefaultOnlyHandleDraggable = () => !!globalThis.matchMedia?.('(pointer: coarse)')?.matches;\n\n/**\n * Hook to completely control the slider including all event handlers and state.\n * This is automatically used by the `ReactCompareSlider` component.\n * Only use this if you are building your own slider using the `react-compare-slider/components` module.\n */\nexport const useReactCompareSlider = ({\n  boundsPadding = '0px',\n  browsingContext = globalThis,\n  changePositionOnHover = false,\n  clip = ReactCompareSliderClip.all,\n  defaultPosition = 50,\n  disabled = false,\n  keyboardIncrement = '5%',\n  onlyHandleDraggable = getDefaultOnlyHandleDraggable(),\n  onPositionChange,\n  portrait = false,\n  transition = getDefaultTransition(),\n}: UseReactCompareSliderProps = {}): UseReactCompareSliderReturn => {\n  /** DOM node of the root element. */\n  const rootRef = useRef<HTMLDivElement>(null);\n  /** DOM node of the handle container. */\n  const handleRootRef = useRef<HTMLDivElement>(null);\n  /** Current position as a percentage value. */\n  const position = useRef(defaultPosition);\n  /** Whether user is currently dragging. */\n  const [isDragging, setIsDragging] = useState(false);\n  /** Whether the `transition` property can be applied. */\n  const [canTransition, setCanTransition] = useState(true);\n  /** Target container for pointer events. */\n  const [interactiveTarget, setInteractiveTarget] = useState<HTMLElement | null>(null);\n\n  const setPosition = useCallback(\n    (nextPosition: number) => {\n      const appliedPosition = Math.min(Math.max(nextPosition, 0), 100);\n\n      rootRef.current?.style.setProperty(ReactCompareSliderCssVars.rawPosition, `${appliedPosition}%`);\n      handleRootRef.current?.setAttribute('aria-valuenow', `${Math.round(appliedPosition)}`);\n      position.current = appliedPosition;\n\n      onPositionChange?.(appliedPosition);\n    },\n    [onPositionChange],\n  );\n\n  /** Set position using pointer coords. */\n  const setPositionFromBounds = useCallback(\n    function updateInternal({ x, y }: SetPositionFromBoundsProps) {\n      const rootElement = rootRef.current as HTMLDivElement;\n      const { width, height, top, left } = rootElement.getBoundingClientRect();\n\n      // Early out when component has zero bounds.\n      if (width === 0 || height === 0) return;\n\n      const pixelPosition = portrait ? y - top - browsingContext.scrollY : x - left - browsingContext.scrollX;\n      const nextPosition = (pixelPosition / (portrait ? height : width)) * 100;\n      setPosition(nextPosition);\n    },\n    [browsingContext, portrait, setPosition],\n  );\n\n  /** Handle mouse/touch down. */\n  const onPointerDown = useCallback(\n    (ev: PointerEvent) => {\n      ev.preventDefault();\n\n      // Only handle left mouse button (touch events also use 0).\n      if (disabled || ev.button !== 0) return;\n\n      setPositionFromBounds({ x: ev.pageX, y: ev.pageY });\n      setIsDragging(true);\n      setCanTransition(true);\n    },\n    [disabled, setPositionFromBounds],\n  );\n\n  /** Handle mouse/touch move. */\n  const onPointerMove = useCallback(\n    function moveCall(ev: PointerEvent) {\n      setCanTransition(false);\n      setPositionFromBounds({ x: ev.pageX, y: ev.pageY });\n    },\n    [setPositionFromBounds],\n  );\n\n  /** Handle mouse/touch up. */\n  const onPointerUp = useCallback((_ev: PointerEvent) => {\n    setIsDragging(false);\n    setCanTransition(true);\n  }, []);\n\n  const onTouchEnd = useCallback((_ev: TouchEvent) => {\n    setIsDragging(false);\n    setCanTransition(true);\n  }, []);\n\n  const onHandleRootClick = useCallback((ev: PointerEvent) => {\n    ev.preventDefault();\n    (ev.currentTarget as HTMLDivElement)?.focus();\n  }, []);\n\n  /** Handle keyboard movment. */\n  const onHandleRootKeyDown = useCallback(\n    (ev: KeyboardEvent) => {\n      if (!Object.values(KeyboardEventKeys).includes(ev.key as KeyboardEventKeys)) {\n        return;\n      }\n\n      ev.preventDefault();\n      setCanTransition(true);\n\n      const incrementPercentage =\n        typeof keyboardIncrement === 'string'\n          ? Number.parseFloat(keyboardIncrement)\n          : (keyboardIncrement / (rootRef.current?.getBoundingClientRect().width as number)) * 100;\n\n      const isIncrement = portrait\n        ? ev.key === KeyboardEventKeys.ARROW_LEFT || ev.key === KeyboardEventKeys.ARROW_DOWN\n        : ev.key === KeyboardEventKeys.ARROW_RIGHT || ev.key === KeyboardEventKeys.ARROW_UP;\n\n      const nextPosition = isIncrement\n        ? position.current + incrementPercentage\n        : position.current - incrementPercentage;\n\n      setPosition(nextPosition);\n    },\n    [keyboardIncrement, portrait, setPosition],\n  );\n\n  // Set target container for pointer events.\n  useLayoutEffect(() => {\n    setInteractiveTarget(onlyHandleDraggable ? handleRootRef.current : rootRef.current);\n  }, [onlyHandleDraggable]);\n\n  // Resync position when defaultPosition changes.\n  useEffect(() => {\n    setPosition(defaultPosition);\n  }, [defaultPosition, setPosition]);\n\n  return {\n    // Direct props\n    boundsPadding,\n    browsingContext,\n    changePositionOnHover,\n    clip,\n    defaultPosition,\n    disabled,\n    keyboardIncrement,\n    onlyHandleDraggable,\n    portrait,\n    transition,\n    // Events\n    onHandleRootKeyDown,\n    onPointerDown,\n    onPointerMove,\n    onPointerUp,\n    onTouchEnd,\n    onHandleRootClick,\n    // State\n    canTransition,\n    isDragging,\n    position,\n    // Setters\n    setPosition,\n    setPositionFromBounds,\n    // Elements\n    rootRef,\n    handleRootRef,\n    interactiveTarget,\n  };\n};\n"],"mappings":"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"}