Calendar
A calendar component for selecting dates and date ranges.
1<Calendar />
Anatomy
Import and assemble the component:
1import { Calendar, RangePicker, DatePicker } from '@raystack/apsara'23<Calendar />45<RangePicker />67<DatePicker />
Usage
Calendar is the grid itself. DatePicker and RangePicker wrap it in a field and a popover, and all three share the props below.
Layout and appearance
Number of months, dropdown nav, loading state, footer.
1<Calendar2 numberOfMonths={2}3 defaultMonth={new Date(2025, 5, 1)}4 showWeekNumber={false}5 weekStartsOn={1}6 showOutsideDays={false}7/>
Behaviour and data
Tooltips, disabled days, timezone, controlled month navigation.
1<Calendar2 showTooltip3 tooltipMessages={{4 "15-06-2026": "Holiday",5 "20-06-2026": "Team off-site",6 }}7/>
Custom date information
You can display custom components above each date using the dateInfo prop. The keys should be date strings in "dd-MM-yyyy" format, and the values are React components that will be rendered above the date number.
1<Calendar2 numberOfMonths={2}3 dateInfo={{4 [dayjs().format("DD-MM-YYYY")]: (5 <Flex6 align="center"7 gap={2}8 style={{9 fontSize: "8px",10 color: "var(--rs-color-foreground-base-secondary)",11 }}12 >13 <Info style={{ width: "8px", height: "8px" }} />14 <Text style={{ fontSize: "8px" }} color="secondary">15 25%
Range picker
Selects a date range across two inputs. The grid uses a state machine that branches on the current from / to:
- Empty: first click sets
fromand advances focus to the end input. - Only
fromset: clicking a later date completes the range and closes the popover; clicking an earlier date resetsfrom. - Both set: clicking again restarts: the new date becomes
from,toclears.
onSelect fires on every step (the shape is { from?: Date; to?: Date }, partial during interaction). Gate on range.to if you only want the completed-range event.
1<RangePicker />
Date picker
Single-date selection with a typable input. The popover opens on focus; pressing Enter, blurring, or clicking outside commits the value and fires onSelect.
1<DatePicker slotProps={{ input: { size: "medium" } }} />
Controlled
Pass selected with onSelect to own the date. This is needed when the value comes from a form or has to be set from elsewhere, like a Today button.
1(function ControlledCalendar() {2 const [date, setDate] = React.useState(new Date());34 return (5 <Flex direction="column" align="center" gap={5}>6 <Calendar mode="single" selected={date} onSelect={setDate} />7 <Flex align="center" gap={4}>8 <Text size="small" variant="secondary">9 {date ? dayjs(date).format("D MMM YYYY") : "nothing selected"}10 </Text>11 <Button12 size="small"13 variant="outline"14 onClick={() => setDate(new Date())}15 >
API Reference
The bare grid, and the two pickers built on top of it.
Calendar
Renders a standalone calendar for date selection.
Prop
Type
RangePicker
The RangePicker exposes its startInput, endInput, calendar and popover slots through the slotProps prop.
Prop
Type
DatePicker
The DatePicker exposes its input, calendar and popover slots through the slotProps prop.
Prop
Type
Slots
Every rendered part carries a stable data-slot attribute for styling and testing:
| Slot | Element |
|---|---|
calendar | The root calendar surface |
calendar-nav-previous | The previous-month navigation button |
calendar-nav-next | The next-month navigation button |
calendar-dropdown | The month/year dropdown trigger (when captionLayout="dropdown") |
calendar-dropdown-content | The dropdown's option list (when the dropdown is open) |
calendar-month-grid | Wrapper around the day grid and its skeleton |
calendar-grid-table | The <table> that holds the days |
calendar-grid-skeleton | The loading skeleton shown over the grid |
calendar-day | The <button> for a single day |
calendar-day-info | Extra info shown inside a day (when dateInfo resolves for that day) |
calendar-day-number | The day number inside a day button |
calendar-day-tooltip | The tooltip shown on hover (when showTooltip and a message exists) |
date-picker-trigger | The <div> wrapping the DatePicker trigger |
date-picker-input | The DatePicker's text <input> |
date-picker-positioner | The popover positioner for the DatePicker |
date-picker-content | The DatePicker popover content that holds the calendar |
range-picker-trigger | The <div> wrapping the RangePicker trigger |
range-picker-trigger-group | The row that groups the start and end inputs |
range-picker-start-input | The RangePicker's start date <input> |
range-picker-end-input | The RangePicker's end date <input> |
range-picker-positioner | The popover positioner for the RangePicker |
range-picker-content | The RangePicker popover content that holds the calendar |
range-picker-footer | The footer below the calendar (when footer is set) |
Accessibility
- Supports keyboard navigation between dates with arrow keys
- Uses
aria-labelattributes for date cells - Selected and disabled dates are announced to screen readers