- Accordion
- Alert
- Alert Dialog
- Avatar
- Badge
- Button
- Calendar
- Card
- Carousel
- Chart
- Checkbox
- Circular Progress
- Collapsible
- Compare Slider
- Dialog
- Dropdown Menu
- Gauge
- Input
- Label
- Marquee
- Navigation Menu
- Number Field
- Pagination
- Popover
- Progress
- Radio Group
- Scroll Area
- Select
- Separator
- Sheet
- Sidebar
- Skeleton
- Slider
- Switch
- Table
- Tabs
- Textarea
- Toggle
- Tooltip
Demos
Pick a single date.
| Su | Mo | Tu | We | Th | Fr | Sa |
|---|---|---|---|---|---|---|
"use client"
import * as React from "react"
import { Calendar } from "@workspace/ui/components/calendar"
export function CalendarDemo() {
const [date, setDate] = React.useState<Date | undefined>(new Date())
return (
<Calendar
mode="single"
selected={date}
onSelect={setDate}
className="rounded-lg border"
/>
)
}
Usage
Use a calendar when the day of the week or nearby dates matter, such as booking a blood draw. For a date the reader already knows, like a birthday, a text input is faster. Put the calendar inside a popover when space is tight.
Import it from @workspace/ui/components/calendar. It is built on React DayPicker, so every DayPicker prop works.
Anatomy
- Calendar — The month grid with navigation.
- CalendarDayButton — The button for each day. Exported so you can reuse it in a custom
components.DayButton.
Notes
- Set
modetosingle,multiple, orrange. The shape ofselectedfollows the mode. - Use
disabledto block dates, for example days before today or days with no slots. captionLayout="dropdown"adds month and year dropdowns for dates far from today. The years run from 100 years ago to this year unless you setstartMonthandendMonth.
Examples
Range
Set mode="range" to pick a start and end date. numberOfMonths={2} shows two months side by side.
| Su | Mo | Tu | We | Th | Fr | Sa |
|---|---|---|---|---|---|---|
| Su | Mo | Tu | We | Th | Fr | Sa |
|---|---|---|---|---|---|---|
"use client"
import * as React from "react"
import { Calendar } from "@workspace/ui/components/calendar"
type DateRange = { from: Date | undefined; to?: Date }
export function CalendarRange() {
const [range, setRange] = React.useState<DateRange | undefined>(() => {
const from = new Date()
const to = new Date()
to.setDate(from.getDate() + 4)
return { from, to }
})
return (
<Calendar
mode="range"
selected={range}
onSelect={setRange}
numberOfMonths={2}
className="rounded-lg border"
/>
)
}
Month and year dropdowns
Set captionLayout="dropdown" to jump between months and years, for example a date of birth.
| Su | Mo | Tu | We | Th | Fr | Sa |
|---|---|---|---|---|---|---|
"use client"
import * as React from "react"
import { Calendar } from "@workspace/ui/components/calendar"
export function CalendarDropdown() {
const [date, setDate] = React.useState<Date | undefined>(new Date(1994, 4, 12))
return (
<Calendar
mode="single"
selected={date}
onSelect={setDate}
defaultMonth={date}
captionLayout="dropdown"
className="rounded-lg border"
/>
)
}
Disabled dates
Pass a matcher to disabled. Here, past days and Sundays cannot be booked.
| Su | Mo | Tu | We | Th | Fr | Sa |
|---|---|---|---|---|---|---|
"use client"
import * as React from "react"
import { Calendar } from "@workspace/ui/components/calendar"
export function CalendarDisabledDates() {
const [date, setDate] = React.useState<Date | undefined>()
return (
<Calendar
mode="single"
selected={date}
onSelect={setDate}
disabled={[{ before: new Date() }, { dayOfWeek: [0] }]}
className="rounded-lg border"
/>
)
}
In a popover
A date picker: a button opens the calendar, and picking a day closes it.
"use client"
import * as React from "react"
import { CalendarIcon } from "lucide-react"
import { Button } from "@workspace/ui/components/button"
import { Calendar } from "@workspace/ui/components/calendar"
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@workspace/ui/components/popover"
export function CalendarInPopover() {
const [open, setOpen] = React.useState(false)
const [date, setDate] = React.useState<Date | undefined>()
return (
<Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger
render={<Button variant="outline" className="w-56 justify-between font-normal" />}
>
{date ? date.toLocaleDateString(undefined, { dateStyle: "medium" }) : "Pick a test date"}
<CalendarIcon data-icon="inline-end" />
</PopoverTrigger>
<PopoverContent className="w-auto p-0" align="start">
<Calendar
mode="single"
selected={date}
onSelect={(next) => {
setDate(next)
setOpen(false)
}}
/>
</PopoverContent>
</Popover>
)
}
Props
These are the props you set most often. Unlisted props pass through to DayPicker.
Calendar
| Prop | Type | Default | Description |
|---|---|---|---|
mode | "single", "multiple", or "range" | — | How many dates can be selected. |
selected | Date, Date[], or DateRange | — | The selected date or dates. |
onSelect | (value) => void | — | Called when the selection changes. |
captionLayout | "label", "dropdown", "dropdown-months", or "dropdown-years" | label | How the month caption is shown. |
showOutsideDays | boolean | true | Show days from the next and previous month. |
disabled | Matcher or Matcher[] | — | Dates that cannot be picked. |
buttonVariant | Button variant | ghost | Variant of the previous and next buttons. |
className | string | — | Classes merged onto the root. |