Calendar
A calendar component that allows users to select a date or a range of dates.
Code
import { Calendar } from "@falcon/ui-kit";import { useState } from "react";
export function Example() { const [date, setDate] = useState<Date | undefined>(new Date());
return ( <Calendar mode="single" selected={date} onSelect={setDate} className="tw:rounded-lg tw:border" captionLayout="dropdown" /> );}Selected Date (With TimeZone)
Section titled “Selected Date (With TimeZone)”The Calendar component accepts a timeZone prop to ensure dates are displayed
and selected in the user’s local timezone.
Code
import { Calendar } from "@falcon/ui-kit";import { useState, useSyncExternalStore } from "react";
export function Example() { const [date, setDate] = useState<Date | undefined>(undefined); const timeZone = useSyncExternalStore( () => () => {}, () => Intl.DateTimeFormat().resolvedOptions().timeZone, () => undefined, );
return ( <Calendar mode="single" selected={date} onSelect={setDate} timeZone={timeZone} /> );}Note: If you notice a selected date offset (for example, selecting the 20th
highlights the 19th), make sure the timeZone prop is set to the user’s local
timezone.
Why client-side? The timezone is detected using
Intl.DateTimeFormat().resolvedOptions().timeZone on the client only, to ensure
compatibility with server-side rendering. Detecting the timezone during server
rendering would cause hydration mismatches, as the server and client may be in
different timezones.
A basic calendar component. We used className="tw:rounded-lg tw:border" to
style the calendar.
Code
import { Calendar } from "@falcon/ui-kit";
export function Example() { return <Calendar mode="single" className="tw:rounded-lg tw:border" />;}Range Calendar
Section titled “Range Calendar”Use the mode="range" prop to enable range selection.
Code
import { Calendar } from "@falcon/ui-kit";import { useState } from "react";
type DateRange = { from: Date | undefined; to?: Date | undefined };
function addDays(date: Date, days: number) { return new Date(date.getFullYear(), date.getMonth(), date.getDate() + days);}
export function Example() { const [dateRange, setDateRange] = useState<DateRange | undefined>({ from: new Date(new Date().getFullYear(), 0, 12), to: addDays(new Date(new Date().getFullYear(), 0, 12), 30), });
return ( <Calendar mode="range" defaultMonth={dateRange?.from} selected={dateRange} onSelect={setDateRange} numberOfMonths={2} className="tw:rounded-lg tw:border" /> );}Month and Year Selector
Section titled “Month and Year Selector”Use captionLayout="dropdown" to show month and year dropdowns.
Code
import { Calendar } from "@falcon/ui-kit";
export function Example() { return ( <Calendar mode="single" captionLayout="dropdown" className="tw:rounded-lg tw:border" /> );}Presets
Section titled “Presets”Code
import { Button, Calendar, Card, CardContent, CardFooter,} from "@falcon/ui-kit";import { useState } from "react";
function addDays(date: Date, days: number) { return new Date(date.getFullYear(), date.getMonth(), date.getDate() + days);}
export function Example() { const [date, setDate] = useState<Date | undefined>( new Date(new Date().getFullYear(), 1, 12), ); const [currentMonth, setCurrentMonth] = useState<Date>( new Date(new Date().getFullYear(), new Date().getMonth(), 1), );
return ( <Card className="tw:mx-auto tw:w-fit tw:max-w-[300px]" size="sm"> <CardContent> <Calendar mode="single" selected={date} onSelect={setDate} month={currentMonth} onMonthChange={setCurrentMonth} fixedWeeks className="tw:p-0 tw:[--cell-size:--spacing(9.5)]" /> </CardContent> <CardFooter className="tw:flex tw:flex-wrap tw:gap-2 tw:border-t"> {[ { label: "Today", value: 0 }, { label: "Tomorrow", value: 1 }, { label: "In 3 days", value: 3 }, { label: "In a week", value: 7 }, { label: "In 2 weeks", value: 14 }, ].map((preset) => ( <Button key={preset.value} variant="outline" size="sm" className="tw:flex-1" onClick={() => { const newDate = addDays(new Date(), preset.value); setDate(newDate); setCurrentMonth( new Date(newDate.getFullYear(), newDate.getMonth(), 1), ); }} > {preset.label} </Button> ))} </CardFooter> </Card> );}Date and Time Picker
Section titled “Date and Time Picker”Code
import { Calendar, Card, CardContent, CardFooter, Clock2Icon, Field, FieldGroup, FieldLabel, InputGroup, InputGroupAddon, InputGroupInput,} from "@falcon/ui-kit";import { useState } from "react";
export function Example() { const [date, setDate] = useState<Date | undefined>( new Date(new Date().getFullYear(), new Date().getMonth(), 12), );
return ( <Card size="sm" className="tw:mx-auto tw:w-fit"> <CardContent> <Calendar mode="single" selected={date} onSelect={setDate} className="tw:p-0" /> </CardContent> <CardFooter className="tw:border-t tw:bg-card"> <FieldGroup> <Field> <FieldLabel htmlFor="time-from">Start Time</FieldLabel> <InputGroup> <InputGroupInput id="time-from" type="time" step="1" defaultValue="10:30:00" className="tw:appearance-none tw:[&::-webkit-calendar-picker-indicator]:hidden tw:[&::-webkit-calendar-picker-indicator]:appearance-none" /> <InputGroupAddon> <Clock2Icon className="tw:text-muted-foreground" /> </InputGroupAddon> </InputGroup> </Field> <Field> <FieldLabel htmlFor="time-to">End Time</FieldLabel> <InputGroup> <InputGroupInput id="time-to" type="time" step="1" defaultValue="12:30:00" className="tw:appearance-none tw:[&::-webkit-calendar-picker-indicator]:hidden tw:[&::-webkit-calendar-picker-indicator]:appearance-none" /> <InputGroupAddon> <Clock2Icon className="tw:text-muted-foreground" /> </InputGroupAddon> </InputGroup> </Field> </FieldGroup> </CardFooter> </Card> );}Booked dates
Section titled “Booked dates”Code
import { Calendar, Card, CardContent } from "@falcon/ui-kit";import { useState } from "react";
export function Example() { const [date, setDate] = useState<Date | undefined>( new Date(new Date().getFullYear(), 0, 6), ); const bookedDates = Array.from( { length: 15 }, (_, i) => new Date(new Date().getFullYear(), 0, 12 + i), );
return ( <Card className="tw:mx-auto tw:w-fit tw:p-0"> <CardContent className="tw:p-0"> <Calendar mode="single" defaultMonth={date} selected={date} onSelect={setDate} disabled={bookedDates} modifiers={{ booked: bookedDates, }} modifiersClassNames={{ booked: "tw:[&>button]:line-through tw:opacity-100", }} /> </CardContent> </Card> );}Custom Cell Size
Section titled “Custom Cell Size”Code
import { Calendar, CalendarDayButton, Card, CardContent } from "@falcon/ui-kit";import { useState } from "react";
type DateRange = { from: Date | undefined; to?: Date | undefined };
function addDays(date: Date, days: number) { return new Date(date.getFullYear(), date.getMonth(), date.getDate() + days);}
export function Example() { const [range, setRange] = useState<DateRange | undefined>({ from: new Date(new Date().getFullYear(), 11, 8), to: addDays(new Date(new Date().getFullYear(), 11, 8), 10), });
return ( <Card className="tw:mx-auto tw:w-fit tw:p-0"> <CardContent className="tw:p-0"> <Calendar mode="range" defaultMonth={range?.from} selected={range} onSelect={setRange} numberOfMonths={1} captionLayout="dropdown" className="tw:[--cell-size:--spacing(10)] tw:md:[--cell-size:--spacing(12)]" formatters={{ formatMonthDropdown: (date) => { return date.toLocaleString("default", { month: "long" }); }, }} components={{ DayButton: ({ children, modifiers, day, ...props }) => { const isWeekend = day.date.getDay() === 0 || day.date.getDay() === 6;
return ( <CalendarDayButton day={day} modifiers={modifiers} {...props}> {children} {!modifiers.outside && ( <span>{isWeekend ? "$120" : "$100"}</span> )} </CalendarDayButton> ); }, }} /> </CardContent> </Card> );}You can customize the size of calendar cells using the --cell-size CSS
variable. You can also make it responsive by using breakpoint-specific values:
<Calendar mode="single" selected={date} onSelect={setDate} className="tw:rounded-lg tw:border tw:[--cell-size:--spacing(11)] tw:md:[--cell-size:--spacing(12)]"/>Or use fixed values:
<Calendar mode="single" selected={date} onSelect={setDate} className="tw:rounded-lg tw:border tw:[--cell-size:2.75rem] tw:md:[--cell-size:3rem]"/>Week Numbers
Section titled “Week Numbers”Use showWeekNumber to show week numbers.
Code
import { Calendar, Card, CardContent } from "@falcon/ui-kit";import { useState } from "react";
export function Example() { const [date, setDate] = useState<Date | undefined>( new Date(new Date().getFullYear(), 0, 12), );
return ( <Card className="tw:mx-auto tw:w-fit tw:p-0"> <CardContent className="tw:p-0"> <Calendar mode="single" defaultMonth={date} selected={date} onSelect={setDate} showWeekNumber /> </CardContent> </Card> );}Calendar
Section titled “Calendar”Renders a monthly calendar and accepts supported calendar props, including
selection, navigation, locale, and time-zone options. Deprecated props are
not exposed: use startMonth, endMonth, and autoFocus instead of the
fromDate/toDate-style month bounds and initialFocus; day key-press,
key-up, pointer, and touch handlers and onWeekNumberClick are omitted.
animate
Section titled “animate”animate?: booleanAnimate transitions while navigating between months.
aria-label
Section titled “aria-label”aria-label?: stringAccessible name for the calendar container.
aria-labelledby
Section titled “aria-labelledby”aria-labelledby?: stringID of the element that labels the calendar container.
autoFocus
Section titled “autoFocus”autoFocus?: booleanFocus the selected day, or today, when the calendar mounts.
broadcastCalendar
Section titled “broadcastCalendar”broadcastCalendar?: booleanUse the broadcast calendar, which starts weeks on Monday.
buttonVariant
Section titled “buttonVariant”buttonVariant?: "outline" | "link" | "secondary" | "default" | "ghost" | "destructive" | null = "ghost"The Falcon Button variant used for month navigation.
captionLayout
Section titled “captionLayout”captionLayout?: "label" | "dropdown" | "dropdown-months" | "dropdown-years" = "label"Choose a month-and-year label or month/year navigation dropdowns.
className
Section titled “className”className?: stringCSS class applied to the calendar root.
classNames
Section titled “classNames”classNames?: (Partial<ClassNames> & Partial<DeprecatedUI<string>>)Override the calendar’s class names after Falcon’s defaults.
components
Section titled “components”components?: Partial<CustomComponents>Override the calendar’s rendered elements. Falcon provides Root, Chevron, DayButton, and WeekNumber by default.
dateLib
Section titled “dateLib”dateLib?: Partial<DateLib>Override experimental date-library methods.
defaultMonth
Section titled “defaultMonth”defaultMonth?: DateInitial month for uncontrolled navigation. Use month to control it.
dir?: stringText direction for the calendar.
disabled
Section titled “disabled”disabled?: Matcher | Matcher[]Dates that cannot be selected.
disableNavigation
Section titled “disableNavigation”disableNavigation?: booleanPrevent navigation between months without hiding the navigation controls.
endMonth
Section titled “endMonth”endMonth?: DateLast month available through navigation.
excludeDisabled
Section titled “excludeDisabled”excludeDisabled: booleanReset the range when a disabled day would be included.
firstWeekContainsDate
Section titled “firstWeekContainsDate”firstWeekContainsDate?: 1 | 4Day in January that is always in the first week of the year.
fixedWeeks
Section titled “fixedWeeks”fixedWeeks?: booleanAlways display six weeks for each month.
footer
Section titled “footer”footer?: React.ReactNodeContent announced as the calendar’s live-region status.
formatters
Section titled “formatters”formatters?: Partial<Formatters>Override date formatters. Falcon overrides formatMonthDropdown by
default.
hidden
Section titled “hidden”hidden?: Matcher | Matcher[]Dates hidden from the calendar.
hideNavigation
Section titled “hideNavigation”hideNavigation?: booleanHide the month navigation controls.
hideWeekdays
Section titled “hideWeekdays”hideWeekdays?: booleanHide the weekday header row.
id?: stringUnique ID for the calendar root.
ISOWeek
Section titled “ISOWeek”ISOWeek?: booleanUse ISO week dates instead of the locale’s week settings.
labels
Section titled “labels”labels?: Partial<Labels>Override the accessible labels used by the calendar.
lang?: stringLanguage tag for the calendar root. Defaults to the locale code.
locale
Section titled “locale”locale?: Partial<DayPickerLocale>Locale used to format calendar dates and labels.
max: numberMaximum number of selected days. Maximum number of days in the range.
min: numberMinimum number of selected days. Minimum number of days in the range.
mode?: undefined | "single" | "multiple" | "range"Do not enable date selection. Enable selection of a single day. Enable selection of multiple days. Enable selection of a date range.
modifiers
Section titled “modifiers”modifiers?: Record<string, Matcher | Matcher[] | undefined>Additional named date matchers.
modifiersClassNames
Section titled “modifiersClassNames”modifiersClassNames?: ModifiersClassNamesCSS classes applied to dates matching named modifiers.
modifiersStyles
Section titled “modifiersStyles”modifiersStyles?: ModifiersStylesInline styles applied to dates matching named modifiers.
month?: DateControlled month. Use with onMonthChange.
navLayout
Section titled “navLayout”navLayout?: "around" | "after"Position navigation controls around or after the month caption.
nonce?: stringCSP nonce for the calendar’s inline styles.
noonSafe
Section titled “noonSafe”noonSafe?: booleanKeep date calculations at noon for time zones with historical offsets.
numberOfMonths
Section titled “numberOfMonths”numberOfMonths?: numberNumber of months shown at once.
numerals
Section titled “numerals”numerals?: NumeralsNumeral system used when formatting dates.
onDayBlur
Section titled “onDayBlur”onDayBlur?: DayEventHandler<React.FocusEvent<Element, Element>>Called when a day button loses focus.
onDayClick
Section titled “onDayClick”onDayClick?: DayEventHandler<React.MouseEvent<Element, MouseEvent>>Called when a day is clicked.
onDayFocus
Section titled “onDayFocus”onDayFocus?: DayEventHandler<React.FocusEvent<Element, Element>>Called when a day button receives focus.
onDayKeyDown
Section titled “onDayKeyDown”onDayKeyDown?: DayEventHandler<React.KeyboardEvent<Element>>Called when a key is pressed on a day button.
onDayMouseEnter
Section titled “onDayMouseEnter”onDayMouseEnter?: DayEventHandler<React.MouseEvent<Element, MouseEvent>>Called when the pointer enters a day.
onDayMouseLeave
Section titled “onDayMouseLeave”onDayMouseLeave?: DayEventHandler<React.MouseEvent<Element, MouseEvent>>Called when the pointer leaves a day.
onMonthChange
Section titled “onMonthChange”onMonthChange?: MonthChangeEventHandlerCalled when the displayed month changes.
onNextClick
Section titled “onNextClick”onNextClick?: MonthChangeEventHandlerCalled after navigating to the next month.
onPrevClick
Section titled “onPrevClick”onPrevClick?: MonthChangeEventHandlerCalled after navigating to the previous month.
onSelect
Section titled “onSelect”onSelect: OnSelectHandler<Date> | OnSelectHandler<Date | undefined> | OnSelectHandler<Date[]> | OnSelectHandler<Date[] | undefined> | OnSelectHandler<DateRange> | OnSelectHandler<DateRange | undefined>Called when the selected day changes. Called when the selected days change. Called when the selected range changes.
pagedNavigation
Section titled “pagedNavigation”pagedNavigation?: booleanNavigate by the displayed number of months.
required
Section titled “required”required?: undefined | true | falseSelection is unavailable when no selection mode is set. Require a selected day. Whether a selected day can be cleared. Require at least one selected day. Whether the selected dates can be cleared. Require a selected date range. Whether the selected range can be cleared.
resetOnSelect
Section titled “resetOnSelect”resetOnSelect: booleanStart a new range when selecting after a completed range.
reverseMonths
Section titled “reverseMonths”reverseMonths?: booleanDisplay multiple months in reverse chronological order.
reverseYears
Section titled “reverseYears”reverseYears?: booleanReverse year order in year dropdowns.
role?: "dialog" | "application"Landmark role for the calendar container.
selected
Section titled “selected”selected: Date | undefined | Date | Date[] | undefined | Date[] | DateRange | undefined | DateRangeSelected day. Selected days. Selected date range.
showOutsideDays
Section titled “showOutsideDays”showOutsideDays?: boolean = trueShow days from adjacent months.
showWeekNumber
Section titled “showWeekNumber”showWeekNumber?: booleanShow the week-number column.
startMonth
Section titled “startMonth”startMonth?: DateFirst month available through navigation.
style?: React.CSSPropertiesInline style applied to the calendar root.
styles
Section titled “styles”styles?: (Partial<Styles> & Partial<DeprecatedUI<React.CSSProperties>>)Override the calendar’s inline styles.
timeZone
Section titled “timeZone”timeZone?: stringIANA time zone or UTC offset used by the calendar.
title?: stringTitle attribute for the calendar root.
today?: DateDate treated as today.
useAdditionalDayOfYearTokens
Section titled “useAdditionalDayOfYearTokens”useAdditionalDayOfYearTokens?: booleanEnable additional day-of-year format tokens.
useAdditionalWeekYearTokens
Section titled “useAdditionalWeekYearTokens”useAdditionalWeekYearTokens?: booleanEnable additional week-year format tokens.
weekStartsOn
Section titled “weekStartsOn”weekStartsOn?: 0 | 3 | 1 | 4 | 2 | 5 | 6First day of the week, overriding the locale default.
CalendarDayButton
Section titled “CalendarDayButton”Renders a calendar day as a button with Falcon selection and focus styling. Accepts supported day-button props.
className
Section titled “className”className?: stringCSS class applied to the day button.
day: CalendarDayDay rendered by this button.
locale
Section titled “locale”locale?: Partial<DayPickerLocale>Locale used to format the date stored in data-day.
modifiers
Section titled “modifiers”modifiers: ModifiersDay state modifiers applied by the calendar.