Date Picker

Date Picker allows users to select a date from a calendar popover.

Source
Theme Source
pnpm dlx dreamy add date-picker

Date Picker provides a calendar interface for selecting dates. It can be used with either an input field or a button trigger.

The most common usage is with an input field that displays the selected date.

<DatePicker.Root>
    <DatePicker.Input />
    <DatePicker.PopoverContent>
        <DatePicker.Header />
        <DatePicker.Control />
        <DatePicker.Nav />
        <DatePicker.Calendar />
        <DatePicker.Footer />
    </DatePicker.PopoverContent>
</DatePicker.Root>

You can also use a button as the trigger instead of an input field.

<DatePicker.Root>
    <DatePicker.Trigger>Select Date</DatePicker.Trigger>
    <DatePicker.PopoverContent>
        <DatePicker.Header />
        <DatePicker.Control />
        <DatePicker.Calendar />
        <DatePicker.Footer />
    </DatePicker.PopoverContent>
</DatePicker.Root>

Add DatePicker.Nav below the Control to let users switch between Day, Month, and Year views. The default view is Day (the standard calendar grid). Month view shows a 3-column month grid. Year view shows a scrollable 3-column year grid from the current year +10 down to 1919, with custom year inputs at the top (for future years) and bottom (for years before 1919).

<DatePicker.Root>
    <DatePicker.Input />
    <DatePicker.PopoverContent>
        <DatePicker.Header />
        <DatePicker.Control />
        <DatePicker.Nav />
        <DatePicker.Calendar />
    </DatePicker.PopoverContent>
</DatePicker.Root>

You can control the date picker's value using the value and onChange props.

function ControlledDatePicker() {
    const [date, setDate] = useState<Date | null>(null);
 
    return (
        <DatePicker.Root
            value={date}
            onChange={setDate}
        >
            <DatePicker.Input />
            <DatePicker.PopoverContent>
                <DatePicker.Header />
                <DatePicker.Control />
                <DatePicker.Calendar />
                <DatePicker.Footer />
            </DatePicker.PopoverContent>
        </DatePicker.Root>
    );
}

Set an initial date using the defaultValue prop.

<DatePicker.Root defaultValue={new Date()}>
    <DatePicker.Input />
    <DatePicker.PopoverContent>
        <DatePicker.Header />
        <DatePicker.Control />
        <DatePicker.Calendar />
        <DatePicker.Footer />
    </DatePicker.PopoverContent>
</DatePicker.Root>

Use minDate and maxDate to restrict selectable dates.

<DatePicker.Root
    minDate={new Date(2024, 0, 1)}
    maxDate={new Date(2024, 11, 31)}
>
    <DatePicker.Input />
    <DatePicker.PopoverContent>
        <DatePicker.Header />
        <DatePicker.Control />
        <DatePicker.Calendar />
        <DatePicker.Footer />
    </DatePicker.PopoverContent>
</DatePicker.Root>

By default, Date Picker starts the week on Monday (weekStartsOn={1}).
Use weekStartsOn to change the first day of the week (0 = Sunday, 1 = Monday, ... 6 = Saturday).

<DatePicker.Root>
    <DatePicker.Input />
    <DatePicker.PopoverContent>
        <DatePicker.Header />
        <DatePicker.Control />
        <DatePicker.Calendar />
        <DatePicker.Footer />
    </DatePicker.PopoverContent>
</DatePicker.Root>
 
<DatePicker.Root weekStartsOn={0}>
    <DatePicker.Input />
    <DatePicker.PopoverContent>
        <DatePicker.Header />
        <DatePicker.Control />
        <DatePicker.Calendar />
        <DatePicker.Footer />
    </DatePicker.PopoverContent>
</DatePicker.Root>

Customize the date format displayed in the input using the dateFormat prop. The format uses dayjs format strings.

<DatePicker.Root dateFormat="DD/MM/YYYY">
    <DatePicker.Input />
    <DatePicker.PopoverContent>
        <DatePicker.Header />
        <DatePicker.Calendar />
        <DatePicker.Footer />
    </DatePicker.PopoverContent>
</DatePicker.Root>

Set a custom placeholder text for the input field.

<DatePicker.Root placeholder="Choose your date">
    <DatePicker.Input />
    <DatePicker.PopoverContent>
        <DatePicker.Header />
        <DatePicker.Control />
        <DatePicker.Calendar />
        <DatePicker.Footer />
    </DatePicker.PopoverContent>
</DatePicker.Root>

Pass props to DatePicker.Header and DatePicker.Footer child parts to customize labels, variants, and styles while keeping the default structure.

<DatePicker.Root>
    <DatePicker.Input />
    <DatePicker.PopoverContent>
        <DatePicker.Header
            previousButtonProps={{ "aria-label": "Go to previous month", variant: "outline" }}
            nextButtonProps={{ "aria-label": "Go to next month", variant: "outline" }}
            titleProps={{ fontWeight: "semibold", color: "fg.default" }}
        />
        <DatePicker.Control />
        <DatePicker.Calendar />
        <DatePicker.Footer
            cancelButtonProps={{ children: "Dismiss", variant: "ghost" }}
            submitButtonProps={{ children: "Confirm Date", variant: "primary" }}
        />
    </DatePicker.PopoverContent>
</DatePicker.Root>

Use DatePicker.AIO when you want the full date picker structure in one component. It renders Input, PopoverContent, Header, Calendar, and Footer for you.

function DatePickerAIOExample() {
    const [date, setDate] = useState<Date | null>(null);
 
    function handleApply() {
        console.log("Date applied:", date);
    }
 
    function handleCancel() {
        console.log("Date selection cancelled");
    }
 
    return (
        <DatePicker.AIO
            value={date}
            onChange={setDate}
            onApply={handleApply}
            onCancel={handleCancel}
            footerProps={{
                cancelButtonProps: { children: "Cancel" },
                submitButtonProps: { children: "Apply" }
            }}
        />
    );
}

Date Picker comes in three sizes: sm, md, and lg.

<VStack gap={8} w="full">
    <DatePicker.Root size="sm">
        <DatePicker.Input />
        <DatePicker.PopoverContent>
            <DatePicker.Header />
            <DatePicker.Control />
            <DatePicker.Calendar />
            <DatePicker.Footer />
        </DatePicker.PopoverContent>
    </DatePicker.Root>
 
    <DatePicker.Root size="md">
        <DatePicker.Input />
        <DatePicker.PopoverContent>
            <DatePicker.Header />
            <DatePicker.Control />
            <DatePicker.Calendar />
            <DatePicker.Footer />
        </DatePicker.PopoverContent>
    </DatePicker.Root>
 
    <DatePicker.Root size="lg">
        <DatePicker.Input />
        <DatePicker.PopoverContent>
            <DatePicker.Header />
            <DatePicker.Control />
            <DatePicker.Calendar />
            <DatePicker.Footer />
        </DatePicker.PopoverContent>
    </DatePicker.Root>
</VStack>