Skip to content

Calendar

Pick a date or range from a month grid.

import { Calendar, CalendarDayButton } from '@youj/react/date'

Installation & usage

npm i @youj/react date-fns react-day-picker

For an app already set up with npx @youj/cli init, which installs the peers (@youj/core, @youj/motion, motion and Base UI) and wires the provider. New app? Start at Installation.

Requires date-fns and react-day-picker, optional dependencies. Import it from @youj/react/date.

Use Calendar when choosing a date is the main task and the month should stay visible. In a form, use Date Picker or Date Range Picker. Both put this calendar in a popover and let people type a date.

import { useState } from 'react'
import { Calendar } from '@youj/react/date'

export function DeployDay() {
  const [date, setDate] = useState<Date | undefined>(new Date())
  return <Calendar mode="single" selected={date} onSelect={setDate} />
}

Calendar is react-day-picker dressed in Youj's controls: every day and both arrows are a ghost Button, so hover, press and the focus ring match every other control. Every react-day-picker prop works as its docs describe: mode (single, multiple or range), selected and onSelect, disabled matchers, startMonth and endMonth, numberOfMonths, locale, footer and more.

Today carries a dot under its number. showOutsideDays and fixedWeeks are on by default, so the grid keeps six rows and the popover around it doesn't change height from month to month.

Reference

PropsCalendar takes react-day-picker's DayPicker props, unchanged, and…

Props

Calendar takes react-day-picker's DayPicker props, unchanged, and passes animate only while motion is allowed. It sets three defaults of its own: showOutsideDays, fixedWeeks and animate are all true. classNames and components merge over Youj's, so you can restyle one part or replace one component without losing the rest. CalendarDayButton is exported for custom day rendering.

MotionMonth enters, month leaves, day hover and press · reduced motion

Motion

Motion tokens
MomentTokens
Month entersfrom the side it comes from, a third of the width, fading in
duration.baseease.enter

220ms · cubic-bezier(0.16, 1, 0.3, 1)

220mscubic-bezier(0.16, 1, 0.3, 1)
Month leavesthe other way, fading out
duration.baseease.standard

220ms · cubic-bezier(0.2, 0, 0, 1)

220mscubic-bezier(0.2, 0, 0, 1)
Day hover and pressthe Button's background and press scale
duration.fastease.standard

140ms · cubic-bezier(0.2, 0, 0, 1)

140mscubic-bezier(0.2, 0, 0, 1)

Reduced motion

The month changes in place, with no slide. Days don't scale when pressed.

The slide only plays when the month changes from the arrows. Moving across a month's edge from the keyboard swaps the month in place, because react-day-picker keeps focus stable on the day. Under right-to-left layouts the slide is mirrored.

Reduced motion

The month swaps in place instead of sliding, and the day buttons don't scale when pressed. Selection, keyboard navigation and labels are unchanged.

AccessibilityKeyboard, ARIA

Accessibility

  • The grid is react-day-picker's role="grid", labeled with the month and year in the locale you pass.
  • Arrow keys move by day, PageUp and PageDown by month, Shift with PageUp or PageDown by year, and Home and End to the start and end of the week. Enter or Space selects.
  • Days carry full date labels ("Monday, September 28th, 2026"), today and selected states, and disabled days are skipped for selection.
  • The arrows are real buttons, named "Go to the Previous Month" and "Go to the Next Month", and disabled at the bounds.