Files
components/calendar.tsx
1'use client'
2
3import * as React from 'react'
4import { type DateRange } from 'react-day-picker'
5
6import { Button } from '@/components/ui/button'
7import { Calendar } from '@/components/ui/calendar'
8import {
9    Card,
10    CardContent,
11    CardDescription,
12    CardFooter,
13    CardHeader,
14    CardTitle,
15} from '@/components/ui/card'
16import { Input } from '@/components/ui/input'
17import { Label } from '@/components/ui/label'
18import { Separator } from '@/components/ui/separator'
19import { Textarea } from '@/components/ui/textarea'
20
21export function Calendar01() {
22    const [date, setDate] = React.useState<DateRange | undefined>({
23        from: new Date(2025, 10, 9),
24        to: new Date(2025, 10, 20),
25    })
26    const [startTime, setStartTime] = React.useState('09:00')
27    const [endTime, setEndTime] = React.useState('09:00')
28    const [participants, setParticipants] = React.useState('10')
29    return (
30        <Card className="w-full max-w-3xl shadow-lg">
31            <CardHeader>
32                <CardTitle>Event Calendar</CardTitle>
33                <CardDescription>
34                    Schedule your team meetings and events easily
35                </CardDescription>
36            </CardHeader>
37            <CardContent className="grid grid-cols-1 gap-4 md:grid-cols-2 md:gap-3">
38                <div className="flex items-center justify-center">
39                    <Calendar
40                        mode="range"
41                        selected={date}
42                        onSelect={setDate}
43                        captionLayout="dropdown"
44                        className="rounded-lg border shadow-sm [--cell-size:--spacing(8)] md:[--cell-size:--spacing(10)]"
45                    />
46                </div>
47
48                <div className="space-y-4">
49                    <div className="space-y-2">
50                        <Label>Start date*</Label>
51                        <div className="flex gap-2">
52                            <Input
53                                type="date"
54                                value={
55                                    date?.from
56                                        ? date.from.toLocaleDateString('en-CA')
57                                        : ''
58                                }
59                                onChange={() => {}}
60                                className="flex-1"
61                            />
62                            <Input
63                                type="time"
64                                value={startTime}
65                                onChange={(e) => setStartTime(e.target.value)}
66                                className="w-[100px]"
67                            />
68                        </div>
69                    </div>
70
71                    <div className="space-y-2">
72                        <Label>End date*</Label>
73                        <div className="flex gap-2">
74                            <Input
75                                type="date"
76                                value={
77                                    date?.to
78                                        ? date.to.toLocaleDateString('en-CA')
79                                        : ''
80                                }
81                                onChange={() => {}}
82                                className="flex-1"
83                            />
84                            <Input
85                                type="time"
86                                value={endTime}
87                                onChange={(e) => setEndTime(e.target.value)}
88                                className="w-[100px]"
89                            />
90                        </div>
91                    </div>
92                    <Separator className="my-6" />
93                    <div className="space-y-2">
94                        <Label>Event agenda and notes</Label>
95                        <Textarea rows={5} placeholder="Enter event agenda" />
96                    </div>
97                    <div className="space-y-2">
98                        <Label>Maximum participants</Label>
99                        <Input
100                            type="number"
101                            value={participants}
102                            onChange={(e) => setParticipants(e.target.value)}
103                        />
104                    </div>
105                </div>
106            </CardContent>
107            <CardFooter className="flex justify-end gap-3 border-t pt-4">
108                <Button variant="outline">Cancel</Button>
109                <Button>Schedule meetings</Button>
110            </CardFooter>
111        </Card>
112    )
113}
114
Event calendar.
calendar-01
Files
components/calendar.tsx
1'use client'
2
3import * as React from 'react'
4import { addDays } from 'date-fns'
5
6import { Button } from '@/components/ui/button'
7import { Calendar } from '@/components/ui/calendar'
8import { Card, CardContent, CardFooter } from '@/components/ui/card'
9
10export function Calendar02() {
11    const [date, setDate] = React.useState<Date | undefined>(new Date())
12    return (
13        <Card className="max-w-[300px] py-2">
14            <CardContent className="px-6">
15                <Calendar
16                    mode="single"
17                    selected={date}
18                    onSelect={setDate}
19                    className="rounded-lg border shadow-sm"
20                />
21            </CardContent>
22            <CardFooter className="flex flex-wrap items-center justify-center gap-2 border-t px-2 pt-4">
23                {[
24                    { label: 'Today', value: 0 },
25                    { label: 'Tomorrow', value: 1 },
26                    { label: 'In 3 days', value: 3 },
27                    { label: 'In 1 week', value: 7 },
28                    { label: 'In 2 weeks', value: 14 },
29                ].map((preset) => (
30                    <Button
31                        key={preset.value}
32                        onClick={() => {
33                            const newDate = addDays(new Date(), preset.value)
34                            setDate(newDate)
35                        }}
36                    >
37                        {preset.label}
38                    </Button>
39                ))}
40            </CardFooter>
41        </Card>
42    )
43}
44
A calendar with presets.
calendar-02
Files
components/calendar.tsx
1'use client'
2
3import * as React from 'react'
4import { type DateRange } from 'react-day-picker'
5
6import { Calendar } from '@/components/ui/calendar'
7
8export function Calendar03() {
9    const [date, setDate] = React.useState<DateRange | undefined>({
10        from: new Date(2025, 10, 9),
11        to: new Date(2025, 11, 26),
12    })
13
14    return (
15        <Calendar
16            mode="range"
17            defaultMonth={date?.from}
18            numberOfMonths={2}
19            selected={date}
20            onSelect={setDate}
21        />
22    )
23}
24
Multiple months with range selection.
calendar-03
Files
components/calendar.tsx
1'use client'
2
3import * as React from 'react'
4import { type DateRange } from 'react-day-picker'
5
6import { Calendar } from '@/components/ui/calendar'
7
8export function Calendar04() {
9    const [date, setDate] = React.useState<DateRange | undefined>({
10        from: new Date(2025, 10, 11),
11        to: new Date(2025, 10, 14),
12    })
13
14    return (
15        <Calendar
16            mode="range"
17            defaultMonth={date?.from}
18            selected={date}
19            onSelect={setDate}
20            numberOfMonths={2}
21            disabled={{ dayOfWeek: [0, 6] }}
22            excludeDisabled
23        />
24    )
25}
26
Calendar with disabled weekends.
calendar-04
Files
components/calendar.tsx
1'use client'
2
3import * as React from 'react'
4import { eachDayOfInterval, isSameDay } from 'date-fns'
5import { enUS } from 'date-fns/locale'
6import { type DateRange } from 'react-day-picker'
7
8import { Calendar } from '@/components/ui/calendar'
9
10export function Calendar05() {
11    const [date, setDate] = React.useState<DateRange | undefined>({
12        from: new Date(2025, 10, 11),
13        to: new Date(2025, 10, 14),
14    })
15
16    const bookedDates = Array.from(
17        { length: 10 },
18        (_, i) => new Date(2025, 10, 20 + i),
19    )
20
21    const selectedDaysCount = React.useMemo(() => {
22        if (!date?.from) return 0
23
24        if (!date.to) {
25            const isBooked = bookedDates.some((b) =>
26                isSameDay(b, date.from as Date),
27            )
28            return isBooked ? 0 : 1
29        }
30
31        const allDays = eachDayOfInterval({
32            start: date.from,
33            end: date.to,
34        })
35
36        const availableDays = allDays.filter(
37            (day) => !bookedDates.some((b) => isSameDay(b, day)),
38        )
39
40        return availableDays.length
41    }, [date, bookedDates])
42
43    return (
44        <div className="flex flex-col items-center space-y-4">
45            <Calendar
46                mode="range"
47                defaultMonth={date?.from}
48                selected={date}
49                onSelect={setDate}
50                numberOfMonths={2}
51                disabled={bookedDates}
52                modifiers={{ booked: bookedDates }}
53                modifiersClassNames={{
54                    booked: '[&>button]:line-through opacity-100',
55                }}
56                locale={enUS}
57            />
58            <div className="text-center text-sm font-medium text-gray-700">
59                {selectedDaysCount > 0 ? (
60                    <>
61                        {selectedDaysCount} day
62                        {selectedDaysCount > 1 ? 's' : ''} selected
63                    </>
64                ) : (
65                    'No days selected'
66                )}
67            </div>
68        </div>
69    )
70}
71
Calendar with disabled days.
calendar-05
Files
components/calendar.tsx
1'use client'
2
3import * as React from 'react'
4import { DateRange } from 'react-day-picker'
5
6import { Calendar } from '@/components/ui/calendar'
7
8export function Calendar06() {
9    const [date, setDate] = React.useState<DateRange | undefined>({
10        from: new Date(2025, 10, 9),
11        to: new Date(2025, 11, 26),
12    })
13    return (
14        <Calendar
15            mode="range"
16            defaultMonth={date?.from}
17            selected={date}
18            onSelect={setDate}
19            captionLayout="dropdown"
20            className="rounded-lg border shadow-sm"
21            showWeekNumber
22        />
23    )
24}
25
Calendar with week numbers.
calendar-06
Files
components/calendar.tsx
1'use client'
2
3import * as React from 'react'
4
5import { Calendar } from '@/components/ui/calendar'
6
7export function Calendar07() {
8    const [date, setDate] = React.useState<Date | undefined>(new Date())
9    return (
10        <Calendar
11            mode="single"
12            selected={date}
13            onSelect={setDate}
14            captionLayout="dropdown"
15            className="rounded-lg border shadow-sm [--cell-size:--spacing(10)] md:[--cell-size:--spacing(12)]"
16        />
17    )
18}
19
Calendar with variable sized cells.
calendar-07
Files
components/calendar.tsx
1'use client'
2
3import * as React from 'react'
4
5import { Calendar } from '@/components/ui/calendar'
6import { Label } from '@/components/ui/label'
7import {
8    Select,
9    SelectContent,
10    SelectItem,
11    SelectTrigger,
12    SelectValue,
13} from '@/components/ui/select'
14
15export function Calendar09() {
16    const [dropdown, setDropdown] =
17        React.useState<React.ComponentProps<typeof Calendar>['captionLayout']>(
18            'dropdown',
19        )
20    const [date, setDate] = React.useState<Date | undefined>(new Date())
21    return (
22        <div className="flex flex-col gap-4">
23            <Calendar
24                mode="single"
25                selected={date}
26                onSelect={setDate}
27                captionLayout={dropdown}
28                className="rounded-lg border shadow-sm"
29            />
30            <div className="flex flex-col gap-3">
31                <Label htmlFor="dropdown" className="px-1">
32                    Dropdown
33                </Label>
34                <Select
35                    value={dropdown}
36                    onValueChange={(value) =>
37                        setDropdown(
38                            value as React.ComponentProps<
39                                typeof Calendar
40                            >['captionLayout'],
41                        )
42                    }
43                >
44                    <SelectTrigger
45                        id="dropdown"
46                        size="sm"
47                        className="bg-background w-full"
48                    >
49                        <SelectValue placeholder="Dropdown" />
50                    </SelectTrigger>
51                    <SelectContent align="center">
52                        <SelectItem value="dropdown">Month and Year</SelectItem>
53                        <SelectItem value="dropdown-months">
54                            Month Only
55                        </SelectItem>
56                        <SelectItem value="dropdown-years">
57                            Year Only
58                        </SelectItem>
59                    </SelectContent>
60                </Select>
61            </div>
62        </div>
63    )
64}
65
Calendar with month and year selector.
calendar-08