UNPKG

@gitlab/ui

Version:
276 lines (253 loc) • 7.91 kB
import Pikaday from 'pikaday'; import { isString } from 'lodash'; import GlFormInput from '../form/form_input/form_input'; import GlIcon from '../icon/icon'; import { areDatesEqual } from '../../../utils/datetime_utility'; import { defaultDateFormat } from '../../../utils/constants'; import __vue_normalize__ from 'vue-runtime-helpers/dist/normalize-component.js'; var pad = function pad(val) { var len = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 2; return "0".concat(val).slice(-len); }; /** * Used `onSelect` method in pickaday * @param {Date} date UTC format * @return {String} Date formated in yyyy-mm-dd */ var defaultDateFormatter = function defaultDateFormatter(date) { var day = pad(date.getDate()); var month = pad(date.getMonth() + 1); var year = date.getFullYear(); return "".concat(year, "-").concat(month, "-").concat(day); }; var isBefore = function isBefore(compareTo, date) { return compareTo && date && date.getTime() < compareTo.getTime(); }; var highlightPastDates = function highlightPastDates(pikaday) { var pikaButtons = pikaday.el.querySelectorAll('.pika-button'); var today = new Date(); pikaButtons.forEach(function (pikaButton) { var _pikaButton$dataset = pikaButton.dataset, pikaYear = _pikaButton$dataset.pikaYear, pikaMonth = _pikaButton$dataset.pikaMonth, pikaDay = _pikaButton$dataset.pikaDay; var pikaButtonDate = new Date(pikaYear, pikaMonth, pikaDay); if (isBefore(today, pikaButtonDate)) { pikaButton.classList.add('is-past-date'); } }); }; var script = { components: { GlFormInput: GlFormInput, GlIcon: GlIcon }, props: { target: { type: String, required: false, default: '' }, container: { type: String, required: false, default: '' }, value: { type: Date, required: false, default: null }, minDate: { type: Date, required: false, default: null }, maxDate: { type: Date, required: false, default: null }, startRange: { type: Date, required: false, default: null }, endRange: { type: Date, required: false, default: null }, disableDayFn: { type: Function, required: false, default: null }, firstDay: { type: Number, required: false, default: 0 }, arialLabel: { type: String, required: false, default: '' }, displayField: { type: Boolean, required: false, default: true }, startOpened: { type: Boolean, required: false, default: false }, defaultDate: { type: Date, required: false, default: null }, i18n: { type: Object, required: false, default: null }, theme: { type: String, required: false, default: '' } }, data: function data() { return { format: defaultDateFormat }; }, computed: { formattedDate: function formattedDate() { return this.calendar && this.calendar.toString(); }, customTrigger: function customTrigger() { return isString(this.target) && this.target !== ''; }, triggerOnFocus: function triggerOnFocus() { return this.target === null; }, showDefaultField: function showDefaultField() { return !this.customTrigger || this.triggerOnFocus; } }, watch: { value: function value(val) { if (!areDatesEqual(val, this.calendar.getDate())) { this.calendar.setDate(val, true); } }, minDate: function minDate(_minDate) { this.calendar.setMinDate(_minDate); }, maxDate: function maxDate(_maxDate) { this.calendar.setMaxDate(_maxDate); }, startRange: function startRange(_startRange) { this.calendar.setStartRange(_startRange); }, endRange: function endRange(_endRange) { this.calendar.setEndRange(_endRange); } }, mounted: function mounted() { var $parentEl = this.$parent.$el; var drawEvent = this.draw.bind(this); var pikadayConfig = { field: this.$el.querySelector('input[type="text"]'), // `position-absolute` is needed because of this bug: https://github.com/Pikaday/Pikaday/issues/840 theme: "gl-datepicker-theme position-absolute ".concat(this.theme), defaultDate: this.value || this.defaultDate, setDefaultDate: Boolean(this.value), minDate: this.minDate, maxDate: this.maxDate, // Only supports default gitlab format YYYY-MM-DD. We have to decide if we want to support other formats. format: this.format, disableDayFn: this.disableDayFn, firstDay: this.firstDay, arialLabel: this.ariaLabel, toString: function toString(date) { return defaultDateFormatter(date); }, onSelect: this.selected.bind(this), onClose: this.closed.bind(this), onOpen: this.opened.bind(this), onDraw: function onDraw(pikaday) { highlightPastDates(pikaday); drawEvent(); } }; // Pass `null` as `target` prop to use the `field` as the trigger (open on focus) if (!this.triggerOnFocus) { var trigger = this.customTrigger ? $parentEl.querySelector(this.target) : this.$refs.calendarTriggerBtn; pikadayConfig.trigger = trigger; // Set `trigger` as the `field` if `field` element doesn't exist (not passed via the slot) if (!pikadayConfig.field && this.customTrigger) { pikadayConfig.field = trigger; } } // Pass `null` as `container` prop to prevent passing the `container` option to Pikaday if (this.container !== null) { var container = this.container ? $parentEl.querySelector(this.container) : this.$el; pikadayConfig.container = container; } if (this.i18n) { pikadayConfig.i18n = this.i18n; } this.calendar = new Pikaday(pikadayConfig); if (this.startOpened) { this.calendar.show(); } }, beforeDestroy: function beforeDestroy() { this.calendar.destroy(); }, methods: { selected: function selected(date) { this.$emit('input', date); }, closed: function closed() { this.$emit('close'); }, opened: function opened() { this.$emit('open'); }, draw: function draw() { this.$emit('monthChange'); } } }; /* script */ const __vue_script__ = script; /* template */ var __vue_render__ = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:"gl-datepicker d-inline-block"},[(_vm.showDefaultField)?_c('div',{staticClass:"position-relative"},[_vm._t("default",[_c('gl-form-input',{staticClass:"gl-datepicker-input",attrs:{"value":_vm.formattedDate,"placeholder":_vm.format}})],{"formattedDate":_vm.formattedDate}),_vm._v(" "),_c('span',{ref:"calendarTriggerBtn",class:['gl-datepicker-trigger', { 'gl-pointer-events-none': _vm.triggerOnFocus }]},[_c('gl-icon',{attrs:{"name":"calendar","size":16}})],1)],2):_vm._t("default",null,{"formattedDate":_vm.formattedDate})],2)}; var __vue_staticRenderFns__ = []; /* style */ const __vue_inject_styles__ = undefined; /* scoped */ const __vue_scope_id__ = undefined; /* module identifier */ const __vue_module_identifier__ = undefined; /* functional template */ const __vue_is_functional_template__ = false; /* style inject */ /* style inject SSR */ /* style inject shadow dom */ const __vue_component__ = __vue_normalize__( { render: __vue_render__, staticRenderFns: __vue_staticRenderFns__ }, __vue_inject_styles__, __vue_script__, __vue_scope_id__, __vue_is_functional_template__, __vue_module_identifier__, false, undefined, undefined, undefined ); export default __vue_component__; export { defaultDateFormatter, pad };