"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

exports.__esModule = true;
exports.default = void 0;

var _utils = require("../utils");

var _unit = require("../utils/format/unit");

var _style = require("../utils/dom/style");

var _scroll = _interopRequireDefault(require("../utils/dom/scroll"));

var _bindEvent = require("../mixins/bind-event");

var _create = _interopRequireDefault(require("../utils/create"));

var _default = (0, _create.default)({
  render: function render() {
    var _vm = this;

    var _h = _vm.$createElement;

    var _c = _vm._self._c || _h;

    return _c('div', {
      style: _vm.rootStyle
    }, [_c('div', {
      class: _vm.b({
        fixed: _vm.fixed
      }),
      style: _vm.style
    }, [_vm._t("default")], 2)]);
  },
  name: "sticky",
  mixins: [(0, _bindEvent.BindEventMixin)(function (bind, isBind) {
    if (!this.scroller) {
      this.scroller = _scroll.default.getScrollEventTarget(this.$el);
    }

    if (this.observer) {
      var method = isBind ? "observe" : "unobserve";
      this.observer[method](this.$el);
    }

    bind(this.scroller, "scroll", this.onScroll, true);
    this.onScroll();
  })],
  props: {
    zIndex: [Number, String],
    container: null,
    offsetTop: {
      type: [Number, String],
      default: 0
    }
  },
  data: function data() {
    return {
      fixed: false,
      height: 0,
      transform: 0
    };
  },
  created: function created() {
    var _this = this;

    if (!_utils.isServer && window.IntersectionObserver) {
      this.observer = new IntersectionObserver(function (entries) {
        // 可见性更改时触发滚动
        if (entries[0].intersectionRatio > 0) {
          _this.onScroll();
        }
      }, {
        root: document.body
      });
    }
  },
  methods: {
    onScroll: function onScroll() {
      var _this2 = this;

      if ((0, _style.isHidden)(this.$el)) {
        return;
      }

      this.height = this.$el.offsetHeight;
      var container = this.container,
          offsetTopPx = this.offsetTopPx;

      var scrollTop = _scroll.default.getScrollTop(window);

      var topToPageTop = _scroll.default.getElementTop(this.$el);

      var emitScrollEvent = function emitScrollEvent() {
        _this2.$emit("scroll", {
          scrollTop: scrollTop,
          isFixed: _this2.fixed
        });
      }; // The sticky component should be kept inside the container element


      if (container) {
        var bottomToPageTop = topToPageTop + container.offsetHeight;

        if (scrollTop + offsetTopPx + this.height > bottomToPageTop) {
          var distanceToBottom = this.height + scrollTop - bottomToPageTop;

          if (distanceToBottom < this.height) {
            this.fixed = true;
            this.transform = -(distanceToBottom + offsetTopPx);
          } else {
            this.fixed = false;
          }

          emitScrollEvent();
          return;
        }
      }

      if (scrollTop + offsetTopPx > topToPageTop) {
        this.fixed = true;
        this.transform = 0;
      } else {
        this.fixed = false;
      }

      emitScrollEvent();
    }
  },
  computed: {
    offsetTopPx: function offsetTopPx() {
      return (0, _unit.unitToPx)(this.offsetTop);
    },
    style: function style() {
      if (!this.fixed) {
        return;
      }

      var style = {};

      if ((0, _utils.isDef)(this.zIndex)) {
        style.zIndex = this.zIndex;
      }

      if (this.offsetTopPx && this.fixed) {
        style.top = this.offsetTopPx + "px";
      }

      if (this.transform) {
        style.transform = "translate3d(0, " + this.transform + "px, 0)";
      }

      return style;
    },
    rootStyle: function rootStyle() {
      var fixed = this.fixed,
          height = this.height;
      return {
        height: fixed ? height + "px" : null
      };
    }
  }
});

exports.default = _default;