Date range input
A DateRangeInput is a pair of text fields for the start and end of a range, with a Date range picker in a popover. Its value is a DateRange of Date objects.
Usage#
import { type DateRange, DateRangeInput } from "@clawscale/react/datetime";<DateRangeInput dateFnsFormat="yyyy-MM-dd" value={range} onChange={setRange} />Examples#
Basic#
dateFnsFormat sets how both fields format and parse dates, here "MMM d, yyyy". For full control, pass formatDate and parseDate instead. The popover closes once both ends are set. Set closeOnSelection={false} to keep it open.
import { DateRangeInput } from "@clawscale/react/datetime";
export default function DateRangeInputBasic() {
return (
<DateRangeInput
dateFnsFormat="MMM d, yyyy"
shortcuts={false}
defaultValue={[new Date(2026, 8, 8), new Date(2026, 8, 14)]}
/>
);
}Shortcuts#
Shortcuts are on by default. Pass an array of { label, dateRange } objects for your own ranges, such as sprints, or false to hide them.
import { type DateRange, DateRangeInput, type DateRangeShortcut } from "@clawscale/react/datetime";
const sprint43: DateRange = [new Date(2026, 8, 14), new Date(2026, 8, 25)];
const sprints: DateRangeShortcut[] = [
{ label: "Sprint 41", dateRange: [new Date(2026, 7, 17), new Date(2026, 7, 28)] },
{ label: "Sprint 42", dateRange: [new Date(2026, 7, 31), new Date(2026, 8, 11)] },
{ label: "Sprint 43", dateRange: sprint43 },
];
export default function DateRangeInputShortcuts() {
return <DateRangeInput shortcuts={sprints} defaultValue={sprint43} />;
}Controlled#
Pass value and onChange to control the range. [null, null] empties both fields. Typed dates that are invalid, out of range or overlapping call onError instead of onChange.
3 days in the export
import { Button } from "@clawscale/react";
import { type DateRange, DateRangeInput } from "@clawscale/react/datetime";
import { useState } from "react";
const incident: DateRange = [new Date(2026, 8, 12), new Date(2026, 8, 14)];
function countDays([start, end]: DateRange) {
return start && end ? Math.round((end.getTime() - start.getTime()) / 86_400_000) + 1 : 0;
}
export default function DateRangeInputControlled() {
const [range, setRange] = useState<DateRange>(incident);
return (
<div style={{ display: "grid", gap: 12, justifyItems: "start" }}>
<DateRangeInput shortcuts={false} value={range} onChange={setRange} />
<div style={{ alignItems: "center", display: "flex", gap: 8 }}>
<Button text="Reset to incident" onClick={() => setRange(incident)} />
<Button variant="minimal" text="Clear" onClick={() => setRange([null, null])} />
<span>{countDays(range)} days in the export</span>
</div>
</div>
);
}Props interface#
interface DateRangeInputProps extends Omit<DatePickerBaseProps, "dayPickerProps" | "locale" | "modifiers">, ReactDayPickerRangeProps, DateFnsLocaleProps, Partial<Omit<DateFormatProps, "locale">>, DatetimePopoverProps, Props@clawscale/react/datetime| Props | Description |
|---|---|
allowSingleDayRange | boolean = falseWhether the start and end dates of the range can be the same day. If true, clicking a selected date will create a one-day range. If false, clicking a selected date will clear the selection. |
className | stringA space-delimited list of class names to pass along to a child element. Inherited from Props |
closeOnSelection | boolean = trueWhether the calendar popover should close when a date range is fully selected. |
contiguousCalendarMonths | boolean = trueWhether displayed months in the calendar are contiguous. If false, each side of the calendar can move independently to non-contiguous months. |
dateFnsFormat | stringdate-fns format string used to format & parse date strings. |
dateFnsLocaleLoader | DateFnsLocaleLoaderOptional custom loader function for the date-fns Inherited from Locale which will be used to localize the date picker. This is useful in test environments or in build systems where you wish to customize module loading behavior. If not provided, a default loader will be used which uses dynamic imports to load date-fns/locale/${localeCode} modules.DateFnsLocaleProps |
dayPickerProps | Omit<DayPickerRangeProps, ReactDayPickerOmittedProps>Props to pass to react-day-picker's day range picker. See API documentation here. Inherited from ReactDayPickerRangeProps |
defaultValue | DateRangeThe default date range to be used in the component when uncontrolled. This will be ignored if value is set. |
disabled | boolean = falseWhether the text inputs are non-interactive. |
endInputProps | InputGroupPropsProps to pass to the end-date input group. disabled and value will be ignored in favor of the top-level props on this component. ref is not supported; use inputRef instead. |
fill | booleanWhether the component should take up the full width of its container. |
footerElement | React.JSX.ElementAn additional element to show below the date picker. Inherited from DatePickerBaseProps |
formatDate | (date: Date, localeCode?: string | undefined): stringFunction to render a JavaScript Inherited from Date to a string. Optional localeCode argument comes directly from the prop on this component: if the prop is defined, then the argument will be too.DateFormatProps |
highlightCurrentDay | boolean = falseWhether the current day should be highlighted in the calendar. Inherited from DatePickerBaseProps |
initialMonth | DateThe initial month the calendar displays. Inherited from DatePickerBaseProps |
invalidDateMessage | string = "Invalid date"The error message to display when the date selected is invalid. Inherited from DateFormatProps |
locale | Locale | string = "en-US"date-fns Inherited from Locale object or locale code string ((ISO 639-1 + optional country code) which will be used to localize the date picker.DateFnsLocaleProps |
maxDate | Date = 6 months from now.The latest date the user can select. Inherited from DatePickerBaseProps |
minDate | Date = Jan. 1st, 20 years in the past.The earliest date the user can select. Inherited from DatePickerBaseProps |
onChange | (selectedRange: DateRange) => voidCalled when the user selects a day. If no days are selected, it will pass [null, null]. If a start date is selected but not an end date, it will pass [selectedDate, null]. If both a start and end date are selected, it will pass [startDate, endDate]. |
onError | (errorRange: DateRange) => voidCalled when the user finishes typing in a new date and the date causes an error state. If the date is invalid, new Date(undefined) will be returned for the corresponding boundary of the date range. If the date is out of range, the out-of-range date will be returned for the corresponding boundary of the date range (onChange is not called in this case). |
outOfRangeMessage | string = "Out of range"The error message to display when the date selected is out of range. Inherited from DateFormatProps |
overlappingDatesMessage | string = "Overlapping dates"The error message to display when the selected dates overlap. This can only happen when typing dates in the input field. |
parseDate | (str: string, localeCode?: string | undefined): false | Date | nullFunction to deserialize user input text to a JavaScript Inherited from Date object. Return false if the string is an invalid date. Return null to represent the absence of a date. Optional localeCode argument comes directly from the prop on this component.DateFormatProps |
placeholder | stringPlaceholder text to display in empty input fields. Recommended practice is to indicate the expected date format. Inherited from DateFormatProps |
popoverProps | Partial<Omit<PopoverProps, "autoFocus" | "content" | "defaultIsOpen" | "disabled" | "enforceFocus" | "fill" | "renderTarget">>Props to spread to Inherited from Popover.DatetimePopoverProps |
popoverRef | React.RefObject<PopoverNextRef>Optional ref to the popover. Inherited from popoverRef.current?.reposition() re-runs position calculation, useful when the target moves in a way the popover doesn't observe automatically (e.g. a parent layout change that doesn't trigger a resize).DatetimePopoverProps |
reverseMonthAndYearMenus | boolean = falseIf Inherited from true, the month menu will appear to the left of the year menu. Otherwise, the month menu will apear to the right of the year menu.DatePickerBaseProps |
selectAllOnFocus | boolean = falseWhether the entire text field should be selected on focus. |
shortcuts | boolean | DateRangeShortcut[] = trueWhether shortcuts to quickly select a range of dates are displayed or not. If true, preset shortcuts will be displayed. If false, no shortcuts will be displayed. If an array is provided, the custom shortcuts will be displayed. |
singleMonthOnly | boolean = falseWhether to show only a single month calendar. |
startInputProps | InputGroupPropsProps to pass to the start-date input group. disabled and value will be ignored in favor of the top-level props on this component. ref is not supported; use inputRef instead. |
timePickerProps | TimePickerPropsFurther configure the Inherited from TimePicker that appears beneath the calendar. onChange and value are ignored in favor of the corresponding top-level props on this component.DatePickerBaseProps |
timePrecision | TimePrecisionThe precision of time selection that accompanies the calendar. Passing a Inherited from TimePrecision value (or providing timePickerProps) shows a TimePicker below the calendar. Time is preserved across date changes.DatePickerBaseProps |
value | DateRangeThe currently selected date range. If the prop is strictly undefined, the component acts in an uncontrolled manner. If this prop is anything else, the component acts in a controlled manner. To display an empty value in the input fields in a controlled manner, pass [null, null]. To display an invalid date error in either input field, pass new Date(undefined) for the appropriate date in the value prop. |