acud
Version:
acg react 组件库
98 lines (96 loc) • 4.17 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _typeof3 = require("@babel/runtime/helpers/typeof");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = useScrollTo;
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
var React = _interopRequireWildcard(require("react"));
var _raf = _interopRequireDefault(require("rc-util/lib/raf"));
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof3(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
/* eslint-disable no-param-reassign */
function useScrollTo(containerRef, data, heights, itemHeight, getKey, collectHeight, syncScrollTop, triggerFlash) {
var scrollRef = React.useRef();
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;
// We will retry 3 times in case dynamic height shaking
var _syncScroll = function syncScroll(times, targetAlign) {
if (times < 0 || !containerRef.current) return;
var height = containerRef.current.clientHeight;
var needCollectHeight = false;
var newTargetAlign = targetAlign;
// Go to next frame if height not exist
if (height) {
var mergedAlign = targetAlign || align;
// Get top & bottom
var stackTop = 0;
var itemTop = 0;
var itemBottom = 0;
var maxLen = Math.min(data.length, 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;
if (i === index && cacheHeight === undefined) {
needCollectHeight = true;
}
}
// Scroll to
var targetTop = null;
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 && targetTop !== containerRef.current.scrollTop) {
syncScrollTop(targetTop);
}
}
// We will retry since element may not sync height as it described
scrollRef.current = (0, _raf["default"])(function () {
if (needCollectHeight) {
collectHeight();
}
_syncScroll(times - 1, newTargetAlign);
});
};
_syncScroll(3);
}
};
}