Files
frontend/packages/common/components/src/ui/date-range-picker/index.tsx
T

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>
);
}