diff --git a/src/DayPicker.tsx b/src/DayPicker.tsx
index 6d8cdde7a..aaface07e 100644
--- a/src/DayPicker.tsx
+++ b/src/DayPicker.tsx
@@ -350,10 +350,7 @@ export function DayPicker(props: DayPickerProps) {
/>
) : (
- {formatMonthDropdown(
- calendarMonth.date.getMonth(),
- locale
- )}
+ {formatMonthDropdown(calendarMonth.date, dateLib)}
)}
{captionLayout === "dropdown" ||
@@ -371,7 +368,7 @@ export function DayPicker(props: DayPickerProps) {
/>
) : (
- {formatYearDropdown(calendarMonth.date.getFullYear())}
+ {formatYearDropdown(calendarMonth.date, dateLib)}
)}
diff --git a/src/formatters/formatMonthDropdown.test.ts b/src/formatters/formatMonthDropdown.test.ts
index b2613cde7..2c79e19e1 100644
--- a/src/formatters/formatMonthDropdown.test.ts
+++ b/src/formatters/formatMonthDropdown.test.ts
@@ -1,19 +1,19 @@
import { es } from "date-fns/locale/es";
-import { defaultLocale } from "../classes/DateLib";
+import { DateLib } from "../classes/DateLib";
import { formatMonthDropdown } from "./formatMonthDropdown";
const date = new Date(2022, 10, 21);
test("should return the formatted month dropdown label", () => {
- expect(formatMonthDropdown(date.getMonth(), defaultLocale)).toEqual(
- "November"
- );
+ expect(formatMonthDropdown(date)).toEqual("November");
});
describe("when a locale is passed in", () => {
test("should format using the locale", () => {
- expect(formatMonthDropdown(date.getMonth(), es)).toEqual("noviembre");
+ expect(formatMonthDropdown(date, new DateLib({ locale: es }))).toEqual(
+ "noviembre"
+ );
});
});
diff --git a/src/formatters/formatMonthDropdown.ts b/src/formatters/formatMonthDropdown.ts
index 05f72add6..cb3b2df40 100644
--- a/src/formatters/formatMonthDropdown.ts
+++ b/src/formatters/formatMonthDropdown.ts
@@ -1,4 +1,4 @@
-import type { DateFnsMonth, Locale } from "../classes/DateLib.js";
+import { defaultDateLib, type DateLib } from "../classes/DateLib.js";
/**
* Format the month number for the dropdown option label.
@@ -8,10 +8,8 @@ import type { DateFnsMonth, Locale } from "../classes/DateLib.js";
* @see https://daypicker.dev/docs/translation#custom-formatters
*/
export function formatMonthDropdown(
- /** The month number to format. */
- monthNumber: number,
- /** The locale to use for formatting. */
- locale: Locale
+ month: Date,
+ dateLib: DateLib = defaultDateLib
): string {
- return locale.localize?.month(monthNumber as DateFnsMonth);
+ return dateLib.format(month, "LLLL");
}
diff --git a/src/formatters/formatYearDropdown.test.ts b/src/formatters/formatYearDropdown.test.ts
index a4cb1765a..8b47fabe2 100644
--- a/src/formatters/formatYearDropdown.test.ts
+++ b/src/formatters/formatYearDropdown.test.ts
@@ -1,5 +1,7 @@
+import { defaultDateLib } from "../classes";
+
import { formatYearDropdown } from "./formatYearDropdown";
test("should return the formatted weekday name", () => {
- expect(formatYearDropdown(2022)).toEqual("2022");
+ expect(formatYearDropdown(new Date(2022, 0), defaultDateLib)).toEqual("2022");
});
diff --git a/src/formatters/formatYearDropdown.ts b/src/formatters/formatYearDropdown.ts
index 07020c27e..879497cb3 100644
--- a/src/formatters/formatYearDropdown.ts
+++ b/src/formatters/formatYearDropdown.ts
@@ -1,12 +1,16 @@
+import { defaultDateLib, type DateLib } from "../classes/DateLib.js";
+
/**
* Format the years for the dropdown option label.
*
- * @defaultValue `year.toString()`
* @group Formatters
* @see https://daypicker.dev/docs/translation#custom-formatters
*/
-export function formatYearDropdown(year: number): string {
- return year.toString();
+export function formatYearDropdown(
+ year: Date,
+ dateLib: DateLib = defaultDateLib
+): string {
+ return dateLib.format(year, "yyyy");
}
/**
diff --git a/src/helpers/getFormatters.test.ts b/src/helpers/getFormatters.test.ts
index 373771aff..4672e2ee5 100644
--- a/src/helpers/getFormatters.test.ts
+++ b/src/helpers/getFormatters.test.ts
@@ -1,4 +1,3 @@
-import { defaultDateLib } from "../classes/DateLib";
import * as defaultFormatters from "../formatters";
import { getFormatters } from "./getFormatters";
@@ -20,12 +19,8 @@ test("merges custom formatters with default formatters", () => {
test("assigns `formatMonthCaption` to `formatCaption` if `formatCaption` is not defined", () => {
const result = getFormatters({ formatMonthCaption: () => "customMonth" });
- expect(result.formatCaption(new Date(), {}, defaultDateLib)).toBe(
- "customMonth"
- );
- expect(result.formatMonthCaption(new Date(), {}, defaultDateLib)).toBe(
- "customMonth"
- );
+ expect(result.formatCaption(new Date(), {})).toBe("customMonth");
+ expect(result.formatMonthCaption(new Date(), {})).toBe("customMonth");
});
test("does not overwrite `formatCaption` if already defined", () => {
@@ -33,22 +28,14 @@ test("does not overwrite `formatCaption` if already defined", () => {
formatMonthCaption: () => "customMonth",
formatCaption: () => "customCaption"
});
- expect(result.formatCaption(new Date(), {}, defaultDateLib)).toBe(
- "customCaption"
- );
- expect(result.formatMonthCaption(new Date(), {}, defaultDateLib)).toBe(
- "customMonth"
- );
+ expect(result.formatCaption(new Date(), {})).toBe("customCaption");
+ expect(result.formatMonthCaption(new Date(), {})).toBe("customMonth");
});
test("assigns `formatYearCaption` to `formatYearDropdown` if `formatYearDropdown` is not defined", () => {
const result = getFormatters({ formatYearCaption: () => "customYear" });
- expect(result.formatYearDropdown(new Date(0).getFullYear())).toBe(
- "customYear"
- );
- expect(result.formatYearCaption(new Date(0).getFullYear())).toBe(
- "customYear"
- );
+ expect(result.formatYearDropdown(new Date(2000, 0))).toBe("customYear");
+ expect(result.formatYearCaption(new Date(2000, 0))).toBe("customYear");
});
test("does not overwrite `formatYearDropdown` if already defined", () => {
@@ -56,8 +43,6 @@ test("does not overwrite `formatYearDropdown` if already defined", () => {
formatYearCaption: () => "customYear",
formatYearDropdown: () => "customDropdown"
});
- expect(result.formatYearDropdown(new Date().getFullYear())).toBe(
- "customDropdown"
- );
- expect(result.formatYearCaption(new Date().getFullYear())).toBe("customYear");
+ expect(result.formatYearDropdown(new Date())).toBe("customDropdown");
+ expect(result.formatYearCaption(new Date())).toBe("customYear");
});
diff --git a/src/helpers/getMonthOptions.ts b/src/helpers/getMonthOptions.ts
index 372f151f6..80ee7ba9d 100644
--- a/src/helpers/getMonthOptions.ts
+++ b/src/helpers/getMonthOptions.ts
@@ -1,4 +1,4 @@
-import { defaultLocale, type DateLib } from "../classes/DateLib.js";
+import { type DateLib } from "../classes/DateLib.js";
import { DropdownOption } from "../components/Dropdown.js";
import type { Formatters } from "../types/index.js";
@@ -12,25 +12,23 @@ export function getMonthOptions(
): DropdownOption[] | undefined {
if (!navStart) return undefined;
if (!navEnd) return undefined;
+ // const year = dateLib.getYear(displayMonth);
+ const {
+ startOfMonth,
+ startOfYear,
+ endOfYear,
+ eachMonthOfInterval,
+ getMonth
+ } = dateLib;
- const { addMonths, startOfMonth } = dateLib;
- const year = displayMonth.getFullYear();
-
- const months: number[] = [];
- let month = navStart;
- while (months.length < 12) {
- months.push(month.getMonth());
- month = addMonths(month, 1);
- }
- const sortedMonths = months.sort((a, b) => {
- return a - b;
+ const months = eachMonthOfInterval({
+ start: startOfYear(displayMonth),
+ end: endOfYear(displayMonth)
});
- const options = sortedMonths.map((value) => {
- const label = formatters.formatMonthDropdown(
- value,
- dateLib.options.locale ?? defaultLocale
- );
- const month = new dateLib.Date(year, value);
+
+ const options = months.map((month) => {
+ const label = formatters.formatMonthDropdown(month, dateLib);
+ const value = getMonth(month);
const disabled =
(navStart && month < startOfMonth(navStart)) ||
(navEnd && month > startOfMonth(navEnd)) ||
diff --git a/src/helpers/getYearOptions.test.ts b/src/helpers/getYearOptions.test.ts
index c5473bea0..b54ff45e8 100644
--- a/src/helpers/getYearOptions.test.ts
+++ b/src/helpers/getYearOptions.test.ts
@@ -5,7 +5,7 @@ import { getYearOptions } from "./getYearOptions";
test("return undefined if startMonth or endMonth is not provided", () => {
const formatters = getFormatters({
- formatYearDropdown: (year: number) => `${year}`
+ formatYearDropdown: (date: Date) => `${date.getFullYear()}`
});
const result1 = getYearOptions(
undefined,
@@ -28,7 +28,7 @@ test("return correct dropdown options", () => {
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}`
+ formatYearDropdown: (date: Date) => `${date.getFullYear()}`
});
const result = getYearOptions(
diff --git a/src/helpers/getYearOptions.ts b/src/helpers/getYearOptions.ts
index 4c88f3161..7a0f35f26 100644
--- a/src/helpers/getYearOptions.ts
+++ b/src/helpers/getYearOptions.ts
@@ -11,21 +11,22 @@ export function getYearOptions(
): DropdownOption[] | undefined {
if (!navStart) return undefined;
if (!navEnd) return undefined;
- const { startOfYear, endOfYear, addYears, isBefore, isSameYear } = dateLib;
+ const { startOfYear, endOfYear, addYears, getYear, isBefore, isSameYear } =
+ dateLib;
const firstNavYear = startOfYear(navStart);
const lastNavYear = endOfYear(navEnd);
- const years: number[] = [];
+ const years: Date[] = [];
let year = firstNavYear;
while (isBefore(year, lastNavYear) || isSameYear(year, lastNavYear)) {
- years.push(year.getFullYear());
+ years.push(year);
year = addYears(year, 1);
}
- return years.map((value) => {
- const label = formatters.formatYearDropdown(value);
+ return years.map((year) => {
+ const label = formatters.formatYearDropdown(year, dateLib);
return {
- value,
+ value: getYear(year),
label,
disabled: false
};