import { useReducer, useState } from 'react'; import * as React from 'react'; import { AnimatePresence, motion } from 'motion/react'; import { useTranslation } from '#hooks'; import { cn } from '#utils'; import { ArrowToggle } from '../ArrowToggle/ArrowToggle.tsx'; import { Card } from '../Card/Card.tsx'; import { Calendar, CALENDAR_ANIMATION_DURATION } from './Calendar.tsx'; import { YearSelector } from './YearSelector.tsx'; const MONTHS = [ 'january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december' ] as const; type IncrementAction = { type: 'increment'; }; type DecrementAction = { type: 'decrement'; }; type SetYearAction = { type: 'set-year'; value: number; }; type ReducerAction = DecrementAction | IncrementAction | SetYearAction; const reducer = (previousDate: Date, action: ReducerAction) => { const newDate = new Date(previousDate.valueOf()); switch (action.type) { case 'decrement': newDate.setMonth(newDate.getMonth() - 1); break; case 'increment': newDate.setMonth(newDate.getMonth() + 1); break; case 'set-year': newDate.setFullYear(action.value); } return newDate; }; export type DatePickerProps = { onMouseEnter?: React.MouseEventHandler; onMouseLeave?: React.MouseEventHandler; onSelection: (value: Date) => void; }; export const DatePicker = React.forwardRef, DatePickerProps>(function DatePicker( { onSelection, ...props }, ref ) { const [date, dispatch] = useReducer(reducer, new Date()); const [showYearSelector, setShowYearSelector] = useState(false); const { t } = useTranslation('libui'); // this is to prevent changing month before prev calendar is unmounted // the duration is doubled because presumably it is to mount old and mount new const [canSetMonth, setCanSetMonth] = useState(true); const monthName = t(`months.${MONTHS[date.getMonth()]!}`); const handleYearSelection = (date: Date) => { dispatch({ type: 'set-year', value: date.getFullYear() }); setShowYearSelector(false); }; return (
{`${monthName} ${date.getFullYear()}`} { setShowYearSelector(!showYearSelector); }} />
{ if (canSetMonth) { setCanSetMonth(false); dispatch({ type: 'decrement' }); setTimeout(() => { setCanSetMonth(true); }, CALENDAR_ANIMATION_DURATION * 2000); } }} /> { if (canSetMonth) { setCanSetMonth(false); dispatch({ type: 'increment' }); setTimeout(() => { setCanSetMonth(true); }, CALENDAR_ANIMATION_DURATION * 2000); } }} />
{showYearSelector ? ( ) : ( )}
); });