| Su | Mo | Tu | We | Th | Fr | Sa |
|---|---|---|---|---|---|---|
Selected: None
const [date, setDate] = useState<Date>();
<DatePicker mode="single" selected={date} onChange={setDate} /> Installation
Barrel
import { DatePicker, type DateRange } from "@cloudflare/kumo"; Granular
import { DatePicker, type DateRange } from "@cloudflare/kumo/components/date-picker"; Usage
DatePicker supports three selection modes: single,
multiple, and
range.
import { useState } from "react";
import { DatePicker } from "@cloudflare/kumo";
export default function Example() {
const [date, setDate] = useState<Date>();
return (
<DatePicker
mode="single"
selected={date}
onChange={setDate}
/>
);
} Examples
Single Date Selection
Select a single date. The most common use case for date pickers.
| Su | Mo | Tu | We | Th | Fr | Sa |
|---|---|---|---|---|---|---|
Selected: None
const [date, setDate] = useState<Date>();
<DatePicker
mode="single"
selected={date}
onChange={setDate}
/> Multiple Date Selection
Select multiple individual dates. Use max to limit the number of selections.
| Su | Mo | Tu | We | Th | Fr | Sa |
|---|---|---|---|---|---|---|
Selected: 0 date(s)
const [dates, setDates] = useState<Date[]>();
<DatePicker
mode="multiple"
selected={dates}
onChange={setDates}
max={5}
/> Date Range Selection
Select a continuous range of dates. Works well with numberOfMonths=2 for a side-by-side view.
| Su | Mo | Tu | We | Th | Fr | Sa |
|---|---|---|---|---|---|---|
| Su | Mo | Tu | We | Th | Fr | Sa |
|---|---|---|---|---|---|---|
Range: None
const [range, setRange] = useState<DateRange>();
<DatePicker
mode="range"
selected={range}
onChange={setRange}
numberOfMonths={2}
/> Range with Min/Max Constraints
Constrain the range length using min and
max props (in days/nights).
| Su | Mo | Tu | We | Th | Fr | Sa |
|---|---|---|---|---|---|---|
<DatePicker
mode="range"
selected={range}
onChange={setRange}
min={3}
max={7}
footer={<span>Select 3-7 nights</span>}
/> With Popover
Compose with the Popover component to create a dropdown date picker.
<Popover>
<Popover.Trigger asChild>
<Button variant="outline" icon={CalendarDotsIcon}>
{date ? date.toLocaleDateString() : "Pick a date"}
</Button>
</Popover.Trigger>
<Popover.Content className="p-1">
<DatePicker
mode="single"
selected={date}
onChange={(d) => setDate(d)}
/>
</Popover.Content>
</Popover> Date Range with Popover
A date range picker in a popover with two months displayed.
<Popover>
<Popover.Trigger asChild>
<Button variant="outline" icon={CalendarDotsIcon}>
{formatRange()}
</Button>
</Popover.Trigger>
<Popover.Content className="p-1">
<DatePicker
mode="range"
selected={range}
onChange={(r) => setRange(r)}
numberOfMonths={2}
/>
</Popover.Content>
</Popover> Date Range with Presets
Combine the date picker with preset options for quick selection.
<Popover>
<Popover.Trigger asChild>
<Button variant="outline" icon={CalendarDotsIcon}>
{formatRange()}
</Button>
</Popover.Trigger>
<Popover.Content className="p-0">
<div className="flex">
<div className="flex flex-col gap-1 border-r border-kumo-line p-2 text-sm">
{presets.map((preset) => (
<button
key={preset.label}
onClick={() => setRange(preset.range)}
className="rounded-md px-3 py-1.5 text-left hover:bg-kumo-control"
>
{preset.label}
</button>
))}
</div>
<div className="p-1">
<DatePicker
mode="range"
selected={range}
onChange={(r) => setRange(r)}
numberOfMonths={2}
/>
</div>
</div>
</Popover.Content>
</Popover> Disabled Dates with Usage Limits
Use the disabled prop to make certain dates unselectable,
and footer to display usage information.
| Su | Mo | Tu | We | Th | Fr | Sa |
|---|---|---|---|---|---|---|
const unavailableDates = [
new Date(2025, 0, 5),
new Date(2025, 0, 12),
];
<DatePicker
mode="multiple"
selected={dates}
onChange={setDates}
max={5}
disabled={unavailableDates}
footer={
<p className="text-xs text-kumo-subtle pt-2">
{selectedCount}/{maxDays} days selected. Grayed dates are unavailable.
</p>
}
/> Full Popover Example
Here's a complete example showing how to compose DatePicker with Popover:
import { useState } from "react";
import { DatePicker, Popover, Button } from "@cloudflare/kumo";
import { CalendarDotsIcon } from "@phosphor-icons/react";
export function DatePickerDropdown() {
const [date, setDate] = useState<Date>();
return (
<Popover>
<Popover.Trigger asChild>
<Button variant="outline" icon={CalendarDotsIcon}>
{date ? date.toLocaleDateString() : "Pick a date"}
</Button>
</Popover.Trigger>
<Popover.Content className="p-3">
<DatePicker
mode="single"
selected={date}
onChange={(d) => setDate(d)}
/>
</Popover.Content>
</Popover>
);
} API Reference
DatePicker forwards all props to react-day-picker. Key props include:
mode—"single" | "multiple" | "range"— Selection mode (required)selected— Currently selected date(s)onChange— Callback when selection changesnumberOfMonths— Number of months to displaydisabled— Dates that cannot be selectedmin/max— Min/max selection constraintsfooter— Content rendered below the calendarlocale— date-fns locale for internationalizationclassName— Additional CSS classes
See the react-day-picker documentation for the full API.
Differences from react-day-picker
For consistency with other Kumo form components, DatePicker uses onChange instead of react-day-picker's onSelect.
Full type inference is preserved — TypeScript will correctly narrow the callback signature based on the mode prop.