Skip to content

Calendar

A month grid for picking one day, several days, or a range.

January 2026

Install

Bash
npx @madeui/cli add calendar

Installs react-day-picker and date-fns alongside the component.

Usage

TSX
import { Calendar } from '@/components/ui/calendar';
TSX
const [date, setDate] = React.useState<Date | undefined>(new Date());

<Calendar mode="single" selected={date} onSelect={setDate} />

Range

January 2026
February 2026

Multiple

January 2026

captionLayout="dropdown" swaps the caption for month and year selects, rendered with this library’s Select. startMonth / endMonth bound the navigable years.

Each trigger is sized to the longest label in the active locale, so month names are never truncated and the caption keeps its width as you move through the year.

June 1990

Disabled days

Any react-day-picker matcher works — here weekends and every day before January 12. Pass { before: new Date() } to block every day before today.

January 2026

Week numbers

January 2026
01
02
03
04
05

Small

January 2026

Locale

Pass a date-fns locale; weekday names, the caption, and the dropdown labels follow it.

Ocak 2026

API reference

Built on react-day-picker. The table below covers the props this library adds or changes — every other prop (mode, selected, onSelect, disabled, numberOfMonths, startMonth, locale, formatters, …) is forwarded to DayPicker; see the react-day-picker API reference for the full list.

Calendar

PropTypeDefaultDescription
size'sm' | 'md''md'Day cell size: md is 32px cells, sm is 28px.
showOutsideDaysbooleantrueChanged default — days of the adjacent months fill the grid.
captionLayout'label' | 'dropdown' | 'dropdown-months' | 'dropdown-years''label'Dropdown variants render the month / year pickers as Select.
navLayout'around' | 'after''around'Changed default — each chevron is pinned to the caption row of its own month, so they stay aligned when the months wrap. 'after' puts both chevrons in a row under the caption.
styleStyleXStyles—StyleX styles merged last on the root — always win over the component’s own styles.

Every slot is styled through react-day-picker’s classNames prop with StyleX classes; your own classNames are merged last, so a key you pass replaces ours for that slot. The nav key only applies to navLayout="after" — the around default styles button_previous and button_next directly.

Slots

The interactive parts are exported slot components. Pass your own through react-day-picker’s components prop to replace one; the rest of the calendar keeps its styling.

SlotComponentRenders
DayButtonCalendarDayButtonThe <button> in each day cell, styled from the day’s modifiers (selected, today, outside, disabled, range_middle).
ChevronCalendarChevronThe nav and dropdown chevrons (lucide icons).
WeekNumberCalendarWeekNumberThe row header when showWeekNumber is on.
DropdownCalendarDropdownThe month / year picker for the dropdown caption layouts, built on Select.
TSX
import { Calendar, CalendarDayButton } from '@/components/ui/calendar';

function DayWithTitle(props: React.ComponentProps<typeof CalendarDayButton>) {
  return <CalendarDayButton {...props} title={props.day.date.toDateString()} />;
}

<Calendar components={{ DayButton: DayWithTitle }} />

Slot components own their styling, so the classNames keys for those slots (day_button, chevron, week_number, dropdown) have no effect — override the component instead.

Styling

Calendar accepts style (StyleXStyles, merged last so caller overrides always win). The slot components take react-day-picker’s slot props; they do not accept style.

Was this page helpful?