Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions docs-site/src/examples/ts/holidayDates.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,18 @@ type Holiday = {
};

const HolidayDates = () => {
const [selectedDate, setSelectedDate] = useState<Date | null>(new Date());
const today = new Date();
const [selectedDate, setSelectedDate] = useState<Date | null>(today);

const holidays: Holiday[] = [
{ date: "2023-08-15", holidayName: "India's Independence Day" },
{ date: "2023-12-31", holidayName: "New Year's Eve" },
{ date: "2023-12-25", holidayName: "Christmas" },
{ date: "2024-01-01", holidayName: "New Year's Day" },
{ date: "2023-11-23", holidayName: "Thanksgiving Day" },
{
date: `${today.getFullYear()}-03-15`,
holidayName: "India's Independence Day",
},
{ date: `${today.getFullYear()}-12-31`, holidayName: "New Year's Eve" },
{ date: `${today.getFullYear()}-12-25`, holidayName: "Christmas" },
{ date: `${today.getFullYear()}-01-01`, holidayName: "New Year's Day" },
{ date: `${today.getFullYear()}-11-23`, holidayName: "Thanksgiving Day" },
];

return (
Expand Down
97 changes: 46 additions & 51 deletions src/day.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -484,33 +484,27 @@ export default class Day extends Component<DayProps> {
return `${prefix} ${formatDate(day, "PPPP", this.props.locale)}`;
};

getHolidayTitle = () => {
const { day, holidays } = this.props;
const compareDt = formatDate(day, "MM.dd.yyyy");
return holidays?.has(compareDt)
? holidays.get(compareDt)?.holidayNames.join(", ")
: "";
};

// A function to return the holiday's name as title's content
getTitle = () => {
const { day, holidays = new Map(), excludeDates } = this.props;
const compareDt = formatDate(day, "MM.dd.yyyy");
const titles = [];
if (holidays.has(compareDt)) {
titles.push(...holidays.get(compareDt).holidayNames);
}
if (this.isExcluded()) {
titles.push(
excludeDates
?.filter((excludeDate) => {
if (excludeDate instanceof Date) {
return isSameDay(excludeDate, day);
}
return isSameDay(excludeDate?.date, day);
})
.map((excludeDate) => {
if (excludeDate instanceof Date) {
return undefined;
}
return excludeDate?.message;
}),
);
}
// I'm not sure that this is a right output, but all tests are green
return titles.join(", ");
const { day, excludeDates } = this.props;

return this.isExcluded()
? excludeDates
?.flatMap((excludeDate) =>
!(excludeDate instanceof Date) && isSameDay(excludeDate?.date, day)
? excludeDate?.message
: [],
)
.join(", ")
: "";
};

getTabIndex = () => {
Expand Down Expand Up @@ -588,31 +582,32 @@ export default class Day extends Component<DayProps> {
: getDate(this.props.day);
};

render = () => (
render = () => {
const holidayTitle = this.getHolidayTitle();
// TODO: Use <option> instead of the "option" role to ensure accessibility across all devices.
<div
ref={this.dayEl}
className={this.getClassNames(this.props.day)}
onKeyDown={this.handleOnKeyDown}
onClick={this.handleClick}
onMouseEnter={
!this.props.usePointerEvent ? this.handleMouseEnter : undefined
}
onPointerEnter={
this.props.usePointerEvent ? this.handleMouseEnter : undefined
}
tabIndex={this.getTabIndex()}
aria-label={this.getAriaLabel()}
role="gridcell"
title={this.getTitle()}
aria-disabled={this.isDisabled()}
aria-current={this.isCurrentDay() ? "date" : undefined}
aria-selected={this.isSelected() || this.isInRange()}
>
{this.renderDayContents()}
{this.getTitle() !== "" && (
<span className="overlay">{this.getTitle()}</span>
)}
</div>
);
return (
<div
ref={this.dayEl}
className={this.getClassNames(this.props.day)}
onKeyDown={this.handleOnKeyDown}
onClick={this.handleClick}
onMouseEnter={
!this.props.usePointerEvent ? this.handleMouseEnter : undefined
}
onPointerEnter={
this.props.usePointerEvent ? this.handleMouseEnter : undefined
}
tabIndex={this.getTabIndex()}
aria-label={this.getAriaLabel()}
role="gridcell"
title={this.getTitle()}
aria-disabled={this.isDisabled()}
aria-current={this.isCurrentDay() ? "date" : undefined}
aria-selected={this.isSelected() || this.isInRange()}
>
{this.renderDayContents()}
{!!holidayTitle && <span className="overlay">{holidayTitle}</span>}
</div>
);
};
}
2 changes: 1 addition & 1 deletion src/stylesheets/datepicker.scss
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,7 @@ h2.react-datepicker__current-month {

.overlay {
position: absolute;
bottom: 100%;
bottom: calc(100% + 2px);
left: 50%;
transform: translateX(-50%);
background-color: #333;
Expand Down
20 changes: 11 additions & 9 deletions src/test/day_test.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1820,8 +1820,8 @@ describe("Day", () => {
});
});

describe("title", () => {
it("should have the correct title if date is from holiday list", () => {
describe("Holiday Tooltip", () => {
it("should have the correct tooltip text if date is from holiday list", () => {
const day = new Date(2023, 11, 25);
const holidays = new Map([
[
Expand All @@ -1843,10 +1843,12 @@ describe("Day", () => {
const container = renderDay(day, {
holidays: holidays,
});
expect(container.innerHTML.indexOf('title="Christmas"')).not.toBe(-1);

const tooltipText = container.querySelector(".overlay")?.textContent;
expect(tooltipText).toBe("Christmas");
});

it("uses both the holiday names for a given date as the title", () => {
it("uses both the holiday names for a given date as the tooltip text", () => {
const day = new Date(2023, 7, 15);
const holidays = new Map([
[
Expand All @@ -1868,12 +1870,11 @@ describe("Day", () => {
const container = renderDay(day, {
holidays: holidays,
});
expect(
container.innerHTML.indexOf('title="Holiday 1, Holiday 2"'),
).not.toBe(-1);
const tooltipText = container.querySelector(".overlay")?.textContent;
expect(tooltipText).toBe("Holiday 1, Holiday 2");
});

it("should have the title as empty string if date is not from holiday list", () => {
it("should have the tooltip text as empty string if date is not from holiday list", () => {
const day = new Date(2023, 7, 14);
const holidays = new Map([
[
Expand All @@ -1895,7 +1896,8 @@ describe("Day", () => {
const container = renderDay(day, {
holidays: holidays,
});
expect(container.innerHTML.indexOf('title=""')).not.toBe(-1);
const tooltip = container.querySelector(".overlay");
expect(tooltip).toBeNull();
});
});
});
Loading