rc-virtual-list
Advanced tools
Comparing version 3.5.3 to 3.6.0
@@ -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 @@ /** |
@@ -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 */ |
183
es/List.js
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 */ |
183
lib/List.js
@@ -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", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
107467
74
2713
21
2