Skip to content

Commit

Permalink
fix: timepicker on 23 and 25-hour days
Browse files Browse the repository at this point in the history
  • Loading branch information
lemming committed Sep 10, 2023
1 parent 21bfd83 commit 2dda767
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 39 deletions.
27 changes: 27 additions & 0 deletions src/date_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -818,3 +818,30 @@ export function getYearsPeriod(
const startPeriod = endPeriod - (yearItemNumber - 1);
return { startPeriod, endPeriod };
}

export function getHoursInDay(d) {
const startOfDay = new Date(d.getFullYear(), d.getMonth(), d.getDate());
const startOfTheNextDay = new Date(
d.getFullYear(),
d.getMonth(),
d.getDate(),
24
);

return Math.round((+startOfTheNextDay - +startOfDay) / 3_600_000);
}

export function isSameMinute(d1, d2) {
const _date1 = toDate(d1);
const _date2 = toDate(d2);

const seconds1 = _date1.getSeconds();
const seconds2 = _date2.getSeconds();
const milliseconds1 = _date1.getMilliseconds();
const milliseconds2 = _date2.getMilliseconds();

return (
_date1.getTime() - seconds1 * 1000 - milliseconds1 ===
_date2.getTime() - seconds2 * 1000 - milliseconds2
);
}
10 changes: 6 additions & 4 deletions src/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -686,10 +686,12 @@ export default class DatePicker extends React.Component {
const selected = this.props.selected
? this.props.selected
: this.getPreSelection();
let changedDate = setTime(selected, {
hour: getHours(time),
minute: getMinutes(time),
});
let changedDate = this.props.selected
? time
: setTime(selected, {
hour: getHours(time),
minute: getMinutes(time),
});

this.setState({
preSelection: changedDate,
Expand Down
60 changes: 25 additions & 35 deletions src/time.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,15 @@ import PropTypes from "prop-types";
import {
getHours,
getMinutes,
setHours,
setMinutes,
newDate,
getStartOfDay,
addMinutes,
formatDate,
isBefore,
isEqual,
isTimeInDisabledRange,
isTimeDisabled,
timesToInjectAfter,
getHoursInDay,
isSameMinute,
} from "./date_utils";

export default class Time extends React.Component {
Expand Down Expand Up @@ -91,20 +89,23 @@ export default class Time extends React.Component {
this.props.onChange(time);
};

isSelectedTime = (time, currH, currM) =>
this.props.selected &&
currH === getHours(time) &&
currM === getMinutes(time);
isSelectedTime = (time) => {
const result =
this.props.selected && isSameMinute(this.props.selected, time);

liClasses = (time, currH, currM) => {
if (result) {
console.log(this.props.selected, time);
}
return result;
};

liClasses = (time) => {
let classes = [
"react-datepicker__time-list-item",
this.props.timeClassName
? this.props.timeClassName(time, currH, currM)
: undefined,
this.props.timeClassName ? this.props.timeClassName(time) : undefined,
];

if (this.isSelectedTime(time, currH, currM)) {
if (this.isSelectedTime(time)) {
classes.push("react-datepicker__time-list-item--selected");
}

Expand Down Expand Up @@ -160,19 +161,18 @@ export default class Time extends React.Component {
const format = this.props.format ? this.props.format : "p";
const intervals = this.props.intervals;

const base = getStartOfDay(newDate(this.props.selected));
const multiplier = 1440 / intervals;
const activeDate =
this.props.selected || this.props.openToDate || newDate();

const base = getStartOfDay(activeDate);
const sortedInjectTimes =
this.props.injectTimes &&
this.props.injectTimes.sort(function (a, b) {
return a - b;
});

const activeDate =
this.props.selected || this.props.openToDate || newDate();
const currH = getHours(activeDate);
const currM = getMinutes(activeDate);
const activeTime = setHours(setMinutes(base, currM), currH);
const minutesInDay = 60 * getHoursInDay(activeDate);
const multiplier = minutesInDay / intervals;

for (let i = 0; i < multiplier; i++) {
const currentTime = addMinutes(base, i * intervals);
Expand All @@ -190,34 +190,24 @@ export default class Time extends React.Component {
}
}

// Determine which time to focus and scroll into view when component mounts
const timeToFocus = times.reduce((prev, time) => {
if (isBefore(time, activeTime) || isEqual(time, activeTime)) {
return time;
} else {
return prev;
}
}, times[0]);

return times.map((time, i) => {
const isActiveTime = isSameMinute(time, activeDate);
return (
<li
key={i}
onClick={this.handleClick.bind(this, time)}
className={this.liClasses(time, currH, currM)}
className={this.liClasses(time)}
ref={(li) => {
if (time === timeToFocus) {
if (isActiveTime) {
this.centerLi = li;
}
}}
onKeyDown={(ev) => {
this.handleOnKeyDown(ev, time);
}}
tabIndex={time === timeToFocus ? "0" : "-1"}
tabIndex={isActiveTime ? 0 : -1}
role="option"
aria-selected={
this.isSelectedTime(time, currH, currM) ? "true" : undefined
}
aria-selected={this.isSelectedTime(time) ? "true" : undefined}
>
{formatDate(time, format, this.props.locale)}
</li>
Expand Down

0 comments on commit 2dda767

Please sign in to comment.