Command Palette

Search for a command to run...

Github

Date Picker

A date picker component with range and presets.

"use client";
import { format } from "date-fns";import { ChevronDownIcon } from "lucide-react";import * as React from "react";
import { Button } from "@/components/ui/button";import { Calendar } from "@/components/ui/calendar";import {	Popover,	PopoverContent,	PopoverTrigger,} from "@/components/ui/popover";
export function DatePickerDemo() {	const [date, setDate] = React.useState<Date>();
	return (		<Popover>			<PopoverTrigger				render={					<Button						variant="tertiary"						data-empty={!date}						className="w-[212px] justify-between text-left font-normal data-[empty=true]:text-muted-foreground"					/>				}			>				{date ? format(date, "PPP") : <span>Pick a date</span>}				<ChevronDownIcon data-icon="inline-end" />			</PopoverTrigger>			<PopoverContent className="w-auto p-0" align="start">				<Calendar					mode="single"					selected={date}					onSelect={setDate}					defaultMonth={date}				/>			</PopoverContent>		</Popover>	);}

Usage

The Date Picker is built using a composition of the <Popover /> and the <Calendar /> components.

"use client"
import * as React from "react"import { format } from "date-fns"import { CalendarIcon } from "lucide-react"
import { Button } from "@/components/ui/button"import { Calendar } from "@/components/ui/calendar"import {  Popover,  PopoverContent,  PopoverTrigger,} from "@/components/ui/popover"
export function DatePickerDemo() {  const [date, setDate] = React.useState<Date>()
  return (    <Popover>      <PopoverTrigger        render={          <Button            variant="outline"            data-empty={!date}            className="justify-start text-left font-normal data-[empty=true]:text-muted-foreground"          />        }      >        <CalendarIcon />        {date ? format(date, "PPP") : <span>Pick a date</span>}      </PopoverTrigger>      <PopoverContent className="w-auto p-0">        <Calendar mode="single" selected={date} onSelect={setDate} />      </PopoverContent>    </Popover>  )}

See the React DayPicker documentation for more information.

Composition

A date picker is built from Popover and Calendar (there is no DatePicker root component):

Popover├── PopoverTrigger└── PopoverContent    └── Calendar

Examples

Basic

A basic date picker component.

"use client";
import { format } from "date-fns";import * as React from "react";
import { Button } from "@/components/ui/button";import { Calendar } from "@/components/ui/calendar";import { Field, FieldLabel } from "@/components/ui/field";import {	Popover,	PopoverContent,	PopoverTrigger,} from "@/components/ui/popover";
export function DatePickerSimple() {	const [date, setDate] = React.useState<Date>();
	return (		<Field className="mx-auto w-44">			<FieldLabel htmlFor="date-picker-simple">Date</FieldLabel>			<Popover>				<PopoverTrigger					render={						<Button							variant="tertiary"							id="date-picker-simple"							className="justify-start font-normal"						/>					}				>					{date ? format(date, "PPP") : <span>Pick a date</span>}				</PopoverTrigger>				<PopoverContent className="w-auto p-0" align="start">					<Calendar						mode="single"						selected={date}						onSelect={setDate}						defaultMonth={date}					/>				</PopoverContent>			</Popover>		</Field>	);}

Range Picker

A date picker component for selecting a range of dates.

"use client";
import { addDays, format } from "date-fns";import { CalendarIcon } from "lucide-react";import * as React from "react";import type { DateRange } from "react-day-picker";
import { Button } from "@/components/ui/button";import { Calendar } from "@/components/ui/calendar";import { Field, FieldLabel } from "@/components/ui/field";import {	Popover,	PopoverContent,	PopoverTrigger,} from "@/components/ui/popover";
export function DatePickerWithRange() {	const [date, setDate] = React.useState<DateRange | undefined>({		from: new Date(new Date().getFullYear(), 0, 20),		to: addDays(new Date(new Date().getFullYear(), 0, 20), 20),	});
	return (		<Field className="mx-auto w-60">			<FieldLabel htmlFor="date-picker-range">Date Picker Range</FieldLabel>			<Popover>				<PopoverTrigger					render={						<Button							variant="tertiary"							id="date-picker-range"							className="justify-start px-2.5 font-normal"						/>					}				>					<CalendarIcon data-icon="inline-start" />					{date?.from ? (						date.to ? (							<>								{format(date.from, "LLL dd, y")} -{" "}								{format(date.to, "LLL dd, y")}							</>						) : (							format(date.from, "LLL dd, y")						)					) : (						<span>Pick a date</span>					)}				</PopoverTrigger>				<PopoverContent className="w-auto p-0" align="start">					<Calendar						mode="range"						defaultMonth={date?.from}						selected={date}						onSelect={setDate}						numberOfMonths={2}					/>				</PopoverContent>			</Popover>		</Field>	);}

Date of Birth

A date picker component for selecting a date of birth. This component includes a dropdown caption layout for date and month selection.

