Animated monthly calendar for single-day or range selection, with bounds, modifiers, locale support, and an optional DatePicker wrapper.
npx shadcn@latest add @iconiq/calendar"use client";
import { useState } from "react";
import { Calendar } from "@/components/ui/calendar";
export function CalendarPreview() {
const [selected, setSelected] = useState<Date | null>(new Date());
return (
<Calendar
onSelect={setSelected}
selected={selected}
size="md"
/>
);
}modeSelection model. Use single for one date or range for start/end selection.
Type "single" | "range"·Default "single"
selectedControlled selected day for single mode. Pass null to clear the highlight.
Type Date | null
defaultSelectedInitial selected day for uncontrolled single mode when selected is not provided.
Type Date | null
onSelectCalled when the user picks a day in single mode, including visible outside-month days.
Type (date: Date | null) => void
rangeControlled range for range mode. Shape is `{ from?: Date; to?: Date }`.
Type CalendarRange
defaultRangeInitial range for uncontrolled range mode.
Type CalendarRange
onRangeSelectCalled when the user updates the range in range mode.
Type (range: CalendarRange) => void
monthControlled visible month. Prev/next, outside-day, and month/year picker navigation requests flow through onMonthChange.
Type Date
defaultMonthInitial visible month for uncontrolled usage when month is not provided.
Type Date
onMonthChangeCalled whenever the user navigates with prev/next, an outside day, or the month/year picker.
Type (month: Date) => void
disabledMarks dates as non-interactive in addition to minDate/maxDate bounds.
Type (date: Date) => boolean
minDateEarliest selectable day. Also disables month navigation into fully out-of-range months.
Type Date
maxDateLatest selectable day. Also disables month navigation into fully out-of-range months.
Type Date
localeOptional date-fns locale used for month labels, weekday headers, and spoken date labels.
Type Locale
labelsOverride built-in English UI and accessibility strings such as Today, Clear, and picker labels.
Type Partial<CalendarLabels>
sizeControls the overall calendar scale, including the card width, spacing, nav controls, weekday row, and day cell sizing. Defaults to sm.
Type "sm" | "md" | "lg"
weekStartsOnOverrides the first day of the week for both the weekday header and rendered month grid.
Type 0 | 1 | 2 | 3 | 4 | 5 | 6
minYearOptional lower bound for selectable years in the year picker.
Type number
maxYearOptional upper bound for selectable years in the year picker.
Type number
showOutsideDaysWhether leading and trailing days from adjacent months are rendered in the grid.
Type boolean·Default true
fixedWeeksPads the month grid to six weeks for consistent height. Only applies when showOutsideDays is true.
Type boolean·Default false
modifiersNamed matchers that render marker dots under matching days.
Type Record<string, (date: Date) => boolean>
modifierLabelsHuman-readable names for modifier keys, appended to spoken day labels.
Type Record<string, string>
idOptional root id used for heading and live-region relationships.
Type string
nameOptional native form field name. Renders a hidden input in single mode.
Type string
classNameOptional class names applied to the root surface.
Type string
The grid is rebuilt with date-fns whenever the visible month changes.
The rendered range runs from startOfWeek(startOfMonth(currentMonth)) through endOfWeek(endOfMonth(currentMonth)). fixedWeeks pads the grid to six rows only when showOutsideDays is enabled.
Days outside the active month remain visible by default and can still be selected. Choosing one switches the visible month and selects that day, unless the date is unavailable.
Weekday headers and the grid start day follow the provided locale and weekStartsOn settings.
Selected days are highlighted even when they appear as outside-month cells in the current grid.
Motion, keyboard support, and screen-reader semantics are built into the grid and picker overlays.
The root uses role=application with a role=grid date table, aria-selected day buttons, and a polite live selection summary.
Keyboard users can move through days with arrow keys, Home/End, PageUp/PageDown, and select with Enter or Space.
Month and year overlays trap focus, support arrow-key grid navigation, and return focus to the trigger on Escape.
Theme colors come from CSS variables, so the surface follows light/dark mode without client-side palette hydration.
Animations respect prefers-reduced-motion through useReducedMotion().
Install the exact registry entry shown on the right when you want the component file and its declared runtime dependencies together.
Dependencies: motion, lucide-react, date-fns.
Contact
Additionally, if you find any bug or issue, feel free to raise an issue.