react-day-picker 8.3.0 → 8.3.1
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/index.d.ts +4 -9
- package/dist/index.esm.d.ts +4 -9
- package/dist/index.esm.js +1472 -1450
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +1485 -1463
- package/dist/index.js.map +1 -1
- package/dist/react-day-picker.min.js +1 -1
- package/package.json +2 -2
- package/src/components/Caption/Caption.tsx +8 -8
- package/src/components/CaptionDropdowns/CaptionDropdowns.tsx +4 -6
- package/src/components/CaptionNavigation/CaptionNavigation.tsx +8 -6
- package/src/components/Dropdown/Dropdown.tsx +5 -5
- package/src/components/Head/Head.tsx +4 -6
- package/src/components/Month/Month.tsx +5 -7
- package/src/components/MonthsDropdown/MonthsDropdown.tsx +6 -3
- package/src/components/Navigation/Navigation.tsx +15 -5
- package/src/components/Row/Row.tsx +8 -8
- package/src/components/Table/Table.test.tsx +19 -3
- package/src/components/Table/Table.tsx +10 -4
- package/src/components/Table/__snapshots__/Table.test.tsx.snap +39 -21
- package/src/components/YearsDropdown/YearsDropdown.tsx +6 -3
- package/src/contexts/DayPicker/DayPickerContext.tsx +1 -7
- package/src/contexts/DayPicker/defaultContextValues.ts +1 -32
- package/src/contexts/Modifiers/utils/isMatch.test.ts +24 -5
- package/src/contexts/Modifiers/utils/isMatch.ts +11 -3
- package/src/contexts/Navigation/NavigationContext.test.ts +5 -3
- package/src/contexts/Navigation/useNavigationState.test.ts +4 -1
- package/src/hooks/useDayRender/useDayRender.tsx +4 -5
- package/src/types/DayPickerBase.ts +0 -5
- package/src/types/DayPickerDefault.ts +2 -2
- package/src/types/Matchers.ts +1 -1
|
@@ -960,30 +960,48 @@ exports[`when using custom components should render correctly 1`] = `
|
|
|
960
960
|
class="rdp-table"
|
|
961
961
|
role="grid"
|
|
962
962
|
>
|
|
963
|
-
<
|
|
964
|
-
|
|
965
|
-
|
|
963
|
+
<thead>
|
|
964
|
+
<tr>
|
|
965
|
+
<td>
|
|
966
|
+
CustomHead
|
|
967
|
+
</td>
|
|
968
|
+
</tr>
|
|
969
|
+
</thead>
|
|
966
970
|
<tbody
|
|
967
971
|
class="rdp-tbody"
|
|
968
972
|
>
|
|
969
|
-
<
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
</
|
|
973
|
+
<tr>
|
|
974
|
+
<td>
|
|
975
|
+
CustomRow
|
|
976
|
+
</td>
|
|
977
|
+
</tr>
|
|
978
|
+
<tr>
|
|
979
|
+
<td>
|
|
980
|
+
CustomRow
|
|
981
|
+
</td>
|
|
982
|
+
</tr>
|
|
983
|
+
<tr>
|
|
984
|
+
<td>
|
|
985
|
+
CustomRow
|
|
986
|
+
</td>
|
|
987
|
+
</tr>
|
|
988
|
+
<tr>
|
|
989
|
+
<td>
|
|
990
|
+
CustomRow
|
|
991
|
+
</td>
|
|
992
|
+
</tr>
|
|
993
|
+
<tr>
|
|
994
|
+
<td>
|
|
995
|
+
CustomRow
|
|
996
|
+
</td>
|
|
997
|
+
</tr>
|
|
984
998
|
</tbody>
|
|
985
|
-
<
|
|
986
|
-
|
|
987
|
-
|
|
999
|
+
<tfoot>
|
|
1000
|
+
<tr>
|
|
1001
|
+
<td>
|
|
1002
|
+
CustomFooter
|
|
1003
|
+
</td>
|
|
1004
|
+
</tr>
|
|
1005
|
+
</tfoot>
|
|
988
1006
|
</table>
|
|
989
1007
|
`;
|
|
@@ -4,6 +4,7 @@ import setYear from 'date-fns/setYear';
|
|
|
4
4
|
import startOfMonth from 'date-fns/startOfMonth';
|
|
5
5
|
import startOfYear from 'date-fns/startOfYear';
|
|
6
6
|
|
|
7
|
+
import { Dropdown } from 'components/Dropdown';
|
|
7
8
|
import { useDayPicker } from 'contexts/DayPicker';
|
|
8
9
|
import { MonthChangeEventHandler } from 'types/EventHandlers';
|
|
9
10
|
|
|
@@ -29,7 +30,7 @@ export function YearsDropdown(props: YearsDropdownProps): JSX.Element {
|
|
|
29
30
|
locale,
|
|
30
31
|
styles,
|
|
31
32
|
classNames,
|
|
32
|
-
components
|
|
33
|
+
components,
|
|
33
34
|
formatters: { formatYearCaption },
|
|
34
35
|
labels: { labelYearDropdown }
|
|
35
36
|
} = useDayPicker();
|
|
@@ -54,8 +55,10 @@ export function YearsDropdown(props: YearsDropdownProps): JSX.Element {
|
|
|
54
55
|
props.onChange(newMonth);
|
|
55
56
|
};
|
|
56
57
|
|
|
58
|
+
const DropdownComponent = components?.Dropdown ?? Dropdown;
|
|
59
|
+
|
|
57
60
|
return (
|
|
58
|
-
<
|
|
61
|
+
<DropdownComponent
|
|
59
62
|
name="years"
|
|
60
63
|
aria-label={labelYearDropdown()}
|
|
61
64
|
className={classNames.dropdown_year}
|
|
@@ -69,6 +72,6 @@ export function YearsDropdown(props: YearsDropdownProps): JSX.Element {
|
|
|
69
72
|
{formatYearCaption(year, { locale })}
|
|
70
73
|
</option>
|
|
71
74
|
))}
|
|
72
|
-
</
|
|
75
|
+
</DropdownComponent>
|
|
73
76
|
);
|
|
74
77
|
}
|
|
@@ -3,11 +3,7 @@ import React, { createContext, ReactNode, useContext } from 'react';
|
|
|
3
3
|
import { DayPickerProps } from 'DayPicker';
|
|
4
4
|
|
|
5
5
|
import { CaptionLayout } from 'components/Caption';
|
|
6
|
-
import {
|
|
7
|
-
Components,
|
|
8
|
-
DayPickerBase,
|
|
9
|
-
DaySelectionMode
|
|
10
|
-
} from 'types/DayPickerBase';
|
|
6
|
+
import { DayPickerBase, DaySelectionMode } from 'types/DayPickerBase';
|
|
11
7
|
import {
|
|
12
8
|
DayPickerMultipleProps,
|
|
13
9
|
isDayPickerMultiple
|
|
@@ -39,7 +35,6 @@ export interface DayPickerContextValue extends DayPickerBase {
|
|
|
39
35
|
selected?: Matcher | Matcher[];
|
|
40
36
|
|
|
41
37
|
captionLayout: CaptionLayout;
|
|
42
|
-
components: Components;
|
|
43
38
|
classNames: Required<ClassNames>;
|
|
44
39
|
formatters: Formatters;
|
|
45
40
|
labels: Labels;
|
|
@@ -104,7 +99,6 @@ export function DayPickerProvider(props: DayPickerProviderProps): JSX.Element {
|
|
|
104
99
|
...initialProps.classNames
|
|
105
100
|
},
|
|
106
101
|
components: {
|
|
107
|
-
...defaultContextValues.components,
|
|
108
102
|
...initialProps.components
|
|
109
103
|
},
|
|
110
104
|
formatters: {
|
|
@@ -1,20 +1,7 @@
|
|
|
1
1
|
import enUS from 'date-fns/locale/en-US';
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import { CaptionLabel } from 'components/CaptionLabel';
|
|
5
|
-
import { Day } from 'components/Day';
|
|
6
|
-
import { DayContent } from 'components/DayContent';
|
|
7
|
-
import { Dropdown } from 'components/Dropdown';
|
|
8
|
-
import { Footer } from 'components/Footer';
|
|
9
|
-
import { Head } from 'components/Head';
|
|
10
|
-
import { HeadRow } from 'components/HeadRow';
|
|
11
|
-
import { IconDropdown } from 'components/IconDropdown';
|
|
12
|
-
import { IconLeft } from 'components/IconLeft';
|
|
13
|
-
import { IconRight } from 'components/IconRight';
|
|
14
|
-
import { Row } from 'components/Row';
|
|
15
|
-
import { WeekNumber } from 'components/WeekNumber';
|
|
3
|
+
import { CaptionLayout } from 'components/Caption';
|
|
16
4
|
import { DayPickerContextValue } from 'contexts/DayPicker';
|
|
17
|
-
import { Components } from 'types/DayPickerBase';
|
|
18
5
|
|
|
19
6
|
import { defaultClassNames } from './defaultClassNames';
|
|
20
7
|
import * as formatters from './formatters';
|
|
@@ -23,7 +10,6 @@ import * as labels from './labels';
|
|
|
23
10
|
export type DefaultContextProps =
|
|
24
11
|
| 'captionLayout'
|
|
25
12
|
| 'classNames'
|
|
26
|
-
| 'components'
|
|
27
13
|
| 'formatters'
|
|
28
14
|
| 'locale'
|
|
29
15
|
| 'labels'
|
|
@@ -52,26 +38,9 @@ export function getDefaultContextValues(): DefaultContextValues {
|
|
|
52
38
|
const styles = {};
|
|
53
39
|
const today = new Date();
|
|
54
40
|
|
|
55
|
-
const components: Components = {
|
|
56
|
-
Caption,
|
|
57
|
-
CaptionLabel,
|
|
58
|
-
Day,
|
|
59
|
-
DayContent,
|
|
60
|
-
Dropdown,
|
|
61
|
-
Footer,
|
|
62
|
-
Head,
|
|
63
|
-
HeadRow,
|
|
64
|
-
IconDropdown,
|
|
65
|
-
IconRight,
|
|
66
|
-
IconLeft,
|
|
67
|
-
Row,
|
|
68
|
-
WeekNumber
|
|
69
|
-
};
|
|
70
|
-
|
|
71
41
|
return {
|
|
72
42
|
captionLayout,
|
|
73
43
|
classNames,
|
|
74
|
-
components,
|
|
75
44
|
formatters,
|
|
76
45
|
labels,
|
|
77
46
|
locale,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { addDays } from 'date-fns';
|
|
1
|
+
import { addDays, subDays } from 'date-fns';
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
DateAfter,
|
|
@@ -56,13 +56,32 @@ describe('when matching the day of week', () => {
|
|
|
56
56
|
});
|
|
57
57
|
});
|
|
58
58
|
|
|
59
|
-
describe('when matching date interval', () => {
|
|
59
|
+
describe('when matching date interval (closed)', () => {
|
|
60
60
|
const matcher: DateInterval = {
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
before: addDays(testDay, 5),
|
|
62
|
+
after: subDays(testDay, 3)
|
|
63
63
|
};
|
|
64
64
|
const result = isMatch(testDay, [matcher]);
|
|
65
|
-
test('should return true', () => {
|
|
65
|
+
test('should return true for the included day', () => {
|
|
66
|
+
expect(result).toBe(true);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
describe('when matching date interval (open)', () => {
|
|
71
|
+
const matcher: DateInterval = {
|
|
72
|
+
before: subDays(testDay, 4),
|
|
73
|
+
after: addDays(testDay, 5)
|
|
74
|
+
};
|
|
75
|
+
test('should return false', () => {
|
|
76
|
+
const result = isMatch(testDay, [matcher]);
|
|
77
|
+
expect(result).toBe(false);
|
|
78
|
+
});
|
|
79
|
+
test('should return true for the days before', () => {
|
|
80
|
+
const result = isMatch(subDays(testDay, 8), [matcher]);
|
|
81
|
+
expect(result).toBe(true);
|
|
82
|
+
});
|
|
83
|
+
test('should return true for the days after', () => {
|
|
84
|
+
const result = isMatch(addDays(testDay, 8), [matcher]);
|
|
66
85
|
expect(result).toBe(true);
|
|
67
86
|
});
|
|
68
87
|
});
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isAfter } from 'date-fns';
|
|
1
2
|
import differenceInCalendarDays from 'date-fns/differenceInCalendarDays';
|
|
2
3
|
import isDate from 'date-fns/isDate';
|
|
3
4
|
import isSameDay from 'date-fns/isSameDay';
|
|
@@ -58,9 +59,16 @@ export function isMatch(day: Date, matchers: Matcher[]): boolean {
|
|
|
58
59
|
return matcher.dayOfWeek.includes(day.getDay());
|
|
59
60
|
}
|
|
60
61
|
if (isDateInterval(matcher)) {
|
|
61
|
-
const
|
|
62
|
-
const
|
|
63
|
-
|
|
62
|
+
const diffBefore = differenceInCalendarDays(matcher.before, day);
|
|
63
|
+
const diffAfter = differenceInCalendarDays(matcher.after, day);
|
|
64
|
+
const isDayBefore = diffBefore > 0;
|
|
65
|
+
const isDayAfter = diffAfter < 0;
|
|
66
|
+
const isClosedInterval = isAfter(matcher.before, matcher.after);
|
|
67
|
+
if (isClosedInterval) {
|
|
68
|
+
return isDayAfter && isDayBefore;
|
|
69
|
+
} else {
|
|
70
|
+
return isDayBefore || isDayAfter;
|
|
71
|
+
}
|
|
64
72
|
}
|
|
65
73
|
if (isDateAfterType(matcher)) {
|
|
66
74
|
return differenceInCalendarDays(day, matcher.after) > 0;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RenderResult } from '@testing-library/react-hooks';
|
|
1
|
+
import { act, RenderResult } from '@testing-library/react-hooks';
|
|
2
2
|
import { addMonths, startOfMonth, subMonths } from 'date-fns';
|
|
3
3
|
|
|
4
4
|
import { customRenderHook } from 'test/render/customRenderHook';
|
|
@@ -39,7 +39,9 @@ describe('when rendered', () => {
|
|
|
39
39
|
describe('when goToMonth is called', () => {
|
|
40
40
|
const newMonth = addMonths(todaysMonth, 10);
|
|
41
41
|
beforeEach(() => {
|
|
42
|
-
|
|
42
|
+
act(() => {
|
|
43
|
+
result.current.goToMonth(newMonth);
|
|
44
|
+
});
|
|
43
45
|
});
|
|
44
46
|
test('should go to the specified month', () => {
|
|
45
47
|
expect(result.current.currentMonth).toEqual(newMonth);
|
|
@@ -59,7 +61,7 @@ describe('when rendered', () => {
|
|
|
59
61
|
const onMonthChange = jest.fn();
|
|
60
62
|
beforeEach(() => {
|
|
61
63
|
setup({ onMonthChange });
|
|
62
|
-
result.current.goToDate(newDate);
|
|
64
|
+
act(() => result.current.goToDate(newDate));
|
|
63
65
|
});
|
|
64
66
|
test('should go to the specified month', () => {
|
|
65
67
|
const date = startOfMonth(newDate);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { act } from '@testing-library/react-hooks';
|
|
1
2
|
import { addMonths, startOfMonth } from 'date-fns';
|
|
2
3
|
|
|
3
4
|
import { customRenderHook } from 'test/render/customRenderHook';
|
|
@@ -23,7 +24,9 @@ describe('when goToMonth is called', () => {
|
|
|
23
24
|
const onMonthChange = jest.fn();
|
|
24
25
|
const result = setup({ onMonthChange });
|
|
25
26
|
const month = addMonths(today, 2);
|
|
26
|
-
|
|
27
|
+
act(() => {
|
|
28
|
+
result.current[1](month);
|
|
29
|
+
});
|
|
27
30
|
expect(result.current[0]).toEqual(startOfMonth(month));
|
|
28
31
|
expect(onMonthChange).toBeCalledWith(startOfMonth(month));
|
|
29
32
|
});
|
|
@@ -3,6 +3,7 @@ import React, { useEffect } from 'react';
|
|
|
3
3
|
import isSameDay from 'date-fns/isSameDay';
|
|
4
4
|
|
|
5
5
|
import { ButtonProps } from 'components/Button';
|
|
6
|
+
import { DayContent } from 'components/DayContent';
|
|
6
7
|
import { useDayPicker } from 'contexts/DayPicker';
|
|
7
8
|
import { useFocusContext } from 'contexts/Focus';
|
|
8
9
|
import { useActiveModifiers } from 'hooks/useActiveModifiers';
|
|
@@ -47,10 +48,7 @@ export function useDayRender(
|
|
|
47
48
|
/** A ref to the button element that will be target of focus when rendered (if required). */
|
|
48
49
|
buttonRef: React.RefObject<HTMLButtonElement>
|
|
49
50
|
): DayRender {
|
|
50
|
-
const
|
|
51
|
-
components: { DayContent },
|
|
52
|
-
...dayPicker
|
|
53
|
-
} = useDayPicker();
|
|
51
|
+
const dayPicker = useDayPicker();
|
|
54
52
|
const focusContext = useFocusContext();
|
|
55
53
|
const activeModifiers = useActiveModifiers(day, displayMonth);
|
|
56
54
|
const eventHandlers = useDayEventHandlers(day, activeModifiers);
|
|
@@ -85,8 +83,9 @@ export function useDayRender(
|
|
|
85
83
|
activeModifiers.hidden
|
|
86
84
|
);
|
|
87
85
|
|
|
86
|
+
const DayContentComponent = dayPicker.components?.DayContent ?? DayContent;
|
|
88
87
|
const children = (
|
|
89
|
-
<
|
|
88
|
+
<DayContentComponent
|
|
90
89
|
date={day}
|
|
91
90
|
displayMonth={displayMonth}
|
|
92
91
|
activeModifiers={activeModifiers}
|
|
@@ -305,8 +305,3 @@ export interface CustomComponents {
|
|
|
305
305
|
/** The component for the week number in the table rows. */
|
|
306
306
|
WeekNumber?: (props: WeekNumberProps) => JSX.Element | null;
|
|
307
307
|
}
|
|
308
|
-
|
|
309
|
-
/**
|
|
310
|
-
* All the components in use by DayPicker that can be customized via the {@link components} prop.
|
|
311
|
-
*/
|
|
312
|
-
export type Components = Required<CustomComponents>;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { DayPickerProps } from 'DayPicker';
|
|
2
2
|
|
|
3
|
-
import { DayPickerBase
|
|
3
|
+
import { DayPickerBase } from './DayPickerBase';
|
|
4
4
|
|
|
5
5
|
/** The props for the {@link DayPicker} component when using `mode="default"` or `undefined`. */
|
|
6
6
|
export interface DayPickerDefaultProps extends DayPickerBase {
|
|
7
|
-
mode?:
|
|
7
|
+
mode?: undefined | 'default';
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
/** Returns true when the props are of type {@link DayPickerDefaultProps}. */
|
package/src/types/Matchers.ts
CHANGED
|
@@ -66,7 +66,7 @@ export type DateAfter = { after: Date };
|
|
|
66
66
|
/** A matcher to match a day falling before the specified date, with the date not included. */
|
|
67
67
|
export type DateBefore = { before: Date };
|
|
68
68
|
|
|
69
|
-
/** A matcher to match a day falling before and after two dates, where the dates are not included. */
|
|
69
|
+
/** A matcher to match a day falling before and/or after two dates, where the dates are not included. */
|
|
70
70
|
export type DateInterval = { before: Date; after: Date };
|
|
71
71
|
|
|
72
72
|
/** A matcher to match a range of dates. The range can be open. Differently from {@link DateInterval}, the dates here are included. */
|