Summit
ComponentsSelection

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

ElementUsage
Previous monthShown by default
CaptionRequired
Next monthShown by default
WeekdayRequired
Outside dayShown by default
TodayAlways marked
Selected dayWhen a mode is set
Disabled dayOptional
Range startRange mode only
Range middleRange mode only
Range endRange 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

ModeValueClick
singleA DateSelects the day. A click on the selected day clears it.
multipleA list of DateAdds 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

KeyResult
TabMoves 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 buttonShows the previous month or the next month. Focus stays on the button.
Enter or Space on a daySelects the day, or clears it if it is already selected
ArrowLeft, ArrowRightMoves focus to the previous or the next day
ArrowUp, ArrowDownMoves focus to the same weekday of the previous or the next week
Home, EndMoves focus to the first or the last day of the week
PageUp, PageDownMoves focus to the same day of the previous or the next month
Shift+PageUp, Shift+PageDownMoves focus to the same day of the previous or the next year

Installation

npx shadcn@latest add @summit/calendar

The 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.

Pick a Range
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.

Disable Days
<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.

In a Popover
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.

Set the Locale
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

PropTypeDefaultDescription
buttonVariantThe variant of a Button'ghost'The variant of the two month buttons
showOutsideDaysbooleantrueShows 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
localeLocaledateLocale of the Summit ProviderThe 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.

On this page