Calendar
A Calendar shows a month of days and allows users to select one day, several days, or a range.
When to Use
- to choose a day near today, such as the due date of an invoice
- to choose a start and an end with
mode="range", such as the period of a report - when a form has no room for a month, inside a Popover
When Not to Use
- for a date that users know and can type, such as a date of birth (use an Input with
type="date", which renders the browser’s own date field)
Anatomy
| Element | Usage |
|---|---|
| Previous month | Shown by default |
| Caption | Required |
| Next month | Shown by default |
| Weekday | Required |
| Outside day | Shown by default |
| Today | Always marked |
| Selected day | When a mode is set |
| Disabled day | Optional |
| Range start | Range mode only |
| Range middle | Range mode only |
| Range end | Range mode only |
Calendar is a single component with no parts to compose. It wraps the DayPicker of React DayPicker, which renders the month, and it renders each day with CalendarDayButton.
Behavior
To make the days selectable, set mode. If mode isn’t set, the Calendar shows a month, and its days aren’t buttons.
Selection
| Mode | Value | Click |
|---|---|---|
single | A Date | Selects the day. A click on the selected day clears it. |
multiple | A list of Date | Adds the day, or removes it if it is already selected |
range | { from, to } | The first click sets the start, and the second sets the end. After that, a click before the start moves the start, and a click after it moves the end. A click on either end shrinks the range to that day. |
If you want to prevent a click from clearing the value, set required.
Months
By default, a Calendar opens on the current month, even when its selected day is in another month. To open it on a different month, set defaultMonth.
The two buttons at the top show the previous month and the next month. To limit how far users can go, set startMonth and endMonth.
To show several months, set numberOfMonths. The months are side by side from 768px and stacked below that.
To replace the caption with a select for the month and one for the year, set captionLayout="dropdown". The year select runs from 100 years back to the current year unless startMonth and endMonth set its range.
Days Outside the Month
Summit turns showOutsideDays on by default, so the first and last weeks show days of the neighboring months. When users click one of these days, it is selected, and the displayed month stays the same.
Size
A Calendar of one month is 212px wide, or 240px with showWeekNumber. A month has four to six weeks, and the height of the Calendar changes with it. If you want the height to stay the same, set fixedWeeks, which renders six weeks in every month.
Locale
A Calendar uses the locale in locale. If locale isn’t set, it uses dateLocale from the Summit Provider, and then US English. The locale sets the names of months and weekdays and the first day of the week.
If you import the locale from react-day-picker/locale, the accessible names are translated too, for example “Go to the Next Month”. If you import it from date-fns/locale, the accessible names stay in English.
Accessibility
React DayPicker renders each month as a grid and provides the accessible name of every button.
Keyboard
| Key | Result |
|---|---|
Tab | Moves focus to the previous-month button, the next-month button, each select of a dropdown caption, and then one day. That day is the selected day, or today, or the first of the month. |
Enter or Space on a month button | Shows the previous month or the next month. Focus stays on the button. |
Enter or Space on a day | Selects the day, or clears it if it is already selected |
ArrowLeft, ArrowRight | Moves focus to the previous or the next day |
ArrowUp, ArrowDown | Moves focus to the same weekday of the previous or the next week |
Home, End | Moves focus to the first or the last day of the week |
PageUp, PageDown | Moves focus to the same day of the previous or the next month |
Shift+PageUp, Shift+PageDown | Moves focus to the same day of the previous or the next year |
Installation
npx shadcn@latest add @summit/calendarThe CLI also adds @summit/button and @summit/summit-provider.
Usage
A Calendar selects days and shows no value outside its grid. If you want to show the date in a field or on a Button, format it in the product.
import { useState } from 'react';
import { Calendar } from '@/components/ui/calendar';
const [date, setDate] = useState<Date | undefined>();
<Calendar mode="single" selected={date} onSelect={setDate} />;Pick a Range
To select a range, set mode="range". selected then accepts a DateRange, and onSelect returns one.
import type { DateRange } from 'react-day-picker';
const [range, setRange] = useState<DateRange | undefined>();
<Calendar mode="range" numberOfMonths={2} selected={range} onSelect={setRange} />;Disable Days
To disable days, pass one matcher or a list of matchers to disabled. A matcher is a date, a list of dates, a range, { before }, { after }, { dayOfWeek }, or a function, and true disables all days. In mode="range", a range can still span disabled days unless you set excludeDisabled.
<Calendar mode="single" disabled={[{ dayOfWeek: [0, 6] }, { before: new Date() }]} />In a Popover
To make the popup fit the Calendar, add w-auto p-0 to PopoverContent. The Calendar keeps its own padding.
import { Button } from '@/components/ui/button';
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
<Popover>
<PopoverTrigger render={<Button variant="outline" />}>
{date ? date.toLocaleDateString() : 'Pick a date'}
</PopoverTrigger>
<PopoverContent aria-label="Due date" className="w-auto p-0">
<Calendar mode="single" selected={date} onSelect={setDate} />
</PopoverContent>
</Popover>;Set the Locale
To set the locale of one Calendar, pass locale. To set it for all Calendars, set dateLocale on the Summit Provider.
import { frCA } from 'react-day-picker/locale';
<Calendar mode="single" locale={frCA} />;API Reference
CalendarDayButton is the DayButton that Calendar passes to React DayPicker. To wrap or replace a day through components, import CalendarDayButton.
Calendar
| Prop | Type | Default | Description |
|---|---|---|---|
buttonVariant | The variant of a Button | 'ghost' | The variant of the two month buttons |
showOutsideDays | boolean | true | Shows the days of the neighboring months |
captionLayout | 'label' | 'dropdown' | 'dropdown-months' | 'dropdown-years' | 'label' | A text caption, or a select for the month, the year, or both |
locale | Locale | dateLocale of the Summit Provider | The language of names and the first day of the week |
Other props are passed to DayPicker. See the React DayPicker documentation for mode, selected, onSelect, required, disabled, numberOfMonths, startMonth, endMonth, fixedWeeks, and labels.