You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

9.2 KiB

react-calendario

A modern, flexible, and highly customizable calendar component library for React with TypeScript support.

🆕 Version 1.4.0 Features

  • 📅 Today in Any State: Define custom colors for today's date in any state (default, active, rangeStart, etc.)
  • ✏️ Header Text Transform: Custom function to transform day name display (e.g., dayName => dayName.slice(0, 2))
  • 🌍 International Locale Support: Full internationalization with 50+ languages via date-fns
  • 🎨 Three-Dimensional Color Schemes: Control colors by week split (weekday/weekend), relative (today/anyday), and state
  • 🎯 Enhanced Weekend Support: Distinct colors for weekends in all selection states

📖 View the complete Usage Guide for detailed examples of the new features!

Features

  • 📅 Multiple Views: Year, Month, Week, and custom date ranges
  • 🎨 Highly Customizable: Multiple header styles, sizes, and visual options
  • 🔍 Interactive: Date selection, range picking, and click handlers
  • 📱 Responsive: Works on all screen sizes
  • 🎯 TypeScript: Full type safety and IntelliSense support
  • 🌍 i18n Support: Locale-aware with date-fns locales
  • 🎨 Advanced Theming: Comprehensive color customization system
  • 📦 Lightweight: Minimal dependencies

Installation

npm install react-calendario date-fns classnames

or

yarn add react-calendario date-fns classnames

Quick Start

import { Month } from 'react-calendario';
import 'react-calendario/dist/react-calendario.css';

function App() {
  return (
    <Month
      date={new Date()}
      dayHeaderStyle="expanded"
      size="l"
    />
  );
}

With Locale and Custom Colors (v1.1.0+)

import { Year } from 'react-calendario';
import { fr } from 'date-fns/locale';

const colorScheme = [
  { 
    type: 'weekday', 
    state: 'default',
    colors: { 
      header: { backgroundColor: '#2c3e50', color: '#ffffff' },
      content: { backgroundColor: '#ffffff', color: '#2c3e50' }
    }
  },
  { 
    type: 'weekend', 
    state: 'default',
    colors: {
      header: { backgroundColor: '#95a5a6', color: '#ffffff' },
      content: { backgroundColor: '#ecf0f1', color: '#34495e' }
    }
  }
  // ... more states
];

<Year
  year={2025}
  locale={fr}  // French locale
  colorScheme={colorScheme}  // Custom colors
/>

Components

Year

Display a full year calendar with customizable month grid.

import { Year } from 'react-calendario';

<Year
  year={2024}
  dayHeaderStyle="tiny"
  monthCutoff="truncate"
  size="m"
  fontProportion={100}
  magnify={true}
/>

Month

Display a single month with various layout options.

import { Month } from 'react-calendario';

<Month
  date={new Date()}
  dayHeaderStyle="expanded"
  direction="column"
  monthCutoff="dimmed"
  size="xl"
/>

Week

Display a single week view.

import { Week } from 'react-calendario';

<Week
  startDate={new Date()}
  headerStyle="compacted"
  referenceMonth={0}
  size="l"
/>

DateRange

Display a custom date range with optional selection and interactivity.

import { DateRange } from 'react-calendario';

<DateRange
  from={new Date(2024, 0, 15)}
  to={new Date(2024, 0, 22)}
  included={true}
  selected={true}
  headerStyle="tiny"
  size="l"
  onDateClick={(date) => console.log('Clicked:', date)}
  activeDates={[new Date(2024, 0, 17)]}
/>

Props

Common Props

All components share these common props:

Prop Type Default Description
size 'xl' | 'l' | 'm' | 's' | 'xs' | 'xxs' 'l' Day cell size
fontProportion number 100 Font size percentage (10-100)
magnify boolean false Enable magnify effect on selection
weekendDays number[] [6, 0] Weekend day indices (0=Sunday)

Header Styles

Style Description
'expanded' Full day names (e.g., "Monday")
'compacted' Three-letter abbreviations (e.g., "Mon")
'tiny' Two-letter abbreviations (e.g., "Mo")
'none' Numbers only

Size Options

  • 'xxs': Extra extra small (20px height, 1:1.5 header:content ratio)
  • 'xs': Extra small (24px height)
  • 's': Small (28px height)
  • 'm': Medium (32px height)
  • 'l': Large (36px height)
  • 'xl': Extra large (48px height)

Advanced Usage

Date Range Selection

import { useState } from 'react';
import { Year } from 'react-calendario';

