Components
Date picker

Date Picker

A component that allows users to select a date from a calendar.

Loading...

You can explore the date-picker component in the following curated examples.

Anatomy

To set up the date picker correctly, you'll need to understand its anatomy and how we name its parts.

Each part includes a data-part attribute to help identify them in the DOM.

Examples

Learn how to use the DatePicker component in your project. Let's take a look at the most basic example

import { DatePicker } from '@ark-ui/react/date-picker'
import { Portal } from '@ark-ui/react/portal'

export const Basic = () => {
  return (
    <DatePicker.Root>
      <DatePicker.Label>Label</DatePicker.Label>
      <DatePicker.Control>
        <DatePicker.Input />
        <DatePicker.Trigger>📅</DatePicker.Trigger>
        <DatePicker.ClearTrigger>Clear</DatePicker.ClearTrigger>
      </DatePicker.Control>
      <Portal>
        <DatePicker.Positioner>
          <DatePicker.Content>
            <DatePicker.YearSelect />
            <DatePicker.MonthSelect />
            <DatePicker.View view="day">
              <DatePicker.Context>
                {(datePicker) => (
                  <>
                    <DatePicker.ViewControl>
                      <DatePicker.PrevTrigger>Prev</DatePicker.PrevTrigger>
                      <DatePicker.ViewTrigger>
                        <DatePicker.RangeText />
                      </DatePicker.ViewTrigger>
                      <DatePicker.NextTrigger>Next</DatePicker.NextTrigger>
                    </DatePicker.ViewControl>
                    <DatePicker.Table>
                      <DatePicker.TableHead>
                        <DatePicker.TableRow>
                          {datePicker.weekDays.map((weekDay, id) => (
                            <DatePicker.TableHeader key={id}>{weekDay.short}</DatePicker.TableHeader>
                          ))}
                        </DatePicker.TableRow>
                      </DatePicker.TableHead>
                      <DatePicker.TableBody>
                        {datePicker.weeks.map((week, id) => (
                          <DatePicker.TableRow key={id}>
                            {week.map((day, id) => (
                              <DatePicker.TableCell key={id} value={day}>
                                <DatePicker.TableCellTrigger>{day.day}</DatePicker.TableCellTrigger>
                              </DatePicker.TableCell>
                            ))}
                          </DatePicker.TableRow>
                        ))}
                      </DatePicker.TableBody>
                    </DatePicker.Table>
                  </>
                )}
              </DatePicker.Context>
            </DatePicker.View>
            <DatePicker.View view="month">
              <DatePicker.Context>
                {(datePicker) => (
                  <>
                    <DatePicker.ViewControl>
                      <DatePicker.PrevTrigger>Prev</DatePicker.PrevTrigger>
                      <DatePicker.ViewTrigger>
                        <DatePicker.RangeText />
                      </DatePicker.ViewTrigger>
                      <DatePicker.NextTrigger>Next</DatePicker.NextTrigger>
                    </DatePicker.ViewControl>
                    <DatePicker.Table>
                      <DatePicker.TableBody>
                        {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => (
                          <DatePicker.TableRow key={id}>
                            {months.map((month, id) => (
                              <DatePicker.TableCell key={id} value={month.value}>
                                <DatePicker.TableCellTrigger>{month.label}</DatePicker.TableCellTrigger>
                              </DatePicker.TableCell>
                            ))}
                          </DatePicker.TableRow>
                        ))}
                      </DatePicker.TableBody>
                    </DatePicker.Table>
                  </>
                )}
              </DatePicker.Context>
            </DatePicker.View>
            <DatePicker.View view="year">
              <DatePicker.Context>
                {(datePicker) => (
                  <>
                    <DatePicker.ViewControl>
                      <DatePicker.PrevTrigger>Prev</DatePicker.PrevTrigger>
                      <DatePicker.ViewTrigger>
                        <DatePicker.RangeText />
                      </DatePicker.ViewTrigger>
                      <DatePicker.NextTrigger>Next</DatePicker.NextTrigger>
                    </DatePicker.ViewControl>
                    <DatePicker.Table>
                      <DatePicker.TableBody>
                        {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => (
                          <DatePicker.TableRow key={id}>
                            {years.map((year, id) => (
                              <DatePicker.TableCell key={id} value={year.value}>
                                <DatePicker.TableCellTrigger>{year.label}</DatePicker.TableCellTrigger>
                              </DatePicker.TableCell>
                            ))}
                          </DatePicker.TableRow>
                        ))}
                      </DatePicker.TableBody>
                    </DatePicker.Table>
                  </>
                )}
              </DatePicker.Context>
            </DatePicker.View>
          </DatePicker.Content>
        </DatePicker.Positioner>
      </Portal>
    </DatePicker.Root>
  )
}

