Skip to main content
The Calendar component provides a date picker interface with support for single date selection, date ranges, month/year navigation, and extensive customization options.

Basic Usage

import { Calendar } from 'reshaped';
import { useState } from 'react';

function Example() {
  const [value, setValue] = useState(new Date());
  
  return (
    <Calendar 
      value={value}
      onChange={({ value }) => setValue(value)}
    />
  );
}

Range Selection

import { Calendar } from 'reshaped';
import { useState } from 'react';

function RangeExample() {
  const [value, setValue] = useState({ start: null, end: null });
  
  return (
    <Calendar 
      range
      value={value}
      onChange={({ value }) => setValue(value)}
    />
  );
}

With Min/Max Dates

import { Calendar } from 'reshaped';

function RestrictedCalendar() {
  const today = new Date();
  const nextMonth = new Date();
  nextMonth.setMonth(nextMonth.getMonth() + 1);
  
  return (
    <Calendar 
      min={today}
      max={nextMonth}
      value={today}
      onChange={({ value }) => console.log(value)}
    />
  );
}

Multiple Months

import { Calendar } from 'reshaped';

function MultiMonthCalendar() {
  return (
    <Calendar 
      monthsToRender={2}
      value={new Date()}
      onChange={({ value }) => console.log(value)}
    />
  );
}

Props

value
Date | null | { start: Date | null, end: Date | null }
Current selected date value, enables controlled mode. Type depends on range prop
defaultValue
Date | { start: Date | null, end: Date | null }
Default selected date value, enables uncontrolled mode
range
boolean
default:"false"
Enable range selection mode
onChange
(args: { value }) => void
Callback when date selection changes. Value type depends on range prop
month
Date
Month to display. Used in controlled mode and should be updated using the onMonthChange callback
defaultMonth
Date
default:"Date.now()"
Default month to display. Used in uncontrolled mode
onMonthChange
(args: { date: Date }) => void
Callback when the month changes
min
Date
Minimum date that can be selected
max
Date
Maximum date that can be selected
monthsToRender
number
default:"1"
Number of months to render at the same time
firstWeekDay
number
default:"1"
First day of the week (0 = Sunday, 1 = Monday, etc.)
selectedDates
Date[]
Additional dates that should appear as selected
disabledDates
Date[]
Dates that should be disabled
renderWeekDay
(args: { weekDay: number, date: Date }) => string
Render a custom weekday label, can be used for localization
renderMonthLabel
(args: { month: number, date: Date }) => string
Render a custom month label, can be used for localization
renderSelectedMonthLabel
(args: { date: Date }) => string
Render a custom selected month label, can be used for localization
renderDateSlot
(args: { date: Date, selected: boolean }) => ReactNode
Render custom content under each date number
renderDateAriaLabel
(args: { date: Date }) => string
Dynamic aria label for each date cell
renderMonthAriaLabel
(args: { month: number }) => string
Dynamic aria label for each month element
previousMonthAriaLabel
string
Aria label for the previous month button
nextMonthAriaLabel
string
Aria label for the next month button
previousYearAriaLabel
string
Aria label for the previous year button
nextYearAriaLabel
string
Aria label for the next year button
monthSelectionAriaLabel
string
Aria label for the month selection button

When to Use

  • Date Pickers: Allow users to select dates from a visual calendar
  • Booking Systems: Select check-in and check-out dates
  • Event Scheduling: Choose event dates or date ranges
  • Filtering: Filter data by date ranges
  • Reports: Select date ranges for reports

Composition Patterns

Date Range Picker

import { Calendar, Text, Stack, View } from 'reshaped';
import { useState } from 'react';

function DateRangePicker() {
  const [value, setValue] = useState({ start: null, end: null });
  
  return (
    <Stack gap={3}>
      <Calendar 
        range
        value={value}
        onChange={({ value }) => setValue(value)}
      />
      {value.start && value.end && (
        <View padding={3} backgroundColor="neutral-faded" borderRadius="medium">
          <Text>
            Selected: {value.start.toLocaleDateString()} - {value.end.toLocaleDateString()}
          </Text>
        </View>
      )}
    </Stack>
  );
}

Localized Calendar

import { Calendar } from 'reshaped';

function LocalizedCalendar() {
  return (
    <Calendar
      value={new Date()}
      onChange={({ value }) => console.log(value)}
      firstWeekDay={0}
      renderWeekDay={({ date }) => 
        date.toLocaleDateString('es-ES', { weekday: 'short' })
      }
      renderMonthLabel={({ date }) => 
        date.toLocaleDateString('es-ES', { month: 'long' })
      }
      renderSelectedMonthLabel={({ date }) => 
        date.toLocaleDateString('es-ES', { month: 'long', year: 'numeric' })
      }
      previousMonthAriaLabel="Mes anterior"
      nextMonthAriaLabel="Próximo mes"
    />
  );
}

Calendar with Event Indicators

import { Calendar, View } from 'reshaped';
import { useState } from 'react';

function EventCalendar({ events }) {
  const [value, setValue] = useState(null);
  const eventDates = events.map(e => new Date(e.date));
  
  return (
    <Calendar
      value={value}
      onChange={({ value }) => setValue(value)}
      selectedDates={eventDates}
      renderDateSlot={({ date, selected }) => {
        const hasEvent = eventDates.some(d => 
          d.toDateString() === date.toDateString()
        );
        return hasEvent ? (
          <View 
            width={1}
            height={1}
            borderRadius="full"
            backgroundColor="primary"
          />
        ) : null;
      }}
    />
  );
}

Disabled Dates Calendar

import { Calendar } from 'reshaped';

function BookingCalendar({ bookedDates }) {
  const disabledDates = bookedDates.map(d => new Date(d));
  
  return (
    <Calendar
      value={null}
      onChange={({ value }) => console.log('Selected:', value)}
      disabledDates={disabledDates}
      min={new Date()}
    />
  );
}

Multi-Month View

import { Calendar, Stack } from 'reshaped';
import { useState } from 'react';

function WideCalendar() {
  const [value, setValue] = useState({ start: null, end: null });
  
  return (
    <Stack gap={4}>
      <Calendar
        range
        monthsToRender={3}
        value={value}
        onChange={({ value }) => setValue(value)}
      />
    </Stack>
  );
}

Build docs developers (and LLMs) love