Skip to main content
PROYECTOVIVIANA

Calendar

A calendar displays a grid of days organized into weeks and months. Users can select a single date by clicking on a day cell. Calendars are useful for date selection in scheduling, booking, and form contexts.

Import

import { Calendar } from '@proyecto-viviana/solid-spectrum';
import { CalendarDateClass as CalendarDate } from '@proyecto-viviana/solid-stately';

Basic Date Selection

A simple calendar that allows users to pick a date. The selected date is tracked via a signal and displayed below the calendar.

Event 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

Selected date: None

const [selectedDate, setSelectedDate] = createSignal<DateValue | null>(null);

<Calendar
  aria-label="Event date"
  value={selectedDate()}
  onChange={setSelectedDate}
/>

<p>Selected: {selectedDate()?.toString() ?? "None"}</p>

Disabled Dates

Use the isDateUnavailable callback to prevent specific dates from being selected. Unavailable dates appear visually muted and cannot be clicked.

Appointment date, February 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

Feb 14-16 are unavailable

const unavailableDates = [
  new CalendarDate(2026, 2, 14),
  new CalendarDate(2026, 2, 15),
  new CalendarDate(2026, 2, 16),
];

const isDateUnavailable = (date: DateValue) =>
  unavailableDates.some(
    (d) => d.year === date.year && d.month === date.month && d.day === date.day
  );

<Calendar
  aria-label="Appointment date"
  isDateUnavailable={isDateUnavailable}
  defaultValue={new CalendarDate(2026, 2, 1)}
/>

Min/Max Date Constraints

Restrict the selectable date range by providing minValue and maxValue props. Dates outside the range are disabled and months beyond the range cannot be navigated to.

Date within 2026, 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

Only dates in 2026 are selectable

const minDate = new CalendarDate(2026, 1, 1);
const maxDate = new CalendarDate(2026, 12, 31);

<Calendar
  aria-label="Date within 2026"
  minValue={minDate}
  maxValue={maxDate}
/>

Props

PropTypeDefaultDescription
valueDateValue | null—The currently selected date (controlled)
onChange(date: DateValue) => void—Handler called when the selected date changes
defaultValueDateValue—The default selected date (uncontrolled)
minValueDateValue—The minimum selectable date
maxValueDateValue—The maximum selectable date
isDisabledbooleanfalseWhether the calendar is disabled
isDateUnavailable(date: DateValue) => boolean—Callback that returns whether a specific date is unavailable
aria-labelstring—Accessible label for the calendar
size'sm' | 'md' | 'lg''md'The visual size of the calendar
localestring—The locale to use for formatting month and day names

Accessibility

  • Uses a grid role with proper gridcell roles for each day
  • Full keyboard navigation: Arrow keys move between days, Page Up/Down change months
  • Today's date is visually indicated and announced to screen readers
  • Disabled and unavailable dates are announced as such via aria-disabled
  • Previous/next month buttons include descriptive aria-label attributes
  • Selected date is communicated via aria-selected