UNPKG

@trellixio/roaster-coffee

Version:
73 lines (72 loc) 4.13 kB
import * as React from 'react'; import { dateStringParser, formatDate, getSeparatorIndex, isDateValid, pickCalendarProps } from './utils'; import { Calendar } from './components'; import { TextField } from '../TextField'; import { useUncontrolled } from '@/utils'; export function DatePicker(props) { const { calendarProps, others } = pickCalendarProps(props); const { month, year, onChange, onInputError, value: passedValue, disableSpecificDates, dateFormat, separator, minDate, maxDate, defaultValue, } = calendarProps; const textFieldRef = React.useRef(); const calendarRef = React.useRef(); const [isTextFieldFocused, setIsTextFieldFocused] = React.useState(false); const [inputError, setInputError] = React.useState(false); const [currentKey, setCurrentKey] = React.useState(''); const [{ currentDisplayedMonth, currentDisplayedYear }, setCalendarDate] = React.useState({ currentDisplayedMonth: month, currentDisplayedYear: year, }); const separatorIndex = getSeparatorIndex(dateFormat); const handleMonthChange = React.useCallback((targetMonth, targetYear) => setCalendarDate({ currentDisplayedMonth: targetMonth, currentDisplayedYear: targetYear }), []); const [date, setDate] = useUncontrolled({ value: passedValue, defaultValue, finalValue: null, onChange, }); const [inputValue, setInputValue] = React.useState(date instanceof Date ? formatDate(date, separator, dateFormat) : ''); const onFocus = () => setIsTextFieldFocused(true); const onBlur = () => setIsTextFieldFocused(false); const handleDateSelection = React.useCallback((selectedDate) => { setInputValue(formatDate(selectedDate, separator)); setDate(selectedDate); setCalendarDate({ currentDisplayedMonth: selectedDate.getMonth(), currentDisplayedYear: selectedDate.getFullYear(), }); setInputError(''); window.setTimeout(onBlur, 10); }, [onChange]); // eslint-disable-next-line consistent-return function handleInputChange(value) { var _a, _b, _c; const valueLength = value.length; if (currentKey !== 'Backspace' && (valueLength === separatorIndex.first || valueLength === separatorIndex.second)) { return setInputValue(value + separator); } if (valueLength === 0) { setDate(null); } setInputValue(value); if (valueLength === 10) { const dateValue = dateStringParser(value); if (!dateValue) { return setInputError((_a = onInputError === null || onInputError === void 0 ? void 0 : onInputError('INVALID_DATE')) !== null && _a !== void 0 ? _a : true); } setInputError(''); if (isDateValid({ date: dateValue, minDate, maxDate })) { return handleDateSelection(dateValue); } return setInputError((_b = onInputError === null || onInputError === void 0 ? void 0 : onInputError('OUT_OF_RANGE')) !== null && _b !== void 0 ? _b : true); } if (valueLength < 10 && valueLength > 0) { return setInputError((_c = onInputError === null || onInputError === void 0 ? void 0 : onInputError('INVALID_DATE')) !== null && _c !== void 0 ? _c : true); } } React.useEffect(() => { if (defaultValue) handleDateSelection(defaultValue); }, []); return (React.createElement("div", { className: "date-picker", ref: calendarRef }, React.createElement(TextField, Object.assign({}, others, { value: inputValue, ref: textFieldRef, onFocus: onFocus, maxLength: 10, onChange: (value) => handleInputChange(value), onKeyDown: (event) => setCurrentKey(event.key), error: inputError })), React.createElement(Calendar, { selected: date, onClose: onBlur, minDate: minDate, maxDate: maxDate, isOpen: isTextFieldFocused, year: currentDisplayedYear, month: currentDisplayedMonth, onMonthChange: handleMonthChange, handleDateSelection: handleDateSelection, disableSpecificDates: disableSpecificDates }))); }