Skip to content

Date Picker

Type a date in your locale’s format or choose it from a calendar.

import { DatePicker } from '@youj/react/date'

Installation & usage

npm i @youj/react date-fns react-day-picker

For an app already set up with npx @youj/cli init, which installs the peers (@youj/core, @youj/motion, motion and Base UI) and wires the provider. New app? Start at Installation.

Requires date-fns and react-day-picker, optional dependencies. Import it from @youj/react/date.

Use Date Picker for a due date, launch date or birthday. People can type the date or choose it from the calendar. Use Date Range Picker for a start and end, Calendar for an always-visible month, or add Time Picker for the time of day.

import { useState } from 'react'
import { Field, FieldLabel } from '@youj/react'
import { DatePicker } from '@youj/react/date'

export function DueDate() {
  const [date, setDate] = useState<Date | null>(null)
  return (
    <Field>
      <FieldLabel>Due date</FieldLabel>
      <DatePicker value={date} onValueChange={setDate} />
    </Field>
  )
}

The field is an Input Group text input in the locale's short format, such as 09/27/2026 in en-US or 27.09.2026 in German, with the order spelled out in the placeholder. The value is a Date, or null while the field is empty or doesn't hold a date.

Without a locale, the picker follows YoujProvider's: <YoujProvider locale="de-DE"> gives 27.09.2026, German month and day names, and weeks from Monday. The order and names come from Intl, and the first day of the week from Intl.Locale's week info where the browser has it (Monday where it doesn't). The same goes for Calendar and Date Range Picker; dateLocale(tag) returns the locale they build.

locale takes a date-fns locale, which is also react-day-picker's, and wins over the provider's. It sets the field's order and separator, the placeholder, the calendar's month and day names, and the first day of the week, and it lets the field read typed month names in that language ("5. Sept. 2026"), which the Intl-built locale reads only in English.

import { de } from 'date-fns/locale'

<DatePicker locale={de} />

Reference

Propsvalue, defaultValue, onValueChange… (18)

Props

DatePicker props
PropType
valueDate | null–
defaultValueDate | null

default null

null
onValueChange(date: Date | null) => void–
localeLocale

A date-fns / react-day-picker locale: order, names, week start, parsing of month names. Default: YoujProvider's locale, through Intl (see Calendar's dateLocale).

–
minDateDate–
maxDateDate–
disabledDatesMatcher | Matcher[]

Days that can't be chosen (react-day-picker matchers).

–
placeholderstring

Default: the locale's pattern ("MM/DD/YYYY").

–
disabledboolean–
namestring

Also submits the date (yyyy-MM-dd) with a native form.

–
idstring–
refRef<HTMLInputElement>–
onBlur() => void–
classNamestring–
aria-labelstring–
presentationOverlayPresentation
'auto''sheet''popover'

auto (the default) opens the calendar in a popover under a pointer and in a bottom sheet on touch; force either one.

default 'auto'

'auto'
variant'default' | 'ghost'

ghost: no typed field, a quiet button showing the date that opens the calendar, matching SelectTrigger variant="ghost" (for a property row or a table cell).

default 'default'

'default'
size'sm' | 'default'

The ghost trigger's height, as SelectTrigger's. The field takes its height from the theme.

default 'default'

'default'

The package also exports the helpers the picker uses, for your own parsing and display: parseDate(text, locale), formatDate(date, locale), datePattern(locale), datePlaceholder(locale) and dateAllowed(date, min, max, disabled).

TouchOn a touch device the field is still a text field you can type in,…

Touch

On a touch device the field is still a text field you can type in, set at 16px so the page doesn't zoom when it's focused. The calendar button has a 44px target and opens the calendar in a bottom sheet with 44px days. Picking a day closes the sheet, and so do pulling it down, tapping outside it and Escape.

presentation chooses: auto (the default) is a popover under a mouse or trackpad and a sheet on touch, sheet always uses the sheet, and popover keeps the popover on touch too.

MotionOpen, close, month change… · reduced motion

Motion

Motion tokens
MomentTokens
Openthe calendar grows out of the field (yj-pop)
duration.fastease.enter

140ms · cubic-bezier(0.16, 1, 0.3, 1)

140mscubic-bezier(0.16, 1, 0.3, 1)
Close
duration.instantease.exit

80ms · cubic-bezier(0.4, 0, 1, 1)

80mscubic-bezier(0.4, 0, 1, 1)
Month changethe Calendar's slide from the side it comes from
duration.baseease.enter

220ms · cubic-bezier(0.16, 1, 0.3, 1)

220mscubic-bezier(0.16, 1, 0.3, 1)
Icon hoverthe calendar icon tears off a day
duration.fastease.standard

140ms · cubic-bezier(0.2, 0, 0, 1)

140mscubic-bezier(0.2, 0, 0, 1)

Reduced motion

The popover opens and closes at once, the month changes in place and the icon stays still.

Reduced motion

The popover and the month change happen at once, and the icon doesn't animate. Typing, parsing and keyboard handling are unchanged.

AccessibilityKeyboard, ARIA, focus

Accessibility

  • The input is named by its FieldLabel, or by aria-label, and carries aria-invalid when the text isn't an allowed date.
  • The calendar button is named "Choose date", and so is the popup. Focus moves into the calendar on the chosen day, and returns to the input when a day is picked or Escape closes it.
  • In the calendar, arrows move by day, PageUp and PageDown by month and Home and End by week.
  • With name, a hidden input submits the date as yyyy-MM-dd.