DateRangePicker
DateRangePicker.tsx
import React, { useState } from 'react';
import './DateRangePicker.css';
interface DateRangePickerProps {
startDate?: Date;
endDate?: Date;
onDateChange?: (startDate: Date, endDate: Date) => void;
}
const DateRangePicker = (props: DateRangePickerProps) => {
const { startDate: initialStartDate, endDate: initialEndDate, onDateChange } = props;
const [startDate, setStartDate] = useState<Date | undefined>(initialStartDate);
const [endDate, setEndDate] = useState<Date | undefined>(initialEndDate);
const handleStartDateChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const newStartDate = event.target.valueAsDate;
if (newStartDate && (!endDate || newStartDate <= endDate)) {
setStartDate(newStartDate);
onDateChange && onDateChange(newStartDate, endDate);
}
};
const handleEndDateChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const newEndDate = event.target.valueAsDate;
if (newEndDate && (!startDate || newEndDate >= startDate)) {
setEndDate(newEndDate);
onDateChange && onDateChange(startDate, newEndDate);
}
};
return (
<div className="date-range-picker-container">
<label htmlFor="start-date">Start Date:</label>
<input type="date" id="start-date" value={startDate?.toISOString().substr(0, 10)} onChange={handleStartDateChange} />
<label htmlFor="end-date">End Date:</label>
<input type="date" id="end-date" value={endDate?.toISOString().substr(0, 10)} onChange={handleEndDateChange} />
</div>
);
};
export default DateRangePicker;
DateRangePicker.module.css
.date-range-picker-container {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
gap: 16px;
padding: 16px;
margin: 16px;
border: 1px solid #ccc;
}
.date-range-picker-input {
font-size: 16px;
padding: 8px;
border-radius: 4px;
border: 1px solid #ccc;
}
.date-range-picker-label {
font-weight: bold;
}
.date-range-picker-calendar {
position: absolute;
top: 100%;
left: 0;
z-index: 1;
background-color: #fff;
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.2);
border-radius: 4px;
padding: 16px;
}
.date-range-picker-calendar-header {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
margin-bottom: 16px;
}
.date-range-picker-calendar-month {
font-size: 24px;
font-weight: bold;
text-transform: uppercase;
}
.date-range-picker-calendar-year {
font-size: 24px;
font-weight: bold;
}
.date-range-picker-calendar-days {
display: grid;
grid-template-columns: repeat(7, 1fr);
grid-template-rows: repeat(6, 1fr);
gap: 16px;
}
.date-range-picker-calendar-day {
display: flex;
justify-content: center;
align-items: center;
font-size: 16px;
font-weight: bold;
border-radius: 50%;
height: 40px;
width: 40px;
transition: background-color 0.2s ease-in-out;
}
.date-range-picker-calendar-day:hover {
background-color: #f0f0f0;
}
.date-range-picker-calendar-day.active {
background-color: #007bff;
color: #fff;
}
.date-range-picker-calendar-day.disabled {
opacity: 0.5;
pointer-events: none;
}