Date Picker

A field that opens a calendar to pick one date, or a range of dates.

Pick a date.

import * as React from "react"

import { DatePicker } from "@hel/ui/date-picker"

When to use it

Use a date picker when a form asks for a date and people should be able to see the month while they choose: a due date, a delivery date, a report period. It looks like a text field, so it sits well next to the other inputs in a form, and it opens the Calendar in a popover.

The date is written with Intl, in the language and digits of the locale, so each person reads it the way they are used to. If the calendar should always be on the page, use Calendar itself.

Import

import { DatePicker, DateRangePicker } from "@hel/ui/date-picker"

DatePicker picks one date. DateRangePicker picks a start and an end. They share most props.

Values

The value of a DatePicker is a Date, or null when nothing is chosen. A DateRangePicker has a { from, to } object, or null. Use value and onValueChange to control it, or defaultValue to give it a starting date and let it manage the rest. Clicking the chosen date again clears it, unless you set required on a DatePicker.

Give every picker a name: put it inside a Field and point aria-labelledby at the label's id, or use aria-label.

Examples

Keeping choices valid

min and max bound the choice. disabledDates takes anything the calendar's disabled prop takes: a date, a range, weekdays or a function, and a list of them. Say why days are unavailable in the helper text, since greyed out dates don't explain themselves.

Within the next 30 days. We don't deliver on Fridays or Saturdays.

import { DatePicker } from "@hel/ui/date-picker"
import { Field, FieldHelperText, FieldLabel } from "@hel/ui/field"

A range with shortcuts

The first click sets the start and the second sets the end. It shows two months, which you can change with numberOfMonths. presets adds shortcuts beside the calendar. A preset's range can be a function, so "Last 7 days" is worked out when it is pressed, not when the page loaded.

Choose the period for the report.

import * as React from "react"

import { DateRangePicker, type DateRange } from "@hel/ui/date-picker"

Date and time

Ask for a moment by putting a date picker next to a time picker. The value of the time picker is a 24-hour string like "09:30", whether or not the locale shows a 12-hour clock.

import { DatePicker } from "@hel/ui/date-picker"
import { Flex } from "@hel/ui/flex"
import { TimePicker } from "@hel/ui/time-picker"

How it is written

formatOptions takes Intl.DateTimeFormat options and defaults to { dateStyle: "medium" }. Use { dateStyle: "full" } for a long form with the weekday. placeholder is what shows before a choice, and by default it is a prompt in the locale's language.

Languages

Everything follows the locale: the written date, the month names, the digits, the first day of the week, and the labels read by screen readers. English and Arabic text is built in. For another language, reword the prompts with messages, or add them for the whole app under messages in your Hel config. numberingSystem picks the digits on its own, for example "latn" for 0 to 9 in an Arabic page.

<DatePicker
  locale="fr-FR"
  formatOptions={{ dateStyle: "long" }}
  messages={{ pickDate: "Choisir une date" }}
/>

In a form

Give a picker a name and it carries its value in hidden inputs as yyyy-mm-dd, so a plain form submits it. A range sends the start and the end under name-from and name-to.

Any Calendar prop can go through calendarProps, for example { captionLayout: "dropdown" } for month and year pickers, or { showWeekNumber: true }.

Props

DatePicker

PropTypeDefault
value / defaultValueDate or nullnone
onValueChange(value: Date | null) => voidnone
min / maxDatenone
disabledDatesA matcher, or a list of themnone
closeOnSelectbooleantrue
requiredbooleanfalse
formatOptionsIntl.DateTimeFormatOptions{ dateStyle: "medium" }
placeholderstringa prompt in the locale
locale / numberingSystemstringthe app's locale
messagesPartial<DateMessages>built in
namestringnone
disabled / invalidbooleanfalse
open / onOpenChangeboolean / (open: boolean) => voidnone
calendarPropsAny other Calendar propnone

DateRangePicker

It takes the props above, except required, with a range as its value, and these:

PropTypeDefault
numberOfMonthsnumber2
presets{ label, range }[], where range is a range or a function that returns onenone
closeOnSelectboolean, closes once both ends are chosentrue