UNPKG

@progress/kendo-vue-inputs

Version:
431 lines (430 loc) 17 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 P, ref as v, inject as V, h as b, createVNode as i, mergeProps as M } from "vue"; import { validatePackage as w, guid as R, getRef as F, canUseDOM as $, kendoThemeMaps as S, getDefaultSlots as z, templateRendering as _, getListeners as C, getTemplate as k, Icon as u, setRef as T } from "@progress/kendo-vue-common"; import { provideIntlService as U, provideLocalizationService as A } from "@progress/kendo-vue-intl"; import { Button as y } from "@progress/kendo-vue-buttons"; import { numericIncreaseValue as d, messages as h, numericDecreaseValue as c } from "../messages/main.mjs"; import { formatValue as m, getStateOrPropsValue as I, sanitizeNumber as x, rangeValue as f, increaseValue as L, decreaseValue as O } from "./utils/main.mjs"; import { packageMetadata as W } from "../package-metadata.mjs"; import { checkIcon as j, exclamationCircleIcon as q, xIcon as K, caretAltUpIcon as H, caretAltDownIcon as Y } from "@progress/kendo-svg-icons"; const G = "Please enter a valid value!", ae = /* @__PURE__ */ P({ model: { event: "changemodel" }, emits: { change: null, changemodel: null, "update:modelValue": null, focus: null, blur: null }, props: { modelValue: Number, value: Number, defaultValue: Number, step: { type: Number, default: 1 }, format: [String, Object], tabIndex: Number, accessKey: String, title: String, placeholder: String, min: Number, max: Number, spinners: { type: Boolean, default: !0 }, disabled: { type: Boolean, default: !1 }, dir: String, name: String, label: String, validationMessage: String, validityStyles: { type: Boolean, default: !0 }, valid: { type: Boolean, default: void 0 }, size: { type: String, default: "medium", validator: function(t) { return [null, "small", "medium", "large"].includes(t); } }, rounded: { type: String, default: "medium", validator: function(t) { return [null, "small", "medium", "large", "full"].includes(t); } }, fillMode: { type: String, default: "solid", validator: function(t) { return [null, "solid", "flat", "outline"].includes(t); } }, required: { type: Boolean, default: !1 }, id: String, ariaLabel: String, iconName: String, inputPrefix: [String, Function], inputSuffix: [String, Function], showValidationIcon: Boolean, showLoadingIcon: Boolean, showClearButton: Boolean, inputClass: String, inputType: { type: String, default: "tel" }, wrapperClass: String, inputAttributes: Object }, inject: { kendoIntlService: { default: null }, kendoLocalizationService: { default: null } }, data() { return { hasMounted: !1, isInvalid: !1, isEmpty: !1, currentValue: 0, valueDuringOnChange: 0, currentLooseValue: "", selectionStart: 0, selectionEnd: 0, decimalSelect: !1, focused: !1, forceUpdate: !1 }; }, created() { w(W), this._textBeforeInput = "", this._inputId = R(), this.$data.currentLooseValue = null, this.$data.valueDuringOnChange = void 0, this._intl = U(this), this._symbols = this._intl.numberSymbols(), this.$props.value !== void 0 ? this.$data.currentValue = this.$props.value : this.$props.modelValue !== void 0 ? this.$data.currentValue = this.$props.modelValue : this.$props.defaultValue !== void 0 ? this.$data.currentValue = this.$props.defaultValue : this.$data.currentValue = null; }, mounted() { this._input = F(this, "input"), this._elementWrapper = this.elementWrapperRef, this.$data.hasMounted = !0, this._input && (this._textBeforeInput = this._input.value), this.setValidity(); }, updated() { !($ && document.activeElement !== this._input || !this._input) && this.$data.currentLooseValue !== null && this.$data.forceUpdate && this._input.type !== "number" && (this._input.selectionStart = this.$data.selectionStart, this._input.selectionEnd = this.$data.selectionEnd, this.$data.forceUpdate = !1), this._input && (this._textBeforeInput = this._input.value), this.setValidity(); }, computed: { computedValue() { return this.$data.valueDuringOnChange !== void 0 ? this.$data.valueDuringOnChange : this.$data.currentValue; }, looseValue() { return m(this.$data.focused ? this.$data.currentLooseValue : I(this.$props.value, this.$data.currentValue), this.$props.format, this._intl); }, spanClassNames() { const t = !this.$data.hasMounted || !this.$props.validityStyles || this.validity().valid, e = this.computedValue; return { "k-floating-label-container": !0, "k-focus": this.$data.focused, "k-empty": !(e === 0 || e || this.$props.placeholder), "k-invalid": !t && t !== void 0, "k-rtl": this.$props.dir === "rtl", [this.inputClass]: this.inputClass }; }, wrapperClassNames() { const { size: t, fillMode: e, rounded: s, required: a, disabled: l } = this.$props, n = !this.$props.validityStyles || this.validity().valid; return { "k-input": !0, "k-numerictextbox": !0, [`k-input-${S.sizeMap[t] || t}`]: t, [`k-input-${e}`]: e, [`k-rounded-${S.roundedMap[s] || s}`]: s, "k-invalid": !n, "k-required": a, "k-disabled": l, "k-loading": this.showLoadingIcon, [this.wrapperClass]: this.wrapperClass }; }, inputInnerClass() { return { "k-input-inner": !0, [this.inputClass]: this.inputClass }; } }, methods: { validity() { const t = this.$props.validationMessage !== void 0, e = !this.$data.valueIsOutOfRange && (!this.$props.required || this.computedValue !== null), s = this.$props.valid !== void 0 ? this.$props.valid : e; return { customError: t, valid: s, valueMissing: this.computedValue === null }; }, clearClick(t) { this.$props.value !== void 0 ? this.$data.currentValue = this.$props.value : this.$props.modelValue !== void 0 ? this.$data.currentValue = this.$props.modelValue : this.$data.currentValue = null, this.$emit("changemodel", null), this.$emit("update:modelValue", null), this.$emit("change", { event: t, value: null, component: this, target: { name: this.$props.name, value: null }, validity: this.validity() }); }, focus() { this._input && this._input.focus(); }, emitFocus(t) { this.$data.currentLooseValue = this._prevLooseValue, this.$data.focused = !0, this.$emit("focus", t), this.$data.forceUpdate = !0; }, emitBlur(t) { this.$data.eventValue = null, this.$data.prevLooseValue = "", this.$data.currentLooseValue = "", this.$data.focused = !1, this.$data.selectionStart = void 0, this.$data.selectionEnd = void 0, this.$data.decimalSelect = !1, this.$data.valueIsCorrected = !1, this.$data.valueIsOutOfRange = !1, this.$emit("blur", t), this.$data.forceUpdate = !0; }, handleFocus(t) { this.$data.focused = !0; }, handleBlur(t) { this.$data.focused = !1; }, setValidity() { this._input && this._input.setCustomValidity && this._input.setCustomValidity(this.validity().valid ? "" : this.$props.validationMessage || G); }, getCurrentState() { return { eventValue: I(this.$props.value, this.$data.currentValue), prevLooseValue: this._prevLooseValue, currentLooseValue: this._input.value, selectionStart: this._input.selectionStart, selectionEnd: this._input.selectionEnd, decimalSelect: !1, valueIsCorrected: !1, valueIsOutOfRange: !1, isPaste: this._isPaste, focused: this.$data.focused }; }, parseNumber(t) { return this._intl.parseNumber(t, this.$props.format); }, elementChange(t) { const e = this.getCurrentState(); this._isPaste = !1, this.triggerChange(t, x(e, this.$props.format, this._intl)); }, triggerChange(t, e) { if (this.$props.disabled) return; this.$data.valueDuringOnChange = e.eventValue, this.$data.currentValue = e.eventValue; const s = m(f(e.eventValue, this.$props.min, this.$props.max), this.$props.format, this._intl), a = f(this.parseNumber(s), this.$props.min, this.$props.max); if (a !== e.eventValue && (e.valueIsOutOfRange = !0, e.eventValue = a, this.$data.valueDuringOnChange = a, this.$data.currentValue = a), e.valueIsCorrected) { const n = this._elementWrapper; n && n.className.indexOf("k-invalid") === -1 && (this.$data.isInvalid = !0, setTimeout(() => { this.$data.isInvalid = !1; }, 50)); } const l = this.$props.value !== e.eventValue; this.$props.value !== void 0 ? this.$data.currentValue = this.$props.value : this.$props.modelValue !== void 0 ? this.$data.currentValue = this.$props.modelValue : this.$data.currentValue = this.$data.valueDuringOnChange, this.$data.prevLooseValue = e.prevLooseValue, this.$data.currentLooseValue = void 0, this.$data.currentLooseValue = e.currentLooseValue, this.$data.selectionStart = e.selectionStart, this.$data.selectionEnd = e.selectionEnd, this.$data.decimalSelect = e.decimalSelect, this.$data.valueIsCorrected = e.valueIsCorrected, this.$data.valueIsOutOfRange = e.valueIsOutOfRange, this.$data.focused = e.focused, this.$data.isPaste = e.isPaste, this.$data.forceUpdate = !this.$data.forceUpdate, l && (this.$emit("changemodel", this.$data.valueDuringOnChange), this.$emit("update:modelValue", this.$data.valueDuringOnChange), this.$emit("change", { event: t, value: this.$data.valueDuringOnChange, component: this, target: { name: this.$props.name, value: this.$data.valueDuringOnChange }, validity: this.validity() })), this.$data.valueDuringOnChange = void 0; }, onPasteHandler(t) { this._isPaste = !0; }, increase(t) { const e = this.getCurrentState(); L(this.parseNumber(String(e.currentLooseValue)), e, this.$props.step, this.$props.min, this.$props.max, this.$props.format, this._intl), this.triggerChange(t, e); }, decrease(t) { const e = this.getCurrentState(); O(this.parseNumber(String(e.currentLooseValue)), e, this.$props.step, this.$props.min, this.$props.max, this.$props.format, this._intl), this.triggerChange(t, e); }, wheel(t) { !$ || document.activeElement !== this._input || !this._input || (t.deltaY < 0 && (t.preventDefault(), this.increase(t)), t.deltaY > 0 && (t.preventDefault(), this.decrease(t))); }, keyDown(t) { let e = this.getCurrentState(), s, a, l, n; const r = this.parseNumber(String(e.currentLooseValue)); if (!(e.selectionEnd > e.selectionStart && e.selectionEnd - e.selectionStart === String(e.currentLooseValue).length)) { switch (t.keyCode) { case 38: L(r, e, this.$props.step, this.$props.min, this.$props.max, this.$props.format, this._intl); break; case 40: O(r, e, this.$props.step, this.$props.min, this.$props.max, this.$props.format, this._intl); break; case 13: s = m(f(r, this.$props.min, this.$props.max), this.$props.format, this._intl), a = f(this.parseNumber(s), this.$props.min, this.$props.max), e.eventValue = a, e.currentLooseValue = m(a, this.$props.format, this._intl), e.selectionStart = e.selectionEnd = e.currentLooseValue.length; break; case 110: l = this._input, n = this._intl.numberSymbols(), l && (e.currentLooseValue = e.currentLooseValue.slice(0, e.selectionStart) + n.decimal + e.currentLooseValue.slice(e.selectionEnd), e.selectionStart = e.selectionEnd = e.selectionStart + 1, e = x(e, this.$props.format, this._intl)); break; default: return; } t.preventDefault(), this.triggerChange(t, e); } }, spinnersWrapperMouseDown(t) { $ && this._input && (t.preventDefault(), document.activeElement !== this._input && this._input.focus()); } }, setup() { const t = v(null), e = v(null), s = V("kendoLocalizationService", {}), a = V("kendoIntlService", {}); return { inputRef: t, elementWrapperRef: e, kendoLocalizationService: s, kendoIntlService: a }; }, render() { const { iconName: t, showValidationIcon: e, showLoadingIcon: s, showClearButton: a, inputAttributes: l } = this.$props, n = this.$props.id || this._inputId, r = z(this), o = A(this), p = this.validity().valid; this.$props.value !== void 0 && this.$props.value !== this.$data.currentValue ? this.$data.currentValue = this.$props.value : this.$props.modelValue !== void 0 && this.$props.modelValue !== this.$data.currentValue && (this.$data.currentValue = this.$props.modelValue), this._prevLooseValue = this.$data.currentLooseValue ? this.looseValue : this.looseValue; const D = _.call(this, this.$props.inputPrefix, C.call(this)), N = _.call(this, this.$props.inputSuffix, C.call(this)), E = k.call(this, { h: b, template: D, additionalProps: { value: this.computedValue, valid: p } }), B = k.call(this, { h: b, template: N, additionalProps: { value: this.computedValue, valid: p } }), g = i("span", { dir: this.$props.dir, class: this.wrapperClassNames, style: this.$attrs.style }, [t && i(u, { name: t, class: "k-input-icon" }, null), this.$props.inputPrefix && i("span", { class: "k-input-prefix" }, [E]), i("input", M({ tabindex: this.$props.tabIndex, accesskey: this.$props.accessKey, disabled: this.$props.disabled, title: this.$props.title, "aria-label": this.$props.ariaLabel, "aria-valuemin": this.$props.min, "aria-valuemax": this.$props.max, "aria-disabled": this.$props.disabled ? "true" : void 0, placeholder: this.$props.placeholder, type: this.$props.inputType, spellcheck: !1, autocomplete: "off", autocorrect: "off", class: this.inputInnerClass, id: n, role: "spinbutton", value: this.looseValue, name: this.$props.name, onWheel: this.wheel, onKeydown: this.keyDown, onInput: this.elementChange, onFocus: this.emitFocus, onBlur: this.emitBlur, onPaste: this.onPasteHandler, ref: T(this, "input") }, l), null), this.$props.inputSuffix && i("span", { class: "k-input-suffix" }, [B]), e && p && i(u, { name: "check", icon: j, class: "k-input-validation-icon" }, null), e && !p && i(u, { name: "exclamation-circle", icon: q, class: "k-input-validation-icon" }, null), s && i(u, { name: "loading", class: "k-input-loading-icon" }, null), a && this.computedValue !== void 0 && this.computedValue !== null && i("span", { onClick: this.clearClick, class: "k-clear-value" }, [i(u, { name: "x", icon: K }, null)]), r, this.$props.spinners && i("span", { class: "k-input-spinner k-spin-button", onMousedown: this.spinnersWrapperMouseDown }, [i(y, { type: "button", tabIndex: -1, icon: "caret-alt-up", svgIcon: H, class: "k-spinner-increase", rounded: null, "aria-label": o.toLanguageString(d, h[d]), title: o.toLanguageString(d, h[d]), onClick: this.increase }, null), i(y, { type: "button", tabIndex: -1, class: "k-spinner-decrease", icon: "caret-alt-down", svgIcon: Y, rounded: null, "aria-label": o.toLanguageString(c, h[c]), title: o.toLanguageString(c, h[c]), onClick: this.decrease }, null)])]); return this.$props.label ? i("span", { class: this.spanClassNames, onFocusin: this.handleFocus, onFocusout: this.handleBlur, dir: this.$props.dir }, [g, this.$props.label ? n ? i("label", { for: n, class: "k-floating-label" }, [this.$props.label]) : i("span", { class: "k-label" }, [this.$props.label]) : null]) : g; } }); export { ae as NumericTextBox };