Skip to content

Calendar

Month grid for picking a date. RangeCalendar picks a start and end. Used inside DatePicker and DateRangePicker.

Inputv0.1.1experimentalWCAG 2.2 AAView spec

Delivery date, October 2026

27
28
29
30
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import { Calendar } from "@rdloom/react";

export default function CalendarSingleExample() {
  return (
    <Calendar aria-label="Delivery date" />
  );
}

Installation

npx rdloom add calendar

Copies the source into src/components/rdloom. Edit it freely: rdloom upgrade merges later versions into your changes. It needs react-aria-components; add --install to install them.

Use another registry client
npx shadcn@latest add https://rdloom.vimalbhatt.com/r/calendar.json

Works, but without upgrade tracking.

Usage

import { Calendar } from "@rdloom/react";

<Calendar aria-label="Delivery date" />

Range

Trip dates, October 2026

27
28
29
30
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import { RangeCalendar } from "@rdloom/react";

export default function CalendarRangeExample() {
  return (
    <RangeCalendar aria-label="Trip dates" />
  );
}

Two months

Stay, October to November 2026

27
28
29
30
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
1
2
3
4
5
import { RangeCalendar } from "@rdloom/react";

export default function CalendarTwoMonthsExample() {
  return (
    <RangeCalendar aria-label="Stay" visibleMonths={2} />
  );
}

Min max

Appointment, October 2026

27
28
29
30
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import { getLocalTimeZone, today } from "@internationalized/date";
import { Calendar } from "@rdloom/react";

export default function CalendarMinMaxExample() {
  const now = today(getLocalTimeZone());
  return (
    <Calendar aria-label="Appointment" minValue={now} maxValue={now.add({ days: 30 })} />
  );
}

With month year selectors

Birth date, June 1990

Month
Year
27
28
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import { parseDate } from "@internationalized/date";
import { Calendar } from "@rdloom/react";

export default function CalendarMonthYearSelectorsExample() {
  return (
    <div className="flex w-full justify-center">
      <Calendar aria-label="Birth date" captionLayout="dropdowns" defaultFocusedValue={parseDate("1990-06-15")} />
    </div>
  );
}

Bordered

Delivery date, October 2026

27
28
29
30
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import { Calendar } from "@rdloom/react";

export default function CalendarBorderedExample() {
  return (
    <div className="flex w-full justify-center">
      <Calendar aria-label="Delivery date" bordered />
    </div>
  );
}

Bordered with selectors

Appointment date, October 2026

Month
Year
27
28
29
30
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import { Calendar } from "@rdloom/react";

export default function CalendarBorderedWithSelectorsExample() {
  return (
    <div className="flex w-full justify-center">
      <Calendar aria-label="Appointment date" bordered captionLayout="dropdowns" />
    </div>
  );
}

API Reference

Defined by the spec. Components also accept the props of the React Aria component they wrap.

PropTypeDefault
visibleMonths

How many months to show side by side.

number1
captionLayout

label shows the month and year as a heading. dropdowns shows a Month and a Year select, so a far date is two choices away.

"label" | "dropdowns""label"
bordered

Draws the calendar inside a rounded border with padding.

booleanfalse
minValue

Earliest selectable date.

DateValuenone
maxValue

Latest selectable date.

DateValuenone
isDisabled

Disables every date.

booleanfalse

Accessibility

Role application, WCAG 2.2 AA. Tested with axe and keyboard tests; screen reader checks are in the audit checklist.

Keyboard

  • Arrow keys move by day and week
  • PageUp/PageDown change month, with Shift change year
  • Home/End jump to start/end of the week
  • Enter or Space selects

Screen readers announce

  • The month and year are announced when the calendar opens and when paging months
  • Each day announces its full date (Friday, 20 March 2026), plus selected or today
  • Dates outside min/max are announced as unavailable

What your code must do

  • Month heading is announced when it changes
  • Unavailable dates are exposed as disabled

Guidelines

Use it when

  • An always-visible calendar, such as a booking sidebar

Avoid it when

  • A compact form field: use DatePicker

Don't

  • Hiding which dates are unavailable until they're clicked

Design tokens

The semantic tokens this component uses. Change them once and every component follows; see Design tokens.

  • --rd-color-action-primary
  • --rd-color-action-on-primary
  • --rd-color-surface-subtle
  • --rd-color-text-default
  • --rd-color-text-muted
  • --rd-color-focus-ring
  • --rd-radius-control