Components / Inputs

Calendar

Browse dates in a clear, compact month view.

Install

npx shadcn@latest add https://irisui.dev/r/calendar.json
import { Calendar } from "@/components/iris/calendar/calendar";
Registry item calendarBrings in foundationRegistry JSON

Preview

Calendar

A month grid with a gliding selection disc, sliding month strip, keyboard navigation and optional Today button.

When to use

  • Inline date selection where the calendar should stay visible (scheduling panels, booking sidebars).
  • With minDate, maxDate and disabledDates for availability rules.
  • In a form field, use DatePicker, which wraps this calendar in a popover.

Usage

import { Calendar } from "@/components/iris/calendar/calendar";
function ViewingDay() {
  const [date, setDate] = React.useState(new Date(2026, 9, 14));
  return h(Calendar, {
    value: date,
    onChange: setDate,
    showToday: true,
    disabledDates: (d) => d.getDay() === 0 || d.getDay() === 6,
  });
}

Props

Prop Type Default Description
value Date – Selected day.
onChange (date: Date) => void – Called when a day is chosen.
month / onMonthChange Date / (month: Date) => void – Control the visible month; uncontrolled it follows the value or today.
minDate / maxDate Date – Bounds; days outside are disabled and month arrows stop.
disabledDates (date: Date) => boolean – Extra blocked days, such as weekends.
locale string "en-US" Month, weekday and aria-label formatting.
showToday boolean false Adds a Today button that slides back and selects today when allowed.
className string – Extra class on the root section.

Notes

  • Days are role="gridcell" buttons with full-date aria-labels and a roving tab stop. Arrows move by day/week, Home/End to week edges, PageUp/PageDown by month (Shift for a year); keyboard moves skip blocked days.
  • Every month shows six weeks so the height never changes. Month changes are announced in a polite live region.
  • Without value or month, the first render waits for the client's today, so server and client markup agree. Reduced motion lands months and the disc in place.
  • Width is min(100%, 328px). Reads --accent, --accent-ink, --on-accent, --ink, --ink-2, --ink-3, --hover.