useDatePicker

The core hook for single date selection. Manages calendar state, open/close behavior, keyboard navigation, and date formatting.

Import

import { useDatePicker } from "react-date-range-picker-headless";

Usage

import { useState } from "react";
import { useDatePicker } from "react-date-range-picker-headless";
function MyDatePicker() {
const [date, setDate] = useState<Date | null>(null);
const picker = useDatePicker({
value: date,
onChange: setDate,
});
return (
<div ref={picker.containerRef}>
<button onClick={picker.handleToggle}>
{picker.displayValue || picker.locale.placeholder}
</button>
{picker.isOpen && (
<div ref={picker.popupRef} onKeyDown={picker.handleKeyDown}>
{/* Calendar header */}
<button onClick={picker.handlePrevMonth}>{picker.locale.prevMonth}</button>
<span>{picker.locale.formatMonthYear(picker.calendar.month)}</span>
<button onClick={picker.handleNextMonth}>{picker.locale.nextMonth}</button>
{/* Calendar grid */}
{picker.calendar.weeks.flat().map((day, i) => {
if (!day) return <span key={i} />;
const dp = picker.getDayProps(day);
return (
<button key={i} onClick={() => picker.handleDateClick(day)} disabled={dp.isDisabled}>
{dp.day}
</button>
);
})}
{/* Footer */}
<button onClick={picker.handleConfirm}>{picker.locale.confirm}</button>
</div>
)}
</div>
);
}

Options

OptionTypeDefaultDescription
valueDate | nullRequired. The currently selected date.
onChange(date: Date | null) => voidRequired. Called when the date selection changes.
minDateDateEarliest selectable date.
maxDateDateLatest selectable date.
localePartial<Locale>DEFAULT_LOCALEOverride locale strings.
initialMonthDateMonth to display initially (defaults to value or today).
sizeDatePickerSizeUI pass-through for styled components. Headless hooks ignore this.
weekStartsOnWeekDay"sunday"First day of the week.
isDateUnavailable(date: Date) => booleanCustom function to disable specific dates.
displayFormatstringCustom format string for the display value (e.g. "YYYY/MM/DD").
openbooleanControlled open state. When provided, the hook does not manage open state internally.
initialOpenbooleanfalseInitial open state (uncontrolled mode).
onOpenChange(open: boolean) => voidCallback when open state changes. Works with both controlled and uncontrolled modes.
requiredbooleanfalseWhen true, handleClear is a no-op.
todayDatenew Date()Override today’s date for isToday and disablePast/disableFuture calculations.
onMonthChange(month: Date) => voidCallback when the displayed month changes.
disablePastbooleanfalseDisable all dates before today.
disableFuturebooleanfalseDisable all dates after today.
showOutsideDaysbooleanfalseShow days from adjacent months to fill the 6-week grid.
highlightDatesDate[]Array of dates to highlight in the calendar.
shouldCloseOnSelectbooleanfalseAuto-confirm and close on date click.
numberOfMonthsnumber1Number of months to display simultaneously.
captionLayoutCaptionLayout"buttons""buttons" for prev/next arrows, "dropdown" for year/month selects.
fromYearnumbercurrent year - 100Start year for dropdown mode.
toYearnumbercurrent year + 10End year for dropdown mode.

Return Values

NameTypeDescription
isOpenbooleanWhether the popup is open.
tempDateDate | nullTemporary selected date (before confirmation).
currentMonthDateThe currently displayed month.
localeLocaleResolved locale object with all strings.
calendarCalendarMonthCalendar data for the current month (includes month, days, weeks).
calendarsCalendarMonth[]Array of calendar months (length = numberOfMonths).
getDayProps(date: Date, referenceMonth?: Date) => DayPropsCompute flags for a calendar day cell.
displayValuestringFormatted string of the confirmed value.
hasValuebooleanWhether a date is currently confirmed.
canConfirmbooleanWhether the current selection is valid for confirmation.
handleDateClick(date: Date) => voidHandle a day cell click.
handlePrevMonth() => voidNavigate to previous month.
handleNextMonth() => voidNavigate to next month.
handleOpen() => voidOpen the popup.
handleClose() => voidClose the popup (discards uncommitted changes).
handleToggle() => voidToggle the popup.
handleConfirm() => voidConfirm the selection and close.
handleCancel() => voidCancel and revert to previous value.
handleClear() => voidClear the value (no-op if required).
handleGoToToday() => voidNavigate the calendar to today’s month.
containerRefRefObject<HTMLDivElement | null>Attach to the wrapper element for click-outside detection.
popupRefRefObject<HTMLDivElement | null>Attach to the popup element.
focusedDateDate | nullCurrently keyboard-focused date.
handleKeyDown(e: KeyboardEvent<HTMLElement>) => voidKeyboard event handler for arrow keys, Enter, Escape, Tab.
yearsnumber[]Array of years for dropdown caption mode.
monthsnumber[]Array of month indices (0-11) for dropdown caption mode.
handleYearSelect(year: number, calendarIndex?: number) => voidSet the displayed year (dropdown mode).
handleMonthSelect(month: number, calendarIndex?: number) => voidSet the displayed month (dropdown mode).

Key Behaviors

Controlled vs Uncontrolled Open State

By default, the hook manages open/close internally. To control it externally, pass open and onOpenChange:

const [isOpen, setIsOpen] = useState(false);
const picker = useDatePicker({
value: date,
onChange: setDate,
open: isOpen,
onOpenChange: setIsOpen,
});

shouldCloseOnSelect

When shouldCloseOnSelect is true, clicking a date immediately confirms and closes the popup, skipping the explicit confirm step.

Keyboard Navigation

KeyAction
Arrow Up/Down/Left/RightMove focus between days
Enter / SpaceSelect the focused date
EscapeCancel and close
TabMove focus within the popup

Caption Dropdown

When captionLayout is "dropdown", the header shows year and month select dropdowns instead of prev/next buttons. Use years, months, handleYearSelect, and handleMonthSelect to render the dropdowns.