@trellixio/roaster-coffee
Version:
Beans' product component library
73 lines (72 loc) • 4.13 kB
JavaScript
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 })));
}