void>;
+ declare years: any[];
+ declare days: any[];
+ declare hours: any[];
+ declare minutes: any[];
+ declare century: number;
+ declare firstYear: 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,
+ };
+ 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");
+
+ // Years: a window spanning the current century, rebuilt when it changes.
+ let currentCentury = (date.getFullYear() / 100) | 0;
+ if (!this.years || this.century !== currentCentury) {
+ this.century = currentCentury;
+ this.firstYear = currentCentury * 100 - 3;
+ let lastYear = (currentCentury + 1) * 100 + 5;
+ this.years = [];
+ for (let y = this.firstYear; y <= lastYear; y++)
+ this.years.push({y});
+ }
+ let years = this.years;
+
+ // Day/hour/minute wheels use a 3x buffer (see buildNumberWheel). The day
+ // buffer depends on the month length, so it is rebuilt when that changes.
+ const numberOfDaysInMonth = new Date(
+ date.getFullYear(),
+ date.getMonth() + 1,
+ 0,
+ ).getDate();
+ if (!this.days || this.numberOfDaysInMonth !== numberOfDaysInMonth) {
+ this.numberOfDaysInMonth = numberOfDaysInMonth;
+ this.days = buildNumberWheel(numberOfDaysInMonth, 1);
+ }
+ let days = this.days;
+
+ if (!this.hours) this.hours = buildNumberWheel(24, 0);
+ let hours = this.hours;
+
+ if (!this.minutes) this.minutes = buildNumberWheel(60, 0);
+ let 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(
+ state.date,
+ "year",
+ newIndex + this.firstYear,
+ ),
+ }),
+ this.handleChange,
+ );
}}
- 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 + 1970),
- }),
- 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 && (
- {
- this.setState(
- (state) => ({
- date: this.setDateComponent(this.state.date, "date", newIndex + 1),
- }),
- this.handleChange,
- );
- }}
- onPipeKeyDown={(kd) => {
- this.keyDownPipes["date"] = kd;
- }}
- onMouseDown={() => {
- this.setState({ activeWheel: "date" });
- }}
- >
- {days}
-
- )}
- {this.wheels.hours && this.wheels.year && }
- {this.wheels.hours && (
- {
- this.setState(
- (state) => ({
- date: this.setDateComponent(this.state.date, "hours", newIndex),
- }),
- this.handleChange,
- );
- }}
- onPipeKeyDown={(kd) => {
- this.keyDownPipes["hours"] = kd;
- }}
- onMouseDown={() => {
- this.setState({ activeWheel: "hours" });
- }}
- >
- {hours}
-
- )}
- {this.wheels.hours && this.wheels.minutes && :}
- {this.wheels.minutes && (
- {
- this.setState(
- (state) => ({
- date: this.setDateComponent(this.state.date, "minutes", newIndex),
- }),
- this.handleChange,
- );
- }}
- onPipeKeyDown={(kd) => {
- this.keyDownPipes["minutes"] = kd;
- }}
- onMouseDown={() => {
- this.setState({ activeWheel: "minutes" });
- }}
- >
- {minutes}
-
- )}
- {this.wheels.minutes && this.wheels.seconds && :}
- {this.wheels.seconds && (
- {
- this.setState(
- (state) => ({
- date: this.setDateComponent(this.state.date, "seconds", newIndex),
- }),
- 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;
- }
- }
-
- this.setState({
- activeWheel: firstWheel,
- });
+ 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(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 && (
+ {
+ let day = rawIndex % this.numberOfDaysInMonth;
+ this.setState(
+ (state) => ({
+ date: this.setDateComponent(state.date, "date", day + 1),
+ }),
+ this.handleChange,
+ );
+ }}
+ onPipeKeyDown={(kd) => {
+ this.keyDownPipes["date"] = kd;
+ }}
+ onMouseDown={() => {
+ this.setState({ activeWheel: "date" });
+ }}
+ >
+ {days}
+
+ )}
+ {this.wheels.hours && this.wheels.year && (
+
+ )}
+ {this.wheels.hours && (
+ {
+ let hour = rawIndex % 24;
+ this.setState(
+ (state) => ({
+ date: this.setDateComponent(state.date, "hours", hour),
+ }),
+ this.handleChange,
+ );
+ }}
+ onPipeKeyDown={(kd) => {
+ this.keyDownPipes["hours"] = kd;
+ }}
+ onMouseDown={() => {
+ this.setState({ activeWheel: "hours" });
+ }}
+ >
+ {hours}
+
+ )}
+ {this.wheels.hours && this.wheels.minutes && :}
+ {this.wheels.minutes && (
+ {
+ let minute = rawIndex % 60;
+ this.setState(
+ (state) => ({
+ date: this.setDateComponent(state.date, "minutes", minute),
+ }),
+ this.handleChange,
+ );
+ }}
+ onPipeKeyDown={(kd) => {
+ this.keyDownPipes["minutes"] = kd;
+ }}
+ onMouseDown={() => {
+ this.setState({ activeWheel: "minutes" });
+ }}
+ >
+ {minutes}
+
+ )}
+ {this.wheels.minutes && this.wheels.seconds && :}
+ {this.wheels.seconds && (
+ {
+ let second = rawIndex % 60;
+ this.setState(
+ (state) => ({
+ date: this.setDateComponent(state.date, "seconds", second),
+ }),
+ this.handleChange,
+ );
+ }}
+ onPipeKeyDown={(kd) => {
+ this.keyDownPipes["seconds"] = kd;
+ }}
+ onMouseDown={() => {
+ this.setState({ activeWheel: "seconds" });
+ }}
+ >
+ {minutes}
+
+ )}
+