void>;
+ declare years: any[];
+ declare days: any[];
+ declare hours: any[];
+ declare minutes: any[];
+ declare century: number;
+ declare numberOfDaysInMonth: number;
+
+ constructor(props: DateTimePickerComponentProps) {
+ super(props);
+ let date = props.data.value
+ ? parseDateInvariant(props.data.value as string | number | Date)
+ : new Date();
+ if (isNaN(date.getTime())) date = new Date();
+ this.state = {
+ date: date,
+ activeWheel: null,
+ daysResetKey: 0,
+ hoursResetKey: 0,
+ minutesResetKey: 0,
+ secondsResetKey: 0,
+ };
+ this.century = (date.getFullYear() / 100) | 0;
+
+ let { widget } = props.instance;
+ let pickerWidget = widget as DateTimePicker;
+
+ this.handleChange = this.handleChange.bind(this);
+ this.onFocus = this.onFocus.bind(this);
+ this.onBlur = this.onBlur.bind(this);
+ this.onKeyDown = this.onKeyDown.bind(this);
+
+ let showDate = props.segment.indexOf("date") !== -1;
+ let showTime = props.segment.indexOf("time") !== -1;
+
+ this.wheels = {
+ year: showDate,
+ month: showDate,
+ date: showDate,
+ hours: showTime,
+ minutes: showTime,
+ seconds: showTime && !!pickerWidget.showSeconds,
+ };
+
+ this.keyDownPipes = {};
+ }
+
+ UNSAFE_componentWillReceiveProps(props: DateTimePickerComponentProps): void {
+ let date = props.data.value
+ ? parseDateInvariant(props.data.value as string | number | Date)
+ : new Date();
+ if (isNaN(date.getTime())) date = new Date();
+ this.setState({ date });
+ }
+
+ setDateComponent(date: Date, component: string, value: number): Date {
+ let v = new Date(date);
+ switch (component) {
+ case "year":
+ v.setFullYear(value);
+ break;
+
+ case "month":
+ v.setMonth(value);
+ break;
+
+ case "date":
+ v.setDate(value);
+ break;
+
+ case "hours":
+ v.setHours(value);
+ break;
+
+ case "minutes":
+ v.setMinutes(value);
+ break;
+
+ case "seconds":
+ v.setSeconds(value);
+ break;
+ }
+ return v;
+ }
+
+ handleChange(): void {
+ let { widget } = this.props.instance;
+ let pickerWidget = widget as DateTimePicker;
+ let encode = pickerWidget.encoding || Culture.getDefaultDateEncoding();
+ this.props.instance.set("value", encode!(this.state.date));
+ }
+
+ render(): React.ReactNode {
+ let { instance, data, size } = this.props;
+ let { widget } = instance;
+ let { CSS, baseClass } = widget;
+ let pickerWidget = widget as DateTimePicker;
+ let date = this.state.date;
+
+ let culture = Culture.getDateTimeCulture();
+ let monthNames = culture.getMonthNames("short");
+
+ let years = [];
+ if (!this.years || this.century !== ((date.getFullYear() / 100) | 0)) {
+ this.century = (date.getFullYear() / 100) | 0;
+
+ for (
+ let y = this.century * 100 - 3;
+ y <= (this.century + 1) * 100 + 5;
+ y++
+ )
+ years.push({y});
+ this.years = years;
+ } else {
+ years = this.years;
+ }
+
+ let days = [];
+ const daysInThisMonth = new Date(
+ date.getFullYear(),
+ date.getMonth() + 1,
+ 0,
+ ).getDate();
+ this.numberOfDaysInMonth ??= daysInThisMonth;
+
+ if (!this.days || this.numberOfDaysInMonth !== daysInThisMonth) {
+ days = Array.from({ length: 5 }, (_, d) => (
+
+ {daysInThisMonth - 4 + d < 10
+ ? "0" + (daysInThisMonth - 4 + d)
+ : daysInThisMonth - 4 + d}
+
+ ));
+ days.push(
+ ...Array.from({ length: 36 }, (_, d) => (
+
+ {(d % daysInThisMonth) + 1 < 10
+ ? "0" + ((d % daysInThisMonth) + 1)
+ : (d % daysInThisMonth) + 1}
+
+ )),
);
- }
-
- componentDidMount(): void {
- let { widget } = this.props.instance;
- let pickerWidget = widget as DateTimePicker;
- if (pickerWidget.autoFocus) this.el.focus();
- }
-
- componentWillUnmount(): void {
- offFocusOut(this);
- }
-
- onFocus(): void {
- oneFocusOut(this, this.el, this.onFocusOut.bind(this));
-
- if (!this.state.activeWheel) {
- let firstWheel: string | null = null;
- for (let wheel in this.wheels) {
- if (this.wheels[wheel]) {
- firstWheel = wheel;
- break;
- }
- }
- this.setState({
- activeWheel: firstWheel,
- });
+ this.days = days;
+ this.numberOfDaysInMonth = daysInThisMonth;
+ } else {
+ days = this.days;
+ }
+
+ let hours = [];
+ if (!this.hours) {
+ hours = Array.from({ length: 52 }, (_, h) => (
+ {h % 24 < 10 ? "0" + (h % 24) : h % 24}
+ ));
+ this.hours = hours;
+ } else {
+ hours = this.hours;
+ }
+
+ let minutes = [];
+ if (!this.minutes) {
+ minutes = Array.from({ length: 130 }, (_, h) => (
+ {h % 60 < 10 ? "0" + (h % 60) : h % 60}
+ ));
+ this.minutes = minutes;
+ } else {
+ minutes = this.minutes;
+ }
+
+ return (
+ {
+ this.el = el!;
+ }}
+ className={data.classNames as string}
+ onFocus={this.onFocus}
+ onBlur={this.onBlur}
+ onKeyDown={this.onKeyDown}
+ >
+ {this.wheels.year && (
+ {
+ this.setState(
+ (state) => ({
+ date: this.setDateComponent(
+ this.state.date,
+ "year",
+ newIndex + Number(this.years[0].key),
+ ),
+ }),
+ this.handleChange,
+ );
+ }}
+ onPipeKeyDown={(kd) => {
+ this.keyDownPipes["year"] = kd;
+ }}
+ onMouseDown={() => {
+ this.setState({ activeWheel: "year" });
+ }}
+ >
+ {years}
+
+ )}
+ {this.wheels.year && this.wheels.month && -}
+ {this.wheels.month && (
+ {
+ this.setState(
+ (state) => ({
+ date: this.setDateComponent(
+ this.state.date,
+ "month",
+ newIndex,
+ ),
+ }),
+ this.handleChange,
+ );
+ }}
+ onPipeKeyDown={(kd) => {
+ this.keyDownPipes["month"] = kd;
+ }}
+ onMouseDown={() => {
+ this.setState({ activeWheel: "month" });
+ }}
+ >
+ {monthNames.map((m: string, i: number) => (
+ {m}
+ ))}
+
+ )}
+ {this.wheels.month && this.wheels.date && -}
+ {this.wheels.date && (
+ {
+ newDate -= 5;
+ if (newDate < 0) {
+ newDate += this.numberOfDaysInMonth;
+ } else {
+ newDate = newDate % this.numberOfDaysInMonth;
+ }
+
+ this.setState(
+ (state) => ({
+ date: this.setDateComponent(state.date, "date", newDate + 1),
+ daysResetKey:
+ ((state.date.getDate() - 1) ^ newDate) ===
+ this.numberOfDaysInMonth - 1
+ ? state.daysResetKey + 1
+ : state.daysResetKey,
+ }),
+ this.handleChange,
+ );
+ }}
+ onPipeKeyDown={(kd) => {
+ this.keyDownPipes["date"] = kd;
+ }}
+ onMouseDown={() => {
+ this.setState({ activeWheel: "date" });
+ }}
+ >
+ {days}
+
+ )}
+ {this.wheels.hours && this.wheels.year && (
+
+ )}
+ {this.wheels.hours && (
+ {
+ const newHour = newIndex % 24;
+
+ this.setState(
+ (s) => ({
+ date: this.setDateComponent(s.date, "hours", newHour),
+ hoursResetKey:
+ (s.date.getHours() ^ newHour) == 23
+ ? s.hoursResetKey + 1
+ : s.hoursResetKey,
+ }),
+ this.handleChange,
+ );
+ }}
+ onPipeKeyDown={(kd) => {
+ this.keyDownPipes["hours"] = kd;
+ }}
+ onMouseDown={() => {
+ this.setState({ activeWheel: "hours" });
+ }}
+ >
+ {hours}
+
+ )}
+ {this.wheels.hours && this.wheels.minutes && :}
+ {this.wheels.minutes && (
+ {
+ const newMinutes = newIndex % 60;
+ this.setState(
+ (state) => ({
+ date: this.setDateComponent(
+ state.date,
+ "minutes",
+ newMinutes,
+ ),
+ minutesResetKey:
+ (state.date.getMinutes() ^ newMinutes) == 59
+ ? state.minutesResetKey + 1
+ : state.minutesResetKey,
+ }),
+ this.handleChange,
+ );
+ }}
+ onPipeKeyDown={(kd) => {
+ this.keyDownPipes["minutes"] = kd;
+ }}
+ onMouseDown={() => {
+ this.setState({ activeWheel: "minutes" });
+ }}
+ >
+ {minutes}
+
+ )}
+ {this.wheels.minutes && this.wheels.seconds && :}
+ {this.wheels.seconds && (
+ {
+ const newSeconds = newIndex % 60;
+ this.setState(
+ (state) => ({
+ date: this.setDateComponent(
+ state.date,
+ "seconds",
+ newSeconds,
+ ),
+ secondsResetKey:
+ (state.date.getSeconds() ^ newSeconds) == 59
+ ? state.secondsResetKey + 1
+ : state.secondsResetKey,
+ }),
+ this.handleChange,
+ );
+ }}
+ onPipeKeyDown={(kd) => {
+ this.keyDownPipes["seconds"] = kd;
+ }}
+ onMouseDown={() => {
+ this.setState({ activeWheel: "seconds" });
+ }}
+ >
+ {minutes}
+
+ )}
+
+ );
+ }
+
+ componentDidMount(): void {
+ let { widget } = this.props.instance;
+ let pickerWidget = widget as DateTimePicker;
+ if (pickerWidget.autoFocus) this.el.focus();
+ }
+
+ componentWillUnmount(): void {
+ offFocusOut(this);
+ }
+
+ onFocus(): void {
+ oneFocusOut(this, this.el, this.onFocusOut.bind(this));
+
+ if (!this.state.activeWheel) {
+ let firstWheel: string | null = null;
+ for (let wheel in this.wheels) {
+ if (this.wheels[wheel]) {
+ firstWheel = wheel;
+ break;
+ }
}
- }
- onFocusOut(): void {
- let { instance } = this.props;
- let { widget } = instance;
- let pickerWidget = widget as DateTimePicker;
- if (pickerWidget.onFocusOut) instance.invoke("onFocusOut", null, instance);
- }
-
- onBlur(): void {
this.setState({
- activeWheel: null,
+ activeWheel: firstWheel,
});
- }
-
- onKeyDown(e: React.KeyboardEvent): void {
- let tmp: string | null = null;
- let { instance } = this.props;
- let { widget } = instance;
- let pickerWidget = widget as DateTimePicker;
-
- switch (e.keyCode) {
- case KeyCode.right:
- e.preventDefault();
- for (let wheel in this.wheels) {
- if (this.wheels[wheel]) {
- if (tmp === this.state.activeWheel) {
- this.setState({ activeWheel: wheel });
- break;
- }
- tmp = wheel;
- }
+ }
+ }
+
+ onFocusOut(): void {
+ let { instance } = this.props;
+ let { widget } = instance;
+ let pickerWidget = widget as DateTimePicker;
+ if (pickerWidget.onFocusOut) instance.invoke("onFocusOut", null, instance);
+ }
+
+ onBlur(): void {
+ this.setState({
+ activeWheel: null,
+ });
+ }
+
+ onKeyDown(e: React.KeyboardEvent): void {
+ let tmp: string | null = null;
+ let { instance } = this.props;
+ let { widget } = instance;
+ let pickerWidget = widget as DateTimePicker;
+
+ switch (e.keyCode) {
+ case KeyCode.right:
+ e.preventDefault();
+ for (let wheel in this.wheels) {
+ if (this.wheels[wheel]) {
+ if (tmp === this.state.activeWheel) {
+ this.setState({ activeWheel: wheel });
+ break;
}
- break;
-
- case KeyCode.left:
- e.preventDefault();
- for (let wheel in this.wheels) {
- if (this.wheels[wheel]) {
- if (wheel === this.state.activeWheel && tmp) {
- this.setState({ activeWheel: tmp });
- break;
- }
- tmp = wheel;
- }
+ tmp = wheel;
+ }
+ }
+ break;
+
+ case KeyCode.left:
+ e.preventDefault();
+ for (let wheel in this.wheels) {
+ if (this.wheels[wheel]) {
+ if (wheel === this.state.activeWheel && tmp) {
+ this.setState({ activeWheel: tmp });
+ break;
}
- break;
-
- case KeyCode.enter:
- e.preventDefault();
- if (pickerWidget.onSelect) instance.invoke("onSelect", e, instance, this.state.date);
- break;
-
- default: let kdp = this.keyDownPipes[this.state.activeWheel!];
- if (kdp) kdp(e);
- break;
- }
- }
+ tmp = wheel;
+ }
+ }
+ break;
+
+ case KeyCode.enter:
+ e.preventDefault();
+ if (pickerWidget.onSelect)
+ instance.invoke("onSelect", e, instance, this.state.date);
+ break;
+
+ default:
+ let kdp = this.keyDownPipes[this.state.activeWheel!];
+ if (kdp) kdp(e);
+ break;
+ }
+ }
}