UNPKG

tdesign-vue

Version:
288 lines (284 loc) 13.2 kB
/** * tdesign v1.14.1 * (c) 2025 tdesign * @license MIT */ import { ref, computed, watch, onBeforeUnmount } from '@vue/composition-api'; import { debounce } from 'lodash-es'; import { off, on } from '../../utils/dom.js'; import 'vue'; import 'raf'; import '../../utils/easing.js'; function useAffix(props) { var tableContentRef = ref(); var affixHeaderRef = ref(); var affixFooterRef = ref(); var horizontalScrollbarRef = ref(); var paginationRef = ref(); var showAffixHeader = ref(true); var showAffixFooter = ref(true); var showAffixPagination = ref(true); var isMousedown = false; var isMouseInScrollableArea = false; var isVirtualScroll = computed(function () { return props.scroll && props.scroll.type === "virtual" && (props.scroll.threshold || 100) < props.data.length; }); var isAffixed = computed(function () { return !!(props.headerAffixedTop || props.footerAffixedBottom || props.horizontalScrollAffixedBottom); }); var lastScrollLeft = 0; var onHorizontalScroll = function onHorizontalScroll(scrollElement) { if (!isAffixed.value && !isVirtualScroll.value) return; var target = scrollElement; if (!target && tableContentRef.value) { lastScrollLeft = 0; target = tableContentRef.value; } if (!target) return; var left = target.scrollLeft; if (lastScrollLeft === left) return; lastScrollLeft = left; var toUpdateScrollElement = [tableContentRef.value, affixHeaderRef.value, affixFooterRef.value, horizontalScrollbarRef.value]; for (var i = 0, len = toUpdateScrollElement.length; i < len; i++) { if (toUpdateScrollElement[i] && scrollElement !== toUpdateScrollElement[i]) { toUpdateScrollElement[i].scrollLeft = left; } } }; var isAffixedBottomElementShow = function isAffixedBottomElementShow(elementRect, tableRect, headerHeight) { return tableRect.top + headerHeight < elementRect.top && elementRect.top > elementRect.height; }; var isAffixedBottomScrollShow = function isAffixedBottomScrollShow(elementRect, tableRect, headerHeight) { return !!tableContentRef.value && tableContentRef.value.scrollWidth > tableContentRef.value.clientWidth && isAffixedBottomElementShow(elementRect, tableRect, headerHeight); }; var getOffsetTop = function getOffsetTop(props2) { if (typeof props2 === "boolean") return 0; return props2.offsetTop || 0; }; var updateAffixHeaderOrFooter = function updateAffixHeaderOrFooter() { var _tableContentRef$valu, _tableContentRef$valu2, _affixFooterRef$value; if (!isAffixed.value && !isVirtualScroll.value) return; var pos = (_tableContentRef$valu = tableContentRef.value) === null || _tableContentRef$valu === void 0 ? void 0 : _tableContentRef$valu.getBoundingClientRect(); if (!pos) return; var headerRect = (_tableContentRef$valu2 = tableContentRef.value) === null || _tableContentRef$valu2 === void 0 || (_tableContentRef$valu2 = _tableContentRef$valu2.querySelector("thead")) === null || _tableContentRef$valu2 === void 0 ? void 0 : _tableContentRef$valu2.getBoundingClientRect(); var headerHeight = (headerRect === null || headerRect === void 0 ? void 0 : headerRect.height) || 0; var footerRect = (_affixFooterRef$value = affixFooterRef.value) === null || _affixFooterRef$value === void 0 ? void 0 : _affixFooterRef$value.getBoundingClientRect(); if ((props.headerAffixedTop || isVirtualScroll.value) && affixHeaderRef.value) { var offsetTop = getOffsetTop(props.headerAffixProps || props.headerAffixedTop); var footerHeight = (footerRect === null || footerRect === void 0 ? void 0 : footerRect.height) || 0; var r = Math.abs(pos.top) < pos.height - headerHeight - offsetTop - footerHeight; if (isVirtualScroll.value) { r = pos.top > -1 * headerRect.height; } showAffixHeader.value = r; } if (props.footerAffixedBottom && affixFooterRef !== null && affixFooterRef !== void 0 && affixFooterRef.value) { showAffixFooter.value = isAffixedBottomElementShow(footerRect, pos, headerHeight); } else if (props.horizontalScrollAffixedBottom && horizontalScrollbarRef !== null && horizontalScrollbarRef !== void 0 && horizontalScrollbarRef.value) { var horizontalScrollbarRect = horizontalScrollbarRef.value.getBoundingClientRect(); showAffixFooter.value = isAffixedBottomScrollShow(horizontalScrollbarRect, pos, headerHeight); } if (props.paginationAffixedBottom && paginationRef.value) { var pageRect = paginationRef.value.getBoundingClientRect(); showAffixPagination.value = isAffixedBottomElementShow(pageRect, pos, headerHeight); } }; var onDocumentScroll = function onDocumentScroll() { updateAffixHeaderOrFooter(); }; var onFootScroll = function onFootScroll() { onHorizontalScroll(affixFooterRef.value); }; var onHeaderScroll = function onHeaderScroll() { onHorizontalScroll(affixHeaderRef.value); }; var horizontalScrollbarScroll = function horizontalScrollbarScroll() { onHorizontalScroll(horizontalScrollbarRef.value); }; var onTableContentScroll = function onTableContentScroll() { onHorizontalScroll(tableContentRef.value); }; var onFootMouseEnter = function onFootMouseEnter() { on(affixFooterRef.value, "scroll", onFootScroll); }; var onFootMouseLeave = function onFootMouseLeave() { off(affixFooterRef.value, "scroll", onFootScroll); }; var onHeaderMouseEnter = function onHeaderMouseEnter() { on(affixHeaderRef.value, "scroll", onHeaderScroll); onMouseEnterScrollableArea(); }; var onHeaderMouseLeave = function onHeaderMouseLeave() { if (!isMousedown) off(affixHeaderRef.value, "scroll", onHeaderScroll); onMouseLeaveScrollableArea(); }; var onScrollbarMouseEnter = function onScrollbarMouseEnter() { on(horizontalScrollbarRef.value, "scroll", horizontalScrollbarScroll); }; var onScrollbarMouseLeave = function onScrollbarMouseLeave() { off(horizontalScrollbarRef.value, "scroll", horizontalScrollbarScroll); }; var onTableContentMouseEnter = function onTableContentMouseEnter() { on(tableContentRef.value, "scroll", onTableContentScroll); onMouseEnterScrollableArea(); }; var onTableContentMouseLeave = function onTableContentMouseLeave() { if (!isMousedown) off(tableContentRef.value, "scroll", onTableContentScroll); onMouseLeaveScrollableArea(); }; var onMousedown = function onMousedown() { isMousedown = true; }; var onMouseup = function onMouseup() { isMousedown = false; if (!isMouseInScrollableArea) { off(affixHeaderRef.value, "scroll", onHeaderScroll); off(tableContentRef.value, "scroll", onTableContentScroll); } }; var onMouseEnterScrollableArea = function onMouseEnterScrollableArea() { isMouseInScrollableArea = true; }; var onMouseLeaveScrollableArea = function onMouseLeaveScrollableArea() { isMouseInScrollableArea = false; }; var addHorizontalScrollListeners = function addHorizontalScrollListeners() { on(window, "mousedown", onMousedown); on(window, "mouseup", onMouseup); removeHorizontalScrollListeners(); if (affixHeaderRef.value) { on(affixHeaderRef.value, "mouseenter", onHeaderMouseEnter); on(affixHeaderRef.value, "mouseleave", onHeaderMouseLeave); } if (props.footerAffixedBottom && affixFooterRef.value) { on(affixFooterRef.value, "mouseenter", onFootMouseEnter); on(affixFooterRef.value, "mouseleave", onFootMouseLeave); } if (props.horizontalScrollAffixedBottom && horizontalScrollbarRef.value) { on(horizontalScrollbarRef.value, "mouseenter", onScrollbarMouseEnter); on(horizontalScrollbarRef.value, "mouseleave", onScrollbarMouseLeave); } if ((isAffixed.value || isVirtualScroll.value) && tableContentRef.value) { on(tableContentRef.value, "mouseenter", onTableContentMouseEnter); on(tableContentRef.value, "mouseleave", onTableContentMouseLeave); } }; var activatingTouchScrollListenerCleanups = []; var setupElementTouchScrollListener = function setupElementTouchScrollListener(element) { var debounceOffScrollListener = debounce(function (listener) { off(element, "scroll", listener); }, 200); function onElementTouchScroll() { onHorizontalScroll(element); debounceOffScrollListener(onElementTouchScroll); } function onElementTouchStart(e) { if (e.composedPath().includes(element)) { activatingTouchScrollListenerCleanups.forEach(function (cleanup) { return cleanup(); }); activatingTouchScrollListenerCleanups.length = 0; on(element, "scroll", onElementTouchScroll); debounceOffScrollListener(onElementTouchScroll); activatingTouchScrollListenerCleanups.push(function () { off(element, "scroll", onElementTouchScroll); }); } } on(element, "touchstart", onElementTouchStart); function removeElementTouchScrollListener() { off(element, "touchstart", onElementTouchStart); } return { removeElementTouchScrollListener: removeElementTouchScrollListener }; }; var elementTouchScrollCleanups = []; var cleanupElementTouchScroll = function cleanupElementTouchScroll() { elementTouchScrollCleanups.forEach(function (cleanup) { return cleanup(); }); elementTouchScrollCleanups.length = 0; }; var removeHorizontalScrollListeners = function removeHorizontalScrollListeners() { off(window, "mousedown", onMousedown); off(window, "mouseup", onMouseup); cleanupElementTouchScroll(); if (affixHeaderRef.value) { off(affixHeaderRef.value, "mouseenter", onHeaderMouseEnter); off(affixHeaderRef.value, "mouseleave", onHeaderMouseLeave); var _setupElementTouchScr = setupElementTouchScrollListener(affixHeaderRef.value), removeElementTouchScrollListener = _setupElementTouchScr.removeElementTouchScrollListener; elementTouchScrollCleanups.push(removeElementTouchScrollListener); } if (affixFooterRef.value) { off(affixFooterRef.value, "mouseenter", onFootMouseEnter); off(affixFooterRef.value, "mouseleave", onFootMouseLeave); var _setupElementTouchScr2 = setupElementTouchScrollListener(affixFooterRef.value), _removeElementTouchScrollListener = _setupElementTouchScr2.removeElementTouchScrollListener; elementTouchScrollCleanups.push(_removeElementTouchScrollListener); } if (tableContentRef.value) { off(tableContentRef.value, "mouseenter", onTableContentMouseEnter); off(tableContentRef.value, "mouseleave", onTableContentMouseLeave); var _setupElementTouchScr3 = setupElementTouchScrollListener(horizontalScrollbarRef.value), _removeElementTouchScrollListener2 = _setupElementTouchScr3.removeElementTouchScrollListener; elementTouchScrollCleanups.push(_removeElementTouchScrollListener2); } if (horizontalScrollbarRef.value) { off(horizontalScrollbarRef.value, "mouseenter", onScrollbarMouseEnter); off(horizontalScrollbarRef.value, "mouseleave", onScrollbarMouseLeave); var _setupElementTouchScr4 = setupElementTouchScrollListener(tableContentRef.value), _removeElementTouchScrollListener3 = _setupElementTouchScr4.removeElementTouchScrollListener; elementTouchScrollCleanups.push(_removeElementTouchScrollListener3); } }; var addVerticalScrollListener = function addVerticalScrollListener() { if (!isAffixed.value && !props.paginationAffixedBottom) return; var timer = setTimeout(function () { if (isAffixed.value || props.paginationAffixedBottom) { on(document, "scroll", onDocumentScroll); } else { off(document, "scroll", onDocumentScroll); } clearTimeout(timer); }); }; watch([affixHeaderRef, affixFooterRef, horizontalScrollbarRef, tableContentRef], function () { addHorizontalScrollListeners(); onHorizontalScroll(); updateAffixHeaderOrFooter(); }); watch(isAffixed, addVerticalScrollListener); watch(function () { return [props.data, props.columns, props.headerAffixedTop, props.footerAffixedBottom, props.horizontalScrollAffixedBottom]; }, function () { onHorizontalScroll(); }); onBeforeUnmount(function () { off(document, "scroll", onDocumentScroll); removeHorizontalScrollListeners(); affixHeaderRef.value = null; affixFooterRef.value = null; horizontalScrollbarRef.value = null; tableContentRef.value = null; }); var setTableContentRef = function setTableContentRef(tableContent) { tableContentRef.value = tableContent; addVerticalScrollListener(); }; return { showAffixHeader: showAffixHeader, showAffixFooter: showAffixFooter, showAffixPagination: showAffixPagination, affixHeaderRef: affixHeaderRef, affixFooterRef: affixFooterRef, horizontalScrollbarRef: horizontalScrollbarRef, paginationRef: paginationRef, onHorizontalScroll: onHorizontalScroll, setTableContentRef: setTableContentRef, updateAffixHeaderOrFooter: updateAffixHeaderOrFooter }; } export { useAffix as default }; //# sourceMappingURL=useAffix.js.map