Skip to content
Esc
navigateopen⌘Jpreview
On this page

Calendar

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

September 2026
'use client';

import * as React from 'react';

import { Calendar } from '@/components/ui/calendar';

export default function CalendarDemo() {
  const [date, setDate] = React.useState<Date | undefined>(new Date());

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

Install

npx @madeui/cli add calendar

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

Usage

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

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

Range

September 2026
October 2026
'use client';

import * as React from 'react';

import { addDays } from 'date-fns';
import type { DateRange } from 'react-day-picker';

import { Calendar } from '@/components/ui/calendar';

export default function CalendarRange() {
  const [range, setRange] = React.useState<DateRange | undefined>({
    from: new Date(),
    to: addDays(new Date(), 6),
  });

  return (
    <Calendar
      mode="range"
      selected={range}
      onSelect={setRange}
      numberOfMonths={2}
    />
  );
}

Multiple

September 2026
'use client';

import * as React from 'react';

import { addDays } from 'date-fns';

import { Calendar } from '@/components/ui/calendar';

export default function CalendarMultiple() {
  const [dates, setDates] = React.useState<Date[] | undefined>([
    new Date(),
    addDays(new Date(), 2),
    addDays(new Date(), 5),
  ]);

  return (
    <Calendar mode="multiple" selected={dates} onSelect={setDates} max={5} />
  );
}

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
'use client';

import * as React from 'react';

import { Calendar } from '@/components/ui/calendar';

export default function CalendarDropdown() {
  const [date, setDate] = React.useState<Date | undefined>(
    new Date(1990, 5, 15)
  );

  return (
    <Calendar
      mode="single"
      selected={date}
      onSelect={setDate}
      captionLayout="dropdown"
      defaultMonth={date}
      startMonth={new Date(1930, 0)}
      endMonth={new Date()}
    />
  );
}

Disabled days

Any react-day-picker matcher works — here weekends and every day before today.

September 2026
'use client';

import * as React from 'react';

import { Calendar } from '@/components/ui/calendar';

export default function CalendarDisabled() {
  const [date, setDate] = React.useState<Date | undefined>();

  return (
    <Calendar
      mode="single"
      selected={date}
      onSelect={setDate}
      disabled={[{ dayOfWeek: [0, 6] }, { before: new Date() }]}
    />
  );
}

Week numbers

September 2026
36
37
38
39
40
'use client';

import * as React from 'react';

import { Calendar } from '@/components/ui/calendar';

export default function CalendarWeekNumbers() {
  const [date, setDate] = React.useState<Date | undefined>(new Date());

  return (
    <Calendar mode="single" selected={date} onSelect={setDate} showWeekNumber />
  );
}

Small

September 2026
'use client';

import * as React from 'react';

import { Calendar } from '@/components/ui/calendar';

export default function CalendarSizes() {
  const [date, setDate] = React.useState<Date | undefined>(new Date());

  return <Calendar mode="single" selected={date} onSelect={setDate} size="sm" />;
}

Locale

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

Eylül 2026
'use client';

import * as React from 'react';

import { tr } from 'date-fns/locale';

import { Calendar } from '@/components/ui/calendar';

export default function CalendarLocale() {
  const [date, setDate] = React.useState<Date | undefined>(new Date());

  return (
    <Calendar
      mode="single"
      selected={date}
      onSelect={setDate}
      locale={tr}
      weekStartsOn={1}
    />
  );
}

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

Prop Type Default Description
size 'sm' | 'md' 'md' Day cell size: md is 32px cells, sm is 28px.
showOutsideDays boolean true Changed 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.
style StyleXStyles 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.

Slot Component Renders
DayButton CalendarDayButton The <button> in each day cell, styled from the day’s modifiers (selected, today, outside, disabled, range_middle).
Chevron CalendarChevron The nav and dropdown chevrons (lucide icons).
WeekNumber CalendarWeekNumber The row header when showWeekNumber is on.
Dropdown CalendarDropdown The month / year picker for the dropdown caption layouts, built on Select.
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?