"use client";
import * as React from "react";
import { Button } from "@/components/ui/button";import { Calendar } from "@/components/ui/calendar";import { Field, FieldLabel } from "@/components/ui/field";import {	Popover,	PopoverContent,	PopoverTrigger,} from "@/components/ui/popover";
export function DatePickerDob() {	const [open, setOpen] = React.useState(false);	const [date, setDate] = React.useState<Date | undefined>(undefined);
	return (		<Field className="mx-auto w-44">			<FieldLabel htmlFor="date">Date of birth</FieldLabel>			<Popover open={open} onOpenChange={setOpen}>				<PopoverTrigger					render={						<Button							variant="tertiary"							id="date"							className="justify-start font-normal"						/>					}				>					{date ? date.toLocaleDateString() : "Select date"}				</PopoverTrigger>				<PopoverContent className="w-auto overflow-hidden p-0" align="start">					<Calendar						mode="single"						selected={date}						defaultMonth={date}						captionLayout="dropdown"						onSelect={(date) => {							setDate(date);							setOpen(false);						}}					/>				</PopoverContent>			</Popover>		</Field>	);}

Input

A date picker component with an input field for selecting a date.

"use client";
import { CalendarIcon } from "lucide-react";import * as React from "react";
import { Calendar } from "@/components/ui/calendar";import { Field, FieldLabel } from "@/components/ui/field";import {	InputGroup,	InputGroupAddon,	InputGroupButton,	InputGroupInput,} from "@/components/ui/input-group";import {	Popover,	PopoverContent,	PopoverTrigger,} from "@/components/ui/popover";
function formatDate(date: Date | undefined) {	if (!date) {		return "";	}
	return date.toLocaleDateString("en-US", {		day: "2-digit",		month: "long",		year: "numeric",	});}
function isValidDate(date: Date | undefined) {	if (!date) {		return false;	}	return !Number.isNaN(date.getTime());}
export function DatePickerInput() {	const [open, setOpen] = React.useState(false);	const [date, setDate] = React.useState<Date | undefined>(		new Date("2025-06-01"),	);	const [month, setMonth] = React.useState<Date | undefined>(date);	const [value, setValue] = React.useState(formatDate(date));
	return (		<Field className="mx-auto w-48">			<FieldLabel htmlFor="date-required">Subscription Date</FieldLabel>			<InputGroup>				<InputGroupInput					id="date-required"					value={value}					placeholder="June 01, 2025"					onChange={(e) => {						const date = new Date(e.target.value);						setValue(e.target.value);						if (isValidDate(date)) {							setDate(date);							setMonth(date);						}					}}					onKeyDown={(e) => {						if (e.key === "ArrowDown") {							e.preventDefault();							setOpen(true);						}					}}				/>				<InputGroupAddon align="inline-end">					<Popover open={open} onOpenChange={setOpen}>						<PopoverTrigger							render={								<InputGroupButton									id="date-picker"									variant="ghost"									size="icon-xs"									aria-label="Select date"								/>							}						>							<CalendarIcon />							<span className="sr-only">Select date</span>						</PopoverTrigger>						<PopoverContent							className="w-auto overflow-hidden p-0"							align="end"							alignOffset={-8}							sideOffset={10}						>							<Calendar								mode="single"								selected={date}								month={month}								onMonthChange={setMonth}								onSelect={(date) => {									setDate(date);									setValue(formatDate(date));									setOpen(false);								}}							/>						</PopoverContent>					</Popover>				</InputGroupAddon>			</InputGroup>		</Field>	);}

Time Picker

A date picker component with a time input field for selecting a time.

"use client";
import { format } from "date-fns";import { ChevronDownIcon } from "lucide-react";import * as React from "react";
import { Button } from "@/components/ui/button";import { Calendar } from "@/components/ui/calendar";import { Field, FieldGroup, FieldLabel } from "@/components/ui/field";import { Input } from "@/components/ui/input";import {	Popover,	PopoverContent,	PopoverTrigger,} from "@/components/ui/popover";
export function DatePickerTime() {	const [open, setOpen] = React.useState(false);	const [date, setDate] = React.useState<Date | undefined>(undefined);
	return (		<FieldGroup className="mx-auto max-w-xs flex-row">			<Field>				<FieldLabel htmlFor="date-picker-optional">Date</FieldLabel>				<Popover open={open} onOpenChange={setOpen}>					<PopoverTrigger						render={							<Button								variant="tertiary"								id="date-picker-optional"								className="w-32 justify-between font-normal"							/>						}					>						{date ? format(date, "PPP") : "Select date"}						<ChevronDownIcon data-icon="inline-end" />					</PopoverTrigger>					<PopoverContent className="w-auto overflow-hidden p-0" align="start">						<Calendar							mode="single"							selected={date}							captionLayout="dropdown"							defaultMonth={date}							onSelect={(sel) => {								setDate(sel);								setOpen(false);							}}						/>					</PopoverContent>				</Popover>			</Field>			<Field className="w-32">				<FieldLabel htmlFor="time-picker-optional">Time</FieldLabel>				<Input					type="time"					id="time-picker-optional"					step="1"					defaultValue="10:30:00"					className="appearance-none [&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none"				/>			</Field>		</FieldGroup>	);}

Natural Language Picker