function DateRangePicker() {
  const [dateRange, setDateRange] = useState({
    startDate: null,
    endDate: null,
    selecting: false,
    hoverDate: null,
    anchorDate: null
  });

  const handleDateSelect = (date) => {
    // Your range selection logic
  };

  return (
    <Year
      year={2024}
      dateRange={dateRange}
      onDateSelect={handleDateSelect}
      onDateHover={(date) => setDateRange(prev => ({ ...prev, hoverDate: date }))}
    />
  );
}

Interactive Date Range with Active States

import { DateRange } from 'react-calendario';

function InteractiveCalendar() {
  const [activeDates, setActiveDates] = useState([]);

  const handleDateClick = (date) => {
    setActiveDates(prev => {
      const exists = prev.some(d => d.getTime() === date.getTime());
      return exists 
        ? prev.filter(d => d.getTime() !== date.getTime())
        : [...prev, date];
    });
  };

  return (
    <DateRange
      from={new Date(2024, 0, 1)}
      to={new Date(2024, 0, 31)}
      onDateClick={handleDateClick}
      activeDates={activeDates}
    />
  );
}

Customization

1. Built-in Props

The easiest way to customize the calendar is through props:

<Month
  date={new Date()}
  dayHeaderStyle="tiny"      // Header style
  size="xl"                  // Cell size
  fontProportion={80}        // Font size (10-100)
  monthCutoff="dimmed"       // How to show other month's days
  weekendDays={[0, 6]}       // Which days are weekends
  magnify={true}             // Magnify effect on selection
/>

2. Theming with CSS

The library uses CSS modules with predictable class names (prefixed with rc_). While the internal Sass variables don't support CSS custom properties due to color manipulation functions, you can still customize the appearance through CSS overrides:

/* Override component styles */
.rc_Day__Container {
  background: var(--my-bg-color, white);
  color: var(--my-text-color, #2c2c2c);
  border-color: var(--my-border-color, #f0f0f0);
}

.rc_Day__Header {
  background: var(--my-header-bg, #2c2c2c);
  color: var(--my-header-text, white);
}

/* Custom theme example */
[data-theme="dark"] {
  --my-bg-color: #1a1a1a;
  --my-text-color: #ffffff;
  --my-border-color: #333333;
  --my-header-bg: #2a2a2a;
  --my-header-text: #ffffff;
}

/* Selected state */
.rc_Day__Container--selected {
  background: var(--my-selected-bg, #e3f2fd) !important;
}

/* Hover state */
.rc_Day__Container--interactive:hover {
  background: var(--my-hover-bg, #f5f5f5);
}

3. Custom Styling

The components use CSS modules with predictable class names:

/* Target specific components */
.rc_Month__Container {
  /* Custom month container styles */
}

.rc_Day__Container {
  /* Custom day styles */
}

.rc_Day__Container--selected {
  /* Custom selected day styles */
}

.rc_Day__Container--active {
  /* Custom active day styles */
}

/* Custom weekend styling */
.rc_Day__Container--greyed {
  opacity: 0.5;
}

4. Size Customization

Create custom sizes beyond the built-in options:

/* Custom size classes */
.rc_Day--custom .rc_Day__Header {
  height: 64px;
  font-size: 1.2rem;
}

.rc_Day--custom .rc_Day__Content {
  height: 128px; /* 2x header height */
}

Then use it:

<Month size="custom" />

5. Complete Theme Example

/* Purple theme */
:root {
  --rc-primary: #7c3aed;
  --rc-primary-dark: #6d28d9;
  --rc-selected: #ede9fe;
  --rc-selected-hover: #ddd6fe;
  --rc-text: #1f2937;
  --rc-hover: #f3f4f6;
}

/* Rounded corners */
.rc_Day__Container {
  border-radius: 12px;
  overflow: hidden;
}

/* Spacing between days */
.rc_Week__Container {
  gap: 4px;
}

/* Custom header style */
.rc_Day__Header {
  text-transform: uppercase;
  letter-spacing: 0.05em;
  font-weight: 600;
}

6. Advanced Customization

For complete control, you can:

  1. Import SCSS variables (if using Sass):
@use 'react-calendario/styles/variables' as rc;

.custom-calendar {
  padding: rc.$week-wrapper-padding;
}
  1. Override specific component styles:
/* Remove borders */
.rc_Day__Container {
  border: none;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

/* Custom hover effect */
.rc_Day__Container--interactive:hover {
  transform: scale(1.05);
  transition: transform 0.2s;
}
  1. Customize date number rendering:
/* Circle style for dates */
.rc_DayNumber__Container {
  background: #f0f0f0;
  border-radius: 50%;
  width: 32px;
  height: 32px;
  margin: auto;
}

TypeScript

Full TypeScript support with exported types:

import type { 
  DateRange, 
  HeaderStyle, 
  DaySize,
  MonthCutoffType 
} from 'react-calendario';

License

MIT

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.