Calendar

A date field component that allows users to enter and edit dates.

August 2025
tsx
"use client"
import * as React from "react"
import { Calendar } from "@/components/ui/calendar"
export function CalendarDemo() {
const [date, setDate] = React.useState<Date | undefined>(new Date())
return (
<Calendar
mode="single"
selected={date}
onSelect={setDate}
className="rounded-md border shadow-sm"
/>
)
}

Installation

CLI

bash
npx fivui add calendar

Manual

Install the following dependencies:

bash
npm install react-day-picker lucide-react

Copy and paste the following code into your project:

tsx
"use client"
import * as React from "react"
import {
ChevronDownIcon,
ChevronLeftIcon,
ChevronRightIcon,
} from "lucide-react"
import { DayButton, DayPicker, getDefaultClassNames } from "react-day-picker"
import { cn } from "@/lib/utils"
import { Button, buttonVariants } from "@/components/ui/button"
function Calendar({
className,
classNames,
showOutsideDays = true,
captionLayout = "label",
buttonVariant = "ghost",
formatters,
components,
...props
}: React.ComponentProps<typeof DayPicker> & {
buttonVariant?: React.ComponentProps<typeof Button>["variant"]
}) {
const defaultClassNames = getDefaultClassNames()
return (
<DayPicker
showOutsideDays={showOutsideDays}
className={cn(
"bg-background group/calendar p-3 [--cell-size:--spacing(8)]",
className
)}
captionLayout={captionLayout}
formatters={{
formatMonthDropdown: (date) =>
date.toLocaleString("default", { month: "short" }),
...formatters,
}}
classNames={{
root: cn("w-fit", defaultClassNames.root),
months: cn(
"flex gap-4 flex-col md:flex-row relative",
defaultClassNames.months
),
month: cn("flex flex-col w-full gap-4", defaultClassNames.month),
nav: cn(
"flex items-center gap-1 w-full absolute top-0 inset-x-0 justify-between",
defaultClassNames.nav
),
button_previous: cn(
buttonVariants({ variant: buttonVariant }),
"size-(--cell-size) aria-disabled:opacity-50 p-0 select-none",
defaultClassNames.button_previous
),
button_next: cn(
buttonVariants({ variant: buttonVariant }),
"size-(--cell-size) aria-disabled:opacity-50 p-0 select-none",
defaultClassNames.button_next
),
// ... more styling classes
...classNames,
}}
components={{
Root: ({ className, rootRef, ...props }) => (
<div
data-slot="calendar"
ref={rootRef}
className={cn(className)}
{...props}
/>
),
Chevron: ({ className, orientation, ...props }) => {
if (orientation === "left") {
return (
<ChevronLeftIcon className={cn("size-4", className)} {...props} />
)
}
if (orientation === "right") {
return (
<ChevronRightIcon className={cn("size-4", className)} {...props} />
)
}
return (
<ChevronDownIcon className={cn("size-4", className)} {...props} />
)
},
DayButton: CalendarDayButton,
...components,
}}
{...props}
/>
)
}
function CalendarDayButton({
className,
day,
modifiers,
...props
}: React.ComponentProps<typeof DayButton>) {
const defaultClassNames = getDefaultClassNames()
const ref = React.useRef<HTMLButtonElement>(null)
React.useEffect(() => {
if (modifiers.focused) ref.current?.focus()
}, [modifiers.focused])
return (
<Button
ref={ref}
variant="ghost"
size="icon"
className={cn(
"data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground",
defaultClassNames.day,
className
)}
{...props}
/>
)
}
export { Calendar, CalendarDayButton }

Usage

tsx
import { Calendar } from "@/components/ui/calendar"
tsx
const [date, setDate] = React.useState<Date | undefined>(new Date())
return (
<Calendar
mode="single"
selected={date}
onSelect={setDate}
className="rounded-lg border"
/>
)

Examples

Range Selection

January 2024
February 2024
tsx
"use client"
import * as React from "react"
import { Calendar } from "@/components/ui/calendar"
export function CalendarRangeDemo() {
const [date, setDate] = React.useState<DateRange | undefined>({
from: new Date(2024, 0, 20),
to: new Date(2024, 0, 25),
})
return (
<Calendar
mode="range"
defaultMonth={date?.from}
selected={date}
onSelect={setDate}
numberOfMonths={2}
className="rounded-md border shadow-sm"
/>
)
}

Multiple Selection

August 2025
tsx
"use client"
import * as React from "react"
import { Calendar } from "@/components/ui/calendar"
export function CalendarMultipleDemo() {
const [dates, setDates] = React.useState<Date[] | undefined>([
new Date(2024, 0, 15),
new Date(2024, 0, 20),
new Date(2024, 0, 25),
])
return (
<Calendar
mode="multiple"
selected={dates}
onSelect={setDates}
className="rounded-md border shadow-sm"
/>
)
}

Dropdown Navigation

Calendar with month and year dropdown selectors using captionLayout="dropdown".

August 2025
tsx
"use client"
import * as React from "react"
import { Calendar } from "@/components/ui/calendar"
export function CalendarWithDropdownsDemo() {
const [date, setDate] = React.useState<Date | undefined>(new Date())
return (
<Calendar
mode="single"
selected={date}
onSelect={setDate}
captionLayout="dropdown"
fromMonth={new Date(2020, 0)}
toMonth={new Date(2030, 11)}
className="rounded-md border shadow-sm"
/>
)
}

Year Dropdown Only

Calendar with only year dropdown using captionLayout="dropdown-years".

AugAugust 2025
tsx
"use client"
import * as React from "react"
import { Calendar } from "@/components/ui/calendar"
export function CalendarWithCustomDropdownsDemo() {
const [date, setDate] = React.useState<Date | undefined>(new Date())
return (
<Calendar
mode="single"
selected={date}
onSelect={setDate}
captionLayout="dropdown-years"
fromMonth={new Date(2020, 0)}
toMonth={new Date(2030, 11)}
className="rounded-md border shadow-sm"
/>
)
}

API Reference

Calendar

PropTypeDefaultDescription
mode"single" | "multiple" | "range""single"The selection mode of the calendar.
selectedDate | Date[] | DateRange-The selected date(s).
onSelectfunction-Event handler called when the selection changes.
defaultMonthDate-The month to display by default.
numberOfMonthsnumber1The number of months to display.
showOutsideDaysbooleantrueShow days outside the current month.
captionLayout"label" | "dropdown" | "dropdown-years""label"The layout of the month caption.
disabledDate | Date[] | function-Dates to disable.
fromMonthDate-Start month for navigation range.
toMonthDate-End month for navigation range.
buttonVariantButtonVariant"ghost"Variant for navigation buttons.

External Documentation