react-day-picker 9.4.4 → 9.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/README.md +1 -1
  2. package/dist/cjs/DayPicker.js +16 -12
  3. package/dist/cjs/DayPicker.js.map +1 -1
  4. package/dist/cjs/classes/DateLib.d.ts +77 -2
  5. package/dist/cjs/classes/DateLib.js +113 -2
  6. package/dist/cjs/classes/DateLib.js.map +1 -1
  7. package/dist/cjs/formatters/formatMonthDropdown.d.ts +2 -6
  8. package/dist/cjs/formatters/formatMonthDropdown.js +3 -6
  9. package/dist/cjs/formatters/formatMonthDropdown.js.map +1 -1
  10. package/dist/cjs/formatters/formatYearDropdown.d.ts +2 -2
  11. package/dist/cjs/formatters/formatYearDropdown.js +3 -3
  12. package/dist/cjs/formatters/formatYearDropdown.js.map +1 -1
  13. package/dist/cjs/helpers/getBroadcastWeeksInMonth.js +1 -1
  14. package/dist/cjs/helpers/getBroadcastWeeksInMonth.js.map +1 -1
  15. package/dist/cjs/helpers/getInitialMonth.js +1 -6
  16. package/dist/cjs/helpers/getInitialMonth.js.map +1 -1
  17. package/dist/cjs/helpers/getMonthOptions.js +7 -20
  18. package/dist/cjs/helpers/getMonthOptions.js.map +1 -1
  19. package/dist/cjs/helpers/getNavMonth.d.ts +1 -1
  20. package/dist/cjs/helpers/getNavMonth.js +12 -24
  21. package/dist/cjs/helpers/getNavMonth.js.map +1 -1
  22. package/dist/cjs/helpers/getWeekdays.d.ts +1 -1
  23. package/dist/cjs/helpers/getWeekdays.js +5 -10
  24. package/dist/cjs/helpers/getWeekdays.js.map +1 -1
  25. package/dist/cjs/helpers/getYearOptions.js +5 -5
  26. package/dist/cjs/helpers/getYearOptions.js.map +1 -1
  27. package/dist/cjs/jalali.d.ts +2 -3
  28. package/dist/cjs/jalali.js +4 -42
  29. package/dist/cjs/jalali.js.map +1 -1
  30. package/dist/cjs/persian.d.ts +54 -0
  31. package/dist/cjs/persian.js +68 -0
  32. package/dist/cjs/persian.js.map +1 -0
  33. package/dist/cjs/types/props.d.ts +23 -6
  34. package/dist/cjs/types/shared.d.ts +19 -0
  35. package/dist/cjs/useGetModifiers.js +1 -7
  36. package/dist/cjs/useGetModifiers.js.map +1 -1
  37. package/dist/esm/DayPicker.js +16 -12
  38. package/dist/esm/DayPicker.js.map +1 -1
  39. package/dist/esm/classes/DateLib.d.ts +77 -2
  40. package/dist/esm/classes/DateLib.js +114 -3
  41. package/dist/esm/classes/DateLib.js.map +1 -1
  42. package/dist/esm/formatters/formatMonthDropdown.d.ts +2 -6
  43. package/dist/esm/formatters/formatMonthDropdown.js +3 -6
  44. package/dist/esm/formatters/formatMonthDropdown.js.map +1 -1
  45. package/dist/esm/formatters/formatYearDropdown.d.ts +2 -2
  46. package/dist/esm/formatters/formatYearDropdown.js +3 -3
  47. package/dist/esm/formatters/formatYearDropdown.js.map +1 -1
  48. package/dist/esm/helpers/getBroadcastWeeksInMonth.js +1 -1
  49. package/dist/esm/helpers/getBroadcastWeeksInMonth.js.map +1 -1
  50. package/dist/esm/helpers/getInitialMonth.js +1 -6
  51. package/dist/esm/helpers/getInitialMonth.js.map +1 -1
  52. package/dist/esm/helpers/getMonthOptions.js +7 -20
  53. package/dist/esm/helpers/getMonthOptions.js.map +1 -1
  54. package/dist/esm/helpers/getNavMonth.d.ts +1 -1
  55. package/dist/esm/helpers/getNavMonth.js +12 -24
  56. package/dist/esm/helpers/getNavMonth.js.map +1 -1
  57. package/dist/esm/helpers/getWeekdays.d.ts +1 -1
  58. package/dist/esm/helpers/getWeekdays.js +5 -10
  59. package/dist/esm/helpers/getWeekdays.js.map +1 -1
  60. package/dist/esm/helpers/getYearOptions.js +5 -5
  61. package/dist/esm/helpers/getYearOptions.js.map +1 -1
  62. package/dist/esm/jalali.d.ts +2 -3
  63. package/dist/esm/jalali.js +2 -17
  64. package/dist/esm/jalali.js.map +1 -1
  65. package/dist/esm/persian.d.ts +54 -0
  66. package/dist/esm/persian.js +27 -0
  67. package/dist/esm/persian.js.map +1 -0
  68. package/dist/esm/types/props.d.ts +23 -6
  69. package/dist/esm/types/shared.d.ts +19 -0
  70. package/dist/esm/useGetModifiers.js +1 -7
  71. package/dist/esm/useGetModifiers.js.map +1 -1
  72. package/examples/DropdownMonths.test.tsx +26 -0
  73. package/examples/DropdownMonths.tsx +7 -0
  74. package/examples/Numerals.test.tsx +18 -0
  75. package/examples/Numerals.tsx +8 -0
  76. package/examples/Persian.test.tsx +16 -0
  77. package/examples/Persian.tsx +7 -0
  78. package/examples/PersianEn.tsx +19 -0
  79. package/examples/PersianFormatted.test.tsx +16 -0
  80. package/examples/PersianFormatted.tsx +20 -0
  81. package/examples/index.ts +5 -2
  82. package/package.json +22 -10
  83. package/src/DayPicker.test.tsx +1 -1
  84. package/src/DayPicker.tsx +19 -18
  85. package/src/classes/DateLib.ts +146 -6
  86. package/src/formatters/formatMonthDropdown.test.ts +5 -5
  87. package/src/formatters/formatMonthDropdown.ts +4 -6
  88. package/src/formatters/formatYearDropdown.test.ts +3 -1
  89. package/src/formatters/formatYearDropdown.ts +7 -3
  90. package/src/helpers/broadcastCalendar.test.ts +1 -1
  91. package/src/helpers/endOfBroadcastWeek.test.ts +1 -1
  92. package/src/helpers/getBroadcastWeeksInMonth.ts +1 -1
  93. package/src/helpers/getFormatters.test.ts +8 -23
  94. package/src/helpers/getInitialMonth.ts +1 -7
  95. package/src/helpers/getMonthOptions.test.ts +214 -160
  96. package/src/helpers/getMonthOptions.ts +15 -22
  97. package/src/helpers/getMonths.test.ts +1 -2
  98. package/src/helpers/getNavMonth.test.ts +206 -63
  99. package/src/helpers/getNavMonth.ts +15 -27
  100. package/src/helpers/getWeekdays.ts +4 -11
  101. package/src/helpers/getYearOptions.test.ts +3 -3
  102. package/src/helpers/getYearOptions.ts +7 -6
  103. package/src/jalali.tsx +2 -24
  104. package/src/persian.tsx +86 -0
  105. package/src/selection/useRange.test.tsx +1 -2
  106. package/src/types/props.ts +24 -6
  107. package/src/types/shared.ts +32 -0
  108. package/src/useGetModifiers.tsx +1 -11
  109. package/website/docs/docs/localization.mdx +84 -52
  110. package/website/docs/docs/translation.mdx +18 -40
  111. package/website/docs/intro.mdx +1 -1
  112. package/website/tsconfig.json +1 -4
  113. package/examples/Jalali.test.tsx +0 -17
  114. package/examples/Jalali.tsx +0 -7
  115. package/examples/NumberingSystem.test.tsx +0 -21
  116. package/examples/NumberingSystem.tsx +0 -33
