A set of React hooks to create an awesome datepicker.
export const DatePicker: FC = () => {
// prepare state to handle selected date
const [selectedDate, setSelectedDate] = useState<OnDateChangeType>(null);
const {
activeMonths,
firstDayOfWeek,
} = useDatePicker({
selectedDate,
minBookingDate: new Date(),
onDateChange: setSelectedDate,
});
// you can use DatePickerContext that helps you avoid passing callbacks throught components
return (
<DatePickerContext.Provider value={{ addPropsHere }}>
{activeMonths.map(month => (
<DateRangePickerMonth
firstDayOfWeek={firstDayOfWeek}
key={`${month.year}-${month.month}`}
month={month.month}
year={month.year}
/>
))}
</DatePickerContext.Provider>
);
};
export const DateRangePickerMonth: FC<UseMonthProps> = ({
firstDayOfWeek,
month,
year,
}) => {
const { days, monthLabel } = useMonth({
year,
month,
firstDayOfWeek,
});
return (
<div>
<p>{monthLabel}</p>
<div style={{ display: "grid" }}>
{days.map((day, index) => {
return <DateRangePickerDay date={day.date} key={day.dayLabel + index} day={day.dayLabel} />;
})}
</div>
</div>
);
};
export const DateRangePickerDay: FC<{ day: string; date: Date }> = ({ day, date }) => {
const dayRef = useRef(null);
const {
focusedDate,
isDateFocused,
isDateSelected,
isDateHovered,
isDateBlocked,
onDateSelect,
onDateFocus,
onDateHover,
} = useContext(DatePickerContext);
const { disabledDate, isSelected, isWithinHoverRange, onClick, isToday } =
useDay<HTMLDivElement>({
date,
dayRef,
focusedDate,
isDateFocused,
isDateSelected,
isDateHovered,
isDateBlocked,
onDateFocus,
onDateSelect,
onDateHover,
});
if (!day) {
return <div />;
}
return (
<button
type="button"
ref={dayRef}
onClick={onClick}
className= {clsx({
"day__disabled": disabledDate,
"day__selected": isSelected,
"day__today": isToday,
})}
>
{day}
</button>
);
};
UseDatePickerProps
name | type | required | default | description |
---|---|---|---|---|
firstDayOfWeek | FirstDayOfWeek |
0 |
||
initialVisibleMonth | Date |
|||
isDateBlocked | (date: Date) => boolean |
() => false |
||
maxBookingDate | Date |
|||
minBookingDate | Date |
|||
numberOfMonths | number |
1 |
||
onDateChange | (data: OnDateChangeType): void |
yes | ||
selectedDate | Date | null |
yes | ||
unavailableDates | Date[] |
[] |
@deprecated | |
datesConfig | DatesConfig[] |
[] |
UseDatePickerReturnType
name | type | description |
---|---|---|
canGoToMonth | (month: Date) => boolean |
|
canGoToNextMonth | boolean |
|
canGoToNextYear | boolean |
|
canGoToPrevMonth | boolean |
|
canGoToPrevYear | boolean |
|
canGoToYear | (month: Date) => boolean |
|
goToDate | (date: Date) => void |
|
goToNextMonths | () => void |
|
goToNextMonthsByOneMonth | () => void |
|
goToNextYear | () => void |
|
goToPrevMonths | () => void |
|
goToPrevMonthsByOneMonth | () => void |
|
goToPrevYear | () => void |
|
activeMonths | MonthType[] |
|
firstDayOfWeek | FirstDayOfWeek |
|
focusedDate | Date | null |
|
hoveredDate | Date | null |
|
isDateBlocked | (date: Date) => boolean |
|
isDateFocused | (date: Date) => boolean |
|
isDateHovered | (date: Date) => boolean |
|
isDateSelected | (date: Date) => boolean |
|
numberOfMonths | number |
|
onDateFocus | (date: Date) => void |
|
onDateHover | (date: Date | null) => void |
|
onDateSelect | (date: Date) => void |
|
onResetDates | () => void |
UseDateRangePickerProps
name | type | required | default | description |
---|---|---|---|---|
changeActiveMonthOnSelect | boolean |
false |
||
endDate | Date | null |
yes | ||
exactMinBookingDays | boolean |
false |
||
firstDayOfWeek | FirstDayOfWeek |
0 |
||
focusedInput | FocusedInput |
yes | startDate |
|
initialVisibleMonth | Date |
|||
isDateBlocked | (date: Date) => boolean |
() => false |
||
maxBookingDate | Date |
|||
minBookingDate | Date |
|||
minBookingDates | number |
1 |
||
numberOfMonths | number |
2 |
||
onDatesChange | (data: OnDatesChangeType): void |
yes | ||
startDate | Date | null |
yes | ||
unavailableDates | Date[] |
[] |
@deprecated | |
datesConfig | DatesConfig[] |
[] |
UseDateRangePickerReturnType
name | type | description |
---|---|---|
canGoToMonth | (month: Date) => boolean |
|
canGoToNextMonth | boolean |
|
canGoToNextYear | boolean |
|
canGoToPrevMonth | boolean |
|
canGoToPrevYear | boolean |
|
canGoToYear | (month: Date) => boolean |
|
goToDate | (date: Date) => void |
|
goToNextMonths | () => void |
|
goToNextMonthsByOneMonth | () => void |
|
goToNextYear | () => void |
|
goToPrevMonths | () => void |
|
goToPrevMonthsByOneMonth | () => void |
|
goToPrevYear | () => void |
|
activeMonths | MonthType[] |
|
firstDayOfWeek | FirstDayOfWeek |
|
focusedDate | Date | null |
|
hoveredDate | Date | null |
|
isDateBlocked | (date: Date) => boolean |
|
isDateFocused | (date: Date) => boolean |
|
isDateHovered | (date: Date) => boolean |
|
isDateSelected | (date: Date) => boolean |
|
isEndDate | (date: Date) => boolean |
|
isStartDate | (date: Date) => boolean |
|
numberOfMonths | number |
|
onDateFocus | (date: Date) => void |
|
onDateHover | (date: Date | null) => void |
|
onDateSelect | (date: Date) => void |
|
onResetDates | () => void |
UseDecadeProps
name | type | required | default | description |
---|---|---|---|---|
decadeLabelFormat | (start: Date, end: Date) => string |
|||
year | number |
yes | ||
yearLabelFormat | 'date: Date) => string |
UseDecadeReturnType
name | type | description |
---|---|---|
years | { yearLabel : string; date: Date }[] |
|
decadeLabel | string |
UseYearProps
name | type | required | default | description |
---|---|---|---|---|
year | number |
yes | ||
yearLabelFormat | (date: Date) => string |
|||
monthLabelFormat | (date: Date) => string |
UseYearReturnType
name | type | description |
---|---|---|
months | { monthLabel : string; date: Date }[] |
|
yearLabel | string |
UseMonthProps
name | type | required | default | description |
---|---|---|---|---|
year | number |
yes | ||
month | number |
yes | ||
firstDayOfWeek | FirstDayOfWeek |
0 |
||
dayLabelFormat | (date: Date) => string |
|||
weekdayLabelFormat | (date: Date) => string |
|||
monthLabelFormat | (date: Date) => string |
UseMonthReturnType
name | type | description |
---|---|---|
days | {currentMonth: boolean; dayLabel: string; date: Date })[] |
|
monthLabel | string |
|
weekdayLabels | string[] |
UseDayProps
name | type | required | default | description |
---|---|---|---|---|
date | Date |
yes | ||
dayRef | RefObject |
|||
focusedDate | Date | null |
yes | ||
isDateBlocked | (date: Date) => boolean |
yes | ||
isDateFocused | (date: Date) => boolean |
yes | ||
isDateHovered | (date: Date) => boolean |
yes | ||
isDateSelected | (date: Date) => boolean |
yes | ||
onDateFocus | (date: Date) => void |
yes | ||
onDateHover | (date: Date) => void |
yes | ||
onDateSelect | (date: Date) => void |
yes | ||
unavailableDates | Date[] |
@deprecated | ||
datesConfig | DatesConfig[] |
UseDayReturnType
name | type | description |
---|---|---|
disabledDate | boolean |
|
isFirstDisabled | boolean |
|
isLastDisabled | boolean |
|
disabledDate | boolean |
|
isHovered | boolean |
|
isSelected | boolean |
|
isToday | boolean |
|
isWithinHoverRange | boolean |
|
onClick | () => void |
|
onKeyDown | (e: KeyboardEvent) => void |
|
onMouseEnter | () => void |
|
tabIndex | number |
|
flags | Flag[] |
- keyboard navigation doesn't work for year and decade view
- the demo needs a little more love!