ScrollBar.js 9.2 KB

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