UNPKG

@progress/kendo-react-dateinputs

Version:

React DateInput is a perfect input component for handling quick and efficient date values. KendoReact Date Inputs package

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