Controlled

Use the value and onValueChange prop to control the date picker's value.

import { DatePicker, parseDate } from '@ark-ui/react/date-picker'
import { Portal } from '@ark-ui/react/portal'
import { useState } from 'react'

export const Controlled = () => {
  const [value, setValue] = useState([parseDate('2022-01-01')])

  return (
    <DatePicker.Root value={value} onValueChange={(e) => setValue(e.value)}>
      <DatePicker.Label>Label</DatePicker.Label>
      <DatePicker.Control>
        <DatePicker.Input />
        <DatePicker.Trigger>📅</DatePicker.Trigger>
        <DatePicker.ClearTrigger>Clear</DatePicker.ClearTrigger>
      </DatePicker.Control>
      <Portal>
        <DatePicker.Positioner>
          <DatePicker.Content>
            <DatePicker.YearSelect />
            <DatePicker.MonthSelect />
            <DatePicker.View view="day">
              <DatePicker.Context>
                {(datePicker) => (
                  <>
                    <DatePicker.ViewControl>
                      <DatePicker.PrevTrigger>Prev</DatePicker.PrevTrigger>
                      <DatePicker.ViewTrigger>
                        <DatePicker.RangeText />
                      </DatePicker.ViewTrigger>
                      <DatePicker.NextTrigger>Next</DatePicker.NextTrigger>
                    </DatePicker.ViewControl>
                    <DatePicker.Table>
                      <DatePicker.TableHead>
                        <DatePicker.TableRow>
                          {datePicker.weekDays.map((weekDay, id) => (
                            <DatePicker.TableHeader key={id}>{weekDay.short}</DatePicker.TableHeader>
                          ))}
                        </DatePicker.TableRow>
                      </DatePicker.TableHead>
                      <DatePicker.TableBody>
                        {datePicker.weeks.map((week, id) => (
                          <DatePicker.TableRow key={id}>
                            {week.map((day, id) => (
                              <DatePicker.TableCell key={id} value={day}>
                                <DatePicker.TableCellTrigger>{day.day}</DatePicker.TableCellTrigger>
                              </DatePicker.TableCell>
                            ))}
                          </DatePicker.TableRow>
                        ))}
                      </DatePicker.TableBody>
                    </DatePicker.Table>
                  </>
                )}
              </DatePicker.Context>
            </DatePicker.View>
            <DatePicker.View view="month">
              <DatePicker.Context>
                {(datePicker) => (
                  <>
                    <DatePicker.ViewControl>
                      <DatePicker.PrevTrigger>Prev</DatePicker.PrevTrigger>
                      <DatePicker.ViewTrigger>
                        <DatePicker.RangeText />
                      </DatePicker.ViewTrigger>
                      <DatePicker.NextTrigger>Next</DatePicker.NextTrigger>
                    </DatePicker.ViewControl>
                    <DatePicker.Table>
                      <DatePicker.TableBody>
                        {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => (
                          <DatePicker.TableRow key={id}>
                            {months.map((month, id) => (
                              <DatePicker.TableCell key={id} value={month.value}>
                                <DatePicker.TableCellTrigger>{month.label}</DatePicker.TableCellTrigger>
                              </DatePicker.TableCell>
                            ))}
                          </DatePicker.TableRow>
                        ))}
                      </DatePicker.TableBody>
                    </DatePicker.Table>
                  </>
                )}
              </DatePicker.Context>
            </DatePicker.View>
            <DatePicker.View view="year">
              <DatePicker.Context>
                {(datePicker) => (
                  <>
                    <DatePicker.ViewControl>
                      <DatePicker.PrevTrigger>Prev</DatePicker.PrevTrigger>
                      <DatePicker.ViewTrigger>
                        <DatePicker.RangeText />
                      </DatePicker.ViewTrigger>
                      <DatePicker.NextTrigger>Next</DatePicker.NextTrigger>
                    </DatePicker.ViewControl>
                    <DatePicker.Table>
                      <DatePicker.TableBody>
                        {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => (
                          <DatePicker.TableRow key={id}>
                            {years.map((year, id) => (
                              <DatePicker.TableCell key={id} value={year.value}>
                                <DatePicker.TableCellTrigger>{year.label}</DatePicker.TableCellTrigger>
                              </DatePicker.TableCell>
                            ))}
                          </DatePicker.TableRow>
                        ))}
                      </DatePicker.TableBody>
                    </DatePicker.Table>
                  </>
                )}
              </DatePicker.Context>
            </DatePicker.View>
          </DatePicker.Content>
        </DatePicker.Positioner>
      </Portal>
    </DatePicker.Root>
  )
}

