// preview in
saved for every page

Calendar

Shows a month and lets people pick one day with the mouse, touch or keyboard. Use it when the date is near and seeing the week matters, such as an appointment or a delivery.

Built on React AriaPattern WAI-ARIA GridClient componentSource ↗
minimal · light · #3fa34d

Appointment 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
weekdayStyle
firstDayOfWeek
readOnly
disabled

Installation

Set up Camaleo once (Installation), then import what you need. Dates are @internationalized/date objects, re-exported from Camaleo.

import { Calendar, CalendarDate, isWeekend } from "@camaleo/react";

Anatomy

A header with the month and two arrows, the grid of days and an optional footer. Every part has a data-slot you can target from CSS.

title‹ ›gridfooter
[data-slot="calendar"][data-slot="calendar-title"] · [data-slot="calendar-nav-button"] · [data-slot="calendar-footer"][data-slot="calendar-grid"] · [data-slot="calendar-cell"]

Examples

Every example is a real file you can copy. They all wear the skin, mode and brand from the bar above.

minimal · light · #3fa34d

Appointment 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

Move-in 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

Move-in: Wednesday, October 14, 2026

Controlled, with a summary

Pick a day. value and onChange keep the date in your state, and the sentence below spells it out with the weekday.

Booking window, 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
Bookings open Oct 5 to Nov 20.

Min and max

minValue and maxValue disable the days outside the window, and the arrows stop at its first and last month.

Pickup 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
Pickups Monday to Friday.

Weekends unavailable

isDateUnavailable with isWeekend follows the locale. Unavailable days stay focusable and are announced as unavailable, so say why in the footer.

Recording studio, 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
Struck-out days are fully booked.

Booked days

Return true for the days your API says are full. The strike-through is not the only signal: the footer explains it in words.

Sprint planning, October 2026

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
Sprints start on Monday.

Week starts on Monday

The locale sets the first day: Sunday in the US and Brazil. firstDayOfWeek="mon" matches a team that plans in ISO weeks.

Confirmed 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
To change it, call (415) 555-0132.

Read-only

readOnly shows a confirmed date that people can still browse and read, unlike disabled, which drops it from the tab order.

Year-end party, December 2026

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
Nothing picked yet.

Open on another month

With no value the calendar opens on today. defaultFocusedValue opens it on the month people need, and renders the same on server and client.

In context

Calendars sit inside bookings and checkouts. These are whole pieces of UI you can copy, in the skin you picked.

Book a consultation

Dr. Helen Park · Dermatology

Appointment date, November 2026

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

Available times

Book a consultationCard · Calendar · ToggleGroup · Button

Choose a delivery day

Free on weekdays. Order before 6 PM.

Delivery day, November 2026

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
Tue, Nov 3Free
Delivery dayCard · Calendar · Button

Schedule a payment

Electricity bill · $142.80 · due Nov 10

Payment date, November 2026

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
Nov 6, 2026on time
Schedule a paymentCard · Calendar · Badge · Button

Guidelines

Available 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
Closed on weekends.
DoSay why days are unavailable.

A short line in the footer answers the question before people click around.

Available 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
Don’tUnavailable days with no reason.

People try them one by one, and a screen reader only hears "unavailable".

Pickup 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
DoA calendar for dates in the next weeks.

The month on screen is the one people pick from.

Date of birth, 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
Don’tA calendar for a date of birth.

Reaching 1994 takes hundreds of clicks. Use a Date field and let people type it.

Props

