Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

rc-virtual-list

Package Overview
Dependencies
Maintainers
2
Versions
128
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

rc-virtual-list - npm Package Compare versions

Comparing version 3.5.3 to 3.6.0

es/utils/scrollbarUtil.d.ts

5

es/Filler.d.ts

@@ -8,6 +8,9 @@ import * as React from 'react';

/** Set offset of visible items. Should be the top of start item position */
offset?: number;
offsetY?: number;
offsetX?: number;
scrollWidth?: number;
children: React.ReactNode;
onInnerResize?: () => void;
innerProps?: InnerProps;
rtl: boolean;
}

@@ -14,0 +17,0 @@ /**

13

es/Filler.js

@@ -12,7 +12,10 @@ import _extends from "@babel/runtime/helpers/esm/extends";

var height = _ref.height,
offset = _ref.offset,
offsetY = _ref.offsetY,
offsetX = _ref.offsetX,
scrollWidth = _ref.scrollWidth,
children = _ref.children,
prefixCls = _ref.prefixCls,
onInnerResize = _ref.onInnerResize,
innerProps = _ref.innerProps;
innerProps = _ref.innerProps,
rtl = _ref.rtl;
var outerStyle = {};

@@ -23,5 +26,7 @@ var innerStyle = {

};
if (offset !== undefined) {
if (offsetY !== undefined) {
outerStyle = {
height: height,
width: scrollWidth,
minWidth: '100%',
position: 'relative',

@@ -31,3 +36,3 @@ overflow: 'hidden'

innerStyle = _objectSpread(_objectSpread({}, innerStyle), {}, {
transform: "translateY(".concat(offset, "px)"),
transform: "translate(".concat(rtl ? offsetX : -offsetX, "px, ").concat(offsetY, "px)"),
position: 'absolute',

@@ -34,0 +39,0 @@ left: 0,

interface FireFoxDOMMouseScrollEvent {
detail: number;
preventDefault: Function;
preventDefault: VoidFunction;
}
export default function useFrameWheel(inVirtual: boolean, isScrollAtTop: boolean, isScrollAtBottom: boolean, onWheelDelta: (offset: number) => void): [(e: WheelEvent) => void, (e: FireFoxDOMMouseScrollEvent) => void];
export default function useFrameWheel(inVirtual: boolean, isScrollAtTop: boolean, isScrollAtBottom: boolean, horizontalScroll: boolean,
/***
* Return `true` when you need to prevent default event
*/
onWheelDelta: (offset: number, horizontal?: boolean) => void): [(e: WheelEvent) => void, (e: FireFoxDOMMouseScrollEvent) => void];
export {};

@@ -5,3 +5,7 @@ import { useRef } from 'react';