Range Selection

To create a date picker that allows a range selection, you need to:

  • Set the selectionMode prop to range.
  • Render multiple inputs with the index prop set to 0 and 1.
import { DatePicker } from '@ark-ui/react/date-picker'

export const Range = () => {
  return (
    <DatePicker.Root selectionMode="range">
      <DatePicker.Label>Label</DatePicker.Label>
      <DatePicker.Control>
        <DatePicker.Input index={0} />
        <DatePicker.Input index={1} />
        <DatePicker.Trigger>📅</DatePicker.Trigger>
        <DatePicker.ClearTrigger>Clear</DatePicker.ClearTrigger>
      </DatePicker.Control>
      <DatePicker.PresetTrigger value="last7Days">Last 7 days</DatePicker.PresetTrigger>
      <DatePicker.Positioner>
        <DatePicker.Content>
          <DatePicker.YearSelect />
          <DatePicker.MonthSelect />
          <DatePicker.View view="day">
            <DatePicker.Context>
              {(datePicker) => (
                <>
                  <DatePicker.ViewControl>
                    <DatePicker.PrevTrigger>Prev</DatePicker.PrevTrigger>
                    <DatePicker.ViewTrigger>
                      <DatePicker.RangeText />
                    </DatePicker.ViewTrigger>
                    <DatePicker.NextTrigger>Next</DatePicker.NextTrigger>
                  </DatePicker.ViewControl>
                  <DatePicker.Table>
                    <DatePicker.TableHead>
                      <DatePicker.TableRow>
                        {datePicker.weekDays.map((weekDay, id) => (
                          <DatePicker.TableHeader key={id}>{weekDay.short}</DatePicker.TableHeader>
                        ))}
                      </DatePicker.TableRow>
                    </DatePicker.TableHead>
                    <DatePicker.TableBody>
                      {datePicker.weeks.map((week, id) => (
                        <DatePicker.TableRow key={id}>
                          {week.map((day, id) => (
                            <DatePicker.TableCell key={id} value={day}>
                              <DatePicker.TableCellTrigger>{day.day}</DatePicker.TableCellTrigger>
                            </DatePicker.TableCell>
                          ))}
                        </DatePicker.TableRow>
                      ))}
                    </DatePicker.TableBody>
                  </DatePicker.Table>
                </>
              )}
            </DatePicker.Context>
          </DatePicker.View>
          <DatePicker.View view="month">
            <DatePicker.Context>
              {(datePicker) => (
                <>
                  <DatePicker.ViewControl>
                    <DatePicker.PrevTrigger>Prev</DatePicker.PrevTrigger>
                    <DatePicker.ViewTrigger>
                      <DatePicker.RangeText />
                    </DatePicker.ViewTrigger>
                    <DatePicker.NextTrigger>Next</DatePicker.NextTrigger>
                  </DatePicker.ViewControl>
                  <DatePicker.Table>
                    <DatePicker.TableBody>
                      {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => (
                        <DatePicker.TableRow key={id}>
                          {months.map((month, id) => (
                            <DatePicker.TableCell key={id} value={month.value}>
                              <DatePicker.TableCellTrigger>{month.label}</DatePicker.TableCellTrigger>
                            </DatePicker.TableCell>
                          ))}
                        </DatePicker.TableRow>
                      ))}
                    </DatePicker.TableBody>
                  </DatePicker.Table>
                </>
              )}
            </DatePicker.Context>
          </DatePicker.View>
          <DatePicker.View view="year">
            <DatePicker.Context>
              {(datePicker) => (
                <>
                  <DatePicker.ViewControl>
                    <DatePicker.PrevTrigger>Prev</DatePicker.PrevTrigger>
                    <DatePicker.ViewTrigger>
                      <DatePicker.RangeText />
                    </DatePicker.ViewTrigger>
                    <DatePicker.NextTrigger>Next</DatePicker.NextTrigger>
                  </DatePicker.ViewControl>
                  <DatePicker.Table>
                    <DatePicker.TableBody>
                      {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => (
                        <DatePicker.TableRow key={id}>
                          {years.map((year, id) => (
                            <DatePicker.TableCell key={id} value={year.value}>
                              <DatePicker.TableCellTrigger>{year.label}</DatePicker.TableCellTrigger>
                            </DatePicker.TableCell>
                          ))}
                        </DatePicker.TableRow>
                      ))}
                    </DatePicker.TableBody>
                  </DatePicker.Table>
                </>
              )}
            </DatePicker.Context>
          </DatePicker.View>
        </DatePicker.Content>
      </DatePicker.Positioner>
    </DatePicker.Root>
  )
}

Multiple Months

