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.2 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 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 };