var __async = (__this, __arguments, generator) => {
  return new Promise((resolve, reject) => {
    var fulfilled = (value) => {
      try {
        step(generator.next(value));
      } catch (e) {
        reject(e);
      }
    };
    var rejected = (value) => {
      try {
        step(generator.throw(value));
      } catch (e) {
        reject(e);
      }
    };
    var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
    step((generator = generator.apply(__this, __arguments)).next());
  });
};
import React, { useCallback, useContext, useMemo, useRef } from "react";
import classnames from "classnames";
import { getScrollTop, preventDefault } from "../utils";
import { useTouch } from "../hooks/use-touch";
import { getScrollParent } from "../hooks/use-scroll-parent";
import useEventListener from "../hooks/use-event-listener";
import Loading from "../loading";
import { useSetState, useUpdateEffect } from "../hooks";
import ConfigProviderContext from "../config-provider/ConfigProviderContext";
const DEFAULT_HEAD_HEIGHT = 50;
const TEXT_STATUS = ["pulling", "loosing", "success"];
const PullRefresh = (props) => {
  const {
    prefixCls,
    createNamespace
  } = useContext(ConfigProviderContext);
  const [bem] = createNamespace("pull-refresh", prefixCls);
  const {
    disabled,
    animationDuration
  } = props;
  const root = useRef();
  const [state, updateState] = useSetState({
    refreshing: false,
    status: "normal",
    distance: 0,
    duration: 0
  });
  const track = useRef();
  const reachTop = useRef(null);
  const touch = useTouch();
  const getHeadStyle = () => {
    if (props.headHeight !== DEFAULT_HEAD_HEIGHT) {
      return {
        height: `${props.headHeight}px`
      };
    }
    return null;
  };
  const isTouchable = useCallback(() => {
    return state.status !== "loading" && state.status !== "success" && !disabled;
  }, [state.status, disabled]);
  const ease = (distance) => {
    const pullDistance = +(props.pullDistance || props.headHeight);
    if (distance > pullDistance) {
      if (distance < pullDistance * 2) {
        distance = pullDistance + (distance - pullDistance) / 2;
      } else {
        distance = pullDistance * 1.5 + (distance - pullDistance * 2) / 4;
      }
    }
    return Math.round(distance);
  };
  const setStatus = (distance, isLoading) => {
    const pullDistance = +(props.pullDistance || props.headHeight);
    const newState = {
      distance
    };
    if (isLoading) {
      newState.status = "loading";
    } else if (distance === 0) {
      newState.status = "normal";
    } else if (distance < pullDistance) {
      newState.status = "pulling";
    } else {
      newState.status = "loosing";
    }
    updateState(newState);
  };
  const getStatusText = () => {
    if (state.status === "normal") {
      return "";
    }
    return props[`${state.status}Text`];
  };
  const renderStatus = () => {
    const {
      status,
      distance
    } = state;
    if (typeof props[`${state.status}Text`] === "function") {
      return props[`${state.status}Text`]({
        distance
      });
    }
    const nodes = [];
    if (TEXT_STATUS.includes(status)) {
      nodes.push(/* @__PURE__ */ React.createElement("div", {
        key: "text",
        className: classnames(bem("text"))
      }, getStatusText()));
    }
    if (status === "loading") {
      nodes.push(/* @__PURE__ */ React.createElement(Loading, {
        key: "loading",
        className: classnames(bem("loading"))
      }, getStatusText()));
    }
    return nodes;
  };
  const showSuccessTip = () => {
    updateState({
      status: "success"
    });
    setTimeout(() => {
      setStatus(0);
    }, +props.successDuration);
  };
  const onRefresh = () => __async(void 0, null, function* () {
    try {
      updateState({
        refreshing: true
      });
      yield props.onRefresh();
      updateState({
        refreshing: false
      });
    } catch (error) {
      updateState({
        refreshing: false
      });
    }
  });
  const checkPosition = (event) => {
    const scrollTarget = getScrollParent(event.target);
    reachTop.current = getScrollTop(scrollTarget) === 0;
    if (reachTop.current) {
      updateState({
        duration: 0
      });
      touch.start(event);
    }
  };
  const onTouchStart = (event) => {
    if (isTouchable()) {
      checkPosition(event.nativeEvent);
    }
  };
  const onTouchMove = useCallback((event) => {
    if (isTouchable()) {
      if (!reachTop.current) {
        checkPosition(event);
      }
      touch.move(event);
      if (reachTop.current && touch.deltaY.current >= 0 && touch.isVertical()) {
        setStatus(ease(touch.deltaY.current));
        preventDefault(event);
      } else {
        setStatus(0);
      }
    }
  }, [reachTop.current, touch.deltaY, isTouchable]);
  const onTouchEnd = () => __async(void 0, null, function* () {
    if (reachTop.current && touch.deltaY && isTouchable()) {
      updateState({
        duration: +animationDuration
      });
      if (state.status === "loosing") {
        setStatus(+props.headHeight, true);
        onRefresh();
      } else {
        setStatus(0);
      }
    }
  });
  useEventListener("touchmove", onTouchMove, {
    target: track.current,
    depends: [reachTop.current, isTouchable(), touch.deltaY]
  });
  useUpdateEffect(() => {
    updateState({
      duration: +animationDuration
    });
    if (state.refreshing) {
      setStatus(+props.headHeight, true);
    } else if (props.successText) {
      showSuccessTip();
    } else {
      setStatus(0, false);
    }
  }, [state.refreshing]);
  const trackStyle = useMemo(() => ({
    transitionDuration: `${state.duration}ms`,
    transform: state.distance ? `translate3d(0,${state.distance}px, 0)` : ""
  }), [state.duration, state.distance]);
  return /* @__PURE__ */ React.createElement("div", {
    ref: root,
    className: classnames(props.className, bem()),
    style: props.style
  }, /* @__PURE__ */ React.createElement("div", {
    ref: track,
    className: classnames(bem("track")),
    style: trackStyle,
    onTouchStart,
    onTouchEnd,
    onTouchCancel: onTouchEnd
  }, /* @__PURE__ */ React.createElement("div", {
    className: classnames(bem("head")),
    style: getHeadStyle()
  }, renderStatus()), props.children));
};
PullRefresh.defaultProps = {
  headHeight: 50,
  animationDuration: 300,
  successDuration: 500,
  pullingText: "\u4E0B\u62C9\u5373\u53EF\u5237\u65B0...",
  loosingText: "\u91CA\u653E\u5373\u53EF\u5237\u65B0...",
  loadingText: "\u52A0\u8F7D\u4E2D..."
};
var stdin_default = PullRefresh;
export {
  stdin_default as default
};