To create a date picker that allows multiple months, you need to:

  • Set the numOfMonths prop to the number of months you want to display.
  • Use the datePicker.getOffset({ months: 1 }) prop to offset the date picker to the next month.
  • Render a DatePicker.RangeText component to display the range text.
import { DatePicker } from '@ark-ui/react/date-picker'

export const MultipleMonths = () => {
  return (
    <DatePicker.Root numOfMonths={2}>
      <DatePicker.Label>Label</DatePicker.Label>

      <DatePicker.Control>
        <DatePicker.Input index={0} />
        <DatePicker.Trigger>📅</DatePicker.Trigger>
        <DatePicker.ClearTrigger>Clear</DatePicker.ClearTrigger>
      </DatePicker.Control>

      <DatePicker.Positioner>
        <DatePicker.Content>
          <DatePicker.YearSelect />
          <DatePicker.MonthSelect />
          <DatePicker.ViewControl>
            <DatePicker.PrevTrigger>Prev</DatePicker.PrevTrigger>
            <DatePicker.RangeText />
            <DatePicker.NextTrigger>Next</DatePicker.NextTrigger>
          </DatePicker.ViewControl>

          <div style={{ display: 'flex', gap: '10px' }}>
            {/* First month */}
            <DatePicker.Context>
              {(datePicker) => (
                <DatePicker.Table>
                  <DatePicker.TableHead>
                    <DatePicker.TableRow>
                      {datePicker.weekDays.map((weekDay, id) => (
                        <DatePicker.TableHeader key={id}>{weekDay.short}</DatePicker.TableHeader>
                      ))}
                    </DatePicker.TableRow>
                  </DatePicker.TableHead>
                  <DatePicker.TableBody>
                    {datePicker.weeks.map((week, id) => (
                      <DatePicker.TableRow key={id}>
                        {week.map((day, id) => (
                          <DatePicker.TableCell key={id} value={day}>
                            <DatePicker.TableCellTrigger>{day.day}</DatePicker.TableCellTrigger>
                          </DatePicker.TableCell>
                        ))}
                      </DatePicker.TableRow>
                    ))}
                  </DatePicker.TableBody>
                </DatePicker.Table>
              )}
            </DatePicker.Context>

            {/* Second month */}
            <DatePicker.Context>
              {(datePicker) => {
                const offset = datePicker.getOffset({ months: 1 })
                return (
                  <DatePicker.Table>
                    <DatePicker.TableHead>
                      <DatePicker.TableRow>
                        {datePicker.weekDays.map((weekDay, id) => (
                          <DatePicker.TableHeader key={id}>{weekDay.short}</DatePicker.TableHeader>
                        ))}
                      </DatePicker.TableRow>
                    </DatePicker.TableHead>
                    <DatePicker.TableBody>
                      {offset.weeks.map((week, id) => (
                        <DatePicker.TableRow key={id}>
                          {week.map((day, id) => (
                            <DatePicker.TableCell key={id} value={day} visibleRange={offset.visibleRange}>
                              <DatePicker.TableCellTrigger>{day.day}</DatePicker.TableCellTrigger>
                            </DatePicker.TableCell>
                          ))}
                        </DatePicker.TableRow>
                      ))}
                    </DatePicker.TableBody>
                  </DatePicker.Table>
                )
              }}
            </DatePicker.Context>
          </div>
        </DatePicker.Content>
      </DatePicker.Positioner>
    </DatePicker.Root>
  )
}

Inline

In some cases, you might want to display an inline date picker without a popup. This can be achieved by passing the inline prop and avoiding the use of Portal, Positioner and Content components.

Important to note that inline date picker doesn't use the Portal and Positioner components.

import { DatePicker } from '@ark-ui/react/date-picker'

