Calendar
Date picker grid built on react-day-picker v10 - single date, multiple dates, or a date range, with token-driven theming and lucide chevrons.
Overview
Calendar wraps react-day-picker v10. Three modes via mode:
single- one daterange- start + end (date range)multiple- several independent dates
Use Calendar standalone in pages with plenty of space (scheduling, planners). For compact forms, wrap it in Popover - that composed pattern is DatePicker. In v10 of react-day-picker the classNames keys were migrated to the UI enum; we call getDefaultClassNames() and merge our semantic tokens on top.
Preview
| Su | Mo | Tu | We | Th | Fr | Sa |
|---|---|---|---|---|---|---|
'use client';import { Calendar } from '@gremorie/rx-forms';import { useState } from 'react';export function CalendarPreview() { const [date, setDate] = useState<Date | undefined>(new Date()); return <Calendar mode="single" selected={date} onSelect={setDate} />;}Anatomy
Calendar self-contained DayPicker grid (caption + nav, weekday header, day buttons)Installation
bash npx gremorie@latest add rx-calendar bash pnpm dlx gremorie@latest add rx-calendar bash yarn dlx gremorie@latest add rx-calendar bash bunx --bun gremorie@latest add rx-calendar Usage
import { Calendar } from "@gremorie/rx-forms";
export function Example() {
const [date, setDate] = React.useState<Date | undefined>(new Date());
return <Calendar mode="single" selected={date} onSelect={setDate} />;
}The Angular edition of this component ships from source today (see the workbench for the side-by-side); its registry entry is coming next.
API
<Calendar>
Forwards every prop to DayPicker from react-day-picker. The most relevant ones:
| Prop | Type | Default | Description |
|---|---|---|---|
mode | "single" | "multiple" | "range" | "single" | Selection model. |
selected | Date | Date[] | DateRange | - | Controlled selection. Shape depends on mode. |
onSelect | depends on mode | - | Fires when the user picks a date. |
disabled | Matcher | Matcher[] | - | Disable specific dates (past dates, weekends, custom predicates). |
showOutsideDays | boolean | true | Show greyed-out days from neighbouring months. |
numberOfMonths | number | 1 | Show multiple months side by side (useful for range pickers). |
defaultMonth | Date | current month | Initial month displayed when uncontrolled. |
locale | Locale | en-US | date-fns locale for month / weekday labels. |
autoFocus | boolean | false | Focus the first selected (or today's) cell on mount. Used by DatePicker inside Popover. |
className | string | - | Classes on the wrapper <div>. Defaults to p-3. |
classNames | Partial<ClassNames> | - | Override any internal class. Merged onto the Gremorie defaults via cn. |
For the full list of props, see the react-day-picker docs.
The Gremorie wrapper customizes:
button_previous/button_next- usebuttonVariants({ variant: "outline" })so the arrows match the rest of the design systemChevron- swaps the default react-day-picker chevrons for lucide'sChevronLeftIcon/ChevronRightIconselected- usesbg-primary text-primary-foregroundsemantic tokenstoday- usesbg-accent text-accent-foregroundoutside,disabled,hidden- all token-driven
Composition
<Calendar>is a self-contained widget. Drop it wherever you need a date grid.- For compact UI, wrap it in a
Popover+PopoverTrigger- that composition is exported asDatePickerin the overlays bundle. - For range pickers, set
mode="range"andnumberOfMonths={2}so users see start + end month at once.
Variations
Single date
The default mode. State is Date | undefined.
function SingleDate() {
const [date, setDate] = React.useState<Date | undefined>(new Date());
return <Calendar mode="single" selected={date} onSelect={setDate} />;
}Date range
State is { from?: Date; to?: Date }. Pair with numberOfMonths={2} for the classic side-by-side calendar UX.
import type { DateRange } from 'react-day-picker';
function DateRangeExample() {
const [range, setRange] = React.useState<DateRange | undefined>();
return (
<Calendar
mode="range"
selected={range}
onSelect={setRange}
numberOfMonths={2}
/>
);
}Disable past dates
The disabled prop accepts a matcher. Use { before: today } to block historical dates.
<Calendar
mode="single"
selected={date}
onSelect={setDate}
disabled={{ before: new Date() }}
/>Multiple independent dates
mode="multiple" lets users select any number of non-contiguous dates. State is Date[].
function MultipleDates() {
const [dates, setDates] = React.useState<Date[] | undefined>();
return <Calendar mode="multiple" selected={dates} onSelect={setDates} />;
}Accessibility
- Grid semantics: react-day-picker renders a
role="grid"with rows of cells. Each cell is a button. - Keyboard:
ArrowLeft/ArrowRightmove one day at a time.ArrowUp/ArrowDownmove one week at a time.Home/Endjump to first / last day of the row.PageUp/PageDownmove one month;Shift+PageUp/Shift+PageDownmove one year.
- Screen reader announcements: the focused date announces day of week, day number, and month. Disabled and outside days are announced as such.
- Focus: when wrapped in
Popover(theDatePickerpattern), setautoFocusso the active date receives focus on open. - Reduced motion: react-day-picker has no motion of its own; the calendar respects user motion preferences automatically.
Related
- Date Picker - the canonical Popover + Calendar composition
- Popover - the recommended wrapper for compact UIs
- Form - wire Calendar into react-hook-form