UNPKG

@mantine/core

Version:

React components library focused on usability, accessibility and developer experience

88 lines (87 loc) 3.48 kB
"use client"; import { useScrollAreaContext } from "../ScrollArea.context.mjs"; import { useResizeObserver } from "../use-resize-observer.mjs"; import { composeEventHandlers } from "../utils/compose-event-handlers.mjs"; import { ScrollbarProvider } from "./Scrollbar.context.mjs"; import { useEffect, useEffectEvent, useRef, useState } from "react"; import { useCallbackRef, useDebouncedCallback, useMergedRef } from "@mantine/hooks"; import { jsx } from "react/jsx-runtime"; //#region packages/@mantine/core/src/components/ScrollArea/ScrollAreaScrollbar/Scrollbar.tsx function Scrollbar(props) { const { sizes, hasThumb, onThumbChange, onThumbPointerUp, onThumbPointerDown, onThumbPositionChange, onDragScroll, onWheelScroll, onResize, ref, ...scrollbarProps } = props; const context = useScrollAreaContext(); const [scrollbar, setScrollbar] = useState(null); const composeRefs = useMergedRef(ref, (node) => setScrollbar(node)); const rectRef = useRef(null); const prevWebkitUserSelectRef = useRef(""); const { viewport } = context; const maxScrollPos = sizes.content - sizes.viewport; const handleWheelScroll = useEffectEvent(onWheelScroll); const handleThumbPositionChange = useCallbackRef(onThumbPositionChange); const handleResize = useDebouncedCallback(onResize, 10); const handleDragScroll = (event) => { if (rectRef.current) onDragScroll({ x: event.clientX - rectRef.current.left, y: event.clientY - rectRef.current.top }); }; useEffect(() => { const handleWheel = (event) => { const element = event.target; if (scrollbar?.contains(element)) handleWheelScroll(event, maxScrollPos); }; document.addEventListener("wheel", handleWheel, { passive: false }); return () => document.removeEventListener("wheel", handleWheel, { passive: false }); }, [ viewport, scrollbar, maxScrollPos ]); useEffect(handleThumbPositionChange, [sizes, handleThumbPositionChange]); useResizeObserver(scrollbar, handleResize); useResizeObserver(context.content, handleResize); return /* @__PURE__ */ jsx(ScrollbarProvider, { value: { scrollbar, hasThumb, onThumbChange: useCallbackRef(onThumbChange), onThumbPointerUp: useCallbackRef(onThumbPointerUp), onThumbPositionChange: handleThumbPositionChange, onThumbPointerDown: useCallbackRef(onThumbPointerDown) }, children: /* @__PURE__ */ jsx("div", { ...scrollbarProps, ref: composeRefs, "data-mantine-scrollbar": true, style: { position: "absolute", ...scrollbarProps.style }, onPointerDown: composeEventHandlers(props.onPointerDown, (event) => { event.preventDefault(); if (event.button === 0) { event.target.setPointerCapture(event.pointerId); rectRef.current = scrollbar.getBoundingClientRect(); prevWebkitUserSelectRef.current = document.body.style.webkitUserSelect; document.body.style.webkitUserSelect = "none"; handleDragScroll(event); } }), onPointerMove: composeEventHandlers(props.onPointerMove, handleDragScroll), onPointerUp: composeEventHandlers(props.onPointerUp, (event) => { const element = event.target; if (element.hasPointerCapture(event.pointerId)) { event.preventDefault(); element.releasePointerCapture(event.pointerId); } }), onLostPointerCapture: () => { document.body.style.webkitUserSelect = prevWebkitUserSelectRef.current; rectRef.current = null; } }) }); } //#endregion export { Scrollbar }; //# sourceMappingURL=Scrollbar.mjs.map