import useOriginScroll from './useOriginScroll';
export default function useFrameWheel(inVirtual, isScrollAtTop, isScrollAtBottom, onWheelDelta) {
export default function useFrameWheel(inVirtual, isScrollAtTop, isScrollAtBottom, horizontalScroll,
/***
* Return `true` when you need to prevent default event
*/
onWheelDelta) {
var offsetRef = useRef(0);

@@ -14,4 +18,3 @@ var nextFrameRef = useRef(null);

var originScroll = useOriginScroll(isScrollAtTop, isScrollAtBottom);
function onWheel(event) {
if (!inVirtual) return;
function onWheelY(event) {
raf.cancel(nextFrameRef.current);

@@ -35,2 +38,32 @@ var deltaY = event.deltaY;

}
function onWheelX(event) {
var deltaX = event.deltaX;
onWheelDelta(deltaX, true);
if (!isFF) {
event.preventDefault();
}
}
// Check for which direction does wheel do
var wheelDirectionRef = useRef(null);
var wheelDirectionCleanRef = useRef(null);
function onWheel(event) {
if (!inVirtual) return;
// Wait for 2 frame to clean direction
raf.cancel(wheelDirectionCleanRef.current);
wheelDirectionCleanRef.current = raf(function () {
wheelDirectionRef.current = null;
}, 2);
var deltaX = event.deltaX,
deltaY = event.deltaY;
var absX = Math.abs(deltaX);
var absY = Math.abs(deltaY);
if (wheelDirectionRef.current === null) {
wheelDirectionRef.current = horizontalScroll && absX > absY ? 'x' : 'y';
}
if (wheelDirectionRef.current === 'x') {
onWheelX(event);
} else {
onWheelY(event);
}
}
// A patch for firefox

@@ -37,0 +70,0 @@ function onFireFoxScroll(event) {

@@ -32,2 +32,8 @@ import * as React from 'react';

direction?: ScrollBarDirectionType;
/**
* By default `scrollWidth` is same as container.
* When set this, it will show the horizontal scrollbar and
* `scrollWidth` will be used as the real width instead of container width.
*/
scrollWidth?: number;
onScroll?: React.UIEventHandler<HTMLElement>;

@@ -34,0 +40,0 @@ /** Trigger when render list item changed */

import _extends from "@babel/runtime/helpers/esm/extends";
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
var _excluded = ["prefixCls", "className", "height", "itemHeight", "fullHeight", "style", "data", "children", "itemKey", "virtual", "direction", "component", "onScroll", "onVisibleChange", "innerProps"];
var _excluded = ["prefixCls", "className", "height", "itemHeight", "fullHeight", "style", "data", "children", "itemKey", "virtual", "direction", "scrollWidth", "component", "onScroll", "onVisibleChange", "innerProps"];
import * as React from 'react';
import { useRef, useState } from 'react';
import classNames from 'classnames';
import ResizeObserver from 'rc-resize-observer';
import Filler from './Filler';

@@ -20,2 +21,4 @@ import ScrollBar from './ScrollBar';

import useLayoutEffect from "rc-util/es/hooks/useLayoutEffect";
import { getSpinSize } from './utils/scrollbarUtil';
import { useEvent } from 'rc-util';
var EMPTY_DATA = [];

@@ -40,2 +43,3 @@ var ScrollStyle = {

direction = props.direction,
scrollWidth = props.scrollWidth,
_props$component = props.component,

@@ -50,16 +54,27 @@ Component = _props$component === void 0 ? 'div' : _props$component,

var inVirtual = useVirtual && data && itemHeight * data.length > height;
var _useState = useState(0),
_useState2 = _slicedToArray(_useState, 2),
scrollTop = _useState2[0],
setScrollTop = _useState2[1];
var _useState3 = useState(false),
_useState4 = _slicedToArray(_useState3, 2),
scrollMoving = _useState4[0],
setScrollMoving = _useState4[1];
var mergedClassName = classNames(prefixCls, _defineProperty({}, "".concat(prefixCls, "-rtl"), direction === 'rtl'), className);
var isRTL = direction === 'rtl';
var mergedClassName = classNames(prefixCls, _defineProperty({}, "".concat(prefixCls, "-rtl"), isRTL), className);
var mergedData = data || EMPTY_DATA;
var componentRef = useRef();
var fillerInnerRef = useRef();
var scrollBarRef = useRef(); // Hack on scrollbar to enable flash call
// =============================== Item Key ===============================
var _useState = useState(0),
_useState2 = _slicedToArray(_useState, 2),
offsetTop = _useState2[0],
setOffsetTop = _useState2[1];
var _useState3 = useState(0),
_useState4 = _slicedToArray(_useState3, 2),
offsetLeft = _useState4[0],
setOffsetLeft = _useState4[1];
var _useState5 = useState(false),
_useState6 = _slicedToArray(_useState5, 2),
scrollMoving = _useState6[0],
setScrollMoving = _useState6[1];
var onScrollbarStartMove = function onScrollbarStartMove() {
setScrollMoving(true);
};
var onScrollbarStopMove = function onScrollbarStopMove() {
setScrollMoving(false);
};
// =============================== Item Key ===============================
var getKey = React.useCallback(function (item) {

@@ -76,3 +91,3 @@ if (typeof itemKey === 'function') {

function syncScrollTop(newTop) {
setScrollTop(function (origin) {
setOffsetTop(function (origin) {
var value;

@@ -138,3 +153,3 @@ if (typeof newTop === 'function') {

// Check item top in the range
if (currentItemBottom >= scrollTop && startIndex === undefined) {
if (currentItemBottom >= offsetTop && startIndex === undefined) {
startIndex = i;

@@ -144,3 +159,3 @@ startOffset = itemTop;

// Check item bottom in the range. We will render additional one item for motion usage
if (currentItemBottom > scrollTop + height && endIndex === undefined) {
if (currentItemBottom > offsetTop + height && endIndex === undefined) {
endIndex = i;

@@ -167,3 +182,3 @@ }

};
}, [inVirtual, useVirtual, scrollTop, mergedData, heightUpdatedMark, height]),
}, [inVirtual, useVirtual, offsetTop, mergedData, heightUpdatedMark, height]),
scrollHeight = _React$useMemo.scrollHeight,

@@ -175,2 +190,22 @@ start = _React$useMemo.start,

rangeRef.current.end = end;
// ================================= Size =================================
var _React$useState = React.useState({
width: 0,
height: height
}),
_React$useState2 = _slicedToArray(_React$useState, 2),
size = _React$useState2[0],
setSize = _React$useState2[1];
var onHolderResize = function onHolderResize(sizeInfo) {
setSize(sizeInfo);
};
// Hack on scrollbar to enable flash call
var verticalScrollBarRef = useRef();
var horizontalScrollBarRef = useRef();
var horizontalScrollBarSpinSize = React.useMemo(function () {
return getSpinSize(size.width, scrollWidth);
}, [size.width, scrollWidth]);
var verticalScrollBarSpinSize = React.useMemo(function () {
return getSpinSize(size.height, scrollHeight);
}, [size.height, scrollHeight]);
// =============================== In Range ===============================

@@ -188,9 +223,13 @@ var maxScrollHeight = scrollHeight - height;

}
var isScrollAtTop = scrollTop <= 0;
var isScrollAtBottom = scrollTop >= maxScrollHeight;
var isScrollAtTop = offsetTop <= 0;
var isScrollAtBottom = offsetTop >= maxScrollHeight;
var originScroll = useOriginScroll(isScrollAtTop, isScrollAtBottom);
// ================================ Scroll ================================
function onScrollBar(newScrollTop) {
var newTop = newScrollTop;
syncScrollTop(newTop);
function onScrollBar(newScrollOffset, horizontal) {
var newOffset = newScrollOffset;
if (horizontal) {
setOffsetLeft(newOffset);
} else {
syncScrollTop(newOffset);
}
}

@@ -200,3 +239,3 @@ // When data size reduce. It may trigger native scroll event back to fit scroll position

var newScrollTop = e.currentTarget.scrollTop;
if (newScrollTop !== scrollTop) {
if (newScrollTop !== offsetTop) {
syncScrollTop(newScrollTop);

@@ -207,9 +246,21 @@ }

}
// Since this added in global,should use ref to keep update
var _useFrameWheel = useFrameWheel(useVirtual, isScrollAtTop, isScrollAtBottom, function (offsetY) {
var onWheelDelta = useEvent(function (offsetXY, fromHorizontal) {
if (fromHorizontal) {
// Horizontal scroll no need sync virtual position
setOffsetLeft(function (left) {
var newLeft = left + offsetXY;
var max = scrollWidth - size.width;
newLeft = Math.max(newLeft, 0);
newLeft = Math.min(newLeft, max);
return newLeft;
});
} else {
syncScrollTop(function (top) {
var newTop = top + offsetY;
var newTop = top + offsetXY;
return newTop;
});
}),
}
});
// Since this added in global,should use ref to keep update
var _useFrameWheel = useFrameWheel(useVirtual, isScrollAtTop, isScrollAtBottom, !!scrollWidth, onWheelDelta),
_useFrameWheel2 = _slicedToArray(_useFrameWheel, 2),

@@ -236,18 +287,19 @@ onRawWheel = _useFrameWheel2[0],

}
componentRef.current.addEventListener('wheel', onRawWheel);
componentRef.current.addEventListener('DOMMouseScroll', onFireFoxScroll);
componentRef.current.addEventListener('MozMousePixelScroll', onMozMousePixelScroll);
var componentEle = componentRef.current;
componentEle.addEventListener('wheel', onRawWheel);
componentEle.addEventListener('DOMMouseScroll', onFireFoxScroll);
componentEle.addEventListener('MozMousePixelScroll', onMozMousePixelScroll);
return function () {
if (componentRef.current) {
componentRef.current.removeEventListener('wheel', onRawWheel);
componentRef.current.removeEventListener('DOMMouseScroll', onFireFoxScroll);
componentRef.current.removeEventListener('MozMousePixelScroll', onMozMousePixelScroll);
}
componentEle.removeEventListener('wheel', onRawWheel);
componentEle.removeEventListener('DOMMouseScroll', onFireFoxScroll);
componentEle.removeEventListener('MozMousePixelScroll', onMozMousePixelScroll);
};
}, [useVirtual]);
// ================================= Ref ==================================
var scrollTo = useScrollTo(componentRef, mergedData, heights, itemHeight, getKey, collectHeight, syncScrollTop, function () {
var _scrollBarRef$current;
(_scrollBarRef$current = scrollBarRef.current) === null || _scrollBarRef$current === void 0 ? void 0 : _scrollBarRef$current.delayHidden();
});
var delayHideScrollBar = function delayHideScrollBar() {
var _verticalScrollBarRef, _horizontalScrollBarR;
(_verticalScrollBarRef = verticalScrollBarRef.current) === null || _verticalScrollBarRef === void 0 ? void 0 : _verticalScrollBarRef.delayHidden();
(_horizontalScrollBarR = horizontalScrollBarRef.current) === null || _horizontalScrollBarR === void 0 ? void 0 : _horizontalScrollBarR.delayHidden();
};
var scrollTo = useScrollTo(componentRef, mergedData, heights, itemHeight, getKey, collectHeight, syncScrollTop, delayHideScrollBar);
React.useImperativeHandle(ref, function () {

@@ -273,2 +325,5 @@ return {

componentStyle.overflowY = 'hidden';
if (scrollWidth) {
componentStyle.overflowX = 'hidden';
}
if (scrollMoving) {

@@ -279,2 +334,6 @@ componentStyle.pointerEvents = 'none';

}
var containerProps = {};
if (isRTL) {
containerProps.dir = 'rtl';
}
return /*#__PURE__*/React.createElement("div", _extends({

@@ -285,29 +344,43 @@ style: _objectSpread(_objectSpread({}, style), {}, {

className: mergedClassName
}, restProps), /*#__PURE__*/React.createElement(Component, {
}, containerProps, restProps), /*#__PURE__*/React.createElement(ResizeObserver, {
onResize: onHolderResize
}, /*#__PURE__*/React.createElement(Component, {
className: "".concat(prefixCls, "-holder"),
style: componentStyle,
ref: componentRef,
onScroll: onFallbackScroll
onScroll: onFallbackScroll,
onMouseEnter: delayHideScrollBar
}, /*#__PURE__*/React.createElement(Filler, {
prefixCls: prefixCls,
height: scrollHeight,
offset: offset,
offsetX: offsetLeft,
offsetY: offset,
scrollWidth: scrollWidth,
onInnerResize: collectHeight,
ref: fillerInnerRef,
innerProps: innerProps
}, listChildren)), useVirtual && /*#__PURE__*/React.createElement(ScrollBar, {
ref: scrollBarRef,
innerProps: innerProps,
rtl: isRTL
}, listChildren))), useVirtual && scrollHeight > height && /*#__PURE__*/React.createElement(ScrollBar, {
ref: verticalScrollBarRef,
prefixCls: prefixCls,
scrollTop: scrollTop,
height: height,
scrollHeight: scrollHeight,
count: mergedData.length,
direction: direction,
scrollOffset: offsetTop,
scrollRange: scrollHeight,
rtl: isRTL,
onScroll: onScrollBar,
onStartMove: function onStartMove() {
setScrollMoving(true);
},
onStopMove: function onStopMove() {
setScrollMoving(false);
}
onStartMove: onScrollbarStartMove,
onStopMove: onScrollbarStopMove,
spinSize: verticalScrollBarSpinSize,
containerSize: size.height
}), useVirtual && scrollWidth && /*#__PURE__*/React.createElement(ScrollBar, {
ref: horizontalScrollBarRef,
prefixCls: prefixCls,
scrollOffset: offsetLeft,
scrollRange: scrollWidth,
rtl: isRTL,
onScroll: onScrollBar,
onStartMove: onScrollbarStartMove,
onStopMove: onScrollbarStopMove,
spinSize: horizontalScrollBarSpinSize,
containerSize: size.width,
horizontal: true
}));

@@ -314,0 +387,0 @@ }

@@ -5,41 +5,16 @@ import * as React from 'react';

prefixCls: string;
scrollTop: number;
scrollHeight: number;
height: number;
count: number;
direction?: ScrollBarDirectionType;
onScroll: (scrollTop: number) => void;
scrollOffset: number;
scrollRange: number;
rtl: boolean;
onScroll: (scrollOffset: number, horizontal?: boolean) => void;
onStartMove: () => void;
onStopMove: () => void;
horizontal?: boolean;
spinSize: number;
containerSize: number;
}
interface ScrollBarState {
dragging: boolean;
pageY: number;
startTop: number;
visible: boolean;
}
export default class ScrollBar extends React.Component<ScrollBarProps, ScrollBarState> {
moveRaf: number;
scrollbarRef: React.RefObject<HTMLDivElement>;
thumbRef: React.RefObject<HTMLDivElement>;
visibleTimeout: ReturnType<typeof setTimeout>;
state: ScrollBarState;
componentDidMount(): void;
componentDidUpdate(prevProps: ScrollBarProps): void;
componentWillUnmount(): void;
export interface ScrollBarRef {
delayHidden: () => void;
onScrollbarTouchStart: (e: TouchEvent) => void;
onContainerMouseDown: React.MouseEventHandler;
patchEvents: () => void;
removeEvents: () => void;
onMouseDown: (e: React.MouseEvent | TouchEvent) => void;
onMouseMove: (e: MouseEvent | TouchEvent) => void;
onMouseUp: () => void;
getSpinHeight: () => number;
getEnableScrollRange: () => number;
getEnableHeightRange: () => number;
getTop: () => number;
showScroll: () => boolean;
render(): React.JSX.Element;
}
export {};
declare const ScrollBar: React.ForwardRefExoticComponent<ScrollBarProps & React.RefAttributes<ScrollBarRef>>;
export default ScrollBar;

@@ -1,223 +0,217 @@

import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
import _createClass from "@babel/runtime/helpers/esm/createClass";
import _inherits from "@babel/runtime/helpers/esm/inherits";
import _createSuper from "@babel/runtime/helpers/esm/createSuper";
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
import * as React from 'react';
import classNames from 'classnames';
import raf from "rc-util/es/raf";
var MIN_SIZE = 20;
function getPageY(e) {
return 'touches' in e ? e.touches[0].pageY : e.pageY;
function getPageXY(e, horizontal) {
var obj = 'touches' in e ? e.touches[0] : e;
return obj[horizontal ? 'pageX' : 'pageY'];
}
var ScrollBar = /*#__PURE__*/function (_React$Component) {
_inherits(ScrollBar, _React$Component);
var _super = _createSuper(ScrollBar);
function ScrollBar() {
var _this;
_classCallCheck(this, ScrollBar);
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
var ScrollBar = /*#__PURE__*/React.forwardRef(function (props, ref) {
var _classNames;
var prefixCls = props.prefixCls,
rtl = props.rtl,
scrollOffset = props.scrollOffset,
scrollRange = props.scrollRange,
onStartMove = props.onStartMove,
onStopMove = props.onStopMove,
onScroll = props.onScroll,
horizontal = props.horizontal,
spinSize = props.spinSize,
containerSize = props.containerSize;
var _React$useState = React.useState(false),
_React$useState2 = _slicedToArray(_React$useState, 2),
dragging = _React$useState2[0],
setDragging = _React$useState2[1];
var _React$useState3 = React.useState(null),
_React$useState4 = _slicedToArray(_React$useState3, 2),
pageXY = _React$useState4[0],
setPageXY = _React$useState4[1];
var _React$useState5 = React.useState(null),
_React$useState6 = _slicedToArray(_React$useState5, 2),
startTop = _React$useState6[0],
setStartTop = _React$useState6[1];
var isLTR = !rtl;
// ========================= Refs =========================
var scrollbarRef = React.useRef();
var thumbRef = React.useRef();
// ======================= Visible ========================
var _React$useState7 = React.useState(false),
_React$useState8 = _slicedToArray(_React$useState7, 2),
visible = _React$useState8[0],
setVisible = _React$useState8[1];
var visibleTimeoutRef = React.useRef();
var delayHidden = function delayHidden() {
clearTimeout(visibleTimeoutRef.current);
setVisible(true);
visibleTimeoutRef.current = setTimeout(function () {
setVisible(false);
}, 3000);
};
// ======================== Range =========================
var enableScrollRange = scrollRange - containerSize || 0;
var enableOffsetRange = containerSize - spinSize || 0;
// `scrollWidth` < `clientWidth` means no need to show scrollbar
var canScroll = enableScrollRange > 0;
// ========================= Top ==========================
var top = React.useMemo(function () {
if (scrollOffset === 0 || enableScrollRange === 0) {
return 0;
}
_this = _super.call.apply(_super, [this].concat(args));
_this.moveRaf = null;
_this.scrollbarRef = /*#__PURE__*/React.createRef();
_this.thumbRef = /*#__PURE__*/React.createRef();
_this.visibleTimeout = null;
_this.state = {
dragging: false,
pageY: null,
startTop: null,
visible: false
};
_this.delayHidden = function () {
clearTimeout(_this.visibleTimeout);
_this.setState({
visible: true
});
_this.visibleTimeout = setTimeout(function () {
_this.setState({
visible: false
});
}, 2000);
};
_this.onScrollbarTouchStart = function (e) {
var ptg = scrollOffset / enableScrollRange;
return ptg * enableOffsetRange;
}, [scrollOffset, enableScrollRange, enableOffsetRange]);
// ====================== Container =======================
var onContainerMouseDown = function onContainerMouseDown(e) {
e.stopPropagation();
e.preventDefault();
};
// ======================== Thumb =========================
var stateRef = React.useRef({
top: top,
dragging: dragging,
pageY: pageXY,
startTop: startTop
});
stateRef.current = {
top: top,
dragging: dragging,
pageY: pageXY,
startTop: startTop
};
var onThumbMouseDown = function onThumbMouseDown(e) {
setDragging(true);
setPageXY(getPageXY(e, horizontal));
setStartTop(stateRef.current.top);
onStartMove();
e.stopPropagation();
e.preventDefault();
};
// ======================== Effect ========================
// React make event as passive, but we need to preventDefault
// Add event on dom directly instead.
// ref: https://github.com/facebook/react/issues/9809
React.useEffect(function () {
var onScrollbarTouchStart = function onScrollbarTouchStart(e) {
e.preventDefault();
};
_this.onContainerMouseDown = function (e) {
e.stopPropagation();
e.preventDefault();
var scrollbarEle = scrollbarRef.current;
var thumbEle = thumbRef.current;
scrollbarEle.addEventListener('touchstart', onScrollbarTouchStart);
thumbEle.addEventListener('touchstart', onThumbMouseDown);
return function () {
scrollbarEle.removeEventListener('touchstart', onScrollbarTouchStart);
thumbEle.removeEventListener('touchstart', onThumbMouseDown);
};
// ======================= Clean =======================
_this.patchEvents = function () {
window.addEventListener('mousemove', _this.onMouseMove);
window.addEventListener('mouseup', _this.onMouseUp);
_this.thumbRef.current.addEventListener('touchmove', _this.onMouseMove);
_this.thumbRef.current.addEventListener('touchend', _this.onMouseUp);
}, []);
React.useEffect(function () {
if (dragging) {
var moveRafId;
var onMouseMove = function onMouseMove(e) {
var _stateRef$current = stateRef.current,
stateDragging = _stateRef$current.dragging,
statePageY = _stateRef$current.pageY,
stateStartTop = _stateRef$current.startTop;
raf.cancel(moveRafId);
if (stateDragging) {
var offset = getPageXY(e, horizontal) - statePageY;
var newTop = stateStartTop;
if (!isLTR && horizontal) {
newTop -= offset;
} else {
newTop += offset;
}
var ptg = enableOffsetRange ? newTop / enableOffsetRange : 0;
var newScrollTop = Math.ceil(ptg * enableScrollRange);
newScrollTop = Math.max(newScrollTop, 0);
newScrollTop = Math.min(newScrollTop, enableScrollRange);
moveRafId = raf(function () {
onScroll(newScrollTop, horizontal);
});
}
};
var onMouseUp = function onMouseUp() {
setDragging(false);
onStopMove();
};
window.addEventListener('mousemove', onMouseMove);
window.addEventListener('touchmove', onMouseMove);
window.addEventListener('mouseup', onMouseUp);
window.addEventListener('touchend', onMouseUp);
return function () {
window.removeEventListener('mousemove', onMouseMove);
window.removeEventListener('touchmove', onMouseMove);
window.removeEventListener('mouseup', onMouseUp);
window.removeEventListener('touchend', onMouseUp);
raf.cancel(moveRafId);
};
}
}, [dragging]);
React.useEffect(function () {
delayHidden();
}, [scrollOffset]);
// ====================== Imperative ======================
React.useImperativeHandle(ref, function () {
return {
delayHidden: delayHidden
};
_this.removeEvents = function () {
window.removeEventListener('mousemove', _this.onMouseMove);
window.removeEventListener('mouseup', _this.onMouseUp);
if (_this.thumbRef.current) {
_this.thumbRef.current.removeEventListener('touchmove', _this.onMouseMove);
_this.thumbRef.current.removeEventListener('touchend', _this.onMouseUp);
}
raf.cancel(_this.moveRaf);
};
// ======================= Thumb =======================
_this.onMouseDown = function (e) {
var onStartMove = _this.props.onStartMove;
_this.setState({
dragging: true,
pageY: getPageY(e),
startTop: _this.getTop()
});
onStartMove();
_this.patchEvents();
e.stopPropagation();
e.preventDefault();
};
_this.onMouseMove = function (e) {
var _this$state = _this.state,
dragging = _this$state.dragging,
pageY = _this$state.pageY,
startTop = _this$state.startTop;
var onScroll = _this.props.onScroll;
raf.cancel(_this.moveRaf);
if (dragging) {
var offsetY = getPageY(e) - pageY;
var newTop = startTop + offsetY;
var enableScrollRange = _this.getEnableScrollRange();
var enableHeightRange = _this.getEnableHeightRange();
var ptg = enableHeightRange ? newTop / enableHeightRange : 0;
var newScrollTop = Math.ceil(ptg * enableScrollRange);
_this.moveRaf = raf(function () {
onScroll(newScrollTop);
});
}
};
_this.onMouseUp = function () {
var onStopMove = _this.props.onStopMove;
_this.setState({
dragging: false
});
onStopMove();
_this.removeEvents();
};
// ===================== Calculate =====================
_this.getSpinHeight = function () {
var _this$props = _this.props,
height = _this$props.height,
count = _this$props.count;
var baseHeight = height / count * 10;
baseHeight = Math.max(baseHeight, MIN_SIZE);
baseHeight = Math.min(baseHeight, height / 2);
return Math.floor(baseHeight);
};
_this.getEnableScrollRange = function () {
var _this$props2 = _this.props,
scrollHeight = _this$props2.scrollHeight,
height = _this$props2.height;
return scrollHeight - height || 0;
};
_this.getEnableHeightRange = function () {
var height = _this.props.height;
var spinHeight = _this.getSpinHeight();
return height - spinHeight || 0;
};
_this.getTop = function () {
var scrollTop = _this.props.scrollTop;
var enableScrollRange = _this.getEnableScrollRange();
var enableHeightRange = _this.getEnableHeightRange();
if (scrollTop === 0 || enableScrollRange === 0) {
return 0;
}
var ptg = scrollTop / enableScrollRange;
return ptg * enableHeightRange;
};
// Not show scrollbar when height is large than scrollHeight
_this.showScroll = function () {
var _this$props3 = _this.props,
height = _this$props3.height,
scrollHeight = _this$props3.scrollHeight;
return scrollHeight > height;
};
return _this;
}
_createClass(ScrollBar, [{
key: "componentDidMount",
value: function componentDidMount() {
this.scrollbarRef.current.addEventListener('touchstart', this.onScrollbarTouchStart);
this.thumbRef.current.addEventListener('touchstart', this.onMouseDown);
});
// ======================== Render ========================
var scrollbarPrefixCls = "".concat(prefixCls, "-scrollbar");
var containerStyle = {
position: 'absolute',
visibility: visible && canScroll ? null : 'hidden'
};
var thumbStyle = {
position: 'absolute',
background: 'rgba(0, 0, 0, 0.5)',
borderRadius: 99,
cursor: 'pointer',
userSelect: 'none'
};
if (horizontal) {
// Container
containerStyle.height = 8;
containerStyle.left = 0;
containerStyle.right = 0;
containerStyle.bottom = 0;
// Thumb
thumbStyle.height = '100%';
thumbStyle.width = spinSize;
if (isLTR) {
thumbStyle.left = top;
} else {
thumbStyle.right = top;
}
}, {
key: "componentDidUpdate",
value: function componentDidUpdate(prevProps) {
if (prevProps.scrollTop !== this.props.scrollTop) {
this.delayHidden();
}
} else {
// Container
containerStyle.width = 8;
containerStyle.top = 0;
containerStyle.bottom = 0;
if (isLTR) {
containerStyle.right = 0;
} else {
containerStyle.left = 0;
}
}, {
key: "componentWillUnmount",
value: function componentWillUnmount() {
var _this$scrollbarRef$cu, _this$thumbRef$curren;
this.removeEvents();
(_this$scrollbarRef$cu = this.scrollbarRef.current) === null || _this$scrollbarRef$cu === void 0 ? void 0 : _this$scrollbarRef$cu.removeEventListener('touchstart', this.onScrollbarTouchStart);
(_this$thumbRef$curren = this.thumbRef.current) === null || _this$thumbRef$curren === void 0 ? void 0 : _this$thumbRef$curren.removeEventListener('touchstart', this.onMouseDown);
clearTimeout(this.visibleTimeout);
}
}, {
key: "render",
value:
// ====================== Render =======================
function render() {
var _this$state2 = this.state,
dragging = _this$state2.dragging,
visible = _this$state2.visible;
var _this$props4 = this.props,
prefixCls = _this$props4.prefixCls,
direction = _this$props4.direction;
var spinHeight = this.getSpinHeight();
var top = this.getTop();
var canScroll = this.showScroll();
var mergedVisible = canScroll && visible;
var scrollBarDirection = direction === 'rtl' ? {
left: 0
} : {
right: 0
};
return /*#__PURE__*/React.createElement("div", {
ref: this.scrollbarRef,
className: classNames("".concat(prefixCls, "-scrollbar"), _defineProperty({}, "".concat(prefixCls, "-scrollbar-show"), canScroll)),
style: _objectSpread(_objectSpread({
width: 8,
top: 0,
bottom: 0
}, scrollBarDirection), {}, {
position: 'absolute',
display: mergedVisible ? null : 'none'
}),
onMouseDown: this.onContainerMouseDown,
onMouseMove: this.delayHidden
}, /*#__PURE__*/React.createElement("div", {
ref: this.thumbRef,
className: classNames("".concat(prefixCls, "-scrollbar-thumb"), _defineProperty({}, "".concat(prefixCls, "-scrollbar-thumb-moving"), dragging)),
style: {
width: '100%',
height: spinHeight,
top: top,
left: 0,
position: 'absolute',
background: 'rgba(0, 0, 0, 0.5)',
borderRadius: 99,
cursor: 'pointer',
userSelect: 'none'
},
onMouseDown: this.onMouseDown
}));
}
}]);
return ScrollBar;
}(React.Component);
export { ScrollBar as default };
// Thumb
thumbStyle.width = '100%';
thumbStyle.height = spinSize;
thumbStyle.top = top;
}
return /*#__PURE__*/React.createElement("div", {
ref: scrollbarRef,
className: classNames(scrollbarPrefixCls, (_classNames = {}, _defineProperty(_classNames, "".concat(scrollbarPrefixCls, "-horizontal"), horizontal), _defineProperty(_classNames, "".concat(scrollbarPrefixCls, "-vertical"), !horizontal), _defineProperty(_classNames, "".concat(scrollbarPrefixCls, "-visible"), visible), _classNames)),
style: containerStyle,
onMouseDown: onContainerMouseDown,
onMouseMove: delayHidden
}, /*#__PURE__*/React.createElement("div", {
ref: thumbRef,
className: classNames("".concat(scrollbarPrefixCls, "-thumb"), _defineProperty({}, "".concat(scrollbarPrefixCls, "-thumb-moving"), dragging)),
style: thumbStyle,
onMouseDown: onThumbMouseDown
}));
});
if (process.env.NODE_ENV !== 'production') {
ScrollBar.displayName = 'ScrollBar';
}
export default ScrollBar;

@@ -8,6 +8,9 @@ import * as React from 'react';

/** Set offset of visible items. Should be the top of start item position */
offset?: number;
offsetY?: number;
offsetX?: number;
scrollWidth?: number;
children: React.ReactNode;
onInnerResize?: () => void;
innerProps?: InnerProps;
rtl: boolean;
}

@@ -14,0 +17,0 @@ /**

@@ -20,7 +20,10 @@ "use strict";

var height = _ref.height,
offset = _ref.offset,
offsetY = _ref.offsetY,
offsetX = _ref.offsetX,
scrollWidth = _ref.scrollWidth,
children = _ref.children,
prefixCls = _ref.prefixCls,
onInnerResize = _ref.onInnerResize,
innerProps = _ref.innerProps;
innerProps = _ref.innerProps,
rtl = _ref.rtl;
var outerStyle = {};

@@ -31,5 +34,7 @@ var innerStyle = {

};
if (offset !== undefined) {
if (offsetY !== undefined) {
outerStyle = {
height: height,
width: scrollWidth,
minWidth: '100%',
position: 'relative',

@@ -39,3 +44,3 @@ overflow: 'hidden'

innerStyle = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, innerStyle), {}, {
transform: "translateY(".concat(offset, "px)"),
transform: "translate(".concat(rtl ? offsetX : -offsetX, "px, ").concat(offsetY, "px)"),
position: 'absolute',

@@ -42,0 +47,0 @@ left: 0,

interface FireFoxDOMMouseScrollEvent {
detail: number;
preventDefault: Function;
preventDefault: VoidFunction;
}
export default function useFrameWheel(inVirtual: boolean, isScrollAtTop: boolean, isScrollAtBottom: boolean, onWheelDelta: (offset: number) => void): [(e: WheelEvent) => void, (e: FireFoxDOMMouseScrollEvent) => void];
export default function useFrameWheel(inVirtual: boolean, isScrollAtTop: boolean, isScrollAtBottom: boolean, horizontalScroll: boolean,
/***
* Return `true` when you need to prevent default event
*/
onWheelDelta: (offset: number, horizontal?: boolean) => void): [(e: WheelEvent) => void, (e: FireFoxDOMMouseScrollEvent) => void];
export {};

@@ -12,3 +12,7 @@ "use strict";

var _useOriginScroll = _interopRequireDefault(require("./useOriginScroll"));
function useFrameWheel(inVirtual, isScrollAtTop, isScrollAtBottom, onWheelDelta) {
function useFrameWheel(inVirtual, isScrollAtTop, isScrollAtBottom, horizontalScroll,
/***
* Return `true` when you need to prevent default event
*/
onWheelDelta) {
var offsetRef = (0, _react.useRef)(0);

@@ -21,4 +25,3 @@ var nextFrameRef = (0, _react.useRef)(null);

var originScroll = (0, _useOriginScroll.default)(isScrollAtTop, isScrollAtBottom);
function onWheel(event) {
if (!inVirtual) return;
function onWheelY(event) {
_raf.default.cancel(nextFrameRef.current);

@@ -42,2 +45,32 @@ var deltaY = event.deltaY;

}
function onWheelX(event) {
var deltaX = event.deltaX;
onWheelDelta(deltaX, true);
if (!_isFirefox.default) {
event.preventDefault();
}
}
// Check for which direction does wheel do
var wheelDirectionRef = (0, _react.useRef)(null);
var wheelDirectionCleanRef = (0, _react.useRef)(null);
function onWheel(event) {
if (!inVirtual) return;
// Wait for 2 frame to clean direction
_raf.default.cancel(wheelDirectionCleanRef.current);
wheelDirectionCleanRef.current = (0, _raf.default)(function () {
wheelDirectionRef.current = null;
}, 2);
var deltaX = event.deltaX,
deltaY = event.deltaY;
var absX = Math.abs(deltaX);
var absY = Math.abs(deltaY);
if (wheelDirectionRef.current === null) {
wheelDirectionRef.current = horizontalScroll && absX > absY ? 'x' : 'y';
}
if (wheelDirectionRef.current === 'x') {
onWheelX(event);
} else {
onWheelY(event);
}
}
// A patch for firefox

@@ -44,0 +77,0 @@ function onFireFoxScroll(event) {

@@ -32,2 +32,8 @@ import * as React from 'react';

direction?: ScrollBarDirectionType;
/**
* By default `scrollWidth` is same as container.
* When set this, it will show the horizontal scrollbar and
* `scrollWidth` will be used as the real width instead of container width.
*/
scrollWidth?: number;
onScroll?: React.UIEventHandler<HTMLElement>;

@@ -34,0 +40,0 @@ /** Trigger when render list item changed */

@@ -12,7 +12,8 @@ "use strict";

var _objectSpread3 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
var React = _interopRequireWildcard(require("react"));
var _classnames = _interopRequireDefault(require("classnames"));
var _rcResizeObserver = _interopRequireDefault(require("rc-resize-observer"));
var _Filler = _interopRequireDefault(require("./Filler"));

@@ -28,3 +29,5 @@ var _ScrollBar = _interopRequireDefault(require("./ScrollBar"));

var _useLayoutEffect = _interopRequireDefault(require("rc-util/lib/hooks/useLayoutEffect"));
var _excluded = ["prefixCls", "className", "height", "itemHeight", "fullHeight", "style", "data", "children", "itemKey", "virtual", "direction", "component", "onScroll", "onVisibleChange", "innerProps"];
var _scrollbarUtil = require("./utils/scrollbarUtil");
var _rcUtil = require("rc-util");
var _excluded = ["prefixCls", "className", "height", "itemHeight", "fullHeight", "style", "data", "children", "itemKey", "virtual", "direction", "scrollWidth", "component", "onScroll", "onVisibleChange", "innerProps"];
var EMPTY_DATA = [];

@@ -49,2 +52,3 @@ var ScrollStyle = {

direction = props.direction,
scrollWidth = props.scrollWidth,
_props$component = props.component,

@@ -59,16 +63,27 @@ Component = _props$component === void 0 ? 'div' : _props$component,

var inVirtual = useVirtual && data && itemHeight * data.length > height;
var _useState = (0, React.useState)(0),
_useState2 = (0, _slicedToArray2.default)(_useState, 2),
scrollTop = _useState2[0],
setScrollTop = _useState2[1];
var _useState3 = (0, React.useState)(false),
_useState4 = (0, _slicedToArray2.default)(_useState3, 2),
scrollMoving = _useState4[0],
setScrollMoving = _useState4[1];
var mergedClassName = (0, _classnames.default)(prefixCls, (0, _defineProperty2.default)({}, "".concat(prefixCls, "-rtl"), direction === 'rtl'), className);
var isRTL = direction === 'rtl';
var mergedClassName = (0, _classnames.default)(prefixCls, (0, _defineProperty2.default)({}, "".concat(prefixCls, "-rtl"), isRTL), className);
var mergedData = data || EMPTY_DATA;
var componentRef = (0, React.useRef)();
var fillerInnerRef = (0, React.useRef)();
var scrollBarRef = (0, React.useRef)(); // Hack on scrollbar to enable flash call
// =============================== Item Key ===============================
var _useState = (0, React.useState)(0),
_useState2 = (0, _slicedToArray2.default)(_useState, 2),
offsetTop = _useState2[0],
setOffsetTop = _useState2[1];
var _useState3 = (0, React.useState)(0),
_useState4 = (0, _slicedToArray2.default)(_useState3, 2),
offsetLeft = _useState4[0],
setOffsetLeft = _useState4[1];
var _useState5 = (0, React.useState)(false),
_useState6 = (0, _slicedToArray2.default)(_useState5, 2),
scrollMoving = _useState6[0],
setScrollMoving = _useState6[1];
var onScrollbarStartMove = function onScrollbarStartMove() {
setScrollMoving(true);
};
var onScrollbarStopMove = function onScrollbarStopMove() {
setScrollMoving(false);
};
// =============================== Item Key ===============================
var getKey = React.useCallback(function (item) {

@@ -85,3 +100,3 @@ if (typeof itemKey === 'function') {

function syncScrollTop(newTop) {
setScrollTop(function (origin) {
setOffsetTop(function (origin) {
var value;

@@ -147,3 +162,3 @@ if (typeof newTop === 'function') {

// Check item top in the range
if (currentItemBottom >= scrollTop && startIndex === undefined) {
if (currentItemBottom >= offsetTop && startIndex === undefined) {
startIndex = i;

@@ -153,3 +168,3 @@ startOffset = itemTop;

// Check item bottom in the range. We will render additional one item for motion usage
if (currentItemBottom > scrollTop + height && endIndex === undefined) {
if (currentItemBottom > offsetTop + height && endIndex === undefined) {
endIndex = i;

@@ -176,3 +191,3 @@ }

};
}, [inVirtual, useVirtual, scrollTop, mergedData, heightUpdatedMark, height]),
}, [inVirtual, useVirtual, offsetTop, mergedData, heightUpdatedMark, height]),
scrollHeight = _React$useMemo.scrollHeight,

@@ -184,2 +199,22 @@ start = _React$useMemo.start,

rangeRef.current.end = end;
// ================================= Size =================================
var _React$useState = React.useState({
width: 0,
height: height
}),
_React$useState2 = (0, _slicedToArray2.default)(_React$useState, 2),
size = _React$useState2[0],
setSize = _React$useState2[1];
var onHolderResize = function onHolderResize(sizeInfo) {
setSize(sizeInfo);
};
// Hack on scrollbar to enable flash call
var verticalScrollBarRef = (0, React.useRef)();
var horizontalScrollBarRef = (0, React.useRef)();
var horizontalScrollBarSpinSize = React.useMemo(function () {
return (0, _scrollbarUtil.getSpinSize)(size.width, scrollWidth);
}, [size.width, scrollWidth]);
var verticalScrollBarSpinSize = React.useMemo(function () {
return (0, _scrollbarUtil.getSpinSize)(size.height, scrollHeight);
}, [size.height, scrollHeight]);
// =============================== In Range ===============================

@@ -197,9 +232,13 @@ var maxScrollHeight = scrollHeight - height;

}
var isScrollAtTop = scrollTop <= 0;
var isScrollAtBottom = scrollTop >= maxScrollHeight;
var isScrollAtTop = offsetTop <= 0;
var isScrollAtBottom = offsetTop >= maxScrollHeight;
var originScroll = (0, _useOriginScroll.default)(isScrollAtTop, isScrollAtBottom);
// ================================ Scroll ================================
function onScrollBar(newScrollTop) {
var newTop = newScrollTop;
syncScrollTop(newTop);
function onScrollBar(newScrollOffset, horizontal) {
var newOffset = newScrollOffset;
if (horizontal) {
setOffsetLeft(newOffset);
} else {
syncScrollTop(newOffset);
}
}

@@ -209,3 +248,3 @@ // When data size reduce. It may trigger native scroll event back to fit scroll position

var newScrollTop = e.currentTarget.scrollTop;
if (newScrollTop !== scrollTop) {
if (newScrollTop !== offsetTop) {
syncScrollTop(newScrollTop);

@@ -216,9 +255,21 @@ }

}
// Since this added in global,should use ref to keep update
var _useFrameWheel = (0, _useFrameWheel3.default)(useVirtual, isScrollAtTop, isScrollAtBottom, function (offsetY) {
var onWheelDelta = (0, _rcUtil.useEvent)(function (offsetXY, fromHorizontal) {
if (fromHorizontal) {
// Horizontal scroll no need sync virtual position
setOffsetLeft(function (left) {
var newLeft = left + offsetXY;
var max = scrollWidth - size.width;
newLeft = Math.max(newLeft, 0);
newLeft = Math.min(newLeft, max);
return newLeft;
});
} else {
syncScrollTop(function (top) {
var newTop = top + offsetY;
var newTop = top + offsetXY;
return newTop;
});
}),
}
});
// Since this added in global,should use ref to keep update
var _useFrameWheel = (0, _useFrameWheel3.default)(useVirtual, isScrollAtTop, isScrollAtBottom, !!scrollWidth, onWheelDelta),
_useFrameWheel2 = (0, _slicedToArray2.default)(_useFrameWheel, 2),

@@ -245,18 +296,19 @@ onRawWheel = _useFrameWheel2[0],

}
componentRef.current.addEventListener('wheel', onRawWheel);
componentRef.current.addEventListener('DOMMouseScroll', onFireFoxScroll);
componentRef.current.addEventListener('MozMousePixelScroll', onMozMousePixelScroll);
var componentEle = componentRef.current;
componentEle.addEventListener('wheel', onRawWheel);
componentEle.addEventListener('DOMMouseScroll', onFireFoxScroll);
componentEle.addEventListener('MozMousePixelScroll', onMozMousePixelScroll);
return function () {
if (componentRef.current) {
componentRef.current.removeEventListener('wheel', onRawWheel);
componentRef.current.removeEventListener('DOMMouseScroll', onFireFoxScroll);
componentRef.current.removeEventListener('MozMousePixelScroll', onMozMousePixelScroll);
}
componentEle.removeEventListener('wheel', onRawWheel);
componentEle.removeEventListener('DOMMouseScroll', onFireFoxScroll);
componentEle.removeEventListener('MozMousePixelScroll', onMozMousePixelScroll);
};
}, [useVirtual]);
// ================================= Ref ==================================
var scrollTo = (0, _useScrollTo.default)(componentRef, mergedData, heights, itemHeight, getKey, collectHeight, syncScrollTop, function () {
var _scrollBarRef$current;
(_scrollBarRef$current = scrollBarRef.current) === null || _scrollBarRef$current === void 0 ? void 0 : _scrollBarRef$current.delayHidden();
});
var delayHideScrollBar = function delayHideScrollBar() {
var _verticalScrollBarRef, _horizontalScrollBarR;
(_verticalScrollBarRef = verticalScrollBarRef.current) === null || _verticalScrollBarRef === void 0 ? void 0 : _verticalScrollBarRef.delayHidden();
(_horizontalScrollBarR = horizontalScrollBarRef.current) === null || _horizontalScrollBarR === void 0 ? void 0 : _horizontalScrollBarR.delayHidden();
};
var scrollTo = (0, _useScrollTo.default)(componentRef, mergedData, heights, itemHeight, getKey, collectHeight, syncScrollTop, delayHideScrollBar);
React.useImperativeHandle(ref, function () {

@@ -282,2 +334,5 @@ return {

componentStyle.overflowY = 'hidden';
if (scrollWidth) {
componentStyle.overflowX = 'hidden';
}
if (scrollMoving) {

@@ -288,2 +343,6 @@ componentStyle.pointerEvents = 'none';

}
var containerProps = {};
if (isRTL) {
containerProps.dir = 'rtl';
}
return /*#__PURE__*/React.createElement("div", (0, _extends2.default)({

@@ -294,29 +353,43 @@ style: (0, _objectSpread3.default)((0, _objectSpread3.default)({}, style), {}, {

className: mergedClassName
}, restProps), /*#__PURE__*/React.createElement(Component, {
}, containerProps, restProps), /*#__PURE__*/React.createElement(_rcResizeObserver.default, {
onResize: onHolderResize
}, /*#__PURE__*/React.createElement(Component, {
className: "".concat(prefixCls, "-holder"),
style: componentStyle,
ref: componentRef,
onScroll: onFallbackScroll
onScroll: onFallbackScroll,
onMouseEnter: delayHideScrollBar
}, /*#__PURE__*/React.createElement(_Filler.default, {
prefixCls: prefixCls,
height: scrollHeight,
offset: offset,
offsetX: offsetLeft,
offsetY: offset,
scrollWidth: scrollWidth,
onInnerResize: collectHeight,
ref: fillerInnerRef,
innerProps: innerProps
}, listChildren)), useVirtual && /*#__PURE__*/React.createElement(_ScrollBar.default, {
ref: scrollBarRef,
innerProps: innerProps,
rtl: isRTL
}, listChildren))), useVirtual && scrollHeight > height && /*#__PURE__*/React.createElement(_ScrollBar.default, {
ref: verticalScrollBarRef,
prefixCls: prefixCls,
scrollTop: scrollTop,
height: height,
scrollHeight: scrollHeight,
count: mergedData.length,
direction: direction,
scrollOffset: offsetTop,
scrollRange: scrollHeight,
rtl: isRTL,
onScroll: onScrollBar,
onStartMove: function onStartMove() {
setScrollMoving(true);
},
onStopMove: function onStopMove() {
setScrollMoving(false);
}
onStartMove: onScrollbarStartMove,
onStopMove: onScrollbarStopMove,
spinSize: verticalScrollBarSpinSize,
containerSize: size.height
}), useVirtual && scrollWidth && /*#__PURE__*/React.createElement(_ScrollBar.default, {
ref: horizontalScrollBarRef,
prefixCls: prefixCls,
scrollOffset: offsetLeft,
scrollRange: scrollWidth,
rtl: isRTL,
onScroll: onScrollBar,
onStartMove: onScrollbarStartMove,
onStopMove: onScrollbarStopMove,
spinSize: horizontalScrollBarSpinSize,
containerSize: size.width,
horizontal: true
}));

@@ -323,0 +396,0 @@ }

@@ -5,41 +5,16 @@ import * as React from 'react';

prefixCls: string;
scrollTop: number;
scrollHeight: number;
height: number;
count: number;
direction?: ScrollBarDirectionType;
onScroll: (scrollTop: number) => void;
scrollOffset: number;
scrollRange: number;
rtl: boolean;
onScroll: (scrollOffset: number, horizontal?: boolean) => void;
onStartMove: () => void;
onStopMove: () => void;
horizontal?: boolean;
spinSize: number;
containerSize: number;
}
interface ScrollBarState {
dragging: boolean;
pageY: number;
startTop: number;
visible: boolean;
}
export default class ScrollBar extends React.Component<ScrollBarProps, ScrollBarState> {
moveRaf: number;
scrollbarRef: React.RefObject<HTMLDivElement>;
thumbRef: React.RefObject<HTMLDivElement>;
visibleTimeout: ReturnType<typeof setTimeout>;
state: ScrollBarState;
componentDidMount(): void;
componentDidUpdate(prevProps: ScrollBarProps): void;
componentWillUnmount(): void;
export interface ScrollBarRef {
delayHidden: () => void;
onScrollbarTouchStart: (e: TouchEvent) => void;
onContainerMouseDown: React.MouseEventHandler;
patchEvents: () => void;
removeEvents: () => void;
onMouseDown: (e: React.MouseEvent | TouchEvent) => void;
onMouseMove: (e: MouseEvent | TouchEvent) => void;
onMouseUp: () => void;
getSpinHeight: () => number;
getEnableScrollRange: () => number;
getEnableHeightRange: () => number;
getTop: () => number;
showScroll: () => boolean;
render(): React.JSX.Element;
}
export {};
declare const ScrollBar: React.ForwardRefExoticComponent<ScrollBarProps & React.RefAttributes<ScrollBarRef>>;
export default ScrollBar;

@@ -9,224 +9,219 @@ "use strict";

exports.default = void 0;
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
var _createSuper2 = _interopRequireDefault(require("@babel/runtime/helpers/createSuper"));
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var React = _interopRequireWildcard(require("react"));
var _classnames = _interopRequireDefault(require("classnames"));
var _raf = _interopRequireDefault(require("rc-util/lib/raf"));
var MIN_SIZE = 20;
function getPageY(e) {
return 'touches' in e ? e.touches[0].pageY : e.pageY;
function getPageXY(e, horizontal) {
var obj = 'touches' in e ? e.touches[0] : e;
return obj[horizontal ? 'pageX' : 'pageY'];
}
var ScrollBar = /*#__PURE__*/function (_React$Component) {
(0, _inherits2.default)(ScrollBar, _React$Component);
var _super = (0, _createSuper2.default)(ScrollBar);
function ScrollBar() {
var _this;
(0, _classCallCheck2.default)(this, ScrollBar);
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
var ScrollBar = /*#__PURE__*/React.forwardRef(function (props, ref) {
var _classNames;
var prefixCls = props.prefixCls,
rtl = props.rtl,
scrollOffset = props.scrollOffset,
scrollRange = props.scrollRange,
onStartMove = props.onStartMove,
onStopMove = props.onStopMove,
onScroll = props.onScroll,
horizontal = props.horizontal,
spinSize = props.spinSize,
containerSize = props.containerSize;
var _React$useState = React.useState(false),
_React$useState2 = (0, _slicedToArray2.default)(_React$useState, 2),
dragging = _React$useState2[0],
setDragging = _React$useState2[1];
var _React$useState3 = React.useState(null),
_React$useState4 = (0, _slicedToArray2.default)(_React$useState3, 2),
pageXY = _React$useState4[0],
setPageXY = _React$useState4[1];
var _React$useState5 = React.useState(null),
_React$useState6 = (0, _slicedToArray2.default)(_React$useState5, 2),
startTop = _React$useState6[0],
setStartTop = _React$useState6[1];
var isLTR = !rtl;
// ========================= Refs =========================
var scrollbarRef = React.useRef();
var thumbRef = React.useRef();
// ======================= Visible ========================
var _React$useState7 = React.useState(false),
_React$useState8 = (0, _slicedToArray2.default)(_React$useState7, 2),
visible = _React$useState8[0],
setVisible = _React$useState8[1];
var visibleTimeoutRef = React.useRef();
var delayHidden = function delayHidden() {
clearTimeout(visibleTimeoutRef.current);
setVisible(true);
visibleTimeoutRef.current = setTimeout(function () {
setVisible(false);
}, 3000);
};
// ======================== Range =========================
var enableScrollRange = scrollRange - containerSize || 0;
var enableOffsetRange = containerSize - spinSize || 0;
// `scrollWidth` < `clientWidth` means no need to show scrollbar
var canScroll = enableScrollRange > 0;
// ========================= Top ==========================
var top = React.useMemo(function () {
if (scrollOffset === 0 || enableScrollRange === 0) {
return 0;
}
_this = _super.call.apply(_super, [this].concat(args));
_this.moveRaf = null;
_this.scrollbarRef = /*#__PURE__*/React.createRef();
_this.thumbRef = /*#__PURE__*/React.createRef();
_this.visibleTimeout = null;
_this.state = {
dragging: false,
pageY: null,
startTop: null,
visible: false
};
_this.delayHidden = function () {
clearTimeout(_this.visibleTimeout);
_this.setState({
visible: true
});
_this.visibleTimeout = setTimeout(function () {
_this.setState({
visible: false
});
}, 2000);
};
_this.onScrollbarTouchStart = function (e) {
var ptg = scrollOffset / enableScrollRange;
return ptg * enableOffsetRange;
}, [scrollOffset, enableScrollRange, enableOffsetRange]);
// ====================== Container =======================
var onContainerMouseDown = function onContainerMouseDown(e) {
e.stopPropagation();
e.preventDefault();
};
// ======================== Thumb =========================
var stateRef = React.useRef({
top: top,
dragging: dragging,
pageY: pageXY,
startTop: startTop
});
stateRef.current = {
top: top,
dragging: dragging,
pageY: pageXY,
startTop: startTop
};
var onThumbMouseDown = function onThumbMouseDown(e) {
setDragging(true);
setPageXY(getPageXY(e, horizontal));
setStartTop(stateRef.current.top);
onStartMove();
e.stopPropagation();
e.preventDefault();
};
// ======================== Effect ========================
// React make event as passive, but we need to preventDefault
// Add event on dom directly instead.
// ref: https://github.com/facebook/react/issues/9809
React.useEffect(function () {
var onScrollbarTouchStart = function onScrollbarTouchStart(e) {
e.preventDefault();
};
_this.onContainerMouseDown = function (e) {
e.stopPropagation();
e.preventDefault();
var scrollbarEle = scrollbarRef.current;
var thumbEle = thumbRef.current;
scrollbarEle.addEventListener('touchstart', onScrollbarTouchStart);
thumbEle.addEventListener('touchstart', onThumbMouseDown);
return function () {
scrollbarEle.removeEventListener('touchstart', onScrollbarTouchStart);
thumbEle.removeEventListener('touchstart', onThumbMouseDown);
};
// ======================= Clean =======================
_this.patchEvents = function () {
window.addEventListener('mousemove', _this.onMouseMove);
window.addEventListener('mouseup', _this.onMouseUp);
_this.thumbRef.current.addEventListener('touchmove', _this.onMouseMove);
_this.thumbRef.current.addEventListener('touchend', _this.onMouseUp);
}, []);
React.useEffect(function () {
if (dragging) {
var moveRafId;
var onMouseMove = function onMouseMove(e) {
var _stateRef$current = stateRef.current,
stateDragging = _stateRef$current.dragging,
statePageY = _stateRef$current.pageY,
stateStartTop = _stateRef$current.startTop;
_raf.default.cancel(moveRafId);
if (stateDragging) {
var offset = getPageXY(e, horizontal) - statePageY;
var newTop = stateStartTop;
if (!isLTR && horizontal) {
newTop -= offset;
} else {
newTop += offset;
}
var ptg = enableOffsetRange ? newTop / enableOffsetRange : 0;
var newScrollTop = Math.ceil(ptg * enableScrollRange);
newScrollTop = Math.max(newScrollTop, 0);
newScrollTop = Math.min(newScrollTop, enableScrollRange);
moveRafId = (0, _raf.default)(function () {
onScroll(newScrollTop, horizontal);
});
}
};
var onMouseUp = function onMouseUp() {
setDragging(false);
onStopMove();
};
window.addEventListener('mousemove', onMouseMove);
window.addEventListener('touchmove', onMouseMove);
window.addEventListener('mouseup', onMouseUp);
window.addEventListener('touchend', onMouseUp);
return function () {
window.removeEventListener('mousemove', onMouseMove);
window.removeEventListener('touchmove', onMouseMove);
window.removeEventListener('mouseup', onMouseUp);
window.removeEventListener('touchend', onMouseUp);
_raf.default.cancel(moveRafId);
};
}
}, [dragging]);
React.useEffect(function () {
delayHidden();
}, [scrollOffset]);
// ====================== Imperative ======================
React.useImperativeHandle(ref, function () {
return {
delayHidden: delayHidden
};
_this.removeEvents = function () {
window.removeEventListener('mousemove', _this.onMouseMove);
window.removeEventListener('mouseup', _this.onMouseUp);
if (_this.thumbRef.current) {
_this.thumbRef.current.removeEventListener('touchmove', _this.onMouseMove);
_this.thumbRef.current.removeEventListener('touchend', _this.onMouseUp);
}
_raf.default.cancel(_this.moveRaf);
};
// ======================= Thumb =======================
_this.onMouseDown = function (e) {
var onStartMove = _this.props.onStartMove;
_this.setState({
dragging: true,
pageY: getPageY(e),
startTop: _this.getTop()
});
onStartMove();
_this.patchEvents();
e.stopPropagation();
e.preventDefault();
};
_this.onMouseMove = function (e) {
var _this$state = _this.state,
dragging = _this$state.dragging,
pageY = _this$state.pageY,
startTop = _this$state.startTop;
var onScroll = _this.props.onScroll;
_raf.default.cancel(_this.moveRaf);
if (dragging) {
var offsetY = getPageY(e) - pageY;
var newTop = startTop + offsetY;
var enableScrollRange = _this.getEnableScrollRange();
var enableHeightRange = _this.getEnableHeightRange();
var ptg = enableHeightRange ? newTop / enableHeightRange : 0;
var newScrollTop = Math.ceil(ptg * enableScrollRange);
_this.moveRaf = (0, _raf.default)(function () {
onScroll(newScrollTop);
});
}
};
_this.onMouseUp = function () {
var onStopMove = _this.props.onStopMove;
_this.setState({
dragging: false
});
onStopMove();
_this.removeEvents();
};
// ===================== Calculate =====================
_this.getSpinHeight = function () {
var _this$props = _this.props,
height = _this$props.height,
count = _this$props.count;
var baseHeight = height / count * 10;
baseHeight = Math.max(baseHeight, MIN_SIZE);
baseHeight = Math.min(baseHeight, height / 2);
return Math.floor(baseHeight);
};
_this.getEnableScrollRange = function () {
var _this$props2 = _this.props,
scrollHeight = _this$props2.scrollHeight,
height = _this$props2.height;
return scrollHeight - height || 0;
};
_this.getEnableHeightRange = function () {
var height = _this.props.height;
var spinHeight = _this.getSpinHeight();
return height - spinHeight || 0;
};
_this.getTop = function () {
var scrollTop = _this.props.scrollTop;
var enableScrollRange = _this.getEnableScrollRange();
var enableHeightRange = _this.getEnableHeightRange();
if (scrollTop === 0 || enableScrollRange === 0) {
return 0;
}
var ptg = scrollTop / enableScrollRange;
return ptg * enableHeightRange;
};
// Not show scrollbar when height is large than scrollHeight
_this.showScroll = function () {
var _this$props3 = _this.props,
height = _this$props3.height,
scrollHeight = _this$props3.scrollHeight;
return scrollHeight > height;
};
return _this;
}
(0, _createClass2.default)(ScrollBar, [{
key: "componentDidMount",
value: function componentDidMount() {
this.scrollbarRef.current.addEventListener('touchstart', this.onScrollbarTouchStart);
this.thumbRef.current.addEventListener('touchstart', this.onMouseDown);
});
// ======================== Render ========================
var scrollbarPrefixCls = "".concat(prefixCls, "-scrollbar");
var containerStyle = {
position: 'absolute',
visibility: visible && canScroll ? null : 'hidden'
};
var thumbStyle = {
position: 'absolute',
background: 'rgba(0, 0, 0, 0.5)',
borderRadius: 99,
cursor: 'pointer',
userSelect: 'none'
};
if (horizontal) {
// Container
containerStyle.height = 8;
containerStyle.left = 0;
containerStyle.right = 0;
containerStyle.bottom = 0;
// Thumb
thumbStyle.height = '100%';
thumbStyle.width = spinSize;
if (isLTR) {
thumbStyle.left = top;
} else {
thumbStyle.right = top;
}
}, {
key: "componentDidUpdate",
value: function componentDidUpdate(prevProps) {
if (prevProps.scrollTop !== this.props.scrollTop) {
this.delayHidden();
}
} else {
// Container
containerStyle.width = 8;
containerStyle.top = 0;
containerStyle.bottom = 0;
if (isLTR) {
containerStyle.right = 0;
} else {
containerStyle.left = 0;
}
}, {
key: "componentWillUnmount",
value: function componentWillUnmount() {
var _this$scrollbarRef$cu, _this$thumbRef$curren;
this.removeEvents();
(_this$scrollbarRef$cu = this.scrollbarRef.current) === null || _this$scrollbarRef$cu === void 0 ? void 0 : _this$scrollbarRef$cu.removeEventListener('touchstart', this.onScrollbarTouchStart);
(_this$thumbRef$curren = this.thumbRef.current) === null || _this$thumbRef$curren === void 0 ? void 0 : _this$thumbRef$curren.removeEventListener('touchstart', this.onMouseDown);
clearTimeout(this.visibleTimeout);
}
}, {
key: "render",
value:
// ====================== Render =======================
function render() {
var _this$state2 = this.state,
dragging = _this$state2.dragging,
visible = _this$state2.visible;
var _this$props4 = this.props,
prefixCls = _this$props4.prefixCls,
direction = _this$props4.direction;
var spinHeight = this.getSpinHeight();
var top = this.getTop();
var canScroll = this.showScroll();
var mergedVisible = canScroll && visible;
var scrollBarDirection = direction === 'rtl' ? {
left: 0
} : {
right: 0
};
return /*#__PURE__*/React.createElement("div", {
ref: this.scrollbarRef,
className: (0, _classnames.default)("".concat(prefixCls, "-scrollbar"), (0, _defineProperty2.default)({}, "".concat(prefixCls, "-scrollbar-show"), canScroll)),
style: (0, _objectSpread2.default)((0, _objectSpread2.default)({
width: 8,
top: 0,
bottom: 0
}, scrollBarDirection), {}, {
position: 'absolute',
display: mergedVisible ? null : 'none'
}),
onMouseDown: this.onContainerMouseDown,
onMouseMove: this.delayHidden
}, /*#__PURE__*/React.createElement("div", {
ref: this.thumbRef,
className: (0, _classnames.default)("".concat(prefixCls, "-scrollbar-thumb"), (0, _defineProperty2.default)({}, "".concat(prefixCls, "-scrollbar-thumb-moving"), dragging)),
style: {
width: '100%',
height: spinHeight,
top: top,
left: 0,
position: 'absolute',
background: 'rgba(0, 0, 0, 0.5)',
borderRadius: 99,
cursor: 'pointer',
userSelect: 'none'
},
onMouseDown: this.onMouseDown
}));
}
}]);
return ScrollBar;
}(React.Component);
exports.default = ScrollBar;
// Thumb
thumbStyle.width = '100%';
thumbStyle.height = spinSize;
thumbStyle.top = top;
}
return /*#__PURE__*/React.createElement("div", {
ref: scrollbarRef,
className: (0, _classnames.default)(scrollbarPrefixCls, (_classNames = {}, (0, _defineProperty2.default)(_classNames, "".concat(scrollbarPrefixCls, "-horizontal"), horizontal), (0, _defineProperty2.default)(_classNames, "".concat(scrollbarPrefixCls, "-vertical"), !horizontal), (0, _defineProperty2.default)(_classNames, "".concat(scrollbarPrefixCls, "-visible"), visible), _classNames)),
style: containerStyle,
onMouseDown: onContainerMouseDown,
onMouseMove: delayHidden
}, /*#__PURE__*/React.createElement("div", {
ref: thumbRef,
className: (0, _classnames.default)("".concat(scrollbarPrefixCls, "-thumb"), (0, _defineProperty2.default)({}, "".concat(scrollbarPrefixCls, "-thumb-moving"), dragging)),
style: thumbStyle,
onMouseDown: onThumbMouseDown
}));
});
if (process.env.NODE_ENV !== 'production') {
ScrollBar.displayName = 'ScrollBar';
}
var _default = ScrollBar;
exports.default = _default;
{
"name": "rc-virtual-list",
"version": "3.5.3",
"version": "3.6.0",
"description": "React Virtual List Component",

@@ -45,2 +45,4 @@ "engines": {

"devDependencies": {
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^12.1.5",
"@types/classnames": "^2.2.10",

@@ -47,0 +49,0 @@ "@types/enzyme": "^3.10.5",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc