UNPKG

@progress/kendo-vue-dateinputs

Version:
494 lines (493 loc) 14.5 kB
/** * @license *------------------------------------------------------------------------------------------- * Copyright © 2025 Progress Software Corporation. All rights reserved. * Licensed under commercial license. See LICENSE.md in the package root for more information *------------------------------------------------------------------------------------------- */ import { defineComponent as ie, createVNode as n, h as b, ref as ne, inject as ae, isVNode as oe } from "vue"; import { FloatingLabel as ue } from "@progress/kendo-vue-labels"; import { Button as se } from "@progress/kendo-vue-buttons"; import { Popup as le } from "@progress/kendo-vue-popup"; import { cloneDate as s } from "@progress/kendo-date-math"; import { Keys as a, canUseDOM as re, getDefaultSlots as de, templateRendering as c, getListeners as m, getTemplate as T, classNames as _, kendoThemeMaps as k, guid as V, validatePackage as pe } from "@progress/kendo-vue-common"; import { DateInput as he } from "../dateinput/DateInput.mjs"; import { packageMetadata as ce } from "../package-metadata.mjs"; import { isInDateRange as me, MAX_TIME as B, MAX_DATE as fe, MIN_DATE as ge } from "../utils.mjs"; import { toggleDateTimeSelector as l, messages as C } from "../messages/main.mjs"; import { provideLocalizationService as F } from "@progress/kendo-vue-intl"; import { DateTimeSelector as Se } from "./DateTimeSelector.mjs"; import { isInTimeRange as ve } from "../timepicker/utils.mjs"; import { MIN_TIME as M } from "../defaults.mjs"; import { defaultFormatPlaceholder as we } from "../dateinput/utils.mjs"; import { calendarIcon as Ie } from "@progress/kendo-svg-icons"; function f(e) { return typeof e == "function" || Object.prototype.toString.call(e) === "[object Object]" && !oe(e); } const Pe = /* @__PURE__ */ ie({ name: "KendoDateTimePicker", emits: { changemodel: (e) => !0, "update:modelValue": (e) => !0, iconclick: (e) => !0, change: (e) => !0, focus: (e) => !0, blur: (e) => !0, keydown: (e) => !0, open: (e) => !0, close: (e) => !0 }, props: { modelValue: { type: Date, default: void 0 }, defaultShow: { type: Boolean, default: !1 }, defaultValue: { type: Date, default: null }, disabled: { type: Boolean, default: !1 }, dateInput: { type: [String, Object, Function], default: function() { } }, popup: { type: [String, Object, Function], default: function() { } }, calendar: { type: [String, Object, Function], default: function() { } }, focusedDate: Date, format: { type: [String, Object], default: function() { return "g"; } }, formatPlaceholder: { type: [String, Object], default: function() { return we; } }, rounded: { type: String, default: "medium", validator: function(e) { return ["small", "medium", "large", "full"].includes(e); } }, fillMode: { type: String, default: "solid", validator: function(e) { return ["solid", "flat", "outline"].includes(e); } }, size: { type: String, default: "medium", validator: function(e) { return ["small", "medium", "large"].includes(e); } }, id: String, ariaLabelledBy: String, ariaDescribedBy: String, min: { type: Date, default: function() { return ge; } }, max: { type: Date, default: function() { return fe; } }, maxTime: { type: Date, default: function() { return s(B); } }, minTime: { type: Date, default: function() { return s(M); } }, name: String, label: String, placeholder: String, popupSettings: { type: Object, default: function() { return {}; } }, show: { type: Boolean, default: void 0 }, tabIndex: { type: Number, default: 0 }, title: { type: String, default: function() { return ""; } }, steps: { type: Object, default: function() { return {}; } }, value: Date, weekNumber: { type: Boolean, default: !1 }, width: String, validationMessage: String, required: { type: Boolean, default: !1 }, validityStyles: { type: Boolean, default: !0 }, validate: Boolean, valid: { type: Boolean, default: void 0 }, cancelButton: { type: Boolean, default: !0 }, inputAttributes: Object }, model: { event: "changemodel" }, created() { this._anchor = V(), this._popupId = "popup" + V(), this._wrapper = null, this._dateInput = null, this._dateTimeSelector = null, pe(ce), this.currentValue = this.$props.defaultValue, this.currentShow = this.$props.defaultShow; }, inject: { kendoLocalizationService: { default: null } }, data() { return { currentValue: null, currentShow: !1, valueDuringOnChange: void 0, showDuringOnChange: void 0, shouldFocusDateInput: !1, isFocused: !1 }; }, computed: { computedValue() { const e = this.valueDuringOnChange !== void 0 ? this.valueDuringOnChange : this.$props.value !== void 0 ? this.$props.value : this.$props.modelValue !== void 0 ? this.$props.modelValue : this.$data.currentValue; return e !== null ? s(e) : null; }, computedShow() { return this.showDuringOnChange !== void 0 ? this.showDuringOnChange : this.$props.show !== void 0 ? this.$props.show : this.currentShow; } }, watch: { show: function(e, t) { this._oldShow = t; }, currentShow: function(e, t) { this._oldShow = t; } }, mounted() { this.computedShow && this.$forceUpdate(); const e = this.dateInputElement(); this._dateTimeSelector = this.$refs.dateTimeSelector, this._wrapper = this.kendoAnchorRef, this._dateInput = this.dateInputRef, e && e.setAttribute("aria-haspopup", "true"); }, updated() { const e = this.dateInputElement(); this._dateTimeSelector = this.$refs.dateTimeSelector, this._wrapper = this.kendoAnchorRef, this._dateTimeSelector && this.computedShow && !this._oldShow && this._dateTimeSelector.focus({ preventScroll: !0 }), e && !this.computedShow && this.shouldFocusDateInput && this._dateInput.focus({ preventScroll: !0 }), this.shouldFocusDateInput = !1; }, setup() { const e = ne(null), t = ae("kendoLocalizationService", {}); return { kendoAnchorRef: e, kendoLocalizationService: t }; }, render() { const e = de(this), { disabled: t, tabIndex: i, title: r, id: g, format: S, formatPlaceholder: O, min: x, max: R, weekNumber: E, focusedDate: A, width: v, name: j, steps: w, placeholder: P, validationMessage: z, required: L, validityStyles: N, cancelButton: K, minTime: I, maxTime: D, ariaLabelledBy: De, ariaDescribedBy: ye, size: d, fillMode: y, rounded: p, inputAttributes: q } = this.$props, { popupClass: U, appendTo: X, animate: H } = this.$props.popupSettings, $ = !this.$props.validityStyles || this.validity().valid, G = this.$props.dateInput ? c.call(this, this.$props.dateInput, m.call(this)) : void 0, J = n(he, { ref: (h) => { this.dateInputRef = h; }, placeholder: P, disabled: t, format: S, formatPlaceholder: O, id: g, max: R, min: x, minTime: I, maxTime: D, name: j, size: null, rounded: null, fillMode: null, onChange: this.handleValueChange, required: L, steps: w, tabIndex: this.computedShow ? -1 : i, title: r, valid: this.validity().valid, validationMessage: z, validityStyles: N, value: this.computedValue, ariaHasPopup: "dialog", ariaExpanded: this.computedShow, ariaRole: "combobox", ariaControls: this._popupId, inputAttributes: q }, f(e) ? e : { default: () => [e] }), Q = T.call(this, { h: b, template: G, defaultRendering: J }), W = this.$props.calendar ? c.call(this, this.$props.calendar, m.call(this)) : void 0, o = n(Se, { ref: "dateTimeSelector", cancelButton: K, value: this.computedValue, onChange: this.handleValueChange, onReject: this.handleReject, disabled: t, weekNumber: E, min: this.$props.min, max: this.$props.max, minTime: I, maxTime: D, focusedDate: A, format: S, calendar: W, steps: w, onFocus: this.timeSelectorFocus, onBlur: this.timeSelectorBlur, onKeydown: this.handleKeyDown }, null), Y = _("k-datetime-container k-reset", U), Z = this.$props.popup ? c.call(this, this.$props.popup, m.call(this)) : void 0, ee = n(le, { show: this.computedShow, anchor: this._anchor, popupClass: Y, id: this._popupId, anchorAlign: { horizontal: "left", vertical: "bottom" }, popupAlign: { horizontal: "left", vertical: "top" }, appendTo: X, animate: H }, f(o) ? o : { default: () => [o] }), te = T.call(this, { h: b, template: Z, defaultRendering: ee, defaultSlots: o }), u = n("div", { class: _("k-input", "k-datetimepicker", { [`k-input-${k.sizeMap[d] || d}`]: d, [`k-input-${y}`]: y, [`k-rounded-${k.roundedMap[p] || p}`]: p, "k-invalid": !$, "k-required": this.required, "k-disabled": this.$props.disabled }), ref: (h) => { this.kendoAnchorRef = h; }, onKeydown: this.handleKeyDown, style: { width: v }, onFocusin: this.handleFocus, onFocusout: this.handleBlur }, [Q, n(se, { type: "button", tabIndex: -1, icon: "calendar", svgIcon: Ie, onMousedown: this.handleIconMouseDown, onClick: this.handleDateIconClick, title: F(this).toLanguageString(l, C[l]), rounded: null, class: "k-input-button", "aria-controls": this._popupId, "aria-label": F(this).toLanguageString(l, C[l]) }, null), te]); return this.$props.label ? n(ue, { label: this.$props.label, editorId: g, editorValid: $, editorValue: this.getDateInputText(), editorPlaceholder: this.$props.placeholder, editorDisabled: this.$props.disabled, style: { width: v } }, f(u) ? u : { default: () => [u] }) : u; }, methods: { validity() { const e = me(this.computedValue, this.$props.min, this.$props.max) && ve(this.computedValue, this.$props.minTime || M, this.$props.maxTime || B), t = this.$props.validationMessage !== void 0, i = (!this.$props.required || this.computedValue !== null) && e, r = this.$props.valid !== void 0 ? this.$props.valid : i; return { customError: t, rangeOverflow: this.computedValue && this.$props.max.getTime() < this.computedValue.getTime() || !1, rangeUnderflow: this.computedValue && this.computedValue.getTime() < this.$props.min.getTime() || !1, valid: r, valueMissing: this.computedValue === null }; }, getDateInputText() { return this.computedValue ? !0 : this._dateInput ? this._dateInput._element.value : ""; }, focus() { const e = this.dateInputElement(); e && e.focus(); }, setShow(e) { this.computedShow !== e && (this.currentShow = e, this.$emit(e ? "open" : "close", { component: this })); }, handleReject() { this.setShow(!1); }, handleValueChange(e) { this.currentValue = s(e.value || void 0), this.valueDuringOnChange = e.value, this.showDuringOnChange = !1, this.shouldFocusDateInput = !0, this.$emit("changemodel", this.computedValue), this.$emit("update:modelValue", this.computedValue), this.$emit("change", { event: e.event, value: this.computedValue, show: this.computedShow, component: this, target: { name: this.$props.name, value: this.computedValue, valueAsDate: this.computedValue } }), this.valueDuringOnChange = void 0, this.showDuringOnChange = void 0, this.setShow(!1); }, handleFocus(e) { this.isFocused = !0, this.$emit("focus", { event: e }); }, handleBlur(e) { this.createBlurTimeout(), this.$emit("blur", { event: e }); }, timeSelectorBlur(e) { this.$emit("blur", { event: e }), clearTimeout(this._blurTimeout), this.createBlurTimeout(); }, timeSelectorFocus() { clearTimeout(this._blurTimeout); }, createBlurTimeout() { this._blurTimeout = setTimeout(() => { this.isFocused = !1; const e = document.activeElement && document.activeElement.closest(`#${this._popupId}`); this._dateInput && re && document.activeElement !== this._dateInput.element() && !e && this.setShow(!1); }, 200); }, handleDateIconClick(e) { this.$props.disabled || (this.shouldFocusDateInput = !0, this.setShow(!this.computedShow), this.$emit("iconclick", e)); }, handleIconMouseDown(e) { e.preventDefault(); }, handleKeyDown(e) { const { altKey: t, keyCode: i } = e; if (i === a.tab && this._dateInput && e.target !== this._dateInput._element) { e.preventDefault(), this.$data.shouldFocusDateInput = !0, this.setShow(!1); return; } if (i === a.esc) { this.shouldFocusDateInput = !0, this.setShow(!1); return; } t && (i === a.up || i === a.down) && (e.preventDefault(), e.stopPropagation(), this.shouldFocusDateInput = i === a.up, this.setShow(i === a.down)), this.$emit("keydown", e); }, dateInputElement() { return this._dateInput && this._dateInput.$el || this._wrapper && this._wrapper.querySelector(".k-dateinput-wrap > input.k-input"); } } }); export { Pe as DateTimePicker };