react-day-picker 8.0.1 → 8.0.4

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 (218) hide show
  1. package/README.md +3 -2
  2. package/dist/components/Caption/Caption.d.ts +2 -2
  3. package/dist/components/CaptionDropdowns/CaptionDropdowns.d.ts +5 -0
  4. package/dist/components/CaptionDropdowns/index.d.ts +1 -0
  5. package/dist/components/CaptionNavigation/CaptionNavigation.d.ts +5 -0
  6. package/dist/components/CaptionNavigation/index.d.ts +1 -0
  7. package/dist/components/Head/utils/getWeekdays.d.ts +4 -2
  8. package/dist/components/Table/utils/daysToMonthWeeks.d.ts +1 -1
  9. package/dist/components/Table/utils/getMonthWeeks.d.ts +1 -1
  10. package/dist/contexts/DayPicker/formatters/formatCaption.d.ts +1 -1
  11. package/dist/contexts/DayPicker/formatters/formatDay.d.ts +1 -1
  12. package/dist/contexts/DayPicker/formatters/formatMonthCaption.d.ts +1 -1
  13. package/dist/contexts/DayPicker/formatters/formatWeekdayName.d.ts +1 -1
  14. package/dist/index.d.ts +2 -0
  15. package/dist/index.esm.js +145 -96
  16. package/dist/index.esm.js.map +1 -1
  17. package/dist/index.js +272 -196
  18. package/dist/index.js.map +1 -1
  19. package/dist/types/DayPickerBase.d.ts +5 -1
  20. package/dist/types/Labels.d.ts +1 -1
  21. package/package.json +15 -14
  22. package/src/DayPicker.tsx +113 -0
  23. package/src/components/Button/Button.test.tsx +47 -0
  24. package/src/components/Button/Button.tsx +36 -0
  25. package/src/components/Button/index.ts +1 -0
  26. package/src/components/Caption/Caption.test.tsx +86 -0
  27. package/src/components/Caption/Caption.tsx +54 -0
  28. package/src/components/Caption/index.ts +1 -0
  29. package/src/components/CaptionDropdowns/CaptionDropdowns.test.tsx +123 -0
  30. package/src/components/CaptionDropdowns/CaptionDropdowns.tsx +43 -0
  31. package/src/components/CaptionDropdowns/index.ts +1 -0
  32. package/src/components/CaptionLabel/CaptionLabel.test.tsx +29 -0
  33. package/src/components/CaptionLabel/CaptionLabel.tsx +32 -0
  34. package/src/components/CaptionLabel/index.ts +1 -0
  35. package/src/components/CaptionNavigation/CaptionNavigation.test.tsx +172 -0
  36. package/src/components/CaptionNavigation/CaptionNavigation.tsx +63 -0
  37. package/src/components/CaptionNavigation/index.ts +1 -0
  38. package/src/components/Day/Day.test.tsx +84 -0
  39. package/src/components/Day/Day.tsx +30 -0
  40. package/src/components/Day/index.ts +1 -0
  41. package/src/components/DayContent/DayContent.test.tsx +51 -0
  42. package/src/components/DayContent/DayContent.tsx +36 -0
  43. package/src/components/DayContent/index.ts +1 -0
  44. package/src/components/Dropdown/Dropdown.test.tsx +73 -0
  45. package/src/components/Dropdown/Dropdown.tsx +56 -0
  46. package/src/components/Dropdown/index.ts +1 -0
  47. package/src/components/Footer/Footer.test.tsx +29 -0
  48. package/src/components/Footer/Footer.tsx +20 -0
  49. package/src/components/Footer/index.ts +1 -0
  50. package/src/components/Head/Head.test.tsx +117 -0
  51. package/src/components/Head/Head.tsx +51 -0
  52. package/src/components/Head/index.ts +1 -0
  53. package/src/components/Head/utils/getWeekdays.test.ts +36 -0
  54. package/src/components/Head/utils/getWeekdays.ts +22 -0
  55. package/src/components/Head/utils/index.ts +1 -0
  56. package/src/components/IconDropdown/IconDropdown.test.tsx +20 -0
  57. package/src/components/IconDropdown/IconDropdown.tsx +24 -0
  58. package/src/components/IconDropdown/index.ts +1 -0
  59. package/src/components/IconLeft/IconLeft.test.tsx +20 -0
  60. package/src/components/IconLeft/IconLeft.tsx +18 -0
  61. package/src/components/IconLeft/index.ts +1 -0
  62. package/src/components/IconRight/IconRight.test.tsx +20 -0
  63. package/src/components/IconRight/IconRight.tsx +17 -0
  64. package/src/components/IconRight/index.ts +1 -0
  65. package/src/components/Month/Month.test.tsx +216 -0
  66. package/src/components/Month/Month.tsx +53 -0
  67. package/src/components/Month/index.ts +1 -0
  68. package/src/components/MonthsDropdown/MonthsDropdown.test.tsx +99 -0
  69. package/src/components/MonthsDropdown/MonthsDropdown.tsx +75 -0
  70. package/src/components/MonthsDropdown/index.ts +1 -0
  71. package/src/components/Navigation/Navigation.test.tsx +129 -0
  72. package/src/components/Navigation/Navigation.tsx +102 -0
  73. package/src/components/Navigation/index.ts +1 -0
  74. package/src/components/Root/Root.test.tsx +123 -0
  75. package/src/components/Root/Root.tsx +58 -0
  76. package/src/components/Root/index.ts +1 -0
  77. package/src/components/Row/Row.test.tsx +69 -0
  78. package/src/components/Row/Row.tsx +51 -0
  79. package/src/components/Row/index.ts +1 -0
  80. package/src/components/Table/Table.test.tsx +42 -0
  81. package/src/components/Table/Table.tsx +60 -0
  82. package/src/components/Table/__snapshots__/Table.test.tsx.snap +1453 -0
  83. package/src/components/Table/index.ts +1 -0
  84. package/src/components/Table/utils/daysToMonthWeeks.ts +47 -0
  85. package/src/components/Table/utils/getMonthWeeks.test.ts +68 -0
  86. package/src/components/Table/utils/getMonthWeeks.ts +55 -0
  87. package/src/components/WeekNumber/WeekNumber.test.tsx +46 -0
  88. package/src/components/WeekNumber/WeekNumber.tsx +58 -0
  89. package/src/components/WeekNumber/__snapshots__/WeekNumber.test.tsx.snap +11 -0
  90. package/src/components/WeekNumber/index.ts +1 -0
  91. package/src/components/YearsDropdown/YearsDropdown.test.tsx +98 -0
  92. package/src/components/YearsDropdown/YearsDropdown.tsx +76 -0
  93. package/src/components/YearsDropdown/index.ts +1 -0
  94. package/src/contexts/DayPicker/DayPickerContext.tsx +156 -0
  95. package/src/contexts/DayPicker/defaultClassNames.ts +58 -0
  96. package/src/contexts/DayPicker/defaultContextValue.ts +37 -0
  97. package/src/contexts/DayPicker/formatters/formatCaption.test.ts +15 -0
  98. package/src/contexts/DayPicker/formatters/formatCaption.ts +12 -0
  99. package/src/contexts/DayPicker/formatters/formatDay.test.ts +7 -0
  100. package/src/contexts/DayPicker/formatters/formatDay.ts +9 -0
  101. package/src/contexts/DayPicker/formatters/formatMonthCaption.test.ts +15 -0
  102. package/src/contexts/DayPicker/formatters/formatMonthCaption.ts +12 -0
  103. package/src/contexts/DayPicker/formatters/formatWeekNumber.test.ts +5 -0
  104. package/src/contexts/DayPicker/formatters/formatWeekNumber.ts +6 -0
  105. package/src/contexts/DayPicker/formatters/formatWeekdayName.test.ts +15 -0
  106. package/src/contexts/DayPicker/formatters/formatWeekdayName.ts +12 -0
  107. package/src/contexts/DayPicker/formatters/formatYearCaption.test.ts +7 -0
  108. package/src/contexts/DayPicker/formatters/formatYearCaption.ts +11 -0
  109. package/src/contexts/DayPicker/formatters/index.ts +6 -0
  110. package/src/contexts/DayPicker/index.ts +2 -0
  111. package/src/contexts/DayPicker/labels/index.ts +7 -0
  112. package/src/contexts/DayPicker/labels/labelDay.test.ts +7 -0
  113. package/src/contexts/DayPicker/labels/labelDay.ts +10 -0
  114. package/src/contexts/DayPicker/labels/labelMonthDropdown.test.ts +5 -0
  115. package/src/contexts/DayPicker/labels/labelMonthDropdown.ts +6 -0
  116. package/src/contexts/DayPicker/labels/labelNext.test.ts +5 -0
  117. package/src/contexts/DayPicker/labels/labelNext.ts +8 -0
  118. package/src/contexts/DayPicker/labels/labelPrevious.test.ts +5 -0
  119. package/src/contexts/DayPicker/labels/labelPrevious.ts +8 -0
  120. package/src/contexts/DayPicker/labels/labelWeekNumber.test.ts +5 -0
  121. package/src/contexts/DayPicker/labels/labelWeekNumber.ts +8 -0
  122. package/src/contexts/DayPicker/labels/labelWeekday.test.ts +15 -0
  123. package/src/contexts/DayPicker/labels/labelWeekday.ts +10 -0
  124. package/src/contexts/DayPicker/labels/labelYearDropdown.test.ts +5 -0
  125. package/src/contexts/DayPicker/labels/labelYearDropdown.ts +6 -0
  126. package/src/contexts/DayPicker/useDayPicker.test.ts +297 -0
  127. package/src/contexts/DayPicker/useDayPicker.ts +17 -0
  128. package/src/contexts/DayPicker/utils/index.ts +1 -0
  129. package/src/contexts/DayPicker/utils/parseFromToProps.test.ts +47 -0
  130. package/src/contexts/DayPicker/utils/parseFromToProps.ts +32 -0
  131. package/src/contexts/Focus/FocusContext.tsx +174 -0
  132. package/src/contexts/Focus/index.ts +2 -0
  133. package/src/contexts/Focus/useFocusContext.test.ts +183 -0
  134. package/src/contexts/Focus/useFocusContext.ts +12 -0
  135. package/src/contexts/Focus/utils/getInitialFocusTarget.test.tsx +12 -0
  136. package/src/contexts/Focus/utils/getInitialFocusTarget.tsx +44 -0
  137. package/src/contexts/Modifiers/ModifiersContext.tsx +44 -0
  138. package/src/contexts/Modifiers/index.ts +2 -0
  139. package/src/contexts/Modifiers/useModifiers.test.ts +46 -0
  140. package/src/contexts/Modifiers/useModifiers.ts +17 -0
  141. package/src/contexts/Modifiers/utils/getActiveModifiers.test.ts +53 -0
  142. package/src/contexts/Modifiers/utils/getActiveModifiers.ts +33 -0
  143. package/src/contexts/Modifiers/utils/getCustomModifiers.test.ts +14 -0
  144. package/src/contexts/Modifiers/utils/getCustomModifiers.ts +14 -0
  145. package/src/contexts/Modifiers/utils/getInternalModifiers.test.ts +146 -0
  146. package/src/contexts/Modifiers/utils/getInternalModifiers.ts +58 -0
  147. package/src/contexts/Modifiers/utils/isDateInRange.test.ts +28 -0
  148. package/src/contexts/Modifiers/utils/isDateInRange.ts +27 -0
  149. package/src/contexts/Modifiers/utils/isMatch.test.ts +92 -0
  150. package/src/contexts/Modifiers/utils/isMatch.ts +76 -0
  151. package/src/contexts/Modifiers/utils/matcherToArray.test.ts +22 -0
  152. package/src/contexts/Modifiers/utils/matcherToArray.ts +14 -0
  153. package/src/contexts/Navigation/NavigationContext.tsx +84 -0
  154. package/src/contexts/Navigation/index.ts +2 -0
  155. package/src/contexts/Navigation/useNavigation.test.ts +126 -0
  156. package/src/contexts/Navigation/useNavigation.ts +12 -0
  157. package/src/contexts/Navigation/useNavigationState.test.ts +36 -0
  158. package/src/contexts/Navigation/useNavigationState.ts +25 -0
  159. package/src/contexts/Navigation/utils/getDisplayMonths.ts +31 -0
  160. package/src/contexts/Navigation/utils/getInitialMonth.test.ts +56 -0
  161. package/src/contexts/Navigation/utils/getInitialMonth.ts +24 -0
  162. package/src/contexts/Navigation/utils/getNextMonth.test.ts +75 -0
  163. package/src/contexts/Navigation/utils/getNextMonth.ts +45 -0
  164. package/src/contexts/Navigation/utils/getPreviousMonth.test.ts +55 -0
  165. package/src/contexts/Navigation/utils/getPreviousMonth.ts +44 -0
  166. package/src/contexts/RootProvider.tsx +37 -0
  167. package/src/contexts/SelectMultiple/SelectMultipleContext.tsx +135 -0
  168. package/src/contexts/SelectMultiple/index.ts +2 -0
  169. package/src/contexts/SelectMultiple/useSelectMultiple.test.ts +191 -0
  170. package/src/contexts/SelectMultiple/useSelectMultiple.ts +17 -0
  171. package/src/contexts/SelectRange/SelectRangeContext.tsx +158 -0
  172. package/src/contexts/SelectRange/index.ts +2 -0
  173. package/src/contexts/SelectRange/useSelectRange.test.ts +282 -0
  174. package/src/contexts/SelectRange/useSelectRange.ts +15 -0
  175. package/src/contexts/SelectRange/utils/addToRange.test.ts +119 -0
  176. package/src/contexts/SelectRange/utils/addToRange.ts +43 -0
  177. package/src/contexts/SelectSingle/SelectSingleContext.tsx +80 -0
  178. package/src/contexts/SelectSingle/index.ts +2 -0
  179. package/src/contexts/SelectSingle/useSelectSingle.test.ts +81 -0
  180. package/src/contexts/SelectSingle/useSelectSingle.ts +17 -0
  181. package/src/hooks/useActiveModifiers/index.ts +1 -0
  182. package/src/hooks/useActiveModifiers/useActiveModifiers.test.tsx +36 -0
  183. package/src/hooks/useActiveModifiers/useActiveModifiers.tsx +18 -0
  184. package/src/hooks/useControlledValue/index.ts +1 -0
  185. package/src/hooks/useControlledValue/useControlledValue.test.ts +68 -0
  186. package/src/hooks/useControlledValue/useControlledValue.ts +24 -0
  187. package/src/hooks/useDayEventHandlers/index.ts +1 -0
  188. package/src/hooks/useDayEventHandlers/useDayEventHandlers.test.tsx +213 -0
  189. package/src/hooks/useDayEventHandlers/useDayEventHandlers.tsx +195 -0
  190. package/src/hooks/useDayRender/index.ts +1 -0
  191. package/src/hooks/useDayRender/useDayRender.test.tsx +304 -0
  192. package/src/hooks/useDayRender/useDayRender.tsx +123 -0
  193. package/src/hooks/useDayRender/utils/getDayClassNames.test.ts +63 -0
  194. package/src/hooks/useDayRender/utils/getDayClassNames.ts +32 -0
  195. package/src/hooks/useDayRender/utils/getDayStyle.ts +19 -0
  196. package/src/hooks/useInput/index.ts +1 -0
  197. package/src/hooks/useInput/useInput.ts +175 -0
  198. package/src/hooks/useInput/utils/isValidDate.tsx +4 -0
  199. package/src/hooks/useSelectedDays/index.ts +1 -0
  200. package/src/hooks/useSelectedDays/useSelectedDays.test.ts +72 -0
  201. package/src/hooks/useSelectedDays/useSelectedDays.ts +32 -0
  202. package/src/index.ts +43 -0
  203. package/src/style.css +310 -0
  204. package/src/style.css.d.ts +38 -0
  205. package/src/types/DayPickerBase.ts +267 -0
  206. package/src/types/DayPickerDefault.ts +15 -0
  207. package/src/types/DayPickerMultiple.ts +26 -0
  208. package/src/types/DayPickerRange.ts +27 -0
  209. package/src/types/DayPickerSingle.ts +24 -0
  210. package/src/types/EventHandlers.ts +87 -0
  211. package/src/types/Formatters.ts +29 -0
  212. package/src/types/Labels.ts +36 -0
  213. package/src/types/Matchers.ts +106 -0
  214. package/src/types/Modifiers.ts +62 -0
  215. package/src/types/Styles.ts +108 -0
  216. package/tsconfig.json +24 -0
  217. package/CHANGELOG.md +0 -26
  218. package/dist/react-day-picker.min.js +0 -1
