"use client"; import { require_react_dom } from "./chunk-MNF4PNE3.js"; import { require_jsx_runtime } from "./chunk-PLXMHLGL.js"; import { require_react } from "./chunk-7ZNOTH45.js"; import { __toESM } from "./chunk-V4OQ3NZ2.js"; // node_modules/@radix-ui/react-scroll-area/dist/index.mjs var React23 = __toESM(require_react(), 1); // node_modules/@radix-ui/react-primitive/dist/index.mjs var React3 = __toESM(require_react(), 1); var ReactDOM = __toESM(require_react_dom(), 1); // node_modules/@radix-ui/react-primitive/node_modules/@radix-ui/react-slot/dist/index.mjs var React2 = __toESM(require_react(), 1); // node_modules/@radix-ui/react-compose-refs/dist/index.mjs var React = __toESM(require_react(), 1); function setRef(ref, value) { if (typeof ref === "function") { return ref(value); } else if (ref !== null && ref !== void 0) { ref.current = value; } } function composeRefs(...refs) { return (node) => { let hasCleanup = false; const cleanups = refs.map((ref) => { const cleanup = setRef(ref, node); if (!hasCleanup && typeof cleanup == "function") { hasCleanup = true; } return cleanup; }); if (hasCleanup) { return () => { for (let i = 0; i < cleanups.length; i++) { const cleanup = cleanups[i]; if (typeof cleanup == "function") { cleanup(); } else { setRef(refs[i], null); } } }; } }; } function useComposedRefs(...refs) { return React.useCallback(composeRefs(...refs), refs); } // node_modules/@radix-ui/react-primitive/node_modules/@radix-ui/react-slot/dist/index.mjs var import_jsx_runtime = __toESM(require_jsx_runtime(), 1); function createSlot(ownerName) { const SlotClone = createSlotClone(ownerName); const Slot2 = React2.forwardRef((props, forwardedRef) => { const { children, ...slotProps } = props; const childrenArray = React2.Children.toArray(children); const slottable = childrenArray.find(isSlottable); if (slottable) { const newElement = slottable.props.children; const newChildren = childrenArray.map((child) => { if (child === slottable) { if (React2.Children.count(newElement) > 1) return React2.Children.only(null); return React2.isValidElement(newElement) ? newElement.props.children : null; } else { return child; } }); return (0, import_jsx_runtime.jsx)(SlotClone, { ...slotProps, ref: forwardedRef, children: React2.isValidElement(newElement) ? React2.cloneElement(newElement, void 0, newChildren) : null }); } return (0, import_jsx_runtime.jsx)(SlotClone, { ...slotProps, ref: forwardedRef, children }); }); Slot2.displayName = `${ownerName}.Slot`; return Slot2; } var Slot = createSlot("Slot"); function createSlotClone(ownerName) { const SlotClone = React2.forwardRef((props, forwardedRef) => { const { children, ...slotProps } = props; if (React2.isValidElement(children)) { const childrenRef = getElementRef(children); const props2 = mergeProps(slotProps, children.props); if (children.type !== React2.Fragment) { props2.ref = forwardedRef ? composeRefs(forwardedRef, childrenRef) : childrenRef; } return React2.cloneElement(children, props2); } return React2.Children.count(children) > 1 ? React2.Children.only(null) : null; }); SlotClone.displayName = `${ownerName}.SlotClone`; return SlotClone; } var SLOTTABLE_IDENTIFIER = /* @__PURE__ */ Symbol("radix.slottable"); function createSlottable(ownerName) { const Slottable2 = ({ children }) => { return (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children }); }; Slottable2.displayName = `${ownerName}.Slottable`; Slottable2.__radixId = SLOTTABLE_IDENTIFIER; return Slottable2; } var Slottable = createSlottable("Slottable"); function isSlottable(child) { return React2.isValidElement(child) && typeof child.type === "function" && "__radixId" in child.type && child.type.__radixId === SLOTTABLE_IDENTIFIER; } function mergeProps(slotProps, childProps) { const overrideProps = { ...childProps }; for (const propName in childProps) { const slotPropValue = slotProps[propName]; const childPropValue = childProps[propName]; const isHandler = /^on[A-Z]/.test(propName); if (isHandler) { if (slotPropValue && childPropValue) { overrideProps[propName] = (...args) => { const result = childPropValue(...args); slotPropValue(...args); return result; }; } else if (slotPropValue) { overrideProps[propName] = slotPropValue; } } else if (propName === "style") { overrideProps[propName] = { ...slotPropValue, ...childPropValue }; } else if (propName === "className") { overrideProps[propName] = [slotPropValue, childPropValue].filter(Boolean).join(" "); } } return { ...slotProps, ...overrideProps }; } function getElementRef(element) { let getter = Object.getOwnPropertyDescriptor(element.props, "ref")?.get; let mayWarn = getter && "isReactWarning" in getter && getter.isReactWarning; if (mayWarn) { return element.ref; } getter = Object.getOwnPropertyDescriptor(element, "ref")?.get; mayWarn = getter && "isReactWarning" in getter && getter.isReactWarning; if (mayWarn) { return element.props.ref; } return element.props.ref || element.ref; } // node_modules/@radix-ui/react-primitive/dist/index.mjs var import_jsx_runtime2 = __toESM(require_jsx_runtime(), 1); var NODES = [ "a", "button", "div", "form", "h2", "h3", "img", "input", "label", "li", "nav", "ol", "p", "select", "span", "svg", "ul" ]; var Primitive = NODES.reduce((primitive, node) => { const Slot2 = createSlot(`Primitive.${node}`); const Node = React3.forwardRef((props, forwardedRef) => { const { asChild, ...primitiveProps } = props; const Comp = asChild ? Slot2 : node; if (typeof window !== "undefined") { window[/* @__PURE__ */ Symbol.for("radix-ui")] = true; } return (0, import_jsx_runtime2.jsx)(Comp, { ...primitiveProps, ref: forwardedRef }); }); Node.displayName = `Primitive.${node}`; return { ...primitive, [node]: Node }; }, {}); // node_modules/@radix-ui/react-presence/dist/index.mjs var React22 = __toESM(require_react(), 1); // node_modules/@radix-ui/react-use-layout-effect/dist/index.mjs var React4 = __toESM(require_react(), 1); var useLayoutEffect2 = globalThis?.document ? React4.useLayoutEffect : () => { }; // node_modules/@radix-ui/react-presence/dist/index.mjs var React5 = __toESM(require_react(), 1); function useStateMachine(initialState, machine) { return React5.useReducer((state, event) => { const nextState = machine[state][event]; return nextState ?? state; }, initialState); } var Presence = (props) => { const { present, children } = props; const presence = usePresence(present); const child = typeof children === "function" ? children({ present: presence.isPresent }) : React22.Children.only(children); const ref = useComposedRefs(presence.ref, getElementRef2(child)); const forceMount = typeof children === "function"; return forceMount || presence.isPresent ? React22.cloneElement(child, { ref }) : null; }; Presence.displayName = "Presence"; function usePresence(present) { const [node, setNode] = React22.useState(); const stylesRef = React22.useRef(null); const prevPresentRef = React22.useRef(present); const prevAnimationNameRef = React22.useRef("none"); const initialState = present ? "mounted" : "unmounted"; const [state, send] = useStateMachine(initialState, { mounted: { UNMOUNT: "unmounted", ANIMATION_OUT: "unmountSuspended" }, unmountSuspended: { MOUNT: "mounted", ANIMATION_END: "unmounted" }, unmounted: { MOUNT: "mounted" } }); React22.useEffect(() => { const currentAnimationName = getAnimationName(stylesRef.current); prevAnimationNameRef.current = state === "mounted" ? currentAnimationName : "none"; }, [state]); useLayoutEffect2(() => { const styles = stylesRef.current; const wasPresent = prevPresentRef.current; const hasPresentChanged = wasPresent !== present; if (hasPresentChanged) { const prevAnimationName = prevAnimationNameRef.current; const currentAnimationName = getAnimationName(styles); if (present) { send("MOUNT"); } else if (currentAnimationName === "none" || styles?.display === "none") { send("UNMOUNT"); } else { const isAnimating = prevAnimationName !== currentAnimationName; if (wasPresent && isAnimating) { send("ANIMATION_OUT"); } else { send("UNMOUNT"); } } prevPresentRef.current = present; } }, [present, send]); useLayoutEffect2(() => { if (node) { let timeoutId; const ownerWindow = node.ownerDocument.defaultView ?? window; const handleAnimationEnd = (event) => { const currentAnimationName = getAnimationName(stylesRef.current); const isCurrentAnimation = currentAnimationName.includes(CSS.escape(event.animationName)); if (event.target === node && isCurrentAnimation) { send("ANIMATION_END"); if (!prevPresentRef.current) { const currentFillMode = node.style.animationFillMode; node.style.animationFillMode = "forwards"; timeoutId = ownerWindow.setTimeout(() => { if (node.style.animationFillMode === "forwards") { node.style.animationFillMode = currentFillMode; } }); } } }; const handleAnimationStart = (event) => { if (event.target === node) { prevAnimationNameRef.current = getAnimationName(stylesRef.current); } }; node.addEventListener("animationstart", handleAnimationStart); node.addEventListener("animationcancel", handleAnimationEnd); node.addEventListener("animationend", handleAnimationEnd); return () => { ownerWindow.clearTimeout(timeoutId); node.removeEventListener("animationstart", handleAnimationStart); node.removeEventListener("animationcancel", handleAnimationEnd); node.removeEventListener("animationend", handleAnimationEnd); }; } else { send("ANIMATION_END"); } }, [node, send]); return { isPresent: ["mounted", "unmountSuspended"].includes(state), ref: React22.useCallback((node2) => { stylesRef.current = node2 ? getComputedStyle(node2) : null; setNode(node2); }, []) }; } function getAnimationName(styles) { return styles?.animationName || "none"; } function getElementRef2(element) { let getter = Object.getOwnPropertyDescriptor(element.props, "ref")?.get; let mayWarn = getter && "isReactWarning" in getter && getter.isReactWarning; if (mayWarn) { return element.ref; } getter = Object.getOwnPropertyDescriptor(element, "ref")?.get; mayWarn = getter && "isReactWarning" in getter && getter.isReactWarning; if (mayWarn) { return element.props.ref; } return element.props.ref || element.ref; } // node_modules/@radix-ui/react-context/dist/index.mjs var React6 = __toESM(require_react(), 1); var import_jsx_runtime3 = __toESM(require_jsx_runtime(), 1); function createContextScope(scopeName, createContextScopeDeps = []) { let defaultContexts = []; function createContext3(rootComponentName, defaultContext) { const BaseContext = React6.createContext(defaultContext); const index = defaultContexts.length; defaultContexts = [...defaultContexts, defaultContext]; const Provider = (props) => { const { scope, children, ...context } = props; const Context = scope?.[scopeName]?.[index] || BaseContext; const value = React6.useMemo(() => context, Object.values(context)); return (0, import_jsx_runtime3.jsx)(Context.Provider, { value, children }); }; Provider.displayName = rootComponentName + "Provider"; function useContext22(consumerName, scope) { const Context = scope?.[scopeName]?.[index] || BaseContext; const context = React6.useContext(Context); if (context) return context; if (defaultContext !== void 0) return defaultContext; throw new Error(`\`${consumerName}\` must be used within \`${rootComponentName}\``); } return [Provider, useContext22]; } const createScope = () => { const scopeContexts = defaultContexts.map((defaultContext) => { return React6.createContext(defaultContext); }); return function useScope(scope) { const contexts = scope?.[scopeName] || scopeContexts; return React6.useMemo( () => ({ [`__scope${scopeName}`]: { ...scope, [scopeName]: contexts } }), [scope, contexts] ); }; }; createScope.scopeName = scopeName; return [createContext3, composeContextScopes(createScope, ...createContextScopeDeps)]; } function composeContextScopes(...scopes) { const baseScope = scopes[0]; if (scopes.length === 1) return baseScope; const createScope = () => { const scopeHooks = scopes.map((createScope2) => ({ useScope: createScope2(), scopeName: createScope2.scopeName })); return function useComposedScopes(overrideScopes) { const nextScopes = scopeHooks.reduce((nextScopes2, { useScope, scopeName }) => { const scopeProps = useScope(overrideScopes); const currentScope = scopeProps[`__scope${scopeName}`]; return { ...nextScopes2, ...currentScope }; }, {}); return React6.useMemo(() => ({ [`__scope${baseScope.scopeName}`]: nextScopes }), [nextScopes]); }; }; createScope.scopeName = baseScope.scopeName; return createScope; } // node_modules/@radix-ui/react-use-callback-ref/dist/index.mjs var React7 = __toESM(require_react(), 1); function useCallbackRef(callback) { const callbackRef = React7.useRef(callback); React7.useEffect(() => { callbackRef.current = callback; }); return React7.useMemo(() => (...args) => callbackRef.current?.(...args), []); } // node_modules/@radix-ui/react-direction/dist/index.mjs var React8 = __toESM(require_react(), 1); var import_jsx_runtime4 = __toESM(require_jsx_runtime(), 1); var DirectionContext = React8.createContext(void 0); function useDirection(localDir) { const globalDir = React8.useContext(DirectionContext); return localDir || globalDir || "ltr"; } // node_modules/@radix-ui/number/dist/index.mjs function clamp(value, [min, max]) { return Math.min(max, Math.max(min, value)); } // node_modules/@radix-ui/primitive/dist/index.mjs var canUseDOM = !!(typeof window !== "undefined" && window.document && window.document.createElement); function composeEventHandlers(originalEventHandler, ourEventHandler, { checkForDefaultPrevented = true } = {}) { return function handleEvent(event) { originalEventHandler?.(event); if (checkForDefaultPrevented === false || !event.defaultPrevented) { return ourEventHandler?.(event); } }; } // node_modules/@radix-ui/react-scroll-area/dist/index.mjs var React9 = __toESM(require_react(), 1); var import_jsx_runtime5 = __toESM(require_jsx_runtime(), 1); function useStateMachine2(initialState, machine) { return React9.useReducer((state, event) => { const nextState = machine[state][event]; return nextState ?? state; }, initialState); } var SCROLL_AREA_NAME = "ScrollArea"; var [createScrollAreaContext, createScrollAreaScope] = createContextScope(SCROLL_AREA_NAME); var [ScrollAreaProvider, useScrollAreaContext] = createScrollAreaContext(SCROLL_AREA_NAME); var ScrollArea = React23.forwardRef( (props, forwardedRef) => { const { __scopeScrollArea, type = "hover", dir, scrollHideDelay = 600, ...scrollAreaProps } = props; const [scrollArea, setScrollArea] = React23.useState(null); const [viewport, setViewport] = React23.useState(null); const [content, setContent] = React23.useState(null); const [scrollbarX, setScrollbarX] = React23.useState(null); const [scrollbarY, setScrollbarY] = React23.useState(null); const [cornerWidth, setCornerWidth] = React23.useState(0); const [cornerHeight, setCornerHeight] = React23.useState(0); const [scrollbarXEnabled, setScrollbarXEnabled] = React23.useState(false); const [scrollbarYEnabled, setScrollbarYEnabled] = React23.useState(false); const composedRefs = useComposedRefs(forwardedRef, (node) => setScrollArea(node)); const direction = useDirection(dir); return (0, import_jsx_runtime5.jsx)( ScrollAreaProvider, { scope: __scopeScrollArea, type, dir: direction, scrollHideDelay, scrollArea, viewport, onViewportChange: setViewport, content, onContentChange: setContent, scrollbarX, onScrollbarXChange: setScrollbarX, scrollbarXEnabled, onScrollbarXEnabledChange: setScrollbarXEnabled, scrollbarY, onScrollbarYChange: setScrollbarY, scrollbarYEnabled, onScrollbarYEnabledChange: setScrollbarYEnabled, onCornerWidthChange: setCornerWidth, onCornerHeightChange: setCornerHeight, children: (0, import_jsx_runtime5.jsx)( Primitive.div, { dir: direction, ...scrollAreaProps, ref: composedRefs, style: { position: "relative", // Pass corner sizes as CSS vars to reduce re-renders of context consumers ["--radix-scroll-area-corner-width"]: cornerWidth + "px", ["--radix-scroll-area-corner-height"]: cornerHeight + "px", ...props.style } } ) } ); } ); ScrollArea.displayName = SCROLL_AREA_NAME; var VIEWPORT_NAME = "ScrollAreaViewport"; var ScrollAreaViewport = React23.forwardRef( (props, forwardedRef) => { const { __scopeScrollArea, children, nonce, ...viewportProps } = props; const context = useScrollAreaContext(VIEWPORT_NAME, __scopeScrollArea); const ref = React23.useRef(null); const composedRefs = useComposedRefs(forwardedRef, ref, context.onViewportChange); return (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [ (0, import_jsx_runtime5.jsx)( "style", { dangerouslySetInnerHTML: { __html: `[data-radix-scroll-area-viewport]{scrollbar-width:none;-ms-overflow-style:none;-webkit-overflow-scrolling:touch;}[data-radix-scroll-area-viewport]::-webkit-scrollbar{display:none}` }, nonce } ), (0, import_jsx_runtime5.jsx)( Primitive.div, { "data-radix-scroll-area-viewport": "", ...viewportProps, ref: composedRefs, style: { /** * We don't support `visible` because the intention is to have at least one scrollbar * if this component is used and `visible` will behave like `auto` in that case * https://developer.mozilla.org/en-US/docs/Web/CSS/overflow#description * * We don't handle `auto` because the intention is for the native implementation * to be hidden if using this component. We just want to ensure the node is scrollable * so could have used either `scroll` or `auto` here. We picked `scroll` to prevent * the browser from having to work out whether to render native scrollbars or not, * we tell it to with the intention of hiding them in CSS. */ overflowX: context.scrollbarXEnabled ? "scroll" : "hidden", overflowY: context.scrollbarYEnabled ? "scroll" : "hidden", ...props.style }, children: (0, import_jsx_runtime5.jsx)("div", { ref: context.onContentChange, style: { minWidth: "100%", display: "table" }, children }) } ) ] }); } ); ScrollAreaViewport.displayName = VIEWPORT_NAME; var SCROLLBAR_NAME = "ScrollAreaScrollbar"; var ScrollAreaScrollbar = React23.forwardRef( (props, forwardedRef) => { const { forceMount, ...scrollbarProps } = props; const context = useScrollAreaContext(SCROLLBAR_NAME, props.__scopeScrollArea); const { onScrollbarXEnabledChange, onScrollbarYEnabledChange } = context; const isHorizontal = props.orientation === "horizontal"; React23.useEffect(() => { isHorizontal ? onScrollbarXEnabledChange(true) : onScrollbarYEnabledChange(true); return () => { isHorizontal ? onScrollbarXEnabledChange(false) : onScrollbarYEnabledChange(false); }; }, [isHorizontal, onScrollbarXEnabledChange, onScrollbarYEnabledChange]); return context.type === "hover" ? (0, import_jsx_runtime5.jsx)(ScrollAreaScrollbarHover, { ...scrollbarProps, ref: forwardedRef, forceMount }) : context.type === "scroll" ? (0, import_jsx_runtime5.jsx)(ScrollAreaScrollbarScroll, { ...scrollbarProps, ref: forwardedRef, forceMount }) : context.type === "auto" ? (0, import_jsx_runtime5.jsx)(ScrollAreaScrollbarAuto, { ...scrollbarProps, ref: forwardedRef, forceMount }) : context.type === "always" ? (0, import_jsx_runtime5.jsx)(ScrollAreaScrollbarVisible, { ...scrollbarProps, ref: forwardedRef }) : null; } ); ScrollAreaScrollbar.displayName = SCROLLBAR_NAME; var ScrollAreaScrollbarHover = React23.forwardRef((props, forwardedRef) => { const { forceMount, ...scrollbarProps } = props; const context = useScrollAreaContext(SCROLLBAR_NAME, props.__scopeScrollArea); const [visible, setVisible] = React23.useState(false); React23.useEffect(() => { const scrollArea = context.scrollArea; let hideTimer = 0; if (scrollArea) { const handlePointerEnter = () => { window.clearTimeout(hideTimer); setVisible(true); }; const handlePointerLeave = () => { hideTimer = window.setTimeout(() => setVisible(false), context.scrollHideDelay); }; scrollArea.addEventListener("pointerenter", handlePointerEnter); scrollArea.addEventListener("pointerleave", handlePointerLeave); return () => { window.clearTimeout(hideTimer); scrollArea.removeEventListener("pointerenter", handlePointerEnter); scrollArea.removeEventListener("pointerleave", handlePointerLeave); }; } }, [context.scrollArea, context.scrollHideDelay]); return (0, import_jsx_runtime5.jsx)(Presence, { present: forceMount || visible, children: (0, import_jsx_runtime5.jsx)( ScrollAreaScrollbarAuto, { "data-state": visible ? "visible" : "hidden", ...scrollbarProps, ref: forwardedRef } ) }); }); var ScrollAreaScrollbarScroll = React23.forwardRef((props, forwardedRef) => { const { forceMount, ...scrollbarProps } = props; const context = useScrollAreaContext(SCROLLBAR_NAME, props.__scopeScrollArea); const isHorizontal = props.orientation === "horizontal"; const debounceScrollEnd = useDebounceCallback(() => send("SCROLL_END"), 100); const [state, send] = useStateMachine2("hidden", { hidden: { SCROLL: "scrolling" }, scrolling: { SCROLL_END: "idle", POINTER_ENTER: "interacting" }, interacting: { SCROLL: "interacting", POINTER_LEAVE: "idle" }, idle: { HIDE: "hidden", SCROLL: "scrolling", POINTER_ENTER: "interacting" } }); React23.useEffect(() => { if (state === "idle") { const hideTimer = window.setTimeout(() => send("HIDE"), context.scrollHideDelay); return () => window.clearTimeout(hideTimer); } }, [state, context.scrollHideDelay, send]); React23.useEffect(() => { const viewport = context.viewport; const scrollDirection = isHorizontal ? "scrollLeft" : "scrollTop"; if (viewport) { let prevScrollPos = viewport[scrollDirection]; const handleScroll = () => { const scrollPos = viewport[scrollDirection]; const hasScrollInDirectionChanged = prevScrollPos !== scrollPos; if (hasScrollInDirectionChanged) { send("SCROLL"); debounceScrollEnd(); } prevScrollPos = scrollPos; }; viewport.addEventListener("scroll", handleScroll); return () => viewport.removeEventListener("scroll", handleScroll); } }, [context.viewport, isHorizontal, send, debounceScrollEnd]); return (0, import_jsx_runtime5.jsx)(Presence, { present: forceMount || state !== "hidden", children: (0, import_jsx_runtime5.jsx)( ScrollAreaScrollbarVisible, { "data-state": state === "hidden" ? "hidden" : "visible", ...scrollbarProps, ref: forwardedRef, onPointerEnter: composeEventHandlers(props.onPointerEnter, () => send("POINTER_ENTER")), onPointerLeave: composeEventHandlers(props.onPointerLeave, () => send("POINTER_LEAVE")) } ) }); }); var ScrollAreaScrollbarAuto = React23.forwardRef((props, forwardedRef) => { const context = useScrollAreaContext(SCROLLBAR_NAME, props.__scopeScrollArea); const { forceMount, ...scrollbarProps } = props; const [visible, setVisible] = React23.useState(false); const isHorizontal = props.orientation === "horizontal"; const handleResize = useDebounceCallback(() => { if (context.viewport) { const isOverflowX = context.viewport.offsetWidth < context.viewport.scrollWidth; const isOverflowY = context.viewport.offsetHeight < context.viewport.scrollHeight; setVisible(isHorizontal ? isOverflowX : isOverflowY); } }, 10); useResizeObserver(context.viewport, handleResize); useResizeObserver(context.content, handleResize); return (0, import_jsx_runtime5.jsx)(Presence, { present: forceMount || visible, children: (0, import_jsx_runtime5.jsx)( ScrollAreaScrollbarVisible, { "data-state": visible ? "visible" : "hidden", ...scrollbarProps, ref: forwardedRef } ) }); }); var ScrollAreaScrollbarVisible = React23.forwardRef((props, forwardedRef) => { const { orientation = "vertical", ...scrollbarProps } = props; const context = useScrollAreaContext(SCROLLBAR_NAME, props.__scopeScrollArea); const thumbRef = React23.useRef(null); const pointerOffsetRef = React23.useRef(0); const [sizes, setSizes] = React23.useState({ content: 0, viewport: 0, scrollbar: { size: 0, paddingStart: 0, paddingEnd: 0 } }); const thumbRatio = getThumbRatio(sizes.viewport, sizes.content); const commonProps = { ...scrollbarProps, sizes, onSizesChange: setSizes, hasThumb: Boolean(thumbRatio > 0 && thumbRatio < 1), onThumbChange: (thumb) => thumbRef.current = thumb, onThumbPointerUp: () => pointerOffsetRef.current = 0, onThumbPointerDown: (pointerPos) => pointerOffsetRef.current = pointerPos }; function getScrollPosition(pointerPos, dir) { return getScrollPositionFromPointer(pointerPos, pointerOffsetRef.current, sizes, dir); } if (orientation === "horizontal") { return (0, import_jsx_runtime5.jsx)( ScrollAreaScrollbarX, { ...commonProps, ref: forwardedRef, onThumbPositionChange: () => { if (context.viewport && thumbRef.current) { const scrollPos = context.viewport.scrollLeft; const offset = getThumbOffsetFromScroll(scrollPos, sizes, context.dir); thumbRef.current.style.transform = `translate3d(${offset}px, 0, 0)`; } }, onWheelScroll: (scrollPos) => { if (context.viewport) context.viewport.scrollLeft = scrollPos; }, onDragScroll: (pointerPos) => { if (context.viewport) { context.viewport.scrollLeft = getScrollPosition(pointerPos, context.dir); } } } ); } if (orientation === "vertical") { return (0, import_jsx_runtime5.jsx)( ScrollAreaScrollbarY, { ...commonProps, ref: forwardedRef, onThumbPositionChange: () => { if (context.viewport && thumbRef.current) { const scrollPos = context.viewport.scrollTop; const offset = getThumbOffsetFromScroll(scrollPos, sizes); thumbRef.current.style.transform = `translate3d(0, ${offset}px, 0)`; } }, onWheelScroll: (scrollPos) => { if (context.viewport) context.viewport.scrollTop = scrollPos; }, onDragScroll: (pointerPos) => { if (context.viewport) context.viewport.scrollTop = getScrollPosition(pointerPos); } } ); } return null; }); var ScrollAreaScrollbarX = React23.forwardRef((props, forwardedRef) => { const { sizes, onSizesChange, ...scrollbarProps } = props; const context = useScrollAreaContext(SCROLLBAR_NAME, props.__scopeScrollArea); const [computedStyle, setComputedStyle] = React23.useState(); const ref = React23.useRef(null); const composeRefs2 = useComposedRefs(forwardedRef, ref, context.onScrollbarXChange); React23.useEffect(() => { if (ref.current) setComputedStyle(getComputedStyle(ref.current)); }, [ref]); return (0, import_jsx_runtime5.jsx)( ScrollAreaScrollbarImpl, { "data-orientation": "horizontal", ...scrollbarProps, ref: composeRefs2, sizes, style: { bottom: 0, left: context.dir === "rtl" ? "var(--radix-scroll-area-corner-width)" : 0, right: context.dir === "ltr" ? "var(--radix-scroll-area-corner-width)" : 0, ["--radix-scroll-area-thumb-width"]: getThumbSize(sizes) + "px", ...props.style }, onThumbPointerDown: (pointerPos) => props.onThumbPointerDown(pointerPos.x), onDragScroll: (pointerPos) => props.onDragScroll(pointerPos.x), onWheelScroll: (event, maxScrollPos) => { if (context.viewport) { const scrollPos = context.viewport.scrollLeft + event.deltaX; props.onWheelScroll(scrollPos); if (isScrollingWithinScrollbarBounds(scrollPos, maxScrollPos)) { event.preventDefault(); } } }, onResize: () => { if (ref.current && context.viewport && computedStyle) { onSizesChange({ content: context.viewport.scrollWidth, viewport: context.viewport.offsetWidth, scrollbar: { size: ref.current.clientWidth, paddingStart: toInt(computedStyle.paddingLeft), paddingEnd: toInt(computedStyle.paddingRight) } }); } } } ); }); var ScrollAreaScrollbarY = React23.forwardRef((props, forwardedRef) => { const { sizes, onSizesChange, ...scrollbarProps } = props; const context = useScrollAreaContext(SCROLLBAR_NAME, props.__scopeScrollArea); const [computedStyle, setComputedStyle] = React23.useState(); const ref = React23.useRef(null); const composeRefs2 = useComposedRefs(forwardedRef, ref, context.onScrollbarYChange); React23.useEffect(() => { if (ref.current) setComputedStyle(getComputedStyle(ref.current)); }, [ref]); return (0, import_jsx_runtime5.jsx)( ScrollAreaScrollbarImpl, { "data-orientation": "vertical", ...scrollbarProps, ref: composeRefs2, sizes, style: { top: 0, right: context.dir === "ltr" ? 0 : void 0, left: context.dir === "rtl" ? 0 : void 0, bottom: "var(--radix-scroll-area-corner-height)", ["--radix-scroll-area-thumb-height"]: getThumbSize(sizes) + "px", ...props.style }, onThumbPointerDown: (pointerPos) => props.onThumbPointerDown(pointerPos.y), onDragScroll: (pointerPos) => props.onDragScroll(pointerPos.y), onWheelScroll: (event, maxScrollPos) => { if (context.viewport) { const scrollPos = context.viewport.scrollTop + event.deltaY; props.onWheelScroll(scrollPos); if (isScrollingWithinScrollbarBounds(scrollPos, maxScrollPos)) { event.preventDefault(); } } }, onResize: () => { if (ref.current && context.viewport && computedStyle) { onSizesChange({ content: context.viewport.scrollHeight, viewport: context.viewport.offsetHeight, scrollbar: { size: ref.current.clientHeight, paddingStart: toInt(computedStyle.paddingTop), paddingEnd: toInt(computedStyle.paddingBottom) } }); } } } ); }); var [ScrollbarProvider, useScrollbarContext] = createScrollAreaContext(SCROLLBAR_NAME); var ScrollAreaScrollbarImpl = React23.forwardRef((props, forwardedRef) => { const { __scopeScrollArea, sizes, hasThumb, onThumbChange, onThumbPointerUp, onThumbPointerDown, onThumbPositionChange, onDragScroll, onWheelScroll, onResize, ...scrollbarProps } = props; const context = useScrollAreaContext(SCROLLBAR_NAME, __scopeScrollArea); const [scrollbar, setScrollbar] = React23.useState(null); const composeRefs2 = useComposedRefs(forwardedRef, (node) => setScrollbar(node)); const rectRef = React23.useRef(null); const prevWebkitUserSelectRef = React23.useRef(""); const viewport = context.viewport; const maxScrollPos = sizes.content - sizes.viewport; const handleWheelScroll = useCallbackRef(onWheelScroll); const handleThumbPositionChange = useCallbackRef(onThumbPositionChange); const handleResize = useDebounceCallback(onResize, 10); function handleDragScroll(event) { if (rectRef.current) { const x = event.clientX - rectRef.current.left; const y = event.clientY - rectRef.current.top; onDragScroll({ x, y }); } } React23.useEffect(() => { const handleWheel = (event) => { const element = event.target; const isScrollbarWheel = scrollbar?.contains(element); if (isScrollbarWheel) handleWheelScroll(event, maxScrollPos); }; document.addEventListener("wheel", handleWheel, { passive: false }); return () => document.removeEventListener("wheel", handleWheel, { passive: false }); }, [viewport, scrollbar, maxScrollPos, handleWheelScroll]); React23.useEffect(handleThumbPositionChange, [sizes, handleThumbPositionChange]); useResizeObserver(scrollbar, handleResize); useResizeObserver(context.content, handleResize); return (0, import_jsx_runtime5.jsx)( ScrollbarProvider, { scope: __scopeScrollArea, scrollbar, hasThumb, onThumbChange: useCallbackRef(onThumbChange), onThumbPointerUp: useCallbackRef(onThumbPointerUp), onThumbPositionChange: handleThumbPositionChange, onThumbPointerDown: useCallbackRef(onThumbPointerDown), children: (0, import_jsx_runtime5.jsx)( Primitive.div, { ...scrollbarProps, ref: composeRefs2, style: { position: "absolute", ...scrollbarProps.style }, onPointerDown: composeEventHandlers(props.onPointerDown, (event) => { const mainPointer = 0; if (event.button === mainPointer) { const element = event.target; element.setPointerCapture(event.pointerId); rectRef.current = scrollbar.getBoundingClientRect(); prevWebkitUserSelectRef.current = document.body.style.webkitUserSelect; document.body.style.webkitUserSelect = "none"; if (context.viewport) context.viewport.style.scrollBehavior = "auto"; handleDragScroll(event); } }), onPointerMove: composeEventHandlers(props.onPointerMove, handleDragScroll), onPointerUp: composeEventHandlers(props.onPointerUp, (event) => { const element = event.target; if (element.hasPointerCapture(event.pointerId)) { element.releasePointerCapture(event.pointerId); } document.body.style.webkitUserSelect = prevWebkitUserSelectRef.current; if (context.viewport) context.viewport.style.scrollBehavior = ""; rectRef.current = null; }) } ) } ); }); var THUMB_NAME = "ScrollAreaThumb"; var ScrollAreaThumb = React23.forwardRef( (props, forwardedRef) => { const { forceMount, ...thumbProps } = props; const scrollbarContext = useScrollbarContext(THUMB_NAME, props.__scopeScrollArea); return (0, import_jsx_runtime5.jsx)(Presence, { present: forceMount || scrollbarContext.hasThumb, children: (0, import_jsx_runtime5.jsx)(ScrollAreaThumbImpl, { ref: forwardedRef, ...thumbProps }) }); } ); var ScrollAreaThumbImpl = React23.forwardRef( (props, forwardedRef) => { const { __scopeScrollArea, style, ...thumbProps } = props; const scrollAreaContext = useScrollAreaContext(THUMB_NAME, __scopeScrollArea); const scrollbarContext = useScrollbarContext(THUMB_NAME, __scopeScrollArea); const { onThumbPositionChange } = scrollbarContext; const composedRef = useComposedRefs( forwardedRef, (node) => scrollbarContext.onThumbChange(node) ); const removeUnlinkedScrollListenerRef = React23.useRef(void 0); const debounceScrollEnd = useDebounceCallback(() => { if (removeUnlinkedScrollListenerRef.current) { removeUnlinkedScrollListenerRef.current(); removeUnlinkedScrollListenerRef.current = void 0; } }, 100); React23.useEffect(() => { const viewport = scrollAreaContext.viewport; if (viewport) { const handleScroll = () => { debounceScrollEnd(); if (!removeUnlinkedScrollListenerRef.current) { const listener = addUnlinkedScrollListener(viewport, onThumbPositionChange); removeUnlinkedScrollListenerRef.current = listener; onThumbPositionChange(); } }; onThumbPositionChange(); viewport.addEventListener("scroll", handleScroll); return () => viewport.removeEventListener("scroll", handleScroll); } }, [scrollAreaContext.viewport, debounceScrollEnd, onThumbPositionChange]); return (0, import_jsx_runtime5.jsx)( Primitive.div, { "data-state": scrollbarContext.hasThumb ? "visible" : "hidden", ...thumbProps, ref: composedRef, style: { width: "var(--radix-scroll-area-thumb-width)", height: "var(--radix-scroll-area-thumb-height)", ...style }, onPointerDownCapture: composeEventHandlers(props.onPointerDownCapture, (event) => { const thumb = event.target; const thumbRect = thumb.getBoundingClientRect(); const x = event.clientX - thumbRect.left; const y = event.clientY - thumbRect.top; scrollbarContext.onThumbPointerDown({ x, y }); }), onPointerUp: composeEventHandlers(props.onPointerUp, scrollbarContext.onThumbPointerUp) } ); } ); ScrollAreaThumb.displayName = THUMB_NAME; var CORNER_NAME = "ScrollAreaCorner"; var ScrollAreaCorner = React23.forwardRef( (props, forwardedRef) => { const context = useScrollAreaContext(CORNER_NAME, props.__scopeScrollArea); const hasBothScrollbarsVisible = Boolean(context.scrollbarX && context.scrollbarY); const hasCorner = context.type !== "scroll" && hasBothScrollbarsVisible; return hasCorner ? (0, import_jsx_runtime5.jsx)(ScrollAreaCornerImpl, { ...props, ref: forwardedRef }) : null; } ); ScrollAreaCorner.displayName = CORNER_NAME; var ScrollAreaCornerImpl = React23.forwardRef((props, forwardedRef) => { const { __scopeScrollArea, ...cornerProps } = props; const context = useScrollAreaContext(CORNER_NAME, __scopeScrollArea); const [width, setWidth] = React23.useState(0); const [height, setHeight] = React23.useState(0); const hasSize = Boolean(width && height); useResizeObserver(context.scrollbarX, () => { const height2 = context.scrollbarX?.offsetHeight || 0; context.onCornerHeightChange(height2); setHeight(height2); }); useResizeObserver(context.scrollbarY, () => { const width2 = context.scrollbarY?.offsetWidth || 0; context.onCornerWidthChange(width2); setWidth(width2); }); return hasSize ? (0, import_jsx_runtime5.jsx)( Primitive.div, { ...cornerProps, ref: forwardedRef, style: { width, height, position: "absolute", right: context.dir === "ltr" ? 0 : void 0, left: context.dir === "rtl" ? 0 : void 0, bottom: 0, ...props.style } } ) : null; }); function toInt(value) { return value ? parseInt(value, 10) : 0; } function getThumbRatio(viewportSize, contentSize) { const ratio = viewportSize / contentSize; return isNaN(ratio) ? 0 : ratio; } function getThumbSize(sizes) { const ratio = getThumbRatio(sizes.viewport, sizes.content); const scrollbarPadding = sizes.scrollbar.paddingStart + sizes.scrollbar.paddingEnd; const thumbSize = (sizes.scrollbar.size - scrollbarPadding) * ratio; return Math.max(thumbSize, 18); } function getScrollPositionFromPointer(pointerPos, pointerOffset, sizes, dir = "ltr") { const thumbSizePx = getThumbSize(sizes); const thumbCenter = thumbSizePx / 2; const offset = pointerOffset || thumbCenter; const thumbOffsetFromEnd = thumbSizePx - offset; const minPointerPos = sizes.scrollbar.paddingStart + offset; const maxPointerPos = sizes.scrollbar.size - sizes.scrollbar.paddingEnd - thumbOffsetFromEnd; const maxScrollPos = sizes.content - sizes.viewport; const scrollRange = dir === "ltr" ? [0, maxScrollPos] : [maxScrollPos * -1, 0]; const interpolate = linearScale([minPointerPos, maxPointerPos], scrollRange); return interpolate(pointerPos); } function getThumbOffsetFromScroll(scrollPos, sizes, dir = "ltr") { const thumbSizePx = getThumbSize(sizes); const scrollbarPadding = sizes.scrollbar.paddingStart + sizes.scrollbar.paddingEnd; const scrollbar = sizes.scrollbar.size - scrollbarPadding; const maxScrollPos = sizes.content - sizes.viewport; const maxThumbPos = scrollbar - thumbSizePx; const scrollClampRange = dir === "ltr" ? [0, maxScrollPos] : [maxScrollPos * -1, 0]; const scrollWithoutMomentum = clamp(scrollPos, scrollClampRange); const interpolate = linearScale([0, maxScrollPos], [0, maxThumbPos]); return interpolate(scrollWithoutMomentum); } function linearScale(input, output) { return (value) => { if (input[0] === input[1] || output[0] === output[1]) return output[0]; const ratio = (output[1] - output[0]) / (input[1] - input[0]); return output[0] + ratio * (value - input[0]); }; } function isScrollingWithinScrollbarBounds(scrollPos, maxScrollPos) { return scrollPos > 0 && scrollPos < maxScrollPos; } var addUnlinkedScrollListener = (node, handler = () => { }) => { let prevPosition = { left: node.scrollLeft, top: node.scrollTop }; let rAF = 0; (function loop() { const position = { left: node.scrollLeft, top: node.scrollTop }; const isHorizontalScroll = prevPosition.left !== position.left; const isVerticalScroll = prevPosition.top !== position.top; if (isHorizontalScroll || isVerticalScroll) handler(); prevPosition = position; rAF = window.requestAnimationFrame(loop); })(); return () => window.cancelAnimationFrame(rAF); }; function useDebounceCallback(callback, delay) { const handleCallback = useCallbackRef(callback); const debounceTimerRef = React23.useRef(0); React23.useEffect(() => () => window.clearTimeout(debounceTimerRef.current), []); return React23.useCallback(() => { window.clearTimeout(debounceTimerRef.current); debounceTimerRef.current = window.setTimeout(handleCallback, delay); }, [handleCallback, delay]); } function useResizeObserver(element, onResize) { const handleResize = useCallbackRef(onResize); useLayoutEffect2(() => { let rAF = 0; if (element) { const resizeObserver = new ResizeObserver(() => { cancelAnimationFrame(rAF); rAF = window.requestAnimationFrame(handleResize); }); resizeObserver.observe(element); return () => { window.cancelAnimationFrame(rAF); resizeObserver.unobserve(element); }; } }, [element, handleResize]); } var Root = ScrollArea; var Viewport = ScrollAreaViewport; var Scrollbar = ScrollAreaScrollbar; var Thumb = ScrollAreaThumb; var Corner = ScrollAreaCorner; export { Corner, Root, ScrollArea, ScrollAreaCorner, ScrollAreaScrollbar, ScrollAreaThumb, ScrollAreaViewport, Scrollbar, Thumb, Viewport, createScrollAreaScope }; //# sourceMappingURL=@radix-ui_react-scroll-area.js.map