1142 lines
44 KiB
JavaScript
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
|