react-day-picker 8.2.1 → 8.3.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 (199) hide show
  1. package/dist/index.d.ts +1176 -40
  2. package/dist/index.esm.d.ts +1176 -0
  3. package/dist/index.esm.js +1473 -1496
  4. package/dist/index.esm.js.map +1 -1
  5. package/dist/index.js +1195 -1214
  6. package/dist/index.js.map +1 -1
  7. package/dist/react-day-picker.min.js +1 -1
  8. package/dist/style.css +9 -11
  9. package/dist/style.module.css +9 -11
  10. package/package.json +2 -2
  11. package/src/components/Caption/Caption.tsx +8 -8
  12. package/src/components/CaptionDropdowns/CaptionDropdowns.tsx +6 -4
  13. package/src/components/CaptionNavigation/CaptionNavigation.tsx +6 -8
  14. package/src/components/Dropdown/Dropdown.tsx +5 -5
  15. package/src/components/Head/Head.tsx +6 -4
  16. package/src/components/HeadRow/HeadRow.tsx +2 -1
  17. package/src/components/HeadRow/utils/getWeekdays.test.ts +10 -0
  18. package/src/components/HeadRow/utils/getWeekdays.ts +9 -3
  19. package/src/components/Month/Month.test.tsx +11 -0
  20. package/src/components/Month/Month.tsx +12 -6
  21. package/src/components/MonthsDropdown/MonthsDropdown.tsx +3 -6
  22. package/src/components/Navigation/Navigation.tsx +5 -15
  23. package/src/components/Row/Row.tsx +8 -8
  24. package/src/components/Table/Table.tsx +10 -12
  25. package/src/components/Table/utils/daysToMonthWeeks.ts +15 -3
  26. package/src/components/Table/utils/getMonthWeeks.test.ts +33 -1
  27. package/src/components/Table/utils/getMonthWeeks.ts +2 -3
  28. package/src/components/YearsDropdown/YearsDropdown.tsx +3 -6
  29. package/src/contexts/DayPicker/{useDayPicker.test.ts → DayPickerContext.test.ts} +13 -29
  30. package/src/contexts/DayPicker/DayPickerContext.tsx +41 -53
  31. package/src/contexts/DayPicker/defaultContextValues.ts +85 -0
  32. package/src/contexts/DayPicker/index.ts +0 -1
  33. package/src/contexts/Focus/{useFocusContext.test.ts → FocusContext.test.ts} +0 -0
  34. package/src/contexts/Focus/FocusContext.tsx +19 -6
  35. package/src/contexts/Focus/index.ts +0 -1
  36. package/src/contexts/Focus/utils/getInitialFocusTarget.test.tsx +37 -8
  37. package/src/contexts/Focus/utils/getInitialFocusTarget.tsx +0 -1
  38. package/src/contexts/Focus/utils/getNextFocus.test.tsx +75 -50
  39. package/src/contexts/Focus/utils/getNextFocus.tsx +54 -19
  40. package/src/contexts/Modifiers/{useModifiers.test.ts → ModifiersContext.test.ts} +0 -0
  41. package/src/contexts/Modifiers/ModifiersContext.tsx +16 -1
  42. package/src/contexts/Modifiers/index.ts +1 -1
  43. package/src/contexts/Modifiers/utils/getInternalModifiers.test.ts +3 -2
  44. package/src/contexts/Navigation/{useNavigation.test.ts → NavigationContext.test.ts} +1 -2
  45. package/src/contexts/Navigation/NavigationContext.tsx +15 -1
  46. package/src/contexts/Navigation/index.ts +0 -1
  47. package/src/contexts/SelectMultiple/{useSelectMultiple.test.ts → SelectMultipleContext.test.ts} +4 -2
  48. package/src/contexts/SelectMultiple/SelectMultipleContext.tsx +16 -1
  49. package/src/contexts/SelectMultiple/index.ts +0 -1
  50. package/src/contexts/SelectRange/{useSelectRange.test.ts → SelectRangeContext.test.ts} +4 -21
  51. package/src/contexts/SelectRange/SelectRangeContext.tsx +51 -36
  52. package/src/contexts/SelectRange/index.ts +0 -1
  53. package/src/contexts/SelectSingle/{useSelectSingle.test.ts → SelectSingleContext.test.ts} +1 -1
  54. package/src/contexts/SelectSingle/SelectSingleContext.tsx +16 -1
  55. package/src/contexts/SelectSingle/index.ts +0 -1
  56. package/src/hooks/useDayRender/useDayRender.tsx +5 -4
  57. package/src/style.css +9 -11
  58. package/src/types/DayPickerBase.ts +33 -6
  59. package/src/types/EventHandlers.ts +9 -11
  60. package/dist/DayPicker.d.ts +0 -93
  61. package/dist/components/Button/Button.d.ts +0 -7
  62. package/dist/components/Button/index.d.ts +0 -1
  63. package/dist/components/Caption/Caption.d.ts +0 -19
  64. package/dist/components/Caption/index.d.ts +0 -1
  65. package/dist/components/CaptionDropdowns/CaptionDropdowns.d.ts +0 -5
  66. package/dist/components/CaptionDropdowns/index.d.ts +0 -1
  67. package/dist/components/CaptionLabel/CaptionLabel.d.ts +0 -9
  68. package/dist/components/CaptionLabel/index.d.ts +0 -1
  69. package/dist/components/CaptionNavigation/CaptionNavigation.d.ts +0 -5
  70. package/dist/components/CaptionNavigation/index.d.ts +0 -1
  71. package/dist/components/Day/Day.d.ts +0 -12
  72. package/dist/components/Day/index.d.ts +0 -1
  73. package/dist/components/DayContent/DayContent.d.ts +0 -12
  74. package/dist/components/DayContent/index.d.ts +0 -1
  75. package/dist/components/Dropdown/Dropdown.d.ts +0 -20
  76. package/dist/components/Dropdown/index.d.ts +0 -1
  77. package/dist/components/Footer/Footer.d.ts +0 -2
  78. package/dist/components/Footer/index.d.ts +0 -1
  79. package/dist/components/Head/Head.d.ts +0 -2
  80. package/dist/components/Head/index.d.ts +0 -1
  81. package/dist/components/HeadRow/HeadRow.d.ts +0 -4
  82. package/dist/components/HeadRow/index.d.ts +0 -1
  83. package/dist/components/HeadRow/utils/getWeekdays.d.ts +0 -8
  84. package/dist/components/HeadRow/utils/index.d.ts +0 -1
  85. package/dist/components/IconDropdown/IconDropdown.d.ts +0 -5
  86. package/dist/components/IconDropdown/index.d.ts +0 -1
  87. package/dist/components/IconLeft/IconLeft.d.ts +0 -5
  88. package/dist/components/IconLeft/index.d.ts +0 -1
  89. package/dist/components/IconRight/IconRight.d.ts +0 -5
  90. package/dist/components/IconRight/index.d.ts +0 -1
  91. package/dist/components/Month/Month.d.ts +0 -7
  92. package/dist/components/Month/index.d.ts +0 -1
  93. package/dist/components/MonthsDropdown/MonthsDropdown.d.ts +0 -9
  94. package/dist/components/MonthsDropdown/index.d.ts +0 -1
  95. package/dist/components/Navigation/Navigation.d.ts +0 -20
  96. package/dist/components/Navigation/index.d.ts +0 -1
  97. package/dist/components/Root/Root.d.ts +0 -2
  98. package/dist/components/Root/index.d.ts +0 -1
  99. package/dist/components/Row/Row.d.ts +0 -13
  100. package/dist/components/Row/index.d.ts +0 -1
  101. package/dist/components/Table/Table.d.ts +0 -9
  102. package/dist/components/Table/index.d.ts +0 -1
  103. package/dist/components/Table/utils/daysToMonthWeeks.d.ts +0 -8
  104. package/dist/components/Table/utils/getMonthWeeks.d.ts +0 -21
  105. package/dist/components/WeekNumber/WeekNumber.d.ts +0 -14
  106. package/dist/components/WeekNumber/index.d.ts +0 -1
  107. package/dist/components/YearsDropdown/YearsDropdown.d.ts +0 -15
  108. package/dist/components/YearsDropdown/index.d.ts +0 -1
  109. package/dist/contexts/DayPicker/DayPickerContext.d.ts +0 -50
  110. package/dist/contexts/DayPicker/defaultClassNames.d.ts +0 -5
  111. package/dist/contexts/DayPicker/defaultContextValue.d.ts +0 -6
  112. package/dist/contexts/DayPicker/formatters/formatCaption.d.ts +0 -7
  113. package/dist/contexts/DayPicker/formatters/formatDay.d.ts +0 -7
  114. package/dist/contexts/DayPicker/formatters/formatMonthCaption.d.ts +0 -7
  115. package/dist/contexts/DayPicker/formatters/formatWeekNumber.d.ts +0 -4
  116. package/dist/contexts/DayPicker/formatters/formatWeekdayName.d.ts +0 -7
  117. package/dist/contexts/DayPicker/formatters/formatYearCaption.d.ts +0 -6
  118. package/dist/contexts/DayPicker/formatters/index.d.ts +0 -6
  119. package/dist/contexts/DayPicker/index.d.ts +0 -2
  120. package/dist/contexts/DayPicker/labels/index.d.ts +0 -7
  121. package/dist/contexts/DayPicker/labels/labelDay.d.ts +0 -5
  122. package/dist/contexts/DayPicker/labels/labelMonthDropdown.d.ts +0 -4
  123. package/dist/contexts/DayPicker/labels/labelNext.d.ts +0 -5
  124. package/dist/contexts/DayPicker/labels/labelPrevious.d.ts +0 -5
  125. package/dist/contexts/DayPicker/labels/labelWeekNumber.d.ts +0 -5
  126. package/dist/contexts/DayPicker/labels/labelWeekday.d.ts +0 -5
  127. package/dist/contexts/DayPicker/labels/labelYearDropdown.d.ts +0 -4
  128. package/dist/contexts/DayPicker/useDayPicker.d.ts +0 -8
  129. package/dist/contexts/DayPicker/utils/index.d.ts +0 -1
  130. package/dist/contexts/DayPicker/utils/parseFromToProps.d.ts +0 -6
  131. package/dist/contexts/Focus/FocusContext.d.ts +0 -36
  132. package/dist/contexts/Focus/index.d.ts +0 -2
  133. package/dist/contexts/Focus/useFocusContext.d.ts +0 -8
  134. package/dist/contexts/Focus/utils/getInitialFocusTarget.d.ts +0 -3
  135. package/dist/contexts/Focus/utils/getNextFocus.d.ts +0 -9
  136. package/dist/contexts/Modifiers/ModifiersContext.d.ts +0 -9
  137. package/dist/contexts/Modifiers/index.d.ts +0 -2
  138. package/dist/contexts/Modifiers/useModifiers.d.ts +0 -9
  139. package/dist/contexts/Modifiers/utils/getActiveModifiers.d.ts +0 -7
  140. package/dist/contexts/Modifiers/utils/getCustomModifiers.d.ts +0 -3
  141. package/dist/contexts/Modifiers/utils/getInternalModifiers.d.ts +0 -6
  142. package/dist/contexts/Modifiers/utils/isDateInRange.d.ts +0 -3
  143. package/dist/contexts/Modifiers/utils/isMatch.d.ts +0 -19
  144. package/dist/contexts/Modifiers/utils/matcherToArray.d.ts +0 -3
  145. package/dist/contexts/Navigation/NavigationContext.d.ts +0 -27
  146. package/dist/contexts/Navigation/index.d.ts +0 -2
  147. package/dist/contexts/Navigation/useNavigation.d.ts +0 -8
  148. package/dist/contexts/Navigation/useNavigationState.d.ts +0 -7
  149. package/dist/contexts/Navigation/utils/getDisplayMonths.d.ts +0 -8
  150. package/dist/contexts/Navigation/utils/getInitialMonth.d.ts +0 -3
  151. package/dist/contexts/Navigation/utils/getNextMonth.d.ts +0 -18
  152. package/dist/contexts/Navigation/utils/getPreviousMonth.d.ts +0 -19
  153. package/dist/contexts/RootProvider.d.ts +0 -8
  154. package/dist/contexts/SelectMultiple/SelectMultipleContext.d.ts +0 -35
  155. package/dist/contexts/SelectMultiple/index.d.ts +0 -2
  156. package/dist/contexts/SelectMultiple/useSelectMultiple.d.ts +0 -7
  157. package/dist/contexts/SelectRange/SelectRangeContext.d.ts +0 -36
  158. package/dist/contexts/SelectRange/index.d.ts +0 -2
  159. package/dist/contexts/SelectRange/useSelectRange.d.ts +0 -7
  160. package/dist/contexts/SelectRange/utils/addToRange.d.ts +0 -8
  161. package/dist/contexts/SelectSingle/SelectSingleContext.d.ts +0 -30
  162. package/dist/contexts/SelectSingle/index.d.ts +0 -2
  163. package/dist/contexts/SelectSingle/useSelectSingle.d.ts +0 -7
  164. package/dist/hooks/useActiveModifiers/index.d.ts +0 -1
  165. package/dist/hooks/useActiveModifiers/useActiveModifiers.d.ts +0 -15
  166. package/dist/hooks/useControlledValue/index.d.ts +0 -1
  167. package/dist/hooks/useControlledValue/useControlledValue.d.ts +0 -12
  168. package/dist/hooks/useDayEventHandlers/index.d.ts +0 -1
  169. package/dist/hooks/useDayEventHandlers/useDayEventHandlers.d.ts +0 -26
  170. package/dist/hooks/useDayRender/index.d.ts +0 -1
  171. package/dist/hooks/useDayRender/useDayRender.d.ts +0 -32
  172. package/dist/hooks/useDayRender/utils/getDayClassNames.d.ts +0 -10
  173. package/dist/hooks/useDayRender/utils/getDayStyle.d.ts +0 -5
  174. package/dist/hooks/useId/index.d.ts +0 -1
  175. package/dist/hooks/useId/useId.d.ts +0 -19
  176. package/dist/hooks/useInput/index.d.ts +0 -1
  177. package/dist/hooks/useInput/useInput.d.ts +0 -28
  178. package/dist/hooks/useInput/utils/isValidDate.d.ts +0 -2
  179. package/dist/hooks/useSelectedDays/index.d.ts +0 -1
  180. package/dist/hooks/useSelectedDays/useSelectedDays.d.ts +0 -10
  181. package/dist/types/DayPickerBase.d.ts +0 -255
  182. package/dist/types/DayPickerDefault.d.ts +0 -8
  183. package/dist/types/DayPickerMultiple.d.ts +0 -18
  184. package/dist/types/DayPickerRange.d.ts +0 -19
  185. package/dist/types/DayPickerSingle.d.ts +0 -16
  186. package/dist/types/EventHandlers.d.ts +0 -51
  187. package/dist/types/Formatters.d.ts +0 -24
  188. package/dist/types/Labels.d.ts +0 -28
  189. package/dist/types/Matchers.d.ts +0 -84
  190. package/dist/types/Modifiers.d.ts +0 -49
  191. package/dist/types/Styles.d.ts +0 -102
  192. package/src/contexts/DayPicker/defaultContextValue.ts +0 -37
  193. package/src/contexts/DayPicker/useDayPicker.ts +0 -17
  194. package/src/contexts/Focus/useFocusContext.ts +0 -17
  195. package/src/contexts/Modifiers/useModifiers.ts +0 -20
  196. package/src/contexts/Navigation/useNavigation.ts +0 -17
  197. package/src/contexts/SelectMultiple/useSelectMultiple.ts +0 -21
  198. package/src/contexts/SelectRange/useSelectRange.ts +0 -19
  199. package/src/contexts/SelectSingle/useSelectSingle.ts +0 -21
package/dist/index.esm.js CHANGED
@@ -1,31 +1,35 @@
1
1
  import * as React from 'react';
2
- import React__default, { createContext, useContext, useState, forwardRef, useEffect, useRef } from 'react';
2
+ import React__default, { useState, createContext, useContext, forwardRef, useEffect, useRef } from 'react';
3
3
  import enUS from 'date-fns/locale/en-US';
4
- import format from 'date-fns/format';
5
- import endOfMonth from 'date-fns/endOfMonth';
6
- import startOfDay from 'date-fns/startOfDay';
7
- import startOfMonth from 'date-fns/startOfMonth';
8
4
  import isSameYear from 'date-fns/isSameYear';
9
5
  import setMonth from 'date-fns/setMonth';
6
+ import startOfMonth from 'date-fns/startOfMonth';
10
7
  import setYear from 'date-fns/setYear';
11
8
  import startOfYear from 'date-fns/startOfYear';
12
9
  import addMonths from 'date-fns/addMonths';
13
10
  import isBefore from 'date-fns/isBefore';
14
11
  import isSameMonth from 'date-fns/isSameMonth';
15
12
  import differenceInCalendarMonths from 'date-fns/differenceInCalendarMonths';
16
- import addDays from 'date-fns/addDays';
17
- import startOfWeek from 'date-fns/startOfWeek';
18
- import getUnixTime from 'date-fns/getUnixTime';
19
13
  import isSameDay from 'date-fns/isSameDay';
14
+ import addDays from 'date-fns/addDays';
20
15
  import differenceInCalendarDays from 'date-fns/differenceInCalendarDays';
16
+ import subDays from 'date-fns/subDays';
21
17
  import isAfter from 'date-fns/isAfter';
22
18
  import isDate from 'date-fns/isDate';
19
+ import endOfMonth from 'date-fns/endOfMonth';
23
20
  import addWeeks from 'date-fns/addWeeks';
24
21
  import addYears from 'date-fns/addYears';
22
+ import endOfISOWeek from 'date-fns/endOfISOWeek';
25
23
  import endOfWeek from 'date-fns/endOfWeek';
26
24
  import max from 'date-fns/max';
27
25
  import min from 'date-fns/min';
26
+ import startOfISOWeek from 'date-fns/startOfISOWeek';
27
+ import startOfWeek from 'date-fns/startOfWeek';
28
+ import getUnixTime from 'date-fns/getUnixTime';
29
+ import format from 'date-fns/format';
30
+ import startOfDay from 'date-fns/startOfDay';
28
31
  import getWeeksInMonth from 'date-fns/getWeeksInMonth';
32
+ import getISOWeek from 'date-fns/getISOWeek';
29
33
  import getWeek from 'date-fns/getWeek';
30
34
  import parse from 'date-fns/parse';
31
35
 
@@ -92,309 +96,342 @@ function isDayPickerSingle(props) {
92
96
  return props.mode === 'single';
93
97
  }
94
98
 
95
- /**
96
- * The name of the default CSS classes.
97
- */
98
- var defaultClassNames = {
99
- root: 'rdp',
100
- multiple_months: 'rdp-multiple_months',
101
- with_weeknumber: 'rdp-with_weeknumber',
102
- vhidden: 'rdp-vhidden',
103
- button_reset: 'rdp-button_reset',
104
- button: 'rdp-button',
105
- caption: 'rdp-caption',
106
- caption_start: 'rdp-caption_start',
107
- caption_end: 'rdp-caption_end',
108
- caption_between: 'rdp-caption_between',
109
- caption_label: 'rdp-caption_label',
110
- caption_dropdowns: 'rdp-caption_dropdowns',
111
- dropdown: 'rdp-dropdown',
112
- dropdown_month: 'rdp-dropdown_month',
113
- dropdown_year: 'rdp-dropdown_year',
114
- dropdown_icon: 'rdp-dropdown_icon',
115
- months: 'rdp-months',
116
- month: 'rdp-month',
117
- table: 'rdp-table',
118
- tbody: 'rdp-tbody',
119
- tfoot: 'rdp-tfoot',
120
- head: 'rdp-head',
121
- head_row: 'rdp-head_row',
122
- head_cell: 'rdp-head_cell',
123
- nav: 'rdp-nav',
124
- nav_button: 'rdp-nav_button',
125
- nav_button_previous: 'rdp-nav_button_previous',
126
- nav_button_next: 'rdp-nav_button_next',
127
- nav_icon: 'rdp-nav_icon',
128
- row: 'rdp-row',
129
- weeknumber: 'rdp-weeknumber',
130
- cell: 'rdp-cell',
131
- day: 'rdp-day',
132
- day_today: 'rdp-day_today',
133
- day_outside: 'rdp-day_outside',
134
- day_selected: 'rdp-day_selected',
135
- day_disabled: 'rdp-day_disabled',
136
- day_hidden: 'rdp-day_hidden',
137
- day_range_start: 'rdp-day_range_start',
138
- day_range_end: 'rdp-day_range_end',
139
- day_range_middle: 'rdp-day_range_middle'
140
- };
99
+ /** Render the dropdown to navigate between months. */
100
+ function MonthsDropdown(props) {
101
+ var _a = useDayPicker(), fromDate = _a.fromDate, toDate = _a.toDate, styles = _a.styles, locale = _a.locale, formatMonthCaption = _a.formatters.formatMonthCaption, classNames = _a.classNames, Dropdown = _a.components.Dropdown, labelMonthDropdown = _a.labels.labelMonthDropdown;
102
+ // Dropdown should appear only when both from/toDate is set
103
+ if (!fromDate)
104
+ return React__default.createElement(React__default.Fragment, null);
105
+ if (!toDate)
106
+ return React__default.createElement(React__default.Fragment, null);
107
+ var dropdownMonths = [];
108
+ if (isSameYear(fromDate, toDate)) {
109
+ // only display the months included in the range
110
+ var date = startOfMonth(fromDate);
111
+ for (var month = fromDate.getMonth(); month <= toDate.getMonth(); month++) {
112
+ dropdownMonths.push(setMonth(date, month));
113
+ }
114
+ }
115
+ else {
116
+ // display all the 12 months
117
+ var date = startOfMonth(new Date()); // Any date should be OK, as we just need the year
118
+ for (var month = 0; month <= 11; month++) {
119
+ dropdownMonths.push(setMonth(date, month));
120
+ }
121
+ }
122
+ var handleChange = function (e) {
123
+ var selectedMonth = Number(e.target.value);
124
+ var newMonth = setMonth(startOfMonth(props.displayMonth), selectedMonth);
125
+ props.onChange(newMonth);
126
+ };
127
+ return (React__default.createElement(Dropdown, { name: "months", "aria-label": labelMonthDropdown(), className: classNames.dropdown_month, style: styles.dropdown_month, onChange: handleChange, value: props.displayMonth.getMonth(), caption: formatMonthCaption(props.displayMonth, { locale: locale }) }, dropdownMonths.map(function (m) { return (React__default.createElement("option", { key: m.getMonth(), value: m.getMonth() }, formatMonthCaption(m, { locale: locale }))); })));
128
+ }
141
129
 
142
130
  /**
143
- * The default formatter for the caption.
131
+ * Render a dropdown to change the year. Take in account the `nav.fromDate` and
132
+ * `toDate` from context.
144
133
  */