export const Inline = () => {
  return (
    <DatePicker.Root open>
      <DatePicker.Input />
      <DatePicker.View view="day">
        <DatePicker.Context>
          {(datePicker) => (
            <>
              <DatePicker.ViewControl>
                <DatePicker.PrevTrigger>Prev</DatePicker.PrevTrigger>
                <DatePicker.ViewTrigger>
                  <DatePicker.RangeText />
                </DatePicker.ViewTrigger>
                <DatePicker.NextTrigger>Next</DatePicker.NextTrigger>
              </DatePicker.ViewControl>
              <DatePicker.Table>
                <DatePicker.TableHead>
                  <DatePicker.TableRow>
                    {datePicker.weekDays.map((weekDay, id) => (
                      <DatePicker.TableHeader key={id}>{weekDay.short}</DatePicker.TableHeader>
                    ))}
                  </DatePicker.TableRow>
                </DatePicker.TableHead>
                <DatePicker.TableBody>
                  {datePicker.weeks.map((week, id) => (
                    <DatePicker.TableRow key={id}>
                      {week.map((day, id) => (
                        <DatePicker.TableCell key={id} value={day}>
                          <DatePicker.TableCellTrigger>{day.day}</DatePicker.TableCellTrigger>
                        </DatePicker.TableCell>
                      ))}
                    </DatePicker.TableRow>
                  ))}
                </DatePicker.TableBody>
              </DatePicker.Table>
            </>
          )}
        </DatePicker.Context>
      </DatePicker.View>
      <DatePicker.View view="month">
        <DatePicker.Context>
          {(datePicker) => (
            <>
              <DatePicker.ViewControl>
                <DatePicker.PrevTrigger>Prev</DatePicker.PrevTrigger>
                <DatePicker.ViewTrigger>
                  <DatePicker.RangeText />
                </DatePicker.ViewTrigger>
                <DatePicker.NextTrigger>Next</DatePicker.NextTrigger>
              </DatePicker.ViewControl>
              <DatePicker.Table>
                <DatePicker.TableBody>
                  {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => (
                    <DatePicker.TableRow key={id}>
                      {months.map((month, id) => (
                        <DatePicker.TableCell key={id} value={month.value}>
                          <DatePicker.TableCellTrigger>{month.label}</DatePicker.TableCellTrigger>
                        </DatePicker.TableCell>
                      ))}
                    </DatePicker.TableRow>
                  ))}
                </DatePicker.TableBody>
              </DatePicker.Table>
            </>
          )}
        </DatePicker.Context>
      </DatePicker.View>
      <DatePicker.View view="year">
        <DatePicker.Context>
          {(datePicker) => (
            <>
              <DatePicker.ViewControl>
                <DatePicker.PrevTrigger>Prev</DatePicker.PrevTrigger>
                <DatePicker.ViewTrigger>
                  <DatePicker.RangeText />
                </DatePicker.ViewTrigger>
                <DatePicker.NextTrigger>Next</DatePicker.NextTrigger>
              </DatePicker.ViewControl>
              <DatePicker.Table>
                <DatePicker.TableBody>
                  {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => (
                    <DatePicker.TableRow key={id}>
                      {years.map((year, id) => (
                        <DatePicker.TableCell key={id} value={year.value}>
                          <DatePicker.TableCellTrigger>{year.label}</DatePicker.TableCellTrigger>
                        </DatePicker.TableCell>
                      ))}
                    </DatePicker.TableRow>
                  ))}
                </DatePicker.TableBody>
              </DatePicker.Table>
            </>
          )}
        </DatePicker.Context>
      </DatePicker.View>
    </DatePicker.Root>
  )
}

Root Provider

Use the useDatePicker hook to create the date picker store and pass it to the DatePicker.RootProvider component. This allows you to have maximum control over the date picker programmatically.

import { DatePicker, useDatePicker } from '@ark-ui/react/date-picker'
import { Portal } from '@ark-ui/react/portal'