PropTypeDefaultDescription
classNamestring—Class names for the root element.
styleCSSProperties—Inline styles for the root element.
disabledboolean—Disables every day and the arrows, and removes the grid from the tab order.
readOnlybooleanfalseShows the value without letting people change it. Days stay focusable.
invalidboolean—Marks the selection as invalid, for errors that come from your app.
localestring—BCP 47 locale for month names, weekdays and the first day of the week, e.g. "pt-BR". Defaults to the nearest I18nProvider or the browser.
weekdayStyleWeekdayStyle"short"How the weekday headers are written: "narrow", "short" (default) or "long".
previousLabelstring—Accessible name of the previous-month arrow. React Aria's localized "Previous" by default.
nextLabelstring—Accessible name of the next-month arrow. React Aria's localized "Next" by default.
footerReactNode—Content under the grid: the chosen date, a legend or a price.
valueDateValue | null—The current value (controlled).
defaultValueDateValue | null—The default value (uncontrolled).
onChange(value: DateValue) => void—Handler that is called when the value changes.
minValueDateValue | null—The minimum allowed date that a user may select.
maxValueDateValue | null—The maximum allowed date that a user may select.
autoFocusbooleanfalseWhether to automatically focus the calendar when it mounts.
focusedValueDateValue | null—Controls the currently focused date within the calendar.
defaultFocusedValueDateValue | null—The date that is focused when the calendar first mounts (uncontrolled).
onFocusChange(date: CalendarDate) => void—Handler that is called when the focused date changes.
firstDayOfWeek"sun" | "mon" | "tue" | "wed" | "thu" | "fri" | "sat"—The day that starts the week.
isDateUnavailable(date: DateValue) => boolean—Callback that is called for each date of the calendar. If it returns true, then the date is unavailable.

Dates are CalendarDate objects from @internationalized/date, re-exported by Camaleo with parseDate, today and isWeekend. React Aria's other calendar props pass through, such as pageBehavior and createCalendar.

Styling hooks

Restyle it without forking: target the attributes, or set the tokens on a parent, a skin or the calendar itself.

Attributes

data-slot"calendar" · "calendar-header" · "calendar-grid" · "calendar-cell" · "calendar-footer"
data-selectedpresent on the chosen day
data-todaypresent on today's date
data-unavailablepresent on days isDateUnavailable rejects
data-disabledpresent on days outside min/max, and on the root when disabled
data-outside-month · data-focus-visiblepresent on days of the next or previous month · on keyboard focus

Tokens it reads

Color

--cml-accent--cml-accent-fg--cml-accent-text--cml-border--cml-border-control--cml-button-outline-bg--cml-button-outline-border--cml-button-outline-shadow--cml-button-solid-shadow--cml-card-border--cml-card-shadow--cml-fg--cml-fg-muted--cml-fg-secondary--cml-focus-offset--cml-focus-ring--cml-focus-width--cml-radius-surface--cml-surface-raised

Shape & size

--cml-border-width--cml-font-size-help--cml-radius-control-sm

Type & motion

--cml-duration-fast--cml-ease-standard--cml-font-control--cml-font-display--cml-font-label--cml-font-weight-display

This component only

--cml-button-solid-image--cml-calendar-bg--cml-calendar-cell-font--cml-calendar-cell-radius--cml-calendar-cell-size--cml-calendar-cell-size-font--cml-calendar-cell-weight--cml-calendar-header-fg--cml-calendar-header-size--cml-calendar-header-tracking--cml-calendar-header-transform--cml-calendar-header-weight--cml-calendar-nav-radius--cml-calendar-nav-size--cml-calendar-padding--cml-calendar-radius--cml-calendar-range-border--cml-calendar-range-fg--cml-calendar-selected-bg--cml-calendar-selected-border--cml-calendar-selected-fg--cml-calendar-title-font--cml-calendar-title-size--cml-calendar-title-tracking--cml-calendar-title-transform--cml-calendar-title-weight--cml-calendar-today-bg--cml-calendar-today-border--cml-calendar-today-fg--cml-calendar-width--cml-corner-shape--cml-disabled-opacity--cml-item-highlight
/* round day cells, only in the booking flow */
.booking [data-slot="calendar"] {
  --cml-calendar-cell-radius: 999px;
}

Accessibility

Arrow keysMove focus one day, or one week up and down.
Home / EndMove focus to the first or last day of the month.
Page Up / Page DownMove to the previous or next month. With Shift, by a year.
Enter / SpaceSelects the focused day.
TabMoves between the arrows and the grid.
Was this page helpful? · Edit this page on GitHub