Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: enable all years available in the year select dropdown #2614

Merged
merged 5 commits into from
Dec 8, 2024
Merged
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
64 changes: 43 additions & 21 deletions examples/Dropdown.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,43 +23,65 @@ test("should display the year dropdown", () => {
expect(yearDropdown()).toBeInTheDocument();
});

test("should disable the months out of range", () => {
expect(
within(monthDropdown()).getByRole("option", { name: "January" })
).toBeDisabled();
test("should disable the months before startMonth", () => {
const disablesMonth = [
"January",
"February",
"March",
"April",
"May",
"June"
];
for (const month of disablesMonth) {
expect(
within(monthDropdown()).getByRole("option", { name: month })
).toBeDisabled();
}
});

test("should disable the months after endMonth", async () => {
await user.selectOptions(yearDropdown(), "2025");
const disablesMonth = ["November", "December"];
for (const month of disablesMonth) {
expect(
within(monthDropdown()).getByRole("option", { name: month })
).toBeDisabled();
}
});

describe("when choosing a month", () => {
const monthName = "December";
beforeEach(async () => {
test("should display the month", async () => {
const monthName = "December";
await user.selectOptions(monthDropdown(), monthName);
});
test("should display the month", () => {
expect(grid()).toHaveAccessibleName(`${monthName} 2024`);
});
test("should disable the years out of range", () => {
expect(
within(yearDropdown()).getByRole("option", { name: "2025" })
).toBeDisabled();
});
});

describe("when choosing a year", () => {
const year = "2025";
beforeEach(async () => {
test("should display the year", async () => {
const year = "2025";
await user.selectOptions(yearDropdown(), year);
});
test("should display the year", () => {
expect(grid()).toHaveAccessibleName(`July ${year}`);
});

test("should display the first available month when selecting a month before startMonth", async () => {
await user.selectOptions(yearDropdown(), "2025");
await user.selectOptions(monthDropdown(), "January");
await user.selectOptions(yearDropdown(), "2024");
expect(grid()).toHaveAccessibleName(`July 2024`);
});

test("should display the last available month when selecting a month after endMonth", async () => {
await user.selectOptions(monthDropdown(), "December");
await user.selectOptions(yearDropdown(), "2025");
expect(grid()).toHaveAccessibleName(`October 2025`);
});
});

describe("when choosing a disabled month", () => {
const monthName = "February";
beforeEach(async () => {
test("should display the first available month", async () => {
const monthName = "February";
await user.selectOptions(monthDropdown(), monthName);
});
test("should display the first available month", () => {
expect(grid()).toHaveAccessibleName(`July 2024`);
});
});
4 changes: 2 additions & 2 deletions examples/DropdownMultipleMonths.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ describe("when choosing a month from the first dropdown", () => {
await user.selectOptions(firstDropDown, monthName);
});
test("should display the month in the first dropdown", () => {
expect(grid(`${monthName} 2023`)).toBeInTheDocument();
expect(grid(`${monthName} 2024`)).toBeInTheDocument();
});
});

Expand All @@ -39,6 +39,6 @@ describe("when choosing a month from the third dropdown", () => {
await user.selectOptions(thirdDropDown, newMonthName);
});
test("should display the month selected the third dropdown", () => {
expect(grid(`${newMonthName} 2023`)).toBeInTheDocument();
expect(grid(`${newMonthName} 2024`)).toBeInTheDocument();
});
});
5 changes: 3 additions & 2 deletions examples/DropdownMultipleMonths.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ export function DropdownMultipleMonths() {
return (
<DayPicker
numberOfMonths={5}
defaultMonth={new Date(2024, 6)}
captionLayout="dropdown"
fromYear={2015}
toYear={2025}
startMonth={new Date(2023, 6)}
endMonth={new Date(2025, 9)}
/>
);
}
1 change: 0 additions & 1 deletion src/DayPicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,6 @@ export function DayPicker(props: DayPickerProps) {
);

const dropdownYears = getYearOptions(
months[0].date,
navStart,
navEnd,
formatters,
Expand Down
5 changes: 0 additions & 5 deletions src/helpers/getYearOptions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,16 @@ import { getFormatters } from "./getFormatters";
import { getYearOptions } from "./getYearOptions";

test("return undefined if startMonth or endMonth is not provided", () => {
const displayMonth = new Date(2022, 0, 1); // January 2022
const formatters = getFormatters({
formatYearDropdown: (year: number) => `${year}`
});
const result1 = getYearOptions(
displayMonth,
undefined,
new Date(2022, 11, 31),
formatters,
defaultDateLib
);
const result2 = getYearOptions(
displayMonth,
new Date(2022, 0, 1),
undefined,
formatters,
Expand All @@ -28,15 +25,13 @@ test("return undefined if startMonth or endMonth is not provided", () => {
});

test("return correct dropdown options", () => {
const displayMonth = new Date(2022, 0, 1); // January 2022
const startMonth = new Date(2022, 0, 1); // January 2022
const endMonth = new Date(2024, 11, 31); // December 2024
const formatters = getFormatters({
formatYearDropdown: (year: number) => `${year}`
});

const result = getYearOptions(
displayMonth,
startMonth,
endMonth,
formatters,
Expand Down
32 changes: 8 additions & 24 deletions src/helpers/getYearOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,16 @@ import type { Formatters } from "../types/index.js";

/** Return the years to show in the dropdown. */
export function getYearOptions(
displayMonth: Date,
calendarStart: Date | undefined,
calendarEnd: Date | undefined,
navStart: Date | undefined,
navEnd: Date | undefined,
formatters: Pick<Formatters, "formatYearDropdown">,
dateLib: DateLib
): DropdownOption[] | undefined {
if (!calendarStart) return undefined;
if (!calendarEnd) return undefined;
const {
startOfMonth,
startOfYear,
endOfYear,
addYears,
isBefore,
isSameYear
} = dateLib;
const month = displayMonth.getMonth();
const firstNavYear = startOfYear(calendarStart);
const lastNavYear = endOfYear(calendarEnd);
if (!navStart) return undefined;
if (!navEnd) return undefined;
const { startOfYear, endOfYear, addYears, isBefore, isSameYear } = dateLib;
const firstNavYear = startOfYear(navStart);
const lastNavYear = endOfYear(navEnd);
const years: number[] = [];

let year = firstNavYear;
Expand All @@ -32,18 +23,11 @@ export function getYearOptions(
}

return years.map((value) => {
const year = dateLib.Date
? new dateLib.Date(value, month)
: new Date(value, month);
const disabled =
(calendarStart && year < startOfMonth(calendarStart)) ||
(month && calendarEnd && year > startOfMonth(calendarEnd)) ||
false;
const label = formatters.formatYearDropdown(value);
return {
value,
label,
disabled
disabled: false
};
});
}
3 changes: 2 additions & 1 deletion src/types/props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,8 @@ export interface PropsBase {
* - `year`: display only the dropdown for the years
*
* **Note:** showing the dropdown will set the start/end months
* {@link fromYear} to 100 years ago, and {@link toYear} to the current year.
* {@link startMonth} to 100 years ago, and {@link endMonth} to the end of the
* current year.
*
* @see https://daypicker.dev/docs/customization#caption-layouts
*/
Expand Down
Loading