UNPKG

puppy-lib-components

Version:

A modern TypeScript React component library with generic UI components and football pickem domain components

98 lines (97 loc) 4.97 kB
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime"; import { useState, useCallback, useMemo } from 'react'; import { useMediaQuery, useTheme } from '@mui/material'; import { DateInput } from './DateInput'; import { DesktopPicker } from './DesktopPicker'; import { MobilePicker } from './MobilePicker'; import { formatDisplayValue } from './utils'; export const DateRangePicker = ({ value, defaultValue, onChange, onAccept, onClose, onOpen, label, placeholder = 'Select date range', disabled = false, readOnly = false, required = false, error = false, errorMessage, helperText, format = 'MM/dd/yyyy', minDate, maxDate, disableFuture = false, disablePast = false, shouldDisableDate, closeOnSelect = true, calendars = 2, showDaysOutsideCurrentMonth = false, displayWeekNumber = false, name, id, className, open: controlledOpen, rangePosition: controlledRangePosition, onRangePositionChange, autoFocus = false, size = 'medium', clearable = true, renderInput, }) => { const theme = useTheme(); const isMobile = useMediaQuery(theme.breakpoints.down('md')); const [internalValue, setInternalValue] = useState(defaultValue || { start: null, end: null }); const [internalOpen, setInternalOpen] = useState(false); const [internalRangePosition, setInternalRangePosition] = useState('start'); const [anchorEl, setAnchorEl] = useState(null); const currentValue = value || internalValue; const isOpen = controlledOpen !== undefined ? controlledOpen : internalOpen; const rangePosition = controlledRangePosition !== undefined ? controlledRangePosition : internalRangePosition; const handleOpen = useCallback((event) => { if (disabled || readOnly) return; setAnchorEl(event.currentTarget); if (controlledOpen === undefined) { setInternalOpen(true); } onOpen?.(); }, [disabled, readOnly, controlledOpen, onOpen]); const handleClose = useCallback(() => { setAnchorEl(null); if (controlledOpen === undefined) { setInternalOpen(false); } onClose?.(); }, [controlledOpen, onClose]); const handleDateChange = useCallback((date, calendarIndex = 0) => { const newValue = { ...currentValue }; if (rangePosition === 'start') { newValue.start = date; if (!newValue.end || date > newValue.end) { newValue.end = null; } } else { newValue.end = date; if (!newValue.start || date < newValue.start) { newValue.start = null; } } if (value === undefined) { setInternalValue(newValue); } onChange?.(newValue); // Auto-close if both dates are selected and closeOnSelect is true if (closeOnSelect && newValue.start && newValue.end) { onAccept?.(newValue); handleClose(); } }, [currentValue, rangePosition, value, onChange, closeOnSelect, onAccept, handleClose]); const handleRangePositionChange = useCallback((position) => { if (controlledRangePosition === undefined) { setInternalRangePosition(position); } onRangePositionChange?.(position); }, [controlledRangePosition, onRangePositionChange]); const handleClear = useCallback(() => { const newValue = { start: null, end: null }; if (value === undefined) { setInternalValue(newValue); } onChange?.(newValue); }, [value, onChange]); const handleAccept = useCallback(() => { onAccept?.(currentValue); handleClose(); }, [onAccept, currentValue, handleClose]); const displayValue = useMemo(() => { return formatDisplayValue(currentValue, format); }, [currentValue, format]); const hasValue = Boolean(currentValue.start || currentValue.end); const commonPickerProps = { open: isOpen, onClose: handleClose, currentValue, rangePosition, onRangePositionChange: handleRangePositionChange, onDateChange: handleDateChange, onAccept: handleAccept, onClear: handleClear, clearable, minDate, maxDate, disableFuture, disablePast, shouldDisableDate, showDaysOutsideCurrentMonth, }; return (_jsxs(_Fragment, { children: [_jsx(DateInput, { value: displayValue, placeholder: placeholder, label: label, disabled: disabled, readOnly: readOnly, required: required, error: error, errorMessage: errorMessage, helperText: helperText, name: name, id: id, size: size, autoFocus: autoFocus, clearable: clearable, hasValue: hasValue, onOpen: handleOpen, onClear: handleClear, renderInput: renderInput, className: className }), isMobile ? (_jsx(MobilePicker, { ...commonPickerProps })) : (_jsx(DesktopPicker, { ...commonPickerProps, anchorEl: anchorEl, calendars: calendars }))] })); };