Clawscale

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
PropsDescription
allowSingleDayRange
boolean = false
Whether 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
string
A space-delimited list of class names to pass along to a child element.
Inherited from Props
closeOnSelection
boolean = true
Whether the calendar popover should close when a date range is fully selected.
contiguousCalendarMonths
boolean = true
Whether displayed months in the calendar are contiguous. If false, each side of the calendar can move independently to non-contiguous months.
dateFnsFormat
string
date-fns format string used to format & parse date strings.
dateFnsLocaleLoader
DateFnsLocaleLoader
Optional custom loader function for the date-fns 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.
Inherited from DateFnsLocaleProps
dayPickerProps
Omit<DayPickerRangeProps, ReactDayPickerOmittedProps>
Props to pass to react-day-picker's day range picker. See API documentation here.
Inherited from ReactDayPickerRangeProps
defaultValue
DateRange
The default date range to be used in the component when uncontrolled. This will be ignored if value is set.
disabled
boolean = false
Whether the text inputs are non-interactive.
endInputProps
InputGroupProps
Props 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
boolean
Whether the component should take up the full width of its container.
footerElement
React.JSX.Element
An additional element to show below the date picker.
Inherited from DatePickerBaseProps
formatDate
(date: Date, localeCode?: string | undefined): string
Function to render a JavaScript 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.
Inherited from DateFormatProps
highlightCurrentDay
boolean = false
Whether the current day should be highlighted in the calendar.
Inherited from DatePickerBaseProps
initialMonth
Date
The 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 Locale object or locale code string ((ISO 639-1 + optional country code) which will be used to localize the date picker.
Inherited from 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) => void
Called 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) => void
Called 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 | null
Function to deserialize user input text to a JavaScript 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.
Inherited from DateFormatProps
placeholder
string
Placeholder 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 Popover.
Inherited from DatetimePopoverProps
popoverRef
React.RefObject<PopoverNextRef>
Optional ref to the popover. 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).
Inherited from DatetimePopoverProps
reverseMonthAndYearMenus
boolean = false
If 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.
Inherited from DatePickerBaseProps
selectAllOnFocus
boolean = false
Whether the entire text field should be selected on focus.
shortcuts
boolean | DateRangeShortcut[] = true
Whether 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 = false
Whether to show only a single month calendar.
startInputProps
InputGroupProps
Props 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
TimePickerProps
Further configure the TimePicker that appears beneath the calendar. onChange and value are ignored in favor of the corresponding top-level props on this component.
Inherited from DatePickerBaseProps
timePrecision
TimePrecision
The precision of time selection that accompanies the calendar. Passing a TimePrecision value (or providing timePickerProps) shows a TimePicker below the calendar. Time is preserved across date changes.
Inherited from DatePickerBaseProps
value
DateRange
The 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.