@progress/kendo-vue-dateinputs
Version:
267 lines (266 loc) • 7.48 kB
JavaScript
/**
* @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 w, inject as m, createVNode as s, isVNode as B } from "vue";
import { Button as b } from "@progress/kendo-vue-buttons";
import { cloneDate as S } from "@progress/kendo-date-math";
import { classNames as d, canUseDOM as I, Keys as f } from "@progress/kendo-vue-common";
import { provideIntlService as M, provideLocalizationService as T } from "@progress/kendo-vue-intl";
import { selectNow as g, messages as v, now as y } from "../messages/main.mjs";
import { TimeList as R } from "./TimeList.mjs";
import { MAX_TIME as F, MIN_TIME as N, MIDNIGHT_DATE as x } from "../utils.mjs";
import { TIME_PART as a } from "./models/TimePart.mjs";
import { snapTime as L, generateSnappers as k, timeInRange as D, isInTimeRange as _, getNow as C } from "./utils.mjs";
function j(t) {
return typeof t == "function" || Object.prototype.toString.call(t) === "[object Object]" && !B(t);
}
const u = new RegExp(`${a.hour}|${a.minute}|${a.second}|${a.dayperiod}|literal`);
let c = /* @__PURE__ */ function(t) {
return t[t.Left = 0] = "Left", t[t.Right = 1] = "Right", t;
}({});
const X = /* @__PURE__ */ w({
name: "KendoTimePart",
props: {
cancelButton: {
type: Boolean,
default: !0
},
disabled: {
type: Boolean,
default: !1
},
format: {
type: [String, Object],
default: function() {
return "hh:mm a";
}
},
max: {
type: Date,
default: function() {
return F;
}
},
min: {
type: Date,
default: function() {
return N;
}
},
nowButton: {
type: Boolean,
default: !0
},
steps: {
type: Object,
default: function() {
return {};
}
},
smoothScroll: {
type: Boolean,
default: !0
},
tabIndex: Number,
value: {
type: Date,
default: function() {
return null;
}
},
boundRange: {
type: Boolean,
default: !1
}
},
emits: {
change: null,
focus: null,
blur: null,
nowclick: null
},
created() {
this.timeLists = [], this.snapTime = L(k(this.$props.steps, this.$props.min)), this.activeListIndex = -1, this.hasActiveButton = this.hasActiveButton.bind(this);
},
inject: {
kendoIntlService: {
default: null
},
kendoLocalizationService: {
default: null
}
},
data() {
return {
activeListIndex: null
};
},
computed: {
element() {
return this._element;
},
computedValue() {
return D(this.snapTime(S(this.$props.value || x)), this.computedMin, this.computedMax);
},
intl() {
return M(this);
},
computedMin() {
return this.snapTime(this.$props.min);
},
computedMax() {
return this.snapTime(this.$props.max);
}
},
mounted() {
this._nowButton = this.$refs.nowButton, this.dateFormatParts.forEach((t, e) => {
t.type !== "literal" && this.timeLists.push(this.$refs["timeList" + e]);
});
},
setup() {
const t = m("kendoIntlService", {}), e = m("kendoLocalizationService", {});
return {
kendoIntlService: t,
kendoLocalizationService: e
};
},
render() {
let t;
const {
format: e,
smoothScroll: n,
disabled: i
} = this.$props;
this.snapTime = L(k(this.$props.steps, this.computedMin)), this.dateFormatParts = this.intl.splitDateFormat(e).filter(this.timeFormatFilter);
const $ = d({
"k-disabled": i
}, "k-time-part"), h = T(this), p = h.toLanguageString(g, v[g]);
return s("div", {
class: $
}, [s("div", {
class: "k-time-header"
}, [s("span", {
class: "k-title"
}, [this.intl.formatDate(this.computedValue, this.dateFormatParts.reduce(this.timeFormatReducer, ""))]), this.showNowButton() && s(b, {
type: "button",
ref: "nowButton",
fillMode: "flat",
class: "k-time-now",
title: p,
"aria-label": p,
onClick: this.onNowClick,
tabIndex: i ? -1 : 0
}, j(t = h.toLanguageString(y, v[y])) ? t : {
default: () => [t]
})]), s("div", {
class: "k-time-list-container",
onKeydown: this.handleKeyDown
}, [s("span", {
class: "k-time-highlight"
}, null), this.dateFormatParts.map(function(o, r) {
return o.type !== "literal" ? s("div", {
key: r,
class: d("k-time-list-wrapper", {
"k-focus": r === this.activeListIndex
}),
role: "presentation",
tabindex: -1
}, [s("span", {
class: "k-title",
onMousedown: (l) => {
l.preventDefault();
}
}, [this.intl.dateFieldName(o)]), s(R, {
min: this.computedMin,
max: this.computedMax,
boundRange: this.$props.boundRange,
part: o,
step: o.type ? this.$props.steps[o.type] : 1,
smoothScroll: n,
ref: "timeList" + r,
id: r,
onFocus: (l) => {
this.handleListFocus(l, r);
},
onBlur: this.handleListBlur,
onChange: this.handleChange,
value: this.computedValue,
disabled: i
}, null)]) : s("div", {
key: r,
class: "k-time-separator"
}, [o.pattern]);
}, this)])]);
},
methods: {
onNowClick(t) {
this.$emit("nowclick", t);
},
focus(t) {
this.$nextTick(() => {
const e = this.timeLists[0];
!this.hasActiveButton() && e && e.$el && e.focus(t);
});
},
timeFormatReducer(t, e) {
return t + e.pattern;
},
timeFormatFilter(t, e, n) {
const i = e >= 1 && n[e - 1];
return i && i && t.type === "literal" ? u.test(i.type || "") : u.test(t.type || "");
},
hasActiveButton() {
return I && this._nowButton && document.activeElement === this._nowButton.$el;
},
focusList(t) {
this.timeLists.length && this.timeLists.reduce(this.listReducer, []).map((e) => t === c.Right ? e.next : e.prev).map((e) => e && e.$el && e.$el.focus({
preventScroll: !0
}));
},
listReducer(t, e, n, i) {
return t.length || e.$props.id !== this.activeListIndex ? t : [{
next: i[n + 1] || e,
prev: i[n - 1] || e
}];
},
showNowButton() {
return !this.hasSteps() && this.$props.nowButton && _(C(), this.computedMin, this.computedMax);
},
hasSteps() {
const t = Object.keys(this.$props.steps);
return t.length !== t.reduce((e, n) => e + this.$props.steps[n], 0);
},
handleKeyDown(t) {
const {
keyCode: e
} = t;
switch (e) {
case f.left:
t.preventDefault(), this.focusList(c.Left);
return;
case f.right:
t.preventDefault(), this.focusList(c.Right);
return;
default:
return;
}
},
handleListBlur(t) {
this.$emit("blur", t);
},
handleListFocus(t, e) {
this.$emit("focus", t), this.activeListIndex = e;
},
handleChange(t) {
this.$emit("change", t);
}
}
});
export {
c as Direction,
X as TimePart
};