@@ -0,0 +1,175 @@
1
+ import React, { useState } from 'react';
2
+
3
+ import differenceInCalendarDays from 'date-fns/differenceInCalendarDays';
4
+ import _format from 'date-fns/format';
5
+ import enUS from 'date-fns/locale/en-US';
6
+ import parse from 'date-fns/parse';
7
+
8
+ import { parseFromToProps } from 'contexts/DayPicker/utils';
9
+ import { DayPickerBase } from 'types/DayPickerBase';
10
+ import { DayPickerDefaultProps } from 'types/DayPickerDefault';
11
+ import {
12
+ DayClickEventHandler,
13
+ MonthChangeEventHandler
14
+ } from 'types/EventHandlers';
15
+
16
+ import { isValidDate } from './utils/isValidDate';
17
+
18
+ /** The props to attach to the input field when using [[useInput]]. */
19
+ export type InputHTMLAttributes = Pick<
20
+ React.InputHTMLAttributes<HTMLInputElement>,
21
+ 'onBlur' | 'onChange' | 'onFocus' | 'value' | 'placeholder'
22
+ >;
23
+
24
+ /** The props to attach to the DayPicker component when using [[useInput]]. */
25
+ export type InputDayPickerProps = Pick<
26
+ DayPickerDefaultProps,
27
+ | 'fromDate'
28
+ | 'toDate'
29
+ | 'locale'
30
+ | 'month'
31
+ | 'onDayClick'
32
+ | 'onMonthChange'
33
+ | 'selected'
34
+ | 'today'
35
+ >;
36
+
37
+ export interface UseInputOptions
38
+ extends Pick<
39
+ DayPickerBase,
40
+ | 'locale'
41
+ | 'fromDate'
42
+ | 'toDate'
43
+ | 'fromMonth'
44
+ | 'toMonth'
45
+ | 'fromYear'
46
+ | 'toYear'
47
+ | 'today'
48
+ > {
49
+ /** The initially selected date */
50
+ defaultSelected?: Date;
51
+ /** The format string for formatting the input field. See https://date-fns.org/docs/format for a list of format strings. Default to `PP`. */
52
+ format?: string;
53
+ /** Make the selection required. */
54
+ required?: boolean;
55
+ }
56
+
57
+ /** Represent the value returned by [[useInput]]. */
58
+ export interface UseInput {
59
+ /** The props to pass to a DayPicker component. */
60
+ dayPickerProps: InputDayPickerProps;
61
+ /** The props to pass to an input field. */
62
+ inputProps: InputHTMLAttributes;
63
+ /** A function to reset to the initial state. */
64
+ reset: () => void;
65
+ /** A function to set the selected day. */
66
+ setSelected: (day: Date | undefined) => void;
67
+ }
68
+
69
+ /** Return props and setters for binding an input field to DayPicker. */
70
+ export function useInput(options: UseInputOptions = {}): UseInput {
71
+ const {
72
+ locale = enUS,
73
+ required,
74
+ format = 'PP',
75
+ defaultSelected,
76
+ today = new Date()
77
+ } = options;
78
+ const { fromDate, toDate } = parseFromToProps(options);
79
+
80
+ // Shortcut to the DateFns functions
81
+ const parseValue = (value: string) => parse(value, format, today, { locale });
82
+
83
+ // Initialize states
84
+ const [month, setMonth] = useState(defaultSelected ?? today);
85
+ const [selectedDay, setSelectedDay] = useState(defaultSelected);
86
+ const defaultInputValue = defaultSelected
87
+ ? _format(defaultSelected, format, { locale })
88
+ : '';
89
+ const [inputValue, setInputValue] = useState(defaultInputValue);
90
+
91
+ const reset = () => {
92
+ setSelectedDay(defaultSelected);
93
+ setMonth(defaultSelected ?? today);
94
+ setInputValue(defaultInputValue ?? '');
95
+ };
96
+
97
+ const setSelected = (date: Date | undefined) => {
98
+ setSelectedDay(date);
99
+ setMonth(date ?? today);
100
+ setInputValue(date ? _format(date, format, { locale }) : '');
101
+ };
102
+
103
+ const handleDayClick: DayClickEventHandler = (day, { selected }) => {
104
+ if (!required && selected) {
105
+ setSelectedDay(undefined);
106
+ setInputValue('');
107
+ return;
108
+ }
109
+ setSelectedDay(day);
110
+ setInputValue(day ? _format(day, format, { locale }) : '');
111
+ };
112
+
113
+ const handleMonthChange: MonthChangeEventHandler = (month) => {
114
+ setMonth(month);
115
+ };
116
+
117
+ // When changing the input field, save its value in state and check if the
118
+ // string is a valid date. If it is a valid day, set it as selected and update
119
+ // the calendar’s month.
120
+ const handleChange: React.ChangeEventHandler<HTMLInputElement> = (e) => {
121
+ setInputValue(e.target.value);
122
+ const day = parseValue(e.target.value);
123
+ const isBefore = fromDate && differenceInCalendarDays(fromDate, day) > 0;
124
+ const isAfter = toDate && differenceInCalendarDays(day, toDate) > 0;
125
+ if (!isValidDate(day) || isBefore || isAfter) {
126
+ setSelectedDay(undefined);
127
+ return;
128
+ }
129
+ setSelectedDay(day);
130
+ setMonth(day);
131
+ };
132
+
133
+ // Special case for _required_ fields: on blur, if the value of the input is not
134
+ // a valid date, reset the calendar and the input value.
135
+ const handleBlur: React.FocusEventHandler<HTMLInputElement> = (e) => {
136
+ const day = parseValue(e.target.value);
137
+ if (!isValidDate(day)) {
138
+ reset();
139
+ }
140
+ };
141
+
142
+ // When focusing, make sure DayPicker visualizes the month of the date in the
143
+ // input field.
144
+ const handleFocus: React.FocusEventHandler<HTMLInputElement> = (e) => {
145
+ if (!e.target.value) {
146
+ reset();
147
+ return;
148
+ }
149
+ const day = parseValue(e.target.value);
150
+ if (isValidDate(day)) {
151
+ setMonth(day);
152
+ }
153
+ };
154
+
155
+ const dayPickerProps: InputDayPickerProps = {
156
+ month: month,
157
+ onDayClick: handleDayClick,
158
+ onMonthChange: handleMonthChange,
159
+ selected: selectedDay,
160
+ locale,
161
+ fromDate: options?.fromDate,
162
+ toDate: options?.toDate,
163
+ today
164
+ };
165
+
166
+ const inputProps: InputHTMLAttributes = {
167
+ onBlur: handleBlur,
168
+ onChange: handleChange,
169
+ onFocus: handleFocus,
170
+ value: inputValue,
171
+ placeholder: _format(new Date(), format, { locale })
172
+ };
173
+
174
+ return { dayPickerProps, inputProps, reset, setSelected };
175
+ }
@@ -0,0 +1,4 @@
1
+ /** @private */
2
+ export function isValidDate(day: Date): boolean {
3
+ return !isNaN(day.getTime());
4
+ }
@@ -0,0 +1 @@
1
+ export * from './useSelectedDays';
@@ -0,0 +1,72 @@
1
+ import { RenderResult } from '@testing-library/react-hooks';
2
+ import { DayPickerProps } from 'DayPicker';
3
+
4
+ import { customRenderHook } from 'test/render';
5
+
6
+ import { SelectMultipleContextValue } from 'contexts/SelectMultiple';
7
+ import { SelectRangeContextValue } from 'contexts/SelectRange';
8
+ import { SelectSingleContextValue } from 'contexts/SelectSingle';
9
+
10
+ import { SelectedDays, useSelectedDays } from './useSelectedDays';
11
+
12
+ const today = new Date(2021, 11, 8);
13
+
14
+ const single: SelectSingleContextValue = {
15
+ selected: today
16
+ };
17
+
18
+ const multiple: SelectMultipleContextValue = {
19
+ selected: [today],
20
+ modifiers: { disabled: [] }
21
+ };
22
+
23
+ const range: SelectRangeContextValue = {
24
+ selected: undefined,
25
+ modifiers: {
26
+ disabled: [],
27
+ range_start: [],
28
+ range_end: [],
29
+ range_middle: []
30
+ }
31
+ };
32
+ const selectionContext = { single, multiple, range };
33
+
34
+ let renderResult: RenderResult<SelectedDays>;
35
+ function setup(dayPickerProps: DayPickerProps) {
36
+ const view = customRenderHook(
37
+ useSelectedDays,
38
+ dayPickerProps,
39
+ selectionContext
40
+ );
41
+ renderResult = view.result;
42
+ }
43
+
44
+ describe('when in single selection mode', () => {
45
+ const mode = 'single';
46
+ beforeEach(() => {
47
+ setup({ mode });
48
+ });
49
+ test('should return the selection from the single context', () => {
50
+ expect(renderResult.current).toBe(single.selected);
51
+ });
52
+ });
53
+
54
+ describe('when in multiple selection mode', () => {
55
+ const mode = 'multiple';
56
+ beforeEach(() => {
57
+ setup({ mode });
58
+ });
59
+ test('should return the selection from the multiple context', () => {
60
+ expect(renderResult.current).toBe(multiple.selected);
61
+ });
62
+ });
63
+
64
+ describe('when in range selection mode', () => {
65
+ const mode = 'range';
66
+ beforeEach(() => {
67
+ setup({ mode });
68
+ });
69
+ test('should return the selection from the range context', () => {
70
+ expect(renderResult.current).toBe(range.selected);
71
+ });
72
+ });
@@ -0,0 +1,32 @@
1
+ import { useDayPicker } from 'contexts/DayPicker';
2
+ import { useSelectMultiple } from 'contexts/SelectMultiple';
3
+ import { useSelectRange } from 'contexts/SelectRange';
4
+ import { useSelectSingle } from 'contexts/SelectSingle';
5
+ import { isDayPickerMultiple } from 'types/DayPickerMultiple';
6
+ import { isDayPickerRange } from 'types/DayPickerRange';
7
+ import { isDayPickerSingle } from 'types/DayPickerSingle';
8
+ import { DateRange } from 'types/Matchers';
9
+
10
+ export type SelectedDays = Date | Date[] | DateRange | undefined;
11
+
12
+ /**
13
+ * Return the current selected days when DayPicker is in selection mode.
14
+ *
15
+ * Days selected by the custom selection mode are not returned.
16
+ */
17
+ export function useSelectedDays(): SelectedDays {
18
+ const dayPicker = useDayPicker();
19
+ const single = useSelectSingle();
20
+ const multiple = useSelectMultiple();
21
+ const range = useSelectRange();
22
+
23
+ const selectedDays = isDayPickerSingle(dayPicker)
24
+ ? single.selected
25
+ : isDayPickerMultiple(dayPicker)
26
+ ? multiple.selected
27
+ : isDayPickerRange(dayPicker)
28
+ ? range.selected
29
+ : undefined;
30
+
31
+ return selectedDays;
32
+ }
package/src/index.ts ADDED
@@ -0,0 +1,43 @@
1
+ export * from './DayPicker';
2
+
3
+ export * from 'components/Button';
4
+ export * from 'components/Caption';
5
+ export * from 'components/CaptionDropdowns';
6
+ export * from 'components/CaptionLabel';
7
+ export * from 'components/CaptionNavigation';
8
+ export * from 'components/Day';
9
+ export * from 'components/DayContent';
10
+ export * from 'components/Dropdown';
11
+ export * from 'components/Footer';
12
+ export * from 'components/Head';
13
+ export * from 'components/IconDropdown';
14
+ export * from 'components/IconRight';
15
+ export * from 'components/IconLeft';
16
+ export * from 'components/Row';
17
+ export * from 'components/WeekNumber';
18
+
19
+ export * from 'hooks/useInput';
20
+ export * from 'hooks/useDayRender';
21
+ export * from 'hooks/useActiveModifiers';
22
+
23
+ export * from 'contexts/DayPicker';
24
+ export * from 'contexts/Focus';
25
+ export * from 'contexts/Navigation';
26
+ export * from 'contexts/RootProvider';
27
+ export * from 'contexts/SelectMultiple';
28
+ export * from 'contexts/SelectRange';
29
+ export * from 'contexts/SelectSingle';
30
+
31
+ export * from 'types/DayPickerBase';
32
+ export * from 'types/DayPickerDefault';
33
+ export * from 'types/DayPickerMultiple';
34
+ export * from 'types/DayPickerRange';
35
+ export * from 'types/DayPickerSingle';
36
+ export * from 'types/EventHandlers';
37
+ export * from 'types/Formatters';
38
+ export * from 'types/Labels';
39
+ export * from 'types/Matchers';
40
+ export * from 'types/Modifiers';
41
+ export * from 'types/Styles';
42
+
43
+ export * from 'contexts/Modifiers/utils/isMatch';
package/src/style.css ADDED
@@ -0,0 +1,310 @@
1
+ :root {
2
+ --rdp-cell-size: 40px;
3
+ --rdp-accent-color: #0000ff;
4
+ --rdp-background-color: #e7edff;
5
+ /* Switch to dark colors for dark themes */
6
+ --rdp-accent-color-dark: #3003e1;
7
+ --rdp-background-color-dark: #180270;
8
+ /* Outline border for focused elements */
9
+ --rdp-outline: 2px solid var(--rdp-accent-color);
10
+ /* Outline border for focused and selected elements */
11
+ --rdp-outline-selected: 2px solid rgba(0, 0, 0, 0.75);
12
+ }
13
+
14
+ .rdp {
15
+ margin: 1em;
16
+ }
17
+
18
+ /* Hide elements for devices that are not screen readers */
19
+ .rdp-vhidden {
20
+ box-sizing: border-box;
21
+ padding: 0;
22
+ margin: 0;
23
+ background: transparent;
24
+ border: 0;
25
+ -moz-appearance: none;
26
+ -webkit-appearance: none;
27
+ appearance: none;
28
+ position: absolute !important;
29
+ top: 0;
30
+ width: 1px !important;
31
+ height: 1px !important;
32
+ padding: 0 !important;
33
+ overflow: hidden !important;
34
+ clip: rect(1px, 1px, 1px, 1px) !important;
35
+ border: 0 !important;
36
+ }
37
+
38
+ /* Buttons */
39
+ .rdp-button_reset {
40
+ appearance: none;
41
+ position: relative;
42
+ margin: 0;
43
+ padding: 0;
44
+ cursor: default;
45
+ color: inherit;
46
+ outline: none;
47
+ background: none;
48
+ font: inherit;
49
+
50
+ -moz-appearance: none;
51
+ -webkit-appearance: none;
52
+ }
53
+
54
+ .rdp-button {
55
+ border: 2px solid transparent;
56
+ }
57
+
58
+ .rdp-button[disabled] {
59
+ opacity: 0.25;
60
+ }
61
+
62
+ .rdp-button:not([disabled]) {
63
+ cursor: pointer;
64
+ }
65
+
66
+ .rdp-button:focus:not([disabled]),
67
+ .rdp-button:active:not([disabled]) {
68
+ color: inherit;
69
+ border: var(--rdp-outline);
70
+ background-color: var(--rdp-background-color);
71
+ }
72
+
73
+ .rdp-button:hover:not([disabled]) {
74
+ background-color: var(--rdp-background-color);
75
+ }
76
+
77
+ .rdp-months {
78
+ display: flex;
79
+ }
80
+
81
+ .rdp-month {
82
+ margin: 0 1em;
83
+ }
84
+
85
+ .rdp-month:first-child {
86
+ margin-left: 0;
87
+ }
88
+
89
+ .rdp-month:last-child {
90
+ margin-right: 0;
91
+ }
92
+
93
+ .rdp-table {
94
+ margin: 0;
95
+ max-width: calc(var(--rdp-cell-size) * 7);
96
+ border-collapse: collapse;
97
+ }
98
+
99
+ .rdp-with_weeknumber .rdp-table {
100
+ max-width: calc(var(--rdp-cell-size) * 8);
101
+ border-collapse: collapse;
102
+ }
103
+
104
+ .rdp-caption {
105
+ display: flex;
106
+ align-items: center;
107
+ justify-content: space-between;
108
+ padding: 0;
109
+ text-align: left;
110
+ }
111
+
112
+ .rdp-multiple_months .rdp-caption {
113
+ position: relative;
114
+ display: block;
115
+ text-align: center;
116
+ }
117
+
118
+ .rdp-caption_dropdowns {
119
+ position: relative;
120
+ display: inline-flex;
121
+ }
122
+
123
+ .rdp-caption_label {
124
+ position: relative;
125
+ z-index: 1;
126
+ display: inline-flex;
127
+ align-items: center;
128
+ margin: 0;
129
+ padding: 0 0.25em;
130
+ white-space: nowrap;
131
+ color: currentColor;
132
+ border: 0;
133
+ border: 2px solid transparent;
134
+ font-family: inherit;
135
+ font-size: 140%;
136
+ font-weight: bold;
137
+ }
138
+
139
+ .rdp-nav {
140
+ white-space: nowrap;
141
+ }
142
+
143
+ .rdp-multiple_months .rdp-caption_start .rdp-nav {
144
+ position: absolute;
145
+ top: 50%;
146
+ left: 0;
147
+ transform: translateY(-50%);
148
+ }
149
+
150
+ .rdp-multiple_months .rdp-caption_end .rdp-nav {
151
+ position: absolute;
152
+ top: 50%;
153
+ right: 0;
154
+ transform: translateY(-50%);
155
+ }
156
+
157
+ .rdp-nav_button {
158
+ display: inline-flex;
159
+ align-items: center;
160
+ justify-content: center;
161
+ width: var(--rdp-cell-size);
162
+ height: var(--rdp-cell-size);
163
+ padding: 0.25em;
164
+ border-radius: 100%;
165
+ }
166
+
167
+ /* ---------- */
168
+ /* Dropdowns */
169
+ /* ---------- */
170
+
171
+ .rdp-dropdown_year,
172
+ .rdp-dropdown_month {
173
+ position: relative;
174
+ display: inline-flex;
175
+ align-items: center;
176
+ }
177
+
178
+ .rdp-dropdown {
179
+ appearance: none;
180
+ position: absolute;
181
+ z-index: 2;
182
+ top: 0;
183
+ bottom: 0;
184
+ left: 0;
185
+ width: 100%;
186
+ margin: 0;
187
+ padding: 0;
188
+ cursor: inherit;
189
+ opacity: 0;
190
+ border: none;
191
+ background-color: transparent;
192
+ font-family: inherit;
193
+ font-size: inherit;
194
+ line-height: inherit;
195
+ }
196
+
197
+ .rdp-dropdown[disabled] {
198
+ opacity: unset;
199
+ color: unset;
200
+ }
201
+
202
+ .rdp-dropdown:focus:not([disabled]) + .rdp-caption_label,
203
+ .rdp-dropdown:active:not([disabled]) + .rdp-caption_label {
204
+ border: var(--rdp-outline);
205
+ border-radius: 6px;
206
+ background-color: var(--rdp-background-color);
207
+ }
208
+
209
+ .rdp-dropdown_icon {
210
+ margin: 0 0 0 5px;
211
+ }
212
+
213
+ .rdp-head {
214
+ border: 0;
215
+ }
216
+
217
+ .rdp-head_row,
218
+ .rdp-row {
219
+ height: 100%;
220
+ }
221
+
222
+ .rdp-head_cell {
223
+ vertical-align: middle;
224
+ text-transform: uppercase;
225
+ font-size: 0.75em;
226
+ font-weight: 700;
227
+ text-align: center;
228
+ height: 100%;
229
+ height: var(--rdp-cell-size);
230
+ padding: 0;
231
+ }
232
+
233
+ .rdp-tbody {
234
+ border: 0;
235
+ }
236
+
237
+ .rdp-tfoot {
238
+ margin: 0.5em;
239
+ }
240
+
241
+ .rdp-cell {
242
+ width: var(--rdp-cell-size);
243
+ height: 100%;
244
+ height: var(--rdp-cell-size);
245
+ padding: 0;
246
+ text-align: center;
247
+ }
248
+
249
+ .rdp-weeknumber {
250
+ font-size: 0.75em;
251
+ }
252
+
253
+ .rdp-weeknumber,
254
+ .rdp-day {
255
+ display: flex;
256
+ overflow: hidden;
257
+ align-items: center;
258
+ justify-content: center;
259
+ box-sizing: border-box;
260
+ width: var(--rdp-cell-size);
261
+ max-width: var(--rdp-cell-size);
262
+ height: var(--rdp-cell-size);
263
+ margin: 0;
264
+ border: 2px solid transparent;
265
+ border-radius: 100%;
266
+ }
267
+
268
+ .rdp-day_today:not(.rdp-day_outside) {
269
+ font-weight: bold;
270
+ }
271
+
272
+ .rdp-day_selected:not([disabled]),
273
+ .rdp-day_selected:focus:not([disabled]),
274
+ .rdp-day_selected:active:not([disabled]),
275
+ .rdp-day_selected:hover:not([disabled]) {
276
+ color: white;
277
+ background-color: var(--rdp-accent-color);
278
+ }
279
+
280
+ .rdp-day_selected:focus:not([disabled]) {
281
+ border: var(--rdp-outline-selected);
282
+ }
283
+
284
+ .rdp:not([dir='rtl']) .rdp-day_range_start:not(.rdp-day_range_end) {
285
+ border-top-right-radius: 0;
286
+ border-bottom-right-radius: 0;
287
+ }
288
+
289
+ .rdp:not([dir='rtl']) .rdp-day_range_end:not(.rdp-day_range_start) {
290
+ border-top-left-radius: 0;
291
+ border-bottom-left-radius: 0;
292
+ }
293
+
294
+ .rdp[dir='rtl'] .rdp-day_range_start:not(.rdp-day_range_end) {
295
+ border-top-left-radius: 0;
296
+ border-bottom-left-radius: 0;
297
+ }
298
+
299
+ .rdp[dir='rtl'] .rdp-day_range_end:not(.rdp-day_range_start) {
300
+ border-top-right-radius: 0;
301
+ border-bottom-right-radius: 0;
302
+ }
303
+
304
+ .rdp-day_range_end.rdp-day_range_start {
305
+ border-radius: 100%;
306
+ }
307
+
308
+ .rdp-day_range_middle {
309
+ border-radius: 0;
310
+ }
@@ -0,0 +1,38 @@
1
+ declare const styles: {
2
+ readonly rdp: string;
3
+ readonly 'rdp-vhidden': string;
4
+ readonly 'rdp-button_reset': string;
5
+ readonly 'rdp-button': string;
6
+ readonly 'rdp-months': string;
7
+ readonly 'rdp-month': string;
8
+ readonly 'rdp-table': string;
9
+ readonly 'rdp-with_weeknumber': string;
10
+ readonly 'rdp-caption': string;
11
+ readonly 'rdp-multiple_months': string;
12
+ readonly 'rdp-caption_dropdowns': string;
13
+ readonly 'rdp-caption_label': string;
14
+ readonly 'rdp-nav': string;
15
+ readonly 'rdp-caption_start': string;
16
+ readonly 'rdp-caption_end': string;
17
+ readonly 'rdp-nav_button': string;
18
+ readonly 'rdp-dropdown_year': string;
19
+ readonly 'rdp-dropdown_month': string;
20
+ readonly 'rdp-dropdown': string;
21
+ readonly 'rdp-dropdown_icon': string;
22
+ readonly 'rdp-head': string;
23
+ readonly 'rdp-head_row': string;
24
+ readonly 'rdp-row': string;
25
+ readonly 'rdp-head_cell': string;
26
+ readonly 'rdp-tbody': string;
27
+ readonly 'rdp-tfoot': string;
28
+ readonly 'rdp-cell': string;
29
+ readonly 'rdp-weeknumber': string;
30
+ readonly 'rdp-day': string;
31
+ readonly 'rdp-day_today': string;
32
+ readonly 'rdp-day_outside': string;
33
+ readonly 'rdp-day_selected': string;
34
+ readonly 'rdp-day_range_start': string;
35
+ readonly 'rdp-day_range_end': string;
36
+ readonly 'rdp-day_range_middle': string;
37
+ };
38
+ export = styles;