@trackpilots/single-select-date-picker
Version:
A customizable single select date picker component for React, built with Tailwind CSS.
149 lines (129 loc) • 4.27 kB
JSX
import React, { useEffect, useState, useRef } from "react";
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import { IoCalendarOutline } from "react-icons/io5";
const options = { year: "numeric", month: "short", day: "numeric" };
const DateFilter = ({
defaultChoosenDate,
selectedDate,
onSelect,
selectedColor,
icon: Icon,
}) => {
const modalRef = useRef(null);
const buttonRef = useRef(null);
const [isOpen, setIsOpen] = useState(false);
const [choosenValue, setChoosenValue] = useState(defaultChoosenDate);
useEffect(() => {
if (selectedDate) {
setChoosenValue(
new Date(selectedDate).toLocaleDateString(undefined, options)
);
}
}, [selectedDate]);
useEffect(() => {
const handleClickOutside = (event) => {
if (
modalRef.current &&
!modalRef.current.contains(event.target) &&
buttonRef.current &&
!buttonRef.current.contains(event.target)
) {
setIsOpen(false);
}
};
if (isOpen) {
document.addEventListener("mousedown", handleClickOutside);
} else {
document.removeEventListener("mousedown", handleClickOutside);
}
return () => {
document.removeEventListener("mousedown", handleClickOutside);
};
}, [isOpen]);
const handleSelectDate = ({ date, value }) => {
setChoosenValue(date);
onSelect({ date, value })
setIsOpen(false);
};
return (
<div className="relative z-10">
<button
ref={buttonRef}
onClick={() => {
setIsOpen(!isOpen);
}}
className="border-2 rounded-full text-gray-600 py-2 px-6 flex w-58 items-center gap-2 bg-white"
>
<span>
<Icon />
</span>
{choosenValue || "Select Date"}
</button>
{isOpen && (
<div
ref={modalRef}
className="absolute right-0 mt-2 bg-white border rounded shadow-lg p-4 flex"
>
<div
className={`opacity-100
`}
>
<DatePicker
selected={selectedDate}
onChange={(dates) => {
const choosenString = `${new Date(dates).toLocaleDateString(
undefined,
options
)}`;
handleSelectDate({
date: choosenString,
value: dates,
});
}}
inline
className={`bg-white border rounded p-2`}
calendarClassName="custom-datepicker"
/>
</div>
</div>
)}
<style>
{`
.custom-datepicker .react-datepicker__day--selected,
.custom-datepicker .react-datepicker__day--in-range,
.custom-datepicker .react-datepicker__day--keyboard-selected {
background-color: ${selectedColor} !important;
color: white ;
}
.custom-datepicker .react-datepicker__day--selected,
.custom-datepicker .react-datepicker__day--range-start,
.custom-datepicker .react-datepicker__day--range-end {
background-color: ${selectedColor} !important;
color: white ;
border-radius: 6px ;
font-weight: bold;
}
.custom-datepicker .react-datepicker__day--in-range {
background-color: ${selectedColor} !important;
}
.custom-datepicker .react-datepicker__day--in-selecting-range {
background-color: ${selectedColor}d3 !important;
}
.custom-datepicker .react-datepicker__day:hover {
background-color: ${selectedColor} !important;
color: white ;
}
`}
</style>
</div>
);
};
DateFilter.defaultProps = {
defaultChoosenDate:"Today",
selectedDate: null, // Default to null if no startDate is provided
onSelect: () => {}, // Prevents "onSelect is not a function" error
selectedColor: "#9D55FF",
icon: IoCalendarOutline,
};
export default DateFilter;