# Calendar

A month grid for picking a date, several dates or a range of them.

Source: [calendar.tsx](https://github.com/jakejarvis/jarvis-ui/blob/main/src/components/ui/calendar.tsx)

```tsx
import * as React from "react";

import { Calendar } from "@/components/ui/calendar";

export default function CalendarBasic() {
  const [date, setDate] = React.useState<Date | undefined>(new Date(2025, 5, 12));

  return (
    <Calendar
      mode="single"
      selected={date}
      onSelect={setDate}
      defaultMonth={date}
      className="rounded-md border-[0.5px] border-border-muted"
    />
  );
}
```

## Installation

Add the registry, once per project:

```bash
npx shadcn@latest registry add @jarvis=https://ui.jarv.is/r/{name}.json
```

Then add the component:

```bash
npx shadcn@latest add @jarvis/calendar
```

## Usage

```tsx
import * as React from "react";

import { Calendar } from "@/components/ui/calendar";

export function DueDateCalendar() {
  const [date, setDate] = React.useState<Date | undefined>();

  return <Calendar mode="single" selected={date} onSelect={setDate} />;
}
```

Calendar is built on [DayPicker](https://daypicker.dev). `mode` is `"single"`, `"multiple"` or
`"range"`. For a field that opens a calendar, use a [Date Picker](https://ui.jarv.is/components/date-picker.md).

Calendar highlights today, which can differ between the server and the browser. If you render it
on the server, give it a `defaultMonth` that doesn't include today, or render it only in the
browser.

## Examples

### Range

`numberOfMonths` shows more than one month.

```tsx
import type { DateRange } from "@daypicker/react";
import * as React from "react";

import { Calendar } from "@/components/ui/calendar";

export default function CalendarRange() {
  const [range, setRange] = React.useState<DateRange | undefined>({
    from: new Date(2025, 5, 26),
    to: new Date(2025, 6, 4),
  });

  return (
    <Calendar
      mode="range"
      selected={range}
      onSelect={setRange}
      defaultMonth={range?.from}
      numberOfMonths={2}
      showOutsideDays={false}
      className="rounded-md border-[0.5px] border-border-muted"
    />
  );
}
```

### Multiple dates

`max` limits how many dates can be picked.

```tsx
import * as React from "react";

import { Calendar } from "@/components/ui/calendar";

export default function CalendarMultiple() {
  const [dates, setDates] = React.useState<Date[] | undefined>([
    new Date(2025, 5, 3),
    new Date(2025, 5, 10),
    new Date(2025, 5, 17),
  ]);

  return (
    <Calendar
      mode="multiple"
      selected={dates}
      onSelect={setDates}
      defaultMonth={new Date(2025, 5)}
      className="rounded-md border-[0.5px] border-border-muted"
    />
  );
}
```

### Month and year dropdowns

`captionLayout="dropdown"` adds month and year menus. `startMonth` and `endMonth` bound them.

```tsx
import * as React from "react";

import { Calendar } from "@/components/ui/calendar";

export default function CalendarDropdowns() {
  const [date, setDate] = React.useState<Date | undefined>(new Date(1992, 2, 14));

  return (
    <Calendar
      mode="single"
      selected={date}
      onSelect={setDate}
      defaultMonth={date}
      captionLayout="dropdown"
      startMonth={new Date(1930, 0)}
      endMonth={new Date(2025, 11)}
      className="rounded-md border-[0.5px] border-border-muted"
    />
  );
}
```

### Disabled days

`disabled` takes dates, ranges, `{ before }`, `{ after }` and `{ dayOfWeek }` matchers, or a list
of them.

```tsx
import * as React from "react";

import { Calendar } from "@/components/ui/calendar";

const booked = [new Date(2025, 5, 10), new Date(2025, 5, 11), new Date(2025, 5, 19)];

export default function CalendarDisabled() {
  const [date, setDate] = React.useState<Date | undefined>(new Date(2025, 5, 12));

  return (
    <Calendar
      mode="single"
      selected={date}
      onSelect={setDate}
      defaultMonth={date}
      disabled={[{ dayOfWeek: [0, 6] }, ...booked]}
      className="rounded-md border-[0.5px] border-border-muted"
    />
  );
}
```

### Week numbers

`showWeekNumber` adds a column of week numbers.

```tsx
import * as React from "react";

import { Calendar } from "@/components/ui/calendar";

export default function CalendarWeekNumbers() {
  const [date, setDate] = React.useState<Date | undefined>(new Date(2025, 5, 12));

  return (
    <Calendar
      mode="single"
      selected={date}
      onSelect={setDate}
      defaultMonth={date}
      showWeekNumber
      className="rounded-md border-[0.5px] border-border-muted"
    />
  );
}
```

### Locale

Pass a locale from `@daypicker/react/locale` to translate it.

```tsx
import { es } from "@daypicker/react/locale";
import * as React from "react";

import { Calendar } from "@/components/ui/calendar";

export default function CalendarLocale() {
  const [date, setDate] = React.useState<Date | undefined>(new Date(2025, 5, 12));

  return (
    <Calendar
      mode="single"
      selected={date}
      onSelect={setDate}
      defaultMonth={date}
      locale={es}
      className="rounded-md border-[0.5px] border-border-muted"
    />
  );
}
```

## Props

`Calendar` takes [DayPicker's props](https://daypicker.dev/api/type-aliases/DayPickerProps). Pass
`classNames` or `components` to override a part. Set `--cell-size` in `className` to resize the
days, as in `[--cell-size:--spacing(8)]`.

`CalendarDayButton` is the day button. Wrap it in your own `DayButton` to add content to each day.

| Part | Extends |
| --- | --- |
| `Calendar` | `DayPicker` |
| `CalendarDayButton` | `DayButton` |
