UNPKG

8.89 kBJavaScriptView Raw
1"use strict";
2
3var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
4var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
5Object.defineProperty(exports, "__esModule", {
6 value: true
7});
8exports.default = void 0;
9var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
10var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
11var React = _interopRequireWildcard(require("react"));
12var _classnames = _interopRequireDefault(require("classnames"));
13var _raf = _interopRequireDefault(require("rc-util/lib/raf"));
14function getPageXY(e, horizontal) {
15 var obj = 'touches' in e ? e.touches[0] : e;
16 return obj[horizontal ? 'pageX' : 'pageY'];
17}
18var ScrollBar = /*#__PURE__*/React.forwardRef(function (props, ref) {
19 var _classNames;
20 var prefixCls = props.prefixCls,
21 rtl = props.rtl,
22 scrollOffset = props.scrollOffset,
23 scrollRange = props.scrollRange,
24 onStartMove = props.onStartMove,
25 onStopMove = props.onStopMove,
26 onScroll = props.onScroll,
27 horizontal = props.horizontal,
28 spinSize = props.spinSize,
29 containerSize = props.containerSize;
30 var _React$useState = React.useState(false),
31 _React$useState2 = (0, _slicedToArray2.default)(_React$useState, 2),
32 dragging = _React$useState2[0],
33 setDragging = _React$useState2[1];
34 var _React$useState3 = React.useState(null),
35 _React$useState4 = (0, _slicedToArray2.default)(_React$useState3, 2),
36 pageXY = _React$useState4[0],
37 setPageXY = _React$useState4[1];
38 var _React$useState5 = React.useState(null),
39 _React$useState6 = (0, _slicedToArray2.default)(_React$useState5, 2),
40 startTop = _React$useState6[0],
41 setStartTop = _React$useState6[1];
42 var isLTR = !rtl;
43 // ========================= Refs =========================
44 var scrollbarRef = React.useRef();
45 var thumbRef = React.useRef();
46 // ======================= Visible ========================
47 var _React$useState7 = React.useState(false),
48 _React$useState8 = (0, _slicedToArray2.default)(_React$useState7, 2),
49 visible = _React$useState8[0],
50 setVisible = _React$useState8[1];
51 var visibleTimeoutRef = React.useRef();
52 var delayHidden = function delayHidden() {
53 clearTimeout(visibleTimeoutRef.current);
54 setVisible(true);
55 visibleTimeoutRef.current = setTimeout(function () {
56 setVisible(false);
57 }, 3000);
58 };
59 // ======================== Range =========================
60 var enableScrollRange = scrollRange - containerSize || 0;
61 var enableOffsetRange = containerSize - spinSize || 0;
62 // `scrollWidth` < `clientWidth` means no need to show scrollbar
63 var canScroll = enableScrollRange > 0;
64 // ========================= Top ==========================
65 var top = React.useMemo(function () {
66 if (scrollOffset === 0 || enableScrollRange === 0) {
67 return 0;
68 }
69 var ptg = scrollOffset / enableScrollRange;
70 return ptg * enableOffsetRange;
71 }, [scrollOffset, enableScrollRange, enableOffsetRange]);
72 // ====================== Container =======================
73 var onContainerMouseDown = function onContainerMouseDown(e) {
74 e.stopPropagation();
75 e.preventDefault();
76 };
77 // ======================== Thumb =========================
78 var stateRef = React.useRef({
79 top: top,
80 dragging: dragging,
81 pageY: pageXY,
82 startTop: startTop
83 });
84 stateRef.current = {
85 top: top,
86 dragging: dragging,
87 pageY: pageXY,
88 startTop: startTop
89 };
90 var onThumbMouseDown = function onThumbMouseDown(e) {
91 setDragging(true);
92 setPageXY(getPageXY(e, horizontal));
93 setStartTop(stateRef.current.top);
94 onStartMove();
95 e.stopPropagation();
96 e.preventDefault();
97 };
98 // ======================== Effect ========================
99 // React make event as passive, but we need to preventDefault
100 // Add event on dom directly instead.
101 // ref: https://github.com/facebook/react/issues/9809
102 React.useEffect(function () {
103 var onScrollbarTouchStart = function onScrollbarTouchStart(e) {
104 e.preventDefault();
105 };
106 var scrollbarEle = scrollbarRef.current;
107 var thumbEle = thumbRef.current;
108 scrollbarEle.addEventListener('touchstart', onScrollbarTouchStart);
109 thumbEle.addEventListener('touchstart', onThumbMouseDown);
110 return function () {
111 scrollbarEle.removeEventListener('touchstart', onScrollbarTouchStart);
112 thumbEle.removeEventListener('touchstart', onThumbMouseDown);
113 };
114 }, []);
115 // Pass to effect
116 var enableScrollRangeRef = React.useRef();
117 enableScrollRangeRef.current = enableScrollRange;
118 var enableOffsetRangeRef = React.useRef();
119 enableOffsetRangeRef.current = enableOffsetRange;
120 React.useEffect(function () {
121 if (dragging) {
122 var moveRafId;
123 var onMouseMove = function onMouseMove(e) {
124 var _stateRef$current = stateRef.current,
125 stateDragging = _stateRef$current.dragging,
126 statePageY = _stateRef$current.pageY,
127 stateStartTop = _stateRef$current.startTop;
128 _raf.default.cancel(moveRafId);
129 if (stateDragging) {
130 var offset = getPageXY(e, horizontal) - statePageY;
131 var newTop = stateStartTop;
132 if (!isLTR && horizontal) {
133 newTop -= offset;
134 } else {
135 newTop += offset;
136 }
137 var tmpEnableScrollRange = enableScrollRangeRef.current;
138 var tmpEnableOffsetRange = enableOffsetRangeRef.current;
139 var ptg = tmpEnableOffsetRange ? newTop / tmpEnableOffsetRange : 0;
140 var newScrollTop = Math.ceil(ptg * tmpEnableScrollRange);
141 newScrollTop = Math.max(newScrollTop, 0);
142 newScrollTop = Math.min(newScrollTop, tmpEnableScrollRange);
143 moveRafId = (0, _raf.default)(function () {
144 onScroll(newScrollTop, horizontal);
145 });
146 }
147 };
148 var onMouseUp = function onMouseUp() {
149 setDragging(false);
150 onStopMove();
151 };
152 window.addEventListener('mousemove', onMouseMove);
153 window.addEventListener('touchmove', onMouseMove);
154 window.addEventListener('mouseup', onMouseUp);
155 window.addEventListener('touchend', onMouseUp);
156 return function () {
157 window.removeEventListener('mousemove', onMouseMove);
158 window.removeEventListener('touchmove', onMouseMove);
159 window.removeEventListener('mouseup', onMouseUp);
160 window.removeEventListener('touchend', onMouseUp);
161 _raf.default.cancel(moveRafId);
162 };
163 }
164 }, [dragging]);
165 React.useEffect(function () {
166 delayHidden();
167 }, [scrollOffset]);
168 // ====================== Imperative ======================
169 React.useImperativeHandle(ref, function () {
170 return {
171 delayHidden: delayHidden
172 };
173 });
174 // ======================== Render ========================
175 var scrollbarPrefixCls = "".concat(prefixCls, "-scrollbar");
176 var containerStyle = {
177 position: 'absolute',
178 visibility: visible && canScroll ? null : 'hidden'
179 };
180 var thumbStyle = {
181 position: 'absolute',
182 background: 'rgba(0, 0, 0, 0.5)',
183 borderRadius: 99,
184 cursor: 'pointer',
185 userSelect: 'none'
186 };
187 if (horizontal) {
188 // Container
189 containerStyle.height = 8;
190 containerStyle.left = 0;
191 containerStyle.right = 0;
192 containerStyle.bottom = 0;
193 // Thumb
194 thumbStyle.height = '100%';
195 thumbStyle.width = spinSize;
196 if (isLTR) {
197 thumbStyle.left = top;
198 } else {
199 thumbStyle.right = top;
200 }
201 } else {
202 // Container
203 containerStyle.width = 8;
204 containerStyle.top = 0;
205 containerStyle.bottom = 0;
206 if (isLTR) {
207 containerStyle.right = 0;
208 } else {
209 containerStyle.left = 0;
210 }
211 // Thumb
212 thumbStyle.width = '100%';
213 thumbStyle.height = spinSize;
214 thumbStyle.top = top;
215 }
216 return /*#__PURE__*/React.createElement("div", {
217 ref: scrollbarRef,
218 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)),
219 style: containerStyle,
220 onMouseDown: onContainerMouseDown,
221 onMouseMove: delayHidden
222 }, /*#__PURE__*/React.createElement("div", {
223 ref: thumbRef,
224 className: (0, _classnames.default)("".concat(scrollbarPrefixCls, "-thumb"), (0, _defineProperty2.default)({}, "".concat(scrollbarPrefixCls, "-thumb-moving"), dragging)),
225 style: thumbStyle,
226 onMouseDown: onThumbMouseDown
227 }));
228});
229if (process.env.NODE_ENV !== 'production') {
230 ScrollBar.displayName = 'ScrollBar';
231}
232var _default = ScrollBar;
233exports.default = _default;
\No newline at end of file