All files / components DateRangePicker.vue

0% Statements 0/72
0% Branches 0/48
0% Functions 0/18
0% Lines 0/59
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139                                                                                                                                                                                                                                                                                     
<template>
<calendar
  :attributes='attributes_'
  @dayselect='selectDay'
  @daymouseenter='enterDay'
  v-bind='$attrs'
  v-on='$listeners'>
</calendar> 
</template>

<script>
import Calendar from './Calendar';
import DateInfo from '../utils/dateInfo';
import defaults from '../utils/defaults';
import { rangeHasValue } from '../utils/pickerProfiles';

export default {
  components: {
    Calendar,
  },
  props: {
    value: { type: Object, default: () => {} },
    selectColor: { type: String, default: () => defaults.datePickerSelectColor },
    dragColor: { type: String, default: () => defaults.datePickerDragColor },
    showCaps: { type: Boolean, default: () => defaults.datePickerShowCaps },
    dragAttribute: Object,
    selectAttribute: Object,
    disabledAttribute: Object,
    dayContentHoverStyle: Object,
    attributes: Array,
  },
  data() {
    return {
      dragValue: null,
    };
  },
  computed: {
    dragAttribute_() {
      const normValue = this.normalizeRange(this.dragValue);
      if (!normValue) return null;
      return {
        ...defaults.datePickerDragAttribute(this.dragColor, this.showCaps),
        ...this.dragAttribute,
        dates: [this.dragValue],
      };
    },
    selectAttribute_() {
      const normValue = this.normalizeRange(this.value);
      if (!normValue) return null;
      return {
        ...defaults.datePickerSelectAttribute(this.selectColor, this.showCaps),
        ...this.selectAttribute,
        dates: [normValue],
      };
    },
    attributes_() {
      const attributes = [...(this.attributes || [])];
      if (this.dragAttribute_) attributes.push(this.dragAttribute_);
      else if (this.selectAttribute_) attributes.push(this.selectAttribute_);
      if (this.disabledAttribute) attributes.push(this.disabledAttribute);
      return attributes;
    },
  },
  watch: {
    dragValue(val) {
      this.$emit('drag', this.normalizeRange(val));
    },
  },
  created() {
    // Clear drag on escape keydown
    document.addEventListener('keydown', (e) => {
      if (this.dragValue && e.keyCode === 27) {
        this.dragValue = null;
      }
    });
  },
  methods: {
    touchStartDay(day) {
      this.selectDay(day);
      this.$emit('daytouchstart', day);
    },
    selectDay(day) {
      // Done if date selection is invalid
      if (this.disabledAttribute && this.disabledAttribute.includesDay(day)) return;
      // Start new drag selection if not dragging
      if (!this.dragValue) {
        // Make sure date selection is valid
        const date = new Date(day.dateTime);
        // Start new drag selection
        this.dragValue = { start: date, end: date };
      } else {
        // Construct new value
        const newValue = new DateInfo({
          start: new Date(this.dragValue.start.getTime()),
          end: new Date(day.dateTime),
        });
        // Clear drag selection
        this.dragValue = null;
        // Signal new value selected
        this.$emit('input', newValue.toRange());
      }
    },
    enterDay(day) {
      // Make sure drag has been initialized
      if (this.dragValue) {
        // Make sure dragged value is valid
        if (this.disabledAttribute && this.disabledAttribute.includesDay(day)) {
          // Assign disabled content hover style
          this.dayContentHoverStyle_ = this.disabledAttribute.contentHoverStyle;
        } else {
          // Update drag selection
          this.dragValue = {
            start: new Date(this.dragValue.start.getTime()),
            end: new Date(day.dateTime),
          };
          // Assign default content hover style
          this.dayContentHoverStyle_ = this.dayContentHoverStyle;
        }
      }
    },
    // Ranges can privately have end date earlier than start date
    // This function will correct the order before exposing it to to other components
    normalizeRange(range) {
      if (!rangeHasValue(range)) return null;
      const { start, end } = range;
      const startTime = start.getTime();
      const endTime = end.getTime();
      const isNormal = start < end;
      return {
        start: isNormal ? start : end,
        startTime: isNormal ? startTime : endTime,
        end: isNormal ? end : start,
        endTime: isNormal ? endTime : startTime,
      };
    },
  },
};
</script>