- Alert
- Avatar
- Badge
- Breadcrumb
- Button
- Button Group
- Calendar
- Card
- Carousel
- Chart
- Checkbox
- Checkbox Group
- ComboBox
- Command
- Data Table
- Date Field
- Date Picker
- Date Range Picker
- Dialog
- Disclosure
- Disclosure Group
- Drawer
- Empty
- Field
- File Trigger
- Form
- Grid List
- Hover Card
- Input
- Input Group
- Input OTP
- Item
- Kbd
- Label
- ListBox
- Menu
- Number Field
- Pagination
- Popover
- Progress Bar
- Radio Group
- Range Calendar
- Resizable
- Search Field
- Select
- Separator
- Sheet
- Sidebar
- Skeleton
- Slider
- Sonner
- Spinner
- Switch
- Table
- Tabs
- Tag Group
- Text Field
- Textarea
- Time Field
- Toast
- Toggle Button
- Toggle Button Group
- Tooltip
- Tree
- Typography
A date picker combines a date field with a calendar popover to allow users to enter or select a date value.
import { DatePicker } from "@/components/ui/date-picker"
export function DatePickerDemo() {
return (
<DatePicker
label="Event date"
description="Select a date for your event."
/>
)
}
Installation
pnpmnpmyarnbunpnpm dlx shadcn@latest add date-picker
Usage
import { DatePicker } from "@/components/ui/date-picker"<DatePicker
label="Event date"
description="Select a date for your event."
/>About
The DatePicker component is built on top of React Aria Components and combines a Date Field with a Calendar in a popover. It allows users to either type a date or select it from a calendar.
Examples
Default
import { DatePicker } from "@/components/ui/date-picker"
export function DatePickerDemo() {
return (
<DatePicker
label="Event date"
description="Select a date for your event."
/>
)
}
<DatePicker
label="Event date"
description="Select a date for your event."
/>Disabled
import { DatePicker } from "@/components/ui/date-picker"
export function DatePickerDisabled() {
return (
<DatePicker
label="Event date"
description="This field is disabled."
isDisabled
/>
)
}
<DatePicker
label="Event date"
description="This field is disabled."
isDisabled
/>Validation
"use client"
import { DatePicker } from "@/components/ui/date-picker"
export function DatePickerValidation() {
return (
<DatePicker
label="Appointment date"
description="Please select a date for your appointment."
isRequired
errorMessage="Please select a valid date."
/>
)
}
<DatePicker
label="Appointment date"
description="Please select a date for your appointment."
isRequired
errorMessage="Please select a valid date."
/>Controlled
Selected date: 2024-12-25
"use client"
import { useState } from "react"
import { parseDate } from "@internationalized/date"
import { DatePicker } from "@/components/ui/date-picker"
export function DatePickerControlled() {
const [value, setValue] = useState(parseDate("2024-12-25"))
return (
<div className="space-y-4">
<DatePicker
label="Travel date"
description="Select your travel date."
value={value}
onChange={setValue}
/>
<p className="text-muted-foreground text-sm">
Selected date: {value ? value.toString() : "None"}
</p>
</div>
)
}
"use client"
import { useState } from "react"
import { parseDate } from "@internationalized/date"
import { DatePicker } from "@/components/ui/date-picker"
export default function DatePickerControlled() {
const [value, setValue] = useState(parseDate("2024-12-25"))
return (
<div className="space-y-4">
<DatePicker
label="Travel date"
description="Select your travel date."
value={value}
onChange={setValue}
/>
<p className="text-muted-foreground text-sm">
Selected date: {value ? value.toString() : "None"}
</p>
</div>
)
}Min and Max Values
"use client"
import { getLocalTimeZone, today } from "@internationalized/date"
import { DatePicker } from "@/components/ui/date-picker"
export function DatePickerMinMax() {
const now = today(getLocalTimeZone())
return (
<DatePicker
label="Booking date"
description="Select a date within the next 30 days."
minValue={now}
maxValue={now.add({ days: 30 })}
/>
)
}
"use client"
import { getLocalTimeZone, today } from "@internationalized/date"
import { DatePicker } from "@/components/ui/date-picker"
export default function DatePickerMinMax() {
const now = today(getLocalTimeZone())
return (
<DatePicker
label="Booking date"
description="Select a date within the next 30 days."
minValue={now}
maxValue={now.add({ days: 30 })}
/>
)
}Granularity
import { DatePicker } from "@/components/ui/date-picker"
export function DatePickerGranularity() {
return (
<div className="space-y-4">
<DatePicker
label="Date only"
description="Year, month, and day."
granularity="day"
/>
<DatePicker
label="Month and year"
description="Month and year only."
granularity="month"
/>
</div>
)
}
<div className="space-y-4">
<DatePicker
label="Date only"
description="Year, month, and day."
granularity="day"
/>
<DatePicker
label="Month and year"
description="Month and year only."
granularity="month"
/>
</div>Unavailable Dates
"use client"
import { DateValue, getLocalTimeZone, today } from "@internationalized/date"
import { DatePicker } from "@/components/ui/date-picker"
export function DatePickerUnavailableDates() {
const now = today(getLocalTimeZone())
const isDateUnavailable = (date: DateValue) => {
const day = date.toDate(getLocalTimeZone()).getDay()
return day === 0 || day === 6 // Disable weekends
}
return (
<DatePicker
label="Meeting date"
description="Weekends are unavailable."
minValue={now}
isDateUnavailable={isDateUnavailable}
/>
)
}
"use client"
import { DateValue, getLocalTimeZone, today } from "@internationalized/date"
import { DatePicker } from "@/components/ui/date-picker"
export default function DatePickerUnavailableDates() {
const now = today(getLocalTimeZone())
const isDateUnavailable = (date: DateValue) => {
const day = date.toDate(getLocalTimeZone()).getDay()
return day === 0 || day === 6 // Disable weekends
}
return (
<DatePicker
label="Meeting date"
description="Weekends are unavailable."
minValue={now}
isDateUnavailable={isDateUnavailable}
/>
)
}API Reference
DatePicker
| Prop | Type | Default | Description |
|---|---|---|---|
label | string | - | Label text for the date picker |
description | string | - | Help text displayed below the input |
errorMessage | string | ((validation: ValidationResult) => string) | - | Error message for validation |
value | DateValue | - | The current value (controlled) |
defaultValue | DateValue | - | The default value (uncontrolled) |
onChange | (value: DateValue) => void | - | Handler called when the value changes |
minValue | DateValue | - | The minimum allowed date |
maxValue | DateValue | - | The maximum allowed date |
isDateUnavailable | (date: DateValue) => boolean | - | Function to determine if a date is unavailable |
granularity | "day" | "hour" | "minute" | "second" | "day" | Determines the smallest unit editable |
isDisabled | boolean | false | Whether the date picker is disabled |
isReadOnly | boolean | false | Whether the date picker is read-only |
isRequired | boolean | false | Whether the date picker is required |
placeholderValue | DateValue | - | A placeholder date that controls the default values |
See the React Aria DatePicker documentation for more props and detailed information.
Internationalization
The DatePicker component automatically formats dates based on the user's locale. The @internationalized/date library handles calendar systems and localization.
import { parseDate } from "@internationalized/date"
// ISO 8601 format
const date = parseDate("2024-12-25")Calendar Systems
The date picker supports multiple calendar systems through the @internationalized/date library:
- Gregorian
- Buddhist
- Hebrew
- Indian
- Islamic (Hijri)
- Japanese
- Persian
- Taiwan
See the @internationalized/date documentation for more information.
Keyboard Navigation
The date picker supports full keyboard navigation:
- Tab: Move focus between the field segments and the calendar button
- Arrow Keys: Navigate between segments in the field, or dates in the calendar
- Enter/Space: Open/close the calendar popover, or select a date
- Escape: Close the calendar popover
- Page Up/Down: Navigate months in the calendar
- Home/End: Go to the first/last day of the week in the calendar
Related Components
- Date Field - For keyboard-only date entry
- Calendar - For visual date selection
- Field - For composing accessible form fields