Date Picker

Use DatePicker for the common path and DateTimePicker when date and time belong to one field. Both choose a Popover on desktop and a Drawer on mobile, while Calendar and TimePicker remain available as lower-level primitives.

Last updated August 12, 2026

CreditsModifiedPublished

Copied from shadcn/ui.

  • Replaced shadcn's chrono-node natural-language input example with parseDate/formatDate + toLatinDigits from this repo's persian-date utility (no chrono-node dependency here)
  • Uses this repo's own Calendar (Jalali/Gregorian switchable via calendarType) and Popover components instead of shadcn's react-day-picker Calendar
  • Added first-class DatePicker and DateTimePicker APIs with responsive presentation, SSR-safe today defaults, and draft/confirm behavior
  • Added Calendar Type toggle, hospital/hotel Reservation, and Field + zod-validated Form examples not present upstream

Overview

Installation

Install the complete picker family with one registry command. Its Calendar, TimePicker, Popover, and Drawer dependencies are installed automatically.

$ npx shadcn@latest add https://ui.persian-labs.ir/r/date-picker.json

Usage

import { DatePicker } from "@/components/ui/date-picker"
 
export function Example() {
  return <DatePicker defaultValue="today" />
}

Examples

Range

Keep a controlled DateRange and pass onSelect={setRange} directly. The same single-calendar interaction appears in a Popover on desktop and a Drawer on mobile.

Close on Select

Control the Popover state and close it after a valid date is selected.

Controlled Value

Own the selected date in application state when other fields, validation, or server mutations need to react to every committed change.

Constrained Dates

Forward Calendar props to limit selection to a rolling seven-day booking window. The same pattern supports disabled weekdays, minimum dates, and maximum dates.

Confirmation Modes

Compare immediate commits with an explicit confirmation flow. Explicit mode is useful when changing the value has expensive side effects.

Custom Trigger

Use renderTrigger to replace the default field while retaining disclosure state, formatting, keyboard behavior, and responsive presentation.

Responsive Presets

Combine controlled state, a responsive Popover/Drawer, and Calendar footer content to provide common dates without giving up free calendar selection.

With Time

Adds a Time Picker input below the Calendar. That input opens its own popover on desktop and a drawer on smaller screens, so the wheel is never cramped beneath the calendar.

Fully Responsive

One trigger opens the familiar Calendar-and-time Popover on desktop, then switches to a single Drawer containing both controls on smaller screens.

Advanced Time Options

Combine a verbose date label with a 12-hour time wheel, Latin digits, seconds, and visible hour/minute/second headings.

Typed Input

A plain text field the user can type a yyyy/MM/dd date into (Persian or Latin digits), parsed live with parseDate and toLatinDigits, kept in sync with a Calendar opened as a secondary picking method. Digits aren't converted while typing (so the cursor stays predictable) -- they're normalized to a consistent digit style on blur or Enter, once the value is done changing.

Date of Birth

Use captionLayout="dropdown" for fast year navigation and close the popover on select.

Calendar Type

Thread calendarType down to Calendar and format the trigger's label with the matching calendar.

Miladi + LTR

Use the Gregorian calendar with English labels, LTR direction, and a long-form trigger format while retaining the same responsive behavior.

Reservation

A hotel/hospital-style booking form: a range Calendar wired to validateRange (minDays, maxDays, disablePast) for stay-length validation, and to persian-holidays's getHolidaysInRange to redden holiday cells.

Zod-Validated Form

A form built with this repo's Field components, where a single date is validated with zPersianDate and a { from, to } range with zPersianDateRange on submit, both driven by Popover+Calendar selection instead of free-text typing.

RTL

The Shamsi calendar (the default) is already RTL. A date-of-birth style field with real Farsi labels and a fully spelled-out trigger date.

API Reference

The product-level APIs cover common date and date-time fields. Use Calendar for lower-level day-grid customization.

DatePicker

DateTimePicker