UNPKG

ant-design-vue

Version:

An enterprise-class UI design language and Vue-based implementation

103 lines (81 loc) 3.35 kB
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } import raf from '../../_util/raf'; export default function useScrollTo(containerRef, state, heights, props, getKey, collectHeight, syncScrollTop, triggerFlash) { var scroll = null; 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.cancel(scroll); var data = state.mergedData; var itemHeight = props.itemHeight; if (typeof arg === 'number') { syncScrollTop(arg); } else if (arg && _typeof(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.value) return; var height = containerRef.value.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; for (var i = 0; i <= index; i += 1) { var key = getKey(data[i]); itemTop = stackTop; var cacheHeight = heights[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.value.scrollTop; var scrollBottom = scrollTop + height; if (itemTop < scrollTop) { newTargetAlign = 'top'; } else if (itemBottom > scrollBottom) { newTargetAlign = 'bottom'; } } } if (targetTop !== null && targetTop !== containerRef.value.scrollTop) { syncScrollTop(targetTop); } } // We will retry since element may not sync height as it described scroll = raf(function () { if (needCollectHeight) { collectHeight(); } syncScroll(times - 1, newTargetAlign); }); }; syncScroll(3); } }; }