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#
| Prop | Type | Default |
|---|---|---|
value / defaultValue | Date or null | none |
onValueChange | (value: Date | null) => void | none |
min / max | Date | none |
disabledDates | A matcher, or a list of them | none |
closeOnSelect | boolean | true |
required | boolean | false |
formatOptions | Intl.DateTimeFormatOptions | { dateStyle: "medium" } |
placeholder | string | a prompt in the locale |
locale / numberingSystem | string | the app's locale |
messages | Partial<DateMessages> | built in |
name | string | none |
disabled / invalid | boolean | false |
open / onOpenChange | boolean / (open: boolean) => void | none |
calendarProps | Any other Calendar prop | none |
DateRangePicker#
It takes the props above, except required, with a range as its value, and these:
| Prop | Type | Default |
|---|---|---|
numberOfMonths | number | 2 |
presets | { label, range }[], where range is a range or a function that returns one | none |
closeOnSelect | boolean, closes once both ends are chosen | true |