UNPKG

@progress/kendo-vue-dateinputs

Version:
481 lines (480 loc) 15.1 kB
/** * @license *------------------------------------------------------------------------------------------- * Copyright © 2026 Progress Software Corporation. All rights reserved. * Licensed under commercial license. See LICENSE.md in the package root for more information *------------------------------------------------------------------------------------------- */ import { defineComponent as T, createVNode as o, mergeProps as _, ref as O, inject as S, isVNode as P } from "vue"; import { isEqual as B, cloneDate as u } from "@progress/kendo-date-math"; import { provideLocalizationService as E, provideIntlService as A } from "@progress/kendo-vue-intl"; import { KendoDate as z } from "./models/kendo-date.mjs"; import { getDefaultSlots as L, noop as j, setRef as R, getRef as N, canUseDOM as h, kendoThemeMaps as v, validatePackage as K, guid as q } from "@progress/kendo-vue-common"; import { Button as D } from "@progress/kendo-vue-buttons"; import { packageMetadata as H } from "../package-metadata.mjs"; import { isInRange as U, approximateStringMatching as X, defaultFormatPlaceholder as Y, defaultFormat as G } from "./utils.mjs"; import { MIN_DATE as W, MAX_DATE as J } from "../utils.mjs"; import { increaseValue as c, messages as p, decreaseValue as m } from "../messages/main.mjs"; import { isInTimeRange as Q } from "../timepicker/utils.mjs"; import { MIN_TIME as Z, MAX_TIME as ee } from "../defaults.mjs"; import { FloatingLabel as te } from "@progress/kendo-vue-labels"; import { chevronUpIcon as ie, chevronDownIcon as ae } from "@progress/kendo-svg-icons"; function ne(e) { return typeof e == "function" || Object.prototype.toString.call(e) === "[object Object]" && !P(e); } const se = "Please enter a valid value!", De = /* @__PURE__ */ T({ name: "DateInput", model: { event: "changemodel" }, inject: { kendoIntlService: { default: null }, kendoLocalizationService: { default: null } }, emits: { change: (e) => !0, changemodel: (e) => !0, "update:modelValue": (e) => !0, focus: (e) => !0, blur: (e) => !0 }, props: { modelValue: Date, value: Date, defaultValue: Date, format: { type: [String, Object], default: function() { return G; } }, formatPlaceholder: { type: [String, Object], default: function() { return Y; } }, rounded: { type: String, validator: function(e) { return ["none", "small", "medium", "large", "full"].includes(e); } }, fillMode: { type: String, validator: function(e) { return ["solid", "flat", "outline"].includes(e); } }, size: { type: String, validator: function(e) { return ["small", "medium", "large"].includes(e); } }, tabIndex: Number, title: String, steps: Object, placeholder: String, max: { type: Date, default: function() { return u(J); } }, min: { type: Date, default: function() { return u(W); } }, maxTime: { type: Date, default: function() { return u(ee); } }, minTime: { type: Date, default: function() { return u(Z); } }, disabled: { type: Boolean, default: !1 }, spinners: { type: Boolean, default: !1 }, name: String, dir: String, label: String, id: String, validationMessage: { type: String, default: se }, required: { type: Boolean, default: !1 }, validityStyles: { type: Boolean, default: !0 }, validate: Boolean, valid: { type: Boolean, default: void 0 }, ariaRole: { type: String, default: void 0 }, ariaControls: String, ariaLabel: String, ariaExpanded: { type: Boolean, default: void 0 }, ariaHasPopup: { type: String, default: void 0 }, inputAttributes: Object }, data() { return { kendoDate: null, currentFormat: void 0, valueDuringOnChange: void 0, hasMounted: !1, isEmpty: void 0, lastSelectedSymbol: void 0, isFocused: !1 }; }, created() { K(H); const { formatPlaceholder: e, format: t, value: i, defaultValue: a } = this.$props; this.kendoDate = new z(this.intl, e, t), this.kendoDate.setValue(null), this._emptyText = this.kendoDate.getTextAndFormat().text, this.kendoDate.setValue(i || a || null), this._element = null, this._inputId = q(); }, computed: { computedValue() { return this.$data.valueDuringOnChange !== void 0 ? this.$data.valueDuringOnChange : this.kendoDate && this.kendoDate.getDateObject(); }, wrapperClassNames() { const e = !this.$data.hasMounted || !this.$props.validityStyles || this.validity().valid, t = this.$props.disabled, { size: i, fillMode: a, rounded: n } = this.$props; return { "k-dateinput": !0, "k-input": !0, [`k-input-${v.sizeMap[i] || i}`]: i, [`k-input-${a}`]: a, [`k-rounded-${v.roundedMap[n] || n}`]: n, "k-disabled": t, "k-invalid": !e && e !== void 0, "k-focus": this.isFocused, "k-rtl": this.$props.dir === "rtl" }; } }, methods: { selection() { let e = { start: 0, end: 0 }; const t = this.element(); return t !== null && t.selectionStart !== void 0 && (e = { start: t.selectionStart, end: t.selectionEnd }), e; }, element() { return this._element; }, focus(e) { this._element && this._element.focus(e); }, handleFocus(e) { this.$data.isFocused = !0, this.$emit("focus", { event: e }); }, handleBlur(e) { this.$data.isFocused = !1, this.$emit("blur", { event: e }); }, intl() { return A(this); }, setValidity() { const e = this.element(); e && e.setCustomValidity && e.setCustomValidity(this.validity().valid ? "" : this.$props.validationMessage); }, spinnersMouseDown(e) { const t = this.element(); e.preventDefault(), t && h && document.activeElement !== t && t.focus({ preventScroll: !0 }); }, elementChange(e) { const t = this.element(); if (!t || !this.kendoDate) return; const { text: i, format: a } = this.kendoDate.getTextAndFormat(); this.$data.currentFormat = a; const n = this.computedValue, s = X(i, this.$data.currentFormat, t.value, this.selection().start), l = s.length === 1 && s[0][1] === "_"; if (!l) for (let r = 0; r < s.length; r++) this.kendoDate.parsePart(s[r][0], s[r][1]); s.length && s[0][0] !== "_" && this.setSelection(this.selectionBySymbol(s[0][0])), l && this.switchDateSegment(1), this.triggerChange(e, n); }, elementClick(e) { this.setSelection(this.selectionByIndex(this.selection().start)); }, wheel(e) { const t = this.element(); h && document.activeElement !== t || (e.deltaY < 0 && (e.preventDefault(), this.increasePart(e)), e.deltaY > 0 && (e.preventDefault(), this.decreasePart(e))); }, increasePart(e) { e.preventDefault(), this.modifyDateSegmentValue(1, e); }, decreasePart(e) { e.preventDefault(), this.modifyDateSegmentValue(-1, e); }, elementKeyDown(e) { if (!e.altKey) { switch (e.keyCode) { case 37: this.switchDateSegment(-1); break; case 38: this.modifyDateSegmentValue(1, e); break; case 39: this.switchDateSegment(1); break; case 40: this.modifyDateSegmentValue(-1, e); break; default: return; } e.preventDefault(); } }, setSelection(e) { const t = this.element(); this.$data.lastSelectedSymbol = this.$data.currentFormat[e.start], h && window.requestAnimationFrame(() => { t && h && document.activeElement === t && t.setSelectionRange(e.start, e.end); }); }, triggerChange(e, t) { this.$data.valueDuringOnChange = this.computedValue, B(t, this.computedValue) || (this.$emit("changemodel", this.computedValue), this.$emit("update:modelValue", this.computedValue), this.$emit("change", { event: e, value: this.computedValue, component: this, target: { name: this.$props.name, value: this.$data.valueDuringOnChange, valueAsDate: this.$data.valueDuringOnChange }, validity: this.validity() })), this.$data.valueDuringOnChange = void 0; }, selectionBySymbol(e) { let t = -1, i = 0; for (let a = 0; a < this.$data.currentFormat.length; a++) this.$data.currentFormat[a] === e && (i = a + 1, t === -1 && (t = a)); return t < 0 && (t = 0), { start: t, end: i }; }, selectionByIndex(e) { let t = { start: e, end: e }; for (let i = e, a = e - 1; i < this.$data.currentFormat.length || a >= 0; i++, a--) { if (i < this.$data.currentFormat.length && this.$data.currentFormat[i] !== "_") { t = this.selectionBySymbol(this.$data.currentFormat[i]); break; } if (a >= 0 && this.$data.currentFormat[a] !== "_") { t = this.selectionBySymbol(this.$data.currentFormat[a]); break; } } return t; }, switchDateSegment(e) { const { start: t, end: i } = this.selection(); if (t < i && this.$data.currentFormat[t] !== this.$data.currentFormat[i - 1]) { this.setSelection(this.selectionByIndex(e > 0 ? t : i - 1)); return; } const a = this.$data.currentFormat[t]; let n = t + e; for (; n > 0 && n < this.$data.currentFormat.length && !(this.$data.currentFormat[n] !== a && this.$data.currentFormat[n] !== "_"); ) n += e; if (this.$data.currentFormat[n] === "_") return; let s = n; for (; s >= 0 && s < this.$data.currentFormat.length && this.$data.currentFormat[s] === this.$data.currentFormat[n]; ) s += e; n > s && (s + 1 !== t || n + 1 !== i) ? this.setSelection({ start: s + 1, end: n + 1 }) : n < s && (n !== t || s !== i) && this.setSelection({ start: n, end: s }); }, modifyDateSegmentValue(e, t) { if (!this.kendoDate) return; const i = this.computedValue, a = this.$data.currentFormat[this.selection().start], n = this.kendoDate.symbolMap(a), s = ((this.$props.steps || {})[n] || 1) * e; this.kendoDate.modifyPart(a, s), this.setSelection(this.selectionBySymbol(a)), this.triggerChange(t, i); }, validity() { const e = U(this.computedValue, this.$props.min, this.$props.max) && Q(this.computedValue, this.$props.minTime, this.$props.maxTime), t = this.$props.validationMessage !== void 0, i = (!this.$props.required || this.computedValue !== null) && e, a = 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: a, valueMissing: this.computedValue === null }; } }, mounted() { this._element = N(this, "input"), this.setValidity(), this.$data.hasMounted = !0; }, updated() { this.$data.lastSelectedSymbol && this.setSelection(this.selectionBySymbol(this.$data.lastSelectedSymbol)), this.setValidity(); }, setup() { const e = O(null), t = S("kendoIntlService", {}), i = S("kendoLocalizationService", {}); return { inputRef: e, kendoIntlService: t, kendoLocalizationService: i }; }, render() { const e = L(this), t = E(this), { formatPlaceholder: i, format: a, value: n, modelValue: s, name: l, label: r, id: b, ariaLabel: k, ariaExpanded: V, ariaHasPopup: F, ariaRole: C, ariaControls: I, inputAttributes: M } = this.$props, f = n !== void 0 ? n : s; this.kendoDate.format = a, this.kendoDate.formatPlaceholder = i, this.valueDuringOnChange = this.valueDuringOnChange ? this.valueDuringOnChange : void 0, f !== void 0 && this.computedValue !== f && this.kendoDate.setValue(f); const { text: g, format: w } = this.kendoDate.getTextAndFormat(); this.$data.currentFormat = w, this.$data.isEmpty = g === this._emptyText; const $ = this.$props.placeholder !== void 0 && this.$data.isEmpty && !this.$data.isFocused ? null : g, y = b || this._inputId, x = !this.$props.validityStyles || this.validity().valid, d = o("span", { class: this.wrapperClassNames, dir: this.$props.dir }, [o("input", _({ role: C, tabindex: this.$props.tabIndex, disabled: this.$props.disabled, title: this.$props.title !== void 0 ? this.$props.title : g, type: "text", spellcheck: !1, autocomplete: "off", autocorrect: "off", class: "k-input-inner", id: y, placeholder: this.$props.placeholder, onWheel: this.wheel, onClick: this.elementClick, onInput: this.elementChange, onKeydown: this.elementKeyDown, onChange: j, onFocusin: this.handleFocus, onFocusout: this.handleBlur, value: $, name: l, "aria-label": k, "aria-expanded": V, "aria-haspopup": F, "aria-controls": I, "aria-disabled": this.$props.disabled || void 0, ref: R(this, "input") }, M), null), e, this.$props.spinners && o("span", { class: "k-input-spinner k-spin-button", onMousedown: this.spinnersMouseDown }, [o(D, { type: "button", tabIndex: -1, icon: "chevron-up", svgIcon: ie, size: this.$props.size, fillMode: this.$props.fillMode, class: "k-spinner-increase", "aria-label": t.toLanguageString(c, p[c]), title: t.toLanguageString(c, p[c]), onClick: this.increasePart }, null), o(D, { type: "button", tabIndex: -1, class: "k-spinner-decrease", icon: "chevron-down", svgIcon: ae, size: this.$props.size, fillMode: this.$props.fillMode, "aria-label": t.toLanguageString(m, p[m]), title: t.toLanguageString(m, p[m]), onClick: this.decreasePart }, null)])]); return r ? o(te, { label: r, editorId: y, editorValue: $, editorPlaceholder: this.$props.placeholder, editorValid: x, editorDisabled: this.$props.disabled }, ne(d) ? d : { default: () => [d] }) : d; } }); export { De as DateInput };