export const RootProvider = () => {
  const datePicker = useDatePicker()

  return (
    <>
      <button onClick={() => datePicker.clearValue()}>Clear</button>

      <DatePicker.RootProvider value={datePicker}>
        <DatePicker.Label>Label</DatePicker.Label>
        <DatePicker.Control>
          <DatePicker.Input />
          <DatePicker.Trigger>📅</DatePicker.Trigger>
          <DatePicker.ClearTrigger>Clear</DatePicker.ClearTrigger>
        </DatePicker.Control>
        <Portal>
          <DatePicker.Positioner>
            <DatePicker.Content>
              <DatePicker.YearSelect />
              <DatePicker.MonthSelect />
              <DatePicker.View view="day">
                <DatePicker.Context>
                  {(datePicker) => (
                    <>
                      <DatePicker.ViewControl>
                        <DatePicker.PrevTrigger>Prev</DatePicker.PrevTrigger>
                        <DatePicker.ViewTrigger>
                          <DatePicker.RangeText />
                        </DatePicker.ViewTrigger>
                        <DatePicker.NextTrigger>Next</DatePicker.NextTrigger>
                      </DatePicker.ViewControl>
                      <DatePicker.Table>
                        <DatePicker.TableHead>
                          <DatePicker.TableRow>
                            {datePicker.weekDays.map((weekDay, id) => (
                              <DatePicker.TableHeader key={id}>{weekDay.short}</DatePicker.TableHeader>
                            ))}
                          </DatePicker.TableRow>
                        </DatePicker.TableHead>
                        <DatePicker.TableBody>
                          {datePicker.weeks.map((week, id) => (
                            <DatePicker.TableRow key={id}>
                              {week.map((day, id) => (
                                <DatePicker.TableCell key={id} value={day}>
                                  <DatePicker.TableCellTrigger>{day.day}</DatePicker.TableCellTrigger>
                                </DatePicker.TableCell>
                              ))}
                            </DatePicker.TableRow>
                          ))}
                        </DatePicker.TableBody>
                      </DatePicker.Table>
                    </>
                  )}
                </DatePicker.Context>
              </DatePicker.View>
              <DatePicker.View view="month">
                <DatePicker.Context>
                  {(datePicker) => (
                    <>
                      <DatePicker.ViewControl>
                        <DatePicker.PrevTrigger>Prev</DatePicker.PrevTrigger>
                        <DatePicker.ViewTrigger>
                          <DatePicker.RangeText />
                        </DatePicker.ViewTrigger>
                        <DatePicker.NextTrigger>Next</DatePicker.NextTrigger>
                      </DatePicker.ViewControl>
                      <DatePicker.Table>
                        <DatePicker.TableBody>
                          {datePicker.getMonthsGrid({ columns: 4, format: 'short' }).map((months, id) => (
                            <DatePicker.TableRow key={id}>
                              {months.map((month, id) => (
                                <DatePicker.TableCell key={id} value={month.value}>
                                  <DatePicker.TableCellTrigger>{month.label}</DatePicker.TableCellTrigger>
                                </DatePicker.TableCell>
                              ))}
                            </DatePicker.TableRow>
                          ))}
                        </DatePicker.TableBody>
                      </DatePicker.Table>
                    </>
                  )}
                </DatePicker.Context>
              </DatePicker.View>
              <DatePicker.View view="year">
                <DatePicker.Context>
                  {(datePicker) => (
                    <>
                      <DatePicker.ViewControl>
                        <DatePicker.PrevTrigger>Prev</DatePicker.PrevTrigger>
                        <DatePicker.ViewTrigger>
                          <DatePicker.RangeText />
                        </DatePicker.ViewTrigger>
                        <DatePicker.NextTrigger>Next</DatePicker.NextTrigger>
                      </DatePicker.ViewControl>
                      <DatePicker.Table>
                        <DatePicker.TableBody>
                          {datePicker.getYearsGrid({ columns: 4 }).map((years, id) => (
                            <DatePicker.TableRow key={id}>
                              {years.map((year, id) => (
                                <DatePicker.TableCell key={id} value={year.value}>
                                  <DatePicker.TableCellTrigger>{year.label}</DatePicker.TableCellTrigger>
                                </DatePicker.TableCell>
                              ))}
                            </DatePicker.TableRow>
                          ))}
                        </DatePicker.TableBody>
                      </DatePicker.Table>
                    </>
                  )}
                </DatePicker.Context>
              </DatePicker.View>
            </DatePicker.Content>
          </DatePicker.Positioner>
        </Portal>
      </DatePicker.RootProvider>
    </>
  )
}

If you're using the DatePicker.RootProvider component, you don't need to use the DatePicker.Root component.

API Reference

Props

Root

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
closeOnSelecttrue
boolean

Whether the calendar should close after the date selection is complete. This is ignored when the selection mode is `multiple`.

defaultFocusedValue
DateValue

The initial focused date when rendered. Use when you don't need to control the focused date of the date picker.

defaultOpen
boolean

The initial open state of the date picker when rendered. Use when you don't need to control the open state of the date picker.

defaultValue
DateValue[]

The initial selected date(s) when rendered. Use when you don't need to control the selected date(s) of the date picker.

defaultView'day'
DateView

The default view of the calendar

disabled
boolean

Whether the calendar is disabled.

fixedWeeks
boolean

Whether the calendar should have a fixed number of weeks. This renders the calendar with 6 weeks instead of 5 or 6.

focusedValue
DateValue

The controlled focused date.

format
(date: DateValue, details: LocaleDetails) => string

The format of the date to display in the input.

id
string

The unique identifier of the machine.

ids
Partial<{ root: string; label: (index: number) => string; table: (id: string) => string; tableHeader: (id: string) => string; tableBody: (id: string) => string; tableRow: (id: string) => string; content: string; ... 10 more ...; positioner: string; }>

The ids of the elements in the date picker. Useful for composition.

immediate
boolean

Whether to synchronize the present change immediately or defer it to the next frame

inline
boolean

Whether to render the date picker inline

isDateUnavailable
(date: DateValue, locale: string) => boolean

Returns whether a date of the calendar is available.

lazyMountfalse
boolean

Whether to enable lazy mounting

locale'en-US'
string

The locale (BCP 47 language tag) to use when formatting the date.

max
DateValue

The maximum date that can be selected.

maxView'year'
DateView

The maximum view of the calendar

min
DateValue

