"use strict";
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
const Vue = require("vue");
const index_esm = require("../../../@vant/use/dist/index.esm.js");
const useLockScroll = require("../composables/use-lock-scroll.js");
const useTouch = require("../composables/use-touch.js");
const useSyncPropRef = require("../composables/use-sync-prop-ref.js");
const props = require("../utils/props.js");
const create = require("../utils/create.js");
const dom = require("../utils/dom.js");
const format = require("../utils/format.js");
const closest = require("../utils/closest.js");
const floatingPanelProps = {
  height: props.makeNumericProp(0),
  anchors: props.makeArrayProp(),
  duration: props.makeNumericProp(0.3),
  magnetic: props.truthProp,
  draggable: props.truthProp,
  contentDraggable: props.truthProp,
  lockScroll: Boolean,
  safeAreaInsetBottom: props.truthProp
};
const [name, bem] = create.createNamespace("floating-panel");
var stdin_default = Vue.defineComponent({
  name,
  props: floatingPanelProps,
  emits: ["heightChange", "update:height"],
  setup(props2, {
    emit,
    slots
  }) {
    const DAMP = 0.2;
    const rootRef = Vue.ref();
    const contentRef = Vue.ref();
    const height = useSyncPropRef.useSyncPropRef(() => +props2.height, (value) => emit("update:height", value));
    const boundary = Vue.computed(() => {
      var _a, _b;
      return {
        min: (_a = props2.anchors[0]) != null ? _a : 100,
        max: (_b = props2.anchors[props2.anchors.length - 1]) != null ? _b : Math.round(dom.windowHeight.value * 0.6)
      };
    });
    const anchors = Vue.computed(() => props2.anchors.length >= 2 ? props2.anchors : [boundary.value.min, boundary.value.max]);
    const dragging = Vue.ref(false);
    const rootStyle = Vue.computed(() => ({
      height: format.addUnit(boundary.value.max),
      transform: `translateY(calc(100% + ${format.addUnit(-height.value)}))`,
      transition: !dragging.value ? `transform ${props2.duration}s cubic-bezier(0.18, 0.89, 0.32, 1.28)` : "none"
    }));
    const ease = (moveY) => {
      const absDistance = Math.abs(moveY);
      const {
        min,
        max
      } = boundary.value;
      if (absDistance > max) {
        return -(max + (absDistance - max) * DAMP);
      }
      if (absDistance < min) {
        return -(min - (min - absDistance) * DAMP);
      }
      return moveY;
    };
    let startY;
    let maxScroll = -1;
    const touch = useTouch.useTouch();
    const onTouchstart = (e) => {
      if (!props2.draggable) return;
      touch.start(e);
      dragging.value = true;
      startY = -height.value;
      maxScroll = -1;
    };
    const onTouchmove = (e) => {
      var _a;
      if (!props2.draggable) return;
      touch.move(e);
      const target = e.target;
      if (contentRef.value === target || ((_a = contentRef.value) == null ? void 0 : _a.contains(target))) {
        const {
          scrollTop
        } = contentRef.value;
        maxScroll = Math.max(maxScroll, scrollTop);
        if (!props2.contentDraggable) return;
        if (-startY < boundary.value.max) {
          dom.preventDefault(e, true);
        } else if (!(scrollTop <= 0 && touch.deltaY.value > 0) || maxScroll > 0) {
          return;
        }
      }
      const moveY = touch.deltaY.value + startY;
      height.value = -ease(moveY);
    };
    const onTouchend = () => {
      maxScroll = -1;
      if (!dragging.value) {
        return;
      }
      dragging.value = false;
      if (!props2.draggable) {
        return;
      }
      if (props2.magnetic) {
        height.value = closest.closest(anchors.value, height.value);
      } else {
        const {
          min,
          max
        } = boundary.value;
        height.value = Math.max(min, Math.min(max, height.value));
      }
      if (height.value !== -startY) {
        emit("heightChange", {
          height: height.value
        });
      }
    };
    Vue.watch(boundary, () => {
      height.value = closest.closest(anchors.value, height.value);
    }, {
      immediate: true
    });
    useLockScroll.useLockScroll(rootRef, () => props2.lockScroll || dragging.value);
    index_esm.useEventListener("touchmove", onTouchmove, {
      target: rootRef
    });
    const renderHeader = () => {
      if (slots.header) {
        return slots.header();
      }
      if (!props2.draggable) {
        return null;
      }
      return Vue.createVNode("div", {
        "class": bem("header")
      }, [Vue.createVNode("div", {
        "class": bem("header-bar")
      }, null)]);
    };
    return () => {
      var _a;
      return Vue.createVNode("div", {
        "class": [bem(), {
          "van-safe-area-bottom": props2.safeAreaInsetBottom
        }],
        "ref": rootRef,
        "style": rootStyle.value,
        "onTouchstartPassive": onTouchstart,
        "onTouchend": onTouchend,
        "onTouchcancel": onTouchend
      }, [renderHeader(), Vue.createVNode("div", {
        "class": bem("content"),
        "ref": contentRef,
        "style": {
          paddingBottom: format.addUnit(boundary.value.max - height.value)
        }
      }, [(_a = slots.default) == null ? void 0 : _a.call(slots)])]);
    };
  }
});
exports.default = stdin_default;
exports.floatingPanelProps = floatingPanelProps;
