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.
- package/README.md +3 -2
- package/dist/components/Caption/Caption.d.ts +2 -2
- package/dist/components/CaptionDropdowns/CaptionDropdowns.d.ts +5 -0
- package/dist/components/CaptionDropdowns/index.d.ts +1 -0
- package/dist/components/CaptionNavigation/CaptionNavigation.d.ts +5 -0
- package/dist/components/CaptionNavigation/index.d.ts +1 -0
- package/dist/components/Head/utils/getWeekdays.d.ts +4 -2
- package/dist/components/Table/utils/daysToMonthWeeks.d.ts +1 -1
- package/dist/components/Table/utils/getMonthWeeks.d.ts +1 -1
- package/dist/contexts/DayPicker/formatters/formatCaption.d.ts +1 -1
- package/dist/contexts/DayPicker/formatters/formatDay.d.ts +1 -1
- package/dist/contexts/DayPicker/formatters/formatMonthCaption.d.ts +1 -1
- package/dist/contexts/DayPicker/formatters/formatWeekdayName.d.ts +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.esm.js +145 -96
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +272 -196
- package/dist/index.js.map +1 -1
- package/dist/types/DayPickerBase.d.ts +5 -1
- package/dist/types/Labels.d.ts +1 -1
- package/package.json +15 -14
- package/src/DayPicker.tsx +113 -0
- package/src/components/Button/Button.test.tsx +47 -0
- package/src/components/Button/Button.tsx +36 -0
- package/src/components/Button/index.ts +1 -0
- package/src/components/Caption/Caption.test.tsx +86 -0
- package/src/components/Caption/Caption.tsx +54 -0
- package/src/components/Caption/index.ts +1 -0
- package/src/components/CaptionDropdowns/CaptionDropdowns.test.tsx +123 -0
- package/src/components/CaptionDropdowns/CaptionDropdowns.tsx +43 -0
- package/src/components/CaptionDropdowns/index.ts +1 -0
- package/src/components/CaptionLabel/CaptionLabel.test.tsx +29 -0
- package/src/components/CaptionLabel/CaptionLabel.tsx +32 -0
- package/src/components/CaptionLabel/index.ts +1 -0
- package/src/components/CaptionNavigation/CaptionNavigation.test.tsx +172 -0
- package/src/components/CaptionNavigation/CaptionNavigation.tsx +63 -0
- package/src/components/CaptionNavigation/index.ts +1 -0
- package/src/components/Day/Day.test.tsx +84 -0
- package/src/components/Day/Day.tsx +30 -0
- package/src/components/Day/index.ts +1 -0
- package/src/components/DayContent/DayContent.test.tsx +51 -0
- package/src/components/DayContent/DayContent.tsx +36 -0
- package/src/components/DayContent/index.ts +1 -0
- package/src/components/Dropdown/Dropdown.test.tsx +73 -0
- package/src/components/Dropdown/Dropdown.tsx +56 -0
- package/src/components/Dropdown/index.ts +1 -0
- package/src/components/Footer/Footer.test.tsx +29 -0
- package/src/components/Footer/Footer.tsx +20 -0
- package/src/components/Footer/index.ts +1 -0
- package/src/components/Head/Head.test.tsx +117 -0
- package/src/components/Head/Head.tsx +51 -0
- package/src/components/Head/index.ts +1 -0
- package/src/components/Head/utils/getWeekdays.test.ts +36 -0
- package/src/components/Head/utils/getWeekdays.ts +22 -0
- package/src/components/Head/utils/index.ts +1 -0
- package/src/components/IconDropdown/IconDropdown.test.tsx +20 -0
- package/src/components/IconDropdown/IconDropdown.tsx +24 -0
- package/src/components/IconDropdown/index.ts +1 -0
- package/src/components/IconLeft/IconLeft.test.tsx +20 -0
- package/src/components/IconLeft/IconLeft.tsx +18 -0
- package/src/components/IconLeft/index.ts +1 -0
- package/src/components/IconRight/IconRight.test.tsx +20 -0
- package/src/components/IconRight/IconRight.tsx +17 -0
- package/src/components/IconRight/index.ts +1 -0
- package/src/components/Month/Month.test.tsx +216 -0
- package/src/components/Month/Month.tsx +53 -0
- package/src/components/Month/index.ts +1 -0
- package/src/components/MonthsDropdown/MonthsDropdown.test.tsx +99 -0
- package/src/components/MonthsDropdown/MonthsDropdown.tsx +75 -0
- package/src/components/MonthsDropdown/index.ts +1 -0
- package/src/components/Navigation/Navigation.test.tsx +129 -0
- package/src/components/Navigation/Navigation.tsx +102 -0
- package/src/components/Navigation/index.ts +1 -0
- package/src/components/Root/Root.test.tsx +123 -0
- package/src/components/Root/Root.tsx +58 -0
- package/src/components/Root/index.ts +1 -0
- package/src/components/Row/Row.test.tsx +69 -0
- package/src/components/Row/Row.tsx +51 -0
- package/src/components/Row/index.ts +1 -0
- package/src/components/Table/Table.test.tsx +42 -0
- package/src/components/Table/Table.tsx +60 -0
- package/src/components/Table/__snapshots__/Table.test.tsx.snap +1453 -0
- package/src/components/Table/index.ts +1 -0
- package/src/components/Table/utils/daysToMonthWeeks.ts +47 -0
- package/src/components/Table/utils/getMonthWeeks.test.ts +68 -0
- package/src/components/Table/utils/getMonthWeeks.ts +55 -0
- package/src/components/WeekNumber/WeekNumber.test.tsx +46 -0
- package/src/components/WeekNumber/WeekNumber.tsx +58 -0
- package/src/components/WeekNumber/__snapshots__/WeekNumber.test.tsx.snap +11 -0
- package/src/components/WeekNumber/index.ts +1 -0
- package/src/components/YearsDropdown/YearsDropdown.test.tsx +98 -0
- package/src/components/YearsDropdown/YearsDropdown.tsx +76 -0
- package/src/components/YearsDropdown/index.ts +1 -0
- package/src/contexts/DayPicker/DayPickerContext.tsx +156 -0
- package/src/contexts/DayPicker/defaultClassNames.ts +58 -0
- package/src/contexts/DayPicker/defaultContextValue.ts +37 -0
- package/src/contexts/DayPicker/formatters/formatCaption.test.ts +15 -0
- package/src/contexts/DayPicker/formatters/formatCaption.ts +12 -0
- package/src/contexts/DayPicker/formatters/formatDay.test.ts +7 -0
- package/src/contexts/DayPicker/formatters/formatDay.ts +9 -0
- package/src/contexts/DayPicker/formatters/formatMonthCaption.test.ts +15 -0
- package/src/contexts/DayPicker/formatters/formatMonthCaption.ts +12 -0
- package/src/contexts/DayPicker/formatters/formatWeekNumber.test.ts +5 -0
- package/src/contexts/DayPicker/formatters/formatWeekNumber.ts +6 -0
- package/src/contexts/DayPicker/formatters/formatWeekdayName.test.ts +15 -0
- package/src/contexts/DayPicker/formatters/formatWeekdayName.ts +12 -0
- package/src/contexts/DayPicker/formatters/formatYearCaption.test.ts +7 -0
- package/src/contexts/DayPicker/formatters/formatYearCaption.ts +11 -0
- package/src/contexts/DayPicker/formatters/index.ts +6 -0
- package/src/contexts/DayPicker/index.ts +2 -0
- package/src/contexts/DayPicker/labels/index.ts +7 -0
- package/src/contexts/DayPicker/labels/labelDay.test.ts +7 -0
- package/src/contexts/DayPicker/labels/labelDay.ts +10 -0
- package/src/contexts/DayPicker/labels/labelMonthDropdown.test.ts +5 -0
- package/src/contexts/DayPicker/labels/labelMonthDropdown.ts +6 -0
- package/src/contexts/DayPicker/labels/labelNext.test.ts +5 -0
- package/src/contexts/DayPicker/labels/labelNext.ts +8 -0
- package/src/contexts/DayPicker/labels/labelPrevious.test.ts +5 -0
- package/src/contexts/DayPicker/labels/labelPrevious.ts +8 -0
- package/src/contexts/DayPicker/labels/labelWeekNumber.test.ts +5 -0
- package/src/contexts/DayPicker/labels/labelWeekNumber.ts +8 -0
- package/src/contexts/DayPicker/labels/labelWeekday.test.ts +15 -0
- package/src/contexts/DayPicker/labels/labelWeekday.ts +10 -0
- package/src/contexts/DayPicker/labels/labelYearDropdown.test.ts +5 -0
- package/src/contexts/DayPicker/labels/labelYearDropdown.ts +6 -0
- package/src/contexts/DayPicker/useDayPicker.test.ts +297 -0
- package/src/contexts/DayPicker/useDayPicker.ts +17 -0
- package/src/contexts/DayPicker/utils/index.ts +1 -0
- package/src/contexts/DayPicker/utils/parseFromToProps.test.ts +47 -0
- package/src/contexts/DayPicker/utils/parseFromToProps.ts +32 -0
- package/src/contexts/Focus/FocusContext.tsx +174 -0
- package/src/contexts/Focus/index.ts +2 -0
- package/src/contexts/Focus/useFocusContext.test.ts +183 -0
- package/src/contexts/Focus/useFocusContext.ts +12 -0
- package/src/contexts/Focus/utils/getInitialFocusTarget.test.tsx +12 -0
- package/src/contexts/Focus/utils/getInitialFocusTarget.tsx +44 -0
- package/src/contexts/Modifiers/ModifiersContext.tsx +44 -0
- package/src/contexts/Modifiers/index.ts +2 -0
- package/src/contexts/Modifiers/useModifiers.test.ts +46 -0
- package/src/contexts/Modifiers/useModifiers.ts +17 -0
- package/src/contexts/Modifiers/utils/getActiveModifiers.test.ts +53 -0
- package/src/contexts/Modifiers/utils/getActiveModifiers.ts +33 -0
- package/src/contexts/Modifiers/utils/getCustomModifiers.test.ts +14 -0
- package/src/contexts/Modifiers/utils/getCustomModifiers.ts +14 -0
- package/src/contexts/Modifiers/utils/getInternalModifiers.test.ts +146 -0
- package/src/contexts/Modifiers/utils/getInternalModifiers.ts +58 -0
- package/src/contexts/Modifiers/utils/isDateInRange.test.ts +28 -0
- package/src/contexts/Modifiers/utils/isDateInRange.ts +27 -0
- package/src/contexts/Modifiers/utils/isMatch.test.ts +92 -0
- package/src/contexts/Modifiers/utils/isMatch.ts +76 -0
- package/src/contexts/Modifiers/utils/matcherToArray.test.ts +22 -0
- package/src/contexts/Modifiers/utils/matcherToArray.ts +14 -0
- package/src/contexts/Navigation/NavigationContext.tsx +84 -0
- package/src/contexts/Navigation/index.ts +2 -0
- package/src/contexts/Navigation/useNavigation.test.ts +126 -0
- package/src/contexts/Navigation/useNavigation.ts +12 -0
- package/src/contexts/Navigation/useNavigationState.test.ts +36 -0
- package/src/contexts/Navigation/useNavigationState.ts +25 -0
- package/src/contexts/Navigation/utils/getDisplayMonths.ts +31 -0
- package/src/contexts/Navigation/utils/getInitialMonth.test.ts +56 -0
- package/src/contexts/Navigation/utils/getInitialMonth.ts +24 -0
- package/src/contexts/Navigation/utils/getNextMonth.test.ts +75 -0
- package/src/contexts/Navigation/utils/getNextMonth.ts +45 -0
- package/src/contexts/Navigation/utils/getPreviousMonth.test.ts +55 -0
- package/src/contexts/Navigation/utils/getPreviousMonth.ts +44 -0
- package/src/contexts/RootProvider.tsx +37 -0
- package/src/contexts/SelectMultiple/SelectMultipleContext.tsx +135 -0
- package/src/contexts/SelectMultiple/index.ts +2 -0
- package/src/contexts/SelectMultiple/useSelectMultiple.test.ts +191 -0
- package/src/contexts/SelectMultiple/useSelectMultiple.ts +17 -0
- package/src/contexts/SelectRange/SelectRangeContext.tsx +158 -0
- package/src/contexts/SelectRange/index.ts +2 -0
- package/src/contexts/SelectRange/useSelectRange.test.ts +282 -0
- package/src/contexts/SelectRange/useSelectRange.ts +15 -0
- package/src/contexts/SelectRange/utils/addToRange.test.ts +119 -0
- package/src/contexts/SelectRange/utils/addToRange.ts +43 -0
- package/src/contexts/SelectSingle/SelectSingleContext.tsx +80 -0
- package/src/contexts/SelectSingle/index.ts +2 -0
- package/src/contexts/SelectSingle/useSelectSingle.test.ts +81 -0
- package/src/contexts/SelectSingle/useSelectSingle.ts +17 -0
- package/src/hooks/useActiveModifiers/index.ts +1 -0
- package/src/hooks/useActiveModifiers/useActiveModifiers.test.tsx +36 -0
- package/src/hooks/useActiveModifiers/useActiveModifiers.tsx +18 -0
- package/src/hooks/useControlledValue/index.ts +1 -0
- package/src/hooks/useControlledValue/useControlledValue.test.ts +68 -0
- package/src/hooks/useControlledValue/useControlledValue.ts +24 -0
- package/src/hooks/useDayEventHandlers/index.ts +1 -0
- package/src/hooks/useDayEventHandlers/useDayEventHandlers.test.tsx +213 -0
- package/src/hooks/useDayEventHandlers/useDayEventHandlers.tsx +195 -0
- package/src/hooks/useDayRender/index.ts +1 -0
- package/src/hooks/useDayRender/useDayRender.test.tsx +304 -0
- package/src/hooks/useDayRender/useDayRender.tsx +123 -0
- package/src/hooks/useDayRender/utils/getDayClassNames.test.ts +63 -0
- package/src/hooks/useDayRender/utils/getDayClassNames.ts +32 -0
- package/src/hooks/useDayRender/utils/getDayStyle.ts +19 -0
- package/src/hooks/useInput/index.ts +1 -0
- package/src/hooks/useInput/useInput.ts +175 -0
- package/src/hooks/useInput/utils/isValidDate.tsx +4 -0
- package/src/hooks/useSelectedDays/index.ts +1 -0
- package/src/hooks/useSelectedDays/useSelectedDays.test.ts +72 -0
- package/src/hooks/useSelectedDays/useSelectedDays.ts +32 -0
- package/src/index.ts +43 -0
- package/src/style.css +310 -0
- package/src/style.css.d.ts +38 -0
- package/src/types/DayPickerBase.ts +267 -0
- package/src/types/DayPickerDefault.ts +15 -0
- package/src/types/DayPickerMultiple.ts +26 -0
- package/src/types/DayPickerRange.ts +27 -0
- package/src/types/DayPickerSingle.ts +24 -0
- package/src/types/EventHandlers.ts +87 -0
- package/src/types/Formatters.ts +29 -0
- package/src/types/Labels.ts +36 -0
- package/src/types/Matchers.ts +106 -0
- package/src/types/Modifiers.ts +62 -0
- package/src/types/Styles.ts +108 -0
- package/tsconfig.json +24 -0
- package/CHANGELOG.md +0 -26
- 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 @@
|
|
|
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;
|