Browse docs
Browse docs
Calendar is a standalone, inline month grid for picking a single date. It is
a primitive — always visible, no popup, no form-bridge or RBAC integration.
For a form-bound date field use DatePicker,
which pairs a trigger with a Calendar popover.
Dates are plain ISO YYYY-MM-DD strings throughout — no time, no time zone. The
month grid, keyboard navigation, and localization come from the headless
@dashforge/calendar-core engine; this
Calendar is the Tailwind presentation layer over it — the same engine the
MUI @dashforge/ui calendar renders.
import { Calendar } from '@dashforge/tw';
<Calendar
defaultValue="2026-05-20"
onChange={(iso) => console.log(iso)}
/>A basic uncontrolled calendar — defaultValue seeds the selection, the grid
manages it from there.
import { Calendar } from '@dashforge/tw';
<Calendar defaultValue="2026-05-20" />minDate / maxDate bound the selectable range; disabledDates blocks
specific days. isDateDisabled (a predicate) covers rule-based cases such as
"weekdays only".
import { Calendar } from '@dashforge/tw';
<Calendar
defaultValue="2026-05-15"
minDate="2026-05-04"
maxDate="2026-05-29"
disabledDates={['2026-05-12', '2026-05-13', '2026-05-20']}
/>weekStartDay sets the first column (0 = Sunday, 1 = Monday). locale is
a BCP-47 tag driving the month and weekday names.
import { Calendar } from '@dashforge/tw';
<Calendar defaultValue="2026-05-20" weekStartDay={1} locale="en-GB" />Pass value + onChange to own the selection in your own state.
import { useState } from 'react';
import { Calendar, Stack, Typography } from '@dashforge/tw';
function ControlledCalendar() {
const [date, setDate] = useState<string | null>('2026-05-20');
return (
<Stack gap={2} sx="items-center">
<Calendar value={date} onChange={setDate} />
<Typography variant="caption" sx="text-neutral-500">
Selected: {date ?? '—'}
</Typography>
</Stack>
);
}| Prop | Type | Default | Description |
|---|---|---|---|
value | ISODate | null | — | Selected date (controlled). |
defaultValue | ISODate | null | null | Initial selected date (uncontrolled). |
onChange | (value: ISODate) => void | — | Fired when a day is chosen. |
month / year | number | — | Controlled displayed month (1-indexed) + year. |
defaultMonth / defaultYear | number | from value / today | Initial displayed month + year (uncontrolled). |
onMonthChange | (month, year) => void | — | Fired when the displayed month changes. |
minDate / maxDate | ISODate | — | Selectable range bounds (inclusive). |
disabledDates | ISODate[] | — | Explicit list of disabled dates. |
isDateDisabled | (date: ISODate) => boolean | — | Predicate disabling arbitrary dates. |
weekStartDay | WeekDay | 0 | First-column weekday (0 = Sunday). |
locale | string | 'en-US' | BCP-47 locale for month / weekday names. |
today | ISODate | host date | Overrides "today" — mainly for testing. |
disabled | boolean | false | Disables the whole calendar. |
autoFocus | boolean | false | Moves DOM focus to the active day cell on mount. |
aria-label | string | 'Calendar' | Accessible label for the grid. |
sx | string | — | Tailwind class override for the root element. |
slotProps | CalendarSlotProps | — | Per-slot className overrides. |
testId | string | — | Test id applied to the root element. |
ISODate is a YYYY-MM-DD string; WeekDay is 0 \| 1 \| … \| 6. Both come
from @dashforge/calendar-core.
sx overrides the root element's Tailwind classes; slotProps targets the
inner slots.
| Slot | Description |
|---|---|
root | The calendar container. |
header | The month-navigation header row. |
grid | The day-grid wrapper. |
day | Every day-cell button. |
<Calendar
defaultValue="2026-05-20"
sx="rounded-xl shadow-md"
slotProps={{ day: { className: 'font-medium' } }}
/>role="grid" with row /
columnheader / gridcell structure.Enter / Space selects.aria-current="date"; the selected day carries
aria-pressed.Calendar has no name, no validation, no RBAC.
It does not register with DashForm. Use DatePicker for form integration.YYYY-MM-DD only. No time component and no time zone — a stored date
never drifts across zones or DST.@dashforge/calendar-core; the same engine
powers the MUI Calendar in @dashforge/ui.dashforgePreset() — no dark: variants, so dark mode follows the CSS-var
swap automatically.