Files
terminal/web/node_modules/.vite/deps/@radix-ui_react-scroll-area.js
T

1142 lines
44 KiB
JavaScript

"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