Components

Calendar

Month calendar built on react-day-picker. Yuno tokens for selected/today/outside days. Use standalone or inside a Popover for a Date picker.

Updated Jul 17, 2026 by Juan Pablo Turina

Anatomy

January 2025
  1. 1
    Caption + nav

    Month + year label (text-sm font-medium) with ghost prev/next arrows (size-8, CaretLeft/Right).

  2. 2
    Weekday row

    Su-Sa abbreviations in muted-foreground text-xs.

  3. 3
    Day grid

    7-column flex grid of day buttons: 32px (size-8), rounded-md, ghost.

  4. 4
    Day states

    Default, today (bg-accent), selected (bg-primary), outside (muted), disabled (opacity-50), and range (accent track + primary endpoints).

Variants

Single
January 2025
<Calendar mode="single" selected={date} onSelect={setDate} />
Range
January 2025
<Calendar mode="range" selected={range} onSelect={setRange} />
Multiple
January 2025
<Calendar mode="multiple" selected={days} onSelect={setDays} />

Recipes

Ready-to-copy compositions covering the most common Yuno usages of this atom.

Date picker (in a Popover)

The canonical use: a button trigger opens a Popover holding the Calendar. Already packaged as the Date picker atom.

January 2025
// Compose Calendar inside a Popover — this is the DatePicker atom.
<Popover>
  <PopoverTrigger asChild>
    <Button variant="outline">
      <CalendarBlank weight="light" />
      {date ? format(date, "PP") : "Pick a date"}
    </Button>
  </PopoverTrigger>
  <PopoverContent className="w-auto p-0" align="start">
    <Calendar mode="single" selected={date} onSelect={setDate} />
  </PopoverContent>
</Popover>
Range for reports

mode='range' with numberOfMonths={2} to pick a start and end date for a report window.

January 2025
February 2025
<Calendar
  mode="range"
  numberOfMonths={2}
  selected={range}
  onSelect={setRange}
/>
Block unavailable dates

Pass disabled with matchers ({ before }, { after }, { dayOfWeek }) to stop selection of past days, weekends, or blackout dates.

January 2025
// Block weekends and past dates
<Calendar
  mode="single"
  selected={date}
  onSelect={setDate}
  disabled={[{ dayOfWeek: [0, 6] }, { before: new Date() }]}
/>

Import

Copy this import line at the top of the file where you compose this atom.

For a text-trigger date field, use the Date picker atom (Calendar in a Popover).
import { Calendar } from "@/components/ui/calendar";

Props

Everything else from the underlying HTML or Radix primitive is forwarded via ...props.

PropTypeDefaultDescription
mode"single" | "multiple" | "range""single"Selection behaviour. Drives the type of selected / onSelect.
selectedDate | Date[] | DateRangeThe selected value. Type matches mode. Controlled with onSelect.
onSelect(value) => voidFires on day click with the new selection.
defaultMonthDatetodayWhich month is shown first (uncontrolled month).
numberOfMonthsnumber1Show several months side by side. Common for range pickers (2).
showOutsideDaysbooleantrueRender the leading/trailing days of adjacent months (muted).
disabledMatcher | Matcher[]Dates that can't be selected: { before }, { after }, { dayOfWeek }, a Date[], etc.
classNamesPartial<ClassNames>Override any react-day-picker part. Merged over the Yuno defaults.

When to use

  • Standalone date picker inside a settings panel.
  • Range selection for reports (paired with mode='range').

When not to use

  • For displaying appointments/events — that's a full calendar view, not this atom.

Usage

Do
  • Provide selected + onSelect props for controlled use.
  • Pair with a Popover trigger button — see the DatePicker atom.
Don't
  • Don't build a bespoke date field from scratch — compose Calendar inside a Popover (the Date picker atom).
  • Don't cram events/appointments into day cells — that's a calendar view, not this atom.

Related

Cross-links to atoms and patterns you may reach for next.

  • Date pickerCalendar composed inside a Popover with a button trigger.
  • PopoverThe surface that holds the Calendar for a picker.
  • InputFor manual date entry next to or instead of the calendar.