/** * Material Design 3 Date Picker */ 'use client'; import React, { useState, useRef, useEffect } from 'react'; import { format, startOfMonth, endOfMonth, eachDayOfInterval, isSameDay, isSameMonth, addMonths, subMonths, startOfWeek, endOfWeek } from 'date-fns'; import { ru } from 'date-fns/locale'; interface DatePickerProps { value: string; // YYYY-MM-DD format onChange: (value: string) => void; disabled?: boolean; required?: boolean; } export const DatePicker: React.FC = ({ value, onChange, disabled = false, required = false, }) => { const [isOpen, setIsOpen] = useState(false); const [displayMonth, setDisplayMonth] = useState(value ? new Date(value) : new Date()); const containerRef = useRef(null); const selectedDate = value ? new Date(value) : null; // Закрываем picker при клике вне компонента useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if (containerRef.current && !containerRef.current.contains(event.target as Node)) { setIsOpen(false); } }; if (isOpen) { document.addEventListener('mousedown', handleClickOutside); } return () => { document.removeEventListener('mousedown', handleClickOutside); }; }, [isOpen]); const handleDateSelect = (date: Date) => { const year = date.getFullYear(); const month = String(date.getMonth() + 1).padStart(2, '0'); const day = String(date.getDate()).padStart(2, '0'); onChange(`${year}-${month}-${day}`); setIsOpen(false); }; // Получаем дни для отображения в календаре const getDaysInMonth = () => { const start = startOfMonth(displayMonth); const end = endOfMonth(displayMonth); const startDate = startOfWeek(start, { locale: ru }); const endDate = endOfWeek(end, { locale: ru }); return eachDayOfInterval({ start: startDate, end: endDate }); }; const days = getDaysInMonth(); const weekDays = ['Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб', 'Вс']; return (
{/* Input field */} {/* Calendar dropdown */} {isOpen && (
{/* Header with month/year navigation */}
{format(displayMonth, 'LLLL yyyy', { locale: ru })}
{/* Week days header */}
{weekDays.map(day => (
{day}
))}
{/* Calendar days grid */}
{days.map((day, index) => { const isSelected = selectedDate && isSameDay(day, selectedDate); const isCurrentMonth = isSameMonth(day, displayMonth); const isToday = isSameDay(day, new Date()); return ( ); })}
{/* Today button */}
)}
); };