The minimum date that can be selected.

minView'day'
DateView

The minimum view of the calendar

name
string

The `name` attribute of the input element.

numOfMonths
number

The number of months to display.

onExitComplete
VoidFunction

Function called when the animation ends in the closed state

onFocusChange
(details: FocusChangeDetails) => void

Function called when the focused date changes.

onOpenChange
(details: OpenChangeDetails) => void

Function called when the calendar opens or closes.

onValueChange
(details: ValueChangeDetails) => void

Function called when the value changes.

onViewChange
(details: ViewChangeDetails) => void

Function called when the view changes.

open
boolean

The controlled open state of the date picker

outsideDaySelectablefalse
boolean

Whether day outside the visible range can be selected.

parse
(value: string, details: LocaleDetails) => DateValue | undefined

Function to parse the date from the input back to a DateValue.

placeholder
string

The placeholder text to display in the input.

positioning
PositioningOptions

The user provided options used to position the date picker content

present
boolean

Whether the node is present (controlled by the user)

readOnly
boolean

Whether the calendar is read-only.

selectionMode'single'
SelectionMode

The selection mode of the calendar. - `single` - only one date can be selected - `multiple` - multiple dates can be selected - `range` - a range of dates can be selected

skipAnimationOnMountfalse
boolean

Whether to allow the initial presence animation.

startOfWeek
number

The first day of the week. `0` - Sunday `1` - Monday `2` - Tuesday `3` - Wednesday `4` - Thursday `5` - Friday `6` - Saturday

timeZone'UTC'
string

The time zone to use

translations
IntlTranslations

The localized messages to use.

unmountOnExitfalse
boolean

Whether to unmount on exit.

value
DateValue[]

The controlled selected date(s).

view
DateView

The view of the calendar

Data AttributeValue
[data-scope]date-picker
[data-part]root
[data-state]"open" | "closed"
[data-disabled]Present when disabled
[data-readonly]Present when read-only

ClearTrigger

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.

Content

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
CSS VariableDescription
--layer-indexThe index of the dismissable in the layer stack
--nested-layer-countThe number of nested date-pickers
Data AttributeValue
[data-scope]date-picker
[data-part]content
[data-state]"open" | "closed"
[data-nested]popover
[data-has-nested]popover
[data-placement]The placement of the content
[data-inline]Present when the content is inline

Control

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
Data AttributeValue
[data-scope]date-picker
[data-part]control
[data-disabled]Present when disabled

Input

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
fixOnBlurtrue
boolean

Whether to fix the input value on blur.

index
number

The index of the input to focus.

Data AttributeValue
[data-scope]date-picker
[data-part]input
[data-index]The index of the item
[data-state]"open" | "closed"

Label

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
Data AttributeValue
[data-scope]date-picker
[data-part]label
[data-state]"open" | "closed"
[data-index]The index of the item
[data-disabled]Present when disabled
[data-readonly]Present when read-only

MonthSelect

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.

NextTrigger

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
Data AttributeValue
[data-scope]date-picker
[data-part]next-trigger
[data-disabled]Present when disabled

Positioner

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
CSS VariableDescription
--transform-originThe transform origin for animations
--reference-widthThe width of the reference element
--available-widthThe available width in viewport
--available-heightThe available height in viewport
--xThe x position for transform
--yThe y position for transform
--z-indexThe z-index value
--reference-heightThe height of the root

PresetTrigger

PropDefaultType
value
PresetTriggerValue

asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.

PrevTrigger

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
Data AttributeValue
[data-scope]date-picker
[data-part]prev-trigger
[data-disabled]Present when disabled

RangeText

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.

RootProvider

PropDefaultType
value
UseDatePickerReturn

asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
immediate
boolean

Whether to synchronize the present change immediately or defer it to the next frame

lazyMountfalse
boolean

Whether to enable lazy mounting

onExitComplete
VoidFunction

Function called when the animation ends in the closed state

present
boolean

Whether the node is present (controlled by the user)

skipAnimationOnMountfalse
boolean

Whether to allow the initial presence animation.

unmountOnExitfalse
boolean

Whether to unmount on exit.

TableBody

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
Data AttributeValue
[data-scope]date-picker
[data-part]table-body
[data-view]The view of the tablebody
[data-disabled]Present when disabled

TableCell

PropDefaultType
value
number | DateValue

asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
columns
number

disabled
boolean

visibleRange
VisibleRange

TableCellTrigger

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.

TableHead

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
Data AttributeValue
[data-scope]date-picker
[data-part]table-head
[data-view]The view of the tablehead
[data-disabled]Present when disabled

TableHeader

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
Data AttributeValue
[data-scope]date-picker
[data-part]table-header
[data-view]The view of the tableheader
[data-disabled]Present when disabled

