"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = exports.BaseSlideGroup = void 0;

require("../../../src/components/VSlideGroup/VSlideGroup.sass");

var _VIcon = _interopRequireDefault(require("../VIcon"));

var _transitions = require("../transitions");

var _VItemGroup = require("../VItemGroup/VItemGroup");

var _mobile = _interopRequireDefault(require("../../mixins/mobile"));

var _resize = _interopRequireDefault(require("../../directives/resize"));

var _touch = _interopRequireDefault(require("../../directives/touch"));

var _mixins = _interopRequireDefault(require("../../util/mixins"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

var BaseSlideGroup = (0, _mixins.default)(_VItemGroup.BaseItemGroup, _mobile.default).extend({
  name: 'base-slide-group',
  directives: {
    Resize: _resize.default,
    Touch: _touch.default
  },
  props: {
    activeClass: {
      type: String,
      default: 'v-slide-item--active'
    },
    centerActive: Boolean,
    nextIcon: {
      type: String,
      default: '$next'
    },
    prevIcon: {
      type: String,
      default: '$prev'
    },
    showArrows: {
      type: [Boolean, String],
      validator: function validator(v) {
        return typeof v === 'boolean' || ['always', 'desktop', 'mobile'].includes(v);
      }
    }
  },
  data: function data() {
    return {
      internalItemsLength: 0,
      isOverflowing: false,
      resizeTimeout: 0,
      startX: 0,
      scrollOffset: 0,
      widths: {
        content: 0,
        wrapper: 0
      }
    };
  },
  computed: {
    __cachedNext: function __cachedNext() {
      return this.genTransition('next');
    },
    __cachedPrev: function __cachedPrev() {
      return this.genTransition('prev');
    },
    classes: function classes() {
      return _objectSpread({}, _VItemGroup.BaseItemGroup.options.computed.classes.call(this), {
        'v-slide-group': true,
        'v-slide-group--has-affixes': this.hasAffixes,
        'v-slide-group--is-overflowing': this.isOverflowing
      });
    },
    hasAffixes: function hasAffixes() {
      switch (this.showArrows) {
        // Always show arrows on desktop & mobile
        case 'always':
          return true;
        // Always show arrows on desktop

        case 'desktop':
          return !this.isMobile;
        // Show arrows on mobile when overflowing.
        // This matches the default 2.2 behavior

        case true:
          return this.isOverflowing || Math.abs(this.scrollOffset) > 0;
        // Always show on mobile

        case 'mobile':
          return this.isMobile || this.isOverflowing || Math.abs(this.scrollOffset) > 0;
        // https://material.io/components/tabs#scrollable-tabs
        // Always show arrows when
        // overflowed on desktop

        default:
          return !this.isMobile && (this.isOverflowing || Math.abs(this.scrollOffset) > 0);
      }
    },
    hasNext: function hasNext() {
      if (!this.hasAffixes) return false;
      var _this$widths = this.widths,
          content = _this$widths.content,
          wrapper = _this$widths.wrapper; // Check one scroll ahead to know the width of right-most item

      return content > Math.abs(this.scrollOffset) + wrapper;
    },
    hasPrev: function hasPrev() {
      return this.hasAffixes && this.scrollOffset !== 0;
    }
  },
  watch: {
    internalValue: 'setWidths',
    // When overflow changes, the arrows alter
    // the widths of the content and wrapper
    // and need to be recalculated
    isOverflowing: 'setWidths',
    scrollOffset: function scrollOffset(val) {
      this.$refs.content.style.transform = "translateX(".concat(-val, "px)");
    }
  },
  beforeUpdate: function beforeUpdate() {
    this.internalItemsLength = (this.$children || []).length;
  },
  updated: function updated() {
    if (this.internalItemsLength === (this.$children || []).length) return;
    this.setWidths();
  },
  methods: {
    // Always generate next for scrollable hint
    genNext: function genNext() {
      var _this = this;

      var slot = this.$scopedSlots.next ? this.$scopedSlots.next({}) : this.$slots.next || this.__cachedNext;
      return this.$createElement('div', {
        staticClass: 'v-slide-group__next',
        class: {
          'v-slide-group__next--disabled': !this.hasNext
        },
        on: {
          click: function click() {
            return _this.onAffixClick('next');
          }
        },
        key: 'next'
      }, [slot]);
    },
    genContent: function genContent() {
      return this.$createElement('div', {
        staticClass: 'v-slide-group__content',
        ref: 'content'
      }, this.$slots.default);
    },
    genData: function genData() {
      return {
        class: this.classes,
        directives: [{
          name: 'resize',
          value: this.onResize
        }]
      };
    },
    genIcon: function genIcon(location) {
      var icon = location;

      if (this.$vuetify.rtl && location === 'prev') {
        icon = 'next';
      } else if (this.$vuetify.rtl && location === 'next') {
        icon = 'prev';
      }

      var upperLocation = "".concat(location[0].toUpperCase()).concat(location.slice(1));
      var hasAffix = this["has".concat(upperLocation)];
      if (!this.showArrows && !hasAffix) return null;
      return this.$createElement(_VIcon.default, {
        props: {
          disabled: !hasAffix
        }
      }, this["".concat(icon, "Icon")]);
    },
    // Always generate prev for scrollable hint
    genPrev: function genPrev() {
      var _this2 = this;

      var slot = this.$scopedSlots.prev ? this.$scopedSlots.prev({}) : this.$slots.prev || this.__cachedPrev;
      return this.$createElement('div', {
        staticClass: 'v-slide-group__prev',
        class: {
          'v-slide-group__prev--disabled': !this.hasPrev
        },
        on: {
          click: function click() {
            return _this2.onAffixClick('prev');
          }
        },
        key: 'prev'
      }, [slot]);
    },
    genTransition: function genTransition(location) {
      return this.$createElement(_transitions.VFadeTransition, [this.genIcon(location)]);
    },
    genWrapper: function genWrapper() {
      var _this3 = this;

      return this.$createElement('div', {
        staticClass: 'v-slide-group__wrapper',
        directives: [{
          name: 'touch',
          value: {
            start: function start(e) {
              return _this3.overflowCheck(e, _this3.onTouchStart);
            },
            move: function move(e) {
              return _this3.overflowCheck(e, _this3.onTouchMove);
            },
            end: function end(e) {
              return _this3.overflowCheck(e, _this3.onTouchEnd);
            }
          }
        }],
        ref: 'wrapper'
      }, [this.genContent()]);
    },
    calculateNewOffset: function calculateNewOffset(direction, widths, rtl, currentScrollOffset) {
      var sign = rtl ? -1 : 1;
      var newAbosluteOffset = sign * currentScrollOffset + (direction === 'prev' ? -1 : 1) * widths.wrapper;
      return sign * Math.max(Math.min(newAbosluteOffset, widths.content - widths.wrapper), 0);
    },
    onAffixClick: function onAffixClick(location) {
      this.$emit("click:".concat(location));
      this.scrollTo(location);
    },
    onResize: function onResize() {
      /* istanbul ignore next */
      if (this._isDestroyed) return;
      this.setWidths();
    },
    onTouchStart: function onTouchStart(e) {
      var content = this.$refs.content;
      this.startX = this.scrollOffset + e.touchstartX;
      content.style.setProperty('transition', 'none');
      content.style.setProperty('willChange', 'transform');
    },
    onTouchMove: function onTouchMove(e) {
      this.scrollOffset = this.startX - e.touchmoveX;
    },
    onTouchEnd: function onTouchEnd() {
      var _this$$refs = this.$refs,
          content = _this$$refs.content,
          wrapper = _this$$refs.wrapper;
      var maxScrollOffset = content.clientWidth - wrapper.clientWidth;
      content.style.setProperty('transition', null);
      content.style.setProperty('willChange', null);

      if (this.$vuetify.rtl) {
        /* istanbul ignore else */
        if (this.scrollOffset > 0 || !this.isOverflowing) {
          this.scrollOffset = 0;
        } else if (this.scrollOffset <= -maxScrollOffset) {
          this.scrollOffset = -maxScrollOffset;
        }
      } else {
        /* istanbul ignore else */
        if (this.scrollOffset < 0 || !this.isOverflowing) {
          this.scrollOffset = 0;
        } else if (this.scrollOffset >= maxScrollOffset) {
          this.scrollOffset = maxScrollOffset;
        }
      }
    },
    overflowCheck: function overflowCheck(e, fn) {
      e.stopPropagation();
      this.isOverflowing && fn(e);
    },
    scrollIntoView
    /* istanbul ignore next */
    : function scrollIntoView() {
      if (!this.selectedItem && this.items.length) {
        var lastItemPosition = this.items[this.items.length - 1].$el.getBoundingClientRect();
        var wrapperPosition = this.$refs.wrapper.getBoundingClientRect();

        if (this.$vuetify.rtl && wrapperPosition.right < lastItemPosition.right || !this.$vuetify.rtl && wrapperPosition.left > lastItemPosition.left) {
          this.scrollTo('prev');
        }
      }

      if (!this.selectedItem) {
        return;
      }

      if (this.selectedIndex === 0 || !this.centerActive && !this.isOverflowing) {
        this.scrollOffset = 0;
      } else if (this.centerActive) {
        this.scrollOffset = this.calculateCenteredOffset(this.selectedItem.$el, this.widths, this.$vuetify.rtl);
      } else if (this.isOverflowing) {
        this.scrollOffset = this.calculateUpdatedOffset(this.selectedItem.$el, this.widths, this.$vuetify.rtl, this.scrollOffset);
      }
    },
    calculateUpdatedOffset: function calculateUpdatedOffset(selectedElement, widths, rtl, currentScrollOffset) {
      var clientWidth = selectedElement.clientWidth;
      var offsetLeft = rtl ? widths.content - selectedElement.offsetLeft - clientWidth : selectedElement.offsetLeft;

      if (rtl) {
        currentScrollOffset = -currentScrollOffset;
      }

      var totalWidth = widths.wrapper + currentScrollOffset;
      var itemOffset = clientWidth + offsetLeft;
      var additionalOffset = clientWidth * 0.4;

      if (offsetLeft <= currentScrollOffset) {
        currentScrollOffset = Math.max(offsetLeft - additionalOffset, 0);
      } else if (totalWidth <= itemOffset) {
        currentScrollOffset = Math.min(currentScrollOffset - (totalWidth - itemOffset - additionalOffset), widths.content - widths.wrapper);
      }

      return rtl ? -currentScrollOffset : currentScrollOffset;
    },
    calculateCenteredOffset: function calculateCenteredOffset(selectedElement, widths, rtl) {
      var offsetLeft = selectedElement.offsetLeft,
          clientWidth = selectedElement.clientWidth;

      if (rtl) {
        var offsetCentered = widths.content - offsetLeft - clientWidth / 2 - widths.wrapper / 2;
        return -Math.min(widths.content - widths.wrapper, Math.max(0, offsetCentered));
      } else {
        var _offsetCentered = offsetLeft + clientWidth / 2 - widths.wrapper / 2;

        return Math.min(widths.content - widths.wrapper, Math.max(0, _offsetCentered));
      }
    },
    scrollTo
    /* istanbul ignore next */
    : function scrollTo(location) {
      this.scrollOffset = this.calculateNewOffset(location, {
        // Force reflow
        content: this.$refs.content ? this.$refs.content.clientWidth : 0,
        wrapper: this.$refs.wrapper ? this.$refs.wrapper.clientWidth : 0
      }, this.$vuetify.rtl, this.scrollOffset);
    },
    setWidths
    /* istanbul ignore next */
    : function setWidths() {
      var _this4 = this;

      window.requestAnimationFrame(function () {
        var _this4$$refs = _this4.$refs,
            content = _this4$$refs.content,
            wrapper = _this4$$refs.wrapper;
        _this4.widths = {
          content: content ? content.clientWidth : 0,
          wrapper: wrapper ? wrapper.clientWidth : 0
        };
        _this4.isOverflowing = _this4.widths.wrapper < _this4.widths.content;

        _this4.scrollIntoView();
      });
    }
  },
  render: function render(h) {
    return h('div', this.genData(), [this.genPrev(), this.genWrapper(), this.genNext()]);
  }
});
exports.BaseSlideGroup = BaseSlideGroup;

var _default = BaseSlideGroup.extend({
  name: 'v-slide-group',
  provide: function provide() {
    return {
      slideGroup: this
    };
  }
});

exports.default = _default;
//# sourceMappingURL=VSlideGroup.js.map