UNPKG

@progress/kendo-react-dateinputs

Version:

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

339 lines (338 loc) 12.3 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 f from "react"; import s from "prop-types"; import { Keys as D, setScrollbarWidth as C, classNames as L, uCalendar as B, createPropsContext as T, withIdHOC as F, withPropsContext as K, withUnstyledHOC as U } from "@progress/kendo-react-common"; import { cloneDate as g, isEqualDate as y, getDate as c } from "@progress/kendo-date-math"; import { provideIntlService as $, registerForIntl as R } from "@progress/kendo-react-intl"; import { ViewList as _ } from "./ViewList.mjs"; import { Navigation as Y } from "./Navigation.mjs"; import { CalendarViewEnum as r } from "../models/CalendarViewEnum.mjs"; import { getToday as x, dateInRange as V, viewInRange as I, MIN_DATE as z, MAX_DATE as H, isInRange as N } from "../../utils.mjs"; import { BusViewService as q } from "../services/BusViewService.mjs"; import { DOMService as X } from "../services/DOMService.mjs"; import { NavigationService as j } from "../services/NavigationService.mjs"; import { ScrollSyncService as G } from "../services/ScrollSyncService.mjs"; const S = (u) => u ? u.virtualization : null, E = (u = d.defaultProps.min, a = d.defaultProps.max, e, t) => t !== void 0 ? t !== null && N(c(t), u, a) ? t : null : e !== null && N(c(e), u, a) ? e : null, n = class n extends f.Component { constructor(a) { super(a), this.scrollSyncService = null, this.focusedDate = null, this.Navigation = null, this.calendarViewList = null, this._element = null, this.intl = null, this.service = null, this.isActive = !1, this.didNavigationChange = !1, this.focus = () => { this._element && this._element.focus(); }, this.shouldScroll = () => this.didNavigationChange, this.handleScroll = (t) => { this.scrollSyncService && this.scrollSyncService.sync( S(this.Navigation), S(this.calendarViewList), t ); }, this.handleNavigationChange = (t) => { if (this.props.disabled) return; this.didNavigationChange = !0; const i = g(t.value); this.setState({ focusedDate: i }); }, this.handleViewChange = ({ view: t }) => { this.scrollSyncService && this.scrollSyncService.configure(t), this.setState({ activeView: t }); }, this.handleDateChange = (t) => { const i = g(t.value), o = g(t.value), v = this.bus.canMoveDown(this.state.activeView); if (this.props.disabled) return; if (v) if (t.isTodayClick) this.bus.moveToBottom(this.state.activeView); else { this.bus.moveDown(this.state.activeView, t.syntheticEvent), this.setState({ focusedDate: o }); return; } this.setState({ value: i, focusedDate: o }), this.valueDuringOnChange = i; const { onChange: h } = this.props; if (h) { const l = { syntheticEvent: t.syntheticEvent, nativeEvent: t.nativeEvent, value: i, target: this }; h.call(void 0, l); } this.valueDuringOnChange = void 0; }, this.handleFocus = (t) => { if (this.isActive = !0, !this.calendarViewList) return; this.calendarViewList.focusActiveDate(); const { onFocus: i } = this.props; i && i.call(void 0, t); }, this.handleBlur = (t) => { if (this.isActive = !1, !this.calendarViewList) return; this.calendarViewList.blurActiveDate(); const { onBlur: i } = this.props; i && i.call(void 0, t); }, this.handleKeyDown = (t) => { const { keyCode: o, ctrlKey: v, metaKey: h } = t; if (!(!this.focusedDate || !this.service)) { if (o === 84 && this.setState({ focusedDate: x() }), (v || h) && (o === D.left || o === D.right)) { if (this.props.disabled) return; this.didNavigationChange = !0, this.focusedDate.getDate() === 31 && this.focusedDate.setDate(30); const l = o === D.left ? this.focusedDate.getMonth() - 1 : this.focusedDate.getMonth() + 1, p = new Date(this.focusedDate.setMonth(l)), b = g(p); this.setState({ focusedDate: b }); } if (o === D.enter) { if (this.value !== null && y(this.focusedDate, this.value)) { const p = V(this.focusedDate, this.min, this.max); S(this.calendarViewList).scrollToIndex(this.service.skip(p, this.min)); } const l = { syntheticEvent: t, nativeEvent: t.nativeEvent, value: this.focusedDate, target: this }; this.handleDateChange(l); } else { const l = V( this.navigation.move( this.focusedDate, this.navigation.action(t), this.state.activeView, this.service, t ), this.min, this.max ); if (y(this.focusedDate, l)) return; this.setState({ focusedDate: l }); } t.preventDefault(); } }, this.handleMouseDown = (t) => { t.preventDefault(); }, this.handleClick = (t) => { this._element && this._element.focus({ preventScroll: !0 }); }; const e = E( this.min, this.max, this.props.defaultValue || n.defaultProps.defaultValue, this.props.value ); this.state = { value: e, activeView: I( r[a.defaultActiveView], this.bottomView, this.topView ), focusedDate: V(a.focusedDate || e || x(), this.min, this.max) }, this.dom = new X(), this.bus = new q(this.handleViewChange), this.navigation = new j(this.bus), this.oldValue = e; } get cellUID() { return this.props.id + "-cell-uid"; } get id() { return this.props.id + "-id"; } /** * Gets the wrapping element of the Calendar. */ get element() { return this._element; } /** * Gets the value of the Calendar. */ get value() { return this.valueDuringOnChange !== void 0 ? this.valueDuringOnChange : this.props.value !== void 0 ? this.props.value : this.state.value; } get min() { return c(this.props.min !== void 0 ? this.props.min : n.defaultProps.min); } get max() { return c(this.props.max !== void 0 ? this.props.max : n.defaultProps.max); } get bottomView() { return r[this.props.bottomView !== void 0 ? this.props.bottomView : n.defaultProps.bottomView]; } get topView() { return r[this.props.topView !== void 0 ? this.props.topView : n.defaultProps.topView]; } /** * @hidden */ componentDidMount() { const { unstyled: a } = this.props; Promise.resolve().then(() => { C(), this._element && (this.dom.calculateHeights(this._element, a), this.scrollSyncService = new G(this.dom), this.scrollSyncService.configure(this.state.activeView), this.forceUpdate()); }); } /** * @hidden */ componentDidUpdate(a, e) { C(), e.activeView !== this.state.activeView && this.scrollSyncService && this.scrollSyncService.configure(this.state.activeView), this.calendarViewList && (this.isActive ? this.calendarViewList.focusActiveDate : this.calendarViewList.blurActiveDate)(), this.didNavigationChange = !1, this.isActive && (this.oldValue = this.value); } /** * @hidden */ render() { const { _ref: a, unstyled: e, bottomView: t, topView: i, disabled: o, weekNumber: v, mobileMode: h, className: l } = this.props; a && a(this); const p = e && e.uCalendar, b = this.value !== null && this.oldValue !== null ? !y(this.value, this.oldValue) : this.value !== this.oldValue, O = I( this.state.activeView, r[t !== void 0 ? t : n.defaultProps.bottomView], r[i !== void 0 ? i : n.defaultProps.topView] ), w = E(this.min, this.max, this.value, this.value), k = w ? c(w) : null; this.focusedDate = c( V(b && w !== null ? w : this.state.focusedDate, this.min, this.max) ), this.intl = $(this), this.bus.configure(this.bottomView, this.topView), this.service = this.bus.service(O, this.intl); const { smoothScroll: A = Number.parseFloat(f.version) < 18 } = this.props, P = L( B.wrapper({ c: p, disabled: o, weekNumber: v, mobileMode: h }), l ), M = [ this.props.navigation && /* @__PURE__ */ f.createElement( Y, { key: 0, ref: (m) => { this.Navigation = m; }, activeView: this.state.activeView, focusedDate: this.focusedDate, min: this.min, max: this.max, onScroll: this.handleScroll, onChange: this.handleNavigationChange, service: this.service, dom: this.dom, navigationItem: this.props.navigationItem, tabIndex: this.props.tabIndex, unstyled: e } ), /* @__PURE__ */ f.createElement( _, { key: 1, ref: (m) => { this.calendarViewList = m; }, activeView: this.state.activeView, focusedDate: this.focusedDate, min: this.min, max: this.max, bus: this.bus, shouldScroll: this.shouldScroll, onScroll: this.handleScroll, service: this.service, cell: this.props.cell, weekCell: this.props.weekCell, dom: this.dom, smoothScroll: A, showWeekNumbers: this.props.weekNumber, onChange: this.handleDateChange, value: k, cellUID: this.cellUID, headerTitle: this.props.headerTitle, header: this.props.header, tabIndex: this.props.tabIndex, weekDaysFormat: this.props.weekDaysFormat, showOtherMonthDays: this.props.showOtherMonthDays, unstyled: e } ) ]; return /* @__PURE__ */ f.createElement( "div", { ref: (m) => { this._element = m; }, className: P, id: this.props.id || this.id, "aria-labelledby": this.props.ariaLabelledBy, "aria-describedby": this.props.ariaDescribedBy, "aria-disabled": this.props.disabled, tabIndex: this.props.disabled ? void 0 : this.props.tabIndex || 0, onFocus: this.handleFocus, onBlur: this.handleBlur, onKeyDown: this.handleKeyDown, onMouseDown: this.handleMouseDown, onClick: this.handleClick }, M ); } }; n.displayName = "Calendar", n.propTypes = { className: s.string, defaultActiveView: s.oneOf(["month", "year", "decade", "century"]), defaultValue: s.instanceOf(Date), disabled: s.bool, focusedDate: s.instanceOf(Date), id: s.string, ariaLabelledBy: s.string, ariaDescribedBy: s.string, weekDaysFormat: s.oneOf(["short", "abbreviated", "narrow"]), max: s.instanceOf(Date), min: s.instanceOf(Date), navigation: s.bool, smoothScroll: s.bool, onBlur: s.func, onChange: s.func, onFocus: s.func, tabIndex: s.number, value: s.instanceOf(Date), weekNumber: s.bool, topView: (a, e, t) => { const i = a[e], o = a.bottomView; return i && o && r[i] < r[o] ? new Error( `Invalid prop + ${e} suplied to ${t}. ${e} can not be smaller than bottomView. ` ) : null; }, bottomView: (a, e, t) => { const i = a[e], o = a.topView; return i && o && r[i] > r[o] ? new Error( `Invalid prop + ${e} suplied to ${t}. ${e} can not be bigger than topView. ` ) : null; } }, n.defaultProps = { disabled: !1, min: z, max: H, weekDaysFormat: "short", navigation: !0, defaultActiveView: "month", defaultValue: null, topView: "century", bottomView: "month", showOtherMonthDays: !1 }; let d = n; const J = T(), Q = F( K( J, U(d) ) ); Q.displayName = "KendoReactCalendar"; R(d); export { Q as Calendar, J as CalendarPropsContext, d as CalendarWithoutContext };