{"version":3,"file":"Scrollbar.mjs","sources":["../../../../src/components/ScrollArea/ScrollAreaScrollbar/Scrollbar.tsx"],"sourcesContent":["import { forwardRef, useEffect, useRef, useState } from 'react';\nimport { useCallbackRef, useDebouncedCallback, useMergedRef } from '@raikou/hooks';\nimport { useScrollAreaContext } from '../ScrollArea.context';\nimport { Sizes } from '../ScrollArea.types';\nimport { useResizeObserver } from '../use-resize-observer';\nimport { composeEventHandlers } from '../utils';\nimport { ScrollbarContextValue, ScrollbarProvider } from './Scrollbar.context';\n\nexport interface ScrollbarPrivateProps {\n  sizes: Sizes;\n  hasThumb: boolean;\n  onThumbChange: ScrollbarContextValue['onThumbChange'];\n  onThumbPointerUp: ScrollbarContextValue['onThumbPointerUp'];\n  onThumbPointerDown: ScrollbarContextValue['onThumbPointerDown'];\n  onThumbPositionChange: ScrollbarContextValue['onThumbPositionChange'];\n  onWheelScroll: (event: WheelEvent, maxScrollPos: number) => void;\n  onDragScroll: (pointerPos: { x: number; y: number }) => void;\n  onResize: () => void;\n}\n\ninterface ScrollbarProps\n  extends ScrollbarPrivateProps,\n    Omit<React.ComponentPropsWithoutRef<'div'>, 'onResize'> {}\n\nexport const Scrollbar = forwardRef<HTMLDivElement, ScrollbarProps>((props, forwardedRef) => {\n  const {\n    sizes,\n    hasThumb,\n    onThumbChange,\n    onThumbPointerUp,\n    onThumbPointerDown,\n    onThumbPositionChange,\n    onDragScroll,\n    onWheelScroll,\n    onResize,\n    ...scrollbarProps\n  } = props;\n  const context = useScrollAreaContext();\n  const [scrollbar, setScrollbar] = useState<HTMLDivElement | null>(null);\n  const composeRefs = useMergedRef(forwardedRef, (node) => setScrollbar(node));\n  const rectRef = useRef<DOMRect | null>(null);\n  const prevWebkitUserSelectRef = useRef<string>('');\n  const { viewport } = context;\n  const maxScrollPos = sizes.content - sizes.viewport;\n  const handleWheelScroll = useCallbackRef(onWheelScroll);\n  const handleThumbPositionChange = useCallbackRef(onThumbPositionChange);\n  const handleResize = useDebouncedCallback(onResize, 10);\n\n  const handleDragScroll = (event: React.PointerEvent<HTMLElement>) => {\n    if (rectRef.current) {\n      const x = event.clientX - rectRef.current.left;\n      const y = event.clientY - rectRef.current.top;\n      onDragScroll({ x, y });\n    }\n  };\n\n  useEffect(() => {\n    const handleWheel = (event: WheelEvent) => {\n      const element = event.target as HTMLElement;\n      const isScrollbarWheel = scrollbar?.contains(element);\n      if (isScrollbarWheel) {\n        handleWheelScroll(event, maxScrollPos);\n      }\n    };\n    document.addEventListener('wheel', handleWheel, { passive: false });\n    return () => document.removeEventListener('wheel', handleWheel, { passive: false } as any);\n  }, [viewport, scrollbar, maxScrollPos, handleWheelScroll]);\n\n  useEffect(handleThumbPositionChange, [sizes, handleThumbPositionChange]);\n\n  useResizeObserver(scrollbar, handleResize);\n  useResizeObserver(context.content, handleResize);\n\n  return (\n    <ScrollbarProvider\n      value={{\n        scrollbar,\n        hasThumb,\n        onThumbChange: useCallbackRef(onThumbChange),\n        onThumbPointerUp: useCallbackRef(onThumbPointerUp),\n        onThumbPositionChange: handleThumbPositionChange,\n        onThumbPointerDown: useCallbackRef(onThumbPointerDown),\n      }}\n    >\n      <div\n        {...scrollbarProps}\n        ref={composeRefs}\n        data-raikou-scrollbar\n        style={{ position: 'absolute', ...scrollbarProps.style }}\n        onPointerDown={composeEventHandlers(props.onPointerDown, (event) => {\n          event.preventDefault();\n\n          const mainPointer = 0;\n          if (event.button === mainPointer) {\n            const element = event.target as HTMLElement;\n            element.setPointerCapture(event.pointerId);\n            rectRef.current = scrollbar!.getBoundingClientRect();\n            prevWebkitUserSelectRef.current = document.body.style.webkitUserSelect;\n            document.body.style.webkitUserSelect = 'none';\n            handleDragScroll(event);\n          }\n        })}\n        onPointerMove={composeEventHandlers(props.onPointerMove, handleDragScroll)}\n        onPointerUp={composeEventHandlers(props.onPointerUp, (event) => {\n          event.preventDefault();\n\n          const element = event.target as HTMLElement;\n          if (element.hasPointerCapture(event.pointerId)) {\n            element.releasePointerCapture(event.pointerId);\n          }\n          document.body.style.webkitUserSelect = prevWebkitUserSelectRef.current;\n          rectRef.current = null;\n        })}\n      />\n    </ScrollbarProvider>\n  );\n});\n"],"names":[],"mappings":"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"}