"use client"
import * as React from "react"
import {
DayPicker,
getDefaultClassNames,
type DayButton,
type DropdownProps,
} from "react-day-picker"
import { cn } from "../../lib/utils"
import { Button } from "./button"
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "./select"
function CalendarDropdown({
options,
value,
onChange,
disabled,
"aria-label": ariaLabel,
}: DropdownProps) {
const stringValue = value === undefined ? "" : String(value)
return (
)
}
function CalendarPreviousMonthButton({
className,
children,
...props
}: React.ComponentProps<"button">) {
return (
)
}
function CalendarNextMonthButton({
className,
children,
...props
}: React.ComponentProps<"button">) {
return (
)
}
function Calendar({
className,
classNames,
showOutsideDays = true,
captionLayout = "label",
formatters,
components,
...props
}: React.ComponentProps) {
const defaultClassNames = getDefaultClassNames()
return (
svg]:rotate-180`,
String.raw`rtl:**:[.rdp-button\_previous>svg]:rotate-180`,
className
)}
captionLayout={captionLayout}
formatters={{
formatMonthDropdown: (date) =>
date.toLocaleString("default", { month: "short" }),
...formatters,
}}
classNames={{
root: cn("w-fit", defaultClassNames.root),
months: cn(
"relative flex flex-col gap-4 md:flex-row",
defaultClassNames.months
),
month: cn("flex w-full flex-col gap-4", defaultClassNames.month),
nav: cn(
"pointer-events-none absolute inset-x-0 top-0 z-30 flex w-full items-center justify-between gap-1",
defaultClassNames.nav
),
button_previous: cn("pointer-events-auto", defaultClassNames.button_previous),
button_next: cn("pointer-events-auto", defaultClassNames.button_next),
month_caption: cn(
"relative z-10 flex h-(--cell-size) w-full items-center justify-center px-(--cell-size)",
defaultClassNames.month_caption
),
dropdowns: cn(
"flex h-(--cell-size) w-full items-center justify-center gap-1.5 text-sm font-medium",
defaultClassNames.dropdowns
),
dropdown_root: cn("hidden", defaultClassNames.dropdown_root),
dropdown: cn("hidden", defaultClassNames.dropdown),
caption_label: cn(
"text-sm font-medium select-none",
defaultClassNames.caption_label
),
table: "w-full border-collapse",
weekdays: cn(defaultClassNames.weekdays),
weekday: cn(
"h-(--cell-size) w-(--cell-size) p-0 text-center text-xs font-normal text-muted-foreground select-none",
defaultClassNames.weekday
),
week: cn("mt-2", defaultClassNames.week),
week_number_header: cn(
"w-(--cell-size) select-none",
defaultClassNames.week_number_header
),
week_number: cn(
"text-xs text-muted-foreground select-none",
defaultClassNames.week_number
),
day: cn(
"group/day relative size-(--cell-size) p-0 text-center align-middle select-none",
defaultClassNames.day
),
range_start: cn(
"rounded-l-md bg-accent",
"[&_button]:!rounded-md [&_button]:!rounded-l-md [&_button]:!bg-primary [&_button]:!text-primary-foreground [&_button]:hover:!bg-primary/90 [&_button]:hover:!text-primary-foreground [&_button]:shadow-none",
defaultClassNames.range_start
),
range_middle: cn(
"rounded-none bg-accent",
"[&_button]:!rounded-none [&_button]:!bg-transparent [&_button]:!text-accent-foreground [&_button]:hover:!bg-transparent [&_button]:hover:!text-accent-foreground [&_button]:shadow-none",
defaultClassNames.range_middle
),
range_end: cn(
"rounded-r-md bg-accent",
"[&_button]:!rounded-md [&_button]:!rounded-r-md [&_button]:!bg-primary [&_button]:!text-primary-foreground [&_button]:hover:!bg-primary/90 [&_button]:hover:!text-primary-foreground [&_button]:shadow-none",
defaultClassNames.range_end
),
today: cn("rounded-md", defaultClassNames.today),
outside: cn(
"text-muted-foreground [&_button]:text-muted-foreground [&_button]:opacity-50",
"aria-selected:bg-accent/50 aria-selected:[&_button]:opacity-100",
defaultClassNames.outside
),
disabled: cn(
"text-muted-foreground opacity-50",
defaultClassNames.disabled
),
hidden: cn("invisible", defaultClassNames.hidden),
...classNames,
}}
components={{
Root: ({ className, rootRef, ...props }) => {
return (
)
},
Dropdown: CalendarDropdown,
PreviousMonthButton: CalendarPreviousMonthButton,
NextMonthButton: CalendarNextMonthButton,
Chevron: ({ className, orientation }) => {
return (
)
},
DayButton: CalendarDayButton,
WeekNumber: ({ children, ...props }) => {
return (
|
{children}
|
)
},
...components,
}}
{...props}
/>
)
}
function CalendarDayButton({
className,
day,
modifiers,
...props
}: React.ComponentProps) {
const defaultClassNames = getDefaultClassNames()
const focusRef = React.useCallback(
(node: HTMLButtonElement | null) => {
if (modifiers.focused) node?.focus()
},
[modifiers.focused],
)
const isSelected =
modifiers.selected &&
!modifiers.range_start &&
!modifiers.range_end &&
!modifiers.range_middle
const inRange =
modifiers.range_start || modifiers.range_middle || modifiers.range_end
return (