DatePicker
A segmented date field with a calendar popover, built on React Aria. Users can type the date or pick it from the grid; both write to the same value.
import { CalendarDate } from "@internationalized/date"
import { Calendar, DatePicker } from "@pockets-ui/components"Anatomy
| Part | Role |
|---|---|
DatePicker.Root | Owns the value and bounds. |
DatePicker.Label | The field's visible label. |
DatePicker.Control | Wraps the input and the popover trigger. |
DatePicker.Input | The segmented date input. |
DatePicker.Trigger | The button that opens the calendar. |
DatePicker.Content | The popover. Put a Calendar inside. |
The calendar isn't built in — you compose one into DatePicker.Content, and it
inherits the picker's value and bounds through context, so it needs no props of
its own.
Basic
Event date
mmddyyyy
Code
import { Calendar, DatePicker } from "@pockets-ui/components"
export default function DatePickerBasic() {
return (
<DatePicker.Root>
<DatePicker.Label>Event date</DatePicker.Label>
<DatePicker.Control>
<DatePicker.Input />
<DatePicker.Trigger />
</DatePicker.Control>
<DatePicker.Content>
<Calendar.Root>
<Calendar.ActionRow>
<Calendar.ActionButton slot="previous">‹</Calendar.ActionButton>
<Calendar.Heading />
<Calendar.ActionButton slot="next">›</Calendar.ActionButton>
</Calendar.ActionRow>
<Calendar.Grid>
<Calendar.Header>
{(day) => <Calendar.HeaderCell>{day}</Calendar.HeaderCell>}
</Calendar.Header>
<Calendar.Body>
{(date) => <Calendar.Cell date={date} />}
</Calendar.Body>
</Calendar.Grid>
</Calendar.Root>
</DatePicker.Content>
</DatePicker.Root>
)
}Default value
Launch day
7192026
Code
import { CalendarDate } from "@internationalized/date"
import { DatePicker } from "@pockets-ui/components"
import { PickerCalendar } from "./shared"
export default function DatePickerDefaultValue() {
return (
<DatePicker.Root defaultValue={new CalendarDate(2026, 7, 19)}>
<DatePicker.Label>Launch day</DatePicker.Label>
<DatePicker.Control>
<DatePicker.Input />
<DatePicker.Trigger />
</DatePicker.Control>
<DatePicker.Content>
<PickerCalendar />
</DatePicker.Content>
</DatePicker.Root>
)
}Min / max range
Bounds set on the root apply to both halves at once: the calendar greys out the excluded days and the segmented input refuses to type past them.
Appointment (next month only)
mmddyyyy
Code
import { getLocalTimeZone, today } from "@internationalized/date"
import { DatePicker } from "@pockets-ui/components"
import { PickerCalendar } from "./shared"
export default function DatePickerMinMax() {
return (
<DatePicker.Root
minValue={today(getLocalTimeZone())}
maxValue={today(getLocalTimeZone()).add({ months: 1 })}
>
<DatePicker.Label>Appointment (next month only)</DatePicker.Label>
<DatePicker.Control>
<DatePicker.Input />
<DatePicker.Trigger />
</DatePicker.Control>
<DatePicker.Content>
<PickerCalendar />
</DatePicker.Content>
</DatePicker.Root>
)
}Disabled
Frozen date
7192026
Code
import { CalendarDate } from "@internationalized/date"
import { DatePicker } from "@pockets-ui/components"
import { PickerCalendar } from "./shared"
export default function DatePickerDisabled() {
return (
<DatePicker.Root isDisabled defaultValue={new CalendarDate(2026, 7, 19)}>
<DatePicker.Label>Frozen date</DatePicker.Label>
<DatePicker.Control>
<DatePicker.Input />
<DatePicker.Trigger />
</DatePicker.Control>
<DatePicker.Content>
<PickerCalendar />
</DatePicker.Content>
</DatePicker.Root>
)
}