react-day-picker 9.0.1 → 9.0.2
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/selection/useRange.js +4 -2
- package/dist/cjs/selection/useRange.js.map +1 -1
- package/dist/cjs/types/props.d.ts +12 -0
- package/dist/esm/selection/useRange.js +4 -2
- package/dist/esm/selection/useRange.js.map +1 -1
- package/dist/esm/types/props.d.ts +12 -0
- package/examples/ModifiersDisabled.test.tsx +10 -3
- package/examples/ModifiersDisabled.tsx +1 -7
- package/examples/RangeExcludeDisabled.tsx +9 -0
- package/examples/index.ts +1 -0
- package/package.json +3 -3
- package/src/selection/useRange.test.tsx +114 -0
- package/src/selection/useRange.tsx +6 -1
- package/src/types/props.ts +12 -0
- package/website/docs/docs/selection-modes.mdx +24 -3
- package/website/docs/upgrading.mdx +13 -13
|
@@ -8,7 +8,7 @@ const react_1 = __importDefault(require("react"));
|
|
|
8
8
|
const index_js_1 = require("../utils/index.js");
|
|
9
9
|
const rangeIncludesDate_js_1 = require("../utils/rangeIncludesDate.js");
|
|
10
10
|
function useRange(props, dateLib) {
|
|
11
|
-
const { mode, disabled, selected: initiallySelected, required, onSelect } = props;
|
|
11
|
+
const { mode, disabled, excludeDisabled, selected: initiallySelected, required, onSelect } = props;
|
|
12
12
|
const { differenceInCalendarDays } = dateLib;
|
|
13
13
|
const [selected, setSelected] = react_1.default.useState(initiallySelected);
|
|
14
14
|
// Update the selected date if the required flag is set.
|
|
@@ -43,7 +43,9 @@ function useRange(props, dateLib) {
|
|
|
43
43
|
let newDate = newRange.from;
|
|
44
44
|
while (dateLib.differenceInCalendarDays(newRange.to, newDate) > 0) {
|
|
45
45
|
newDate = dateLib.addDays(newDate, 1);
|
|
46
|
-
if (
|
|
46
|
+
if (excludeDisabled &&
|
|
47
|
+
disabled &&
|
|
48
|
+
(0, index_js_1.dateMatchModifiers)(newDate, disabled, dateLib)) {
|
|
47
49
|
newRange.from = triggerDate;
|
|
48
50
|
newRange.to = undefined;
|
|
49
51
|
break;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useRange.js","sourceRoot":"","sources":["../../../src/selection/useRange.tsx"],"names":[],"mappings":";;;;;AAaA,
|
|
1
|
+
{"version":3,"file":"useRange.js","sourceRoot":"","sources":["../../../src/selection/useRange.tsx"],"names":[],"mappings":"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"}
|
|
@@ -492,6 +492,12 @@ export interface PropsRangeRequired {
|
|
|
492
492
|
mode: "range";
|
|
493
493
|
required: true;
|
|
494
494
|
disabled?: Matcher | Matcher[] | undefined;
|
|
495
|
+
/**
|
|
496
|
+
* When `true`, the range will reset when including a disabled day.
|
|
497
|
+
*
|
|
498
|
+
* @since V9.0.2
|
|
499
|
+
*/
|
|
500
|
+
excludeDisabled?: boolean | undefined;
|
|
495
501
|
/** The selected range. */
|
|
496
502
|
selected: DateRange;
|
|
497
503
|
/** Event handler when a range is selected. */
|
|
@@ -510,6 +516,12 @@ export interface PropsRange {
|
|
|
510
516
|
mode: "range";
|
|
511
517
|
required?: false | undefined;
|
|
512
518
|
disabled?: Matcher | Matcher[] | undefined;
|
|
519
|
+
/**
|
|
520
|
+
* When `true`, the range will reset when including a disabled day.
|
|
521
|
+
*
|
|
522
|
+
* @since V9.0.2
|
|
523
|
+
*/
|
|
524
|
+
excludeDisabled?: boolean | undefined;
|
|
513
525
|
/** The selected range. */
|
|
514
526
|
selected?: DateRange | undefined;
|
|
515
527
|
/** Event handler when the selection changes. */
|
|
@@ -2,7 +2,7 @@ import React from "react";
|
|
|
2
2
|
import { addToRange, dateMatchModifiers } from "../utils/index.js";
|
|
3
3
|
import { rangeIncludesDate } from "../utils/rangeIncludesDate.js";
|
|
4
4
|
export function useRange(props, dateLib) {
|
|
5
|
-
const { mode, disabled, selected: initiallySelected, required, onSelect } = props;
|
|
5
|
+
const { mode, disabled, excludeDisabled, selected: initiallySelected, required, onSelect } = props;
|
|
6
6
|
const { differenceInCalendarDays } = dateLib;
|
|
7
7
|
const [selected, setSelected] = React.useState(initiallySelected);
|
|
8
8
|
// Update the selected date if the required flag is set.
|
|
@@ -37,7 +37,9 @@ export function useRange(props, dateLib) {
|
|
|
37
37
|
let newDate = newRange.from;
|
|
38
38
|
while (dateLib.differenceInCalendarDays(newRange.to, newDate) > 0) {
|
|
39
39
|
newDate = dateLib.addDays(newDate, 1);
|
|
40
|
-
if (
|
|
40
|
+
if (excludeDisabled &&
|
|
41
|
+
disabled &&
|
|
42
|
+
dateMatchModifiers(newDate, disabled, dateLib)) {
|
|
41
43
|
newRange.from = triggerDate;
|
|
42
44
|
newRange.to = undefined;
|
|
43
45
|
break;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useRange.js","sourceRoot":"","sources":["../../../src/selection/useRange.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAU1B,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAElE,MAAM,UAAU,QAAQ,CACtB,KAAQ,EACR,OAAgB;IAEhB,MAAM,EACJ,IAAI,EACJ,QAAQ,EACR,QAAQ,EAAE,iBAAiB,EAC3B,QAAQ,EACR,QAAQ,EACT,GAAG,KAAmB,CAAC;IAExB,MAAM,EAAE,wBAAwB,EAAE,GAAG,OAAO,CAAC;IAC7C,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,KAAK,CAAC,QAAQ,CAC5C,iBAAiB,CAClB,CAAC;IAEF,wDAAwD;IACxD,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,IAAI,QAAQ,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YACvC,WAAW,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;QAClD,CAAC;IACH,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC;IAE/B,MAAM,UAAU,GAAG,CAAC,IAAU,EAAE,EAAE,CAChC,QAAQ,IAAI,iBAAiB,CAAC,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;IAEhE,MAAM,MAAM,GAAG,CACb,WAAiB,EACjB,SAAoB,EACpB,CAAyC,EACzC,EAAE;QACF,MAAM,QAAQ,GAAG,WAAW;YAC1B,CAAC,CAAC,UAAU,CAAC,WAAW,EAAE,QAAQ,EAAE,OAAO,CAAC;YAC5C,CAAC,CAAC,SAAS,CAAC;QACd,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,KAAmB,CAAC;QAEzC,IAAI,GAAG,EAAE,CAAC;YACR,IACE,QAAQ,EAAE,IAAI;gBACd,QAAQ,CAAC,EAAE;gBACX,wBAAwB,CAAC,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC,EAC9D,CAAC;gBACD,QAAQ,CAAC,IAAI,GAAG,WAAW,CAAC;gBAC5B,QAAQ,CAAC,EAAE,GAAG,SAAS,CAAC;YAC1B,CAAC;QACH,CAAC;QAED,IAAI,GAAG,EAAE,CAAC;YACR,IACE,QAAQ,EAAE,IAAI;gBACd,QAAQ,CAAC,EAAE;gBACX,wBAAwB,CAAC,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,GAAG,EAC3D,CAAC;gBACD,QAAQ,CAAC,IAAI,GAAG,WAAW,CAAC;gBAC5B,QAAQ,CAAC,EAAE,GAAG,SAAS,CAAC;YAC1B,CAAC;QACH,CAAC;QAED,IAAI,QAAQ,EAAE,IAAI,IAAI,QAAQ,CAAC,EAAE,EAAE,CAAC;YAClC,IAAI,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC;YAC5B,OAAO,OAAO,CAAC,wBAAwB,CAAC,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;gBAClE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;gBACtC,
|
|
1
|
+
{"version":3,"file":"useRange.js","sourceRoot":"","sources":["../../../src/selection/useRange.tsx"],"names":[],"mappings":"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"}
|
|
@@ -492,6 +492,12 @@ export interface PropsRangeRequired {
|
|
|
492
492
|
mode: "range";
|
|
493
493
|
required: true;
|
|
494
494
|
disabled?: Matcher | Matcher[] | undefined;
|
|
495
|
+
/**
|
|
496
|
+
* When `true`, the range will reset when including a disabled day.
|
|
497
|
+
*
|
|
498
|
+
* @since V9.0.2
|
|
499
|
+
*/
|
|
500
|
+
excludeDisabled?: boolean | undefined;
|
|
495
501
|
/** The selected range. */
|
|
496
502
|
selected: DateRange;
|
|
497
503
|
/** Event handler when a range is selected. */
|
|
@@ -510,6 +516,12 @@ export interface PropsRange {
|
|
|
510
516
|
mode: "range";
|
|
511
517
|
required?: false | undefined;
|
|
512
518
|
disabled?: Matcher | Matcher[] | undefined;
|
|
519
|
+
/**
|
|
520
|
+
* When `true`, the range will reset when including a disabled day.
|
|
521
|
+
*
|
|
522
|
+
* @since V9.0.2
|
|
523
|
+
*/
|
|
524
|
+
excludeDisabled?: boolean | undefined;
|
|
513
525
|
/** The selected range. */
|
|
514
526
|
selected?: DateRange | undefined;
|
|
515
527
|
/** Event handler when the selection changes. */
|
|
@@ -5,13 +5,20 @@ import { render } from "@/test/render";
|
|
|
5
5
|
|
|
6
6
|
import { ModifiersDisabled } from "./ModifiersDisabled";
|
|
7
7
|
|
|
8
|
+
const today = new Date(2024, 6, 22);
|
|
9
|
+
|
|
10
|
+
beforeAll(() => jest.setSystemTime(today));
|
|
11
|
+
afterAll(() => jest.useRealTimers());
|
|
12
|
+
|
|
8
13
|
const days = [
|
|
9
|
-
new Date(2024,
|
|
10
|
-
new Date(2024,
|
|
11
|
-
new Date(2024,
|
|
14
|
+
new Date(2024, 6, 6),
|
|
15
|
+
new Date(2024, 6, 13),
|
|
16
|
+
new Date(2024, 6, 20),
|
|
17
|
+
new Date(2024, 6, 27)
|
|
12
18
|
];
|
|
13
19
|
|
|
14
20
|
test.each(days)("the day %s should be disabled", (day) => {
|
|
15
21
|
render(<ModifiersDisabled />);
|
|
22
|
+
// return all month's
|
|
16
23
|
expect(dateButton(day)).toBeDisabled();
|
|
17
24
|
});
|
|
@@ -3,11 +3,5 @@ import React from "react";
|
|
|
3
3
|
import { DayPicker } from "react-day-picker";
|
|
4
4
|
|
|
5
5
|
export function ModifiersDisabled() {
|
|
6
|
-
return
|
|
7
|
-
<DayPicker
|
|
8
|
-
defaultMonth={new Date(2024, 5, 10)}
|
|
9
|
-
mode="range"
|
|
10
|
-
disabled={{ dayOfWeek: [0, 6] }}
|
|
11
|
-
/>
|
|
12
|
-
);
|
|
6
|
+
return <DayPicker mode="range" disabled={{ dayOfWeek: [0, 6] }} />;
|
|
13
7
|
}
|
package/examples/index.ts
CHANGED
|
@@ -43,6 +43,7 @@ export * from "./MultipleMonthsPaged";
|
|
|
43
43
|
export * from "./NumberingSystem";
|
|
44
44
|
export * from "./OutsideDays";
|
|
45
45
|
export * from "./Range";
|
|
46
|
+
export * from "./RangeExcludeDisabled";
|
|
46
47
|
export * from "./RangeMinMax";
|
|
47
48
|
export * from "./RangeShiftKey";
|
|
48
49
|
export * from "./Rtl";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-day-picker",
|
|
3
|
-
"version": "9.0.
|
|
3
|
+
"version": "9.0.2",
|
|
4
4
|
"description": "Customizable Date Picker for React",
|
|
5
5
|
"author": "Giampaolo Bellavite <io@gpbl.dev>",
|
|
6
6
|
"homepage": "https://daypicker.dev",
|
|
@@ -135,7 +135,7 @@
|
|
|
135
135
|
"devDependencies": {
|
|
136
136
|
"@date-fns/utc": "^1.2.0",
|
|
137
137
|
"@jest/types": "^29.6.3",
|
|
138
|
-
"@testing-library/dom": "^10.
|
|
138
|
+
"@testing-library/dom": "^10.4.0",
|
|
139
139
|
"@testing-library/jest-dom": "^6.4.5",
|
|
140
140
|
"@testing-library/react": "^16.0.0",
|
|
141
141
|
"@testing-library/user-event": "^14.5.2",
|
|
@@ -154,7 +154,7 @@
|
|
|
154
154
|
"eslint-plugin-import": "^2.29.1",
|
|
155
155
|
"eslint-plugin-jest": "^28.6.0",
|
|
156
156
|
"eslint-plugin-prettier": "^5.1.3",
|
|
157
|
-
"eslint-plugin-react": "^7.
|
|
157
|
+
"eslint-plugin-react": "^7.35.0",
|
|
158
158
|
"eslint-plugin-react-hooks": "^4.6.2",
|
|
159
159
|
"eslint-plugin-require-extensions": "^0.1.3",
|
|
160
160
|
"eslint-plugin-testing-library": "^6.2.2",
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import { act, renderHook } from "@/test/render";
|
|
3
|
+
|
|
4
|
+
import { dateLib } from "../lib";
|
|
5
|
+
|
|
6
|
+
import { useRange } from "./useRange";
|
|
7
|
+
|
|
8
|
+
describe("useRange", () => {
|
|
9
|
+
test("initialize with initiallySelected date range", () => {
|
|
10
|
+
const initiallySelected = {
|
|
11
|
+
from: new Date(2023, 6, 1),
|
|
12
|
+
to: new Date(2023, 6, 5)
|
|
13
|
+
};
|
|
14
|
+
const { result } = renderHook(() =>
|
|
15
|
+
useRange(
|
|
16
|
+
{ mode: "range", selected: initiallySelected, required: false },
|
|
17
|
+
dateLib
|
|
18
|
+
)
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
expect(result.current.selected).toEqual(initiallySelected);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test("update the selected range on select", () => {
|
|
25
|
+
const initiallySelected = {
|
|
26
|
+
from: new Date(2023, 6, 1),
|
|
27
|
+
to: new Date(2023, 6, 5)
|
|
28
|
+
};
|
|
29
|
+
const { result } = renderHook(() =>
|
|
30
|
+
useRange(
|
|
31
|
+
{ mode: "range", selected: initiallySelected, required: false },
|
|
32
|
+
dateLib
|
|
33
|
+
)
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
act(() => {
|
|
37
|
+
result.current.select?.(new Date(2023, 6, 10), {}, {} as any);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
expect(result.current.selected).toEqual({
|
|
41
|
+
from: new Date(2023, 6, 1),
|
|
42
|
+
to: new Date(2023, 6, 10)
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test("reset range if new range exceeds max days", () => {
|
|
47
|
+
const { result } = renderHook(() =>
|
|
48
|
+
useRange(
|
|
49
|
+
{
|
|
50
|
+
mode: "range",
|
|
51
|
+
selected: undefined,
|
|
52
|
+
required: false,
|
|
53
|
+
max: 5
|
|
54
|
+
},
|
|
55
|
+
dateLib
|
|
56
|
+
)
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
act(() => {
|
|
60
|
+
result.current.select?.(new Date(2023, 6, 1), {}, {} as any);
|
|
61
|
+
result.current.select?.(new Date(2023, 6, 10), {}, {} as any);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
expect(result.current.selected).toEqual({
|
|
65
|
+
from: new Date(2023, 6, 10),
|
|
66
|
+
to: undefined
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
test("reset range if new range is less than min days", () => {
|
|
71
|
+
const { result } = renderHook(() =>
|
|
72
|
+
useRange(
|
|
73
|
+
{ mode: "range", selected: undefined, required: false, min: 5 },
|
|
74
|
+
dateLib
|
|
75
|
+
)
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
act(() => {
|
|
79
|
+
result.current.select?.(new Date(2023, 6, 1), {}, {} as any);
|
|
80
|
+
result.current.select?.(new Date(2023, 6, 3), {}, {} as any);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
expect(result.current.selected).toEqual({
|
|
84
|
+
from: new Date(2023, 6, 3),
|
|
85
|
+
to: undefined
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
test("exclude disabled dates when selecting range", () => {
|
|
90
|
+
const disabled = [{ from: new Date(2023, 6, 5), to: new Date(2023, 6, 7) }];
|
|
91
|
+
const { result } = renderHook(() =>
|
|
92
|
+
useRange(
|
|
93
|
+
{
|
|
94
|
+
mode: "range",
|
|
95
|
+
selected: undefined,
|
|
96
|
+
required: false,
|
|
97
|
+
excludeDisabled: true,
|
|
98
|
+
disabled
|
|
99
|
+
},
|
|
100
|
+
dateLib
|
|
101
|
+
)
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
act(() => {
|
|
105
|
+
result.current.select?.(new Date(2023, 6, 1), {}, {} as any);
|
|
106
|
+
result.current.select?.(new Date(2023, 6, 10), {}, {} as any);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
expect(result.current.selected).toEqual({
|
|
110
|
+
from: new Date(2023, 6, 10),
|
|
111
|
+
to: undefined
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
});
|
|
@@ -18,6 +18,7 @@ export function useRange<T extends DayPickerProps>(
|
|
|
18
18
|
const {
|
|
19
19
|
mode,
|
|
20
20
|
disabled,
|
|
21
|
+
excludeDisabled,
|
|
21
22
|
selected: initiallySelected,
|
|
22
23
|
required,
|
|
23
24
|
onSelect
|
|
@@ -74,7 +75,11 @@ export function useRange<T extends DayPickerProps>(
|
|
|
74
75
|
let newDate = newRange.from;
|
|
75
76
|
while (dateLib.differenceInCalendarDays(newRange.to, newDate) > 0) {
|
|
76
77
|
newDate = dateLib.addDays(newDate, 1);
|
|
77
|
-
if (
|
|
78
|
+
if (
|
|
79
|
+
excludeDisabled &&
|
|
80
|
+
disabled &&
|
|
81
|
+
dateMatchModifiers(newDate, disabled, dateLib)
|
|
82
|
+
) {
|
|
78
83
|
newRange.from = triggerDate;
|
|
79
84
|
newRange.to = undefined;
|
|
80
85
|
break;
|
package/src/types/props.ts
CHANGED
|
@@ -546,6 +546,12 @@ export interface PropsRangeRequired {
|
|
|
546
546
|
mode: "range";
|
|
547
547
|
required: true;
|
|
548
548
|
disabled?: Matcher | Matcher[] | undefined;
|
|
549
|
+
/**
|
|
550
|
+
* When `true`, the range will reset when including a disabled day.
|
|
551
|
+
*
|
|
552
|
+
* @since V9.0.2
|
|
553
|
+
*/
|
|
554
|
+
excludeDisabled?: boolean | undefined;
|
|
549
555
|
/** The selected range. */
|
|
550
556
|
selected: DateRange;
|
|
551
557
|
/** Event handler when a range is selected. */
|
|
@@ -569,6 +575,12 @@ export interface PropsRange {
|
|
|
569
575
|
mode: "range";
|
|
570
576
|
required?: false | undefined;
|
|
571
577
|
disabled?: Matcher | Matcher[] | undefined;
|
|
578
|
+
/**
|
|
579
|
+
* When `true`, the range will reset when including a disabled day.
|
|
580
|
+
*
|
|
581
|
+
* @since V9.0.2
|
|
582
|
+
*/
|
|
583
|
+
excludeDisabled?: boolean | undefined;
|
|
572
584
|
/** The selected range. */
|
|
573
585
|
selected?: DateRange | undefined;
|
|
574
586
|
/** Event handler when the selection changes. */
|
|
@@ -194,17 +194,38 @@ export function RangeMinMax() {
|
|
|
194
194
|
|
|
195
195
|
## Disabling Dates
|
|
196
196
|
|
|
197
|
-
To disable specific days, use the `disabled` prop.
|
|
197
|
+
To disable specific days, use the `disabled` prop. Disabled dates cannot be selected.
|
|
198
|
+
|
|
199
|
+
The prop accepts a [`Matcher`](../api/type-aliases/Matcher.md) or an array of matchers that can be used to make some days not selectable.
|
|
200
|
+
|
|
201
|
+
```tsx
|
|
202
|
+
// disable today
|
|
203
|
+
<DayPicker mode="single" disabled={ new Date() } />
|
|
204
|
+
|
|
205
|
+
// disable weekends
|
|
206
|
+
<DayPicker mode="range" disabled={{ dayOfWeek: [0, 6] }} />
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
<BrowserWindow>
|
|
210
|
+
<Examples.ModifiersDisabled />
|
|
211
|
+
</BrowserWindow>
|
|
212
|
+
|
|
213
|
+
### Excluding Disabled Dates from Range {#exclude-disabled}
|
|
214
|
+
|
|
215
|
+
When using the `range` mode, disabled dates will be included in the selected range. Use the `excludeDisabled` prop to prevent this behavior. The range will reset when a disabled date is included.
|
|
198
216
|
|
|
199
217
|
```tsx
|
|
200
218
|
<DayPicker
|
|
201
219
|
mode="range"
|
|
202
|
-
|
|
220
|
+
// Disable weekends
|
|
221
|
+
disabled={{ dayOfWeek: [0, 6] }}
|
|
222
|
+
// Reset range when a disabled date is included
|
|
223
|
+
excludeDisabled
|
|
203
224
|
/>
|
|
204
225
|
```
|
|
205
226
|
|
|
206
227
|
<BrowserWindow>
|
|
207
|
-
<Examples.
|
|
228
|
+
<Examples.RangeExcludeDisabled />
|
|
208
229
|
</BrowserWindow>
|
|
209
230
|
|
|
210
231
|
## Customizing Selections
|
|
@@ -35,9 +35,9 @@ The default design is slightly changed, so you may need to adjust DayPicker agai
|
|
|
35
35
|
|
|
36
36
|
### 3. Update the class names
|
|
37
37
|
|
|
38
|
-
This version updates the name of the [UI elements](./api/enumerations/UI.md) to be more clear and consistent, so the class names have changed.
|
|
38
|
+
This version updates the name of the [UI elements](./api/enumerations/UI.md) to be more clear and consistent, so the class names have changed.
|
|
39
39
|
|
|
40
|
-
If you are using custom styles via `classNames` or `styles` prop, you
|
|
40
|
+
If you are using custom styles via `classNames` or `styles` prop, you will need to update some of them.
|
|
41
41
|
|
|
42
42
|
For example, `day_disabled` is now `disabled`:
|
|
43
43
|
|
|
@@ -213,17 +213,17 @@ In case you are using the `components` prop, you may need to update your code, a
|
|
|
213
213
|
<details>
|
|
214
214
|
<summary>**List of Updated Components**</summary>
|
|
215
215
|
|
|
216
|
-
| Components | Changes
|
|
217
|
-
| -------------- |
|
|
218
|
-
| `Caption` | Renamed to [`MonthCaption`](./api/functions/MonthCaption.md).
|
|
219
|
-
| `Day` | Now it renders a [`DayButton`](./api/functions/DayButton.md).
|
|
220
|
-
| `DayContent` | Removed. Change its content with [`
|
|
221
|
-
| `Head` | Removed.
|
|
222
|
-
| `HeadRow` | Renamed to [`
|
|
223
|
-
| `IconDropdown` | Removed. The icon is rendered by [`Chevron`](./api/functions/Chevron.md).
|
|
224
|
-
| `IconLeft` | Removed. The icon is rendered by [`Chevron`](./api/functions/Chevron.md).
|
|
225
|
-
| `IconRight` | Removed. The icon is rendered by [`Chevron`](./api/functions/Chevron.md).
|
|
226
|
-
| `Row` | Renamed to [`Week`](./api/functions/Week.md).
|
|
216
|
+
| Components | Changes |
|
|
217
|
+
| -------------- | --------------------------------------------------------------------------------------- |
|
|
218
|
+
| `Caption` | Renamed to [`MonthCaption`](./api/functions/MonthCaption.md). |
|
|
219
|
+
| `Day` | Now it renders a [`DayButton`](./api/functions/DayButton.md). |
|
|
220
|
+
| `DayContent` | Removed. Change its content with [`labelDayButton`](./api/functions/labelDayButton.md). |
|
|
221
|
+
| `Head` | Removed. |
|
|
222
|
+
| `HeadRow` | Renamed to [`Weekdays`](./api/functions/Weekdays.md). |
|
|
223
|
+
| `IconDropdown` | Removed. The icon is rendered by [`Chevron`](./api/functions/Chevron.md). |
|
|
224
|
+
| `IconLeft` | Removed. The icon is rendered by [`Chevron`](./api/functions/Chevron.md). |
|
|
225
|
+
| `IconRight` | Removed. The icon is rendered by [`Chevron`](./api/functions/Chevron.md). |
|
|
226
|
+
| `Row` | Renamed to [`Week`](./api/functions/Week.md). |
|
|
227
227
|
|
|
228
228
|
</details>
|
|
229
229
|
|