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.
Files changed (31) hide show
  1. package/dist/index.d.ts +4 -9
  2. package/dist/index.esm.d.ts +4 -9
  3. package/dist/index.esm.js +1472 -1450
  4. package/dist/index.esm.js.map +1 -1
  5. package/dist/index.js +1485 -1463
  6. package/dist/index.js.map +1 -1
  7. package/dist/react-day-picker.min.js +1 -1
  8. package/package.json +2 -2
  9. package/src/components/Caption/Caption.tsx +8 -8
  10. package/src/components/CaptionDropdowns/CaptionDropdowns.tsx +4 -6
  11. package/src/components/CaptionNavigation/CaptionNavigation.tsx +8 -6
  12. package/src/components/Dropdown/Dropdown.tsx +5 -5
  13. package/src/components/Head/Head.tsx +4 -6
  14. package/src/components/Month/Month.tsx +5 -7
  15. package/src/components/MonthsDropdown/MonthsDropdown.tsx +6 -3
  16. package/src/components/Navigation/Navigation.tsx +15 -5
  17. package/src/components/Row/Row.tsx +8 -8
  18. package/src/components/Table/Table.test.tsx +19 -3
  19. package/src/components/Table/Table.tsx +10 -4
  20. package/src/components/Table/__snapshots__/Table.test.tsx.snap +39 -21
  21. package/src/components/YearsDropdown/YearsDropdown.tsx +6 -3
  22. package/src/contexts/DayPicker/DayPickerContext.tsx +1 -7
  23. package/src/contexts/DayPicker/defaultContextValues.ts +1 -32
  24. package/src/contexts/Modifiers/utils/isMatch.test.ts +24 -5
  25. package/src/contexts/Modifiers/utils/isMatch.ts +11 -3
  26. package/src/contexts/Navigation/NavigationContext.test.ts +5 -3
  27. package/src/contexts/Navigation/useNavigationState.test.ts +4 -1
  28. package/src/hooks/useDayRender/useDayRender.tsx +4 -5
  29. package/src/types/DayPickerBase.ts +0 -5
  30. package/src/types/DayPickerDefault.ts +2 -2
  31. 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
- <div>
964
- CustomHead
965
- </div>
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
- <div>
970
- CustomRow
971
- </div>
972
- <div>
973
- CustomRow
974
- </div>
975
- <div>
976
- CustomRow
977
- </div>
978
- <div>
979
- CustomRow
980
- </div>
981
- <div>
982
- CustomRow
983
- </div>
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
- <div>
986
- CustomFooter
987
- </div>
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: { Dropdown },
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
- <Dropdown
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
- </Dropdown>
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 { Caption, CaptionLayout } from 'components/Caption';
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
- after: addDays(testDay, -1),
62
- before: addDays(testDay, 1)
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 isBefore = differenceInCalendarDays(matcher.before, day) > 0;
62
- const isAfter = differenceInCalendarDays(day, matcher.after) > 0;
63
- return isBefore && isAfter;
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
- result.current.goToMonth(newMonth);
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
- result.current[1](month);
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
- <DayContent
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, DaySelectionMode } from './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?: DaySelectionMode;
7
+ mode?: undefined | 'default';
8
8
  }
9
9
 
10
10
  /** Returns true when the props are of type {@link DayPickerDefaultProps}. */
@@ -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. */