react-day-picker 9.0.6 → 9.0.7
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.
- package/dist/cjs/DayPicker.js +6 -3
- package/dist/cjs/DayPicker.js.map +1 -1
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.js +3 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/selection/useMulti.js +1 -7
- package/dist/cjs/selection/useMulti.js.map +1 -1
- package/dist/cjs/selection/useRange.js +1 -7
- package/dist/cjs/selection/useRange.js.map +1 -1
- package/dist/cjs/selection/useSingle.js +2 -8
- package/dist/cjs/selection/useSingle.js.map +1 -1
- package/dist/cjs/types/props.d.ts +16 -8
- package/dist/cjs/useCalendar.d.ts +1 -1
- package/dist/cjs/useCalendar.js +26 -2
- package/dist/cjs/useCalendar.js.map +1 -1
- package/dist/cjs/useDayPicker.d.ts +1 -0
- package/dist/cjs/useDayPicker.js +1 -1
- package/dist/cjs/useDayPicker.js.map +1 -1
- package/dist/esm/DayPicker.js +6 -3
- package/dist/esm/DayPicker.js.map +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/selection/useMulti.js +1 -7
- package/dist/esm/selection/useMulti.js.map +1 -1
- package/dist/esm/selection/useRange.js +1 -7
- package/dist/esm/selection/useRange.js.map +1 -1
- package/dist/esm/selection/useSingle.js +2 -8
- package/dist/esm/selection/useSingle.js.map +1 -1
- package/dist/esm/types/props.d.ts +16 -8
- package/dist/esm/useCalendar.d.ts +1 -1
- package/dist/esm/useCalendar.js +26 -2
- package/dist/esm/useCalendar.js.map +1 -1
- package/dist/esm/useDayPicker.d.ts +1 -0
- package/dist/esm/useDayPicker.js +1 -1
- package/dist/esm/useDayPicker.js.map +1 -1
- package/examples/SingleRequired.tsx +1 -1
- package/package.json +4 -4
- package/src/DayPicker.test.tsx +49 -5
- package/src/DayPicker.tsx +20 -17
- package/src/index.ts +2 -0
- package/src/selection/useMulti.tsx +1 -8
- package/src/selection/useRange.tsx +0 -8
- package/src/selection/useSingle.tsx +2 -9
- package/src/types/props.test.tsx +10 -3
- package/src/types/props.ts +16 -8
- package/src/useCalendar.ts +63 -6
- package/src/useDayPicker.ts +1 -1
- package/website/docs/docs/localization.mdx +21 -0
- package/website/docs/docs/selection-modes.mdx +9 -8
- package/website/docs/docs/styling.mdx +2 -2
- package/website/docs/upgrading.mdx +2 -2
|
@@ -12,8 +12,11 @@ export type DayPickerProps = PropsBase & (PropsSingle | PropsSingleRequired | Pr
|
|
|
12
12
|
required?: undefined;
|
|
13
13
|
});
|
|
14
14
|
/**
|
|
15
|
-
* Props
|
|
16
|
-
*
|
|
15
|
+
* Props for customizing the calendar, handling localization, and managing
|
|
16
|
+
* events. These exclude the selection mode props.
|
|
17
|
+
*
|
|
18
|
+
* @group DayPicker
|
|
19
|
+
* @see https://daypicker.dev/api/interfaces/PropsBase
|
|
17
20
|
*/
|
|
18
21
|
export interface PropsBase {
|
|
19
22
|
/**
|
|
@@ -307,12 +310,17 @@ export interface PropsBase {
|
|
|
307
310
|
/** Add the language tag to the container element. */
|
|
308
311
|
lang?: HTMLDivElement["lang"];
|
|
309
312
|
/**
|
|
310
|
-
* The
|
|
313
|
+
* The locale object used to localize dates. Pass a locale from `date-fns` to
|
|
314
|
+
* localize the calendar.
|
|
315
|
+
*
|
|
316
|
+
* @example
|
|
317
|
+
* import { es } from "date-fns/locale";
|
|
318
|
+
* <DayPicker locale={es} />
|
|
311
319
|
*
|
|
312
|
-
* @defaultValue
|
|
320
|
+
* @defaultValue enUS - The English locale default of `date-fns`.
|
|
313
321
|
* @see https://daypicker.dev/docs/localization
|
|
314
322
|
*/
|
|
315
|
-
locale?: Locale | undefined;
|
|
323
|
+
locale?: Partial<Locale> | undefined;
|
|
316
324
|
/**
|
|
317
325
|
* The index of the first day of the week (0 - Sunday). Overrides the locale's
|
|
318
326
|
* one.
|
|
@@ -436,7 +444,7 @@ export interface PropsSingleRequired {
|
|
|
436
444
|
mode: "single";
|
|
437
445
|
required: true;
|
|
438
446
|
/** The selected date. */
|
|
439
|
-
selected: Date;
|
|
447
|
+
selected: Date | undefined;
|
|
440
448
|
/** Event handler when a day is selected. */
|
|
441
449
|
onSelect?: (selected: Date, triggerDate: Date, modifiers: Modifiers, e: React.MouseEvent | React.KeyboardEvent) => void | undefined;
|
|
442
450
|
}
|
|
@@ -462,7 +470,7 @@ export interface PropsMultiRequired {
|
|
|
462
470
|
mode: "multiple";
|
|
463
471
|
required: true;
|
|
464
472
|
/** The selected dates. */
|
|
465
|
-
selected: Date[];
|
|
473
|
+
selected: Date[] | undefined;
|
|
466
474
|
/** Event handler when days are selected. */
|
|
467
475
|
onSelect?: (selected: Date[], triggerDate: Date, modifiers: Modifiers, e: React.MouseEvent | React.KeyboardEvent) => void;
|
|
468
476
|
/** The minimum number of selectable days. */
|
|
@@ -503,7 +511,7 @@ export interface PropsRangeRequired {
|
|
|
503
511
|
*/
|
|
504
512
|
excludeDisabled?: boolean | undefined;
|
|
505
513
|
/** The selected range. */
|
|
506
|
-
selected: DateRange;
|
|
514
|
+
selected: DateRange | undefined;
|
|
507
515
|
/** Event handler when a range is selected. */
|
|
508
516
|
onSelect?: (selected: DateRange, triggerDate: Date, modifiers: Modifiers, e: React.MouseEvent | React.KeyboardEvent) => void;
|
|
509
517
|
/** The minimum number of days to include in the range. */
|
|
@@ -45,4 +45,4 @@ export interface Calendar {
|
|
|
45
45
|
goToDay: (day: CalendarDay) => void;
|
|
46
46
|
}
|
|
47
47
|
/** @private */
|
|
48
|
-
export declare function useCalendar(props: DayPickerProps, dateLib: DateLib): Calendar;
|
|
48
|
+
export declare function useCalendar(props: Pick<DayPickerProps, "captionLayout" | "endMonth" | "startMonth" | "today" | "fixedWeeks" | "ISOWeek" | "weekStartsOn" | "numberOfMonths" | "disableNavigation" | "onMonthChange" | "month" | "defaultMonth" | "fromMonth" | "fromYear" | "toMonth" | "toYear">, dateLib: DateLib): Calendar;
|
package/dist/esm/useCalendar.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
1
2
|
import { getDates } from "./helpers/getDates.js";
|
|
2
3
|
import { getDays } from "./helpers/getDays.js";
|
|
3
4
|
import { getDisplayMonths } from "./helpers/getDisplayMonths.js";
|
|
@@ -7,14 +8,37 @@ import { getNavMonths } from "./helpers/getNavMonth.js";
|
|
|
7
8
|
import { getNextMonth } from "./helpers/getNextMonth.js";
|
|
8
9
|
import { getPreviousMonth } from "./helpers/getPreviousMonth.js";
|
|
9
10
|
import { getWeeks } from "./helpers/getWeeks.js";
|
|
10
|
-
import { useControlledValue } from "./helpers/useControlledValue.js";
|
|
11
11
|
/** @private */
|
|
12
12
|
export function useCalendar(props, dateLib) {
|
|
13
|
+
const { fromYear, toYear, startMonth, endMonth, today, numberOfMonths, month, defaultMonth } = props;
|
|
13
14
|
const [navStart, navEnd] = getNavMonths(props, dateLib);
|
|
14
15
|
const { startOfMonth, endOfMonth } = dateLib;
|
|
15
16
|
const initialDisplayMonth = getInitialMonth(props, dateLib);
|
|
16
17
|
// The first month displayed in the calendar
|
|
17
|
-
const [firstMonth, setFirstMonth] =
|
|
18
|
+
const [firstMonth, setFirstMonth] = useState(initialDisplayMonth);
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
const initialDisplayMonth = getInitialMonth({
|
|
21
|
+
fromYear,
|
|
22
|
+
toYear,
|
|
23
|
+
startMonth,
|
|
24
|
+
endMonth,
|
|
25
|
+
month,
|
|
26
|
+
defaultMonth,
|
|
27
|
+
today,
|
|
28
|
+
numberOfMonths
|
|
29
|
+
}, dateLib);
|
|
30
|
+
setFirstMonth(initialDisplayMonth);
|
|
31
|
+
}, [
|
|
32
|
+
dateLib,
|
|
33
|
+
defaultMonth,
|
|
34
|
+
endMonth,
|
|
35
|
+
fromYear,
|
|
36
|
+
month,
|
|
37
|
+
numberOfMonths,
|
|
38
|
+
startMonth,
|
|
39
|
+
toYear,
|
|
40
|
+
today
|
|
41
|
+
]);
|
|
18
42
|
/** The months displayed in the calendar. */
|
|
19
43
|
const displayMonths = getDisplayMonths(firstMonth, navEnd, props, dateLib);
|
|
20
44
|
/** The dates displayed in the calendar. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useCalendar.js","sourceRoot":"","sources":["../../src/useCalendar.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useCalendar.js","sourceRoot":"","sources":["../../src/useCalendar.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,6 +3,7 @@ import { CalendarMonth } from "./classes/CalendarMonth.js";
|
|
|
3
3
|
import type { DayPickerProps } from "./types/props.js";
|
|
4
4
|
import type { SelectedValue, SelectHandler } from "./types/selection.js";
|
|
5
5
|
import { Modifiers } from "./types/shared.js";
|
|
6
|
+
/** @private */
|
|
6
7
|
export declare const dayPickerContext: import("react").Context<DayPickerContext<DayPickerProps> | undefined>;
|
|
7
8
|
export type DayPickerContext<T extends DayPickerProps> = {
|
|
8
9
|
/** The months displayed in the calendar. */
|
package/dist/esm/useDayPicker.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDayPicker.js","sourceRoot":"","sources":["../../src/useDayPicker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAQlD,
|
|
1
|
+
{"version":3,"file":"useDayPicker.js","sourceRoot":"","sources":["../../src/useDayPicker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAQlD,eAAe;AACf,MAAM,CAAC,MAAM,gBAAgB,GAAG,aAAa,CAE3C,SAAS,CAAC,CAAC;AAqBb;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAA2B,KAAS;IAC9D,MAAM,OAAO,GAAG,UAAU,CAAC,gBAAgB,CAAC,CAAC;IAC7C,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;IAC5E,CAAC;IACD,OAAO,OAA8B,CAAC;AACxC,CAAC"}
|
|
@@ -3,7 +3,7 @@ import React, { useState } from "react";
|
|
|
3
3
|
import { DayPicker } from "react-day-picker";
|
|
4
4
|
|
|
5
5
|
export function SingleRequired() {
|
|
6
|
-
const [selectedDay, setSelectedDay] = useState<Date>(
|
|
6
|
+
const [selectedDay, setSelectedDay] = useState<Date>();
|
|
7
7
|
|
|
8
8
|
return (
|
|
9
9
|
<DayPicker
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-day-picker",
|
|
3
|
-
"version": "9.0.
|
|
3
|
+
"version": "9.0.7",
|
|
4
4
|
"description": "Customizable Date Picker for React",
|
|
5
5
|
"author": "Giampaolo Bellavite <io@gpbl.dev>",
|
|
6
6
|
"homepage": "https://daypicker.dev",
|
|
@@ -141,7 +141,7 @@
|
|
|
141
141
|
"@testing-library/user-event": "^14.5.2",
|
|
142
142
|
"@trivago/prettier-plugin-sort-imports": "^4.3.0",
|
|
143
143
|
"@types/jest": "^29.5.12",
|
|
144
|
-
"@types/node": "^22.
|
|
144
|
+
"@types/node": "^22.1.0",
|
|
145
145
|
"@types/react": "^18.3.3",
|
|
146
146
|
"@types/react-dom": "^18.3.0",
|
|
147
147
|
"@typescript-eslint/eslint-plugin": "^7.18.0",
|
|
@@ -152,7 +152,7 @@
|
|
|
152
152
|
"eslint-config-prettier": "^9.1.0",
|
|
153
153
|
"eslint-import-resolver-typescript": "^3.6.1",
|
|
154
154
|
"eslint-plugin-import": "^2.29.1",
|
|
155
|
-
"eslint-plugin-jest": "^28.
|
|
155
|
+
"eslint-plugin-jest": "^28.7.0",
|
|
156
156
|
"eslint-plugin-prettier": "^5.2.1",
|
|
157
157
|
"eslint-plugin-react": "^7.35.0",
|
|
158
158
|
"eslint-plugin-react-hooks": "^4.6.2",
|
|
@@ -166,7 +166,7 @@
|
|
|
166
166
|
"react": "^18.3.1",
|
|
167
167
|
"react-classnaming": "^0.16.4",
|
|
168
168
|
"react-dom": "^18.3.1",
|
|
169
|
-
"ts-jest": "^29.2.
|
|
169
|
+
"ts-jest": "^29.2.4",
|
|
170
170
|
"ts-node": "^10.9.2",
|
|
171
171
|
"tslib": "^2.6.3",
|
|
172
172
|
"typescript": "~5.5.4",
|
package/src/DayPicker.test.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { addMonths, startOfDay, startOfMonth } from "date-fns";
|
|
4
|
+
import { defaultLocale } from "react-day-picker";
|
|
5
5
|
|
|
6
6
|
import {
|
|
7
7
|
activeElement,
|
|
@@ -10,11 +10,13 @@ import {
|
|
|
10
10
|
nav,
|
|
11
11
|
previousButton
|
|
12
12
|
} from "@/test/elements";
|
|
13
|
+
import { fireEvent, render, screen } from "@/test/render";
|
|
13
14
|
import { user } from "@/test/user";
|
|
14
15
|
|
|
15
16
|
import { DayPicker } from "./DayPicker";
|
|
16
17
|
import { MonthProps } from "./components/Month";
|
|
17
18
|
import { MonthsProps } from "./components/Months";
|
|
19
|
+
import { labelGrid } from "./labels";
|
|
18
20
|
|
|
19
21
|
const testId = "test";
|
|
20
22
|
const dayPicker = () => screen.getByTestId(testId);
|
|
@@ -24,14 +26,14 @@ test("should render a date picker component", () => {
|
|
|
24
26
|
expect(dayPicker()).toBeInTheDocument();
|
|
25
27
|
});
|
|
26
28
|
|
|
27
|
-
|
|
29
|
+
test("render the navigation and month grids", () => {
|
|
28
30
|
render(<DayPicker data-testid={testId} />);
|
|
29
31
|
|
|
30
32
|
expect(nav()).toBeInTheDocument();
|
|
31
33
|
expect(grid()).toBeInTheDocument();
|
|
32
34
|
});
|
|
33
35
|
|
|
34
|
-
|
|
36
|
+
test("apply classnames and style according to props", () => {
|
|
35
37
|
render(
|
|
36
38
|
<DayPicker
|
|
37
39
|
data-testid={testId}
|
|
@@ -47,7 +49,7 @@ it("should apply classnames and style according to props", () => {
|
|
|
47
49
|
expect(dayPicker()).toHaveStyle({ color: "red" });
|
|
48
50
|
});
|
|
49
51
|
|
|
50
|
-
|
|
52
|
+
test("use custom components", () => {
|
|
51
53
|
render(
|
|
52
54
|
<DayPicker
|
|
53
55
|
data-testid={testId}
|
|
@@ -131,3 +133,45 @@ describe("when a day is mouse entered", () => {
|
|
|
131
133
|
expect(handleDayMouseLeave).toHaveBeenCalled();
|
|
132
134
|
});
|
|
133
135
|
});
|
|
136
|
+
|
|
137
|
+
describe("when the `month` is changed programmatically", () => {
|
|
138
|
+
test("should update the calendar to reflect the new month", async () => {
|
|
139
|
+
const initialMonth = new Date(2023, 0, 1); // January 2023
|
|
140
|
+
const newMonth = new Date(2023, 1, 1); // February 2023
|
|
141
|
+
const { rerender } = render(
|
|
142
|
+
<DayPicker month={initialMonth} mode="single" />
|
|
143
|
+
);
|
|
144
|
+
expect(grid("January 2023")).toBeInTheDocument();
|
|
145
|
+
rerender(<DayPicker month={newMonth} mode="single" />);
|
|
146
|
+
expect(grid("February 2023")).toBeInTheDocument();
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
describe("when the `startMonth` is changed programmatically", () => {
|
|
151
|
+
test("should update the calendar to reflect the new month", async () => {
|
|
152
|
+
const initialStartMonth = new Date();
|
|
153
|
+
const newStartMonth = addMonths(new Date(), 2);
|
|
154
|
+
const { rerender } = render(
|
|
155
|
+
<DayPicker startMonth={initialStartMonth} mode="single" />
|
|
156
|
+
);
|
|
157
|
+
expect(grid(labelGrid(initialStartMonth))).toBeInTheDocument();
|
|
158
|
+
rerender(<DayPicker startMonth={newStartMonth} mode="single" />);
|
|
159
|
+
expect(grid(labelGrid(newStartMonth))).toBeInTheDocument();
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
test("extends the default locale", () => {
|
|
164
|
+
render(
|
|
165
|
+
<DayPicker
|
|
166
|
+
month={new Date(2024, 0)}
|
|
167
|
+
locale={{
|
|
168
|
+
localize: {
|
|
169
|
+
...defaultLocale.localize,
|
|
170
|
+
month: () => "bar"
|
|
171
|
+
}
|
|
172
|
+
}}
|
|
173
|
+
/>
|
|
174
|
+
);
|
|
175
|
+
// Check if the custom month name is rendered
|
|
176
|
+
expect(grid("bar 2024")).toBeInTheDocument();
|
|
177
|
+
});
|
package/src/DayPicker.tsx
CHANGED
|
@@ -20,6 +20,7 @@ import { getWeekdays } from "./helpers/getWeekdays.js";
|
|
|
20
20
|
import { getYearOptions } from "./helpers/getYearOptions.js";
|
|
21
21
|
import * as defaultLabels from "./labels/index.js";
|
|
22
22
|
import type { FormatOptions, LabelOptions } from "./lib/dateLib.js";
|
|
23
|
+
import { enUS } from "./lib/locales.js";
|
|
23
24
|
import type {
|
|
24
25
|
DayPickerProps,
|
|
25
26
|
Modifiers,
|
|
@@ -43,27 +44,29 @@ import { isDateRange } from "./utils/typeguards.js";
|
|
|
43
44
|
* @see https://daypicker.dev
|
|
44
45
|
*/
|
|
45
46
|
export function DayPicker(props: DayPickerProps) {
|
|
46
|
-
const { components, formatters, labels, dateLib, classNames } =
|
|
47
|
-
(
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
47
|
+
const { components, formatters, labels, dateLib, locale, classNames } =
|
|
48
|
+
useMemo(
|
|
49
|
+
() => ({
|
|
50
|
+
dateLib: getDateLib(props.dateLib),
|
|
51
|
+
components: getComponents(props.components),
|
|
52
|
+
formatters: getFormatters(props.formatters),
|
|
53
|
+
labels: { ...defaultLabels, ...props.labels },
|
|
54
|
+
locale: { ...enUS, ...props.locale },
|
|
55
|
+
classNames: { ...getDefaultClassNames(), ...props.classNames }
|
|
56
|
+
}),
|
|
57
|
+
[
|
|
58
|
+
props.classNames,
|
|
59
|
+
props.components,
|
|
60
|
+
props.dateLib,
|
|
61
|
+
props.formatters,
|
|
62
|
+
props.labels,
|
|
63
|
+
props.locale
|
|
64
|
+
]
|
|
65
|
+
);
|
|
62
66
|
|
|
63
67
|
const {
|
|
64
68
|
captionLayout,
|
|
65
69
|
firstWeekContainsDate,
|
|
66
|
-
locale,
|
|
67
70
|
mode,
|
|
68
71
|
onDayBlur,
|
|
69
72
|
onDayClick,
|
package/src/index.ts
CHANGED
|
@@ -22,14 +22,7 @@ export function useMulti<T extends DayPickerProps>(
|
|
|
22
22
|
initiallySelected
|
|
23
23
|
);
|
|
24
24
|
|
|
25
|
-
const { isSameDay
|
|
26
|
-
|
|
27
|
-
// Update the selected date if the required flag is set.
|
|
28
|
-
React.useEffect(() => {
|
|
29
|
-
if (required && selected === undefined) {
|
|
30
|
-
setSelected([new Date()]);
|
|
31
|
-
}
|
|
32
|
-
}, [required, selected, Date, mode]);
|
|
25
|
+
const { isSameDay } = dateLib;
|
|
33
26
|
|
|
34
27
|
// Update the selected date if the selected value from props changes.
|
|
35
28
|
React.useEffect(() => {
|
|
@@ -16,7 +16,6 @@ export function useRange<T extends DayPickerProps>(
|
|
|
16
16
|
dateLib: DateLib
|
|
17
17
|
): Selection<T> {
|
|
18
18
|
const {
|
|
19
|
-
mode,
|
|
20
19
|
disabled,
|
|
21
20
|
excludeDisabled,
|
|
22
21
|
selected: initiallySelected,
|
|
@@ -28,13 +27,6 @@ export function useRange<T extends DayPickerProps>(
|
|
|
28
27
|
initiallySelected
|
|
29
28
|
);
|
|
30
29
|
|
|
31
|
-
// Update the selected date if the required flag is set.
|
|
32
|
-
React.useEffect(() => {
|
|
33
|
-
if (required && selected === undefined) {
|
|
34
|
-
setSelected({ from: undefined, to: undefined });
|
|
35
|
-
}
|
|
36
|
-
}, [required, selected, mode]);
|
|
37
|
-
|
|
38
30
|
// Update the selected date if the `selected` prop changes.
|
|
39
31
|
React.useEffect(() => {
|
|
40
32
|
setSelected(initiallySelected);
|
|
@@ -23,21 +23,14 @@ export function useSingle<T extends DayPickerProps>(
|
|
|
23
23
|
const {
|
|
24
24
|
selected: initiallySelected,
|
|
25
25
|
required,
|
|
26
|
-
onSelect
|
|
27
|
-
mode
|
|
26
|
+
onSelect
|
|
28
27
|
} = props as PropsSingle;
|
|
29
28
|
|
|
30
29
|
const [selected, setSelected] = React.useState<Date | undefined>(
|
|
31
30
|
initiallySelected
|
|
32
31
|
);
|
|
33
32
|
|
|
34
|
-
const { isSameDay
|
|
35
|
-
// Update the selected date if the required flag is set.
|
|
36
|
-
React.useEffect(() => {
|
|
37
|
-
if (required && selected === undefined) {
|
|
38
|
-
setSelected(startOfDay(new Date()));
|
|
39
|
-
}
|
|
40
|
-
}, [required, selected, Date, startOfDay, mode]);
|
|
33
|
+
const { isSameDay } = dateLib;
|
|
41
34
|
|
|
42
35
|
// Update the selected date if the `selected` value changes.
|
|
43
36
|
React.useEffect(() => {
|
package/src/types/props.test.tsx
CHANGED
|
@@ -2,6 +2,8 @@ import React from "react";
|
|
|
2
2
|
|
|
3
3
|
import { DayPicker } from "../DayPicker";
|
|
4
4
|
|
|
5
|
+
import { DateRange } from "./shared";
|
|
6
|
+
|
|
5
7
|
const Test = () => {
|
|
6
8
|
return (
|
|
7
9
|
<>
|
|
@@ -23,15 +25,20 @@ const Test = () => {
|
|
|
23
25
|
required
|
|
24
26
|
onSelect={(date: Date | undefined) => {}}
|
|
25
27
|
/>
|
|
26
|
-
{/*
|
|
28
|
+
{/* Allow undefined as initial selected value */}
|
|
27
29
|
<DayPicker mode="single" required selected={undefined} />
|
|
28
30
|
<DayPicker
|
|
29
31
|
mode="multiple"
|
|
30
|
-
required
|
|
31
|
-
// @ts-expect-error Missing `selected`
|
|
32
|
+
required
|
|
32
33
|
selected={undefined}
|
|
33
34
|
onSelect={(selected: Date[], date: Date, modifiers) => {}}
|
|
34
35
|
/>
|
|
36
|
+
<DayPicker
|
|
37
|
+
mode="range"
|
|
38
|
+
required
|
|
39
|
+
selected={undefined}
|
|
40
|
+
onSelect={(selected: DateRange, date: Date, modifiers) => {}}
|
|
41
|
+
/>
|
|
35
42
|
<DayPicker
|
|
36
43
|
mode="multiple"
|
|
37
44
|
required={false}
|
package/src/types/props.ts
CHANGED
|
@@ -37,8 +37,11 @@ export type DayPickerProps = PropsBase &
|
|
|
37
37
|
);
|
|
38
38
|
|
|
39
39
|
/**
|
|
40
|
-
* Props
|
|
41
|
-
*
|
|
40
|
+
* Props for customizing the calendar, handling localization, and managing
|
|
41
|
+
* events. These exclude the selection mode props.
|
|
42
|
+
*
|
|
43
|
+
* @group DayPicker
|
|
44
|
+
* @see https://daypicker.dev/api/interfaces/PropsBase
|
|
42
45
|
*/
|
|
43
46
|
export interface PropsBase {
|
|
44
47
|
/**
|
|
@@ -335,12 +338,17 @@ export interface PropsBase {
|
|
|
335
338
|
/** Add the language tag to the container element. */
|
|
336
339
|
lang?: HTMLDivElement["lang"];
|
|
337
340
|
/**
|
|
338
|
-
* The
|
|
341
|
+
* The locale object used to localize dates. Pass a locale from `date-fns` to
|
|
342
|
+
* localize the calendar.
|
|
343
|
+
*
|
|
344
|
+
* @example
|
|
345
|
+
* import { es } from "date-fns/locale";
|
|
346
|
+
* <DayPicker locale={es} />
|
|
339
347
|
*
|
|
340
|
-
* @defaultValue
|
|
348
|
+
* @defaultValue enUS - The English locale default of `date-fns`.
|
|
341
349
|
* @see https://daypicker.dev/docs/localization
|
|
342
350
|
*/
|
|
343
|
-
locale?: Locale | undefined;
|
|
351
|
+
locale?: Partial<Locale> | undefined;
|
|
344
352
|
/**
|
|
345
353
|
* The index of the first day of the week (0 - Sunday). Overrides the locale's
|
|
346
354
|
* one.
|
|
@@ -470,7 +478,7 @@ export interface PropsSingleRequired {
|
|
|
470
478
|
mode: "single";
|
|
471
479
|
required: true;
|
|
472
480
|
/** The selected date. */
|
|
473
|
-
selected: Date;
|
|
481
|
+
selected: Date | undefined;
|
|
474
482
|
/** Event handler when a day is selected. */
|
|
475
483
|
onSelect?: (
|
|
476
484
|
selected: Date,
|
|
@@ -506,7 +514,7 @@ export interface PropsMultiRequired {
|
|
|
506
514
|
mode: "multiple";
|
|
507
515
|
required: true;
|
|
508
516
|
/** The selected dates. */
|
|
509
|
-
selected: Date[];
|
|
517
|
+
selected: Date[] | undefined;
|
|
510
518
|
/** Event handler when days are selected. */
|
|
511
519
|
onSelect?: (
|
|
512
520
|
selected: Date[],
|
|
@@ -557,7 +565,7 @@ export interface PropsRangeRequired {
|
|
|
557
565
|
*/
|
|
558
566
|
excludeDisabled?: boolean | undefined;
|
|
559
567
|
/** The selected range. */
|
|
560
|
-
selected: DateRange;
|
|
568
|
+
selected: DateRange | undefined;
|
|
561
569
|
/** Event handler when a range is selected. */
|
|
562
570
|
onSelect?: (
|
|
563
571
|
selected: DateRange,
|
package/src/useCalendar.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
|
|
1
3
|
import type {
|
|
2
4
|
CalendarWeek,
|
|
3
5
|
CalendarDay,
|
|
@@ -12,7 +14,6 @@ import { getNavMonths } from "./helpers/getNavMonth.js";
|
|
|
12
14
|
import { getNextMonth } from "./helpers/getNextMonth.js";
|
|
13
15
|
import { getPreviousMonth } from "./helpers/getPreviousMonth.js";
|
|
14
16
|
import { getWeeks } from "./helpers/getWeeks.js";
|
|
15
|
-
import { useControlledValue } from "./helpers/useControlledValue.js";
|
|
16
17
|
import type { DayPickerProps } from "./types/props.js";
|
|
17
18
|
import type { DateLib } from "./types/shared.js";
|
|
18
19
|
|
|
@@ -64,7 +65,39 @@ export interface Calendar {
|
|
|
64
65
|
}
|
|
65
66
|
|
|
66
67
|
/** @private */
|
|
67
|
-
export function useCalendar(
|
|
68
|
+
export function useCalendar(
|
|
69
|
+
props: Pick<
|
|
70
|
+
DayPickerProps,
|
|
71
|
+
| "captionLayout"
|
|
72
|
+
| "endMonth"
|
|
73
|
+
| "startMonth"
|
|
74
|
+
| "today"
|
|
75
|
+
| "fixedWeeks"
|
|
76
|
+
| "ISOWeek"
|
|
77
|
+
| "weekStartsOn"
|
|
78
|
+
| "numberOfMonths"
|
|
79
|
+
| "disableNavigation"
|
|
80
|
+
| "onMonthChange"
|
|
81
|
+
| "month"
|
|
82
|
+
| "defaultMonth"
|
|
83
|
+
// Deprecated:
|
|
84
|
+
| "fromMonth"
|
|
85
|
+
| "fromYear"
|
|
86
|
+
| "toMonth"
|
|
87
|
+
| "toYear"
|
|
88
|
+
>,
|
|
89
|
+
dateLib: DateLib
|
|
90
|
+
): Calendar {
|
|
91
|
+
const {
|
|
92
|
+
fromYear,
|
|
93
|
+
toYear,
|
|
94
|
+
startMonth,
|
|
95
|
+
endMonth,
|
|
96
|
+
today,
|
|
97
|
+
numberOfMonths,
|
|
98
|
+
month,
|
|
99
|
+
defaultMonth
|
|
100
|
+
} = props;
|
|
68
101
|
const [navStart, navEnd] = getNavMonths(props, dateLib);
|
|
69
102
|
|
|
70
103
|
const { startOfMonth, endOfMonth } = dateLib;
|
|
@@ -72,10 +105,34 @@ export function useCalendar(props: DayPickerProps, dateLib: DateLib): Calendar {
|
|
|
72
105
|
const initialDisplayMonth = getInitialMonth(props, dateLib);
|
|
73
106
|
|
|
74
107
|
// The first month displayed in the calendar
|
|
75
|
-
const [firstMonth, setFirstMonth] =
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
108
|
+
const [firstMonth, setFirstMonth] = useState(initialDisplayMonth);
|
|
109
|
+
|
|
110
|
+
useEffect(() => {
|
|
111
|
+
const initialDisplayMonth = getInitialMonth(
|
|
112
|
+
{
|
|
113
|
+
fromYear,
|
|
114
|
+
toYear,
|
|
115
|
+
startMonth,
|
|
116
|
+
endMonth,
|
|
117
|
+
month,
|
|
118
|
+
defaultMonth,
|
|
119
|
+
today,
|
|
120
|
+
numberOfMonths
|
|
121
|
+
},
|
|
122
|
+
dateLib
|
|
123
|
+
);
|
|
124
|
+
setFirstMonth(initialDisplayMonth);
|
|
125
|
+
}, [
|
|
126
|
+
dateLib,
|
|
127
|
+
defaultMonth,
|
|
128
|
+
endMonth,
|
|
129
|
+
fromYear,
|
|
130
|
+
month,
|
|
131
|
+
numberOfMonths,
|
|
132
|
+
startMonth,
|
|
133
|
+
toYear,
|
|
134
|
+
today
|
|
135
|
+
]);
|
|
79
136
|
|
|
80
137
|
/** The months displayed in the calendar. */
|
|
81
138
|
const displayMonths = getDisplayMonths(firstMonth, navEnd, props, dateLib);
|
package/src/useDayPicker.ts
CHANGED
|
@@ -6,7 +6,7 @@ import type { DayPickerProps } from "./types/props.js";
|
|
|
6
6
|
import type { SelectedValue, SelectHandler } from "./types/selection.js";
|
|
7
7
|
import { Modifiers } from "./types/shared.js";
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
/** @private */
|
|
10
10
|
export const dayPickerContext = createContext<
|
|
11
11
|
DayPickerContext<DayPickerProps> | undefined
|
|
12
12
|
>(undefined);
|
|
@@ -41,6 +41,27 @@ import { es } from "date-fns/locale";
|
|
|
41
41
|
<Examples.Spanish />
|
|
42
42
|
</BrowserWindow>
|
|
43
43
|
|
|
44
|
+
:::tip Customizing the Locale
|
|
45
|
+
|
|
46
|
+
You can customize the locale by passing an object with the desired translations. Use the `defaultLocale` object for the default translations.
|
|
47
|
+
|
|
48
|
+
```tsx
|
|
49
|
+
import { DayPicker, defaultLocale } from "react-day-picker";
|
|
50
|
+
|
|
51
|
+
<DayPicker
|
|
52
|
+
locale={{
|
|
53
|
+
localize: {
|
|
54
|
+
...defaultLocale.localize,
|
|
55
|
+
day: (day) => "custom-localized-day"
|
|
56
|
+
}
|
|
57
|
+
}}
|
|
58
|
+
month={new Date(2023, 0, 1)}
|
|
59
|
+
mode="single"
|
|
60
|
+
/>;
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
:::
|
|
64
|
+
|
|
44
65
|
## First Date of the Week
|
|
45
66
|
|
|
46
67
|
Use the `weekStartsOn` prop to specify the starting day of the week.
|