"use strict";
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
const Vue = require("vue");
const utils = require("./utils.js");
const index_esm = require("../../../@vant/use/dist/index.esm.js");
const useTouch = require("../composables/use-touch.js");
const useExpose = require("../composables/use-expose.js");
const props = require("../utils/props.js");
const create = require("../utils/create.js");
const format = require("../utils/format.js");
const dom = require("../utils/dom.js");
const DEFAULT_DURATION = 200;
const MOMENTUM_TIME = 300;
const MOMENTUM_DISTANCE = 15;
const [name, bem] = create.createNamespace("picker-column");
const PICKER_KEY = Symbol(name);
var stdin_default = Vue.defineComponent({
  name,
  props: {
    value: props.numericProp,
    fields: props.makeRequiredProp(Object),
    options: props.makeArrayProp(),
    readonly: Boolean,
    allowHtml: Boolean,
    optionHeight: props.makeRequiredProp(Number),
    swipeDuration: props.makeRequiredProp(props.numericProp),
    visibleOptionNum: props.makeRequiredProp(props.numericProp)
  },
  emits: ["change", "clickOption", "scrollInto"],
  setup(props2, {
    emit,
    slots
  }) {
    let moving;
    let startOffset;
    let touchStartTime;
    let momentumOffset;
    let transitionEndTrigger;
    const root = Vue.ref();
    const wrapper = Vue.ref();
    const currentOffset = Vue.ref(0);
    const currentDuration = Vue.ref(0);
    const touch = useTouch.useTouch();
    const count = () => props2.options.length;
    const baseOffset = () => props2.optionHeight * (+props2.visibleOptionNum - 1) / 2;
    const updateValueByIndex = (index) => {
      let enabledIndex = utils.findIndexOfEnabledOption(props2.options, index);
      const offset = -enabledIndex * props2.optionHeight;
      const trigger = () => {
        if (enabledIndex > count() - 1) {
          enabledIndex = utils.findIndexOfEnabledOption(props2.options, index);
        }
        const value = props2.options[enabledIndex][props2.fields.value];
        if (value !== props2.value) {
          emit("change", value);
        }
      };
      if (moving && offset !== currentOffset.value) {
        transitionEndTrigger = trigger;
      } else {
        trigger();
      }
      currentOffset.value = offset;
    };
    const isReadonly = () => props2.readonly || !props2.options.length;
    const onClickOption = (index) => {
      if (moving || isReadonly()) {
        return;
      }
      transitionEndTrigger = null;
      currentDuration.value = DEFAULT_DURATION;
      updateValueByIndex(index);
      emit("clickOption", props2.options[index]);
    };
    const getIndexByOffset = (offset) => format.clamp(Math.round(-offset / props2.optionHeight), 0, count() - 1);
    const currentIndex = Vue.computed(() => getIndexByOffset(currentOffset.value));
    const momentum = (distance, duration) => {
      const speed = Math.abs(distance / duration);
      distance = currentOffset.value + speed / 3e-3 * (distance < 0 ? -1 : 1);
      const index = getIndexByOffset(distance);
      currentDuration.value = +props2.swipeDuration;
      updateValueByIndex(index);
    };
    const stopMomentum = () => {
      moving = false;
      currentDuration.value = 0;
      if (transitionEndTrigger) {
        transitionEndTrigger();
        transitionEndTrigger = null;
      }
    };
    const onTouchStart = (event) => {
      if (isReadonly()) {
        return;
      }
      touch.start(event);
      if (moving) {
        const translateY = utils.getElementTranslateY(wrapper.value);
        currentOffset.value = Math.min(0, translateY - baseOffset());
      }
      currentDuration.value = 0;
      startOffset = currentOffset.value;
      touchStartTime = Date.now();
      momentumOffset = startOffset;
      transitionEndTrigger = null;
    };
    const onTouchMove = (event) => {
      if (isReadonly()) {
        return;
      }
      touch.move(event);
      if (touch.isVertical()) {
        moving = true;
        dom.preventDefault(event, true);
      }
      const newOffset = format.clamp(startOffset + touch.deltaY.value, -(count() * props2.optionHeight), props2.optionHeight);
      const newIndex = getIndexByOffset(newOffset);
      if (newIndex !== currentIndex.value) {
        emit("scrollInto", props2.options[newIndex]);
      }
      currentOffset.value = newOffset;
      const now = Date.now();
      if (now - touchStartTime > MOMENTUM_TIME) {
        touchStartTime = now;
        momentumOffset = newOffset;
      }
    };
    const onTouchEnd = () => {
      if (isReadonly()) {
        return;
      }
      const distance = currentOffset.value - momentumOffset;
      const duration = Date.now() - touchStartTime;
      const startMomentum = duration < MOMENTUM_TIME && Math.abs(distance) > MOMENTUM_DISTANCE;
      if (startMomentum) {
        momentum(distance, duration);
        return;
      }
      const index = getIndexByOffset(currentOffset.value);
      currentDuration.value = DEFAULT_DURATION;
      updateValueByIndex(index);
      setTimeout(() => {
        moving = false;
      }, 0);
    };
    const renderOptions = () => {
      const optionStyle = {
        height: `${props2.optionHeight}px`
      };
      return props2.options.map((option, index) => {
        const text = option[props2.fields.text];
        const {
          disabled
        } = option;
        const value = option[props2.fields.value];
        const data = {
          role: "button",
          style: optionStyle,
          tabindex: disabled ? -1 : 0,
          class: [bem("item", {
            disabled,
            selected: value === props2.value
          }), option.className],
          onClick: () => onClickOption(index)
        };
        const childData = {
          class: "van-ellipsis",
          [props2.allowHtml ? "innerHTML" : "textContent"]: text
        };
        return Vue.createVNode("li", data, [slots.option ? slots.option(option, index) : Vue.createVNode("div", childData, null)]);
      });
    };
    index_esm.useParent(PICKER_KEY);
    useExpose.useExpose({
      stopMomentum
    });
    Vue.watchEffect(() => {
      const index = moving ? Math.floor(-currentOffset.value / props2.optionHeight) : props2.options.findIndex((option) => option[props2.fields.value] === props2.value);
      const enabledIndex = utils.findIndexOfEnabledOption(props2.options, index);
      const offset = -enabledIndex * props2.optionHeight;
      if (moving && enabledIndex < index) stopMomentum();
      currentOffset.value = offset;
    });
    index_esm.useEventListener("touchmove", onTouchMove, {
      target: root
    });
    return () => Vue.createVNode("div", {
      "ref": root,
      "class": bem(),
      "onTouchstartPassive": onTouchStart,
      "onTouchend": onTouchEnd,
      "onTouchcancel": onTouchEnd
    }, [Vue.createVNode("ul", {
      "ref": wrapper,
      "style": {
        transform: `translate3d(0, ${currentOffset.value + baseOffset()}px, 0)`,
        transitionDuration: `${currentDuration.value}ms`,
        transitionProperty: currentDuration.value ? "all" : "none"
      },
      "class": bem("wrapper"),
      "onTransitionend": stopMomentum
    }, [renderOptions()])]);
  }
});
exports.PICKER_KEY = PICKER_KEY;
exports.default = stdin_default;
