@progress/kendo-react-dateinputs
Version:
React DateInput is a perfect input component for handling quick and efficient date values. KendoReact Date Inputs package
422 lines (421 loc) • 13.1 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 * as n from "react";
import e from "prop-types";
import { Popup as ut } from "@progress/kendo-react-popup";
import { cloneDate as le, getDate as st } from "@progress/kendo-date-math";
import { useId as ct, useAdaptiveModeContext as dt, usePropsContext as ft, canUseDOM as ie, AsyncFocusBlur as mt, classNames as ue, kendoThemeMaps as se, createPropsContext as pt, Keys as O } from "@progress/kendo-react-common";
import { calendarIcon as gt } from "@progress/kendo-svg-icons";
import { DateInput as ht } from "../dateinput/DateInput.mjs";
import { Calendar as vt } from "../calendar/components/Calendar.mjs";
import { nullable as r, MAX_DATE as bt, MIN_DATE as wt, isInDateRange as yt, setTime as Ct } from "../utils.mjs";
import { toggleCalendar as ce, messages as Dt } from "../messages/index.mjs";
import { useLocalization as Ot } from "@progress/kendo-react-intl";
import { ToggleButton as Mt } from "./ToggleButton.mjs";
import { PickerFloatingLabel as kt } from "../hooks/usePickerFloatingLabel.mjs";
import { ActionSheetContent as Pt } from "@progress/kendo-react-layout";
import { AdaptiveMode as Rt } from "../common/AdaptiveMode.mjs";
const de = n.forwardRef((a, fe) => {
const L = ct(a.id), me = Ot(), h = dt(), {
defaultShow: pe = l.defaultShow,
defaultValue: ge = l.defaultValue,
dateInput: he = l.dateInput,
calendar: ve = l.calendar,
toggleButton: be = l.toggleButton,
popup: we = l.popup,
disabled: v = l.disabled,
format: ye = l.format,
max: R = l.max,
min: _ = l.min,
popupSettings: b = l.popupSettings,
tabIndex: Ce = l.tabIndex,
weekNumber: De = l.weekNumber,
validityStyles: K = l.validityStyles,
size: I = l.size,
rounded: S = l.rounded,
fillMode: E = l.fillMode,
autoFocus: Oe = l.autoFocus,
show: q,
autoSwitchParts: Me,
autoSwitchKeys: ke,
twoDigitYearMax: Pe,
ariaLabel: Re,
adaptive: It,
adaptiveTitle: _e = a.label || void 0,
adaptiveSubtitle: Ie,
formatPlaceholder: Se,
inputAttributes: Ee,
validationMessage: W,
visited: St,
value: B,
touched: Et,
modified: Bt,
_adaptiveMode: xt = h,
valid: H,
focusedDate: Be,
id: xe,
ariaLabelledBy: Te,
ariaDescribedBy: Ae,
placeholder: Ve,
onChange: U,
onOpen: Y,
onClose: $,
...j
} = ft(_t, a), x = () => {
if (ie)
return y.current && y.current.ownerDocument || window.document;
}, u = () => !!(g.windowWidth && h && g.windowWidth <= (h == null ? void 0 : h.medium) && a.adaptive), f = () => {
const t = M.current !== void 0 ? M.current : B !== void 0 ? B : g.value;
return t !== null ? le(t) : null;
}, i = () => k.current !== void 0 ? k.current : q !== void 0 ? q : g.show, Fe = () => he || l.dateInput, Ne = () => be || l.toggleButton, ze = () => ve || l.calendar, Le = () => we || l.popup, X = () => a.required !== void 0 ? a.required : !1, T = () => {
const t = f() || B || null, o = _, s = R, P = yt(t, o, s), F = W !== void 0, N = (!X() || t != null) && P, z = H !== void 0 ? H : N;
return {
customError: F,
rangeOverflow: t && s.getTime() < t.getTime() || !1,
rangeUnderflow: t && t.getTime() < o.getTime() || !1,
valid: z,
valueMissing: t === null
};
}, Ke = (t) => {
for (const o of t)
D({ windowWidth: o.target.clientWidth });
}, qe = () => {
c.current && c.current.focus();
}, Z = (t) => {
d.current = t;
}, m = (t) => {
i() !== t && (D({ show: t }), t && Y && Y({ target: w.current }), !t && $ && $({ target: w.current }));
}, We = (t) => {
const o = f();
return o && t ? Ct(t, o) : t;
}, He = (t) => {
b != null && b.onMouseDownOutside && b.onMouseDownOutside(t);
}, G = (t, o) => {
D({ value: le(t || void 0) }), M.current = t, k.current = !1, u() || (p.current = !0), U && U({
syntheticEvent: o.syntheticEvent,
nativeEvent: o.nativeEvent,
value: f(),
show: i(),
target: w.current
}), M.current = void 0, k.current = void 0, m(!1);
}, Ue = (t) => {
const o = We(t.value);
G(o, t);
}, J = () => {
const { popupClass: t, ...o } = b, s = i(), P = f(), F = P && st(P), N = ue(t), z = {
popupClass: "k-datepicker-popup",
show: s,
anchor: y.current,
className: N,
id: ee,
anchorAlign: {
horizontal: "left",
vertical: "bottom"
},
popupAlign: {
horizontal: "left",
vertical: "top"
},
...o,
onMouseDownOutside: He
}, re = {
disabled: v,
value: F,
min: _,
max: R,
weekNumber: De,
focusedDate: Be,
className: u() ? "k-calendar-lg" : "",
navigation: !u(),
onChange: Ue
}, ae = ze(), it = Le();
return u() ? /* @__PURE__ */ n.createElement(ae, { _ref: Z, ...re }) : /* @__PURE__ */ n.createElement(it, { ...z }, /* @__PURE__ */ n.createElement(ae, { _ref: Z, ...re }));
}, Q = () => {
D({ focused: !1 }), m(!1);
}, Ye = () => {
const { windowWidth: t = 0 } = g, o = {
expand: i(),
onClose: Q,
title: _e,
subTitle: Ie,
windowWidth: t
};
return /* @__PURE__ */ n.createElement(Rt, { ...o }, /* @__PURE__ */ n.createElement(Pt, null, J()));
}, $e = (t) => {
G(t.value, t);
}, je = () => {
D({ focused: !0 });
}, Xe = () => {
m(!i());
}, A = () => {
v || (p.current = !0, m(!i()));
}, Ze = (t) => {
t.preventDefault();
}, Ge = (t) => {
const { altKey: o, keyCode: s } = t;
if (s === O.esc && i()) {
p.current = !0, m(!1);
return;
}
o && (s === O.up || s === O.down) && (t.preventDefault(), t.stopPropagation(), p.current = s === O.up, m(s === O.down));
}, w = n.useRef(null), y = n.useRef(null), c = n.useRef(null), d = n.useRef(null);
n.useImperativeHandle(
w,
() => ({
props: a,
get element() {
return y.current;
},
get calendar() {
return d.current;
},
get dateInput() {
return c.current;
},
get name() {
return a.name;
},
get show() {
return i();
},
get validity() {
return T();
},
get value() {
return f();
},
get mobileMode() {
return u();
},
togglePopup: Xe,
// Hidden Methods but still accessible
focus: qe
})
), n.useImperativeHandle(fe, () => w.current);
const M = n.useRef(void 0), k = n.useRef(void 0), Je = n.useRef(null), p = n.useRef(!1), V = n.useRef(!1), C = n.useRef(null), [g, Qe] = n.useState({
value: ge,
show: pe,
focused: !1
}), [, et] = n.useReducer((t) => t, !0), D = (t) => {
Qe((o) => ({ ...o, ...t }));
};
n.useEffect(() => {
d.current && d.current.element && i() && !V.current && d.current.element.focus({ preventScroll: !0 }), u() && i() && !V.current && setTimeout(() => {
d.current && d.current.element && d.current.element.focus({ preventScroll: !0 });
}, 300), c.current && c.current.element && !i() && p.current && c.current.element.focus({ preventScroll: !0 }), V.current = i(), p.current = !1;
}), n.useEffect(() => {
var t;
return C.current = ie && window.ResizeObserver && new window.ResizeObserver((o) => Ke(o)), i() && et(), (t = x()) != null && t.body && C.current && C.current.observe(x().body), () => {
var o;
clearTimeout(Je.current), (o = x()) != null && o.body && C.current && C.current.disconnect();
};
}, []);
const ee = L + "-popup-id", tt = J(), nt = Fe(), ot = f(), rt = Ne(), at = Ye(), te = !K || T().valid, ne = me.toLanguageString(ce, Dt[ce]), lt = {
disabled: v,
format: ye,
formatPlaceholder: Se,
id: xe,
ariaLabelledBy: Te,
ariaDescribedBy: Ae,
ariaLabel: Re,
max: R,
min: _,
name: a.name,
onChange: $e,
required: a.required,
_ref: c,
tabIndex: i() ? -1 : Ce,
title: a.title,
valid: T().valid,
validationMessage: W,
validityStyles: K,
value: ot,
label: void 0,
placeholder: g.focused ? null : Ve,
ariaExpanded: i(),
size: null,
fillMode: null,
rounded: null,
autoFill: a.autoFill,
twoDigitYearMax: Pe,
enableMouseWheel: a.enableMouseWheel,
autoCorrectParts: a.autoCorrectParts,
autoSwitchParts: Me,
autoSwitchKeys: ke,
allowCaretMode: a.allowCaretMode,
inputAttributes: Ee
}, oe = /* @__PURE__ */ n.createElement(
mt,
{
onFocus: je,
onBlur: u() ? void 0 : Q,
onSyncBlur: a.onBlur,
onSyncFocus: a.onFocus
},
(t) => /* @__PURE__ */ n.createElement(n.Fragment, null, /* @__PURE__ */ n.createElement(
"span",
{
...a.label ? {} : j,
ref: y,
className: ue(
"k-input",
"k-datepicker",
{
[`k-input-${se.sizeMap[I] || I}`]: I,
[`k-rounded-${se.roundedMap[S] || S}`]: S,
[`k-input-${E}`]: E,
"k-invalid": !te,
"k-required": X(),
"k-disabled": v
},
a.className
),
onKeyDown: Ge,
style: { width: a.width },
onFocus: u() ? A : t.onFocus,
onBlur: t.onBlur,
onClick: u() ? A : void 0
},
/* @__PURE__ */ n.createElement(
nt,
{
_ref: c,
ariaRole: "combobox",
ariaExpanded: i(),
ariaControls: ee,
autoFocus: Oe,
...lt
}
),
/* @__PURE__ */ n.createElement(
rt,
{
type: "button",
icon: "calendar",
svgIcon: gt,
title: ne,
className: "k-input-button",
rounded: null,
onClick: u() ? void 0 : A,
"aria-label": ne,
fillMode: E,
onMouseDown: Ze
}
),
!u() && tt
), u() && at)
);
return a.label ? /* @__PURE__ */ n.createElement(
kt,
{
dateInput: c,
label: a.label,
editorId: L,
editorValid: te,
editorDisabled: v,
children: oe,
style: { width: a.width },
...j
}
) : oe;
});
de.propTypes = {
className: e.string,
defaultShow: e.bool,
defaultValue: e.instanceOf(Date),
disabled: e.bool,
focusedDate: e.instanceOf(Date),
format: e.oneOfType([
e.string,
e.shape({
skeleton: r(e.string),
pattern: r(e.string),
date: r(e.oneOf(["short", "medium", "long", "full"])),
time: r(e.oneOf(["short", "medium", "long", "full"])),
datetime: r(e.oneOf(["short", "medium", "long", "full"])),
era: r(e.oneOf(["narrow", "short", "long"])),
year: r(e.oneOf(["numeric", "2-digit"])),
month: r(e.oneOf(["numeric", "2-digit", "narrow", "short", "long"])),
day: r(e.oneOf(["numeric", "2-digit"])),
weekday: r(e.oneOf(["narrow", "short", "long"])),
hour: r(e.oneOf(["numeric", "2-digit"])),
hour12: r(e.bool),
minute: r(e.oneOf(["numeric", "2-digit"])),
second: r(e.oneOf(["numeric", "2-digit"])),
timeZoneName: r(e.oneOf(["short", "long"]))
})
]),
formatPlaceholder: e.oneOfType([
r(
e.oneOf(["wide", "narrow", "short", "formatPattern"])
),
e.shape({
year: r(e.string),
month: r(e.string),
day: r(e.string),
hour: r(e.string),
minute: r(e.string),
second: r(e.string)
})
]),
id: e.string,
ariaLabelledBy: e.string,
ariaDescribedBy: e.string,
ariaLabel: e.string,
min: e.instanceOf(Date),
max: e.instanceOf(Date),
name: e.string,
popupSettings: e.shape({
animate: r(e.bool),
appendTo: r(e.any),
popupClass: r(e.string)
}),
show: e.bool,
tabIndex: e.number,
title: e.string,
value: e.instanceOf(Date),
weekNumber: e.bool,
width: e.oneOfType([e.number, e.string]),
validationMessage: e.string,
required: e.bool,
valid: e.bool,
size: e.oneOf([null, "small", "medium", "large"]),
rounded: e.oneOf([null, "small", "medium", "large", "full"]),
fillMode: e.oneOf([null, "solid", "flat", "outline"]),
adaptive: e.bool,
adaptiveTitle: e.string,
adaptiveSubtitle: e.string,
autoFocus: e.bool,
inputAttributes: e.object
};
const l = {
defaultShow: !1,
defaultValue: null,
dateInput: ht,
calendar: vt,
toggleButton: Mt,
popup: ut,
disabled: !1,
format: "d",
max: bt,
min: wt,
popupSettings: {},
tabIndex: 0,
weekNumber: !1,
validityStyles: !0,
size: "medium",
rounded: "medium",
fillMode: "solid",
autoFocus: !1
}, _t = pt();
de.displayName = "KendoReactDatePicker";
export {
de as DatePicker,
_t as DatePickerPropsContext,
l as datePickerDefaultProps
};