Calendar
A month grid for picking one day, several days, or a range.
| Su | Mo | Tu | We | Th | Fr | Sa |
|---|---|---|---|---|---|---|
'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
| Su | Mo | Tu | We | Th | Fr | Sa |
|---|---|---|---|---|---|---|
| Su | Mo | Tu | We | Th | Fr | Sa |
|---|---|---|---|---|---|---|
'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
| Su | Mo | Tu | We | Th | Fr | Sa |
|---|---|---|---|---|---|---|
'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} />
);
}
Dropdown caption
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.
| Su | Mo | Tu | We | Th | Fr | Sa |
|---|---|---|---|---|---|---|
'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.
| Su | Mo | Tu | We | Th | Fr | Sa |
|---|---|---|---|---|---|---|
'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
| Su | Mo | Tu | We | Th | Fr | Sa | |
|---|---|---|---|---|---|---|---|
| 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
| Su | Mo | Tu | We | Th | Fr | Sa |
|---|---|---|---|---|---|---|
'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.
| Pt | Sa | Ça | Pe | Cu | Ct | Pz |
|---|---|---|---|---|---|---|
'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.