Skip to content

Commit

Permalink
🐛 Address datepicker crashing when manually entering year
Browse files Browse the repository at this point in the history
  • Loading branch information
ibolton336 committed Mar 7, 2024
1 parent 7b860c7 commit e9abf0a
Showing 1 changed file with 34 additions and 13 deletions.
47 changes: 34 additions & 13 deletions packages/react-core/src/components/CalendarMonth/CalendarMonth.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,6 @@ export interface CalendarProps extends CalendarFormat, Omit<React.HTMLProps<HTML
validators?: ((date: Date) => boolean)[];
}

// Must be numeric given current header design
const yearFormat = (date: Date) => date.getFullYear();

const buildCalendar = (year: number, month: number, weekStart: number, validators: ((date: Date) => boolean)[]) => {
const defaultDate = new Date(year, month);

Expand Down Expand Up @@ -164,6 +161,13 @@ export const CalendarMonth = ({
};
const initialDate = getInitialDate();
const [focusedDate, setFocusedDate] = React.useState(initialDate);

// Must be numeric given current header design
const yearFormat = (date: Date) => date.getFullYear();
//
const yearFormatted = yearFormat(focusedDate);
const [yearInput, setYearInput] = React.useState(yearFormatted.toString());

const [hoveredDate, setHoveredDate] = React.useState(new Date(focusedDate));
const focusRef = React.useRef<HTMLButtonElement>();
const [hiddenMonthId] = React.useState(getUniqueId('hidden-month-span'));
Expand Down Expand Up @@ -217,6 +221,31 @@ export const CalendarMonth = ({
const changeMonth = (newMonth: number, newYear?: number) =>
new Date(newYear ?? focusedDate.getFullYear(), newMonth, 1);

const MIN_YEAR = 1900;
const MAX_YEAR = 2100;

const handleYearInputChange = (event: React.FormEvent<HTMLInputElement>) => {
const yearStr = event.currentTarget.value;

if (/^\d{0,4}$/.test(yearStr)) {
setYearInput(yearStr);

if (yearStr.length === 4) {
const yearNum = Number(yearStr);
if (yearNum >= MIN_YEAR && yearNum <= MAX_YEAR) {
const newDate = changeYear(yearNum);
setFocusedDate(newDate);
setHoveredDate(newDate);
setShouldFocus(false);
onMonthChange(event, newDate);
} else {
// If the year is not valid, reset the year input to the current year.
setYearInput(yearFormatted.toString());
}
}
}
};

const addMonth = (toAdd: -1 | 1) => {
let newMonth = focusedDate.getMonth() + toAdd;
let newYear = focusedDate.getFullYear();
Expand Down Expand Up @@ -254,7 +283,6 @@ export const CalendarMonth = ({
}
const isHoveredDateValid = isValidated(hoveredDate);
const monthFormatted = monthFormat(focusedDate);
const yearFormatted = yearFormat(focusedDate);

const calendarToRender = (
<div className={css(styles.calendarMonth, className)} {...props}>
Expand Down Expand Up @@ -321,15 +349,8 @@ export const CalendarMonth = ({
<TextInput
aria-label={yearInputAriaLabel}
type="number"
value={yearFormatted}
onChange={(ev: React.FormEvent<HTMLInputElement>, year: string) => {
const newDate = changeYear(Number(year));
setFocusedDate(newDate);
setHoveredDate(newDate);
setShouldFocus(false);
focusRef.current?.blur(); // will unfocus a date when changing year via up/down arrows
onMonthChange(ev, newDate);
}}
value={yearInput}
onChange={handleYearInputChange}
/>
</div>
</InputGroupItem>
Expand Down

0 comments on commit e9abf0a

Please sign in to comment.