This component uses the chrono-node library to parse natural language dates.

Your post will be published on October 31, 2026.
"use client";
import { parseDate } from "chrono-node";import { CalendarIcon } from "lucide-react";import * as React from "react";
import { Calendar } from "@/components/ui/calendar";import { Field, FieldLabel } from "@/components/ui/field";import {	InputGroup,	InputGroupAddon,	InputGroupButton,	InputGroupInput,} from "@/components/ui/input-group";import {	Popover,	PopoverContent,	PopoverTrigger,} from "@/components/ui/popover";
function formatDate(date: Date | undefined) {	if (!date) {		return "";	}
	return date.toLocaleDateString("en-US", {		day: "2-digit",		month: "long",		year: "numeric",	});}
export function DatePickerNaturalLanguage() {	const [open, setOpen] = React.useState(false);	const [value, setValue] = React.useState("In 2 days");	const [date, setDate] = React.useState<Date | undefined>(		parseDate(value) || undefined,	);
	return (		<Field className="mx-auto max-w-xs">			<FieldLabel htmlFor="date-optional">Schedule Date</FieldLabel>			<InputGroup>				<InputGroupInput					id="date-optional"					value={value}					placeholder="Tomorrow or next week"					onChange={(e) => {						setValue(e.target.value);						const date = parseDate(e.target.value);						if (date) {							setDate(date);						}					}}					onKeyDown={(e) => {						if (e.key === "ArrowDown") {							e.preventDefault();							setOpen(true);						}					}}				/>				<InputGroupAddon align="inline-end">					<Popover open={open} onOpenChange={setOpen}>						<PopoverTrigger							render={								<InputGroupButton									id="date-picker"									variant="ghost"									size="icon-xs"									aria-label="Select date"								/>							}						>							<CalendarIcon />							<span className="sr-only">Select date</span>						</PopoverTrigger>						<PopoverContent							className="w-auto overflow-hidden p-0"							align="end"							sideOffset={8}						>							<Calendar								mode="single"								selected={date}								captionLayout="dropdown"								defaultMonth={date}								onSelect={(sel) => {									setDate(sel);									setValue(formatDate(sel));									setOpen(false);								}}							/>						</PopoverContent>					</Popover>				</InputGroupAddon>			</InputGroup>			<div className="px-1 text-muted-foreground text-sm">				Your post will be published on{" "}				<span className="font-medium">{formatDate(date)}</span>.			</div>		</Field>	);}

RTL

"use client";
import { format } from "date-fns";import { arSA, he } from "date-fns/locale";import { ChevronDownIcon } from "lucide-react";import * as React from "react";import {	arSA as arSADayPicker,	he as heDayPicker,} from "react-day-picker/locale";
import {	type Translations,	useTranslation,} from "@/components/language-selector";import { Button } from "@/components/ui/button";import { Calendar } from "@/components/ui/calendar";import {	Popover,	PopoverContent,	PopoverTrigger,} from "@/components/ui/popover";
const translations: Translations = {	en: {		dir: "ltr",		values: {			placeholder: "Pick a date",		},	},	ar: {		dir: "rtl",		values: {			placeholder: "اختر تاريخًا",		},	},	he: {		dir: "rtl",		values: {			placeholder: "בחר תאריך",		},	},};
const dayPickerLocales = {	ar: arSADayPicker,	he: heDayPicker,} as const;
const dateFnsLocales = {	ar: arSA,	he: he,} as const;
export function DatePickerRtl() {	const { dir, t, language } = useTranslation(translations, "ar");	const [date, setDate] = React.useState<Date>();
	const dateFnsLocale =		dir === "rtl"			? dateFnsLocales[language as keyof typeof dateFnsLocales]			: undefined;	const dayPickerLocale =		dir === "rtl"			? dayPickerLocales[language as keyof typeof dayPickerLocales]			: undefined;
	return (		<Popover>			<PopoverTrigger				render={					<Button						variant="tertiary"						data-empty={!date}						className="w-[212px] justify-between text-left font-normal data-[empty=true]:text-muted-foreground"						dir={dir}					/>				}			>				{date ? (					format(date, "PPP", { locale: dateFnsLocale })				) : (					<span>{t.placeholder}</span>				)}				<ChevronDownIcon data-icon="inline-end" />			</PopoverTrigger>			<PopoverContent className="w-auto p-0" align="start" dir={dir}>				<Calendar					mode="single"					selected={date}					onSelect={setDate}					defaultMonth={date}					dir={dir}					locale={dayPickerLocale}				/>			</PopoverContent>		</Popover>	);}

To enable RTL support in the date picker, import locales from both date-fns/locale and react-day-picker/locale, then pass dir, locale to the Calendar component and dir to the PopoverContent and PopoverTrigger:

import { arSA } from "date-fns/locale"import { arSA as arSADayPicker } from "react-day-picker/locale"
<Popover>  <PopoverContent className="w-auto p-0" align="start" dir="rtl">    <Calendar      mode="single"      selected={date}      onSelect={setDate}      dir="rtl"      locale={arSADayPicker}    />  </PopoverContent></Popover>