Skip to content

Commit 45d7780

Browse files
Add date validity checks to Calendar and Month components
Introduces isValid checks in Calendar and Month components to prevent rendering and formatting with invalid dates. This improves robustness and accessibility by ensuring UI elements and aria-labels are only generated for valid dates.
1 parent 51980d9 commit 45d7780

File tree

2 files changed

+33
-3
lines changed

2 files changed

+33
-3
lines changed

src/calendar.tsx

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,7 @@ export default class Calendar extends Component<CalendarProps, CalendarState> {
266266
componentDidUpdate(prevProps: CalendarProps) {
267267
if (
268268
this.props.preSelection &&
269+
isValid(this.props.preSelection) &&
269270
(!isSameDay(this.props.preSelection, prevProps.preSelection) ||
270271
this.props.monthSelectedIn !== prevProps.monthSelectedIn)
271272
) {
@@ -468,6 +469,11 @@ export default class Calendar extends Component<CalendarProps, CalendarState> {
468469
};
469470

470471
header = (date: Date = this.state.date): React.ReactElement[] => {
472+
// Return empty array if date is invalid
473+
if (!isValid(date)) {
474+
return [];
475+
}
476+
471477
const disabled = this.props.disabled;
472478
const startOfWeek = getStartOfWeek(
473479
date,
@@ -781,7 +787,9 @@ export default class Calendar extends Component<CalendarProps, CalendarState> {
781787
}
782788
return (
783789
<h2 className={classes.join(" ")}>
784-
{formatDate(date, this.props.dateFormat, this.props.locale)}
790+
{isValid(date)
791+
? formatDate(date, this.props.dateFormat, this.props.locale)
792+
: ""}
785793
</h2>
786794
);
787795
};
@@ -1112,6 +1120,17 @@ export default class Calendar extends Component<CalendarProps, CalendarState> {
11121120
};
11131121

11141122
renderAriaLiveRegion = (): React.ReactElement => {
1123+
// Don't render aria-live message if date is invalid
1124+
if (!isValid(this.state.date)) {
1125+
return (
1126+
<span
1127+
role="alert"
1128+
aria-live="polite"
1129+
className="react-datepicker__aria-live"
1130+
/>
1131+
);
1132+
}
1133+
11151134
const { startPeriod, endPeriod } = getYearsPeriod(
11161135
this.state.date,
11171136
this.props.yearItemNumber ?? Calendar.defaultProps.yearItemNumber,

src/month.tsx

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import {
2727
isSameMonth,
2828
isSameQuarter,
2929
isSpaceKeyDown,
30+
isValid,
3031
newDate,
3132
setMonth,
3233
setQuarter,
@@ -447,6 +448,11 @@ export default class Month extends Component<MonthProps> {
447448
};
448449

449450
renderWeeks = () => {
451+
// Return empty array if day is invalid
452+
if (!isValid(this.props.day)) {
453+
return [];
454+
}
455+
450456
const weeks = [];
451457
const isFixedHeight = this.props.fixedHeight;
452458

@@ -1138,6 +1144,11 @@ export default class Month extends Component<MonthProps> {
11381144
? ariaLabelPrefix.trim() + " "
11391145
: "";
11401146

1147+
// Format aria-label, return empty string if date is invalid
1148+
const formattedAriaLabel = isValid(day)
1149+
? `${formattedAriaLabelPrefix}${formatDate(day, "MMMM, yyyy", this.props.locale)}`
1150+
: "";
1151+
11411152
const shouldUseListboxRole = showMonthYearPicker || showQuarterYearPicker;
11421153

11431154
if (shouldUseListboxRole) {
@@ -1150,7 +1161,7 @@ export default class Month extends Component<MonthProps> {
11501161
onPointerLeave={
11511162
this.props.usePointerEvent ? this.handleMouseLeave : undefined
11521163
}
1153-
aria-label={`${formattedAriaLabelPrefix}${formatDate(day, "MMMM, yyyy", this.props.locale)}`}
1164+
aria-label={formattedAriaLabel}
11541165
role="listbox"
11551166
>
11561167
{showMonthYearPicker ? this.renderMonths() : this.renderQuarters()}
@@ -1172,7 +1183,7 @@ export default class Month extends Component<MonthProps> {
11721183
onPointerLeave={
11731184
this.props.usePointerEvent ? this.handleMouseLeave : undefined
11741185
}
1175-
aria-label={`${formattedAriaLabelPrefix}${formatDate(day, "MMMM, yyyy", this.props.locale)}`}
1186+
aria-label={formattedAriaLabel}
11761187
role="rowgroup"
11771188
>
11781189
{this.renderWeeks()}

0 commit comments

Comments
 (0)