95 lines
2.6 KiB
TypeScript
95 lines
2.6 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect, useState } from "react";
|
|
import { format } from "date-fns";
|
|
import { CalendarIcon } from "lucide-react";
|
|
import type { DateRange, DayPicker } from "react-day-picker";
|
|
|
|
import { cn } from "../../lib/utils";
|
|
import { Button } from "../button";
|
|
import { Calendar } from "../calendar";
|
|
import { Popover, PopoverContent, PopoverTrigger } from "../popover";
|
|
|
|
type DateRangePickerProps = React.HTMLAttributes<HTMLDivElement> &
|
|
React.ComponentProps<typeof DayPicker> & {
|
|
value?: DateRange;
|
|
defaultValue?: DateRange;
|
|
disabled?: boolean;
|
|
onValueChange?: (date: DateRange | undefined) => void;
|
|
};
|
|
|
|
export function DateRangePicker({
|
|
value,
|
|
defaultValue,
|
|
disabled,
|
|
className,
|
|
children,
|
|
onValueChange,
|
|
...props
|
|
}: DateRangePickerProps) {
|
|
const [dateState, setDateState] = useState<DateRange | undefined>(
|
|
defaultValue,
|
|
);
|
|
|
|
const isControlled = value !== undefined;
|
|
const dateValue = isControlled ? value : dateState;
|
|
|
|
useEffect(() => {
|
|
if (isControlled) {
|
|
setDateState(value);
|
|
}
|
|
}, [isControlled, value]);
|
|
|
|
const handleSelect = (date: DateRange | undefined) => {
|
|
if (!isControlled) {
|
|
setDateState(date);
|
|
}
|
|
onValueChange?.(date);
|
|
};
|
|
|
|
return (
|
|
<div className={cn("grid gap-2", className)}>
|
|
<Popover>
|
|
<PopoverTrigger asChild>
|
|
<Button
|
|
id="date"
|
|
variant="outline"
|
|
className={cn(
|
|
"h-[3.2rem] min-w-[12rem] justify-start border-input !bg-background px-4 py-2 text-left text-[1.3rem] font-normal text-muted-foreground hover:!bg-accent",
|
|
!dateValue && "text-muted-foreground",
|
|
)}
|
|
disabled={disabled}
|
|
>
|
|
<CalendarIcon className="!size-[1.6rem]" />
|
|
{dateValue?.from ? (
|
|
dateValue.to ? (
|
|
<>
|
|
{format(dateValue.from, "yyyy-MM-dd")} ~{" "}
|
|
{format(dateValue.to, "yyyy-MM-dd")}
|
|
</>
|
|
) : (
|
|
format(dateValue.from, "yyyy-MM-dd")
|
|
)
|
|
) : (
|
|
<span>기간 선택</span>
|
|
)}
|
|
</Button>
|
|
</PopoverTrigger>
|
|
<PopoverContent className="w-auto p-0" align="start">
|
|
<div>
|
|
{children}
|
|
<Calendar
|
|
{...props}
|
|
mode="range"
|
|
defaultMonth={dateValue?.from}
|
|
selected={dateValue}
|
|
onSelect={handleSelect}
|
|
numberOfMonths={2}
|
|
/>
|
|
</div>
|
|
</PopoverContent>
|
|
</Popover>
|
|
</div>
|
|
);
|
|
}
|