Table

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
columns
number

Data AttributeValue
[data-scope]date-picker
[data-part]table
[data-columns]
[data-view]The view of the table

TableRow

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
Data AttributeValue
[data-scope]date-picker
[data-part]table-row
[data-disabled]Present when disabled
[data-view]The view of the tablerow

Trigger

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
Data AttributeValue
[data-scope]date-picker
[data-part]trigger
[data-placement]The placement of the trigger
[data-state]"open" | "closed"

ViewControl

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
Data AttributeValue
[data-scope]date-picker
[data-part]view-control
[data-view]The view of the viewcontrol

View

PropDefaultType
view
DateView

asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
Data AttributeValue
[data-scope]date-picker
[data-part]view
[data-view]The view of the view

ViewTrigger

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
Data AttributeValue
[data-scope]date-picker
[data-part]view-trigger
[data-view]The view of the viewtrigger

YearSelect

PropDefaultType
asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.

Context

These are the properties available when using UdateUpicker.Context, useUdateUpickerContext hook or useUdateUpicker hook.

API

PropertyType
focused
boolean

Whether the input is focused

open
boolean

Whether the date picker is open

inline
boolean

Whether the date picker is rendered inline

view
DateView

The current view of the date picker

getDaysInWeek
(week: number, from?: DateValue) => DateValue[]

Returns an array of days in the week index counted from the provided start date, or the first visible date if not given.

getOffset
(duration: DateDuration) => DateValueOffset

Returns the offset of the month based on the provided number of months.

getRangePresetValue
(value: DateRangePreset) => DateValue[]

Returns the range of dates based on the provided date range preset.

getMonthWeeks
(from?: DateValue) => DateValue[][]

Returns the weeks of the month from the provided date. Represented as an array of arrays of dates.

isUnavailable
(date: DateValue) => boolean

Returns whether the provided date is available (or can be selected)

weeks
DateValue[][]

The weeks of the month. Represented as an array of arrays of dates.

weekDays
WeekDay[]

The days of the week. Represented as an array of strings.

visibleRange
VisibleRange

The visible range of dates.

visibleRangeText
VisibleRangeText

The human readable text for the visible range of dates.

value
DateValue[]

The selected date.

valueAsDate
Date[]

The selected date as a Date object.

valueAsString
string[]

The selected date as a string.

focusedValue
DateValue

The focused date.

focusedValueAsDate
Date

The focused date as a Date object.

focusedValueAsString
string

The focused date as a string.

selectToday
VoidFunction

Sets the selected date to today.

setValue
(values: DateValue[]) => void

Sets the selected date to the given date.

setFocusedValue
(value: DateValue) => void

Sets the focused date to the given date.

clearValue
VoidFunction

Clears the selected date(s).

setOpen
(open: boolean) => void

Function to open or close the calendar.

focusMonth
(month: number) => void

Function to set the selected month.

focusYear
(year: number) => void

Function to set the selected year.

getYears
() => Cell[]

Returns the months of the year

getYearsGrid
(props?: YearGridProps) => YearGridValue

Returns the years of the decade based on the columns. Represented as an array of arrays of years.

getDecade
() => Range<number>

Returns the start and end years of the decade.

getMonths
(props?: MonthFormatOptions) => Cell[]

Returns the months of the year

getMonthsGrid
(props?: MonthGridProps) => MonthGridValue

Returns the months of the year based on the columns. Represented as an array of arrays of months.

format
(value: DateValue, opts?: Intl.DateTimeFormatOptions) => string

Formats the given date value based on the provided options.

setView
(view: DateView) => void

Sets the view of the date picker.

goToNext
VoidFunction

Goes to the next month/year/decade.

goToPrev
VoidFunction

Goes to the previous month/year/decade.

getDayTableCellState
(props: DayTableCellProps) => DayTableCellState

Returns the state details for a given cell.

getMonthTableCellState
(props: TableCellProps) => TableCellState

Returns the state details for a given month cell.

getYearTableCellState
(props: TableCellProps) => TableCellState

Returns the state details for a given year cell.

Accessibility

Keyboard Support

KeyDescription
ArrowLeft
Moves focus to the previous day within the current week.
ArrowRight
Moves focus to the next day within the current week.
ArrowUp
Moves focus to the same day of the week in the previous week.
ArrowDown
Moves focus to the same day of the week in the next week.
Home
Moves focus to the first day of the current month.
End
Moves focus to the last day of the current month.
PageUp
Moves focus to the same day of the month in the previous month.
PageDown
Moves focus to the same day of the month in the next month.
Enter
Selects the focused date and closes the date picker.
Esc
Closes the date picker without selecting any date.