Event date
mm/dd/yyyy
mm/dd/yyyy
"use client"
import {
DateRangePicker,
DateRangePickerTrigger,
} from "@/components/ui/preskok-ui/date-range-picker"
import { Label } from "@/components/ui/preskok-ui/field"
export function Component() {
return (
<div className="max-w-xs">
<DateRangePicker visibleDuration={{ months: 2 }}>
<Label>Event date</Label>
<DateRangePickerTrigger />
</DateRangePicker>
</div>
)
}
Installation
pnpmnpmyarnbunpnpm dlx @preskok-org/ui@latest add date-range-picker
Usage
import { parseDate } from "@internationalized/date"
import {
DateRangePicker,
DateRangePickerTrigger,
} from "@/registry/preskok/ui/preskok-ui/date-range-picker"
import { Label } from "@/registry/preskok/ui/preskok-ui/field"
export function Example() {
return (
<DateRangePicker
visibleDuration={{ months: 2 }}
defaultValue={{
start: parseDate("2024-02-10"),
end: parseDate("2024-02-20"),
}}
>
<Label>Date range</Label>
<DateRangePickerTrigger />
</DateRangePicker>
)
}Props
- visibleDuration:
DateDuration— Number of months shown. - pageBehavior:
"visible" | "single"— Paging behavior for multi-month view. - popover:
PopoverProps(without children) — Desktop overlay options. - Inherits all
react-aria-componentsDateRangePickerprops. - Compose field content using
Label,DateRangePickerTrigger, and optionalFieldError.
Features
- Two inputs with separator
- Responsive popover/modal overlay
- Keyboard and screen reader support
Examples
Basic
Event date
mm/dd/yyyy
mm/dd/yyyy
"use client"
import {
DateRangePicker,
DateRangePickerTrigger,
} from "@/components/ui/preskok-ui/date-range-picker"
import { Label } from "@/components/ui/preskok-ui/field"
export function Component() {
return (
<div className="max-w-xs">
<DateRangePicker visibleDuration={{ months: 2 }}>
<Label>Event date</Label>
<DateRangePickerTrigger />
</DateRangePicker>
</div>
)
}
Controlled
Event date
4/8/2026
4/14/2026
Selected: Apr 8, 2026 - Apr 14, 2026
"use client"
import { useState } from "react"
import type { CalendarDate } from "@internationalized/date"
import { getLocalTimeZone, parseDate } from "@internationalized/date"
import type { RangeValue } from "react-aria-components"
import {
DateRangePicker,
DateRangePickerTrigger,
} from "@/components/ui/preskok-ui/date-range-picker"
import { Label } from "@/components/ui/preskok-ui/field"
export function DateRangePickerControlledPreskokDemo() {
const timeZone = getLocalTimeZone()
const [range, setRange] = useState<RangeValue<CalendarDate> | null>(() => ({
start: parseDate("2026-04-08"),
end: parseDate("2026-04-14"),
}))
const selectedRange =
range?.start && range?.end
? `${range.start.toDate(timeZone).toLocaleDateString("en-US", {
day: "numeric",
month: "short",
year: "numeric",
})} - ${range.end.toDate(timeZone).toLocaleDateString("en-US", {
day: "numeric",
month: "short",
year: "numeric",
})}`
: "No range selected"
return (
<div className="max-w-xs space-y-3">
<DateRangePicker
value={range}
onChange={setRange}
visibleDuration={{ months: 2 }}
>
<Label>Event date</Label>
<DateRangePickerTrigger />
</DateRangePicker>
<p className="text-muted-foreground text-sm">Selected: {selectedRange}</p>
</div>
)
}
Disabled
Closed period
5/3/2026
5/7/2026
"use client"
import { parseDate } from "@internationalized/date"
import {
DateRangePicker,
DateRangePickerTrigger,
} from "@/components/ui/preskok-ui/date-range-picker"
import { Label } from "@/components/ui/preskok-ui/field"
export function DateRangePickerDisabledPreskokDemo() {
return (
<div className="max-w-xs">
<DateRangePicker
isDisabled
defaultValue={{
start: parseDate("2026-05-03"),
end: parseDate("2026-05-07"),
}}
>
<Label>Closed period</Label>
<DateRangePickerTrigger />
</DateRangePicker>
</div>
)
}
Validation
"use client"
import { getLocalTimeZone, today } from "@internationalized/date"
import type { DateValue } from "react-aria-components"
import { Button } from "@/components/ui/preskok-ui/button"
import {
DateRangePicker,
DateRangePickerTrigger,
} from "@/components/ui/preskok-ui/date-range-picker"
import { FieldError, Label } from "@/components/ui/preskok-ui/field"
import { Form } from "@/components/ui/preskok-ui/form"
export function DateRangePickerValidationPreskokDemo() {
const timeZone = getLocalTimeZone()
const getDayDifference = (start: DateValue, end: DateValue) => {
const diffMs =
end.toDate(timeZone).getTime() - start.toDate(timeZone).getTime()
return Math.round(diffMs / 86_400_000)
}
return (
<Form onSubmit={(e) => e.preventDefault()} className="max-w-xs">
<DateRangePicker
validate={(range) => {
if (!range?.start || !range?.end) {
return null
}
return getDayDifference(range.start, range.end) > 7
? "Maximum booking duration is 1 week."
: null
}}
defaultValue={{
start: today(timeZone),
end: today(timeZone).add({ weeks: 2 }),
}}
className="mb-2"
>
<Label>Room booking</Label>
<DateRangePickerTrigger />
<FieldError />
</DateRangePicker>
<Button type="submit">Book Room</Button>
</Form>
)
}