# DatePicker **Category**: react **URL**: https://www.heroui.com/docs/react/components/date-picker **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/components/(date-and-time)/date-picker.mdx > Composable date picker built on React Aria DatePicker with DateField and Calendar composition *** ## Import ```tsx import { DatePicker, DateField, Calendar, Label } from '@heroui/react'; ``` ### Usage ```tsx "use client"; import {Calendar, DateField, DatePicker, Label} from "@heroui/react"; export function Basic() { return ( {(segment) => } {(day) => {day}} {(date) => } {({year}) => } ); } ``` ### Anatomy `DatePicker` follows a composition-first API. Compose `DateField` and `Calendar` explicitly to control structure and styling. ```tsx import {Calendar, DateField, DatePicker, Label} from '@heroui/react'; export default () => ( ) ``` ### Controlled ```tsx "use client"; import type {DateValue} from "@internationalized/date"; import {Button, Calendar, DateField, DatePicker, Description, Label} from "@heroui/react"; import {getLocalTimeZone, today} from "@internationalized/date"; import {useState} from "react"; export function Controlled() { const [value, setValue] = useState(today(getLocalTimeZone())); return (
{(segment) => } {(day) => {day}} {(date) => } {({year}) => } Current value: {value ? value.toString() : "(empty)"}
); } ``` ### Validation ```tsx "use client"; import type {DateValue} from "@internationalized/date"; import {Calendar, DateField, DatePicker, FieldError, Label} from "@heroui/react"; import {getLocalTimeZone, today} from "@internationalized/date"; import {useState} from "react"; export function WithValidation() { const [value, setValue] = useState(null); const currentDate = today(getLocalTimeZone()); const isInvalid = value != null && value.compare(currentDate) < 0; return ( {(segment) => } Date must be today or in the future. {(day) => {day}} {(date) => } {({year}) => } ); } ``` ### Format Options Control how DatePicker values are displayed with props such as `granularity`, `hourCycle`, `hideTimeZone`, and `shouldForceLeadingZeros`. ```tsx "use client"; import type {TimeValue} from "@heroui/react"; import type {DateValue} from "@internationalized/date"; import { Calendar, DateField, DatePicker, Label, ListBox, Select, Switch, TimeField, } from "@heroui/react"; import {getLocalTimeZone, parseDate, parseZonedDateTime} from "@internationalized/date"; import {useMemo, useState} from "react"; type Granularity = "day" | "hour" | "minute" | "second"; type HourCycle = 12 | 24; const granularityOptions: {label: string; value: Granularity}[] = [ {label: "Day", value: "day"}, {label: "Hour", value: "hour"}, {label: "Minute", value: "minute"}, {label: "Second", value: "second"}, ]; const hourCycleOptions: {label: string; value: HourCycle}[] = [ {label: "12-hour", value: 12}, {label: "24-hour", value: 24}, ]; export function FormatOptions() { const [granularity, setGranularity] = useState("minute"); const [hourCycle, setHourCycle] = useState(12); const [hideTimeZone, setHideTimeZone] = useState(false); const [shouldForceLeadingZeros, setShouldForceLeadingZeros] = useState(false); const timeGranularity = granularity !== "day" ? granularity : undefined; const showTimeField = !!timeGranularity; const defaultValue = useMemo(() => { const localTimeZone = getLocalTimeZone(); if (granularity === "day") { return parseDate("2026-02-03"); } return parseZonedDateTime(`2026-02-03T08:45:00[${localTimeZone}]`); }, [granularity]); return (
{({state}) => ( <> {(segment) => } {(day) => {day}} {(date) => } {({year}) => } {!!showTimeField && (
state.setTimeValue(v as TimeValue)} > {(segment) => }
)}
)}
); } ``` ### Disabled ```tsx "use client"; import {Calendar, DateField, DatePicker, Description, Label} from "@heroui/react"; import {getLocalTimeZone, today} from "@internationalized/date"; export function Disabled() { return ( {(segment) => } This date picker is disabled. {(day) => {day}} {(date) => } {({year}) => } ); } ``` ### Custom Indicator `DatePicker.TriggerIndicator` renders the default `IconCalendar` when no children are provided. Pass children to replace it. ```tsx "use client"; import {Calendar, DateField, DatePicker, Description, Label} from "@heroui/react"; import {Icon} from "@iconify/react"; export function WithCustomIndicator() { return ( {(segment) => } Replace the default calendar icon by passing custom children. {(day) => {day}} {(date) => } {({year}) => } ); } ``` ### Form Example ```tsx "use client"; import type {DateValue} from "@internationalized/date"; import { Button, Calendar, DateField, DatePicker, Description, FieldError, Form, Label, } from "@heroui/react"; import {getLocalTimeZone, today} from "@internationalized/date"; import {useState} from "react"; export function FormExample() { const [value, setValue] = useState(null); const [isSubmitting, setIsSubmitting] = useState(false); const currentDate = today(getLocalTimeZone()); const isInvalid = value != null && value.compare(currentDate) < 0; const handleSubmit = (event: React.FormEvent) => { event.preventDefault(); if (!value || isInvalid) { return; } setIsSubmitting(true); setTimeout(() => { setValue(null); setIsSubmitting(false); }, 1200); }; return (
{(segment) => } {isInvalid ? ( Date must be today or in the future. ) : ( Choose a valid appointment date. )} {(day) => {day}} {(date) => } {({year}) => }
); } ``` ### International Calendar By default, DatePicker displays dates using the calendar system for the user's locale. You can override this by wrapping your DatePicker with `I18nProvider` and setting the [Unicode calendar locale extension](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale/calendar#adding_a_calendar_in_the_locale_string). The example below shows the Indian calendar system: ```tsx "use client"; import {Calendar, DateField, DatePicker, Label} from "@heroui/react"; import {getLocalTimeZone, today} from "@internationalized/date"; import {I18nProvider} from "react-aria-components"; export function InternationalCalendar() { return ( {(segment) => } {(day) => {day}} {(date) => } {({year}) => } ); } ``` **Note:** The `onChange` event always returns a date in the same calendar system as the `value` or `defaultValue` (Gregorian if no value is provided), regardless of the displayed locale. This ensures your application logic works consistently with a single calendar system while still displaying dates in the user's preferred format. For a complete list of supported calendar systems and their identifiers, see: - [React Aria Calendar Implementations](https://react-aria.adobe.com/internationalized/date/Calendar#implementations) - [React Aria International Calendars](https://react-aria.adobe.com/Calendar#international-calendars) ### Custom Render Function ```tsx "use client"; import {Calendar, DateField, DatePicker, Label} from "@heroui/react"; export function CustomRenderFunction() { return (
} >
} >
}> {(segment) => ( } segment={segment} /> )}