/**
 * ldesign v0.2.14
 * (c) 2022/11/2 16:16 built by swimly
 * @license MIT
 */

import { ref, computed, watch, onBeforeMount } from '@vue/composition-api';
import { off, on } from '../../../utils/dom.js';
import 'vue';
import 'raf';
import 'lodash/isString';
import '../../../_chunks/dep-70c789e5.js';
import '../../../_chunks/dep-5210251b.js';
import '../../../utils/easing.js';

function useAffix(props) {
  const tableContentRef = ref();
  const affixHeaderRef = ref();
  const affixFooterRef = ref();
  const horizontalScrollbarRef = ref();
  const paginationRef = ref();
  const showAffixHeader = ref(true);
  const showAffixFooter = ref(true);
  const showAffixPagination = ref(true);
  const isVirtualScroll = computed(() => props.scroll && props.scroll.type === "virtual" && (props.scroll.threshold || 100) < props.data.length);
  const isAffixed = computed(() => !!(props.headerAffixedTop || props.footerAffixedBottom || props.horizontalScrollAffixedBottom));
  let lastScrollLeft = 0;
  const onHorizontalScroll = scrollElement => {
    if (!isAffixed.value && !isVirtualScroll.value) return;
    let target = scrollElement;
    if (!target && tableContentRef.value) {
      lastScrollLeft = 0;
      target = tableContentRef.value;
    }
    if (!target) return;
    const left = target.scrollLeft;
    if (lastScrollLeft === left) return;
    lastScrollLeft = left;
    const toUpdateScrollElement = [tableContentRef.value, affixHeaderRef.value, affixFooterRef.value, horizontalScrollbarRef.value];
    for (let i = 0, len = toUpdateScrollElement.length; i < len; i++) {
      if (toUpdateScrollElement[i] && scrollElement !== toUpdateScrollElement[i]) toUpdateScrollElement[i].scrollLeft = left;
    }
  };
  const isAffixedBottomElementShow = (elementRect, tableRect, headerHeight) => tableRect.top + headerHeight < elementRect.top && elementRect.top > elementRect.height;
  const isAffixedBottomScrollShow = (elementRect, tableRect, headerHeight) => tableContentRef.value.scrollWidth > tableContentRef.value.clientWidth && isAffixedBottomElementShow(elementRect, tableRect, headerHeight);
  const getOffsetTop = props2 => {
    if (typeof props2 === "boolean") return 0;
    return props2.offsetTop || 0;
  };
  const updateAffixHeaderOrFooter = () => {
    var _tableContentRef$valu, _tableContentRef$valu2, _tableContentRef$valu3, _affixFooterRef$value;
    if (!isAffixed.value && !isVirtualScroll.value) return;
    const pos = (_tableContentRef$valu = tableContentRef.value) === null || _tableContentRef$valu === void 0 ? void 0 : _tableContentRef$valu.getBoundingClientRect();
    const headerRect = (_tableContentRef$valu2 = tableContentRef.value) === null || _tableContentRef$valu2 === void 0 ? void 0 : (_tableContentRef$valu3 = _tableContentRef$valu2.querySelector("thead")) === null || _tableContentRef$valu3 === void 0 ? void 0 : _tableContentRef$valu3.getBoundingClientRect();
    const headerHeight = (headerRect === null || headerRect === void 0 ? void 0 : headerRect.height) || 0;
    const footerRect = (_affixFooterRef$value = affixFooterRef.value) === null || _affixFooterRef$value === void 0 ? void 0 : _affixFooterRef$value.getBoundingClientRect();
    if ((props.headerAffixedTop || isVirtualScroll.value) && affixHeaderRef.value) {
      const offsetTop = getOffsetTop(props.headerAffixProps || props.headerAffixedTop);
      const footerHeight = (footerRect === null || footerRect === void 0 ? void 0 : footerRect.height) || 0;
      let 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) {
      const horizontalScrollbarRect = horizontalScrollbarRef.value.getBoundingClientRect();
      showAffixFooter.value = isAffixedBottomScrollShow(horizontalScrollbarRect, pos, headerHeight);
    }
    if (props.paginationAffixedBottom && paginationRef.value) {
      const pageRect = paginationRef.value.getBoundingClientRect();
      showAffixPagination.value = isAffixedBottomElementShow(pageRect, pos, headerHeight);
    }
  };
  const onDocumentScroll = () => {
    updateAffixHeaderOrFooter();
  };
  const onFootScroll = () => {
    onHorizontalScroll(affixFooterRef.value);
  };
  const onHeaderScroll = () => {
    onHorizontalScroll(affixHeaderRef.value);
  };
  const horizontalScrollbarScroll = () => {
    onHorizontalScroll(horizontalScrollbarRef.value);
  };
  const onTableContentScroll = () => {
    onHorizontalScroll(tableContentRef.value);
  };
  const onFootMouseEnter = () => {
    on(affixFooterRef.value, "scroll", onFootScroll);
  };
  const onFootMouseLeave = () => {
    off(affixFooterRef.value, "scroll", onFootScroll);
  };
  const onHeaderMouseEnter = () => {
    on(affixHeaderRef.value, "scroll", onHeaderScroll);
  };
  const onHeaderMouseLeave = () => {
    off(affixHeaderRef.value, "scroll", onHeaderScroll);
  };
  const onScrollbarMouseEnter = () => {
    on(horizontalScrollbarRef.value, "scroll", horizontalScrollbarScroll);
  };
  const onScrollbarMouseLeave = () => {
    off(horizontalScrollbarRef.value, "scroll", horizontalScrollbarScroll);
  };
  const onTableContentMouseEnter = () => {
    on(tableContentRef.value, "scroll", onTableContentScroll);
  };
  const onTableContentMouseLeave = () => {
    off(tableContentRef.value, "scroll", onTableContentScroll);
  };
  const addHorizontalScrollListeners = () => {
    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);
    }
  };
  const removeHorizontalScrollListeners = () => {
    if (affixHeaderRef.value) {
      off(affixHeaderRef.value, "mouseenter", onHeaderMouseEnter);
      off(affixHeaderRef.value, "mouseleave", onHeaderMouseLeave);
    }
    if (affixFooterRef.value) {
      off(affixFooterRef.value, "mouseenter", onFootMouseEnter);
      off(affixFooterRef.value, "mouseleave", onFootMouseLeave);
    }
    if (tableContentRef.value) {
      off(tableContentRef.value, "mouseenter", onTableContentMouseEnter);
      off(tableContentRef.value, "mouseleave", onTableContentMouseLeave);
    }
    if (horizontalScrollbarRef.value) {
      off(horizontalScrollbarRef.value, "mouseenter", onScrollbarMouseEnter);
      off(horizontalScrollbarRef.value, "mouseleave", onScrollbarMouseLeave);
    }
  };
  const addVerticalScrollListener = () => {
    if (!isAffixed.value && !props.paginationAffixedBottom) return;
    const timer = setTimeout(() => {
      if (isAffixed.value || props.paginationAffixedBottom) on(document, "scroll", onDocumentScroll);else off(document, "scroll", onDocumentScroll);
      clearTimeout(timer);
    });
  };
  watch([affixHeaderRef, affixFooterRef, horizontalScrollbarRef, tableContentRef], () => {
    addHorizontalScrollListeners();
    onHorizontalScroll();
    updateAffixHeaderOrFooter();
  });
  watch(isAffixed, addVerticalScrollListener);
  watch(() => [props.data, props.columns, props.headerAffixedTop, props.footerAffixedBottom, props.horizontalScrollAffixedBottom], () => {
    onHorizontalScroll();
  });
  onBeforeMount(() => {
    off(document, "scroll", onDocumentScroll);
    removeHorizontalScrollListeners();
  });
  const setTableContentRef = tableContent => {
    tableContentRef.value = tableContent;
    addVerticalScrollListener();
  };
  return {
    showAffixHeader,
    showAffixFooter,
    showAffixPagination,
    affixHeaderRef,
    affixFooterRef,
    horizontalScrollbarRef,
    paginationRef,
    onHorizontalScroll,
    setTableContentRef,
    updateAffixHeaderOrFooter
  };
}

export { useAffix as default };
//# sourceMappingURL=useAffix.js.map