145
- function formatCaption(month, options) {
146
- return format(month, 'LLLL y', options);
134
+ function YearsDropdown(props) {
135
+ var displayMonth = props.displayMonth;
136
+ var _a = useDayPicker(), fromDate = _a.fromDate, toDate = _a.toDate, locale = _a.locale, styles = _a.styles, classNames = _a.classNames, Dropdown = _a.components.Dropdown, formatYearCaption = _a.formatters.formatYearCaption, labelYearDropdown = _a.labels.labelYearDropdown;
137
+ var years = [];
138
+ // Dropdown should appear only when both from/toDate is set
139
+ if (!fromDate)
140
+ return React__default.createElement(React__default.Fragment, null);
141
+ if (!toDate)
142
+ return React__default.createElement(React__default.Fragment, null);
143
+ var fromYear = fromDate.getFullYear();
144
+ var toYear = toDate.getFullYear();
145
+ for (var year = fromYear; year <= toYear; year++) {
146
+ years.push(setYear(startOfYear(new Date()), year));
147
+ }
148
+ var handleChange = function (e) {
149
+ var newMonth = setYear(startOfMonth(displayMonth), Number(e.target.value));
150
+ props.onChange(newMonth);
151
+ };
152
+ return (React__default.createElement(Dropdown, { name: "years", "aria-label": labelYearDropdown(), className: classNames.dropdown_year, style: styles.dropdown_year, onChange: handleChange, value: displayMonth.getFullYear(), caption: formatYearCaption(displayMonth, { locale: locale }) }, years.map(function (year) { return (React__default.createElement("option", { key: year.getFullYear(), value: year.getFullYear() }, formatYearCaption(year, { locale: locale }))); })));
147
153
  }
148
154
 
149
155
  /**
150
- * The default formatter for the Day button.
156
+ * Helper hook for using controlled/uncontrolled values from a component props.
157
+ *
158
+ * When the value is not controlled, pass `undefined` as `controlledValue` and
159
+ * use the returned setter to update it.
160
+ *
161
+ * When the value is controlled, pass the controlled value as second
162
+ * argument, which will be always returned as `value`.
151
163
  */
152
- function formatDay(day, options) {
153
- return format(day, 'd', options);
164
+ function useControlledValue(defaultValue, controlledValue) {
165
+ var _a = useState(defaultValue), uncontrolledValue = _a[0], setValue = _a[1];
166
+ var value = controlledValue === undefined ? uncontrolledValue : controlledValue;
167
+ return [value, setValue];
154
168
  }
155
169
 
156
- /**
157
- * The default formatter for the Month caption.
158
- */
159
- function formatMonthCaption(month, options) {
160
- return format(month, 'LLLL', options);
170
+ /** Return the initial month according to the given options. */
171
+ function getInitialMonth(context) {
172
+ var month = context.month, defaultMonth = context.defaultMonth, today = context.today;
173
+ var initialMonth = month || defaultMonth || today || new Date();
174
+ var toDate = context.toDate, fromDate = context.fromDate, _a = context.numberOfMonths, numberOfMonths = _a === void 0 ? 1 : _a;
175
+ // Fix the initialMonth if is after the to-date
176
+ if (toDate && differenceInCalendarMonths(toDate, initialMonth) < 0) {
177
+ var offset = -1 * (numberOfMonths - 1);
178
+ initialMonth = addMonths(toDate, offset);
179
+ }
180
+ // Fix the initialMonth if is before the from-date
181
+ if (fromDate && differenceInCalendarMonths(initialMonth, fromDate) < 0) {
182
+ initialMonth = fromDate;
183
+ }
184
+ return startOfMonth(initialMonth);
161
185
  }
162
186
 
163
- /**
164
- * The default formatter for the week number.
165
- */
166
- function formatWeekNumber(weekNumber) {
167
- return "".concat(weekNumber);
187
+ /** Controls the navigation state. */
188
+ function useNavigationState() {
189
+ var context = useDayPicker();
190
+ var initialMonth = getInitialMonth(context);
191
+ var _a = useControlledValue(initialMonth, context.month), month = _a[0], setMonth = _a[1];
192
+ var goToMonth = function (date) {
193
+ var _a;
194
+ if (context.disableNavigation)
195
+ return;
196
+ var month = startOfMonth(date);
197
+ setMonth(month);
198
+ (_a = context.onMonthChange) === null || _a === void 0 ? void 0 : _a.call(context, month);
199
+ };
200
+ return [month, goToMonth];
168
201
  }
169
202
 
170
203
  /**
171
- * The default formatter for the name of the weekday.
204
+ * Return the months to display in the component according to the number of
205
+ * months and the from/to date.
172
206
  */
173
- function formatWeekdayName(weekday, options) {
174
- return format(weekday, 'cccccc', options);
207
+ function getDisplayMonths(month, _a) {
208
+ var reverseMonths = _a.reverseMonths, numberOfMonths = _a.numberOfMonths;
209
+ var start = startOfMonth(month);
210
+ var end = startOfMonth(addMonths(start, numberOfMonths));
211
+ var monthsDiff = differenceInCalendarMonths(end, start);
212
+ var months = [];
213
+ for (var i = 0; i < monthsDiff; i++) {
214
+ var nextMonth = addMonths(start, i);
215
+ months.push(nextMonth);
216
+ }
217
+ if (reverseMonths)
218
+ months = months.reverse();
219
+ return months;
175
220
  }
176
221
 
177
222
  /**
178
- * The default formatter for the Year caption.
223
+ * Returns the next month the user can navigate to according to the given
224
+ * options.
225
+ *
226
+ * Please note that the next month is not always the next calendar month:
227
+ *
228
+ * - if after the `toDate` range, is undefined;
229
+ * - if the navigation is paged, is the number of months displayed ahead.
230
+ *
179
231
  */
180
- function formatYearCaption(year, options) {
181
- return format(year, 'yyyy', options);
232
+ function getNextMonth(startingMonth, options) {
233
+ if (options.disableNavigation) {
234
+ return undefined;
235
+ }
236
+ var toDate = options.toDate, pagedNavigation = options.pagedNavigation, _a = options.numberOfMonths, numberOfMonths = _a === void 0 ? 1 : _a;
237
+ var offset = pagedNavigation ? numberOfMonths : 1;
238
+ var month = startOfMonth(startingMonth);
239
+ if (!toDate) {
240
+ return addMonths(month, offset);
241
+ }
242
+ var monthsDiff = differenceInCalendarMonths(toDate, startingMonth);
243
+ if (monthsDiff < numberOfMonths) {
244
+ return undefined;
245
+ }
246
+ // Jump forward as the number of months when paged navigation
247
+ return addMonths(month, offset);
182
248
  }
183
249
 
184
- var formatters = /*#__PURE__*/Object.freeze({
185
- __proto__: null,
186
- formatCaption: formatCaption,
187
- formatDay: formatDay,
188
- formatMonthCaption: formatMonthCaption,
189
- formatWeekNumber: formatWeekNumber,
190
- formatWeekdayName: formatWeekdayName,
191
- formatYearCaption: formatYearCaption
192
- });
193
-
194
250
  /**
195
- * The default ARIA label for the day button.
251
+ * Returns the next previous the user can navigate to, according to the given
252
+ * options.
253
+ *
254
+ * Please note that the previous month is not always the previous calendar
255
+ * month:
256
+ *
257
+ * - if before the `fromDate` date, is `undefined`;
258
+ * - if the navigation is paged, is the number of months displayed before.
259
+ *
196
260
  */
197
- var labelDay = function (day, activeModifiers, options) {
198
- return format(day, 'do MMMM (EEEE)', options);
199
- };
261
+ function getPreviousMonth(startingMonth, options) {
262
+ if (options.disableNavigation) {
263
+ return undefined;
264
+ }
265
+ var fromDate = options.fromDate, pagedNavigation = options.pagedNavigation, _a = options.numberOfMonths, numberOfMonths = _a === void 0 ? 1 : _a;
266
+ var offset = pagedNavigation ? numberOfMonths : 1;
267
+ var month = startOfMonth(startingMonth);
268
+ if (!fromDate) {
269
+ return addMonths(month, -offset);
270
+ }
271
+ var monthsDiff = differenceInCalendarMonths(month, fromDate);
272
+ if (monthsDiff <= 0) {
273
+ return undefined;
274
+ }
275
+ // Jump back as the number of months when paged navigation
276
+ return addMonths(month, -offset);
277
+ }
200
278
 
201
279
  /**
202
- * The default ARIA label for the WeekNumber element.
280
+ * The Navigation context shares details and methods to navigate the months in DayPicker.
281
+ * Access this context from the {@link useNavigation} hook.
203
282
  */
204
- var labelMonthDropdown = function () {
205
- return 'Month: ';
206
- };
207
-
208
- /**
209
- * The default ARIA label for next month button in navigation
210
- */
211
- var labelNext = function () {
212
- return 'Go to next month';
213
- };
214
-
215
- /**
216
- * The default ARIA label for previous month button in navigation
217
- */
218
- var labelPrevious = function () {
219
- return 'Go to previous month';
220
- };
221
-
222
- /**
223
- * The default ARIA label for the Weekday element.
224
- */
225
- var labelWeekday = function (day, options) {
226
- return format(day, 'cccc', options);
227
- };
228
-
229
- /**
230
- * The default ARIA label for the WeekNumber element.
231
- */
232
- var labelWeekNumber = function (n) {
233
- return "Week n. ".concat(n);
234
- };
235
-
283
+ var NavigationContext = createContext(undefined);
284
+ /** Provides the values for the {@link NavigationContext}. */
285
+ function NavigationProvider(props) {
286
+ var dayPicker = useDayPicker();
287
+ var _a = useNavigationState(), currentMonth = _a[0], goToMonth = _a[1];
288
+ var displayMonths = getDisplayMonths(currentMonth, dayPicker);
289
+ var nextMonth = getNextMonth(currentMonth, dayPicker);
290
+ var previousMonth = getPreviousMonth(currentMonth, dayPicker);
291
+ var isDateDisplayed = function (date) {
292
+ return displayMonths.some(function (displayMonth) {
293
+ return isSameMonth(date, displayMonth);
294
+ });
295
+ };
296
+ var goToDate = function (date, refDate) {
297
+ if (isDateDisplayed(date)) {
298
+ return;
299
+ }
300
+ if (refDate && isBefore(date, refDate)) {
301
+ goToMonth(addMonths(date, 1 + dayPicker.numberOfMonths * -1));
302
+ }
303
+ else {
304
+ goToMonth(date);
305
+ }
306
+ };
307
+ var value = {
308
+ currentMonth: currentMonth,
309
+ displayMonths: displayMonths,
310
+ goToMonth: goToMonth,
311
+ goToDate: goToDate,
312
+ previousMonth: previousMonth,
313
+ nextMonth: nextMonth,
314
+ isDateDisplayed: isDateDisplayed
315
+ };
316
+ return (React__default.createElement(NavigationContext.Provider, { value: value }, props.children));
317
+ }
236
318
  /**
237
- * The default ARIA label for the WeekNumber element.
319
+ * Hook to access the {@link NavigationContextValue}. Use this hook to navigate
320
+ * between months or years in DayPicker.
321
+ *
322
+ * This hook is meant to be used inside internal or custom components.
238
323
  */
239
- var labelYearDropdown = function () {
240
- return 'Year: ';
241
- };
242
-
243
- var labels = /*#__PURE__*/Object.freeze({
244
- __proto__: null,
245
- labelDay: labelDay,
246
- labelMonthDropdown: labelMonthDropdown,
247
- labelNext: labelNext,
248
- labelPrevious: labelPrevious,
249
- labelWeekday: labelWeekday,
250
- labelWeekNumber: labelWeekNumber,
251
- labelYearDropdown: labelYearDropdown
252
- });
324
+ function useNavigation() {
325
+ var context = useContext(NavigationContext);
326
+ if (!context) {
327
+ throw new Error('useNavigation must be used within a NavigationProvider');
328
+ }
329
+ return context;
330
+ }
253
331
 
254
332
  /**
255
- * Returns the default values to use in the DayPickerContext, in case they are
256
- * not passed down with the DayPicker initial props.
333
+ * Render a caption with the dropdowns to navigate between months and years.
257
334
  */
258
- function getDefaultContextValue() {
259
- var captionLayout = 'buttons';
260
- var classNames = defaultClassNames;
261
- var locale = enUS;
262
- var modifiersClassNames = {};
263
- var modifiers = {};
264
- var numberOfMonths = 1;
265
- var styles = {};
266
- var today = new Date();
267
- return {
268
- captionLayout: captionLayout,
269
- classNames: classNames,
270
- formatters: formatters,
271
- labels: labels,
272
- locale: locale,
273
- modifiersClassNames: modifiersClassNames,
274
- modifiers: modifiers,
275
- numberOfMonths: numberOfMonths,
276
- styles: styles,
277
- today: today,
278
- mode: 'default'
335
+ function CaptionDropdowns(props) {
336
+ var _a = useDayPicker(), classNames = _a.classNames, styles = _a.styles, CaptionLabel = _a.components.CaptionLabel;
337
+ var goToMonth = useNavigation().goToMonth;
338
+ var handleMonthChange = function (newMonth) {
339
+ goToMonth(newMonth);
279
340
  };
341
+ var captionLabel = (React__default.createElement(CaptionLabel, { id: props.id, displayMonth: props.displayMonth }));
342
+ return (React__default.createElement("div", { className: classNames.caption_dropdowns, style: styles.caption_dropdowns },
343
+ React__default.createElement("div", { className: classNames.vhidden }, captionLabel),
344
+ React__default.createElement(MonthsDropdown, { onChange: handleMonthChange, displayMonth: props.displayMonth }),
345
+ React__default.createElement(YearsDropdown, { onChange: handleMonthChange, displayMonth: props.displayMonth })));
280
346
  }
281
347
 
282
- /** Return the `fromDate` and `toDate` prop values values parsing the DayPicker props. */
283
- function parseFromToProps(props) {
284
- var fromYear = props.fromYear, toYear = props.toYear, fromMonth = props.fromMonth, toMonth = props.toMonth;
285
- var fromDate = props.fromDate, toDate = props.toDate;
286
- if (fromMonth) {
287
- fromDate = startOfMonth(fromMonth);
288
- }
289
- else if (fromYear) {
290
- fromDate = new Date(fromYear, 0, 1);
348
+ /**
349
+ * Render a button HTML element applying the reset class name.
350
+ */
351
+ var Button = forwardRef(function (props, ref) {
352
+ var _a = useDayPicker(), classNames = _a.classNames, styles = _a.styles;
353
+ var classNamesArr = [classNames.button_reset, classNames.button];
354
+ if (props.className) {
355
+ classNamesArr.push(props.className);
291
356
  }
292
- if (toMonth) {
293
- toDate = endOfMonth(toMonth);
357
+ var className = classNamesArr.join(' ');
358
+ var style = __assign(__assign({}, styles.button_reset), styles.button);
359
+ if (props.style) {
360
+ Object.assign(style, props.style);
294
361
  }
295
- else if (toYear) {
296
- toDate = new Date(toYear, 11, 31);
362
+ return (React__default.createElement("button", __assign({}, props, { ref: ref, type: "button", className: className, style: style })));
363
+ });
364
+
365
+ /** A component rendering the navigation buttons or the drop-downs. */
366
+ function Navigation(props) {
367
+ var _a = useDayPicker(), dir = _a.dir, locale = _a.locale, classNames = _a.classNames, styles = _a.styles, _b = _a.labels, labelPrevious = _b.labelPrevious, labelNext = _b.labelNext, _c = _a.components, IconRight = _c.IconRight, IconLeft = _c.IconLeft;
368
+ if (!props.nextMonth && !props.previousMonth) {
369
+ return React__default.createElement(React__default.Fragment, null);
297
370
  }
298
- return {
299
- fromDate: fromDate ? startOfDay(fromDate) : undefined,
300
- toDate: toDate ? startOfDay(toDate) : undefined
301
- };
371
+ var previousLabel = labelPrevious(props.previousMonth, { locale: locale });
372
+ var previousClassName = [
373
+ classNames.nav_button,
374
+ classNames.nav_button_previous
375
+ ].join(' ');
376
+ var nextLabel = labelNext(props.nextMonth, { locale: locale });
377
+ var nextClassName = [
378
+ classNames.nav_button,
379
+ classNames.nav_button_next
380
+ ].join(' ');
381
+ return (React__default.createElement("div", { className: classNames.nav, style: styles.nav },
382
+ !props.hidePrevious && (React__default.createElement(Button, { name: "previous-month", "aria-label": previousLabel, className: previousClassName, style: styles.nav_button_previous, disabled: !props.previousMonth, onClick: props.onPreviousClick }, dir === 'rtl' ? (React__default.createElement(IconRight, { className: classNames.nav_icon, style: styles.nav_icon })) : (React__default.createElement(IconLeft, { className: classNames.nav_icon, style: styles.nav_icon })))),
383
+ !props.hideNext && (React__default.createElement(Button, { name: "next-month", "aria-label": nextLabel, className: nextClassName, style: styles.nav_button_next, disabled: !props.nextMonth, onClick: props.onNextClick }, dir === 'rtl' ? (React__default.createElement(IconLeft, { className: classNames.nav_icon, style: styles.nav_icon })) : (React__default.createElement(IconRight, { className: classNames.nav_icon, style: styles.nav_icon }))))));
302
384
  }
303
385
 
304
386
  /**
305
- * The DayPicker context shares the props passed to DayPicker within internal
306
- * and custom components. It is used to set the default values and perform
307
- * one-time calculations required to render the days.
308
- *
309
- * Access to this context from the {@link useDayPicker} hook.
310
- */
311
- var DayPickerContext = createContext(undefined);
312
- /**
313
- * The provider for the {@link DayPickerContext}, assigning the defaults from the
314
- * initial DayPicker props.
387
+ * Render a caption with a button-based navigation.
315
388
  */
316
- function DayPickerProvider(props) {
317
- var _a, _b, _c, _d;
318
- var initialProps = props.initialProps;
319
- var defaults = getDefaultContextValue();
320
- var _e = parseFromToProps(initialProps), fromDate = _e.fromDate, toDate = _e.toDate;
321
- var captionLayout = (_a = initialProps.captionLayout) !== null && _a !== void 0 ? _a : defaults.captionLayout;
322
- if (captionLayout !== 'buttons' && (!fromDate || !toDate)) {
323
- captionLayout = 'buttons';
324
- }
325
- var onSelect;
326
- if (isDayPickerSingle(initialProps) ||
327
- isDayPickerMultiple(initialProps) ||
328
- isDayPickerRange(initialProps)) {
329
- onSelect = initialProps.onSelect;
389
+ function CaptionNavigation(props) {
390
+ var _a;
391
+ var _b = useDayPicker(), numberOfMonths = _b.numberOfMonths, dir = _b.dir, CaptionLabel = _b.components.CaptionLabel;
392
+ var _c = useNavigation(), previousMonth = _c.previousMonth, nextMonth = _c.nextMonth, goToMonth = _c.goToMonth, displayMonths = _c.displayMonths;
393
+ var displayIndex = displayMonths.findIndex(function (month) {
394
+ return isSameMonth(props.displayMonth, month);
395
+ });
396
+ var isFirst = displayIndex === 0;
397
+ var isLast = displayIndex === displayMonths.length - 1;
398
+ if (dir === 'rtl') {
399
+ _a = [isFirst, isLast], isLast = _a[0], isFirst = _a[1];
330
400
  }
331
- var value = {
332
- captionLayout: captionLayout,
333
- className: initialProps.className,
334
- classNames: __assign(__assign({}, defaults.classNames), initialProps.classNames),
335
- components: __assign(__assign({}, defaults.components), initialProps.components),
336
- defaultMonth: initialProps.defaultMonth,
337
- dir: initialProps.dir,
338
- disabled: initialProps.disabled,
339
- disableNavigation: initialProps.disableNavigation,
340
- fixedWeeks: initialProps.fixedWeeks,
341
- footer: initialProps.footer,
342
- formatters: __assign(__assign({}, defaults.formatters), initialProps.formatters),
343
- fromDate: fromDate,
344
- hidden: initialProps.hidden,
345
- hideHead: initialProps.hideHead,
346
- initialFocus: initialProps.initialFocus,
347
- labels: __assign(__assign({}, defaults.labels), initialProps.labels),
348
- locale: (_b = initialProps.locale) !== null && _b !== void 0 ? _b : defaults.locale,
349
- mode: initialProps.mode || 'default',
350
- modifiers: __assign(__assign({}, defaults.modifiers), initialProps.modifiers),
351
- modifiersClassNames: __assign(__assign({}, defaults.modifiersClassNames), initialProps.modifiersClassNames),
352
- modifiersStyles: initialProps.modifiersStyles,
353
- month: initialProps.month,
354
- numberOfMonths: (_c = initialProps.numberOfMonths) !== null && _c !== void 0 ? _c : defaults.numberOfMonths,
355
- onDayBlur: initialProps.onDayBlur,
356
- onDayClick: initialProps.onDayClick,
357
- onDayFocus: initialProps.onDayFocus,
358
- onDayKeyDown: initialProps.onDayKeyDown,
359
- onDayKeyPress: initialProps.onDayKeyPress,
360
- onDayKeyUp: initialProps.onDayKeyUp,
361
- onDayMouseEnter: initialProps.onDayMouseEnter,
362
- onDayMouseLeave: initialProps.onDayMouseLeave,
363
- onDayTouchCancel: initialProps.onDayTouchCancel,
364
- onDayTouchEnd: initialProps.onDayTouchEnd,
365
- onDayTouchMove: initialProps.onDayTouchMove,
366
- onDayTouchStart: initialProps.onDayTouchStart,
367
- onMonthChange: initialProps.onMonthChange,
368
- onNextClick: initialProps.onNextClick,
369
- onPrevClick: initialProps.onPrevClick,
370
- onSelect: onSelect,
371
- onWeekNumberClick: initialProps.onWeekNumberClick,
372
- pagedNavigation: initialProps.pagedNavigation,
373
- reverseMonths: initialProps.reverseMonths,
374
- selected: initialProps.selected,
375
- showOutsideDays: initialProps.showOutsideDays,
376
- showWeekNumber: initialProps.showWeekNumber,
377
- style: initialProps.style,
378
- styles: __assign(__assign({}, defaults.styles), initialProps.styles),
379
- toDate: toDate,
380
- today: (_d = initialProps.today) !== null && _d !== void 0 ? _d : defaults.today,
381
- weekStartsOn: initialProps.weekStartsOn
401
+ var hideNext = numberOfMonths > 1 && (isFirst || !isLast);
402
+ var hidePrevious = numberOfMonths > 1 && (isLast || !isFirst);
403
+ var handlePreviousClick = function () {
404
+ if (!previousMonth)
405
+ return;
406
+ goToMonth(previousMonth);
382
407
  };
383
- return (React__default.createElement(DayPickerContext.Provider, { value: value }, props.children));
408
+ var handleNextClick = function () {
409
+ if (!nextMonth)
410
+ return;
411
+ goToMonth(nextMonth);
412
+ };
413
+ return (React__default.createElement(React__default.Fragment, null,
414
+ React__default.createElement(CaptionLabel, { id: props.id, displayMonth: props.displayMonth }),
415
+ React__default.createElement(Navigation, { displayMonth: props.displayMonth, hideNext: hideNext, hidePrevious: hidePrevious, nextMonth: nextMonth, previousMonth: previousMonth, onPreviousClick: handlePreviousClick, onNextClick: handleNextClick })));
384
416
  }
385
417
 
386
418
  /**
387
- * Hook to access the {@link DayPickerContextValue}.
388
- *
389
- * Use the DayPicker context to access to the props passed to DayPicker inside
390
- * internal or custom components.
419
+ * Render the caption of a month. The caption has a different layout when
420
+ * setting the {@link DayPickerBase.captionLayout} prop.
391
421
  */
392
- function useDayPicker() {
393
- var context = useContext(DayPickerContext);
394
- if (!context) {
395
- throw new Error("useDayPicker must be used within a DayPickerProvider.");
422
+ function Caption(props) {
423
+ var _a = useDayPicker(), classNames = _a.classNames, disableNavigation = _a.disableNavigation, styles = _a.styles, captionLayout = _a.captionLayout, CaptionLabel = _a.components.CaptionLabel;
424
+ var caption;
425
+ if (disableNavigation) {
426
+ caption = React__default.createElement(CaptionLabel, { id: props.id, displayMonth: props.displayMonth });
396
427
  }
397
- return context;
428
+ else if (captionLayout === 'dropdown') {
429
+ caption = (React__default.createElement(CaptionDropdowns, { displayMonth: props.displayMonth, id: props.id }));
430
+ }
431
+ else {
432
+ caption = (React__default.createElement(CaptionNavigation, { displayMonth: props.displayMonth, id: props.id }));
433
+ }
434
+ return (React__default.createElement("div", { className: classNames.caption, style: styles.caption }, caption));
398
435
  }
399
436
 
400
437
  /** Render the caption for the displayed month. This component is used when `captionLayout="buttons"`. */
@@ -404,1422 +441,1368 @@ function CaptionLabel(props) {
404
441
  }
405
442
 
406
443
  /**
407
- * Render the icon in the styled drop-down.
408
- */
409
- function IconDropdown(props) {
410
- return (React__default.createElement("svg", __assign({ width: "8px", height: "8px", viewBox: "0 0 120 120", "data-testid": "iconDropdown" }, props),
411
- React__default.createElement("path", { d: "M4.22182541,48.2218254 C8.44222828,44.0014225 15.2388494,43.9273804 19.5496459,47.9996989 L19.7781746,48.2218254 L60,88.443 L100.221825,48.2218254 C104.442228,44.0014225 111.238849,43.9273804 115.549646,47.9996989 L115.778175,48.2218254 C119.998577,52.4422283 120.07262,59.2388494 116.000301,63.5496459 L115.778175,63.7781746 L67.7781746,111.778175 C63.5577717,115.998577 56.7611506,116.07262 52.4503541,112.000301 L52.2218254,111.778175 L4.22182541,63.7781746 C-0.0739418023,59.4824074 -0.0739418023,52.5175926 4.22182541,48.2218254 Z", fill: "currentColor", fillRule: "nonzero" })));
412
- }
413
-
414
- /**
415
- * Render a styled select component – displaying a caption and a custom
416
- * drop-down icon.
444
+ * The SelectMultiple context shares details about the selected days when in
445
+ * multiple selection mode.
446
+ *
447
+ * Access this context from the {@link useSelectMultiple} hook.
417
448
  */
418
- function Dropdown(props) {
419
- var _a, _b;
420
- var onChange = props.onChange, value = props.value, children = props.children, caption = props.caption, className = props.className, style = props.style;
421
- var dayPicker = useDayPicker();
422
- var IconDropdownComponent = (_b = (_a = dayPicker.components) === null || _a === void 0 ? void 0 : _a.IconDropdown) !== null && _b !== void 0 ? _b : IconDropdown;
423
- return (React__default.createElement("div", { className: className, style: style },
424
- React__default.createElement("span", { className: dayPicker.classNames.vhidden }, props['aria-label']),
425
- React__default.createElement("select", { name: props.name, "aria-label": props['aria-label'], className: dayPicker.classNames.dropdown, style: dayPicker.styles.dropdown, value: value, onChange: onChange }, children),
426
- React__default.createElement("div", { className: dayPicker.classNames.caption_label, style: dayPicker.styles.caption_label, "aria-hidden": "true" },
427
- caption,
428
- React__default.createElement(IconDropdownComponent, { className: dayPicker.classNames.dropdown_icon, style: dayPicker.styles.dropdown_icon }))));
449
+ var SelectMultipleContext = createContext(undefined);
450
+ /** Provides the values for the {@link SelectMultipleContext}. */
451
+ function SelectMultipleProvider(props) {
452
+ if (!isDayPickerMultiple(props.initialProps)) {
453
+ var emptyContextValue = {
454
+ selected: undefined,
455
+ modifiers: {
456
+ disabled: []
457
+ }
458
+ };
459
+ return (React__default.createElement(SelectMultipleContext.Provider, { value: emptyContextValue }, props.children));
460
+ }
461
+ return (React__default.createElement(SelectMultipleProviderInternal, { initialProps: props.initialProps, children: props.children }));
429
462
  }
430
-
431
- /** Render the dropdown to navigate between months. */
432
- function MonthsDropdown(props) {
433
- var _a;
434
- var _b = useDayPicker(), fromDate = _b.fromDate, toDate = _b.toDate, styles = _b.styles, locale = _b.locale, formatMonthCaption = _b.formatters.formatMonthCaption, classNames = _b.classNames, components = _b.components, labelMonthDropdown = _b.labels.labelMonthDropdown;
435
- // Dropdown should appear only when both from/toDate is set
436
- if (!fromDate)
437
- return React__default.createElement(React__default.Fragment, null);
438
- if (!toDate)
439
- return React__default.createElement(React__default.Fragment, null);
440
- var dropdownMonths = [];
441
- if (isSameYear(fromDate, toDate)) {
442
- // only display the months included in the range
443
- var date = startOfMonth(fromDate);
444
- for (var month = fromDate.getMonth(); month <= toDate.getMonth(); month++) {
445
- dropdownMonths.push(setMonth(date, month));
463
+ function SelectMultipleProviderInternal(_a) {
464
+ var initialProps = _a.initialProps, children = _a.children;
465
+ var selected = initialProps.selected, min = initialProps.min, max = initialProps.max;
466
+ var onDayClick = function (day, activeModifiers, e) {
467
+ var _a, _b;
468
+ (_a = initialProps.onDayClick) === null || _a === void 0 ? void 0 : _a.call(initialProps, day, activeModifiers, e);
469
+ var isMinSelected = Boolean(activeModifiers.selected && min && (selected === null || selected === void 0 ? void 0 : selected.length) === min);
470
+ if (isMinSelected) {
471
+ return;
446
472
  }
447
- }
448
- else {
449
- // display all the 12 months
450
- var date = startOfMonth(new Date()); // Any date should be OK, as we just need the year
451
- for (var month = 0; month <= 11; month++) {
452
- dropdownMonths.push(setMonth(date, month));
473
+ var isMaxSelected = Boolean(!activeModifiers.selected && max && (selected === null || selected === void 0 ? void 0 : selected.length) === max);
474
+ if (isMaxSelected) {
475
+ return;
453
476
  }
477
+ var selectedDays = selected ? __spreadArray([], selected, true) : [];
478
+ if (activeModifiers.selected) {
479
+ var index = selectedDays.findIndex(function (selectedDay) {
480
+ return isSameDay(day, selectedDay);
481
+ });
482
+ selectedDays.splice(index, 1);
483
+ }
484
+ else {
485
+ selectedDays.push(day);
486
+ }
487
+ (_b = initialProps.onSelect) === null || _b === void 0 ? void 0 : _b.call(initialProps, selectedDays, day, activeModifiers, e);
488
+ };
489
+ var modifiers = {
490
+ disabled: []
491
+ };
492
+ if (selected) {
493
+ modifiers.disabled.push(function (day) {
494
+ var isMaxSelected = max && selected.length > max - 1;
495
+ var isSelected = selected.some(function (selectedDay) {
496
+ return isSameDay(selectedDay, day);
497
+ });
498
+ return Boolean(isMaxSelected && !isSelected);
499
+ });
454
500
  }
455
- var handleChange = function (e) {
456
- var selectedMonth = Number(e.target.value);
457
- var newMonth = setMonth(startOfMonth(props.displayMonth), selectedMonth);
458
- props.onChange(newMonth);
501
+ var contextValue = {
502
+ selected: selected,
503
+ onDayClick: onDayClick,
504
+ modifiers: modifiers
459
505
  };
460
- var DropdownComponent = (_a = components === null || components === void 0 ? void 0 : components.Dropdown) !== null && _a !== void 0 ? _a : Dropdown;
461
- return (React__default.createElement(DropdownComponent, { name: "months", "aria-label": labelMonthDropdown(), className: classNames.dropdown_month, style: styles.dropdown_month, onChange: handleChange, value: props.displayMonth.getMonth(), caption: formatMonthCaption(props.displayMonth, { locale: locale }) }, dropdownMonths.map(function (m) { return (React__default.createElement("option", { key: m.getMonth(), value: m.getMonth() }, formatMonthCaption(m, { locale: locale }))); })));
506
+ return (React__default.createElement(SelectMultipleContext.Provider, { value: contextValue }, children));
462
507
  }
463
-
464
508
  /**
465
- * Render a dropdown to change the year. Take in account the `nav.fromDate` and
466
- * `toDate` from context.
509
+ * Hook to access the {@link SelectMultipleContextValue}.
510
+ *
511
+ * This hook is meant to be used inside internal or custom components.
467
512
  */
468
- function YearsDropdown(props) {
469
- var _a;
470
- var displayMonth = props.displayMonth;
471
- var _b = useDayPicker(), fromDate = _b.fromDate, toDate = _b.toDate, locale = _b.locale, styles = _b.styles, classNames = _b.classNames, components = _b.components, formatYearCaption = _b.formatters.formatYearCaption, labelYearDropdown = _b.labels.labelYearDropdown;
472
- var years = [];
473
- // Dropdown should appear only when both from/toDate is set
474
- if (!fromDate)
475
- return React__default.createElement(React__default.Fragment, null);
476
- if (!toDate)
477
- return React__default.createElement(React__default.Fragment, null);
478
- var fromYear = fromDate.getFullYear();
479
- var toYear = toDate.getFullYear();
480
- for (var year = fromYear; year <= toYear; year++) {
481
- years.push(setYear(startOfYear(new Date()), year));
513
+ function useSelectMultiple() {
514
+ var context = useContext(SelectMultipleContext);
515
+ if (!context) {
516
+ throw new Error('useSelectMultiple must be used within a SelectMultipleProvider');
482
517
  }
483
- var handleChange = function (e) {
484
- var newMonth = setYear(startOfMonth(displayMonth), Number(e.target.value));
485
- props.onChange(newMonth);
486
- };
487
- var DropdownComponent = (_a = components === null || components === void 0 ? void 0 : components.Dropdown) !== null && _a !== void 0 ? _a : Dropdown;
488
- return (React__default.createElement(DropdownComponent, { name: "years", "aria-label": labelYearDropdown(), className: classNames.dropdown_year, style: styles.dropdown_year, onChange: handleChange, value: displayMonth.getFullYear(), caption: formatYearCaption(displayMonth, { locale: locale }) }, years.map(function (year) { return (React__default.createElement("option", { key: year.getFullYear(), value: year.getFullYear() }, formatYearCaption(year, { locale: locale }))); })));
518
+ return context;
489
519
  }
490
520
 
491
521
  /**
492
- * Helper hook for using controlled/uncontrolled values from a component props.
493
- *
494
- * When the value is not controlled, pass `undefined` as `controlledValue` and
495
- * use the returned setter to update it.
522
+ * Add a day to an existing range.
496
523
  *
497
- * When the value is controlled, pass the controlled value as second
498
- * argument, which will be always returned as `value`.
524
+ * The returned range takes in account the `undefined` values and if the added
525
+ * day is already present in the range.
499
526
  */
500
- function useControlledValue(defaultValue, controlledValue) {
501
- var _a = useState(defaultValue), uncontrolledValue = _a[0], setValue = _a[1];
502
- var value = controlledValue === undefined ? uncontrolledValue : controlledValue;
503
- return [value, setValue];
504
- }
505
-
506
- /** Return the initial month according to the given options. */
507
- function getInitialMonth(context) {
508
- var month = context.month, defaultMonth = context.defaultMonth, today = context.today;
509
- var initialMonth = month || defaultMonth || today || new Date();
510
- var toDate = context.toDate, fromDate = context.fromDate, _a = context.numberOfMonths, numberOfMonths = _a === void 0 ? 1 : _a;
511
- // Fix the initialMonth if is after the to-date
512
- if (toDate && differenceInCalendarMonths(toDate, initialMonth) < 0) {
513
- var offset = -1 * (numberOfMonths - 1);
514
- initialMonth = addMonths(toDate, offset);
527
+ function addToRange(day, range) {
528
+ var _a = range || {}, from = _a.from, to = _a.to;
529
+ if (!from) {
530
+ return { from: day, to: undefined };
515
531
  }
516
- // Fix the initialMonth if is before the from-date
517
- if (fromDate && differenceInCalendarMonths(initialMonth, fromDate) < 0) {
518
- initialMonth = fromDate;
532
+ if (!to && isSameDay(from, day)) {
533
+ return { from: from, to: day };
519
534
  }
520
- return startOfMonth(initialMonth);
521
- }
522
-
523
- /** Controls the navigation state. */
524
- function useNavigationState() {
525
- var context = useDayPicker();
526
- var initialMonth = getInitialMonth(context);
527
- var _a = useControlledValue(initialMonth, context.month), month = _a[0], setMonth = _a[1];
528
- var goToMonth = function (date) {
529
- var _a;
530
- if (context.disableNavigation)
531
- return;
532
- var month = startOfMonth(date);
533
- setMonth(month);
534
- (_a = context.onMonthChange) === null || _a === void 0 ? void 0 : _a.call(context, month);
535
- };
536
- return [month, goToMonth];
537
- }
538
-
539
- /**
540
- * Return the months to display in the component according to the number of
541
- * months and the from/to date.
542
- */
543
- function getDisplayMonths(month, _a) {
544
- var reverseMonths = _a.reverseMonths, numberOfMonths = _a.numberOfMonths;
545
- var start = startOfMonth(month);
546
- var end = startOfMonth(addMonths(start, numberOfMonths));
547
- var monthsDiff = differenceInCalendarMonths(end, start);
548
- var months = [];
549
- for (var i = 0; i < monthsDiff; i++) {
550
- var nextMonth = addMonths(start, i);
551
- months.push(nextMonth);
535
+ if (!to && isBefore(day, from)) {
536
+ return { from: day, to: from };
552
537
  }
553
- if (reverseMonths)
554
- months = months.reverse();
555
- return months;
556
- }
557
-
558
- /**
559
- * Returns the next month the user can navigate to according to the given
560
- * options.
561
- *
562
- * Please note that the next month is not always the next calendar month:
563
- *
564
- * - if after the `toDate` range, is undefined;
565
- * - if the navigation is paged, is the number of months displayed ahead.
566
- *
567
- */
568
- function getNextMonth(startingMonth, options) {
569
- if (options.disableNavigation) {
538
+ if (!to) {
539
+ return { from: from, to: day };
540
+ }
541
+ if (isSameDay(to, day) && isSameDay(from, day)) {
570
542
  return undefined;
571
543
  }
572
- var toDate = options.toDate, pagedNavigation = options.pagedNavigation, _a = options.numberOfMonths, numberOfMonths = _a === void 0 ? 1 : _a;
573
- var offset = pagedNavigation ? numberOfMonths : 1;
574
- var month = startOfMonth(startingMonth);
575
- if (!toDate) {
576
- return addMonths(month, offset);
544
+ if (isSameDay(to, day)) {
545
+ return { from: to, to: undefined };
577
546
  }
578
- var monthsDiff = differenceInCalendarMonths(toDate, startingMonth);
579
- if (monthsDiff < numberOfMonths) {
547
+ if (isSameDay(from, day)) {
580
548
  return undefined;
581
549
  }
582
- // Jump forward as the number of months when paged navigation
583
- return addMonths(month, offset);
550
+ if (isAfter(from, day)) {
551
+ return { from: day, to: to };
552
+ }
553
+ return { from: from, to: day };
584
554
  }
585
555
 
586
556
  /**
587
- * Returns the next previous the user can navigate to, according to the given
588
- * options.
589
- *
590
- * Please note that the previous month is not always the previous calendar
591
- * month:
592
- *
593
- * - if before the `fromDate` date, is `undefined`;
594
- * - if the navigation is paged, is the number of months displayed before.
557
+ * The SelectRange context shares details about the selected days when in
558
+ * range selection mode.
595
559
  *
560
+ * Access this context from the {@link useSelectRange} hook.
596
561
  */
597
- function getPreviousMonth(startingMonth, options) {
598
- if (options.disableNavigation) {
599
- return undefined;
600
- }
601
- var fromDate = options.fromDate, pagedNavigation = options.pagedNavigation, _a = options.numberOfMonths, numberOfMonths = _a === void 0 ? 1 : _a;
602
- var offset = pagedNavigation ? numberOfMonths : 1;
603
- var month = startOfMonth(startingMonth);
604
- if (!fromDate) {
605
- return addMonths(month, -offset);
606
- }
607
- var monthsDiff = differenceInCalendarMonths(month, fromDate);
608
- if (monthsDiff <= 0) {
609
- return undefined;
562
+ var SelectRangeContext = createContext(undefined);
563
+ /** Provides the values for the {@link SelectRangeProvider}. */
564
+ function SelectRangeProvider(props) {
565
+ if (!isDayPickerRange(props.initialProps)) {
566
+ var emptyContextValue = {
567
+ selected: undefined,
568
+ modifiers: {
569
+ range_start: [],
570
+ range_end: [],
571
+ range_middle: [],
572
+ disabled: []
573
+ }
574
+ };
575
+ return (React__default.createElement(SelectRangeContext.Provider, { value: emptyContextValue }, props.children));
610
576
  }
611
- // Jump back as the number of months when paged navigation
612
- return addMonths(month, -offset);
577
+ return (React__default.createElement(SelectRangeProviderInternal, { initialProps: props.initialProps, children: props.children }));
613
578
  }
614
-
615
- /**
616
- * The Navigation context shares details and methods to navigate the months in DayPicker.
617
- * Access this context from the {@link useNavigation} hook.
618
- */
619
- var NavigationContext = createContext(undefined);
620
- /** Provides the values for the {@link NavigationContext}. */
621
- function NavigationProvider(props) {
622
- var dayPicker = useDayPicker();
623
- var _a = useNavigationState(), currentMonth = _a[0], goToMonth = _a[1];
624
- var displayMonths = getDisplayMonths(currentMonth, dayPicker);
625
- var nextMonth = getNextMonth(currentMonth, dayPicker);
626
- var previousMonth = getPreviousMonth(currentMonth, dayPicker);
627
- var isDateDisplayed = function (date) {
628
- return displayMonths.some(function (displayMonth) {
629
- return isSameMonth(date, displayMonth);
630
- });
579
+ function SelectRangeProviderInternal(_a) {
580
+ var initialProps = _a.initialProps, children = _a.children;
581
+ var selected = initialProps.selected;
582
+ var _b = selected || {}, selectedFrom = _b.from, selectedTo = _b.to;
583
+ var min = initialProps.min;
584
+ var max = initialProps.max;
585
+ var onDayClick = function (day, activeModifiers, e) {
586
+ var _a, _b;
587
+ (_a = initialProps.onDayClick) === null || _a === void 0 ? void 0 : _a.call(initialProps, day, activeModifiers, e);
588
+ var newRange = addToRange(day, selected);
589
+ (_b = initialProps.onSelect) === null || _b === void 0 ? void 0 : _b.call(initialProps, newRange, day, activeModifiers, e);
631
590
  };
632
- var goToDate = function (date, refDate) {
633
- if (isDateDisplayed(date)) {
634
- return;
635
- }
636
- if (refDate && isBefore(date, refDate)) {
637
- goToMonth(addMonths(date, 1 + dayPicker.numberOfMonths * -1));
591
+ var modifiers = {
592
+ range_start: [],
593
+ range_end: [],
594
+ range_middle: [],
595
+ disabled: []
596
+ };
597
+ if (selectedFrom) {
598
+ modifiers.range_start = [selectedFrom];
599
+ if (!selectedTo) {
600
+ modifiers.range_end = [selectedFrom];
638
601
  }
639
602
  else {
640
- goToMonth(date);
603
+ modifiers.range_end = [selectedTo];
604
+ modifiers.range_middle = [
605
+ {
606
+ after: selectedFrom,
607
+ before: selectedTo
608
+ }
609
+ ];
641
610
  }
642
- };
643
- var value = {
644
- currentMonth: currentMonth,
645
- displayMonths: displayMonths,
646
- goToMonth: goToMonth,
647
- goToDate: goToDate,
648
- previousMonth: previousMonth,
649
- nextMonth: nextMonth,
650
- isDateDisplayed: isDateDisplayed
651
- };
652
- return (React__default.createElement(NavigationContext.Provider, { value: value }, props.children));
611
+ }
612
+ if (min) {
613
+ if (selectedFrom && !selectedTo) {
614
+ modifiers.disabled.push({
615
+ after: subDays(selectedFrom, min - 1),
616
+ before: addDays(selectedFrom, min - 1)
617
+ });
618
+ }
619
+ if (selectedFrom && selectedTo) {
620
+ modifiers.disabled.push({
621
+ after: selectedFrom,
622
+ before: addDays(selectedFrom, min - 1)
623
+ });
624
+ }
625
+ }
626
+ if (max) {
627
+ if (selectedFrom && !selectedTo) {
628
+ modifiers.disabled.push({
629
+ before: addDays(selectedFrom, -max + 1)
630
+ });
631
+ modifiers.disabled.push({
632
+ after: addDays(selectedFrom, max - 1)
633
+ });
634
+ }
635
+ if (selectedFrom && selectedTo) {
636
+ var selectedCount = differenceInCalendarDays(selectedTo, selectedFrom) + 1;
637
+ var offset = max - selectedCount;
638
+ modifiers.disabled.push({
639
+ before: subDays(selectedFrom, offset)
640
+ });
641
+ modifiers.disabled.push({
642
+ after: addDays(selectedTo, offset)
643
+ });
644
+ }
645
+ }
646
+ return (React__default.createElement(SelectRangeContext.Provider, { value: { selected: selected, onDayClick: onDayClick, modifiers: modifiers } }, children));
653
647
  }
654
-
655
648
  /**
656
- * Hook to access the {@link NavigationContextValue}. Use this hook to navigate
657
- * between months or years in DayPicker.
649
+ * Hook to access the {@link SelectRangeContextValue}.
658
650
  *
659
651
  * This hook is meant to be used inside internal or custom components.
660
652
  */
661
- function useNavigation() {
662
- var context = useContext(NavigationContext);
653
+ function useSelectRange() {
654
+ var context = useContext(SelectRangeContext);
663
655
  if (!context) {
664
- throw new Error('useNavigation must be used within a NavigationProvider');
656
+ throw new Error('useSelectRange must be used within a SelectRangeProvider');
665
657
  }
666
658
  return context;
667
659
  }
668
660
 
669
- /**
670
- * Render a caption with the dropdowns to navigate between months and years.
671
- */
672
- function CaptionDropdowns(props) {
673
- var _a;
674
- var _b = useDayPicker(), classNames = _b.classNames, styles = _b.styles, components = _b.components;
675
- var goToMonth = useNavigation().goToMonth;
676
- var handleMonthChange = function (newMonth) {
677
- goToMonth(newMonth);
678
- };
679
- var CaptionLabelComponent = (_a = components === null || components === void 0 ? void 0 : components.CaptionLabel) !== null && _a !== void 0 ? _a : CaptionLabel;
680
- var captionLabel = (React__default.createElement(CaptionLabelComponent, { id: props.id, displayMonth: props.displayMonth }));
681
- return (React__default.createElement("div", { className: classNames.caption_dropdowns, style: styles.caption_dropdowns },
682
- React__default.createElement("div", { className: classNames.vhidden }, captionLabel),
683
- React__default.createElement(MonthsDropdown, { onChange: handleMonthChange, displayMonth: props.displayMonth }),
684
- React__default.createElement(YearsDropdown, { onChange: handleMonthChange, displayMonth: props.displayMonth })));
661
+ /** Normalize to array a matcher input. */
662
+ function matcherToArray(matcher) {
663
+ if (Array.isArray(matcher)) {
664
+ return matcher;
665
+ }
666
+ else if (matcher !== undefined) {
667
+ return [matcher];
668
+ }
669
+ else {
670
+ return [];
671
+ }
685
672
  }
686
673
 
687
- /**
688
- * Render the "previous month" button in the navigation.
689
- */
690
- function IconLeft(props) {
691
- return (React__default.createElement("svg", __assign({ width: "16px", height: "16px", viewBox: "0 0 120 120" }, props),
692
- React__default.createElement("path", { d: "M69.490332,3.34314575 C72.6145263,0.218951416 77.6798462,0.218951416 80.8040405,3.34314575 C83.8617626,6.40086786 83.9268205,11.3179931 80.9992143,14.4548388 L80.8040405,14.6568542 L35.461,60 L80.8040405,105.343146 C83.8617626,108.400868 83.9268205,113.317993 80.9992143,116.454839 L80.8040405,116.656854 C77.7463184,119.714576 72.8291931,119.779634 69.6923475,116.852028 L69.490332,116.656854 L18.490332,65.6568542 C15.4326099,62.5991321 15.367552,57.6820069 18.2951583,54.5451612 L18.490332,54.3431458 L69.490332,3.34314575 Z", fill: "currentColor", fillRule: "nonzero" })));
674
+ /** Create CustomModifiers from dayModifiers */
675
+ function getCustomModifiers(dayModifiers) {
676
+ var customModifiers = {};
677
+ Object.entries(dayModifiers).forEach(function (_a) {
678
+ var modifier = _a[0], matcher = _a[1];
679
+ customModifiers[modifier] = matcherToArray(matcher);
680
+ });
681
+ return customModifiers;
693
682
  }
694
683
 
695
- /**
696
- * Render the "next month" button in the navigation.
697
- */
698
- function IconRight(props) {
699
- return (React__default.createElement("svg", __assign({ width: "16px", height: "16px", viewBox: "0 0 120 120" }, props),
700
- React__default.createElement("path", { d: "M49.8040405,3.34314575 C46.6798462,0.218951416 41.6145263,0.218951416 38.490332,3.34314575 C35.4326099,6.40086786 35.367552,11.3179931 38.2951583,14.4548388 L38.490332,14.6568542 L83.8333725,60 L38.490332,105.343146 C35.4326099,108.400868 35.367552,113.317993 38.2951583,116.454839 L38.490332,116.656854 C41.5480541,119.714576 46.4651794,119.779634 49.602025,116.852028 L49.8040405,116.656854 L100.804041,65.6568542 C103.861763,62.5991321 103.926821,57.6820069 100.999214,54.5451612 L100.804041,54.3431458 L49.8040405,3.34314575 Z", fill: "currentColor" })));
701
- }
684
+ /** The name of the modifiers that are used internally by DayPicker. */
685
+ var InternalModifier;
686
+ (function (InternalModifier) {
687
+ InternalModifier["Outside"] = "outside";
688
+ /** Name of the modifier applied to the disabled days, using the `disabled` prop. */
689
+ InternalModifier["Disabled"] = "disabled";
690
+ /** Name of the modifier applied to the selected days using the `selected` prop). */
691
+ InternalModifier["Selected"] = "selected";
692
+ /** Name of the modifier applied to the hidden days using the `hidden` prop). */
693
+ InternalModifier["Hidden"] = "hidden";
694
+ /** Name of the modifier applied to the day specified using the `today` prop). */
695
+ InternalModifier["Today"] = "today";
696
+ /** The modifier applied to the day starting a selected range, when in range selection mode. */
697
+ InternalModifier["RangeStart"] = "range_start";
698
+ /** The modifier applied to the day ending a selected range, when in range selection mode. */
699
+ InternalModifier["RangeEnd"] = "range_end";
700
+ /** The modifier applied to the days between the start and the end of a selected range, when in range selection mode. */
701
+ InternalModifier["RangeMiddle"] = "range_middle";
702
+ })(InternalModifier || (InternalModifier = {}));
702
703
 
703
- /**
704
- * Render a button HTML element applying the reset class name.
705
- */
706
- var Button = forwardRef(function (props, ref) {
707
- var _a = useDayPicker(), classNames = _a.classNames, styles = _a.styles;
708
- var classNamesArr = [classNames.button_reset, classNames.button];
709
- if (props.className) {
710
- classNamesArr.push(props.className);
704
+ var Selected = InternalModifier.Selected, Disabled = InternalModifier.Disabled, Hidden = InternalModifier.Hidden, Today = InternalModifier.Today, RangeEnd = InternalModifier.RangeEnd, RangeMiddle = InternalModifier.RangeMiddle, RangeStart = InternalModifier.RangeStart, Outside = InternalModifier.Outside;
705
+ /** Return the {@link InternalModifiers} from the DayPicker and select contexts. */
706
+ function getInternalModifiers(dayPicker, selectMultiple, selectRange) {
707
+ var _a;
708
+ var internalModifiers = (_a = {},
709
+ _a[Selected] = matcherToArray(dayPicker.selected),
710
+ _a[Disabled] = matcherToArray(dayPicker.disabled),
711
+ _a[Hidden] = matcherToArray(dayPicker.hidden),
712
+ _a[Today] = [dayPicker.today],
713
+ _a[RangeEnd] = [],
714
+ _a[RangeMiddle] = [],
715
+ _a[RangeStart] = [],
716
+ _a[Outside] = [],
717
+ _a);
718
+ if (dayPicker.fromDate) {
719
+ internalModifiers[Disabled].push({ before: dayPicker.fromDate });
711
720
  }
712
- var className = classNamesArr.join(' ');
713
- var style = __assign(__assign({}, styles.button_reset), styles.button);
714
- if (props.style) {
715
- Object.assign(style, props.style);
721
+ if (dayPicker.toDate) {
722
+ internalModifiers[Disabled].push({ after: dayPicker.toDate });
716
723
  }
717
- return (React__default.createElement("button", __assign({}, props, { ref: ref, type: "button", className: className, style: style })));
718
- });
719
-
720
- /** A component rendering the navigation buttons or the drop-downs. */
721
- function Navigation(props) {
722
- var _a, _b;
723
- var _c = useDayPicker(), dir = _c.dir, locale = _c.locale, classNames = _c.classNames, styles = _c.styles, _d = _c.labels, labelPrevious = _d.labelPrevious, labelNext = _d.labelNext, components = _c.components;
724
- if (!props.nextMonth && !props.previousMonth) {
725
- return React__default.createElement(React__default.Fragment, null);
724
+ if (isDayPickerMultiple(dayPicker)) {
725
+ internalModifiers[Disabled] = internalModifiers[Disabled].concat(selectMultiple.modifiers[Disabled]);
726
726
  }
727
- var previousLabel = labelPrevious(props.previousMonth, { locale: locale });
728
- var previousClassName = [
729
- classNames.nav_button,
730
- classNames.nav_button_previous
731
- ].join(' ');
732
- var nextLabel = labelNext(props.nextMonth, { locale: locale });
733
- var nextClassName = [
734
- classNames.nav_button,
735
- classNames.nav_button_next
736
- ].join(' ');
737
- var IconRightComponent = (_a = components === null || components === void 0 ? void 0 : components.IconRight) !== null && _a !== void 0 ? _a : IconRight;
738
- var IconLeftComponent = (_b = components === null || components === void 0 ? void 0 : components.IconLeft) !== null && _b !== void 0 ? _b : IconLeft;
739
- return (React__default.createElement("div", { className: classNames.nav, style: styles.nav },
740
- !props.hidePrevious && (React__default.createElement(Button, { name: "previous-month", "aria-label": previousLabel, className: previousClassName, style: styles.nav_button_previous, disabled: !props.previousMonth, onClick: props.onPreviousClick }, dir === 'rtl' ? (React__default.createElement(IconRightComponent, { className: classNames.nav_icon, style: styles.nav_icon })) : (React__default.createElement(IconLeftComponent, { className: classNames.nav_icon, style: styles.nav_icon })))),
741
- !props.hideNext && (React__default.createElement(Button, { name: "next-month", "aria-label": nextLabel, className: nextClassName, style: styles.nav_button_next, disabled: !props.nextMonth, onClick: props.onNextClick }, dir === 'rtl' ? (React__default.createElement(IconLeftComponent, { className: classNames.nav_icon, style: styles.nav_icon })) : (React__default.createElement(IconRightComponent, { className: classNames.nav_icon, style: styles.nav_icon }))))));
727
+ else if (isDayPickerRange(dayPicker)) {
728
+ internalModifiers[Disabled] = internalModifiers[Disabled].concat(selectRange.modifiers[Disabled]);
729
+ internalModifiers[RangeStart] = selectRange.modifiers[RangeStart];
730
+ internalModifiers[RangeMiddle] = selectRange.modifiers[RangeMiddle];
731
+ internalModifiers[RangeEnd] = selectRange.modifiers[RangeEnd];
732
+ }
733
+ return internalModifiers;
742
734
  }
743
735
 
736
+ /** The Modifiers context store the modifiers used in DayPicker. To access the value of this context, use {@link useModifiers}. */
737
+ var ModifiersContext = createContext(undefined);
738
+ /** Provide the value for the {@link ModifiersContext}. */
739
+ function ModifiersProvider(props) {
740
+ var dayPicker = useDayPicker();
741
+ var selectMultiple = useSelectMultiple();
742
+ var selectRange = useSelectRange();
743
+ var internalModifiers = getInternalModifiers(dayPicker, selectMultiple, selectRange);
744
+ var customModifiers = getCustomModifiers(dayPicker.modifiers);
745
+ var modifiers = __assign(__assign({}, internalModifiers), customModifiers);
746
+ return (React__default.createElement(ModifiersContext.Provider, { value: modifiers }, props.children));
747
+ }
744
748
  /**
745
- * Render a caption with a button-based navigation.
749
+ * Return the modifiers used by DayPicker.
750
+ *
751
+ * This hook is meant to be used inside internal or custom components.
752
+ * Requires to be wrapped into {@link ModifiersProvider}.
753
+ *
746
754
  */
747
- function CaptionNavigation(props) {
748
- var _a;
749
- var _b;
750
- var _c = useDayPicker(), numberOfMonths = _c.numberOfMonths, dir = _c.dir, components = _c.components;
751
- var _d = useNavigation(), previousMonth = _d.previousMonth, nextMonth = _d.nextMonth, goToMonth = _d.goToMonth, displayMonths = _d.displayMonths;
752
- var displayIndex = displayMonths.findIndex(function (month) {
753
- return isSameMonth(props.displayMonth, month);
754
- });
755
- var isFirst = displayIndex === 0;
756
- var isLast = displayIndex === displayMonths.length - 1;
757
- if (dir === 'rtl') {
758
- _a = [isFirst, isLast], isLast = _a[0], isFirst = _a[1];
755
+ function useModifiers() {
756
+ var context = useContext(ModifiersContext);
757
+ if (!context) {
758
+ throw new Error('useModifiers must be used within a ModifiersProvider');
759
759
  }
760
- var hideNext = numberOfMonths > 1 && (isFirst || !isLast);
761
- var hidePrevious = numberOfMonths > 1 && (isLast || !isFirst);
762
- var handlePreviousClick = function () {
763
- if (!previousMonth)
764
- return;
765
- goToMonth(previousMonth);
766
- };
767
- var handleNextClick = function () {
768
- if (!nextMonth)
769
- return;
770
- goToMonth(nextMonth);
771
- };
772
- var CaptionLabelComponent = (_b = components === null || components === void 0 ? void 0 : components.CaptionLabel) !== null && _b !== void 0 ? _b : CaptionLabel;
773
- var captionLabel = (React__default.createElement(CaptionLabelComponent, { id: props.id, displayMonth: props.displayMonth }));
774
- return (React__default.createElement(React__default.Fragment, null,
775
- captionLabel,
776
- React__default.createElement(Navigation, { displayMonth: props.displayMonth, hideNext: hideNext, hidePrevious: hidePrevious, nextMonth: nextMonth, previousMonth: previousMonth, onPreviousClick: handlePreviousClick, onNextClick: handleNextClick })));
760
+ return context;
777
761
  }
778
762
 
779
- /**
780
- * Render the caption of a month. The caption has a different layout when
781
- * setting the {@link DayPickerBase.captionLayout} prop.
782
- */
783
- function Caption(props) {
784
- var _a;
785
- var _b = useDayPicker(), classNames = _b.classNames, disableNavigation = _b.disableNavigation, styles = _b.styles, captionLayout = _b.captionLayout, components = _b.components;
786
- var CaptionLabelComponent = (_a = components === null || components === void 0 ? void 0 : components.CaptionLabel) !== null && _a !== void 0 ? _a : CaptionLabel;
787
- var caption;
788
- if (disableNavigation) {
789
- caption = (React__default.createElement(CaptionLabelComponent, { id: props.id, displayMonth: props.displayMonth }));
790
- }
791
- else if (captionLayout === 'dropdown') {
792
- caption = (React__default.createElement(CaptionDropdowns, { displayMonth: props.displayMonth, id: props.id }));
793
- }
794
- else {
795
- caption = (React__default.createElement(CaptionNavigation, { displayMonth: props.displayMonth, id: props.id }));
796
- }
797
- return (React__default.createElement("div", { className: classNames.caption, style: styles.caption }, caption));
763
+ /** Returns true if `matcher` is of type {@link DateInterval}. */
764
+ function isDateInterval(matcher) {
765
+ return Boolean(matcher &&
766
+ typeof matcher === 'object' &&
767
+ 'before' in matcher &&
768
+ 'after' in matcher);
798
769
  }
799
-
800
- /** Render the Footer component (empty as default).*/
801
- function Footer() {
802
- var _a = useDayPicker(), footer = _a.footer, styles = _a.styles, tfoot = _a.classNames.tfoot;
803
- if (!footer)
804
- return React__default.createElement(React__default.Fragment, null);
805
- return (React__default.createElement("tfoot", { className: tfoot, style: styles.tfoot },
806
- React__default.createElement("tr", null,
807
- React__default.createElement("td", { colSpan: 8 }, footer))));
770
+ /** Returns true if `value` is a {@link DateRange} type. */
771
+ function isDateRange(value) {
772
+ return Boolean(value && typeof value === 'object' && 'from' in value);
808
773
  }
809
-
810
- /**
811
- * Generate a series of 7 days, starting from the week, to use for formatting
812
- * the weekday names (Monday, Tuesday, etc.).
813
- */
814
- function getWeekdays(locale,
815
- /** The index of the first day of the week (0 - Sunday) */
816
- weekStartsOn) {
817
- var start = startOfWeek(new Date(), { locale: locale, weekStartsOn: weekStartsOn });
818
- var days = [];
819
- for (var i = 0; i < 7; i++) {
820
- var day = addDays(start, i);
821
- days.push(day);
822
- }
823
- return days;
774
+ /** Returns true if `value` is of type {@link DateAfter}. */
775
+ function isDateAfterType(value) {
776
+ return Boolean(value && typeof value === 'object' && 'after' in value);
824
777
  }
825
-
826
- /**
827
- * Render the HeadRow component - i.e. the table head row with the weekday names.
828
- */
829
- function HeadRow() {
830
- var _a = useDayPicker(), classNames = _a.classNames, styles = _a.styles, showWeekNumber = _a.showWeekNumber, locale = _a.locale, weekStartsOn = _a.weekStartsOn, formatWeekdayName = _a.formatters.formatWeekdayName, labelWeekday = _a.labels.labelWeekday;
831
- var weekdays = getWeekdays(locale, weekStartsOn);
832
- return (React__default.createElement("tr", { style: styles.head_row, className: classNames.head_row },
833
- showWeekNumber && (React__default.createElement("th", { scope: "col", style: styles.head_cell, className: classNames.head_cell })),
834
- weekdays.map(function (weekday, i) { return (React__default.createElement("th", { key: i, scope: "col", className: classNames.head_cell, style: styles.head_cell },
835
- React__default.createElement("span", { "aria-hidden": true }, formatWeekdayName(weekday, { locale: locale })),
836
- React__default.createElement("span", { className: classNames.vhidden }, labelWeekday(weekday, { locale: locale })))); })));
778
+ /** Returns true if `value` is of type {@link DateBefore}. */
779
+ function isDateBeforeType(value) {
780
+ return Boolean(value && typeof value === 'object' && 'before' in value);
781
+ }
782
+ /** Returns true if `value` is a {@link DayOfWeek} type. */
783
+ function isDayOfWeekType(value) {
784
+ return Boolean(value && typeof value === 'object' && 'dayOfWeek' in value);
837
785
  }
838
786
 
839
- /** Render the table head. */
840
- function Head() {
787
+ /** Return `true` whether `date` is inside `range`. */
788
+ function isDateInRange(date, range) {
841
789
  var _a;
842
- var _b = useDayPicker(), classNames = _b.classNames, styles = _b.styles, components = _b.components;
843
- var HeadRowComponent = (_a = components === null || components === void 0 ? void 0 : components.HeadRow) !== null && _a !== void 0 ? _a : HeadRow;
844
- return (React__default.createElement("thead", { style: styles.head, className: classNames.head },
845
- React__default.createElement(HeadRowComponent, null)));
790
+ var from = range.from, to = range.to;
791
+ if (!from) {
792
+ return false;
793
+ }
794
+ if (!to && isSameDay(from, date)) {
795
+ return true;
796
+ }
797
+ if (!to) {
798
+ return false;
799
+ }
800
+ var isToBeforeFrom = differenceInCalendarDays(to, from) < 0;
801
+ if (to && isToBeforeFrom) {
802
+ _a = [to, from], from = _a[0], to = _a[1];
803
+ }
804
+ return (differenceInCalendarDays(date, from) >= 0 &&
805
+ differenceInCalendarDays(to, date) >= 0);
846
806
  }
847
807
 
848
- /** Render the content of the day cell. */
849
- function DayContent(props) {
850
- var _a = useDayPicker(), locale = _a.locale, formatDay = _a.formatters.formatDay;
851
- return React__default.createElement(React__default.Fragment, null, formatDay(props.date, { locale: locale }));
808
+ /** Returns true if `value` is a Date type. */
809
+ function isDateType(value) {
810
+ return isDate(value);
811
+ }
812
+ /** Returns true if `value` is an array of valid dates. */
813
+ function isArrayOfDates(value) {
814
+ return Array.isArray(value) && value.every(isDate);
852
815
  }
853
-
854
816
  /**
855
- * The SelectMultiple context shares details about the selected days when in
856
- * multiple selection mode.
817
+ * Returns whether a day matches against at least one of the given Matchers.
857
818
  *
858
- * Access this context from the {@link useSelectMultiple} hook.
859
- */
860
- var SelectMultipleContext = createContext(undefined);
861
- /** Provides the values for the {@link SelectMultipleContext}. */
862
- function SelectMultipleProvider(props) {
863
- if (!isDayPickerMultiple(props.initialProps)) {
864
- var emptyContextValue = {
865
- selected: undefined,
866
- modifiers: {
867
- disabled: []
868
- }
869
- };
870
- return (React__default.createElement(SelectMultipleContext.Provider, { value: emptyContextValue }, props.children));
871
- }
872
- return (React__default.createElement(SelectMultipleProviderInternal, { initialProps: props.initialProps, children: props.children }));
873
- }
874
- function SelectMultipleProviderInternal(_a) {
875
- var initialProps = _a.initialProps, children = _a.children;
876
- var selected = initialProps.selected, min = initialProps.min, max = initialProps.max;
877
- var onDayClick = function (day, activeModifiers, e) {
878
- var _a, _b;
879
- (_a = initialProps.onDayClick) === null || _a === void 0 ? void 0 : _a.call(initialProps, day, activeModifiers, e);
880
- var isMinSelected = Boolean(activeModifiers.selected && min && (selected === null || selected === void 0 ? void 0 : selected.length) === min);
881
- if (isMinSelected) {
882
- return;
819
+ * ```
820
+ * const day = new Date(2022, 5, 19);
821
+ * const matcher1: DateRange = {
822
+ * from: new Date(2021, 12, 21),
823
+ * to: new Date(2021, 12, 30)
824
+ * }
825
+ * const matcher2: DateRange = {
826
+ * from: new Date(2022, 5, 1),
827
+ * to: new Date(2022, 5, 23)
828
+ * }
829
+ *
830
+ * const isMatch(day, [matcher1, matcher2]); // true, since day is in the matcher1 range.
831
+ * ```
832
+ * */
833
+ function isMatch(day, matchers) {
834
+ return matchers.some(function (matcher) {
835
+ if (typeof matcher === 'boolean') {
836
+ return matcher;
883
837
  }
884
- var isMaxSelected = Boolean(!activeModifiers.selected && max && (selected === null || selected === void 0 ? void 0 : selected.length) === max);
885
- if (isMaxSelected) {
886
- return;
838
+ if (isDateType(matcher)) {
839
+ return isSameDay(day, matcher);
887
840
  }
888
- var selectedDays = selected ? __spreadArray([], selected, true) : [];
889
- if (activeModifiers.selected) {
890
- var index = selectedDays.findIndex(function (selectedDay) {
891
- return isSameDay(day, selectedDay);
892
- });
893
- selectedDays.splice(index, 1);
841
+ if (isArrayOfDates(matcher)) {
842
+ return matcher.includes(day);
894
843
  }
895
- else {
896
- selectedDays.push(day);
844
+ if (isDateRange(matcher)) {
845
+ return isDateInRange(day, matcher);
897
846
  }
898
- (_b = initialProps.onSelect) === null || _b === void 0 ? void 0 : _b.call(initialProps, selectedDays, day, activeModifiers, e);
899
- };
900
- var modifiers = {
901
- disabled: []
902
- };
903
- if (selected) {
904
- modifiers.disabled.push(function (day) {
905
- var isMaxSelected = max && selected.length > max - 1;
906
- var isSelected = selected.some(function (selectedDay) {
907
- return isSameDay(selectedDay, day);
908
- });
909
- return Boolean(isMaxSelected && !isSelected);
910
- });
847
+ if (isDayOfWeekType(matcher)) {
848
+ return matcher.dayOfWeek.includes(day.getDay());
849
+ }
850
+ if (isDateInterval(matcher)) {
851
+ var isBefore = differenceInCalendarDays(matcher.before, day) > 0;
852
+ var isAfter = differenceInCalendarDays(day, matcher.after) > 0;
853
+ return isBefore && isAfter;
854
+ }
855
+ if (isDateAfterType(matcher)) {
856
+ return differenceInCalendarDays(day, matcher.after) > 0;
857
+ }
858
+ if (isDateBeforeType(matcher)) {
859
+ return differenceInCalendarDays(matcher.before, day) > 0;
860
+ }
861
+ if (typeof matcher === 'function') {
862
+ return matcher(day);
863
+ }
864
+ return false;
865
+ });
866
+ }
867
+
868
+ /** Return the active modifiers for the given day. */
869
+ function getActiveModifiers(day,
870
+ /** The modifiers to match for the given date. */
871
+ modifiers,
872
+ /** The month where the day is displayed, to add the "outside" modifiers. */
873
+ displayMonth) {
874
+ var matchedModifiers = Object.keys(modifiers).reduce(function (result, key) {
875
+ var modifier = modifiers[key];
876
+ if (isMatch(day, modifier)) {
877
+ result.push(key);
878
+ }
879
+ return result;
880
+ }, []);
881
+ var activeModifiers = {};
882
+ matchedModifiers.forEach(function (modifier) { return (activeModifiers[modifier] = true); });
883
+ if (displayMonth && !isSameMonth(day, displayMonth)) {
884
+ activeModifiers.outside = true;
911
885
  }
912
- var contextValue = {
913
- selected: selected,
914
- onDayClick: onDayClick,
915
- modifiers: modifiers
916
- };
917
- return (React__default.createElement(SelectMultipleContext.Provider, { value: contextValue }, children));
886
+ return activeModifiers;
918
887
  }
919
888
 
920
- /**
921
- * Hook to access the {@link SelectMultipleContextValue}.
922
- *
923
- * This hook is meant to be used inside internal or custom components.
924
- */
925
- function useSelectMultiple() {
926
- var context = useContext(SelectMultipleContext);
927
- if (!context) {
928
- throw new Error('useSelectMultiple must be used within a SelectMultipleProvider');
889
+ /** Returns the day that should be the target of the focus when DayPicker is rendered the first time. */
890
+ function getInitialFocusTarget(displayMonths, modifiers) {
891
+ var firstDayInMonth = startOfMonth(displayMonths[0]);
892
+ var lastDayInMonth = endOfMonth(displayMonths[displayMonths.length - 1]);
893
+ // TODO: cleanup code
894
+ var firstFocusableDay;
895
+ var today;
896
+ var date = firstDayInMonth;
897
+ while (date <= lastDayInMonth) {
898
+ var activeModifiers = getActiveModifiers(date, modifiers);
899
+ var isFocusable = !activeModifiers.disabled && !activeModifiers.hidden;
900
+ if (!isFocusable) {
901
+ date = addDays(date, 1);
902
+ continue;
903
+ }
904
+ if (activeModifiers.selected) {
905
+ return date;
906
+ }
907
+ if (activeModifiers.today && !today) {
908
+ today = date;
909
+ }
910
+ if (!firstFocusableDay) {
911
+ firstFocusableDay = date;
912
+ }
913
+ date = addDays(date, 1);
914
+ }
915
+ if (today) {
916
+ return today;
917
+ }
918
+ else {
919
+ return firstFocusableDay;
929
920
  }
930
- return context;
931
921
  }
932
922
 
933
- /**
934
- * Add a day to an existing range.
935
- *
936
- * The returned range takes in account the `undefined` values and if the added
937
- * day is already present in the range.
938
- */
939
- function addToRange(day, range) {
940
- var _a = range || {}, from = _a.from, to = _a.to;
941
- if (!from) {
942
- return { from: day, to: undefined };
943
- }
944
- if (!to && isSameDay(from, day)) {
945
- return { from: from, to: day };
946
- }
947
- if (!to && isBefore(day, from)) {
948
- return { from: day, to: from };
923
+ var MAX_RETRY = 365;
924
+ /** Return the next date to be focused. */
925
+ function getNextFocus(focusedDay, options) {
926
+ var moveBy = options.moveBy, direction = options.direction, context = options.context, modifiers = options.modifiers, _a = options.retry, retry = _a === void 0 ? { count: 0, lastFocused: focusedDay } : _a;
927
+ var weekStartsOn = context.weekStartsOn, fromDate = context.fromDate, toDate = context.toDate, locale = context.locale;
928
+ var moveFns = {
929
+ day: addDays,
930
+ week: addWeeks,
931
+ month: addMonths,
932
+ year: addYears,
933
+ startOfWeek: function (date) {
934
+ return context.ISOWeek
935
+ ? startOfISOWeek(date)
936
+ : startOfWeek(date, { locale: locale, weekStartsOn: weekStartsOn });
937
+ },
938
+ endOfWeek: function (date) {
939
+ return context.ISOWeek
940
+ ? endOfISOWeek(date)
941
+ : endOfWeek(date, { locale: locale, weekStartsOn: weekStartsOn });
942
+ }
943
+ };
944
+ var newFocusedDay = moveFns[moveBy](focusedDay, direction === 'after' ? 1 : -1);
945
+ if (direction === 'before' && fromDate) {
946
+ newFocusedDay = max([fromDate, newFocusedDay]);
949
947
  }
950
- if (!to) {
951
- return { from: from, to: day };
948
+ else if (direction === 'after' && toDate) {
949
+ newFocusedDay = min([toDate, newFocusedDay]);
952
950
  }
953
- if (isSameDay(to, day) && isSameDay(from, day)) {
954
- return undefined;
951
+ var isFocusable = true;
952
+ if (modifiers) {
953
+ var activeModifiers = getActiveModifiers(newFocusedDay, modifiers);
954
+ isFocusable = !activeModifiers.disabled && !activeModifiers.hidden;
955
955
  }
956
- if (isSameDay(to, day)) {
957
- return { from: to, to: undefined };
956
+ if (isFocusable) {
957
+ return newFocusedDay;
958
958
  }
959
- if (isSameDay(from, day)) {
960
- return undefined;
959
+ else {
960
+ if (retry.count > MAX_RETRY) {
961
+ return retry.lastFocused;
962
+ }
963
+ return getNextFocus(newFocusedDay, {
964
+ moveBy: moveBy,
965
+ direction: direction,
966
+ context: context,
967
+ modifiers: modifiers,
968
+ retry: __assign(__assign({}, retry), { count: retry.count + 1 })
969
+ });
961
970
  }
962
- if (isAfter(from, day)) {
963
- return { from: day, to: to };
971
+ }
972
+
973
+ /**
974
+ * The Focus context shares details about the focused day for the keyboard
975
+ *
976
+ * Access this context from the {@link useFocusContext} hook.
977
+ */
978
+ var FocusContext = createContext(undefined);
979
+ /** The provider for the {@link FocusContext}. */
980
+ function FocusProvider(props) {
981
+ var navigation = useNavigation();
982
+ var modifiers = useModifiers();
983
+ var _a = useState(), focusedDay = _a[0], setFocusedDay = _a[1];
984
+ var _b = useState(), lastFocused = _b[0], setLastFocused = _b[1];
985
+ var initialFocusTarget = getInitialFocusTarget(navigation.displayMonths, modifiers);
986
+ // TODO: cleanup and test obscure code below
987
+ var focusTarget = (focusedDay !== null && focusedDay !== void 0 ? focusedDay : (lastFocused && navigation.isDateDisplayed(lastFocused)))
988
+ ? lastFocused
989
+ : initialFocusTarget;
990
+ var blur = function () {
991
+ setLastFocused(focusedDay);
992
+ setFocusedDay(undefined);
993
+ };
994
+ var focus = function (date) {
995
+ setFocusedDay(date);
996
+ };
997
+ var context = useDayPicker();
998
+ var moveFocus = function (moveBy, direction) {
999
+ if (!focusedDay)
1000
+ return;
1001
+ var nextFocused = getNextFocus(focusedDay, {
1002
+ moveBy: moveBy,
1003
+ direction: direction,
1004
+ context: context,
1005
+ modifiers: modifiers
1006
+ });
1007
+ if (isSameDay(focusedDay, nextFocused))
1008
+ return undefined;
1009
+ navigation.goToDate(nextFocused, focusedDay);
1010
+ focus(nextFocused);
1011
+ };
1012
+ var value = {
1013
+ focusedDay: focusedDay,
1014
+ focusTarget: focusTarget,
1015
+ blur: blur,
1016
+ focus: focus,
1017
+ focusDayAfter: function () { return moveFocus('day', 'after'); },
1018
+ focusDayBefore: function () { return moveFocus('day', 'before'); },
1019
+ focusWeekAfter: function () { return moveFocus('week', 'after'); },
1020
+ focusWeekBefore: function () { return moveFocus('week', 'before'); },
1021
+ focusMonthBefore: function () { return moveFocus('month', 'before'); },
1022
+ focusMonthAfter: function () { return moveFocus('month', 'after'); },
1023
+ focusYearBefore: function () { return moveFocus('year', 'before'); },
1024
+ focusYearAfter: function () { return moveFocus('year', 'after'); },
1025
+ focusStartOfWeek: function () { return moveFocus('startOfWeek', 'before'); },
1026
+ focusEndOfWeek: function () { return moveFocus('endOfWeek', 'after'); }
1027
+ };
1028
+ return (React__default.createElement(FocusContext.Provider, { value: value }, props.children));
1029
+ }
1030
+ /**
1031
+ * Hook to access the {@link FocusContextValue}. Use this hook to handle the
1032
+ * focus state of the elements.
1033
+ *
1034
+ * This hook is meant to be used inside internal or custom components.
1035
+ */
1036
+ function useFocusContext() {
1037
+ var context = useContext(FocusContext);
1038
+ if (!context) {
1039
+ throw new Error('useFocusContext must be used within a FocusProvider');
964
1040
  }
965
- return { from: from, to: day };
1041
+ return context;
966
1042
  }
967
1043
 
968
1044
  /**
969
- * The SelectRange context shares details about the selected days when in
970
- * range selection mode.
1045
+ * Return the active modifiers for the specified day.
971
1046
  *
972
- * Access this context from the {@link useSelectRange} hook.
1047
+ * This hook is meant to be used inside internal or custom components.
1048
+ *
1049
+ * @param day
1050
+ * @param displayMonth
973
1051
  */
974
- var SelectRangeContext = createContext(undefined);
975
- /** Provides the values for the {@link SelectRangeProvider}. */
976
- function SelectRangeProvider(props) {
977
- if (!isDayPickerRange(props.initialProps)) {
1052
+ function useActiveModifiers(day,
1053
+ /**
1054
+ * The month where the date is displayed. If not the same as `date`, the day
1055
+ * is an "outside day".
1056
+ */
1057
+ displayMonth) {
1058
+ var modifiers = useModifiers();
1059
+ var activeModifiers = getActiveModifiers(day, modifiers, displayMonth);
1060
+ return activeModifiers;
1061
+ }
1062
+
1063
+ /**
1064
+ * The SelectSingle context shares details about the selected days when in
1065
+ * single selection mode.
1066
+ *
1067
+ * Access this context from the {@link useSelectSingle} hook.
1068
+ */
1069
+ var SelectSingleContext = createContext(undefined);
1070
+ /** Provides the values for the {@link SelectSingleProvider}. */
1071
+ function SelectSingleProvider(props) {
1072
+ if (!isDayPickerSingle(props.initialProps)) {
978
1073
  var emptyContextValue = {
979
- selected: undefined,
980
- modifiers: {
981
- range_start: [],
982
- range_end: [],
983
- range_middle: [],
984
- disabled: []
985
- }
1074
+ selected: undefined
986
1075
  };
987
- return (React__default.createElement(SelectRangeContext.Provider, { value: emptyContextValue }, props.children));
1076
+ return (React__default.createElement(SelectSingleContext.Provider, { value: emptyContextValue }, props.children));
988
1077
  }
989
- return (React__default.createElement(SelectRangeProviderInternal, { initialProps: props.initialProps, children: props.children }));
1078
+ return (React__default.createElement(SelectSingleProviderInternal, { initialProps: props.initialProps, children: props.children }));
990
1079
  }
991
- function SelectRangeProviderInternal(_a) {
1080
+ function SelectSingleProviderInternal(_a) {
992
1081
  var initialProps = _a.initialProps, children = _a.children;
993
- var selected = initialProps.selected;
994
- var _b = selected || {}, selectedFrom = _b.from, selectedTo = _b.to;
995
- var min = initialProps.min;
996
- var max = initialProps.max;
997
1082
  var onDayClick = function (day, activeModifiers, e) {
998
- var _a, _b;
1083
+ var _a, _b, _c;
999
1084
  (_a = initialProps.onDayClick) === null || _a === void 0 ? void 0 : _a.call(initialProps, day, activeModifiers, e);
1000
- var range = addToRange(day, selected);
1001
- if ((min || max) &&
1002
- selected &&
1003
- (range === null || range === void 0 ? void 0 : range.to) &&
1004
- range.from &&
1005
- range.from !== range.to) {
1006
- var diff = Math.abs(differenceInCalendarDays(range === null || range === void 0 ? void 0 : range.to, range === null || range === void 0 ? void 0 : range.from));
1007
- if ((min && diff < min) || (max && diff >= max)) {
1008
- return;
1009
- }
1085
+ if (activeModifiers.selected && !initialProps.required) {
1086
+ (_b = initialProps.onSelect) === null || _b === void 0 ? void 0 : _b.call(initialProps, undefined, day, activeModifiers, e);
1087
+ return;
1010
1088
  }
1011
- (_b = initialProps.onSelect) === null || _b === void 0 ? void 0 : _b.call(initialProps, range, day, activeModifiers, e);
1089
+ (_c = initialProps.onSelect) === null || _c === void 0 ? void 0 : _c.call(initialProps, day, day, activeModifiers, e);
1012
1090
  };
1013
- var modifiers = {
1014
- range_start: [],
1015
- range_end: [],
1016
- range_middle: [],
1017
- disabled: []
1091
+ var contextValue = {
1092
+ selected: initialProps.selected,
1093
+ onDayClick: onDayClick
1018
1094
  };
1019
- if (selectedFrom) {
1020
- modifiers.range_start = [selectedFrom];
1021
- if (!selectedTo) {
1022
- modifiers.range_end = [selectedFrom];
1023
- }
1024
- else {
1025
- modifiers.range_end = [selectedTo];
1026
- modifiers.range_middle = [
1027
- {
1028
- after: selectedFrom,
1029
- before: selectedTo
1030
- }
1031
- ];
1032
- }
1033
- }
1034
- if (min && selectedFrom && selectedTo) {
1035
- modifiers.disabled.push(function (date) {
1036
- return ((isBefore(date, selectedFrom) &&
1037
- differenceInCalendarDays(selectedFrom, date) < min) ||
1038
- (isAfter(date, selectedTo) &&
1039
- differenceInCalendarDays(date, selectedFrom) < min));
1040
- });
1041
- }
1042
- if (max && selectedFrom && selectedTo) {
1043
- modifiers.disabled.push(function (date) {
1044
- return ((isBefore(date, selectedFrom) &&
1045
- differenceInCalendarDays(selectedTo, date) >= max) ||
1046
- (isAfter(date, selectedTo) &&
1047
- differenceInCalendarDays(date, selectedFrom) >= max));
1048
- });
1049
- }
1050
- return (React__default.createElement(SelectRangeContext.Provider, { value: { selected: selected, onDayClick: onDayClick, modifiers: modifiers } }, children));
1095
+ return (React__default.createElement(SelectSingleContext.Provider, { value: contextValue }, children));
1051
1096
  }
1052
-
1053
1097
  /**
1054
- * Hook to access the {@link SelectRangeContextValue}.
1098
+ * Hook to access the {@link SelectSingleContextValue}.
1055
1099
  *
1056
1100
  * This hook is meant to be used inside internal or custom components.
1057
1101
  */
1058
- function useSelectRange() {
1059
- var context = useContext(SelectRangeContext);
1102
+ function useSelectSingle() {
1103
+ var context = useContext(SelectSingleContext);
1060
1104
  if (!context) {
1061
- throw new Error('useSelectRange must be used within a SelectRangeProvider');
1105
+ throw new Error('useSelectSingle must be used within a SelectSingleProvider');
1062
1106
  }
1063
1107
  return context;
1064
1108
  }
1065
1109
 
1066
- /** Normalize to array a matcher input. */
1067
- function matcherToArray(matcher) {
1068
- if (Array.isArray(matcher)) {
1069
- return matcher;
1070
- }
1071
- else if (matcher !== undefined) {
1072
- return [matcher];
1073
- }
1074
- else {
1075
- return [];
1076
- }
1077
- }
1078
-
1079
- /** Create CustomModifiers from dayModifiers */
1080
- function getCustomModifiers(dayModifiers) {
1081
- var customModifiers = {};
1082
- Object.entries(dayModifiers).forEach(function (_a) {
1083
- var modifier = _a[0], matcher = _a[1];
1084
- customModifiers[modifier] = matcherToArray(matcher);
1085
- });
1086
- return customModifiers;
1087
- }
1088
-
1089
- /** The name of the modifiers that are used internally by DayPicker. */
1090
- var InternalModifier;
1091
- (function (InternalModifier) {
1092
- InternalModifier["Outside"] = "outside";
1093
- /** Name of the modifier applied to the disabled days, using the `disabled` prop. */
1094
- InternalModifier["Disabled"] = "disabled";
1095
- /** Name of the modifier applied to the selected days using the `selected` prop). */
1096
- InternalModifier["Selected"] = "selected";
1097
- /** Name of the modifier applied to the hidden days using the `hidden` prop). */
1098
- InternalModifier["Hidden"] = "hidden";
1099
- /** Name of the modifier applied to the day specified using the `today` prop). */
1100
- InternalModifier["Today"] = "today";
1101
- /** The modifier applied to the day starting a selected range, when in range selection mode. */
1102
- InternalModifier["RangeStart"] = "range_start";
1103
- /** The modifier applied to the day ending a selected range, when in range selection mode. */
1104
- InternalModifier["RangeEnd"] = "range_end";
1105
- /** The modifier applied to the days between the start and the end of a selected range, when in range selection mode. */
1106
- InternalModifier["RangeMiddle"] = "range_middle";
1107
- })(InternalModifier || (InternalModifier = {}));
1108
-
1109
- var Selected = InternalModifier.Selected, Disabled = InternalModifier.Disabled, Hidden = InternalModifier.Hidden, Today = InternalModifier.Today, RangeEnd = InternalModifier.RangeEnd, RangeMiddle = InternalModifier.RangeMiddle, RangeStart = InternalModifier.RangeStart, Outside = InternalModifier.Outside;
1110
- /** Return the {@link InternalModifiers} from the DayPicker and select contexts. */
1111
- function getInternalModifiers(dayPicker, selectMultiple, selectRange) {
1112
- var _a;
1113
- var internalModifiers = (_a = {},
1114
- _a[Selected] = matcherToArray(dayPicker.selected),
1115
- _a[Disabled] = matcherToArray(dayPicker.disabled),
1116
- _a[Hidden] = matcherToArray(dayPicker.hidden),
1117
- _a[Today] = [dayPicker.today],
1118
- _a[RangeEnd] = [],
1119
- _a[RangeMiddle] = [],
1120
- _a[RangeStart] = [],
1121
- _a[Outside] = [],
1122
- _a);
1123
- if (dayPicker.fromDate) {
1124
- internalModifiers[Disabled].push({ before: dayPicker.fromDate });
1125
- }
1126
- if (dayPicker.toDate) {
1127
- internalModifiers[Disabled].push({ after: dayPicker.toDate });
1128
- }
1129
- if (isDayPickerMultiple(dayPicker)) {
1130
- internalModifiers[Disabled] = internalModifiers[Disabled].concat(selectMultiple.modifiers[Disabled]);
1131
- }
1132
- else if (isDayPickerRange(dayPicker)) {
1133
- internalModifiers[Disabled] = internalModifiers[Disabled].concat(selectRange.modifiers[Disabled]);
1134
- internalModifiers[RangeStart] = selectRange.modifiers[RangeStart];
1135
- internalModifiers[RangeMiddle] = selectRange.modifiers[RangeMiddle];
1136
- internalModifiers[RangeEnd] = selectRange.modifiers[RangeEnd];
1137
- }
1138
- return internalModifiers;
1139
- }
1140
-
1141
- /** The Modifiers context store the modifiers used in DayPicker. To access the value of this context, use {@link useModifiers}. */
1142
- var ModifiersContext = createContext(undefined);
1143
- /** Provide the value for the {@link ModifiersContext}. */
1144
- function ModifiersProvider(props) {
1110
+ /**
1111
+ * This hook returns details about the content to render in the day cell.
1112
+ *
1113
+ *
1114
+ * When a day cell is rendered in the table, DayPicker can either:
1115
+ *
1116
+ * - render nothing: when the day is outside the month or has matched the
1117
+ * "hidden" modifier.
1118
+ * - render a button when `onDayClick` or a selection mode is set.
1119
+ * - render a non-interactive element: when no selection mode is set, the day
1120
+ * cell shouldn’t respond to any interaction. DayPicker should render a `div`
1121
+ * or a `span`.
1122
+ *
1123
+ * ### Usage
1124
+ *
1125
+ * Use this hook to customize the behavior of the {@link Day} component. Create a
1126
+ * new `Day` component using this hook and pass it to the `components` prop.
1127
+ * The source of {@link Day} can be a good starting point.
1128
+ *
1129
+ */
1130
+ function useDayEventHandlers(date, activeModifiers) {
1145
1131
  var dayPicker = useDayPicker();
1146
- var selectMultiple = useSelectMultiple();
1147
- var selectRange = useSelectRange();
1148
- var internalModifiers = getInternalModifiers(dayPicker, selectMultiple, selectRange);
1149
- var customModifiers = getCustomModifiers(dayPicker.modifiers);
1150
- var modifiers = __assign(__assign({}, internalModifiers), customModifiers);
1151
- return (React__default.createElement(ModifiersContext.Provider, { value: modifiers }, props.children));
1132
+ var single = useSelectSingle();
1133
+ var multiple = useSelectMultiple();
1134
+ var range = useSelectRange();
1135
+ var _a = useFocusContext(), focusDayAfter = _a.focusDayAfter, focusDayBefore = _a.focusDayBefore, focusWeekAfter = _a.focusWeekAfter, focusWeekBefore = _a.focusWeekBefore, blur = _a.blur, focus = _a.focus, focusMonthBefore = _a.focusMonthBefore, focusMonthAfter = _a.focusMonthAfter, focusYearBefore = _a.focusYearBefore, focusYearAfter = _a.focusYearAfter, focusStartOfWeek = _a.focusStartOfWeek, focusEndOfWeek = _a.focusEndOfWeek;
1136
+ var onClick = function (e) {
1137
+ var _a, _b, _c, _d;
1138
+ if (isDayPickerSingle(dayPicker)) {
1139
+ (_a = single.onDayClick) === null || _a === void 0 ? void 0 : _a.call(single, date, activeModifiers, e);
1140
+ }
1141
+ else if (isDayPickerMultiple(dayPicker)) {
1142
+ (_b = multiple.onDayClick) === null || _b === void 0 ? void 0 : _b.call(multiple, date, activeModifiers, e);
1143
+ }
1144
+ else if (isDayPickerRange(dayPicker)) {
1145
+ (_c = range.onDayClick) === null || _c === void 0 ? void 0 : _c.call(range, date, activeModifiers, e);
1146
+ }
1147
+ else {
1148
+ (_d = dayPicker.onDayClick) === null || _d === void 0 ? void 0 : _d.call(dayPicker, date, activeModifiers, e);
1149
+ }
1150
+ };
1151
+ var onFocus = function (e) {
1152
+ var _a;
1153
+ focus(date);
1154
+ (_a = dayPicker.onDayFocus) === null || _a === void 0 ? void 0 : _a.call(dayPicker, date, activeModifiers, e);
1155
+ };
1156
+ var onBlur = function (e) {
1157
+ var _a;
1158
+ blur();
1159
+ (_a = dayPicker.onDayBlur) === null || _a === void 0 ? void 0 : _a.call(dayPicker, date, activeModifiers, e);
1160
+ };
1161
+ var onMouseEnter = function (e) {
1162
+ var _a;
1163
+ (_a = dayPicker.onDayMouseEnter) === null || _a === void 0 ? void 0 : _a.call(dayPicker, date, activeModifiers, e);
1164
+ };
1165
+ var onMouseLeave = function (e) {
1166
+ var _a;
1167
+ (_a = dayPicker.onDayMouseLeave) === null || _a === void 0 ? void 0 : _a.call(dayPicker, date, activeModifiers, e);
1168
+ };
1169
+ var onTouchCancel = function (e) {
1170
+ var _a;
1171
+ (_a = dayPicker.onDayTouchCancel) === null || _a === void 0 ? void 0 : _a.call(dayPicker, date, activeModifiers, e);
1172
+ };
1173
+ var onTouchEnd = function (e) {
1174
+ var _a;
1175
+ (_a = dayPicker.onDayTouchEnd) === null || _a === void 0 ? void 0 : _a.call(dayPicker, date, activeModifiers, e);
1176
+ };
1177
+ var onTouchMove = function (e) {
1178
+ var _a;
1179
+ (_a = dayPicker.onDayTouchMove) === null || _a === void 0 ? void 0 : _a.call(dayPicker, date, activeModifiers, e);
1180
+ };
1181
+ var onTouchStart = function (e) {
1182
+ var _a;
1183
+ (_a = dayPicker.onDayTouchStart) === null || _a === void 0 ? void 0 : _a.call(dayPicker, date, activeModifiers, e);
1184
+ };
1185
+ var onKeyUp = function (e) {
1186
+ var _a;
1187
+ (_a = dayPicker.onDayKeyUp) === null || _a === void 0 ? void 0 : _a.call(dayPicker, date, activeModifiers, e);
1188
+ };
1189
+ var onKeyDown = function (e) {
1190
+ var _a;
1191
+ switch (e.key) {
1192
+ case 'ArrowLeft':
1193
+ e.preventDefault();
1194
+ e.stopPropagation();
1195
+ dayPicker.dir === 'rtl' ? focusDayAfter() : focusDayBefore();
1196
+ break;
1197
+ case 'ArrowRight':
1198
+ e.preventDefault();
1199
+ e.stopPropagation();
1200
+ dayPicker.dir === 'rtl' ? focusDayBefore() : focusDayAfter();
1201
+ break;
1202
+ case 'ArrowDown':
1203
+ e.preventDefault();
1204
+ e.stopPropagation();
1205
+ focusWeekAfter();
1206
+ break;
1207
+ case 'ArrowUp':
1208
+ e.preventDefault();
1209
+ e.stopPropagation();
1210
+ focusWeekBefore();
1211
+ break;
1212
+ case 'PageUp':
1213
+ e.preventDefault();
1214
+ e.stopPropagation();
1215
+ e.shiftKey ? focusYearBefore() : focusMonthBefore();
1216
+ break;
1217
+ case 'PageDown':
1218
+ e.preventDefault();
1219
+ e.stopPropagation();
1220
+ e.shiftKey ? focusYearAfter() : focusMonthAfter();
1221
+ break;
1222
+ case 'Home':
1223
+ e.preventDefault();
1224
+ e.stopPropagation();
1225
+ focusStartOfWeek();
1226
+ break;
1227
+ case 'End':
1228
+ e.preventDefault();
1229
+ e.stopPropagation();
1230
+ focusEndOfWeek();
1231
+ break;
1232
+ }
1233
+ (_a = dayPicker.onDayKeyDown) === null || _a === void 0 ? void 0 : _a.call(dayPicker, date, activeModifiers, e);
1234
+ };
1235
+ var eventHandlers = {
1236
+ onClick: onClick,
1237
+ onFocus: onFocus,
1238
+ onBlur: onBlur,
1239
+ onKeyDown: onKeyDown,
1240
+ onKeyUp: onKeyUp,
1241
+ onMouseEnter: onMouseEnter,
1242
+ onMouseLeave: onMouseLeave,
1243
+ onTouchCancel: onTouchCancel,
1244
+ onTouchEnd: onTouchEnd,
1245
+ onTouchMove: onTouchMove,
1246
+ onTouchStart: onTouchStart
1247
+ };
1248
+ return eventHandlers;
1152
1249
  }
1153
1250
 
1154
1251
  /**
1155
- * Return the modifiers used by DayPicker.
1252
+ * Return the current selected days when DayPicker is in selection mode. Days
1253
+ * selected by the custom selection mode are not returned.
1156
1254
  *
1157
1255
  * This hook is meant to be used inside internal or custom components.
1158
- * Requires to be wrapped into {@link ModifiersProvider}.
1159
1256
  *
1160
1257
  */
1161
- function useModifiers() {
1162
- var context = useContext(ModifiersContext);
1163
- if (!context) {
1164
- throw new Error('useModifiers must be used within a ModifiersProvider');
1165
- }
1166
- return context;
1258
+ function useSelectedDays() {
1259
+ var dayPicker = useDayPicker();
1260
+ var single = useSelectSingle();
1261
+ var multiple = useSelectMultiple();
1262
+ var range = useSelectRange();
1263
+ var selectedDays = isDayPickerSingle(dayPicker)
1264
+ ? single.selected
1265
+ : isDayPickerMultiple(dayPicker)
1266
+ ? multiple.selected
1267
+ : isDayPickerRange(dayPicker)
1268
+ ? range.selected
1269
+ : undefined;
1270
+ return selectedDays;
1167
1271
  }
1168
1272
 
1169
- /** Returns true if `matcher` is of type {@link DateInterval}. */
1170
- function isDateInterval(matcher) {
1171
- return Boolean(matcher &&
1172
- typeof matcher === 'object' &&
1173
- 'before' in matcher &&
1174
- 'after' in matcher);
1175
- }
1176
- /** Returns true if `value` is a {@link DateRange} type. */
1177
- function isDateRange(value) {
1178
- return Boolean(value && typeof value === 'object' && 'from' in value);
1179
- }
1180
- /** Returns true if `value` is of type {@link DateAfter}. */
1181
- function isDateAfterType(value) {
1182
- return Boolean(value && typeof value === 'object' && 'after' in value);
1273
+ function isInternalModifier(modifier) {
1274
+ return Object.values(InternalModifier).includes(modifier);
1183
1275
  }
1184
- /** Returns true if `value` is of type {@link DateBefore}. */
1185
- function isDateBeforeType(value) {
1186
- return Boolean(value && typeof value === 'object' && 'before' in value);
1276
+ /**
1277
+ * Return the class names for the Day element, according to the given active
1278
+ * modifiers.
1279
+ *
1280
+ * Custom class names are set via `modifiersClassNames` or `classNames`,
1281
+ * where the first have the precedence.
1282
+ */
1283
+ function getDayClassNames(dayPicker, activeModifiers) {
1284
+ var classNames = [dayPicker.classNames.day];
1285
+ Object.keys(activeModifiers).forEach(function (modifier) {
1286
+ var customClassName = dayPicker.modifiersClassNames[modifier];
1287
+ if (customClassName) {
1288
+ classNames.push(customClassName);
1289
+ }
1290
+ else if (isInternalModifier(modifier)) {
1291
+ var internalClassName = dayPicker.classNames["day_".concat(modifier)];
1292
+ if (internalClassName) {
1293
+ classNames.push(internalClassName);
1294
+ }
1295
+ }
1296
+ });
1297
+ return classNames;
1187
1298
  }
1188
- /** Returns true if `value` is a {@link DayOfWeek} type. */
1189
- function isDayOfWeekType(value) {
1190
- return Boolean(value && typeof value === 'object' && 'dayOfWeek' in value);
1299
+
1300
+ /** Return the style for the Day element, according to the given active modifiers. */
1301
+ function getDayStyle(dayPicker, activeModifiers) {
1302
+ var style = __assign({}, dayPicker.styles.day);
1303
+ Object.keys(activeModifiers).forEach(function (modifier) {
1304
+ var _a;
1305
+ style = __assign(__assign({}, style), (_a = dayPicker.modifiersStyles) === null || _a === void 0 ? void 0 : _a[modifier]);
1306
+ });
1307
+ return style;
1191
1308
  }
1192
1309
 
1193
- /** Return `true` whether `date` is inside `range`. */
1194
- function isDateInRange(date, range) {
1310
+ /**
1311
+ * Return props and data used to render the {@link Day} component.
1312
+ *
1313
+ * Use this hook when creating a component to replace the built-in `Day`
1314
+ * component.
1315
+ */
1316
+ function useDayRender(
1317
+ /** The date to render. */
1318
+ day,
1319
+ /** The month where the date is displayed (if not the same as `date`, it means it is an "outside" day). */
1320
+ displayMonth,
1321
+ /** A ref to the button element that will be target of focus when rendered (if required). */
1322
+ buttonRef) {
1195
1323
  var _a;
1196
- var from = range.from, to = range.to;
1197
- if (!from) {
1198
- return false;
1199
- }
1200
- if (!to && isSameDay(from, date)) {
1201
- return true;
1202
- }
1203
- if (!to) {
1204
- return false;
1324
+ var _b = useDayPicker(), DayContent = _b.components.DayContent, dayPicker = __rest(_b, ["components"]);
1325
+ var focusContext = useFocusContext();
1326
+ var activeModifiers = useActiveModifiers(day, displayMonth);
1327
+ var eventHandlers = useDayEventHandlers(day, activeModifiers);
1328
+ var selectedDays = useSelectedDays();
1329
+ var isButton = Boolean(dayPicker.onDayClick || dayPicker.mode !== 'default');
1330
+ // Focus the button if the day is focused according to the focus context
1331
+ useEffect(function () {
1332
+ var _a;
1333
+ if (activeModifiers.outside)
1334
+ return;
1335
+ if (!focusContext.focusedDay)
1336
+ return;
1337
+ if (!isButton)
1338
+ return;
1339
+ if (isSameDay(focusContext.focusedDay, day)) {
1340
+ (_a = buttonRef.current) === null || _a === void 0 ? void 0 : _a.focus();
1341
+ }
1342
+ }, [
1343
+ focusContext.focusedDay,
1344
+ day,
1345
+ buttonRef,
1346
+ isButton,
1347
+ activeModifiers.outside
1348
+ ]);
1349
+ var className = getDayClassNames(dayPicker, activeModifiers).join(' ');
1350
+ var style = getDayStyle(dayPicker, activeModifiers);
1351
+ var ariaLabel = dayPicker.labels.labelDay(day, activeModifiers, {
1352
+ locale: dayPicker.locale
1353
+ });
1354
+ var isHidden = Boolean((activeModifiers.outside && !dayPicker.showOutsideDays) ||
1355
+ activeModifiers.hidden);
1356
+ var children = (React__default.createElement(DayContent, { date: day, displayMonth: displayMonth, activeModifiers: activeModifiers }));
1357
+ var divProps = {
1358
+ style: style,
1359
+ className: className,
1360
+ children: children,
1361
+ 'aria-label': ariaLabel
1362
+ };
1363
+ var isFocusTarget = Boolean(focusContext.focusTarget && isSameDay(focusContext.focusTarget, day));
1364
+ var buttonProps = __assign(__assign(__assign({}, divProps), (_a = { disabled: activeModifiers.disabled }, _a['aria-pressed'] = activeModifiers.selected, _a['aria-label'] = ariaLabel, _a.tabIndex = isFocusTarget ? 0 : -1, _a)), eventHandlers);
1365
+ var dayRender = {
1366
+ isButton: isButton,
1367
+ isHidden: isHidden,
1368
+ activeModifiers: activeModifiers,
1369
+ selectedDays: selectedDays,
1370
+ buttonProps: buttonProps,
1371
+ divProps: divProps
1372
+ };
1373
+ return dayRender;
1374
+ }
1375
+
1376
+ /**
1377
+ * The content of a day cell – as a button or span element according to its
1378
+ * modifiers.
1379
+ */
1380
+ function Day(props) {
1381
+ var buttonRef = useRef(null);
1382
+ var dayRender = useDayRender(props.date, props.displayMonth, buttonRef);
1383
+ if (dayRender.isHidden) {
1384
+ return React__default.createElement(React__default.Fragment, null);
1205
1385
  }
1206
- var isToBeforeFrom = differenceInCalendarDays(to, from) < 0;
1207
- if (to && isToBeforeFrom) {
1208
- _a = [to, from], from = _a[0], to = _a[1];
1386
+ if (!dayRender.isButton) {
1387
+ return React__default.createElement("div", __assign({}, dayRender.divProps));
1209
1388
  }
1210
- return (differenceInCalendarDays(date, from) >= 0 &&
1211
- differenceInCalendarDays(to, date) >= 0);
1389
+ return React__default.createElement(Button, __assign({ name: "day", ref: buttonRef }, dayRender.buttonProps));
1212
1390
  }
1213
1391
 
1214
- /** Returns true if `value` is a Date type. */
1215
- function isDateType(value) {
1216
- return isDate(value);
1392
+ /** Render the content of the day cell. */
1393
+ function DayContent(props) {
1394
+ var _a = useDayPicker(), locale = _a.locale, formatDay = _a.formatters.formatDay;
1395
+ return React__default.createElement(React__default.Fragment, null, formatDay(props.date, { locale: locale }));
1396
+ }
1397
+
1398
+ /**
1399
+ * Render a styled select component – displaying a caption and a custom
1400
+ * drop-down icon.
1401
+ */
1402
+ function Dropdown(props) {
1403
+ var onChange = props.onChange, value = props.value, children = props.children, caption = props.caption, className = props.className, style = props.style;
1404
+ var _a = useDayPicker(), IconDropdown = _a.components.IconDropdown, dayPicker = __rest(_a, ["components"]);
1405
+ return (React__default.createElement("div", { className: className, style: style },
1406
+ React__default.createElement("span", { className: dayPicker.classNames.vhidden }, props['aria-label']),
1407
+ React__default.createElement("select", { name: props.name, "aria-label": props['aria-label'], className: dayPicker.classNames.dropdown, style: dayPicker.styles.dropdown, value: value, onChange: onChange }, children),
1408
+ React__default.createElement("div", { className: dayPicker.classNames.caption_label, style: dayPicker.styles.caption_label, "aria-hidden": "true" },
1409
+ caption,
1410
+ React__default.createElement(IconDropdown, { className: dayPicker.classNames.dropdown_icon, style: dayPicker.styles.dropdown_icon }))));
1411
+ }
1412
+
1413
+ /** Render the Footer component (empty as default).*/
1414
+ function Footer() {
1415
+ var _a = useDayPicker(), footer = _a.footer, styles = _a.styles, tfoot = _a.classNames.tfoot;
1416
+ if (!footer)
1417
+ return React__default.createElement(React__default.Fragment, null);
1418
+ return (React__default.createElement("tfoot", { className: tfoot, style: styles.tfoot },
1419
+ React__default.createElement("tr", null,
1420
+ React__default.createElement("td", { colSpan: 8 }, footer))));
1421
+ }
1422
+
1423
+ /** Render the table head. */
1424
+ function Head() {
1425
+ var _a = useDayPicker(), classNames = _a.classNames, styles = _a.styles, HeadRow = _a.components.HeadRow;
1426
+ return (React__default.createElement("thead", { style: styles.head, className: classNames.head },
1427
+ React__default.createElement(HeadRow, null)));
1428
+ }
1429
+
1430
+ /**
1431
+ * Generate a series of 7 days, starting from the week, to use for formatting
1432
+ * the weekday names (Monday, Tuesday, etc.).
1433
+ */
1434
+ function getWeekdays(locale,
1435
+ /** The index of the first day of the week (0 - Sunday). */
1436
+ weekStartsOn,
1437
+ /** Use ISOWeek instead of locale/ */
1438
+ ISOWeek) {
1439
+ var start = ISOWeek
1440
+ ? startOfISOWeek(new Date())
1441
+ : startOfWeek(new Date(), { locale: locale, weekStartsOn: weekStartsOn });
1442
+ var days = [];
1443
+ for (var i = 0; i < 7; i++) {
1444
+ var day = addDays(start, i);
1445
+ days.push(day);
1446
+ }
1447
+ return days;
1217
1448
  }
1218
- /** Returns true if `value` is an array of valid dates. */
1219
- function isArrayOfDates(value) {
1220
- return Array.isArray(value) && value.every(isDate);
1449
+
1450
+ /**
1451
+ * Render the HeadRow component - i.e. the table head row with the weekday names.
1452
+ */
1453
+ function HeadRow() {
1454
+ var _a = useDayPicker(), classNames = _a.classNames, styles = _a.styles, showWeekNumber = _a.showWeekNumber, locale = _a.locale, weekStartsOn = _a.weekStartsOn, ISOWeek = _a.ISOWeek, formatWeekdayName = _a.formatters.formatWeekdayName, labelWeekday = _a.labels.labelWeekday;
1455
+ var weekdays = getWeekdays(locale, weekStartsOn, ISOWeek);
1456
+ return (React__default.createElement("tr", { style: styles.head_row, className: classNames.head_row },
1457
+ showWeekNumber && (React__default.createElement("th", { scope: "col", style: styles.head_cell, className: classNames.head_cell })),
1458
+ weekdays.map(function (weekday, i) { return (React__default.createElement("th", { key: i, scope: "col", className: classNames.head_cell, style: styles.head_cell },
1459
+ React__default.createElement("span", { "aria-hidden": true }, formatWeekdayName(weekday, { locale: locale })),
1460
+ React__default.createElement("span", { className: classNames.vhidden }, labelWeekday(weekday, { locale: locale })))); })));
1221
1461
  }
1462
+
1222
1463
  /**
1223
- * Returns whether a day matches against at least one of the given Matchers.
1224
- *
1225
- * ```
1226
- * const day = new Date(2022, 5, 19);
1227
- * const matcher1: DateRange = {
1228
- * from: new Date(2021, 12, 21),
1229
- * to: new Date(2021, 12, 30)
1230
- * }
1231
- * const matcher2: DateRange = {
1232
- * from: new Date(2022, 5, 1),
1233
- * to: new Date(2022, 5, 23)
1234
- * }
1235
- *
1236
- * const isMatch(day, [matcher1, matcher2]); // true, since day is in the matcher1 range.
1237
- * ```
1238
- * */
1239
- function isMatch(day, matchers) {
1240
- return matchers.some(function (matcher) {
1241
- if (typeof matcher === 'boolean') {
1242
- return matcher;
1243
- }
1244
- if (isDateType(matcher)) {
1245
- return isSameDay(day, matcher);
1246
- }
1247
- if (isArrayOfDates(matcher)) {
1248
- return matcher.includes(day);
1249
- }
1250
- if (isDateRange(matcher)) {
1251
- return isDateInRange(day, matcher);
1252
- }
1253
- if (isDayOfWeekType(matcher)) {
1254
- return matcher.dayOfWeek.includes(day.getDay());
1255
- }
1256
- if (isDateInterval(matcher)) {
1257
- var isBefore = differenceInCalendarDays(matcher.before, day) > 0;
1258
- var isAfter = differenceInCalendarDays(day, matcher.after) > 0;
1259
- return isBefore && isAfter;
1260
- }
1261
- if (isDateAfterType(matcher)) {
1262
- return differenceInCalendarDays(day, matcher.after) > 0;
1263
- }
1264
- if (isDateBeforeType(matcher)) {
1265
- return differenceInCalendarDays(matcher.before, day) > 0;
1266
- }
1267
- if (typeof matcher === 'function') {
1268
- return matcher(day);
1269
- }
1270
- return false;
1271
- });
1464
+ * Render the icon in the styled drop-down.
1465
+ */
1466
+ function IconDropdown(props) {
1467
+ return (React__default.createElement("svg", __assign({ width: "8px", height: "8px", viewBox: "0 0 120 120", "data-testid": "iconDropdown" }, props),
1468
+ React__default.createElement("path", { d: "M4.22182541,48.2218254 C8.44222828,44.0014225 15.2388494,43.9273804 19.5496459,47.9996989 L19.7781746,48.2218254 L60,88.443 L100.221825,48.2218254 C104.442228,44.0014225 111.238849,43.9273804 115.549646,47.9996989 L115.778175,48.2218254 C119.998577,52.4422283 120.07262,59.2388494 116.000301,63.5496459 L115.778175,63.7781746 L67.7781746,111.778175 C63.5577717,115.998577 56.7611506,116.07262 52.4503541,112.000301 L52.2218254,111.778175 L4.22182541,63.7781746 C-0.0739418023,59.4824074 -0.0739418023,52.5175926 4.22182541,48.2218254 Z", fill: "currentColor", fillRule: "nonzero" })));
1272
1469
  }
1273
1470
 
1274
- /** Return the active modifiers for the given day. */
1275
- function getActiveModifiers(day,
1276
- /** The modifiers to match for the given date. */
1277
- modifiers,
1278
- /** The month where the day is displayed, to add the "outside" modifiers. */
1279
- displayMonth) {
1280
- var matchedModifiers = Object.keys(modifiers).reduce(function (result, key) {
1281
- var modifier = modifiers[key];
1282
- if (isMatch(day, modifier)) {
1283
- result.push(key);
1284
- }
1285
- return result;
1286
- }, []);
1287
- var activeModifiers = {};
1288
- matchedModifiers.forEach(function (modifier) { return (activeModifiers[modifier] = true); });
1289
- if (displayMonth && !isSameMonth(day, displayMonth)) {
1290
- activeModifiers.outside = true;
1291
- }
1292
- return activeModifiers;
1471
+ /**
1472
+ * Render the "previous month" button in the navigation.
1473
+ */
1474
+ function IconLeft(props) {
1475
+ return (React__default.createElement("svg", __assign({ width: "16px", height: "16px", viewBox: "0 0 120 120" }, props),
1476
+ React__default.createElement("path", { d: "M69.490332,3.34314575 C72.6145263,0.218951416 77.6798462,0.218951416 80.8040405,3.34314575 C83.8617626,6.40086786 83.9268205,11.3179931 80.9992143,14.4548388 L80.8040405,14.6568542 L35.461,60 L80.8040405,105.343146 C83.8617626,108.400868 83.9268205,113.317993 80.9992143,116.454839 L80.8040405,116.656854 C77.7463184,119.714576 72.8291931,119.779634 69.6923475,116.852028 L69.490332,116.656854 L18.490332,65.6568542 C15.4326099,62.5991321 15.367552,57.6820069 18.2951583,54.5451612 L18.490332,54.3431458 L69.490332,3.34314575 Z", fill: "currentColor", fillRule: "nonzero" })));
1293
1477
  }
1294
1478
 
1295
- /** Returns the day that should be the target of the focus when DayPicker is rendered the first time. */
1296
- function getInitialFocusTarget(displayMonths, modifiers) {
1297
- var firstDayInMonth = startOfMonth(displayMonths[0]);
1298
- var lastDayInMonth = endOfMonth(displayMonths[displayMonths.length - 1]);
1299
- // TODO: cleanup code
1300
- var firstFocusableDay;
1301
- var today;
1302
- var date = firstDayInMonth;
1303
- while (date <= lastDayInMonth) {
1304
- var activeModifiers = getActiveModifiers(date, modifiers);
1305
- var isFocusable = !activeModifiers.disabled && !activeModifiers.hidden;
1306
- if (!isFocusable) {
1307
- date = addDays(date, 1);
1308
- continue;
1309
- }
1310
- if (activeModifiers.selected) {
1311
- return date;
1312
- }
1313
- if (activeModifiers.today && !today) {
1314
- today = date;
1315
- }
1316
- if (!firstFocusableDay) {
1317
- firstFocusableDay = date;
1318
- }
1319
- date = addDays(date, 1);
1320
- }
1321
- if (today) {
1322
- return today;
1323
- }
1324
- else {
1325
- return firstFocusableDay;
1326
- }
1479
+ /**
1480
+ * Render the "next month" button in the navigation.
1481
+ */
1482
+ function IconRight(props) {
1483
+ return (React__default.createElement("svg", __assign({ width: "16px", height: "16px", viewBox: "0 0 120 120" }, props),
1484
+ React__default.createElement("path", { d: "M49.8040405,3.34314575 C46.6798462,0.218951416 41.6145263,0.218951416 38.490332,3.34314575 C35.4326099,6.40086786 35.367552,11.3179931 38.2951583,14.4548388 L38.490332,14.6568542 L83.8333725,60 L38.490332,105.343146 C35.4326099,108.400868 35.367552,113.317993 38.2951583,116.454839 L38.490332,116.656854 C41.5480541,119.714576 46.4651794,119.779634 49.602025,116.852028 L49.8040405,116.656854 L100.804041,65.6568542 C103.861763,62.5991321 103.926821,57.6820069 100.999214,54.5451612 L100.804041,54.3431458 L49.8040405,3.34314575 Z", fill: "currentColor" })));
1327
1485
  }
1328
1486
 
1329
- /** Return the next date to be focused. */
1330
- function getNextFocus(
1331
- /** The day that is focused. */
1332
- focusedDay, moveBy, direction, options, modifiers) {
1333
- var weekStartsOn = options.weekStartsOn, fromDate = options.fromDate, toDate = options.toDate, locale = options.locale;
1334
- var moveFns = {
1335
- day: addDays,
1336
- week: addWeeks,
1337
- month: addMonths,
1338
- year: addYears,
1339
- startOfWeek: function (date) { return startOfWeek(date, { locale: locale, weekStartsOn: weekStartsOn }); },
1340
- endOfWeek: function (date) { return endOfWeek(date, { locale: locale, weekStartsOn: weekStartsOn }); }
1341
- };
1342
- var newFocusedDay = moveFns[moveBy](focusedDay, direction === 'after' ? 1 : -1);
1343
- if (direction === 'before' && fromDate) {
1344
- newFocusedDay = max([fromDate, newFocusedDay]);
1345
- }
1346
- else if (direction === 'after' && toDate) {
1347
- newFocusedDay = min([toDate, newFocusedDay]);
1348
- }
1349
- if (modifiers) {
1350
- var activeModifiers = getActiveModifiers(newFocusedDay, modifiers);
1351
- var isFocusable = !activeModifiers.disabled && !activeModifiers.hidden;
1352
- if (!isFocusable) {
1353
- return getNextFocus(newFocusedDay, moveBy, direction, options, modifiers);
1354
- }
1487
+ /** Render a row in the calendar, with the days and the week number. */
1488
+ function Row(props) {
1489
+ var _a = useDayPicker(), styles = _a.styles, classNames = _a.classNames, showWeekNumber = _a.showWeekNumber, _b = _a.components, Day = _b.Day, WeekNumber = _b.WeekNumber;
1490
+ var weekNumberCell;
1491
+ if (showWeekNumber) {
1492
+ weekNumberCell = (React__default.createElement("td", { className: classNames.cell, style: styles.cell },
1493
+ React__default.createElement(WeekNumber, { number: props.weekNumber, dates: props.dates })));
1355
1494
  }
1356
- return newFocusedDay;
1495
+ return (React__default.createElement("tr", { className: classNames.row, style: styles.row },
1496
+ weekNumberCell,
1497
+ props.dates.map(function (date) { return (React__default.createElement("td", { className: classNames.cell, style: styles.cell, key: getUnixTime(date) },
1498
+ React__default.createElement(Day, { displayMonth: props.displayMonth, date: date }))); })));
1357
1499
  }
1358
1500
 
1359
1501
  /**
1360
- * The Focus context shares details about the focused day for the keyboard
1361
- *
1362
- * Access this context from the {@link useFocusContext} hook.
1502
+ * Render the week number element. If `onWeekNumberClick` is passed to DayPicker, it
1503
+ * renders a button, otherwise a span element.
1363
1504
  */
1364
- var FocusContext = createContext(undefined);
1365
- /** The provider for the {@link FocusContext}. */
1366
- function FocusProvider(props) {
1367
- var navigation = useNavigation();
1368
- var modifiers = useModifiers();
1369
- var _a = useState(), focusedDay = _a[0], setFocusedDay = _a[1];
1370
- var _b = useState(), lastFocused = _b[0], setLastFocused = _b[1];
1371
- var initialFocusTarget = getInitialFocusTarget(navigation.displayMonths, modifiers);
1372
- // TODO: cleanup and test obscure code below
1373
- var focusTarget = (focusedDay !== null && focusedDay !== void 0 ? focusedDay : (lastFocused && navigation.isDateDisplayed(lastFocused)))
1374
- ? lastFocused
1375
- : initialFocusTarget;
1376
- var blur = function () {
1377
- setLastFocused(focusedDay);
1378
- setFocusedDay(undefined);
1379
- };
1380
- var focus = function (date) {
1381
- setFocusedDay(date);
1382
- };
1383
- var dayPicker = useDayPicker();
1384
- var moveFocus = function (moveBy, direction) {
1385
- if (!focusedDay)
1386
- return;
1387
- var nextFocused = getNextFocus(focusedDay, moveBy, direction, dayPicker, modifiers);
1388
- if (isSameDay(focusedDay, nextFocused))
1389
- return undefined;
1390
- navigation.goToDate(nextFocused, focusedDay);
1391
- focus(nextFocused);
1392
- };
1393
- var value = {
1394
- focusedDay: focusedDay,
1395
- focusTarget: focusTarget,
1396
- blur: blur,
1397
- focus: focus,
1398
- focusDayAfter: function () { return moveFocus('day', 'after'); },
1399
- focusDayBefore: function () { return moveFocus('day', 'before'); },
1400
- focusWeekAfter: function () { return moveFocus('week', 'after'); },
1401
- focusWeekBefore: function () { return moveFocus('week', 'before'); },
1402
- focusMonthBefore: function () { return moveFocus('month', 'before'); },
1403
- focusMonthAfter: function () { return moveFocus('month', 'after'); },
1404
- focusYearBefore: function () { return moveFocus('year', 'before'); },
1405
- focusYearAfter: function () { return moveFocus('year', 'after'); },
1406
- focusStartOfWeek: function () { return moveFocus('startOfWeek', 'before'); },
1407
- focusEndOfWeek: function () { return moveFocus('endOfWeek', 'after'); }
1505
+ function WeekNumber(props) {
1506
+ var weekNumber = props.number, dates = props.dates;
1507
+ var _a = useDayPicker(), onWeekNumberClick = _a.onWeekNumberClick, styles = _a.styles, classNames = _a.classNames, locale = _a.locale, labelWeekNumber = _a.labels.labelWeekNumber, formatWeekNumber = _a.formatters.formatWeekNumber;
1508
+ var content = formatWeekNumber(Number(weekNumber), { locale: locale });
1509
+ if (!onWeekNumberClick) {
1510
+ return (React__default.createElement("span", { className: classNames.weeknumber, style: styles.weeknumber }, content));
1511
+ }
1512
+ var label = labelWeekNumber(Number(weekNumber), { locale: locale });
1513
+ var handleClick = function (e) {
1514
+ onWeekNumberClick(weekNumber, dates, e);
1408
1515
  };
1409
- return (React__default.createElement(FocusContext.Provider, { value: value }, props.children));
1516
+ return (React__default.createElement(Button, { name: "week-number", "aria-label": label, className: classNames.weeknumber, style: styles.weeknumber, onClick: handleClick }, content));
1410
1517
  }
1411
1518
 
1412
1519
  /**
1413
- * Hook to access the {@link FocusContextValue}. Use this hook to handle the
1414
- * focus state of the elements.
1415
- *
1416
- * This hook is meant to be used inside internal or custom components.
1520
+ * The name of the default CSS classes.
1521
+ */
1522
+ var defaultClassNames = {
1523
+ root: 'rdp',
1524
+ multiple_months: 'rdp-multiple_months',
1525
+ with_weeknumber: 'rdp-with_weeknumber',
1526
+ vhidden: 'rdp-vhidden',
1527
+ button_reset: 'rdp-button_reset',
1528
+ button: 'rdp-button',
1529
+ caption: 'rdp-caption',
1530
+ caption_start: 'rdp-caption_start',
1531
+ caption_end: 'rdp-caption_end',
1532
+ caption_between: 'rdp-caption_between',
1533
+ caption_label: 'rdp-caption_label',
1534
+ caption_dropdowns: 'rdp-caption_dropdowns',
1535
+ dropdown: 'rdp-dropdown',
1536
+ dropdown_month: 'rdp-dropdown_month',
1537
+ dropdown_year: 'rdp-dropdown_year',
1538
+ dropdown_icon: 'rdp-dropdown_icon',
1539
+ months: 'rdp-months',
1540
+ month: 'rdp-month',
1541
+ table: 'rdp-table',
1542
+ tbody: 'rdp-tbody',
1543
+ tfoot: 'rdp-tfoot',
1544
+ head: 'rdp-head',
1545
+ head_row: 'rdp-head_row',
1546
+ head_cell: 'rdp-head_cell',
1547
+ nav: 'rdp-nav',
1548
+ nav_button: 'rdp-nav_button',
1549
+ nav_button_previous: 'rdp-nav_button_previous',
1550
+ nav_button_next: 'rdp-nav_button_next',
1551
+ nav_icon: 'rdp-nav_icon',
1552
+ row: 'rdp-row',
1553
+ weeknumber: 'rdp-weeknumber',
1554
+ cell: 'rdp-cell',
1555
+ day: 'rdp-day',
1556
+ day_today: 'rdp-day_today',
1557
+ day_outside: 'rdp-day_outside',
1558
+ day_selected: 'rdp-day_selected',
1559
+ day_disabled: 'rdp-day_disabled',
1560
+ day_hidden: 'rdp-day_hidden',
1561
+ day_range_start: 'rdp-day_range_start',
1562
+ day_range_end: 'rdp-day_range_end',
1563
+ day_range_middle: 'rdp-day_range_middle'
1564
+ };
1565
+
1566
+ /**
1567
+ * The default formatter for the caption.
1417
1568
  */
1418
- function useFocusContext() {
1419
- var context = useContext(FocusContext);
1420
- if (!context) {
1421
- throw new Error('useFocusContext must be used within a FocusProvider');
1422
- }
1423
- return context;
1569
+ function formatCaption(month, options) {
1570
+ return format(month, 'LLLL y', options);
1424
1571
  }
1425
1572
 
1426
1573
  /**
1427
- * Return the active modifiers for the specified day.
1428
- *
1429
- * This hook is meant to be used inside internal or custom components.
1430
- *
1431
- * @param day
1432
- * @param displayMonth
1574
+ * The default formatter for the Day button.
1433
1575
  */
1434
- function useActiveModifiers(day,
1576
+ function formatDay(day, options) {
1577
+ return format(day, 'd', options);
1578
+ }
1579
+
1435
1580
  /**
1436
- * The month where the date is displayed. If not the same as `date`, the day
1437
- * is an "outside day".
1581
+ * The default formatter for the Month caption.
1438
1582
  */
1439
- displayMonth) {
1440
- var modifiers = useModifiers();
1441
- var activeModifiers = getActiveModifiers(day, modifiers, displayMonth);
1442
- return activeModifiers;
1583
+ function formatMonthCaption(month, options) {
1584
+ return format(month, 'LLLL', options);
1443
1585
  }
1444
1586
 
1445
1587
  /**
1446
- * The SelectSingle context shares details about the selected days when in
1447
- * single selection mode.
1448
- *
1449
- * Access this context from the {@link useSelectSingle} hook.
1588
+ * The default formatter for the week number.
1450
1589
  */
1451
- var SelectSingleContext = createContext(undefined);
1452
- /** Provides the values for the {@link SelectSingleProvider}. */
1453
- function SelectSingleProvider(props) {
1454
- if (!isDayPickerSingle(props.initialProps)) {
1455
- var emptyContextValue = {
1456
- selected: undefined
1457
- };
1458
- return (React__default.createElement(SelectSingleContext.Provider, { value: emptyContextValue }, props.children));
1459
- }
1460
- return (React__default.createElement(SelectSingleProviderInternal, { initialProps: props.initialProps, children: props.children }));
1461
- }
1462
- function SelectSingleProviderInternal(_a) {
1463
- var initialProps = _a.initialProps, children = _a.children;
1464
- var onDayClick = function (day, activeModifiers, e) {
1465
- var _a, _b, _c;
1466
- (_a = initialProps.onDayClick) === null || _a === void 0 ? void 0 : _a.call(initialProps, day, activeModifiers, e);
1467
- if (activeModifiers.selected && !initialProps.required) {
1468
- (_b = initialProps.onSelect) === null || _b === void 0 ? void 0 : _b.call(initialProps, undefined, day, activeModifiers, e);
1469
- return;
1470
- }
1471
- (_c = initialProps.onSelect) === null || _c === void 0 ? void 0 : _c.call(initialProps, day, day, activeModifiers, e);
1472
- };
1473
- var contextValue = {
1474
- selected: initialProps.selected,
1475
- onDayClick: onDayClick
1476
- };
1477
- return (React__default.createElement(SelectSingleContext.Provider, { value: contextValue }, children));
1590
+ function formatWeekNumber(weekNumber) {
1591
+ return "".concat(weekNumber);
1478
1592
  }
1479
1593
 
1480
1594
  /**
1481
- * Hook to access the {@link SelectSingleContextValue}.
1482
- *
1483
- * This hook is meant to be used inside internal or custom components.
1595
+ * The default formatter for the name of the weekday.
1484
1596
  */
1485
- function useSelectSingle() {
1486
- var context = useContext(SelectSingleContext);
1487
- if (!context) {
1488
- throw new Error('useSelectSingle must be used within a SelectSingleProvider');
1489
- }
1490
- return context;
1597
+ function formatWeekdayName(weekday, options) {
1598
+ return format(weekday, 'cccccc', options);
1491
1599
  }
1492
1600
 
1493
1601
  /**
1494
- * This hook returns details about the content to render in the day cell.
1495
- *
1496
- *
1497
- * When a day cell is rendered in the table, DayPicker can either:
1498
- *
1499
- * - render nothing: when the day is outside the month or has matched the
1500
- * "hidden" modifier.
1501
- * - render a button when `onDayClick` or a selection mode is set.
1502
- * - render a non-interactive element: when no selection mode is set, the day
1503
- * cell shouldn’t respond to any interaction. DayPicker should render a `div`
1504
- * or a `span`.
1505
- *
1506
- * ### Usage
1507
- *
1508
- * Use this hook to customize the behavior of the {@link Day} component. Create a
1509
- * new `Day` component using this hook and pass it to the `components` prop.
1510
- * The source of {@link Day} can be a good starting point.
1511
- *
1602
+ * The default formatter for the Year caption.
1512
1603
  */
1513
- function useDayEventHandlers(date, activeModifiers) {
1514
- var dayPicker = useDayPicker();
1515
- var single = useSelectSingle();
1516
- var multiple = useSelectMultiple();
1517
- var range = useSelectRange();
1518
- var _a = useFocusContext(), focusDayAfter = _a.focusDayAfter, focusDayBefore = _a.focusDayBefore, focusWeekAfter = _a.focusWeekAfter, focusWeekBefore = _a.focusWeekBefore, blur = _a.blur, focus = _a.focus, focusMonthBefore = _a.focusMonthBefore, focusMonthAfter = _a.focusMonthAfter, focusYearBefore = _a.focusYearBefore, focusYearAfter = _a.focusYearAfter, focusStartOfWeek = _a.focusStartOfWeek, focusEndOfWeek = _a.focusEndOfWeek;
1519
- var onClick = function (e) {
1520
- var _a, _b, _c, _d;
1521
- if (isDayPickerSingle(dayPicker)) {
1522
- (_a = single.onDayClick) === null || _a === void 0 ? void 0 : _a.call(single, date, activeModifiers, e);
1523
- }
1524
- else if (isDayPickerMultiple(dayPicker)) {
1525
- (_b = multiple.onDayClick) === null || _b === void 0 ? void 0 : _b.call(multiple, date, activeModifiers, e);
1526
- }
1527
- else if (isDayPickerRange(dayPicker)) {
1528
- (_c = range.onDayClick) === null || _c === void 0 ? void 0 : _c.call(range, date, activeModifiers, e);
1529
- }
1530
- else {
1531
- (_d = dayPicker.onDayClick) === null || _d === void 0 ? void 0 : _d.call(dayPicker, date, activeModifiers, e);
1532
- }
1533
- };
1534
- var onFocus = function (e) {
1535
- var _a;
1536
- focus(date);
1537
- (_a = dayPicker.onDayFocus) === null || _a === void 0 ? void 0 : _a.call(dayPicker, date, activeModifiers, e);
1538
- };
1539
- var onBlur = function (e) {
1540
- var _a;
1541
- blur();
1542
- (_a = dayPicker.onDayBlur) === null || _a === void 0 ? void 0 : _a.call(dayPicker, date, activeModifiers, e);
1543
- };
1544
- var onMouseEnter = function (e) {
1545
- var _a;
1546
- (_a = dayPicker.onDayMouseEnter) === null || _a === void 0 ? void 0 : _a.call(dayPicker, date, activeModifiers, e);
1547
- };
1548
- var onMouseLeave = function (e) {
1549
- var _a;
1550
- (_a = dayPicker.onDayMouseLeave) === null || _a === void 0 ? void 0 : _a.call(dayPicker, date, activeModifiers, e);
1551
- };
1552
- var onTouchCancel = function (e) {
1553
- var _a;
1554
- (_a = dayPicker.onDayTouchCancel) === null || _a === void 0 ? void 0 : _a.call(dayPicker, date, activeModifiers, e);
1555
- };
1556
- var onTouchEnd = function (e) {
1557
- var _a;
1558
- (_a = dayPicker.onDayTouchEnd) === null || _a === void 0 ? void 0 : _a.call(dayPicker, date, activeModifiers, e);
1559
- };
1560
- var onTouchMove = function (e) {
1561
- var _a;
1562
- (_a = dayPicker.onDayTouchMove) === null || _a === void 0 ? void 0 : _a.call(dayPicker, date, activeModifiers, e);
1563
- };
1564
- var onTouchStart = function (e) {
1565
- var _a;
1566
- (_a = dayPicker.onDayTouchStart) === null || _a === void 0 ? void 0 : _a.call(dayPicker, date, activeModifiers, e);
1567
- };
1568
- var onKeyUp = function (e) {
1569
- var _a;
1570
- (_a = dayPicker.onDayKeyUp) === null || _a === void 0 ? void 0 : _a.call(dayPicker, date, activeModifiers, e);
1571
- };
1572
- var onKeyDown = function (e) {
1573
- var _a;
1574
- switch (e.key) {
1575
- case 'ArrowLeft':
1576
- e.preventDefault();
1577
- e.stopPropagation();
1578
- dayPicker.dir === 'rtl' ? focusDayAfter() : focusDayBefore();
1579
- break;
1580
- case 'ArrowRight':
1581
- e.preventDefault();
1582
- e.stopPropagation();
1583
- dayPicker.dir === 'rtl' ? focusDayBefore() : focusDayAfter();
1584
- break;
1585
- case 'ArrowDown':
1586
- e.preventDefault();
1587
- e.stopPropagation();
1588
- focusWeekAfter();
1589
- break;
1590
- case 'ArrowUp':
1591
- e.preventDefault();
1592
- e.stopPropagation();
1593
- focusWeekBefore();
1594
- break;
1595
- case 'PageUp':
1596
- e.preventDefault();
1597
- e.stopPropagation();
1598
- e.shiftKey ? focusYearBefore() : focusMonthBefore();
1599
- break;
1600
- case 'PageDown':
1601
- e.preventDefault();
1602
- e.stopPropagation();
1603
- e.shiftKey ? focusYearAfter() : focusMonthAfter();
1604
- break;
1605
- case 'Home':
1606
- e.preventDefault();
1607
- e.stopPropagation();
1608
- focusStartOfWeek();
1609
- break;
1610
- case 'End':
1611
- e.preventDefault();
1612
- e.stopPropagation();
1613
- focusEndOfWeek();
1614
- break;
1615
- }
1616
- (_a = dayPicker.onDayKeyDown) === null || _a === void 0 ? void 0 : _a.call(dayPicker, date, activeModifiers, e);
1617
- };
1618
- var eventHandlers = {
1619
- onClick: onClick,
1620
- onFocus: onFocus,
1621
- onBlur: onBlur,
1622
- onKeyDown: onKeyDown,
1623
- onKeyUp: onKeyUp,
1624
- onMouseEnter: onMouseEnter,
1625
- onMouseLeave: onMouseLeave,
1626
- onTouchCancel: onTouchCancel,
1627
- onTouchEnd: onTouchEnd,
1628
- onTouchMove: onTouchMove,
1629
- onTouchStart: onTouchStart
1630
- };
1631
- return eventHandlers;
1604
+ function formatYearCaption(year, options) {
1605
+ return format(year, 'yyyy', options);
1632
1606
  }
1633
1607
 
1608
+ var formatters = /*#__PURE__*/Object.freeze({
1609
+ __proto__: null,
1610
+ formatCaption: formatCaption,
1611
+ formatDay: formatDay,
1612
+ formatMonthCaption: formatMonthCaption,
1613
+ formatWeekNumber: formatWeekNumber,
1614
+ formatWeekdayName: formatWeekdayName,
1615
+ formatYearCaption: formatYearCaption
1616
+ });
1617
+
1618
+ /**
1619
+ * The default ARIA label for the day button.
1620
+ */
1621
+ var labelDay = function (day, activeModifiers, options) {
1622
+ return format(day, 'do MMMM (EEEE)', options);
1623
+ };
1624
+
1625
+ /**
1626
+ * The default ARIA label for the WeekNumber element.
1627
+ */
1628
+ var labelMonthDropdown = function () {
1629
+ return 'Month: ';
1630
+ };
1631
+
1632
+ /**
1633
+ * The default ARIA label for next month button in navigation
1634
+ */
1635
+ var labelNext = function () {
1636
+ return 'Go to next month';
1637
+ };
1638
+
1634
1639
  /**
1635
- * Return the current selected days when DayPicker is in selection mode. Days
1636
- * selected by the custom selection mode are not returned.
1637
- *
1638
- * This hook is meant to be used inside internal or custom components.
1639
- *
1640
+ * The default ARIA label for previous month button in navigation
1640
1641
  */
1641
- function useSelectedDays() {
1642
- var dayPicker = useDayPicker();
1643
- var single = useSelectSingle();
1644
- var multiple = useSelectMultiple();
1645
- var range = useSelectRange();
1646
- var selectedDays = isDayPickerSingle(dayPicker)
1647
- ? single.selected
1648
- : isDayPickerMultiple(dayPicker)
1649
- ? multiple.selected
1650
- : isDayPickerRange(dayPicker)
1651
- ? range.selected
1652
- : undefined;
1653
- return selectedDays;
1654
- }
1642
+ var labelPrevious = function () {
1643
+ return 'Go to previous month';
1644
+ };
1655
1645
 
1656
- function isInternalModifier(modifier) {
1657
- return Object.values(InternalModifier).includes(modifier);
1658
- }
1659
1646
  /**
1660
- * Return the class names for the Day element, according to the given active
1661
- * modifiers.
1662
- *
1663
- * Custom class names are set via `modifiersClassNames` or `classNames`,
1664
- * where the first have the precedence.
1647
+ * The default ARIA label for the Weekday element.
1665
1648
  */
1666
- function getDayClassNames(dayPicker, activeModifiers) {
1667
- var classNames = [dayPicker.classNames.day];
1668
- Object.keys(activeModifiers).forEach(function (modifier) {
1669
- var customClassName = dayPicker.modifiersClassNames[modifier];
1670
- if (customClassName) {
1671
- classNames.push(customClassName);
1672
- }
1673
- else if (isInternalModifier(modifier)) {
1674
- var internalClassName = dayPicker.classNames["day_".concat(modifier)];
1675
- if (internalClassName) {
1676
- classNames.push(internalClassName);
1677
- }
1678
- }
1679
- });
1680
- return classNames;
1681
- }
1649
+ var labelWeekday = function (day, options) {
1650
+ return format(day, 'cccc', options);
1651
+ };
1682
1652
 
1683
- /** Return the style for the Day element, according to the given active modifiers. */
1684
- function getDayStyle(dayPicker, activeModifiers) {
1685
- var style = __assign({}, dayPicker.styles.day);
1686
- Object.keys(activeModifiers).forEach(function (modifier) {
1687
- var _a;
1688
- style = __assign(__assign({}, style), (_a = dayPicker.modifiersStyles) === null || _a === void 0 ? void 0 : _a[modifier]);
1689
- });
1690
- return style;
1691
- }
1653
+ /**
1654
+ * The default ARIA label for the WeekNumber element.
1655
+ */
1656
+ var labelWeekNumber = function (n) {
1657
+ return "Week n. ".concat(n);
1658
+ };
1692
1659
 
1693
1660
  /**
1694
- * Return props and data used to render the {@link Day} component.
1695
- *
1696
- * Use this hook when creating a component to replace the built-in `Day`
1697
- * component.
1661
+ * The default ARIA label for the WeekNumber element.
1698
1662
  */
1699
- function useDayRender(
1700
- /** The date to render. */
1701
- day,
1702
- /** The month where the date is displayed (if not the same as `date`, it means it is an "outside" day). */
1703
- displayMonth,
1704
- /** A ref to the button element that will be target of focus when rendered (if required). */
1705
- buttonRef) {
1706
- var _a;
1707
- var _b, _c;
1708
- var dayPicker = useDayPicker();
1709
- var focusContext = useFocusContext();
1710
- var activeModifiers = useActiveModifiers(day, displayMonth);
1711
- var eventHandlers = useDayEventHandlers(day, activeModifiers);
1712
- var selectedDays = useSelectedDays();
1713
- var isButton = Boolean(dayPicker.onDayClick || dayPicker.mode !== 'default');
1714
- // Focus the button if the day is focused according to the focus context
1715
- useEffect(function () {
1716
- var _a;
1717
- if (activeModifiers.outside)
1718
- return;
1719
- if (!focusContext.focusedDay)
1720
- return;
1721
- if (!isButton)
1722
- return;
1723
- if (isSameDay(focusContext.focusedDay, day)) {
1724
- (_a = buttonRef.current) === null || _a === void 0 ? void 0 : _a.focus();
1725
- }
1726
- }, [
1727
- focusContext.focusedDay,
1728
- day,
1729
- buttonRef,
1730
- isButton,
1731
- activeModifiers.outside
1732
- ]);
1733
- var className = getDayClassNames(dayPicker, activeModifiers).join(' ');
1734
- var style = getDayStyle(dayPicker, activeModifiers);
1735
- var ariaLabel = dayPicker.labels.labelDay(day, activeModifiers, {
1736
- locale: dayPicker.locale
1737
- });
1738
- var isHidden = Boolean((activeModifiers.outside && !dayPicker.showOutsideDays) ||
1739
- activeModifiers.hidden);
1740
- var DayContentComponent = (_c = (_b = dayPicker.components) === null || _b === void 0 ? void 0 : _b.DayContent) !== null && _c !== void 0 ? _c : DayContent;
1741
- var children = (React__default.createElement(DayContentComponent, { date: day, displayMonth: displayMonth, activeModifiers: activeModifiers }));
1742
- var divProps = {
1743
- style: style,
1744
- className: className,
1745
- children: children,
1746
- 'aria-label': ariaLabel
1663
+ var labelYearDropdown = function () {
1664
+ return 'Year: ';
1665
+ };
1666
+
1667
+ var labels = /*#__PURE__*/Object.freeze({
1668
+ __proto__: null,
1669
+ labelDay: labelDay,
1670
+ labelMonthDropdown: labelMonthDropdown,
1671
+ labelNext: labelNext,
1672
+ labelPrevious: labelPrevious,
1673
+ labelWeekday: labelWeekday,
1674
+ labelWeekNumber: labelWeekNumber,
1675
+ labelYearDropdown: labelYearDropdown
1676
+ });
1677
+
1678
+ /**
1679
+ * Returns the default values to use in the DayPickerContext, in case they are
1680
+ * not passed down with the DayPicker initial props.
1681
+ */
1682
+ function getDefaultContextValues() {
1683
+ var captionLayout = 'buttons';
1684
+ var classNames = defaultClassNames;
1685
+ var locale = enUS;
1686
+ var modifiersClassNames = {};
1687
+ var modifiers = {};
1688
+ var numberOfMonths = 1;
1689
+ var styles = {};
1690
+ var today = new Date();
1691
+ var components = {
1692
+ Caption: Caption,
1693
+ CaptionLabel: CaptionLabel,
1694
+ Day: Day,
1695
+ DayContent: DayContent,
1696
+ Dropdown: Dropdown,
1697
+ Footer: Footer,
1698
+ Head: Head,
1699
+ HeadRow: HeadRow,
1700
+ IconDropdown: IconDropdown,
1701
+ IconRight: IconRight,
1702
+ IconLeft: IconLeft,
1703
+ Row: Row,
1704
+ WeekNumber: WeekNumber
1747
1705
  };
1748
- var isFocusTarget = Boolean(focusContext.focusTarget && isSameDay(focusContext.focusTarget, day));
1749
- var buttonProps = __assign(__assign(__assign({}, divProps), (_a = { disabled: activeModifiers.disabled }, _a['aria-pressed'] = activeModifiers.selected, _a['aria-label'] = ariaLabel, _a.tabIndex = isFocusTarget ? 0 : -1, _a)), eventHandlers);
1750
- var dayRender = {
1751
- isButton: isButton,
1752
- isHidden: isHidden,
1753
- activeModifiers: activeModifiers,
1754
- selectedDays: selectedDays,
1755
- buttonProps: buttonProps,
1756
- divProps: divProps
1706
+ return {
1707
+ captionLayout: captionLayout,
1708
+ classNames: classNames,
1709
+ components: components,
1710
+ formatters: formatters,
1711
+ labels: labels,
1712
+ locale: locale,
1713
+ modifiersClassNames: modifiersClassNames,
1714
+ modifiers: modifiers,
1715
+ numberOfMonths: numberOfMonths,
1716
+ styles: styles,
1717
+ today: today,
1718
+ mode: 'default'
1757
1719
  };
1758
- return dayRender;
1759
1720
  }
1760
1721
 
1761
- /**
1762
- * The content of a day cell – as a button or span element according to its
1763
- * modifiers.
1764
- */
1765
- function Day(props) {
1766
- var buttonRef = useRef(null);
1767
- var dayRender = useDayRender(props.date, props.displayMonth, buttonRef);
1768
- if (dayRender.isHidden) {
1769
- return React__default.createElement(React__default.Fragment, null);
1722
+ /** Return the `fromDate` and `toDate` prop values values parsing the DayPicker props. */
1723
+ function parseFromToProps(props) {
1724
+ var fromYear = props.fromYear, toYear = props.toYear, fromMonth = props.fromMonth, toMonth = props.toMonth;
1725
+ var fromDate = props.fromDate, toDate = props.toDate;
1726
+ if (fromMonth) {
1727
+ fromDate = startOfMonth(fromMonth);
1770
1728
  }
1771
- if (!dayRender.isButton) {
1772
- return React__default.createElement("div", __assign({}, dayRender.divProps));
1729
+ else if (fromYear) {
1730
+ fromDate = new Date(fromYear, 0, 1);
1773
1731
  }
1774
- return React__default.createElement(Button, __assign({ name: "day", ref: buttonRef }, dayRender.buttonProps));
1732
+ if (toMonth) {
1733
+ toDate = endOfMonth(toMonth);
1734
+ }
1735
+ else if (toYear) {
1736
+ toDate = new Date(toYear, 11, 31);
1737
+ }
1738
+ return {
1739
+ fromDate: fromDate ? startOfDay(fromDate) : undefined,
1740
+ toDate: toDate ? startOfDay(toDate) : undefined
1741
+ };
1775
1742
  }
1776
1743
 
1777
1744
  /**
1778
- * Render the week number element. If `onWeekNumberClick` is passed to DayPicker, it
1779
- * renders a button, otherwise a span element.
1745
+ * The DayPicker context shares the props passed to DayPicker within internal
1746
+ * and custom components. It is used to set the default values and perform
1747
+ * one-time calculations required to render the days.
1748
+ *
1749
+ * Access to this context from the {@link useDayPicker} hook.
1780
1750
  */
1781
- function WeekNumber(props) {
1782
- var weekNumber = props.number, dates = props.dates;
1783
- var _a = useDayPicker(), onWeekNumberClick = _a.onWeekNumberClick, styles = _a.styles, classNames = _a.classNames, locale = _a.locale, labelWeekNumber = _a.labels.labelWeekNumber, formatWeekNumber = _a.formatters.formatWeekNumber;
1784
- var content = formatWeekNumber(Number(weekNumber), { locale: locale });
1785
- if (!onWeekNumberClick) {
1786
- return (React__default.createElement("span", { className: classNames.weeknumber, style: styles.weeknumber }, content));
1751
+ var DayPickerContext = createContext(undefined);
1752
+ /**
1753
+ * The provider for the {@link DayPickerContext}, assigning the defaults from the
1754
+ * initial DayPicker props.
1755
+ */
1756
+ function DayPickerProvider(props) {
1757
+ var _a;
1758
+ var initialProps = props.initialProps;
1759
+ var defaultContextValues = getDefaultContextValues();
1760
+ var _b = parseFromToProps(initialProps), fromDate = _b.fromDate, toDate = _b.toDate;
1761
+ var captionLayout = (_a = initialProps.captionLayout) !== null && _a !== void 0 ? _a : defaultContextValues.captionLayout;
1762
+ if (captionLayout !== 'buttons' && (!fromDate || !toDate)) {
1763
+ // When no from/to dates are set, the caption is always buttons
1764
+ captionLayout = 'buttons';
1787
1765
  }
1788
- var label = labelWeekNumber(Number(weekNumber), { locale: locale });
1789
- var handleClick = function (e) {
1790
- onWeekNumberClick(weekNumber, dates, e);
1791
- };
1792
- return (React__default.createElement(Button, { name: "week-number", "aria-label": label, className: classNames.weeknumber, style: styles.weeknumber, onClick: handleClick }, content));
1766
+ var onSelect;
1767
+ if (isDayPickerSingle(initialProps) ||
1768
+ isDayPickerMultiple(initialProps) ||
1769
+ isDayPickerRange(initialProps)) {
1770
+ onSelect = initialProps.onSelect;
1771
+ }
1772
+ var value = __assign(__assign(__assign({}, defaultContextValues), initialProps), { captionLayout: captionLayout, classNames: __assign(__assign({}, defaultContextValues.classNames), initialProps.classNames), components: __assign(__assign({}, defaultContextValues.components), initialProps.components), formatters: __assign(__assign({}, defaultContextValues.formatters), initialProps.formatters), fromDate: fromDate, labels: __assign(__assign({}, defaultContextValues.labels), initialProps.labels), mode: initialProps.mode || defaultContextValues.mode, modifiers: __assign(__assign({}, defaultContextValues.modifiers), initialProps.modifiers), modifiersClassNames: __assign(__assign({}, defaultContextValues.modifiersClassNames), initialProps.modifiersClassNames), onSelect: onSelect, styles: __assign(__assign({}, defaultContextValues.styles), initialProps.styles), toDate: toDate });
1773
+ return (React__default.createElement(DayPickerContext.Provider, { value: value }, props.children));
1793
1774
  }
1794
-
1795
- /** Render a row in the calendar, with the days and the week number. */
1796
- function Row(props) {
1797
- var _a, _b;
1798
- var _c = useDayPicker(), styles = _c.styles, classNames = _c.classNames, showWeekNumber = _c.showWeekNumber, components = _c.components;
1799
- var DayComponent = (_a = components === null || components === void 0 ? void 0 : components.Day) !== null && _a !== void 0 ? _a : Day;
1800
- var WeeknumberComponent = (_b = components === null || components === void 0 ? void 0 : components.WeekNumber) !== null && _b !== void 0 ? _b : WeekNumber;
1801
- var weekNumberCell;
1802
- if (showWeekNumber) {
1803
- weekNumberCell = (React__default.createElement("td", { className: classNames.cell, style: styles.cell },
1804
- React__default.createElement(WeeknumberComponent, { number: props.weekNumber, dates: props.dates })));
1775
+ /**
1776
+ * Hook to access the {@link DayPickerContextValue}.
1777
+ *
1778
+ * Use the DayPicker context to access to the props passed to DayPicker inside
1779
+ * internal or custom components.
1780
+ */
1781
+ function useDayPicker() {
1782
+ var context = useContext(DayPickerContext);
1783
+ if (!context) {
1784
+ throw new Error("useDayPicker must be used within a DayPickerProvider.");
1805
1785
  }
1806
- return (React__default.createElement("tr", { className: classNames.row, style: styles.row },
1807
- weekNumberCell,
1808
- props.dates.map(function (date) { return (React__default.createElement("td", { className: classNames.cell, style: styles.cell, key: getUnixTime(date) },
1809
- React__default.createElement(DayComponent, { displayMonth: props.displayMonth, date: date }))); })));
1786
+ return context;
1810
1787
  }
1811
1788
 
1812
1789
  /** Return the weeks between two dates. */
1813
1790
  function daysToMonthWeeks(fromDate, toDate, options) {
1814
- var toWeek = endOfWeek(toDate, options);
1815
- var fromWeek = startOfWeek(fromDate, options);
1791
+ var toWeek = (options === null || options === void 0 ? void 0 : options.ISOWeek)
1792
+ ? endOfISOWeek(toDate)
1793
+ : endOfWeek(toDate, options);
1794
+ var fromWeek = (options === null || options === void 0 ? void 0 : options.ISOWeek)
1795
+ ? startOfISOWeek(fromDate)
1796
+ : startOfWeek(fromDate, options);
1816
1797
  var nOfDays = differenceInCalendarDays(toWeek, fromWeek);
1817
1798
  var days = [];
1818
1799
  for (var i = 0; i <= nOfDays; i++) {
1819
1800
  days.push(addDays(fromWeek, i));
1820
1801
  }
1821
1802
  var weeksInMonth = days.reduce(function (result, date) {
1822
- var weekNumber = getWeek(date, options);
1803
+ var weekNumber = (options === null || options === void 0 ? void 0 : options.ISOWeek)
1804
+ ? getISOWeek(date)
1805
+ : getWeek(date, options);
1823
1806
  var existingWeek = result.find(function (value) { return value.weekNumber === weekNumber; });
1824
1807
  if (existingWeek) {
1825
1808
  existingWeek.dates.push(date);
@@ -1838,12 +1821,10 @@ function daysToMonthWeeks(fromDate, toDate, options) {
1838
1821
  * Return the weeks belonging to the given month, adding the "outside days" to
1839
1822
  * the first and last week.
1840
1823
  */
1841
- function getMonthWeeks(
1842
- /** The month to get the weeks from */
1843
- month, options) {
1824
+ function getMonthWeeks(month, options) {
1844
1825
  var weeksInMonth = daysToMonthWeeks(startOfMonth(month), endOfMonth(month), options);
1845
- // Add extra weeks to the month, up to 6 weeks
1846
1826
  if (options === null || options === void 0 ? void 0 : options.useFixedWeeks) {
1827
+ // Add extra weeks to the month, up to 6 weeks
1847
1828
  var nrOfMonthWeeks = getWeeksInMonth(month, options);
1848
1829
  if (nrOfMonthWeeks < 6) {
1849
1830
  var lastWeek = weeksInMonth[weeksInMonth.length - 1];
@@ -1858,20 +1839,18 @@ month, options) {
1858
1839
 
1859
1840
  /** Render the table with the calendar. */
1860
1841
  function Table(props) {
1861
- var _a, _b, _c;
1862
- var _d = useDayPicker(), locale = _d.locale, classNames = _d.classNames, styles = _d.styles, hideHead = _d.hideHead, fixedWeeks = _d.fixedWeeks, components = _d.components, weekStartsOn = _d.weekStartsOn;
1842
+ var _a = useDayPicker(), locale = _a.locale, classNames = _a.classNames, styles = _a.styles, hideHead = _a.hideHead, fixedWeeks = _a.fixedWeeks, _b = _a.components, Head = _b.Head, Row = _b.Row, Footer = _b.Footer, weekStartsOn = _a.weekStartsOn, firstWeekContainsDate = _a.firstWeekContainsDate, ISOWeek = _a.ISOWeek;
1863
1843
  var weeks = getMonthWeeks(props.displayMonth, {
1864
1844
  useFixedWeeks: Boolean(fixedWeeks),
1845
+ ISOWeek: ISOWeek,
1865
1846
  locale: locale,
1866
- weekStartsOn: weekStartsOn
1847
+ weekStartsOn: weekStartsOn,
1848
+ firstWeekContainsDate: firstWeekContainsDate
1867
1849
  });
1868
- var HeadComponent = (_a = components === null || components === void 0 ? void 0 : components.Head) !== null && _a !== void 0 ? _a : Head;
1869
- var RowComponent = (_b = components === null || components === void 0 ? void 0 : components.Row) !== null && _b !== void 0 ? _b : Row;
1870
- var FooterComponent = (_c = components === null || components === void 0 ? void 0 : components.Footer) !== null && _c !== void 0 ? _c : Footer;
1871
1850
  return (React__default.createElement("table", { className: classNames.table, style: styles.table, role: "grid", "aria-labelledby": props['aria-labelledby'] },
1872
- !hideHead && React__default.createElement(HeadComponent, null),
1873
- React__default.createElement("tbody", { className: classNames.tbody, style: styles.tbody }, weeks.map(function (week) { return (React__default.createElement(RowComponent, { displayMonth: props.displayMonth, key: week.weekNumber, dates: week.dates, weekNumber: week.weekNumber })); })),
1874
- React__default.createElement(FooterComponent, null)));
1851
+ !hideHead && React__default.createElement(Head, null),
1852
+ React__default.createElement("tbody", { className: classNames.tbody, style: styles.tbody }, weeks.map(function (week) { return (React__default.createElement(Row, { displayMonth: props.displayMonth, key: week.weekNumber, dates: week.dates, weekNumber: week.weekNumber })); })),
1853
+ React__default.createElement(Footer, null)));
1875
1854
  }
1876
1855
 
1877
1856
  /*
@@ -1954,11 +1933,10 @@ function useId(providedId) {
1954
1933
  /** Render a month. */
1955
1934
  function Month(props) {
1956
1935
  var _a;
1957
- var _b;
1958
1936
  var dayPicker = useDayPicker();
1959
- var dir = dayPicker.dir, classNames = dayPicker.classNames, styles = dayPicker.styles, components = dayPicker.components;
1937
+ var dir = dayPicker.dir, classNames = dayPicker.classNames, styles = dayPicker.styles, Caption = dayPicker.components.Caption;
1960
1938
  var displayMonths = useNavigation().displayMonths;
1961
- var captionId = useId();
1939
+ var captionId = useId(dayPicker.id ? "".concat(dayPicker.id, "-").concat(props.displayIndex) : undefined);
1962
1940
  var className = [classNames.month];
1963
1941
  var style = styles.month;
1964
1942
  var isStart = props.displayIndex === 0;
@@ -1979,9 +1957,8 @@ function Month(props) {
1979
1957
  className.push(classNames.caption_between);
1980
1958
  style = __assign(__assign({}, style), styles.caption_between);
1981
1959
  }
1982
- var CaptionComponent = (_b = components === null || components === void 0 ? void 0 : components.Caption) !== null && _b !== void 0 ? _b : Caption;
1983
1960
  return (React__default.createElement("div", { key: props.displayIndex, className: className.join(' '), style: style },
1984
- React__default.createElement(CaptionComponent, { id: captionId, displayMonth: props.displayMonth }),
1961
+ React__default.createElement(Caption, { id: captionId, displayMonth: props.displayMonth }),
1985
1962
  React__default.createElement(Table, { "aria-labelledby": captionId, displayMonth: props.displayMonth })));
1986
1963
  }
1987
1964