import { defineComponent, shallowRef, watchEffect, ref, onMounted, onActivated, nextTick, watch, onBeforeUnmount, createVNode } from 'vue';
import '../../../utils/index.mjs';
import { useInjectTable } from './context/TableContext.mjs';
import { useLayoutState } from './hooks/useFrame.mjs';
import { getOffset } from '../../../utils/dom/css.mjs';
import { getScrollBarSize } from '../../../utils/scroll/getScrollBarSize.mjs';
import { addEventListenerWrap } from '../../../utils/event/addEventListener.mjs';
import { classNames } from '../../../utils/dom/class.mjs';

var StickyScrollBar = /* @__PURE__ */ defineComponent({
  name: "StickyScrollBar",
  inheritAttrs: false,
  props: ["offsetScroll", "container", "scrollBodyRef", "scrollBodySizeInfo"],
  emits: ["scroll"],
  setup(props, {
    emit,
    expose
  }) {
    const tableContext = useInjectTable();
    const bodyScrollWidth = shallowRef(0);
    const bodyWidth = shallowRef(0);
    const scrollBarWidth = shallowRef(0);
    watchEffect(() => {
      bodyScrollWidth.value = props.scrollBodySizeInfo.scrollWidth || 0;
      bodyWidth.value = props.scrollBodySizeInfo.clientWidth || 0;
      scrollBarWidth.value = bodyScrollWidth.value && bodyWidth.value * (bodyWidth.value / bodyScrollWidth.value);
    }, {
      flush: "post"
    });
    const scrollBarRef = shallowRef();
    const [scrollState, setScrollState] = useLayoutState({
      scrollLeft: 0,
      isHiddenScrollBar: true
    });
    const refState = ref({
      delta: 0,
      x: 0
    });
    const isActive = shallowRef(false);
    const onMouseUp = () => {
      isActive.value = false;
    };
    const onMouseDown = (event) => {
      refState.value = {
        delta: event.pageX - scrollState.value.scrollLeft,
        x: 0
      };
      isActive.value = true;
      event.preventDefault();
    };
    const onMouseMove = (event) => {
      const {
        buttons
      } = event || (window == null ? void 0 : window.event);
      if (!isActive.value || buttons === 0) {
        if (isActive.value)
          isActive.value = false;
        return;
      }
      let left = refState.value.x + event.pageX - refState.value.x - refState.value.delta;
      if (left <= 0)
        left = 0;
      if (left + scrollBarWidth.value >= bodyWidth.value)
        left = bodyWidth.value - scrollBarWidth.value;
      emit("scroll", {
        scrollLeft: left / bodyWidth.value * (bodyScrollWidth.value + 2)
      });
      refState.value.x = event.pageX;
    };
    const onContainerScroll = () => {
      if (!props.scrollBodyRef.value)
        return;
      const tableOffsetTop = getOffset(props.scrollBodyRef.value).top;
      const tableBottomOffset = tableOffsetTop + props.scrollBodyRef.value.offsetHeight;
      const currentClientOffset = props.container === window ? document.documentElement.scrollTop + window.innerHeight : getOffset(props.container).top + props.container.clientHeight;
      if (tableBottomOffset - getScrollBarSize() <= currentClientOffset || tableOffsetTop >= currentClientOffset - props.offsetScroll) {
        setScrollState((state) => ({
          ...state,
          isHiddenScrollBar: true
        }));
      } else {
        setScrollState((state) => ({
          ...state,
          isHiddenScrollBar: false
        }));
      }
    };
    const setScrollLeft = (left) => {
      setScrollState((state) => {
        return {
          ...state,
          scrollLeft: left / bodyScrollWidth.value * bodyWidth.value || 0
        };
      });
    };
    expose({
      setScrollLeft
    });
    let onMouseUpListener = null;
    let onMouseMoveListener = null;
    let onResizeListener = null;
    let onScrollListener = null;
    onMounted(() => {
      onMouseUpListener = addEventListenerWrap(document.body, "mouseup", onMouseUp, false);
      onMouseMoveListener = addEventListenerWrap(document.body, "mousemove", onMouseMove, false);
      onResizeListener = addEventListenerWrap(window, "resize", onContainerScroll, false);
    });
    onActivated(() => {
      nextTick(() => {
        onContainerScroll();
      });
    });
    onMounted(() => {
      setTimeout(() => {
        watch([scrollBarWidth, isActive], () => {
          onContainerScroll();
        }, {
          immediate: true,
          flush: "post"
        });
      });
    });
    watch(() => props.container, () => {
      onScrollListener == null ? void 0 : onScrollListener.remove();
      onScrollListener = addEventListenerWrap(props.container, "scroll", onContainerScroll, false);
    }, {
      immediate: true,
      flush: "post"
    });
    onBeforeUnmount(() => {
      onMouseUpListener == null ? void 0 : onMouseUpListener.remove();
      onMouseMoveListener == null ? void 0 : onMouseMoveListener.remove();
      onScrollListener == null ? void 0 : onScrollListener.remove();
      onResizeListener == null ? void 0 : onResizeListener.remove();
    });
    watch(() => ({
      ...scrollState.value
    }), (newState, preState) => {
      if (newState.isHiddenScrollBar !== (preState == null ? void 0 : preState.isHiddenScrollBar) && !newState.isHiddenScrollBar) {
        setScrollState((state) => {
          const bodyNode = props.scrollBodyRef.value;
          if (!bodyNode)
            return state;
          return {
            ...state,
            scrollLeft: bodyNode.scrollLeft / bodyNode.scrollWidth * bodyNode.clientWidth
          };
        });
      }
    }, {
      immediate: true
    });
    const scrollbarSize = getScrollBarSize();
    return () => {
      if (bodyScrollWidth.value <= bodyWidth.value || !scrollBarWidth.value || scrollState.value.isHiddenScrollBar)
        return null;
      const {
        prefixCls
      } = tableContext;
      return createVNode("div", {
        "style": {
          height: `${scrollbarSize}px`,
          width: `${bodyWidth.value}px`,
          bottom: `${props.offsetScroll}px`
        },
        "class": `${prefixCls}-sticky-scroll`
      }, [createVNode("div", {
        "onMousedown": onMouseDown,
        "ref": scrollBarRef,
        "class": classNames(`${prefixCls}-sticky-scroll-bar`, {
          [`${prefixCls}-sticky-scroll-bar-active`]: isActive.value
        }),
        "style": {
          width: `${scrollBarWidth.value}px`,
          transform: `translate3d(${scrollState.value.scrollLeft}px, 0, 0)`
        }
      }, null)]);
    };
  }
});

export { StickyScrollBar as default };
//# sourceMappingURL=stickyScrollBar.mjs.map
