ComponentsPickers

Date Picker

A single date in a typeable field with a popover calendar: due dates, hire dates, birth dates, publish dates. Type in the locale's pattern, digits only, a partial date or “tomorrow”. The value is always a YYYY-MM-DD string that never shifts across time zones. DateTimePicker adds a time for scheduling.

react-day-picker v9 + date-fns v4 + Radix Popover components/date-picker.tsx, components/calendar.tsx, components/time-picker.tsx, lib/date.ts, styles/calendar.csstheme · material · accent · density · font

Type 12/04/2026, 1204 or “tomorrow” — or open the calendar.

value: 2026-12-04

Installation

$ pnpm add @vamos-ui/react

The whole kit as one package — get updates by bumping the version. Add the styles to globals.css: @import "@vamos-ui/react/styles.css";

Usage

import { DatePicker, Field } from "@vamos-ui/react";

const [due, setDue] = React.useState<string | null>("2026-12-04");

<Field label="Invoice due date">
  <DatePicker value={due} onValueChange={setDue} clearable />
</Field>

Never build the value with toISOString(): at UTC+3 a local midnight is the previous day in UTC. The pickers read and write the local calendar.

Keyboard: the field stays typeable; Alt+↓ opens the calendar, where arrows / PageUp / PageDown / Home / End move, Enter picks and Esc closes and returns focus to the field.

Examples

Button trigger

trigger="button" for filter bars: the button reads the full date and opens a dialog (aria-haspopup="dialog").

214 deals

Min and max

Days outside min / max are disabled in the grid; a typed date out of range keeps its text, sets aria-invalid and reports a message through onInputError.

Between today and 90 days out. Weekends are allowed.

Natural input & locales

Separators . / - and space, digits only (1123 / 23112026), partial dates (this year), two-digit years, month names, +N days and relative words from the dictionary.

Try “tomorrow”, “+7”, “1123” or “Nov 23”.

“yarın”, “23.11” veya “23112026” yazın.

Date and time

DateTimePicker emits a local wall-clock "YYYY-MM-DDTHH:mm" and shows the zone it is meant in. Picking a date first fills defaultTime.

––––––
GMT+3

The post goes live at this local time in Istanbul.

value: null

In a form

name renders a hidden input with the YYYY-MM-DD value, so plain FormData and server actions get an unambiguous date.

Sizes & states

sm / md / lg follow --control-h; read-only, disabled and a Field error.

Set automatically from the plan.

Pick a weekday — the warehouse is closed at weekends.

API

DatePicker

PropTypeDefault
value / defaultValue
YYYY-MM-DD, or null when empty.
string | null—
onValueChange
After a pick, Today, Clear, or a valid typed date (on blur / Enter).
(value: string | null) => void—
trigger
Typeable field + calendar button, or a single trigger for filter bars.
"input" | "button""input"
displayFormat
Text of the button trigger, via Intl.
"short" | "medium" | "long" | "full""long"
placeholder
Default: the locale pattern (MM/DD/YYYY, GG.AA.YYYY) or “Pick a date” for the button.
string—
min / max
Earliest / latest selectable date (YYYY-MM-DD). Also limits calendar navigation.
string—
disabledDays
react-day-picker matchers ({ dayOfWeek: [0, 6] }, { before }, functions) or YYYY-MM-DD strings.
DayMatcher | DayMatcher[]—
clearable
Clear button in the field and in the popover footer.
booleanfalse
showToday
Today shortcut in the popover footer (disabled when today is not allowed).
booleantrue
name
Hidden input that submits YYYY-MM-DD.
string—
size
Height from the density axis.
"sm" | "md" | "lg""md"
invalid / disabled / readOnly / required
Also read from the surrounding Field.
boolean—
align
Popover alignment.
"start" | "center" | "end""start"
open / defaultOpen / onOpenChange
Popover state.
boolean / (open) => void—
onInputError
"invalid", "beforeMin", "afterMax" or "unavailable" for typed text, with a localized message for Field error.
(error: DateInputError | null, message: string) => void—
calendarProps
Passed to the grid: captionLayout, startMonth, endMonth, showWeekNumber, renderDayExtra, size…
DatePickerCalendarProps—
labels
Strings (datePicker namespace): openCalendar, clear, today, invalid, tokens (dayToken / monthToken / yearToken), relative words.
Partial<DatePickerLabels>—
calendarLabels
Grid strings (calendar namespace).
Partial<CalendarLabels>—

DateTimePicker

PropTypeDefault
value / defaultValue
Local wall-clock "YYYY-MM-DDTHH:mm".
string | null—
onValueChange
Once both a date and a time are set; null otherwise.
(value: string | null) => void—
defaultTime
Time filled when only a date is picked; null waits for a time.
string | null"09:00"
step
Minutes between time slots and per arrow press.
number15
hourCycle
Default from the locale.
12 | 24—
minTime / maxTime
Allowed time of day (HH:mm).
string—
timeZone
IANA zone shown after the inputs (GMT+3). Convert on the server.
string—
…DatePicker props
min, max, disabledDays, size, labels, calendarProps…
—

Helpers

PropTypeDefault
parseDateInput(text, locale, options?)
The parser behind the field. Options: reference date, relative words.
string | null—
formatDateInput(value, locale)
YYYY-MM-DD → locale numeric pattern.
string—
dateToIso(date) / isoToDate(value)
Local calendar conversions (no UTC shift).
string / Date | null—
todayIso(timeZone?) / addIsoDays(value, n)
Date-only arithmetic.
string—
registerDateLocale(tag, locale)
Add a date-fns locale for month / weekday names (en-US and tr built in).
void—