UNPKG

@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
/** * @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 };