useStandaloneTimePicker
Manages time state with open/close and click-outside behavior.
Import
import { useStandaloneTimePicker } from "react-date-range-picker-headless";Usage
import { useState } from "react";import { useStandaloneTimePicker } from "react-date-range-picker-headless";
function MyTimePicker() { const [time, setTime] = useState<Date | null>(null);
const picker = useStandaloneTimePicker({ value: time, onChange: setTime, time: { precision: "minute", hourFormat: "24", minuteStep: 5 }, placeholder: "Select time", });
return ( <div ref={picker.containerRef}> <button onClick={picker.handleToggle}> {picker.hasValue ? picker.displayValue : "Select time"} </button>
{picker.isOpen && ( <div ref={picker.popupRef} onKeyDown={picker.handleKeyDown}> <div> <span>{String(picker.tempHour).padStart(2, "0")}</span> <span>:</span> <span>{String(picker.tempMinute).padStart(2, "0")}</span> </div>
{/* Hook up hour/minute controls */} <input type="range" min={0} max={23} value={picker.tempHour} onChange={(e) => picker.handleHourChange(Number(e.target.value))} /> <input type="range" min={0} max={55} step={5} value={picker.tempMinute} onChange={(e) => picker.handleMinuteChange(Number(e.target.value))} />
<div> <button onClick={picker.handleClear}>Clear</button> <button onClick={picker.handleCancel}>Cancel</button> <button onClick={picker.handleConfirm}>Confirm</button> </div> </div> )} </div> );}Options
| Option | Type | Default | Description |
|---|---|---|---|
value | Date | null | — | Required. Current time as a Date object (only the time portion is used). |
onChange | (date: Date | null) => void | — | Required. Called when the time is confirmed. |
time | TimeConfig | { precision: "minute", hourFormat: "24", minuteStep: 5, secondStep: 1 } | Time picker configuration. |
locale | Partial<Locale> | DEFAULT_LOCALE | Override locale strings. |
displayFormat | string | — | Custom format string for the trigger display. |
placeholder | string | — | Placeholder text when no value is selected. |
open | boolean | — | Controlled open state. |
initialOpen | boolean | false | Initial open state (uncontrolled). |
onOpenChange | (open: boolean) => void | — | Callback when open state changes. |
required | boolean | false | When true, handleClear is a no-op. |
inline | boolean | false | Always show the panel without a trigger/popup. |
name | string | — | Hidden input name for form submission. |
Return Values
| Name | Type | Description |
|---|---|---|
isOpen | boolean | Whether the popup is currently open. |
handleOpen | () => void | Open the popup. |
handleClose | () => void | Close the popup. |
handleToggle | () => void | Toggle the popup. |
tempHour | number | Current temporary hour value. |
tempMinute | number | Current temporary minute value. |
tempSecond | number | Current temporary second value. |
tempPeriod | TimePeriod | Current AM/PM period. |
handleHourChange | (hour: number) => void | Update the temporary hour. |
handleMinuteChange | (minute: number) => void | Update the temporary minute. |
handleSecondChange | (second: number) => void | Update the temporary second. |
handlePeriodChange | (period: TimePeriod) => void | Update AM/PM period. |
handleConfirm | () => void | Confirm the temporary time, call onChange, and close the popup. |
handleCancel | () => void | Revert to the original value and close the popup. |
handleClear | () => void | Clear the value and close. No-op if required. |
displayValue | string | Formatted time string for the trigger (committed value). |
timeDisplayValue | string | Formatted time string for the panel (temporary value). |
hasValue | boolean | Whether a time value is currently set. |
canConfirm | boolean | Whether the confirm button should be enabled. |
locale | Locale | Resolved locale object. |
resolvedTimeConfig | Required<TimeConfig> | Fully resolved time configuration. |
containerRef | RefObject<HTMLDivElement | null> | Ref for the outer container (used for click-outside detection). |
popupRef | RefObject<HTMLDivElement | null> | Ref for the popup element (used for click-outside detection). |
handleKeyDown | (e: KeyboardEvent) => void | Keyboard handler (Escape to cancel). |
Key Behaviors
Open/Close
The popup can be controlled or uncontrolled. When open is provided, the hook uses it as the source of truth. Otherwise, internal state is used with initialOpen as the starting value.
Click Outside
Clicking outside both containerRef and popupRef triggers handleCancel, reverting to the original value and closing the popup.
Keyboard
Pressing Escape while the popup is open triggers handleCancel.
Inline Mode
When inline is true, the panel is always visible and changes are applied immediately (auto-sync). The open/close logic is bypassed.
Temporary State Pattern
This hook maintains temporary state that only commits when handleConfirm is called:
handleConfirm— writes temporary state toonChangeand closes the popuphandleCancel— reverts temporary state to the currentvalueand closeshandleClear— callsonChange(null)and closes
Display Values
displayValue— formatted string of the committedvalue(for the trigger)timeDisplayValue— formatted string of the temporary values (for the panel)