UNPKG

@lobehub/ui

Version:

Lobe UI is an open-source UI component library for building AIGC web apps

82 lines (80 loc) • 2.64 kB
"use client"; import { ScrollAreaRoot, ScrollAreaScrollbar, ScrollAreaThumb, ScrollAreaViewport } from "../ScrollArea/atoms.mjs"; import { Children, cloneElement, useCallback, useEffect, useRef } from "react"; import { jsx, jsxs } from "react/jsx-runtime"; import { createStaticStyles, cx } from "antd-style"; import { useMergeRefs } from "react-merge-refs"; import { Virtualizer } from "virtua"; //#region src/base-ui/virtual/VirtualScrollArea.tsx const styles = createStaticStyles(({ css }) => ({ root: css` display: flex; flex: 1; flex-direction: column; min-height: 0; margin-inline: calc(-1 * var(--lobe-virtual-scroll-inset, 0px)); `, viewport: css` flex: 1; height: auto; min-height: 0; padding-inline: var(--lobe-virtual-scroll-inset, 0); ` })); const INITIAL_ROW_COUNT = 20; const VirtualScrollArea = ({ children, className, itemSize, keepMounted, viewport, viewportProps, virtualizerRef, ...rest }) => { const viewportRef = useRef(null); const mergedViewportRef = useMergeRefs([viewportRef, viewportProps?.ref]); const list = /* @__PURE__ */ jsx(Virtualizer, { itemSize, keepMounted, ref: virtualizerRef, scrollRef: viewportRef, ssrCount: Math.min(INITIAL_ROW_COUNT, Children.count(children)), children }); const viewportElement = /* @__PURE__ */ jsx(ScrollAreaViewport, { tabIndex: -1, ...viewportProps, className: cx(styles.viewport, viewportProps?.className), ref: mergedViewportRef }); return /* @__PURE__ */ jsxs(ScrollAreaRoot, { "data-virtual": "", ...rest, className: cx(styles.root, className), children: [cloneElement(viewport ?? viewportElement, { children: list, ...viewport && { render: viewportElement } }), /* @__PURE__ */ jsx(ScrollAreaScrollbar, { children: /* @__PURE__ */ jsx(ScrollAreaThumb, {}) })] }); }; VirtualScrollArea.displayName = "VirtualScrollArea"; function usePointerScrollGuard() { const pointerScrollRef = useRef(false); const timeoutRef = useRef(null); const markPointerScroll = useCallback(() => { pointerScrollRef.current = true; if (timeoutRef.current) clearTimeout(timeoutRef.current); timeoutRef.current = setTimeout(() => { pointerScrollRef.current = false; }, 120); }, []); useEffect(() => { return () => { if (timeoutRef.current) clearTimeout(timeoutRef.current); }; }, []); return { markPointerScroll, pointerScrollRef, scrollGuardProps: { onPointerDown: markPointerScroll, onTouchMove: markPointerScroll, onWheel: markPointerScroll } }; } //#endregion export { VirtualScrollArea, usePointerScrollGuard }; //# sourceMappingURL=VirtualScrollArea.mjs.map