ComponentsDateRangePicker
DateRangePicker
Let users choose a start date and an end date.
On this page
Use this component from the local workspace package. Follow the setup guide first. A public npm package and registry are not available yet.
View registry filesImport the component into your page or component file.
import {
DateRangePicker,
type DateRangePickerValue,
} from "@dethink/components";
import { CalendarDate } from "@internationalized/date";Try the examples, then open the code to use them in your app. Tab through the start and end segments, or open the popover and pick both ends on the range calendar.
Basic
Label and helper description around the linked start–end field — the uncontrolled default.
Show sourceexamples/date-range-picker/basic.tsx
"use client";
import { DateRangePicker } from "@dethink/components";
export function DateRangePickerBasic() {
return (
<div className="mx-auto max-w-sm">
<DateRangePicker
label="Trip dates"
description="Both nights are included in the rate."
/>
</div>
);
}Controlled and clearable
value and onValueChange hold the { start, end } pair in React state; clearable resets the whole range at once.
2026-07-06 → 2026-07-17
Show sourceexamples/date-range-picker/controlled.tsx
"use client";
import { useState } from "react";
import {
DateRangePicker,
type DateRangePickerValue,
} from "@dethink/components";
import { CalendarDate } from "@internationalized/date";
export function DateRangePickerControlled() {
const [value, setValue] = useState<DateRangePickerValue | null>({
start: new CalendarDate(2026, 7, 6),
end: new CalendarDate(2026, 7, 17),
});
return (
<div className="mx-auto max-w-sm space-y-3">
<DateRangePicker
label="Sprint window"
value={value}
onValueChange={setValue}
clearable
/>
<p className="text-muted-foreground text-sm">
{value
? `${value.start.toString()} → ${value.end.toString()}`
: "No range selected"}
</p>
</div>
);
}Native form submission
startName and endName name the hidden inputs, so a plain FormData read gets both ISO dates.
Show sourceexamples/date-range-picker/form.tsx
"use client";
import { useState } from "react";
import { Button, DateRangePicker } from "@dethink/components";
export function DateRangePickerForm() {
const [submitted, setSubmitted] = useState<string | null>(null);
return (
<form
className="mx-auto max-w-sm space-y-3"
onSubmit={(event) => {
event.preventDefault();
const data = new FormData(event.currentTarget);
setSubmitted(
`checkIn=${data.get("checkIn")} checkOut=${data.get("checkOut")}`,
);
}}
>
<DateRangePicker
label="Stay"
startName="checkIn"
endName="checkOut"
required
/>
<Button type="submit" size="sm">
Book
</Button>
{submitted ? (
<p className="text-muted-foreground font-mono text-xs">{submitted}</p>
) : null}
</form>
);
}Bounds
minValue and maxValue clamp both ends of the range to a window.
Show sourceexamples/date-range-picker/bounds.tsx
"use client";
import { DateRangePicker } from "@dethink/components";
import { CalendarDate } from "@internationalized/date";
export function DateRangePickerBounds() {
return (
<div className="mx-auto max-w-sm">
<DateRangePicker
label="Q3 review period"
description="Must fall inside the third quarter."
minValue={new CalendarDate(2026, 7, 1)}
maxValue={new CalendarDate(2026, 9, 30)}
defaultValue={{
start: new CalendarDate(2026, 7, 6),
end: new CalendarDate(2026, 7, 17),
}}
/>
</div>
);
}DateRangePicker owns its field anatomy — pass a label instead of wrapping it in an external one.
| Prop | What it does | Default |
|---|---|---|
valueDateRangePickerValue | null | Controlled range — { start, end } CalendarDates from @internationalized/date. | Not set |
defaultValueDateRangePickerValue | null | Initial range for uncontrolled usage. | Not set |
onValueChange(value: DateRangePickerValue | null) => void | Fires when the range changes or is cleared. | Not set |
label / description / errorMessageReactNode | The field label, help text, and error message. | Not set |
namestring | Base name for the hidden inputs — submits as "<name>Start" and "<name>End". | Not set |
startName / endNamestring | Explicit hidden input names for the start and end dates; override the base name. | Not set |
required / disabled / readOnly / invalidboolean | Makes the field required, disabled, read-only, or invalid. | false |
clearableboolean | Shows a clear button when a range is selected. | false |
minValue / maxValueDateValue | Inclusive bounds enforced across both ends of the range. | Not set |
isDateUnavailable(date: DateValue) => boolean | Marks individual dates unavailable in the popover calendar. | Not set |
localestring | BCP 47 tag controlling segment order and formatting. | runtime locale |
weekStartsOn"sun" | "mon" | … | "sat" | First day of the week in the popover calendar. | locale default |