"use client"; import React, { useEffect, useRef, useState } from "react"; import { Placement } from "@popperjs/core"; import { DateRange, Matcher } from "react-day-picker"; import { usePopper } from "react-popper"; import { ArrowRight, CalendarCheck2, CalendarDays, X } from "lucide-react"; import { Combobox } from "@headlessui/react"; // plane imports import { useTranslation } from "@plane/i18n"; // ui import { ComboDropDown, Calendar } from "@plane/ui"; import { cn, renderFormattedDate } from "@plane/utils"; // helpers // hooks import { useDropdown } from "@/hooks/use-dropdown"; // components import { DropdownButton } from "./buttons"; import { MergedDateDisplay } from "./merged-date"; // types import { TButtonVariants } from "./types"; type Props = { applyButtonText?: string; bothRequired?: boolean; buttonClassName?: string; buttonContainerClassName?: string; buttonFromDateClassName?: string; buttonToDateClassName?: string; buttonVariant: TButtonVariants; cancelButtonText?: string; className?: string; clearIconClassName?: string; disabled?: boolean; hideIcon?: { from?: boolean; to?: boolean; }; isClearable?: boolean; mergeDates?: boolean; minDate?: Date; maxDate?: Date; onSelect?: (range: DateRange | undefined) => void; placeholder?: { from?: string; to?: string; }; placement?: Placement; required?: boolean; showTooltip?: boolean; tabIndex?: number; value: { from: Date | undefined; to: Date | undefined; }; renderByDefault?: boolean; renderPlaceholder?: boolean; customTooltipContent?: React.ReactNode; customTooltipHeading?: string; }; export const DateRangeDropdown: React.FC = (props) => { const { t } = useTranslation(); const { buttonClassName, buttonContainerClassName, buttonFromDateClassName, buttonToDateClassName, buttonVariant, className, clearIconClassName = "", disabled = false, hideIcon = { from: true, to: true, }, isClearable = false, mergeDates, minDate, maxDate, onSelect, placeholder = { from: t("project_cycles.add_date"), to: t("project_cycles.add_date"), }, placement, showTooltip = false, tabIndex, value, renderByDefault = true, renderPlaceholder = true, customTooltipContent, customTooltipHeading, } = props; // states const [isOpen, setIsOpen] = useState(false); const [dateRange, setDateRange] = useState(value); // refs const dropdownRef = useRef(null); // popper-js refs const [referenceElement, setReferenceElement] = useState(null); const [popperElement, setPopperElement] = useState(null); // popper-js init const { styles, attributes } = usePopper(referenceElement, popperElement, { placement: placement ?? "bottom-start", modifiers: [ { name: "preventOverflow", options: { padding: 12, }, }, ], }); const onOpen = () => { if (referenceElement) referenceElement.focus(); }; const { handleKeyDown, handleOnClick } = useDropdown({ dropdownRef, isOpen, onOpen, setIsOpen, }); const disabledDays: Matcher[] = []; if (minDate) disabledDays.push({ before: minDate }); if (maxDate) disabledDays.push({ after: maxDate }); const clearDates = () => { const clearedRange = { from: undefined, to: undefined }; setDateRange(clearedRange); onSelect?.(clearedRange); }; const hasDisplayedDates = dateRange.from || dateRange.to; useEffect(() => { setDateRange(value); }, [value]); const comboButton = ( ); return ( { if (e.key === "Enter") { if (!isOpen) handleKeyDown(e); } else handleKeyDown(e); }} button={comboButton} disabled={disabled} renderByDefault={renderByDefault} > {isOpen && (
{ onSelect?.(val); }} mode="range" disabled={disabledDays} showOutsideDays fixedWeeks initialFocus />
)}
); };