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