@i-novus/ui-core
Version:
Базовые UI компоненты
66 lines (65 loc) • 2.61 kB
JavaScript
import { useState } from 'react';
import dayjs from 'dayjs';
import { INTERVAL_SEPARATOR } from '../../const';
import { useMemoFunction } from '../../../core';
import { getActiveElement } from '../../../utils/get-active-dom-node';
export const useDatePickerInputEvents = (isCalendarOpen, calendarElem, { onFocus, onBlur, onEnterKeyDown }, dateRangeOptions) => {
const [isPreventFocusEvent, setIsPreventFocusEvent] = useState(false);
const handleKeyDown = useMemoFunction((event) => {
const isInputFocus = calendarElem.current?.contains(getActiveElement());
if ((event.key === 'Enter' || event.code === 'Space') && isInputFocus) {
event.preventDefault();
event.stopPropagation();
onEnterKeyDown?.();
}
});
const handleFocus = useMemoFunction(() => {
if (isPreventFocusEvent) {
return;
}
setIsPreventFocusEvent(true);
onFocus?.();
window?.addEventListener('keydown', handleKeyDown);
});
const onBlurEvent = useMemoFunction((event) => {
setIsPreventFocusEvent(false);
onBlur?.(event);
window?.removeEventListener('keydown', handleKeyDown);
});
const checkIsInvalid = (rawValue, fullFormat, minDate, maxDate, isInterval) => {
if (isInterval) {
const parts = rawValue.split(INTERVAL_SEPARATOR).map(p => p.trim());
if (parts.length !== 2) {
return false;
}
const [begin, end] = parts.map(p => dayjs(p, fullFormat));
return begin?.isValid() && end?.isValid() &&
((minDate && begin.isBefore(minDate)) || (maxDate && end.isAfter(maxDate)));
}
const date = dayjs(rawValue, fullFormat);
return date.isValid() && (date.isAfter(maxDate) || date.isBefore(minDate));
};
const handleBlur = useMemoFunction((event, setValue) => {
const { maxDate, minDate, fullFormat, value, isInterval } = dateRangeOptions || {};
const rawValue = event.target.value;
if (checkIsInvalid(rawValue, fullFormat, minDate, maxDate, isInterval)) {
if (isInterval) {
// сброс до валидного значения
setValue(value);
}
else {
setValue(dayjs(value).format(fullFormat));
}
}
setTimeout(() => {
if (!isCalendarOpen.current) {
onBlurEvent(event);
}
}, 150);
});
return ({
handleFocus,
handleBlur,
onBlurEvent,
});
};