Dates@knitui/dates
Calendar
Calendar is the keystone level state machine: it owns the displayed level (decade ↔ year ↔ month) and the displayed date, and renders one level group at a time. It is display + navigation only — it does not own a selection (the DatePicker family layers selection on top). minLevel / maxLevel clamp how far the user can zoom; numberOfColumns renders several months side by side. Accent comes from the active Tamagui theme.
import { Calendar } from "@knitui/dates";Playground
Loading playground…
<Calendar
size="md"
numberOfColumns={1}
minLevel="month"
maxLevel="decade"
static={false}
fullWidth={false}
defaultDate="2026-06-15"
/>Examples
Month Level
Default month view, opened on June 2026.
Loading example…
Year Level
Year view — pick a month to zoom into it.
Loading example…
Decade Level
Decade view — pick a year to zoom into it.
Loading example…
Multiple Columns
Three months side by side — numberOfColumns={3}.
Loading example…
Min Max Date
Bounded range — only March–September 2026 is navigable/selectable.
Loading example…
Custom Render Day
Custom day rendering — weekend numbers get a colored dot via renderDay.
Loading example…
Themed
The accent recolors with the Tamagui theme= prop — no color prop, no hex. Here the whole calendar renders in the red ramp.
Loading example…
Framed Surface
Calendar.Frame is the styled root, exposed as the single extension point — styled(Calendar.Frame, …) (here a bordered, padded surface) and the forwarded frame style props both land on the root.
Loading example…
Sizes
Every size token, from xxs to xxl, at the month level.
Loading example…
Full Width
fullWidth stretches the whole calendar — header, weekday row and grid — to its container's width, with the cells sharing each row equally. Unlike the standalone Month, this exercises the full container chain (Calendar → level group → level → grid), so every wrapper must opt into the stretch.
Loading example…
Full Width Filled
fullWidth fills BOTH axes. Given a fixed container height, the level fills it below the header and the week rows distribute the extra vertical space (the day cells grow taller). Switch levels to see the month/year grids fill the same way.
Loading example…
Props
| Prop | Type | Default | Description |
|---|---|---|---|
ariaLabels | CalendarAriaLabels | undefined | — | `aria-label`s for the controls on the different levels. |
columnsToScroll | number | undefined | `numberOfColumns` | Number of columns to scroll with the next/prev buttons. |
date | string | Date | undefined | — | Displayed date in controlled mode. |
decadeLabelFormat | DecadeLabelFormat | undefined | 'YYYY' | dayjs format for the decade label, or a function returning it. |
defaultDate | string | Date | undefined | — | Initial displayed date in uncontrolled mode. |
defaultLevel | CalendarLevel | undefinedunset · month · year · decade | — | Initial displayed level (uncontrolled). |
disabled system | boolean | undefined | — | |
enableKeyboardNavigation | boolean | undefined | true | Enable enhanced keyboard navigation (web only): Ctrl/Cmd+Arrow steps a year, Ctrl/Cmd+Shift+Arrow steps a decade, `Y` opens the year view. |
excludeDate | ((date: DateStringValue) => boolean) | undefined | — | Predicate marking a day disabled. |
firstDayOfWeek | DayOfWeek | undefined | `DatesProvider` (1) | First weekday of each row, `0` (Sunday) … `6` (Saturday). |
fullWidth system | boolean | undefined | false | Stretch the calendar to the full width of its container. |
getDayAriaLabel | ((date: DateStringValue) => string) | undefined | — | Assigns each `Day` an `aria-label` based on its date. |
getDayProps | ((date: DateStringValue) => Partial<DayProps>) | undefined | — | Passes props down to every `Day` (wins over `styles.day`). |
getMonthControlProps | ((date: DateStringValue) => Partial<PickerControlProps>) | undefined | — | Passes props down to each month `PickerControl`, keyed by date (wins over `styles.control`). |
getYearControlProps | ((date: DateStringValue) => Partial<PickerControlProps>) | undefined | — | Passes props down to each year `PickerControl`, keyed by date (wins over `styles.control`). |
headerControlsOrder | CalendarHeaderControlName[] | undefined | ['previous', 'level', 'next'] | Order in which the controls are rendered. |
hideOutsideDates | boolean | undefined | false | Hide days outside the current month. |
hideWeekdays | boolean | undefined | false | Hide the weekday header row. |
highlightToday | boolean | undefined | false | Highlight today with a border. |
level | CalendarLevel | undefined | — | Current displayed level in controlled mode. |
locale | string | undefined | — | dayjs locale; falls back to the value defined in `DatesProvider`. |
maxDate | string | Date | undefined | — | Maximum possible date in `YYYY-MM-DD` format or a `Date` object. |
maxLevel | CalendarLevel | undefinedmonth · year · decade | 'decade' | Max level the user can zoom out to. |
minDate | string | Date | undefined | — | Minimum possible date in `YYYY-MM-DD` format or a `Date` object. |
minLevel | CalendarLevel | undefinedmonth · year · decade | 'month' | Min level the user can zoom in to. |
monthLabelFormat | DateLabelFormat | undefined | 'MMMM YYYY' | dayjs format for the month label, or a function returning it. |
monthsListFormat | string | undefined | 'MMM' | dayjs format for the month labels. |
nextIcon | ReactNode | — | Replace the next-button icon. |
nextLabel | string | undefined | — | Next button `aria-label`. |
numberOfColumns | number | undefined | 1 | Number of month columns displayed next to each other. |
onDateChange | ((date: DateStringValue) => void) | undefined | — | Called when the displayed date changes. |
onLevelChange | ((level: CalendarLevel) => void) | undefined | — | Called when the displayed level changes. |
onMonthMouseEnter | ((event: unknown, date: DateStringValue) => void) | undefined | — | Called when the pointer enters a month control (web hover; used for range preview). Cross-platform — the event type is opaque, never a DOM event. |
onMonthSelect | ((date: DateStringValue) => void) | undefined | — | Called when the user selects a month. |
onMouseLeave | ((event: unknown) => void) | undefined | — | Called when the pointer leaves the calendar root (web hover; used by range pickers to clear the hover preview). Cross-platform — the event type is opaque, never a DOM event; Tamagui no-ops it on native. |
onNextDecade | ((date: DateStringValue) => void) | undefined | — | Called when the next-decade button is clicked. |
onNextMonth | ((date: DateStringValue) => void) | undefined | — | Called when the next-month button is clicked. |
onNextYear | ((date: DateStringValue) => void) | undefined | — | Called when the next-year button is clicked. |
onPreviousDecade | ((date: DateStringValue) => void) | undefined | — | Called when the previous-decade button is clicked. |
onPreviousMonth | ((date: DateStringValue) => void) | undefined | — | Called when the previous-month button is clicked. |
onPreviousYear | ((date: DateStringValue) => void) | undefined | — | Called when the previous-year button is clicked. |
onYearMouseEnter | ((event: unknown, date: DateStringValue) => void) | undefined | — | Called when the pointer enters a year control (web hover; used for range preview). Cross-platform — the event type is opaque, never a DOM event. |
onYearSelect | ((date: DateStringValue) => void) | undefined | — | Called when the user selects a year. |
previousIcon | ReactNode | — | Replace the previous-button icon. |
previousLabel | string | undefined | — | Previous button `aria-label`. |
renderDay | RenderDay | undefined | — | Custom renderer for each day's content. |
shadow system | "xs" | "sm" | "md" | "lg" | "xl" | "xxs" | "xxl" | undefined | — | |
size system | CalendarSize | undefinedxxs · xs · sm · md · lg · xl · xxl | 'md' | Width/font of the header controls and cells. |
static | boolean | undefined | false | Render days as static (non-interactive) display cells. |
theme system | ThemeName | null | undefined | — | Applies a theme to this element |
weekdayFormat | DateLabelFormat | undefined | 'dd' | dayjs format for weekday names, or a custom renderer. |
weekendDays | DayOfWeek[] | undefined | `DatesProvider` ([0, 6]) | Indices of weekend days. |
withCellSpacing | boolean | undefined | true | Separate controls/rows with spacing. |
withWeekNumbers | boolean | undefined | false | Display a leading week-number column. |
yearLabelFormat | DateLabelFormat | undefined | 'YYYY' | dayjs format for the year label, or a function returning it. |
yearsListFormat | string | undefined | 'YYYY' | dayjs format for the year labels. |
Accessibility & DOM props (2)
| Prop | Type |
|---|---|
key | Key | null | undefined |
ref | Ref<TamaguiElement> | undefined |
Plus 497 inherited style props from Box — the full Tamagui/React Native style surface, including token shorthands like p, mx, bg and c. See Tokens for the scales they accept, or the full list.