-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcalendar.tsx
130 lines (124 loc) · 4.83 KB
/
calendar.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
"use client";
import { ChevronLeftIcon, ChevronRightIcon } from "@radix-ui/react-icons";
import * as React from "react";
import { DayPicker } from "react-day-picker";
import { buttonVariants } from "@/components/ui/button";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
import { cn } from "@/lib/utils";
export type CalendarProps = React.ComponentProps<typeof DayPicker>;
function Calendar({
className,
classNames,
showOutsideDays = true,
...props
}: CalendarProps & { onChange?: React.ChangeEventHandler<HTMLSelectElement> }) {
const handleCalendarChange = (
_value: string | number,
_e: React.ChangeEventHandler<HTMLSelectElement>
) => {
const _event = {
target: {
value: String(_value),
},
} as React.ChangeEvent<HTMLSelectElement>;
_e(_event);
};
return (
<DayPicker
showOutsideDays={showOutsideDays}
className={cn("p-3", className)}
classNames={{
months: "flex flex-col sm:flex-row space-y-4 sm:space-x-4 sm:space-y-0",
month: "space-y-4",
caption_start: "is-start",
caption_between: "is-between",
caption_end: "is-end",
caption: "flex justify-center pt-1 relative items-center gap-1",
caption_label:
"flex h-7 text-sm font-medium justify-center items-center grow [.is-multiple_&]:flex",
caption_dropdowns: "flex justify-center gap-1 grow dropdowns pl-8 pr-9",
multiple_months: "is-multiple",
vhidden:
"hidden [.is-between_&]:flex [.is-end_&]:flex [.is-start.is-end_&]:hidden",
nav: "flex items-center [&:has([name='previous-month'])]:order-first [&:has([name='next-month'])]:order-last gap-1",
nav_button: cn(
buttonVariants({ variant: "outline" }),
"h-7 w-7 bg-transparent p-0 text-muted-foreground"
),
nav_button_previous: "absolute left-1",
nav_button_next: "absolute right-1",
table: "w-full border-collapse space-y-1",
head_row: "flex",
head_cell:
"text-muted-foreground rounded-md w-9 font-normal text-[0.8rem]",
row: "flex w-full mt-2",
cell: cn(
"relative p-0 text-center text-sm focus-within:relative focus-within:z-20 [&:has([aria-selected])]:bg-accent",
props.mode === "range"
? "[&:has(>.day-range-end)]:rounded-r-md [&:has(>.day-range-start)]:rounded-l-md first:[&:has([aria-selected])]:rounded-l-md last:[&:has([aria-selected])]:rounded-r-md"
: "[&:has([aria-selected])]:rounded-md"
),
day: cn(
buttonVariants({ variant: "ghost" }),
"h-9 w-9 p-0 font-normal aria-selected:opacity-100"
),
day_range_start: "day-range-start",
day_range_end: "day-range-end",
day_selected:
"bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground focus:bg-primary focus:text-primary-foreground",
day_today: "bg-accent text-accent-foreground",
day_outside: "text-muted-foreground opacity-50",
day_disabled: "text-muted-foreground opacity-50",
day_range_middle:
"aria-selected:bg-accent aria-selected:text-accent-foreground",
day_hidden: "invisible",
}}
components={{
IconLeft: ({ ...props }) => <ChevronLeftIcon className="h-4 w-4" />,
IconRight: ({ ...props }) => <ChevronRightIcon className="h-4 w-4" />,
Dropdown: ({ ...props }) => (
<Select
{...props}
onValueChange={(value) => {
if (props.onChange) {
handleCalendarChange(value, props.onChange);
}
}}
value={props.value as string}
>
<SelectTrigger
className={cn(
buttonVariants({ variant: "ghost" }),
"h-7 w-fit py-2 pl-2 pr-1 font-medium [.is-between_&]:hidden [.is-end_&]:hidden [.is-start.is-end_&]:flex"
)}
>
<SelectValue placeholder={props?.caption}>
{props?.caption}
</SelectValue>
</SelectTrigger>
<SelectContent className="scrolling-auto max-h-[var(--radix-popper-available-height);] min-w-[var(--radix-popper-anchor-width)] overflow-y-auto">
{props.children &&
React.Children.map(props.children, (child) => (
<SelectItem
value={(child as React.ReactElement<any>)?.props?.value}
className="min-w-[var(--radix-popper-anchor-width)]"
>
{(child as React.ReactElement<any>)?.props?.children}
</SelectItem>
))}
</SelectContent>
</Select>
),
}}
{...props}
/>
);
}
Calendar.displayName = "Calendar";
export { Calendar };