Calendar Components
Proton provides calendar components for displaying and selecting dates, including a comprehensive mini calendar component.
MiniCalendar
A compact calendar component for date selection and display.
Location: components/miniCalendar/MiniCalendar.tsx
Basic Usage
import { useState } from 'react';
import MiniCalendar from '@proton/components/components/miniCalendar/MiniCalendar';
const MyCalendar = () => {
const [selectedDate, setSelectedDate] = useState(new Date());
return (
<MiniCalendar
date={selectedDate}
onSelectDate={setSelectedDate}
/>
);
};
Props
Currently displayed/selected date
Callback when a date is selected
onSelectDateRange
(range: DateTuple, resetRange?: boolean) => void
Callback when a date range is selected
Selected date range [startDate, endDate]
Current date for highlighting. Default: new Date()
Show previous/next month navigation. Default: true
Show “today” button. Default: false
Display week numbers. Default: false
Callback when month changes
First day of week (0=Sunday, 1=Monday). Default: 1
Custom day formatting function
getDayClassName
(date: Date) => string | undefined
Function to get custom className for specific days
Number of weeks to display. Default: 6
Number of days per week. Default: 7
Use fixed size cells. Default: false
Prevent focus from leaving component. Default: false
miniCalendarNextPrevButtonsColor
Color for navigation buttons. Default: weak
Array of dates to highlight
disableNonHighlightedDates
Disable dates not in highlightedDates. Default: false
Examples
Basic Calendar
Date Range Selection
With Constraints
With Week Numbers
With Today Button
Custom Styling
const [date, setDate] = useState(new Date());
<MiniCalendar
date={date}
onSelectDate={setDate}
/>
const [dateRange, setDateRange] = useState<[Date, Date]>([
new Date(),
addDays(new Date(), 7)
]);
<MiniCalendar
date={dateRange[0]}
dateRange={dateRange}
onSelectDateRange={setDateRange}
/>
<MiniCalendar
date={date}
onSelectDate={setDate}
min={new Date()}
max={addMonths(new Date(), 6)}
/>
<MiniCalendar
date={date}
onSelectDate={setDate}
displayWeekNumbers
weekStartsOn={1}
/>
<MiniCalendar
date={date}
onSelectDate={setDate}
hasToday
todayTitle="Go to today"
/>
<MiniCalendar
date={date}
onSelectDate={setDate}
getDayClassName={(date) => {
if (isWeekend(date)) return 'color-weak';
if (isHoliday(date)) return 'color-danger';
return undefined;
}}
highlightedDates={holidays}
/>
LocalizedMiniCalendar
MiniCalendar with automatic localization.
Location: components/miniCalendar/LocalizedMiniCalendar.tsx
Usage
import LocalizedMiniCalendar from '@proton/components/components/miniCalendar/LocalizedMiniCalendar';
const MyLocalizedCalendar = () => {
const [date, setDate] = useState(new Date());
return (
<LocalizedMiniCalendar
date={date}
onSelectDate={setDate}
/>
);
};
This component automatically provides localized month names, weekday names, and date formatting based on the user’s locale.
Header component for displaying calendar event dates.
Location: components/calendarEventDateHeader/
Usage
import CalendarEventDateHeader from '@proton/components/components/calendarEventDateHeader';
const MyEventHeader = () => {
return (
<CalendarEventDateHeader
startDate={new Date()}
endDate={addHours(new Date(), 2)}
/>
);
};
CalendarSelect
Dropdown for selecting calendars.
Location: components/calendarSelect/
Usage
import CalendarSelect from '@proton/components/components/calendarSelect';
const MyCalendarSelect = () => {
const [selectedCalendar, setSelectedCalendar] = useState(null);
return (
<CalendarSelect
value={selectedCalendar}
onChange={setSelectedCalendar}
calendars={calendars}
/>
);
};
Best Practices
Date Range Selection
const DateRangePicker = () => {
const [range, setRange] = useState<[Date, Date] | null>(null);
const handleRangeSelect = (newRange: [Date, Date], reset?: boolean) => {
if (reset) {
// Start new range
setRange([newRange[0], newRange[0]]);
} else {
setRange(newRange);
}
};
return (
<div>
<MiniCalendar
date={range?.[0] || new Date()}
dateRange={range || undefined}
onSelectDateRange={handleRangeSelect}
/>
{range && (
<div className="mt-4">
<p>From: {format(range[0], 'PP')}</p>
<p>To: {format(range[1], 'PP')}</p>
</div>
)}
</div>
);
};
Disabling Dates
const BookingCalendar = () => {
const [date, setDate] = useState(new Date());
const availableDates = getAvailableDates(); // Array of available dates
return (
<MiniCalendar
date={date}
onSelectDate={setDate}
highlightedDates={availableDates}
disableNonHighlightedDates
getDayClassName={(date) => {
if (!isAvailable(date)) return 'disabled';
return undefined;
}}
/>
);
};
const CustomCalendar = () => {
const [date, setDate] = useState(new Date());
return (
<MiniCalendar
date={date}
onSelectDate={setDate}
formatDay={(date) => {
// Custom day formatting
return format(date, 'd');
}}
getDayClassName={(date) => {
// Highlight special dates
if (isToday(date)) return 'font-bold color-primary';
if (isWeekend(date)) return 'color-weak';
return undefined;
}}
/>
);
};
Month Navigation
const NavigableCalendar = () => {
const [currentMonth, setCurrentMonth] = useState(new Date());
const [selectedDate, setSelectedDate] = useState<Date | null>(null);
const handleMonthChange = (newDate: Date) => {
setCurrentMonth(newDate);
};
return (
<div>
<div className="flex items-center justify-between mb-4">
<h3>{format(currentMonth, 'MMMM yyyy')}</h3>
</div>
<MiniCalendar
date={currentMonth}
onSelectDate={setSelectedDate}
onMonthChange={handleMonthChange}
hasCursors
/>
{selectedDate && (
<p className="mt-4">
Selected: {format(selectedDate, 'PP')}
</p>
)}
</div>
);
};
Accessibility
<MiniCalendar
date={date}
onSelectDate={setDate}
// Calendar already includes proper ARIA labels
// Month label is automatically set
// Navigation buttons have proper titles
/>
The MiniCalendar component includes:
- Proper ARIA labels for navigation
- Keyboard navigation support
- Screen reader announcements
- Accessible date selection
Integration Examples
With Modal
const DatePickerModal = ({ open, onClose, onSelect }) => {
const [tempDate, setTempDate] = useState(new Date());
const handleConfirm = () => {
onSelect(tempDate);
onClose();
};
return (
<Modal open={open} onClose={onClose} size="small">
<ModalHeader title="Select Date" />
<ModalContent>
<MiniCalendar
date={tempDate}
onSelectDate={setTempDate}
/>
</ModalContent>
<ModalFooter>
<Button onClick={onClose}>Cancel</Button>
<Button onClick={handleConfirm} color="norm">Confirm</Button>
</ModalFooter>
</Modal>
);
};
With Dropdown
const DatePickerDropdown = () => {
const [date, setDate] = useState(new Date());
const [isOpen, setIsOpen] = useState(false);
const anchorRef = useRef<HTMLButtonElement>(null);
const handleSelectDate = (newDate: Date) => {
setDate(newDate);
setIsOpen(false);
};
return (
<>
<Button ref={anchorRef} onClick={() => setIsOpen(!isOpen)}>
{format(date, 'PP')}
</Button>
<Dropdown
isOpen={isOpen}
anchorRef={anchorRef}
onClose={() => setIsOpen(false)}
>
<MiniCalendar
date={date}
onSelectDate={handleSelectDate}
/>
</Dropdown>
</>
);
};
Source Code
View source:
- MiniCalendar:
packages/components/components/miniCalendar/MiniCalendar.tsx:1
- LocalizedMiniCalendar:
packages/components/components/miniCalendar/LocalizedMiniCalendar.tsx:1
- MonthDays:
packages/components/components/miniCalendar/MonthDays.tsx:1