Calendar
A date field component that lets users select dates and date ranges, navigate months, and pick a month or year directly.
Default
Built on React DayPicker. A single date is selected with mode="single".
| Su | Mo | Tu | We | Th | Fr | Sa |
|---|---|---|---|---|---|---|
tsx
import * as React from "react";
import { Calendar } from "@hummingbirdui/react";
export default function CalendarDefault() {
const [date, setDate] = React.useState<Date | undefined>(new Date());
return (
<Calendar
mode="single"
selected={date}
onSelect={setDate}
className="mx-auto rounded-lg border border-default"
/>
);
}Range Calendar
mode="range" selects a start and end date, and numberOfMonths shows several months side by side.
| Su | Mo | Tu | We | Th | Fr | Sa |
|---|---|---|---|---|---|---|
| Su | Mo | Tu | We | Th | Fr | Sa |
|---|---|---|---|---|---|---|
tsx
import * as React from "react";
import { addDays } from "date-fns";
import { type DateRange } from "react-day-picker";
import { Calendar } from "@hummingbirdui/react";
import { Card } from "@hummingbirdui/react";
export default function CalendarRange() {
const [dateRange, setDateRange] = React.useState<DateRange | undefined>({
from: new Date(new Date().getFullYear(), 0, 12),
to: addDays(new Date(new Date().getFullYear(), 0, 12), 30),
});
return (
<Card className="mx-auto w-fit p-0">
<Calendar
mode="range"
defaultMonth={dateRange?.from}
selected={dateRange}
onSelect={setDateRange}
numberOfMonths={2}
disabled={(date) => date > new Date() || date < new Date("1900-01-01")}
/>
</Card>
);
}Month and Year Selector
captionLayout="dropdown" replaces the caption label with month and year dropdowns.
| Su | Mo | Tu | We | Th | Fr | Sa |
|---|---|---|---|---|---|---|
tsx
import { Calendar } from "@hummingbirdui/react";
export default function CalendarCaption() {
return (
<Calendar
mode="single"
className="mx-auto rounded-lg border border-default"
captionLayout="dropdown"
/>
);
}Calendar Presets
Buttons outside the calendar can set the selected date and visible month through the controlled selected and month props.
| Su | Mo | Tu | We | Th | Fr | Sa |
|---|---|---|---|---|---|---|
tsx
import * as React from "react";
import { addDays } from "date-fns";
import { Button, Calendar, Card } from "@hummingbirdui/react";
export default function CalendarWithPresets() {
const [date, setDate] = React.useState<Date | undefined>(
new Date(new Date().getFullYear(), 1, 12),
);
const [currentMonth, setCurrentMonth] = React.useState<Date>(
new Date(new Date().getFullYear(), new Date().getMonth(), 1),
);
return (
<Card className="mx-auto w-fit max-w-75">
<Card.Body className="p-0">
<Calendar
mode="single"
selected={date}
onSelect={setDate}
month={currentMonth}
onMonthChange={setCurrentMonth}
fixedWeeks
className="w-full"
/>
</Card.Body>
<Card.Footer className="flex flex-wrap gap-2 border-t border-default">
{[
{ label: "Today", value: 0 },
{ label: "Tomorrow", value: 1 },
{ label: "In 3 days", value: 3 },
{ label: "In a week", value: 7 },
{ label: "In 2 weeks", value: 14 },
].map((preset) => (
<Button
key={preset.value}
variant="outline"
size="sm"
onClick={() => {
const newDate = addDays(new Date(), preset.value);
setDate(newDate);
setCurrentMonth(
new Date(newDate.getFullYear(), newDate.getMonth(), 1),
);
}}
>
{preset.label}
</Button>
))}
</Card.Footer>
</Card>
);
}Calendar With Time
A calendar combined with time inputs for picking a date and time together.
| Su | Mo | Tu | We | Th | Fr | Sa |
|---|---|---|---|---|---|---|
tsx
import * as React from "react";
import { Calendar, Card, Field, Input, InputIcon } from "@hummingbirdui/react";
import { Clock2Icon } from "lucide-react";
export default function CalendarWithTime() {
const [date, setDate] = React.useState<Date | undefined>(
new Date(new Date().getFullYear(), new Date().getMonth(), 12),
);
return (
<Card className="mx-auto w-fit">
<Card.Body className="p-0">
<Calendar
mode="single"
selected={date}
onSelect={setDate}
className="w-full"
/>
</Card.Body>
<Card.Footer className="border-t border-default">
<div>
<Field className="mb-3">
<Field.Label htmlFor="time-from">Start Time</Field.Label>
<InputIcon>
<Input
id="time-from"
type="time"
step="1"
defaultValue="10:30:00"
className="appearance-none [&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none"
/>
<InputIcon.End>
<Clock2Icon className="text-muted size-4" />
</InputIcon.End>
</InputIcon>
</Field>
<Field>
<Field.Label htmlFor="time-to">End Time</Field.Label>
<InputIcon>
<Input
id="time-to"
type="time"
step="1"
defaultValue="12:30:00"
className="appearance-none [&::-webkit-calendar-picker-indicator]:hidden [&::-webkit-calendar-picker-indicator]:appearance-none"
/>
<InputIcon.End>
<Clock2Icon className="text-muted size-4" />
</InputIcon.End>
</InputIcon>
</Field>
</div>
</Card.Footer>
</Card>
);
}Booked dates
The disabled and modifiers props mark dates as unavailable.
| Su | Mo | Tu | We | Th | Fr | Sa |
|---|---|---|---|---|---|---|
tsx
import * as React from "react";
import { Calendar, Card } from "@hummingbirdui/react";
export default function CalendarBookedDates() {
const [date, setDate] = React.useState<Date | undefined>(
new Date(new Date().getFullYear(), 0, 6),
);
const bookedDates = Array.from(
{ length: 15 },
(_, i) => new Date(new Date().getFullYear(), 0, 12 + i),
);
return (
<Card className="mx-auto w-fit p-0">
<Card.Body className="p-0">
<Calendar
mode="single"
defaultMonth={date}
selected={date}
onSelect={setDate}
disabled={bookedDates}
modifiers={{
booked: bookedDates,
}}
modifiersClassNames={{
booked: "[&>button]:line-through opacity-100",
}}
/>
</Card.Body>
</Card>
);
}Week numbers
showWeekNumber adds an ISO week number column.
| Su | Mo | Tu | We | Th | Fr | Sa | |
|---|---|---|---|---|---|---|---|
01 | |||||||
02 | |||||||
03 | |||||||
04 | |||||||
05 |
tsx
import * as React from "react";
import { Card, Calendar } from "@hummingbirdui/react";
export default function CalendarWeekNumbers() {
const [date, setDate] = React.useState<Date | undefined>(
new Date(new Date().getFullYear(), 0, 12),
);
return (
<Card className="mx-auto w-fit p-0">
<Card.Body className="p-0">
<Calendar
mode="single"
defaultMonth={date}
selected={date}
onSelect={setDate}
showWeekNumber
/>
</Card.Body>
</Card>
);
}API Reference
Calendar forwards all props to React DayPicker.
CSS variables
The calendar class exposes these CSS variables, which can be overridden to modify the calendar's appearance. Read more about customizing with CSS variables here.
.calendar {
--calendar-bg: var(--background-color-default);
--calendar-color: var(--text-color-default);
--calendar-muted-color: var(--text-color-muted);
--calendar-padding: --spacing(2);
--calendar-border-radius: var(--radius-lg);
--calendar-cell-size: --spacing(9);
--calendar-cell-radius: var(--radius-md);
--calendar-disabled-opacity: 0.5;
--calendar-outside-opacity: 0.7;
--calendar-nav-btn-size: --spacing(9);
--calendar-nav-btn-icon-size: --spacing(4);
--calendar-caption-height: --spacing(9);
--calendar-caption-font-size: var(--text-sm);
--calendar-caption-font-weight: var(--font-weight-medium);
--calendar-caption-icon-size: --spacing(3.5);
--calendar-caption-icon-color: var(--text-color-muted);
--calendar-weekday-color: var(--text-color-muted);
--calendar-weekday-font-size: var(--text-xs);
--calendar-weekday-font-weight: var(--font-weight-normal);
--calendar-day-color: var(--text-color-default);
--calendar-day-font-weight: var(--font-weight-normal);
--calendar-day-selected-color: var(--color-white);
--calendar-day-selected-bg: var(--color-primary);
--calendar-day-range-color: var(--text-color-default);
--calendar-day-range-bg: var(--background-color-muted);
--calendar-week-number-color: var(--text-color-muted);
--calendar-week-number-font-size: var(--text-xs);
}