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