123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- "use strict";
- var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
- Object.defineProperty(exports, "__esModule", {
- value: true
- });
- exports.default = useScrollTo;
- var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
- var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
- var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
- var React = _interopRequireWildcard(require("react"));
- var _raf = _interopRequireDefault(require("rc-util/lib/raf"));
- var _useLayoutEffect = _interopRequireDefault(require("rc-util/lib/hooks/useLayoutEffect"));
- var _rcUtil = require("rc-util");
- /* eslint-disable no-param-reassign */
- var MAX_TIMES = 10;
- function useScrollTo(containerRef, data, heights, itemHeight, getKey, collectHeight, syncScrollTop, triggerFlash) {
- var scrollRef = React.useRef();
- var _React$useState = React.useState(null),
- _React$useState2 = (0, _slicedToArray2.default)(_React$useState, 2),
- syncState = _React$useState2[0],
- setSyncState = _React$useState2[1];
- // ========================== Sync Scroll ==========================
- (0, _useLayoutEffect.default)(function () {
- if (syncState && syncState.times < MAX_TIMES) {
- // Never reach
- if (!containerRef.current) {
- setSyncState(function (ori) {
- return (0, _objectSpread2.default)({}, ori);
- });
- return;
- }
- collectHeight();
- var targetAlign = syncState.targetAlign,
- originAlign = syncState.originAlign,
- index = syncState.index,
- offset = syncState.offset;
- var height = containerRef.current.clientHeight;
- var needCollectHeight = false;
- var newTargetAlign = targetAlign;
- var targetTop = null;
- // Go to next frame if height not exist
- if (height) {
- var mergedAlign = targetAlign || originAlign;
- // Get top & bottom
- var stackTop = 0;
- var itemTop = 0;
- var itemBottom = 0;
- var maxLen = Math.min(data.length - 1, index);
- for (var i = 0; i <= maxLen; i += 1) {
- var key = getKey(data[i]);
- itemTop = stackTop;
- var cacheHeight = heights.get(key);
- itemBottom = itemTop + (cacheHeight === undefined ? itemHeight : cacheHeight);
- stackTop = itemBottom;
- }
- // Check if need sync height (visible range has item not record height)
- var leftHeight = mergedAlign === 'top' ? offset : height - offset;
- for (var _i = maxLen; _i >= 0; _i -= 1) {
- var _key = getKey(data[_i]);
- var _cacheHeight = heights.get(_key);
- if (_cacheHeight === undefined) {
- needCollectHeight = true;
- break;
- }
- leftHeight -= _cacheHeight;
- if (leftHeight <= 0) {
- break;
- }
- }
- // Scroll to
- switch (mergedAlign) {
- case 'top':
- targetTop = itemTop - offset;
- break;
- case 'bottom':
- targetTop = itemBottom - height + offset;
- break;
- default:
- {
- var scrollTop = containerRef.current.scrollTop;
- var scrollBottom = scrollTop + height;
- if (itemTop < scrollTop) {
- newTargetAlign = 'top';
- } else if (itemBottom > scrollBottom) {
- newTargetAlign = 'bottom';
- }
- }
- }
- if (targetTop !== null) {
- syncScrollTop(targetTop);
- }
- // One more time for sync
- if (targetTop !== syncState.lastTop) {
- needCollectHeight = true;
- }
- }
- // Trigger next effect
- if (needCollectHeight) {
- setSyncState((0, _objectSpread2.default)((0, _objectSpread2.default)({}, syncState), {}, {
- times: syncState.times + 1,
- targetAlign: newTargetAlign,
- lastTop: targetTop
- }));
- }
- } else if (process.env.NODE_ENV !== 'production' && (syncState === null || syncState === void 0 ? void 0 : syncState.times) === MAX_TIMES) {
- (0, _rcUtil.warning)(false, 'Seems `scrollTo` with `rc-virtual-list` reach the max limitation. Please fire issue for us. Thanks.');
- }
- }, [syncState, containerRef.current]);
- // =========================== Scroll To ===========================
- return function (arg) {
- // When not argument provided, we think dev may want to show the scrollbar
- if (arg === null || arg === undefined) {
- triggerFlash();
- return;
- }
- // Normal scroll logic
- _raf.default.cancel(scrollRef.current);
- if (typeof arg === 'number') {
- syncScrollTop(arg);
- } else if (arg && (0, _typeof2.default)(arg) === 'object') {
- var index;
- var align = arg.align;
- if ('index' in arg) {
- index = arg.index;
- } else {
- index = data.findIndex(function (item) {
- return getKey(item) === arg.key;
- });
- }
- var _arg$offset = arg.offset,
- offset = _arg$offset === void 0 ? 0 : _arg$offset;
- setSyncState({
- times: 0,
- index: index,
- offset: offset,
- originAlign: align
- });
- }
- };
- }
|