For AI agents: the complete documentation index is available at https://wallarm.github.io/design-system/llms.txt, the full documentation bundle is available at https://wallarm.github.io/design-system/llms-full.txt, and this page is available as Markdown at https://wallarm.github.io/design-system/components/calendar.md.

Calendar

The month grid for choosing a date the reader needs to see in context — a weekday, a distance from today — where DateInput is for a date they already know. It is its own popover, so compose a trigger beside it rather than wrapping it in one, and take React Aria date objects rather than a JavaScript Date.

Source · Storybook

Usage

import { Button } from '@wallarm-org/design-system/Button';
import { Calendar, CalendarBody, CalendarContent, CalendarGrids, CalendarTrigger } from '@wallarm-org/design-system/Calendar';
import { Calendar as CalendarIcon } from '@wallarm-org/design-system/icons';

Examples

Range

A start and an end in one grid, with the span drawn between them. Two months show at once so a range crossing a boundary can be chosen without paging.

Range with presets

CalendarPresets alongside the grid. The shipped defaults cover the ranges people actually ask for — last week, this month, last 90 days — so reach for them before writing your own.

Range with input

CalendarInputHeader puts a typed field above the grid, so the same popover serves both a reader who knows the dates and one who needs to look.

CalendarFooter holds Reset and Apply, which turns the grid into a deliberate commit — nothing changes underneath the reader until they apply it.

Presets, input header and footer together, which is the shape a filter bar wants. Everything else on this page is a subset of it.

Single with input

The typed header on a single calendar, for the same reason as the range: the reader chooses how to answer.

Single with date time

showTime adds a time to the date, for a moment rather than a day. Ask for it only where the time genuinely changes the result.

Single with presets

Single-date presets — today, yesterday, first of the month — which answer the questions a single date usually stands for.

Range with disabled dates

isDateUnavailable greys out dates that cannot be chosen. Show them rather than hiding them, so the reader can see the shape of what is allowed.

Range disallow disabled

A range refusing to span an unavailable date, which needs controlled mode. Use it where crossing the gap would produce a period the system cannot honour.

Range controlled

Owning the value, which is what presets, Apply and disallowed spans all require — the uncontrolled form is only for the simplest case.

Single custom presets

Your own preset list, for domain periods the defaults do not cover. Keep the labels as plain as the shipped ones.

Range readonly

A range shown but not editable, for a period the reader needs to read back rather than change.

Range readonly with presets

The same, with presets rendered but inert — worth seeing, because a live-looking preset that does nothing is worse than none.

Single readonly

A single date shown but not editable.

Props

PropTypeDefaultDescription
typeCalendarType | undefinedsingleCalendar type: 'single' for one month, 'range' for two months (date range selection)
showTimeboolean | undefinedfalseShow time selection (affects input placeholder text)
showKeyboardHintsboolean | undefinedtrueShow keyboard shortcut hints in presets and footer
valueDateValue[] | undefinedControlled value - array of selected dates
defaultValueDateValue[] | undefinedDefault value for uncontrolled mode
onChangecomplexCallback fired when selected value changes
minDateDateValue | undefinedMinimum selectable date
maxDateDateValue | undefinedMaximum selectable date
isDateUnavailablecomplexFunction to determine if a specific date should be unavailable/disabled. DateValue has year, month (1-12), and day properties. To get day of week, use: new Date(date.year, date.month - 1, date.day).getDay() where Sunday = 0, Saturday = 6.
disallowDisabledDatesInRangeboolean | undefinedfalseWhen true, prevents selecting a range that contains any unavailable dates. Requires controlled mode (value + onChange props) to work properly.
openboolean | undefinedControlled open state of the calendar popover
defaultOpenboolean | undefinedDefault open state for uncontrolled mode
onOpenChange((open: boolean) => void) | undefinedCallback fired when popover open state changes
closeOnSelectboolean | undefinedtrueWhether to close calendar on date selection. Default: true
readonlyboolean | undefinedfalseWhether calendar is readonly (display only, no date selection allowed). Default: false
focusedValueDateValue | undefinedControlled focused date — navigates the calendar view to this date

CalendarApplyButton

PropTypeDefaultDescription
onClick(() => void) | undefinedCallback fired before closing calendar
titlestring | undefined
defaultCheckedboolean | undefined
defaultValuestring | number | readonly string[] | undefined
autoFocusboolean | undefined
idstring | undefined
tabIndexnumber | undefined
relstring | undefined
colorstring | undefinedbrand
onChangeChangeEventHandler<T, Element> | undefined
type"button" | "submit" | "reset" | undefined
disabledboolean | undefined
namestring | undefined
valuestring | number | readonly string[] | undefined
asChildboolean | undefined
size{ small: string; medium: string; large: string; 'inline-edit': string; }small
data-testidstring | undefined
variant{ primary: string; outline: string; ghost: string; secondary: string; }primary
loading{ true: string; }
asC | undefined
fullWidth{ true: string; false: string; }

CalendarPresetItem

PropTypeDefaultDescription
label *stringDisplay label for the preset
value *PresetValuePreset value - dates array or named preset string
shortcutstring | undefinedKeyboard shortcut key
showShortcutboolean | undefinedtrueWhether to display the shortcut badge
titlestring | undefined
defaultCheckedboolean | undefined
defaultValuestring | number | readonly string[] | undefined
autoFocusboolean | undefined
idstring | undefined
tabIndexnumber | undefined
relstring | undefined
onChangeChangeEventHandler<T, Element> | undefined
disabledboolean | undefined
namestring | undefined
data-testidstring | undefined

CalendarPresets

PropTypeDefaultDescription
presetsPresetConfig[] | undefinedArray of preset configurations. Defaults to DEFAULT_SINGLE_PRESETS or DEFAULT_RANGE_PRESETS based on calendar type
showShortcutsboolean | undefinedtrueWhether to show keyboard shortcuts next to presets

CalendarResetButton

PropTypeDefaultDescription
onClick(() => void) | undefinedCallback fired after reset (in addition to clearing value)
titlestring | undefined
defaultCheckedboolean | undefined
defaultValuestring | number | readonly string[] | undefined
autoFocusboolean | undefined
idstring | undefined
tabIndexnumber | undefined
relstring | undefined
colorstring | undefinedneutral
onChangeChangeEventHandler<T, Element> | undefined
type"button" | "submit" | "reset" | undefined
disabledboolean | undefined
namestring | undefined
valuestring | number | readonly string[] | undefined
asChildboolean | undefined
size{ small: string; medium: string; large: string; 'inline-edit': string; }small
data-testidstring | undefined
variant{ primary: string; outline: string; ghost: string; secondary: string; }ghost
loading{ true: string; }
asC | undefined
fullWidth{ true: string; false: string; }

CalendarTrigger

PropTypeDefaultDescription
asChildboolean | undefinedtrueAdditional props passed to the trigger wrapper
titlestring | undefined
defaultCheckedboolean | undefined
defaultValuestring | number | readonly string[] | undefined
autoFocusboolean | undefined
idstring | undefined
tabIndexnumber | undefined
relstring | undefined
onChangeChangeEventHandler<T, Element> | undefined
data-testidstring | undefined