@@ -1,110 +1,253 @@
1
+ import {
2
+ addYears,
3
+ endOfMonth,
4
+ endOfYear,
5
+ startOfDay,
6
+ startOfMonth,
7
+ startOfYear
8
+ } from "date-fns";
9
+ import { DayPickerProps } from "react-day-picker/types";
10
+
1
11
  import { defaultDateLib } from "../classes/DateLib";
2
12
 
3
13
  import { getNavMonths } from "./getNavMonth";
4
14
 
5
- describe('when "startMonth" is not passed in', () => {
15
+ describe('when "startMonth" is not set', () => {
6
16
  test('"startMonth" should be undefined', () => {
7
17
  const [navStartMonth] = getNavMonths({}, defaultDateLib);
8
18
  expect(navStartMonth).toBeUndefined();
9
19
  });
10
20
  });
11
- describe('when "startMonth" is passed in', () => {
12
- const [navStartMonth] = getNavMonths(
13
- {
14
- startMonth: new Date(2021, 4, 3)
15
- },
16
- defaultDateLib
17
- );
21
+ describe('when "startMonth" is set', () => {
22
+ const startMonth = new Date(2021, 4, 3);
23
+ const props: DayPickerProps = { startMonth };
18
24
  test('"startMonth" should be the start of that month', () => {
19
- expect(navStartMonth).toEqual(new Date(2021, 4, 1));
25
+ const [navStartMonth] = getNavMonths(props, defaultDateLib);
26
+ const startOfThatMonth = startOfMonth(startMonth);
27
+ expect(navStartMonth).toEqual(startOfThatMonth);
20
28
  });
21
- describe('when "fromYear" is passed in', () => {
29
+ describe('when "fromYear" is set', () => {
30
+ const fromYear = 2021;
22
31
  test('"startMonth" should be the start of that month', () => {
23
- expect(navStartMonth).toEqual(new Date(2021, 4, 1));
32
+ const [navStartMonth] = getNavMonths(
33
+ { ...props, fromYear },
34
+ defaultDateLib
35
+ );
36
+ const startOfThatMonth = startOfMonth(startMonth);
37
+ expect(navStartMonth).toEqual(startOfThatMonth);
24
38
  });
25
39
  });
26
40
  });
27
- describe('when "fromYear" is passed in', () => {
28
- const [navStartMonth] = getNavMonths({ fromYear: 2021 }, defaultDateLib);
41
+ describe('when "fromYear" is set', () => {
42
+ const fromYear = 2021;
43
+ const props: DayPickerProps = { fromYear };
29
44
  test('"startMonth" should be the start of that year', () => {
30
- expect(navStartMonth).toEqual(new Date(2021, 0, 1));
45
+ const [navStartMonth] = getNavMonths(props, defaultDateLib);
46
+ const startOfThatYear = new Date(fromYear, 0, 1);
47
+ expect(navStartMonth).toEqual(startOfThatYear);
31
48
  });
32
49
  });
33
- describe('when "endMonth" is passed in', () => {
34
- const [, navEndMonth] = getNavMonths(
35
- {
36
- endMonth: new Date(2021, 4, 3)
37
- },
38
- defaultDateLib
39
- );
50
+ describe('when "endMonth" is set', () => {
51
+ const endMonth = new Date(2021, 4, 3);
52
+ const props: DayPickerProps = { endMonth };
40
53
  test('"endMonth" should be the end of that month', () => {
41
- expect(navEndMonth).toEqual(new Date(2021, 4, 31));
54
+ const [, navEndMonth] = getNavMonths(props, defaultDateLib);
55
+ const endOfThatMonth = startOfDay(endOfMonth(endMonth));
56
+ expect(navEndMonth).toEqual(endOfThatMonth);
42
57
  });
43
- describe('when "fromYear" is passed in', () => {
58
+ describe('when "fromYear" is set', () => {
59
+ const fromYear = 2021;
44
60
  test('"endMonth" should be the end of that month', () => {
45
- expect(navEndMonth).toEqual(new Date(2021, 4, 31));
61
+ const [, navEndMonth] = getNavMonths(
62
+ { ...props, fromYear },
63
+ defaultDateLib
64
+ );
65
+ const endOfThatMonth = startOfDay(endOfMonth(endMonth));
66
+ expect(navEndMonth).toEqual(endOfThatMonth);
46
67
  });
47
68
  });
48
69
  });
49
70
 
50
- describe('when "toYear" is passed in', () => {
71
+ describe('when "toYear" is set', () => {
51
72
  const toYear = 2021;
52
- const expectedendMonth = new Date(2021, 11, 31);
53
- const [, navEndMonth] = getNavMonths({ toYear }, defaultDateLib);
73
+ const props: DayPickerProps = { toYear };
54
74
  test('"endMonth" should be the end of that year', () => {
55
- expect(navEndMonth).toEqual(expectedendMonth);
75
+ const [, navEndMonth] = getNavMonths(props, defaultDateLib);
76
+ expect(navEndMonth).toEqual(new Date(toYear, 11, 31));
56
77
  });
57
78
  });
58
79
 
59
- describe('when "captionLayout" is dropdown', () => {
80
+ describe.each([["dropdown" as const], ["dropdown-years" as const]])(
81
+ 'when "captionLayout" is "%s"',
82
+ (captionLayout) => {
83
+ const today = new Date(2024, 4, 3);
84
+ const props: DayPickerProps = { captionLayout, today };
85
+
86
+ test('"startMonth" should be 100 years ago', () => {
87
+ const [navStartMonth] = getNavMonths(props, defaultDateLib);
88
+ const startOf100YearsAgo = startOfYear(addYears(today, -100));
89
+ expect(navStartMonth).toEqual(startOf100YearsAgo);
90
+ });
91
+ test('"endMonth" should be the end of this year', () => {
92
+ const [, navEndMonth] = getNavMonths(props, defaultDateLib);
93
+ const endOfThisYear = startOfDay(endOfYear(new Date()));
94
+ expect(navEndMonth).toEqual(endOfThisYear);
95
+ });
96
+
97
+ describe('when "startMonth" is set', () => {
98
+ const today = new Date(2024, 4, 3);
99
+ const startMonth = new Date(2021, 4, 3);
100
+ const props: DayPickerProps = { captionLayout, startMonth, today };
101
+ test('"startMonth" should be the start of that month', () => {
102
+ const [navStartMonth] = getNavMonths(props, defaultDateLib);
103
+ const startOfThatMonth = startOfMonth(startMonth);
104
+ expect(navStartMonth).toEqual(startOfThatMonth);
105
+ });
106
+ test('"endMonth" should be the end of this year', () => {
107
+ const [, navEndMonth] = getNavMonths(props, defaultDateLib);
108
+ const endOfThisYear = startOfDay(endOfYear(new Date()));
109
+ expect(navEndMonth).toEqual(endOfThisYear);
110
+ });
111
+ });
112
+
113
+ describe('when "endMonth" is set', () => {
114
+ const today = new Date(2021, 4, 3);
115
+ const endMonth = new Date(2022, 4, 3);
116
+ const props: DayPickerProps = { captionLayout, endMonth, today };
117
+
118
+ test('"startMonth" should be 100 years ago', () => {
119
+ const [navStartMonth] = getNavMonths(props, defaultDateLib);
120
+ const startOf100YearsAgo = startOfYear(addYears(today, -100));
121
+ expect(navStartMonth).toEqual(startOf100YearsAgo);
122
+ });
123
+ test('"endMonth" should be the end of that month', () => {
124
+ const [, navEndMonth] = getNavMonths(props, defaultDateLib);
125
+ expect(navEndMonth).toEqual(startOfDay(endOfMonth(endMonth)));
126
+ });
127
+ });
128
+
129
+ describe('when "fromYear" is set', () => {
130
+ const today = new Date(2024, 4, 3);
131
+ const fromYear = 2022;
132
+ const props: DayPickerProps = { captionLayout, fromYear, today };
133
+
134
+ test('"startMonth" should be equal to the "fromYear"', () => {
135
+ const [navStartMonth] = getNavMonths(props, defaultDateLib);
136
+ const startOfThatYear = new Date(fromYear, 0, 1);
137
+ expect(navStartMonth).toEqual(startOfThatYear);
138
+ });
139
+ test('"endMonth" should be the end of this year', () => {
140
+ const [, navEndMonth] = getNavMonths(props, defaultDateLib);
141
+ const endOfThisYear = startOfDay(endOfYear(today));
142
+ expect(navEndMonth).toEqual(endOfThisYear);
143
+ });
144
+ });
145
+
146
+ describe('when "toYear" is set', () => {
147
+ const today = new Date(2021, 4, 3);
148
+ const toYear = 2022;
149
+ const props: DayPickerProps = { captionLayout, toYear, today };
150
+
151
+ test('"startMonth" should be 100 years ago', () => {
152
+ const [navStartMonth] = getNavMonths(props, defaultDateLib);
153
+ expect(navStartMonth).toEqual(startOfYear(addYears(today, -100)));
154
+ });
155
+ test('"endMonth" should be equal the last day of the year', () => {
156
+ const [, navEndMonth] = getNavMonths(props, defaultDateLib);
157
+ expect(navEndMonth).toEqual(new Date(toYear, 11, 31));
158
+ });
159
+ });
160
+ }
161
+ );
162
+
163
+ describe('when "captionLayout" is "dropdown-months"', () => {
60
164
  const today = new Date(2024, 4, 3);
61
- const [navStartMonth, navEndMonth] = getNavMonths(
62
- {
63
- captionLayout: "dropdown",
165
+ const props: DayPickerProps = {
166
+ captionLayout: "dropdown-months",
167
+ today
168
+ };
169
+ test('"startMonth" should be undefined', () => {
170
+ const [navStartMonth] = getNavMonths(props, defaultDateLib);
171
+ expect(navStartMonth).toBeUndefined();
172
+ });
173
+ test('"endMonth" should be undefined', () => {
174
+ const [, navEndMonth] = getNavMonths(props, defaultDateLib);
175
+ expect(navEndMonth).toBeUndefined();
176
+ });
177
+
178
+ describe('when "startMonth" is set', () => {
179
+ const today = new Date(2024, 4, 3);
180
+ const startMonth = new Date(2021, 4, 3);
181
+ const props: DayPickerProps = {
182
+ captionLayout: "dropdown-months",
183
+ startMonth,
64
184
  today
65
- },
66
- defaultDateLib
67
- );
68
- test('"startMonth" should be 100 years ago', () => {
69
- expect(navStartMonth).toEqual(new Date(1924, 0, 1));
185
+ };
186
+ test('"startMonth" should be the start of that month', () => {
187
+ const [navStartMonth] = getNavMonths(props, defaultDateLib);
188
+ const startOfThatMonth = startOfMonth(startMonth);
189
+ expect(navStartMonth).toEqual(startOfThatMonth);
190
+ });
191
+ test('"endMonth" should be undefined', () => {
192
+ const [, navEndMonth] = getNavMonths(props, defaultDateLib);
193
+ expect(navEndMonth).toBeUndefined();
194
+ });
70
195
  });
71
- test('"endMonth" should be the end of this year', () => {
72
- expect(navEndMonth).toEqual(new Date(2024, 11, 31));
196
+
197
+ describe('when "endMonth" is set', () => {
198
+ const today = new Date(2021, 4, 3);
199
+ const endMonth = new Date(2022, 4, 3);
200
+ const props: DayPickerProps = {
201
+ captionLayout: "dropdown-months",
202
+ endMonth,
203
+ today
204
+ };
205
+ test('"startMonth" should be undefined', () => {
206
+ const [navStartMonth] = getNavMonths(props, defaultDateLib);
207
+ expect(navStartMonth).toBeUndefined();
208
+ });
209
+ test('"endMonth" should be the end of that month', () => {
210
+ const [, navEndMonth] = getNavMonths(props, defaultDateLib);
211
+ const endOfThatMonth = startOfDay(endOfMonth(endMonth));
212
+ expect(navEndMonth).toEqual(endOfThatMonth);
213
+ });
73
214
  });
215
+
74
216
  describe('when "fromYear" is set', () => {
75
217
  const today = new Date(2024, 4, 3);
76
218
  const fromYear = 2022;
77
- const [navStartMonth, navEndMonth] = getNavMonths(
78
- {
79
- captionLayout: "dropdown",
80
- fromYear,
81
- today
82
- },
83
- defaultDateLib
84
- );
85
- test('"startMonth" should be equal to the "fromYear"', () => {
86
- expect(navStartMonth).toEqual(new Date(2022, 0, 1));
219
+ const props: DayPickerProps = {
220
+ captionLayout: "dropdown-months",
221
+ fromYear,
222
+ today
223
+ };
224
+ test('"startMonth" should be equal to the start of that year', () => {
225
+ const [navStartMonth] = getNavMonths(props, defaultDateLib);
226
+ const startOfThatYear = new Date(fromYear, 0, 1);
227
+ expect(navStartMonth).toEqual(startOfThatYear);
87
228
  });
88
- test('"endMonth" should be the end of this year', () => {
89
- expect(navEndMonth).toEqual(new Date(2024, 11, 31));
229
+ test('"endMonth" should be undefined', () => {
230
+ const [, navEndMonth] = getNavMonths(props, defaultDateLib);
231
+ expect(navEndMonth).toBeUndefined();
90
232
  });
91
233
  });
234
+
92
235
  describe('when "toYear" is set', () => {
93
236
  const today = new Date(2021, 4, 3);
94
237
  const toYear = 2022;
95
- const [navStartMonth, navEndMonth] = getNavMonths(
96
- {
97
- captionLayout: "dropdown",
98
- toYear,
99
- today
100
- },
101
- defaultDateLib
102
- );
103
- test('"startMonth" should be 100 years ago', () => {
104
- expect(navStartMonth).toEqual(new Date(1921, 0, 1));
238
+ const props: DayPickerProps = {
239
+ captionLayout: "dropdown-months",
240
+ toYear,
241
+ today
242
+ };
243
+ test('"startMonth" should be undefined', () => {
244
+ const [navStartMonth] = getNavMonths(props, defaultDateLib);
245
+ expect(navStartMonth).toBeUndefined();
105
246
  });
106
- test('"endMonth" should be equal to "toYear"', () => {
107
- expect(navEndMonth).toEqual(new Date(2022, 11, 31));
247
+ test('"endMonth" should be equal to the end of that year', () => {
248
+ const [, navEndMonth] = getNavMonths(props, defaultDateLib);
249
+ const endOfThatYear = new Date(2022, 11, 31);
250
+ expect(navEndMonth).toEqual(endOfThatYear);
108
251
  });
109
252
  });
110
253
  });
@@ -1,6 +1,4 @@
1
- import { TZDate } from "@date-fns/tz";
2
-
3
- import type { DateLib } from "../classes/DateLib.js";
1
+ import { type DateLib } from "../classes/DateLib.js";
4
2
  import type { DayPickerProps } from "../types/index.js";
5
3
 
6
4
  /** Return the start and end months for the calendar navigation. */
@@ -28,7 +26,9 @@ export function getNavMonths(
28
26
  startOfMonth,
29
27
  endOfMonth,
30
28
  addYears,
31
- endOfYear
29
+ endOfYear,
30
+ newDate,
31
+ today
32
32
  } = dateLib;
33
33
 
34
34
  // Handle deprecated code
@@ -37,43 +37,31 @@ export function getNavMonths(
37
37
  startMonth = fromMonth;
38
38
  }
39
39
  if (!startMonth && fromYear) {
40
- startMonth = new Date(fromYear, 0, 1);
40
+ startMonth = dateLib.newDate(fromYear, 0, 1);
41
41
  }
42
42
  if (!endMonth && toMonth) {
43
43
  endMonth = toMonth;
44
44
  }
45
45
  if (!endMonth && toYear) {
46
- endMonth = new Date(toYear, 11, 31);
46
+ endMonth = newDate(toYear, 11, 31);
47
47
  }
48
48
 
49
- const hasDropdowns = props.captionLayout?.startsWith("dropdown");
49
+ const hasYearDropdown =
50
+ props.captionLayout === "dropdown" ||
51
+ props.captionLayout === "dropdown-years";
50
52
  if (startMonth) {
51
53
  startMonth = startOfMonth(startMonth);
52
54
  } else if (fromYear) {
53
- startMonth = new Date(fromYear, 0, 1);
54
- } else if (!startMonth && hasDropdowns) {
55
- const today =
56
- props.today ??
57
- (props.timeZone
58
- ? TZDate.tz(props.timeZone)
59
- : dateLib.Date
60
- ? new dateLib.Date()
61
- : new Date());
62
- startMonth = startOfYear(addYears(today, -100));
55
+ startMonth = newDate(fromYear, 0, 1);
56
+ } else if (!startMonth && hasYearDropdown) {
57
+ startMonth = startOfYear(addYears(props.today ?? today(), -100));
63
58
  }
64
59
  if (endMonth) {
65
60
  endMonth = endOfMonth(endMonth);
66
61
  } else if (toYear) {
67
- endMonth = new Date(toYear, 11, 31);
68
- } else if (!endMonth && hasDropdowns) {
69
- const today =
70
- props.today ??
71
- (props.timeZone
72
- ? TZDate.tz(props.timeZone)
73
- : dateLib.Date
74
- ? new dateLib.Date()
75
- : new Date());
76
- endMonth = endOfYear(today);
62
+ endMonth = newDate(toYear, 11, 31);
63
+ } else if (!endMonth && hasYearDropdown) {
64
+ endMonth = endOfYear(props.today ?? today());
77
65
  }
78
66
  return [
79
67
  startMonth ? startOfDay(startMonth) : startMonth,
@@ -1,5 +1,3 @@
1
- import { TZDate } from "@date-fns/tz";
2
-
3
1
  import { DateLib } from "../classes/DateLib.js";
4
2
 
5
3
  /**
@@ -11,21 +9,16 @@ export function getWeekdays(
11
9
  dateLib: DateLib,
12
10
  /** Use ISOWeek instead of locale/ */
13
11
  ISOWeek?: boolean | undefined,
14
- timeZone?: string | undefined,
15
12
  /** @since 9.4.0 */
16
13
  broadcastCalendar?: boolean | undefined
17
14
  ): Date[] {
18
- const date = timeZone
19
- ? TZDate.tz(timeZone)
20
- : dateLib.Date
21
- ? new dateLib.Date()
22
- : new Date();
15
+ const today = dateLib.today();
23
16
 
24
17
  const start = broadcastCalendar
25
- ? dateLib.startOfBroadcastWeek(date, dateLib)
18
+ ? dateLib.startOfBroadcastWeek(today, dateLib)
26
19
  : ISOWeek
27
- ? dateLib.startOfISOWeek(date)
28
- : dateLib.startOfWeek(date);
20
+ ? dateLib.startOfISOWeek(today)
21
+ : dateLib.startOfWeek(today);
29
22
 
30
23
  const days: Date[] = [];
31
24
  for (let i = 0; i < 7; i++) {
@@ -3,9 +3,9 @@ import { defaultDateLib } from "../classes/DateLib";
3
3
  import { getFormatters } from "./getFormatters";
4
4
  import { getYearOptions } from "./getYearOptions";
5
5
 
6
- test("return undefined if startMonth or endMonth is not provided", () => {
6
+ test("return undefined if navStart or navEnd are not set", () => {
7
7
  const formatters = getFormatters({
8
- formatYearDropdown: (year: number) => `${year}`
8
+ formatYearDropdown: (date: Date) => `${date.getFullYear()}`
9
9
  });
10
10
  const result1 = getYearOptions(
11
11
  undefined,
@@ -28,7 +28,7 @@ test("return correct dropdown options", () => {
28
28
  const startMonth = new Date(2022, 0, 1); // January 2022
29
29
  const endMonth = new Date(2024, 11, 31); // December 2024
30
30
  const formatters = getFormatters({
31
- formatYearDropdown: (year: number) => `${year}`
31
+ formatYearDropdown: (date: Date) => `${date.getFullYear()}`
32
32
  });
33
33
 
34
34
  const result = getYearOptions(
@@ -11,21 +11,22 @@ export function getYearOptions(
11
11
  ): DropdownOption[] | undefined {
12
12
  if (!navStart) return undefined;
13
13
  if (!navEnd) return undefined;
14
- const { startOfYear, endOfYear, addYears, isBefore, isSameYear } = dateLib;
14
+ const { startOfYear, endOfYear, addYears, getYear, isBefore, isSameYear } =
15
+ dateLib;
15
16
  const firstNavYear = startOfYear(navStart);
16
17
  const lastNavYear = endOfYear(navEnd);
17
- const years: number[] = [];
18
+ const years: Date[] = [];
18
19
 
19
20
  let year = firstNavYear;
20
21
  while (isBefore(year, lastNavYear) || isSameYear(year, lastNavYear)) {
21
- years.push(year.getFullYear());
22
+ years.push(year);
22
23
  year = addYears(year, 1);
23
24
  }
24
25
 
25
- return years.map((value) => {
26
- const label = formatters.formatYearDropdown(value);
26
+ return years.map((year) => {
27
+ const label = formatters.formatYearDropdown(year, dateLib);
27
28
  return {
28
- value,
29
+ value: getYear(year),
29
30
  label,
30
31
  disabled: false
31
32
  };
package/src/jalali.tsx CHANGED
@@ -1,24 +1,2 @@
1
- import React from "react";
2
-
3
- import * as jalaliDateLib from "date-fns-jalali";
4
- import { faIR } from "date-fns-jalali/locale";
5
-
6
- import {
7
- DayPicker as DayPickerComponent,
8
- type DayPickerProps
9
- } from "./index.js";
10
-
11
- export function DayPicker(props: DayPickerProps) {
12
- return (
13
- <DayPickerComponent
14
- // @ts-expect-error The type definitions for the date-fns-jalali library
15
- // are not compatible with the date-fns 4.0 types. The `addDays`
16
- // function's return type is causing a type mismatch. (This casting should
17
- // be not needed when date-fns-jalali upgrades to date-fns@4)
18
- dateLib={jalaliDateLib}
19
- locale={faIR}
20
- dir="rtl"
21
- {...props}
22
- />
23
- );
24
- }
1
+ /** @deprecated Import from `react-day-picker/persian` instead. */
2
+ export * from "./persian.js";
@@ -0,0 +1,86 @@
1
+ import React from "react";
2
+
3
+ import * as dateFnsJalali from "date-fns-jalali";
4
+ import { Locale } from "date-fns-jalali";
5
+ import * as locales from "date-fns-jalali/locale";
6
+
7
+ import {
8
+ DateLib,
9
+ DateLibOptions,
10
+ DayPicker as DayPickerComponent
11
+ } from "./index.js";
12
+ import type { DayPickerProps } from "./types/props.js";
13
+
14
+ export const faIR = locales.faIR;
15
+ export const enUS = locales.enUS;
16
+
17
+ /**
18
+ * Render the Persian Calendar.
19
+ *
20
+ * @see https://daypicker.dev/docs/localization#persian-calendar
21
+ */
22
+ export function DayPicker(
23
+ props: DayPickerProps & {
24
+ /**
25
+ * The locale to use in the calendar.
26
+ *
27
+ * @default `faIR`
28
+ */
29
+ locale?: Locale;
30
+ /**
31
+ * The direction of the text in the calendar.
32
+ *
33
+ * @default `rtl`
34
+ */
35
+ dir?: DayPickerProps["dir"];
36
+ /**
37
+ * The date library to use in the calendar.
38
+ *
39
+ * @default `jalaliDateLib` from `date-fns-jalali`
40
+ */
41
+ dateLib?: DayPickerProps["dateLib"];
42
+ /**
43
+ * The numeral system to use when formatting dates.
44
+ *
45
+ * - `latn`: Latin (Western Arabic)
46
+ * - `arab`: Arabic-Indic
47
+ * - `arabext`: Eastern Arabic-Indic (Persian)
48
+ * - `deva`: Devanagari
49
+ * - `beng`: Bengali
50
+ * - `guru`: Gurmukhi
51
+ * - `gujr`: Gujarati
52
+ * - `orya`: Oriya
53
+ * - `tamldec`: Tamil
54
+ * - `telu`: Telugu
55
+ * - `knda`: Kannada
56
+ * - `mlym`: Malayalam
57
+ *
58
+ * @defaultValue `arabext` Eastern Arabic-Indic (Persian)
59
+ * @see https://daypicker.dev/docs/translation#numeral-systems
60
+ */
61
+ numerals?: DayPickerProps["numerals"];
62
+ }
63
+ ) {
64
+ const dateLib = getDateLib({
65
+ locale: props.locale,
66
+ weekStartsOn: props.broadcastCalendar ? 1 : props.weekStartsOn,
67
+ firstWeekContainsDate: props.firstWeekContainsDate,
68
+ useAdditionalWeekYearTokens: props.useAdditionalWeekYearTokens,
69
+ useAdditionalDayOfYearTokens: props.useAdditionalDayOfYearTokens,
70
+ timeZone: props.timeZone
71
+ });
72
+ return (
73
+ <DayPickerComponent
74
+ {...props}
75
+ locale={props.locale ?? faIR}
76
+ numerals={props.numerals ?? "arabext"}
77
+ dir={props.dir ?? "rtl"}
78
+ dateLib={dateLib}
79
+ />
80
+ );
81
+ }
82
+
83
+ /** Returns the date library used in the calendar. */
84
+ export const getDateLib = (options?: DateLibOptions) => {
85
+ return new DateLib(options, dateFnsJalali);
86
+ };
@@ -1,9 +1,8 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import { DayPickerProps } from "react-day-picker/types";
3
-
4
2
  import { act, renderHook } from "@/test/render";
5
3
 
6
4
  import { defaultDateLib } from "../classes/DateLib";
5
+ import type { DayPickerProps } from "../types";
7
6
 
8
7
  import { useRange } from "./useRange";
9
8
 
@@ -16,7 +16,8 @@ import type {
16
16
  DayEventHandler,
17
17
  Modifiers,
18
18
  DateRange,
19
- Mode
19
+ Mode,
20
+ Numerals
20
21
  } from "./shared.js";
21
22
 
22
23
  /**
@@ -231,7 +232,8 @@ export interface PropsBase {
231
232
  /**
232
233
  * Show the outside days (days falling in the next or the previous month).
233
234
  *
234
- * **Note:** when {@link broadcastCalendar} is set, this prop defaults to true.
235
+ * **Note:** when a broadcast {@link calendar} is set, this prop defaults to
236
+ * true.
235
237
  *
236
238
  * @see https://daypicker.dev/docs/customization#outside-days
237
239
  */
@@ -240,9 +242,6 @@ export interface PropsBase {
240
242
  * Show the week numbers column. Weeks are numbered according to the local
241
243
  * week index.
242
244
  *
243
- * - To use ISO week numbering, use the `ISOWeek` prop.
244
- * - To change how the week numbers are displayed, use the `formatters` prop.
245
- *
246
245
  * @see https://daypicker.dev/docs/customization#showweeknumber
247
246
  */
248
247
  showWeekNumber?: boolean;
@@ -392,6 +391,26 @@ export interface PropsBase {
392
391
  * @see https://github.com/date-fns/date-fns/tree/main/src/locale for a list of the supported locales
393
392
  */
394
393
  locale?: Partial<Locale> | undefined;
394
+ /**
395
+ * The numeral system to use when formatting dates.
396
+ *
397
+ * - `latn`: Latin (Western Arabic)
398
+ * - `arab`: Arabic-Indic
399
+ * - `arabext`: Eastern Arabic-Indic (Persian)
400
+ * - `deva`: Devanagari
401
+ * - `beng`: Bengali
402
+ * - `guru`: Gurmukhi
403
+ * - `gujr`: Gujarati
404
+ * - `orya`: Oriya
405
+ * - `tamldec`: Tamil
406
+ * - `telu`: Telugu
407
+ * - `knda`: Kannada
408
+ * - `mlym`: Malayalam
409
+ *
410
+ * @defaultValue `latn` Latin (Western Arabic)
411
+ * @see https://daypicker.dev/docs/translation#numeral-systems
412
+ */
413
+ numerals?: Numerals | undefined;
395
414
  /**
396
415
  * The index of the first day of the week (0 - Sunday). Overrides the locale's
397
416
  * one.
@@ -522,7 +541,6 @@ export interface PropsBase {
522
541
  * @param {Date} triggerDate - The date when the event was triggered.
523
542
  * @param {Modifiers} modifiers - The modifiers associated with the event.
524
543
  * @param {React.MouseEvent | React.KeyboardEvent} e - The event object.
525
- * @group DayPicker
526
544
  */
527
545
  export type OnSelectHandler<T> = (
528
546
  selected: T,